视频生成模型这两年卷得厉害,从画面清晰度到运动流畅度都在快速迭代,但有一个老问题始终绕不过去:模型本质上是在"猜"下一帧画面,它并不理解画面里的物体是什么、物理规律是什么、背景信息是什么。这就导致一个很尴尬的局面——你让它生成一杯水被碰倒的短视频,它可能画出水花四溅的漂亮画面,但溅射方向跟重力方向完全相反;你让它生成一个"1980年代老式火车站的雨景",它可能把电气化铁路的接触网、现代车站的LED屏幕全画进去,因为训练数据里那个年代的信息跟当代信息混在一起了。
我最近折腾了一个有意思的项目:用一个只有8B参数的模型,让它学会了自主调用外部工具——需要背景知识的时候就先去查资料,涉及物理模拟的环节就先跑一遍仿真,把工具返回的结果作为视频生成的约束条件。整套系统跑下来,效果超出我预期。今天把这套东西的架构思路、训练细节、踩坑记录完整写出来,希望对正在做Agent落地、或者想给生成模型"开外挂"的朋友有点参考价值。
1. 项目缘起:先搞清楚视频生成模型的"短视"病根在哪
很多人一上来就研究模型结构、优化生成质量,但我个人觉得,视频生成模型最核心的问题不是"画质不够好",而是它缺乏对世界基本事实的感知能力。换句话说,它是个"高分低能"的画家——笔法很好,但不懂物理、不懂历史、不懂逻辑。
1.1 生成模型的通病:画面很精美,常识很离谱
我做个简单的分类,把视频生成模型容易犯的错误归成三类:
- 物理规律违背:物体运动轨迹不符合牛顿力学,比如杯子掉地上应该碎或弹起,但模型让它穿模;水应该往低处流,模型让它悬浮。
- 知识性错误:特定年代、特定地点、特定文化背景下的场景元素张冠李戴,比如把现代元素带进历史场景,或者把不同地域的建筑风格混搭。
- 逻辑一致性缺失:前5秒人物穿的是红色外套,第10秒变成了蓝色;明明生成的是白天的场景,光线阴影却像黄昏。
这些问题的根源是同一个:模型用概率在"拟合"画面,而不是用理解在"渲染"世界。它没有知识库可以查询,没有物理引擎可以模拟,所有的输出都依赖训练时见过的数据分布。一旦用户的prompt触及知识盲区,或者需要精确的物理计算,模型就会胡编。
1.2 为什么是"工具调用":让模型学会求助,而不是死记硬背
面对上面这些问题,行业里有两种主流思路:
第一种是加大模型规模、增加训练数据,寄希望于"喂得多了它就懂了"。这个方向有效,但成本极其高昂,而且物理规律这种动态约束很难靠静态数据完全覆盖——你总不能给模型喂一遍所有可能的抛物线轨迹吧。
第二种是给模型接上外部工具。既然模型不懂物理,那就让它在生成之前先跑一个物理模拟器,拿到准确的运动轨迹再生成;不懂历史背景,就先搜一轮知识库,把检索结果作为prompt的补充信息。这个思路本质上是把"记忆"和"推理"外包出去,让模型成为一个"调度者"而不是"万事通"。
我选择第二条路。原因很现实:项目可用算力有限,大规模训练从成本和周期上都扛不住。而8B这个参数规模的模型,在单机多卡环境下是可以做微调训练的,推理延迟也在可接受范围内。关键它capacity足够承载工具调用的指令遵循能力——不需要它记住所有知识,只要它学得会"遇到什么情况、调用什么工具、怎么用工具返回的结果"。
打个比方:8B模型像是一个经验尚浅但执行力很强的助理。你不需要让他背下整个行业年鉴,但你要训练他"查资料前先翻目录,测量前先校准仪器"的工作习惯。工具调用能力的本质,是让模型形成一套"发现问题→定位工具→获取信息→落回任务"的工作流。
2. 系统整体设计:先把工具编排的骨架搭明白
这个项目我最深的体会就是:训练一个会调工具的模型,结构设计比训练技巧更重要。模型本来就不大,如果工具调用的链路设计得绕来绕去,学习负担太重,效果会很差。
2.1 工具层:构建一个低耦合、高内聚的工具沙箱
我没有把工具逻辑写死在模型代码里,而是单独做了一个工具执行层。每个工具对应一个注册描述,模型的每一次工具调用都通过结构化命令触发,由调度器统一接管。
实际项目中我注册了以下几类核心工具:
| 工具类别 | 工具名称 | 功能描述 | 返回形式 |
|---|---|---|---|
| 知识检索 | web_search | 搜索给定主题的背景资料 | 结构化文本(标题+摘要+正文片段) |
| 知识检索 | doc_retrieve | 从本地知识库中按语义检索语料 | 文本块列表(含相关性分数) |
| 物理模拟 | rigid_body_sim | 对物体运动进行刚体力学仿真 | JSON轨迹数据(坐标+姿态+时间戳) |
| 物理模拟 | fluid_sim | 简单流体效果模拟(适用于水、烟雾) | 栅格强度场数据 |
| 场景规划 | scene_layout | 根据约束生成场景元素布局方案 | 结构化布局描述(物体坐标+属性) |
| 计算校准 | unit_convert | 单位换算、时间/空间标度校准 | 数值结果 |
这里有个设计细节值得说:工具返回的数据格式,全部统一成视频生成引擎能直接消费的结构化格式。比如物理模拟返回的不是一张图,而是带时间戳的物体坐标序列;场景布局返回的是物体坐标和类别标签。为什么?因为后续要把它注入到视频生成的条件控制中,格式越干净,对齐越容易,模型也越容易学到"工具结果是用来约束生成参数"这个逻辑。
2.2 决策层:让模型学会在"何时调用"与"调用什么"之间做权衡
工具层只解决了"有工具可用"的问题,真正的难点在决策层——8B模型怎么知道当前任务要不要调用工具?调哪个?调完工具之后返回的信息该怎么用?
我的做法是给模型设定了固定的对话-工具交替模式:
Thought: 分析当前任务需求,判断是否需要外部知识或模拟。 Action: 如果需要工具,则输出工具名称和参数。 Observation: 接收工具返回结果。 ... (可重复多轮) Final Answer: 综合所有信息,生成最终视频参数描述。这个框架不新鲜,本质上是经典的ReAct循环,但落地的时候有个关键取舍——我把工具的调用策略分成"强制型"和"自主型"两种:
- 强制型:当用户prompt里包含明显的物理过程关键词(如"碰撞""坠落""流体""运动轨迹")或特定知识背景关键词(如"维多利亚时代""上世纪90年代的老北京胡同")时,系统直接强制插入工具调用,不让模型自己决定。这个兜底策略极大提升了稳定性。
- 自主型:prompt中没有明显的工具需求特征,完全交给模型根据理解自主判断是否需要工具介入。这个模式考验模型的泛化能力,也是训练和调优的重点。
为什么做这种区分?因为在实践中我发现,8B模型在"工具必要性判定"上确实比大模型弱——有时候明明需要检索背景知识它却直接生成,有时候不需要任何额外信息它偏要去调用个没用的工具。强制型规则兜住下限,自主型能力决定上限,两者配合才能稳。
2.3 执行层:视频生成引擎如何消费工具返回的结果
工具返回的数据,最终要跟视频生成模型对接。我用的是一个以扩散模型为骨干的视频生成架构,支持以控制信号的方式注入额外条件。
对于不同工具类型,对接方式完全不同:
- 物理模拟结果:把物体的运动轨迹转换成一系列引导信号,在生成过程中约束对应区域的内容位置变化。比如模拟结果显示一个杯子从桌面掉落到地面经历了约0.4秒、落地时发生碎裂,那视频生成模型就要在对应的帧区间内呈现"杯子下落→触地→碎片飞溅"的过程。实现上这类约束最复杂,我贴一段调度逻辑伪代码:
def build_motion_condition(sim_result, video_cfg): """将物理模拟结果转为视频生成的运动控制条件""" conditions = [] for obj in sim_result.objects: # 每个物体取出关键帧的坐标与姿态 trajectory = obj.trajectory # list of (t, x, y, z, rx, ry, rz) # 插值到视频帧率对应的时间轴 frame_trajectory = interpolate(trajectory, fps=video_cfg.fps, frames=video_cfg.total_frames) # 转成空间注意力掩码或深度条件 cond = MotionCond( obj_id=obj.id, bbox_sequence=frame_trajectory, motion_type=obj.motion_type # fall, collide, fluid_flow ) conditions.append(cond) return conditions def generate_with_tools(prompt_embed, tool_conditions, generator): # 把工具条件叠加到常规的生成采样流程中 noise = torch.randn(video_cfg.latent_shape) for t in tqdm(scheduler.timesteps): cond = torch.cat([prompt_embed, tool_conditions], dim=-1) noise_pred = generator.unet(noise, t, cond) noise = scheduler.step(noise_pred, t, noise) return decoder(noise)知识检索结果:这些文本信息处理起来容易些,直接跟用户prompt拼到一起,压缩进文本编码器的输入。核心技巧是要做信息筛选,不能把检索回来的所有文本块都塞进去——8B模型的上下文窗口有限,塞太多反而稀释了重点。我设计了一个简单的相关性截断策略:只保留与prompt中核心名词(通过NER抽取)重叠度最高的2-3个文本块。
场景布局结果:转换成初始帧的布局条件,通过跨注意力机制注入,约束首帧中物体位置、大小、类别。后续帧的演进依然靠扩散模型自回归生成。
3. 训练数据的构造:想教会模型调工具,要给它一本"行动手册"
结构搭好了,接下来是训练。很多做Agent的朋友一上来就问模型结构怎么改,但实际上这个项目里模型结构我没动一刀,做的是LoRA微调。关键全在数据。
3.1 轨迹数据的来源:与其人工标注,不如"教师模型蒸馏"
8B模型要学的不是"知识",而是"工作流习惯"。所以训练数据必须是完整的工具调用轨迹——从用户请求,到模型判断要调工具,到观察返回结果,再到调整思路继续行动,最后生成正确答案。
这个轨迹数据怎么来?人工构造太慢,而且容易自我重复。我采用了一种半自动的生产链路:
- 准备一组覆盖不同难度等级的用户请求(约5000条种子请求,包含强制工具型、自主判断型、纯生成型三类混合分布)。
- 让一个具备强工具调用能力的大模型(教师模型)逐条执行完整的ReAct循环,保存中间的思考、动作、观察。
- 对教师模型产生的轨迹做质量过滤。过滤规则包括:工具是否调用正确、观察结果是否真的被后续行动消费、最终生成内容是否包含工具返回的关键信息。
- 把通过过滤的轨迹转写成训练格式,关键字段包括系统提示、用户请求、模型的工具调用序列(Think/Action/Observation交替格式)、最终响应。
这套流程跑完之后,我拿到了大约3万条高质量轨迹。有一条我印象很深的过滤规则:轨迹中如果用到的工具次数超过5次但任务本身并不复杂,这条轨迹会被降权甚至丢弃。因为工具调用链条越短,模型越容易学会"精准决策",而不是"滥用工具"。
3.2 训练策略的关键:任务难度的渐进式课程
数据准备好之后,训练也不是一股脑堆进去。我参照课程学习(Curriculum Learning)的思路,把数据按难度划分成了三档:
- 认知构建期(前30%的数据):只用"工具类型单一、调用轮次为1"的简单轨迹。让模型先建立"有需求-调工具-用结果"的基础映射。
- 能力扩展期(中间50%的数据):引入"工具类型混合、需要判断不同场景选择不同工具"的任务。比如同一段prompt里既需要查资料,又需要做物理模拟。
- 综合应用期(最后20%的数据):用"工具调用失败后需要自主纠错""工具调用轮次≥3"的高难度轨迹。
这个渐进安排的效果非常明显。一开始我也试过直接全量数据一股脑训练,结果模型在小样本上表现不错,但一遇到稍微复杂的任务就乱套——经常是连续调用同一个工具好几次,或者调用工具之后返回结果没用上就直接生成。改成课程式训练后,模型的稳定性有了质的提升。
3.3 微调参数的实操记录:LoRA配置与训练稳定性
这里直接给出我实盘验证过的训练配置,供参考:
| 配置项 | 设定值 | 说明 |
|---|---|---|
| 基座模型 | 8B参数的多模态对话模型 | 支持文本+图像输入,但本项目主要用文本链路 |
| 微调方法 | LoRA(低秩适配) | 仅训练注意力层的低秩分支,原始权重冻结 |
| LoRA秩 | 64 | 秩太小声容不够,秩太大有过拟合风险,64是平衡点 |
| 学习率 | 2e-5,线性衰减 | 比常规微调要小,因为轨迹数据本身token量大,学习率太大会震荡 |
| 训练步数 | 约8000步 | 每步batch包含2048条轨迹片段 |
| 上下文长度 | 4096 token | 覆盖完整的多轮工具调用轨迹 |
| 精度 | bfloat16 混合精度 | 单卡显存消耗约48GB,双卡可跑 |
一个细节:训练时我在每个样本前都加了固定的系统提示,反复强调"如果你拿到的信息不足或者存在矛盾,你可以选择再次调用工具或者直接向用户说明"。这看似多余的引导,对模型在推理时的行为影响很大——它学会了在不确定时坦诚求助,而不是硬编。
4. 核心链路实现:一个视频从"查资料"到"生成"的全过程拆解
理论讲了一堆,这一节我用一个具体的例子串一遍整个链路。假设用户输入了这样一个请求:"请生成一段视频:一个红酒杯从桌面边缘滑落,砸在大理石地面上碎裂的过程。场景是1980年代巴黎左岸的一间咖啡馆。"
你可能已经注意到了,这个prompt同时命中了两个工具需求:物理模拟(红酒杯滑落-碎裂)和知识检索(1980年代巴黎左岸咖啡馆的视觉特征)。来,看系统怎么处理。
4.1 任务解析:先拆需求,再定工具策略
模型读完prompt后的内部思考轨迹大概长这样:
Thought: 这个任务包含两个核心信息维度。第一,"滑落-碎裂"是刚体力学的典型过程,需要调用rigid_body_sim来获取准确的运动轨迹和破碎形态;第二,"1980年代巴黎左岸咖啡馆"涉及具体年代和地域的视觉风格,我对这个特定时期的场景细节掌握不足,需要调用web_search检索参考信息。 Action: call rigid_body_sim(source="object_glass", ground_material="marble", initial_velocity=[0.3,0,0.05], gravity=9.8) Action: call web_search(query="1980s Paris Left Bank cafe interior design style", time_range="1980-1989")这个判断过程不是凭空出现的——训练数据里大量覆盖了这种"一个任务同时需要多个工具"的场景。模型学会了多线程拆解任务,而不是一股脑只生成。
4.2 工具执行与结果处理:拿到原始数据不是终点,是起点
工具执行层收到调用请求,分别返回两类结果。
物理模拟返回的是一段JSON格式的运动轨迹:
{ "object": "wine_glass", "motion": [ {"t": 0.00, "x": 0.00, "y": 0.75, "roll": 0.0}, {"t": 0.12, "x": 0.28, "y": 0.71, "roll": 18.5}, {"t": 0.24, "x": 0.55, "y": 0.63, "roll": 37.2}, {"t": 0.31, "x": 0.72, "y": 0.42, "roll": 52.8}, {"t": 0.38, "x": 0.76, "y": 0.02, "roll": 70.1}, {"t": 0.41, "x": 0.77, "y": 0.00, "break": true} ], "debris": [ {"id": "s1", "vx": 1.2, "vy": 0.3, "vz": 0.8}, {"id": "s2", "vx": -0.8, "vy": 0.5, "vz": 0.4} ] }我在这里踩过一个坑,值得提前说:模拟结果的精度要跟视频帧率对齐。最初我直接把模拟器的10Hz采样点丢给视频生成器,结果画面里物体的运动像"掉帧"一样一顿一顿的,很不自然。后来在调度器里加了线性插值,把模拟轨迹重采样到跟视频帧率一致(比如24fps),运动才变得平滑。
知识检索那边返回了几条语料片段,内容包括1980s巴黎咖啡馆的典型装修偏好——深色木地板、黄铜灯具、藤编座椅、墙面海报拼贴,以及那个年代特有的柔和暖色调光线氛围。这些文本块经过相关性截断后只保留了top2,拼接到prompt中。
4.3 条件注入:不同工具的结果走不同的"入口"
接下来是生产链路中最讲究的部分:
- 物理模拟结果:经过轨迹插值后,转换成一组空间控制信号。生成器在每帧计算时,会将物体的目标位置作为强约束条件叠加到注意力机制中,确保生成的酒杯运动轨迹与模拟结果吻合。碎片的飞散路径则作为辅助引导信号。
- 知识检索结果:作为文本上下文的一部分,进入文本编码器。这样视频生成模型在渲染"咖啡馆"时,能将这些年代特征映射到画面元素上。
- 场景布局建议:这里我没有让模型直接输出布局,而是让场景规划模块基于检索到的年代语料,生成一个初始场景物件清单和位置关系——包括咖啡桌在镜头左侧、酒杯位于桌子边缘右侧、背景墙面有几张怀旧海报等。这些结构约束会在首帧生成时做一次性注入。
整个多条件融合的生成过程我上面已经贴过核心SDK代码片段,本质就是把多个条件向量对齐后拼接进UNet的条件通道。实测效果中,物理约束的跟随性最好——生成的视频里酒杯从滑落到碎落的位移轨迹与模拟结果的相关性超过0.9。知识约束则体现在画面细节的还原度上:生成的视频中出现了藤编座椅、黄铜吊灯、墙面泛黄的海报,没有混入现代元素。
4.4 输出校验:让工具结果反哺生成质量审计
生成完之后,系统并没有直接交付用户。我在管线末尾加了一个初始评审模块——用一套轻量的视频理解模型(又是一个7B级多模态模型)对生成结果做质量审计:
- 检测画面中物体的运动是否与模拟轨迹有明显偏差(比如酒杯中途转向、碎片飞得过于整齐)。
- 检测场景元素与检索到的知识描述是否矛盾(比如出现了LED灯具这类不可能出现在1980年代咖啡馆的物件)。
如果审计不通过,系统会自动打回重生成,最多重试两轮并微调条件权重。这个环节让我省了很多"人工肉眼审查"的时间,特别是批量产出视频时价值极大。
5. 踩坑实录:这些坑你可能也会遇到
这一节我整理一下项目过程中印象最深的问题和解决思路,全是真金白银换来的。
5.1 工具选择偏差:调了工具,但调了错的工具
现象:模型面对一个涉及流体场景的任务,却调用了刚体模拟工具,返回了"假设理想刚体"的结果。生成的画面里水花效果依然错误。
排查过程是这样的:我先去检查训练数据中"流体类关键词"的覆盖量,结果发现确实偏低——种子请求里关于水、烟雾、蒸汽的场景只占7%左右,模型对这类任务的工具映射学习不够充分。修复合规数据配比:把流体类任务的比例提到15%,同时专门构造了一批"同一场景下刚体与流体都可用但结果不同"的对比样本,强制模型通过语义判断工具边界。
教训:训练数据里某一类工具的"曝光度"不足,模型对它就会产生选择性遗忘。做数据配比时,工具类别分布比任务类别分布更重要,每个工具至少要保证15%以上的出现率。
5.2 多轮循环死锁:模型在工具调用里出不来
现象:任务已经是纯生成型任务(比如"阳光洒在湖面上"这种意象性prompt),模型却连续调用了3轮工具,每轮返回结果都差不多,还是不进入生成阶段。
这个问题本质上是工具的"必要性判断"没学好。我做了两层修复:
- 数据层面:增加"不调用工具直接生成"的轨迹样本比例,从原来的15%提到30%。特别注意在训练损失中给"过早调用工具"的loss加了一倍权重,让错误动作的梯度惩罚更明显。
- 推理层面:加了一个硬性"阀值轮次"——如果ReAct循环超过5轮仍在调用工具,调度器就强制终止工具循环,直接带着已有信息进入生成阶段。
这套组合拳打完之后,工具乱调率从8%降到了2%左右。
5.3 幻觉消除不彻底:工具返回的信息被"睁眼瞎"掉
现象:工具明明返回了正确的背景信息(比如"该场景应为暖色调、藤编座椅"),但最终生成的视频里这些特征完全没有体现。
这不是工具没调用成功,而是生成的视频引擎没有收到条件约束。我排查后发现问题出在对齐环节——知识检索返回的文本经过prompt拼接后,由于文本量太大、跟原有prompt挤在一起,重点信息被"淹没"了。解决办法是:在拼接时对检索文本做了显著性标识,在文本编码时给予更高的关注权重(通过加权token的方式实现),而不是简单字符串拼接。这一步改造之后,知识使用率明显提升,场景还原度评分平均涨了18%。
6. 效果评估:如何客观衡量"会查资料、会做模拟"这件事
聊了这么多架构和实现,最终要回答的问题是:这套系统到底比"直接生成"强在哪?我的评估体系分成三个维度。
6.1 工具调用准确率:做对事的前提是选对工具
我在一个500条测试请求的集合上做了评测,请求覆盖了物理模拟类、知识检索类、纯生成类、混合类四种难度,统计两个指标:
| 指标 | 直接生成基座 | 8B智能体(未用工具) | 8B智能体(项目最终版) |
|---|---|---|---|
| 工具选择准确率 | — | 无法评估AUC | 89.6% |
| 工具效率指数(有效调用/总调用) | — | — | 76.8% |
| 任务完成率(视频可用比例) | 41.2% | 52.3% | 84.7% |
"工具效率指数"这个指标我特别关注——它衡量的是模型有没有"瞎调工具"。最终版有约23%的调用是无效的(比如明明直接生成更好,模型却多此一举地调了检索工具),说明还有优化空间,但相比第一版已经好了非常多。
6.2 物理一致性与知识还原度:和基座模型比到底强在哪
除了工具调用层面,我还用两个专项指标评测了最终生成视频的质量:
- 物理事件准确率:人工判定生成的视频中,物理事件(如碰撞、掉落)的发生时序和运动形态是否符合真实世界规律。基座模型约为35%,项目系统达到88%。最明显的差异在"触发时序"——基座模型经常提前或延迟呈现物理结果,工具系统则能把控到帧级精度。
- 知识还原度:针对含有特定背景知识要求的请求(比如某个年代、某个地域特色),统计场景元素是否准确呈现以及是否出现时代错位。基座模型约为40%,项目系统达到80%。知识还原度的偏差主要发生在检索语料本身覆盖不全的场景——工具再强,也怕"仓库里没货"。
6.3 那21%的失败任务:边界在哪里
有效但不够好,那剩下的15.3%任务失败在哪?我逐一分析了失败样本,总结成三类:
- 条件冲突(占失败样本的45%):物理模拟结果和知识检索结果之间存在冲突。比如模拟器计算出酒杯落地时间为0.41秒,但知识库中描述"这种酒杯非常轻、下落较慢"——两个约束冲突,生成引擎不知道听谁的。目前的方案是让调度器检查条件冲突,按"物理优先、知识次之"的优先级降级处理,但这明显不是最优解。
- 极端复杂场景(占失败样本的32%):多个物体交互、遮挡关系复杂、场景内部有多层结构的视频,控制信号太密集,扩散模型难以在有限步数内同时满足所有约束。
- 生僻知识盲区(占失败样本的23%):检索库覆盖率不足,工具返回结果都是"低相关性"的泛泛内容,信息价值约等于零。
针对这三类问题,我的后续计划很明确:条件冲突场景建一个干扰消解模块;极端复杂场景改为"分段生成再拼接",降低单次采样压力;生僻知识盲区则持续扩充工具库,考虑接入更多行业的垂直数据源。
7. 实操中的额外收获:一些你可能没注意到的细节技巧
内容写得比较满了,最后分享三个我在项目过程中总结的、不占主干但实战价值很高的技巧。
技巧一:工具的"观测结果"要带时效属性。我第一次设计工具返回时,没有给数据加时间戳。后来发现模型在多次调用同一个工具时,经常把旧结果当成新结果来用——比如第一次模拟得出的轨迹,在第二次模拟后依然被引用。给每个工具返回结果加上生成时间,并在prompt中明确标注"此为最新结果",模型的引用混乱率降低了六成。
技巧二:训练时故意注入一批"工具调用失败"的轨迹。任何能自主调工具的Agent,迟早都会遇到工具本身出错的情况——服务器超时、检索不到内容、模拟器报错。如果你只在训练数据里放"工具总是可用"的样本,模型一旦遇到真实环境中的失败,只会崩溃或无限循环。我额外构造了2000条"工具返回错误/空结果,模型如何自救"的轨迹数据,这个动作让系统在真实环境中的鲁棒性提升非常明显。
技巧三:系统提示词里加一句"你正在被评估"其实是有用的。这是一个经验性发现:当系统提示词明确告知模型"你的工具调用行为将被用于质量评估,选择调用工具的数量应遵循最小必要原则"时,模型在推理阶段会倾向于减少冗余调用。这可能是因为提示词激活了模型的指令遵循机制,让它更留意动作的成本意识。当然,具体机制还需要更严谨的实验验证,但从工程效果上看,这个"暗示"值得一试。
项目做到现在,我最大的感受是:让模型学会调用工具,本质上是在给生成系统补上"理解世界"的短板。模型不需要变成一个万事通,它只需要知道自己的知识边界在哪里,然后学会在边界之外向工具求助。这个思路,我相信在视频生成之外的其他生成任务里同样适用。如果你正在做类似的Agent项目,希望这篇记录能给你省下一些试错的时间。如果你有更好的工具编排思路,也欢迎在评论区交流。