一次 Video Agent 迭代如何长成 Harness 方法

2026-05-18review#ai-engineering#agent#thoughts

前段时间我在优化一个特定视频风格的 video agent。

任务不是“让它能生成视频”这么宽泛,而是让它稳定产出某一类风格:参考品牌的 Instagram / Reel 视觉语言,替换成另一个品牌或产品,同时保留构图、灯光、色调、运镜节奏,不把参考品牌的 logo、包装、文字带进最终画面。

这个任务很容易让人误判。

单看某一次输出,可能只是“还不错”或“不像”。但迭代几轮之后,问题会变得很难描述:有些版本更稳了,但风格变平了;有些版本更像参考视频,但产品识别变差了;有些修复看起来合理,下一轮却把原本好的 case 改坏。

我最开始没有想做一套方法论。

我只是想把每轮迭代效果记录下来,方便在开发 meeting 里对齐生成效果:这一轮到底改了什么,哪些 case 好了,哪些 case 退了,下一轮应该继续修哪里。

后来才发现,真正要优化的不是某一个 prompt,也不只是某段代码,而是整套 agent 迭代的反馈系统。

过程记录:从“对齐效果”开始

第一步很朴素:让 coding agent 每次跑完测试后,把结果同步到飞书文档里。

这些文档最初不是论文式记录,也不是写给外部读者看的报告。它更像一次开发协作里的效果看板。

一类文档负责横向对比:同一批 case,在不同版本、不同策略、不同生成链路下分别产出了什么结果。重点不是表格长什么样,而是所有人可以在 meeting 里指着同一行说:这个 case 是变好了,还是退化了。

另一类文档负责纵向展开:一个 case 从用户输入开始,经过素材抓取、风格分析、产品分析、素材编排、prompt 生成、工具调用,再到输出结果。它把 agent 的中间产物摊开,让问题不再只落在最终成片上。

这两类记录解决的是同一个问题:不要让 agent 只凭对话记忆理解上一轮发生了什么。

video agent 的一次失败,往往不是“成片不好看”这么简单。它可能是素材阶段拿错了参考,也可能是产品识别阶段没有拿到真实 SKU,也可能是 prompt 阶段把“参考构图”写成了“复刻参考产品”。

如果没有 trace,coding agent 很容易只改 render 那一层。

图 1:同一批视频 case 在多轮迭代中的效果对比矩阵

共享上下文:飞书文档变成外部记忆

跑了几轮之后,飞书文档的角色变了。

它不只是效果看板,而是 coding agent、sub agent 和我共同工作的界面。

coding agent 把测试结果写进去;sub agent 在文档里做独立 review;我会在旁边补充人工判断,比如“这个版本看起来更像参考风格,但产品主体变弱了”“这不是 bad case,是这个风格本来就应该保留的粗糙感”“这个修复方向不对,会把整体带向模板化广告片”。

这时飞书文档承担了三个角色。

Shared Context:所有参与者都围绕同一批 case、同一轮输出、同一组评论工作。

External Memory:跨轮次保存判断,不依赖一次对话窗口。

Review Surface:评论直接挂在具体段落、表格或结果上,不停留在泛泛的“效果不好”。

这一步让我对 harness 有了更具体的理解。

harness 不只是运行测试的脚本。对 agent 工作流来说,它还包括 agent 能读取的历史、能复用的案例、能被审阅的输出,以及能把审阅结果带回下一轮修改的通道。

图 2:一个 video agent case 的 phase trace 展开

独立评审:sub agent 更客观,但不是客观真理

后面我加入了 sub agent review。

它的价值在于独立上下文。

coding agent 刚改完 workflow,往往会顺着自己的补丁解释结果。比如它刚加了更强的 product constraint,就容易把“产品更清楚”看成进步;但我真正关心的可能是,产品清楚之后,原来那种参考品牌的随手感没了。

sub agent 从另一个上下文进入,只看到测试文档、输出结果和评审要求。它没有参与刚才那轮修改,所以更容易指出 coding agent 没意识到的副作用。

但这里不能神化 sub agent。

sub agent 仍然是主观评审。它可能偏向更清晰、更完整、更商业化的输出;也可能把某个风格里本来应该保留的噪声判断成缺陷。所以它不是最终裁判,而是一个上下文隔离的 AI reviewer。

这也是后面为什么需要人工校准,甚至需要迭代 sub agent 自己的评审 prompt。

三层 Review:固定脚本、AI、人工

做到这里时,我想起之前读过的 harness engineering 相关文章。

当时触发我的不是某个具体术语,而是一个判断:可靠的 agent review 不能只有一种信号。

我记得类似的观点是,harness 里的 review 至少需要三类东西一起工作:固定脚本、AI review、人工 review。

这和我正在做的事情刚好对上。

固定脚本负责没必要争论的硬规则。比如有没有生成文件,视频链接是否可访问,时长是否在目标范围内,输出里是否出现明显禁止的字幕、水印、品牌文字。

AI review负责高吞吐的语义判断。比如风格是否接近参考,产品是否被错误替换,镜头节奏是否明显偏离,某个版本相比上一版有什么退化。

人工 review负责方向和取舍。比如某个“粗糙”到底是失败,还是这个风格本来就需要的质感;某个规则要不要进入下一轮,还是只作为这次 case 的观察。

图 3:固定脚本、AI review 和人工校准组成三层评审

这时我意识到,我不是在让 coding agent“多改几轮”。

我是在给它搭一个小型 harness:运行 case、保存 trace、发起 review、读取评论、改代码,再回到下一轮 case。

Judge Calibration:AI 评审也要被迭代

sub agent 的判断有用,但不能默认可靠。

在视频风格任务里,AI reviewer 很容易稳定地偏向某些方向:更清晰、更完整、更像广告、更少噪声。这些偏好在普通质量评估里可能是优点,但在某些风格拟合任务里反而会把系统带偏。

所以我开始把 sub agent 也当成需要迭代的组件。

人工评论不只是补充漏判,而是在校准 judge 的方向:

  • 它把哪些风格特征误判成缺陷?
  • 它在哪些维度上判断比较稳定?
  • 它是不是过度奖励清晰度、产品占比或商业感?
  • 它的评审 prompt 是否需要加入“保留低保真质感”之类的约束?

这就是 Judge Calibration。

它不一定一开始就有 precision、recall、agreement 这些完整指标,但思路已经在那里:AI reviewer 的输出也要被抽检、降权、修正,而不是直接进入 coding agent 的修改依据。

边界知识:从评论走向条件

第一版循环的问题很快出现。

飞书评论对人有用,但对 coding agent 仍然太松。

比如我写“这个更像广告片了”,人能理解这背后可能包含过度打光、产品摆拍感太强、镜头太稳定、后期太干净。但 coding agent 可能只抓住其中一个点,把它改成“降低产品清晰度”。

这就是自然语言评论到代码修改之间的 grounding gap。

所以我开始沿着已有 harness 的实践,按照“积累边界”的逻辑整理问题。

边界不是一句“这个不好”,而是带条件的判断:

  • 当目标是保留 Instagram 随手感时,过度干净的 studio lighting 会把输出推向广告棚拍。
  • 当参考素材里出现的是源品牌产品时,只能提取构图、光线、颗粒和色彩,不能让目标 prompt 复刻源产品形状。
  • 当产品图分析没有拿到足够真实 SKU 时,继续 render 可能会生成虚构产品,这时宁可 fail fast。
  • 当为了强化产品识别而把主体放得过大时,style transfer 会退化成 product hero packshot。

这对应到后面整理出来的方法论,就是 Boundary Knowledge。

它的作用是把 bad case 从“某次输出很差”升级成“某类条件下会失败”。coding agent 读到的不再是情绪化评论,而是更接近规则的修改依据。

结构化边界:减少 Agent 之间的语义损耗

只积累自然语言边界,还是会有损耗。

同一句“产品被硬塞进场景”,可能指产品占比过大,也可能指光照不匹配,也可能指产品和人物动作没有关系。人能靠上下文补齐,coding agent 不一定每次都补对。

所以边界需要逐步结构化。

一个更稳的 boundary 至少应该包含:

  • category:问题属于风格、产品识别、素材选择、prompt 约束、运镜节奏,还是安全规则。
  • condition:问题在什么条件下出现。
  • failure:它伤害了什么目标。
  • evidence:关联哪些 case。
  • severity:它是必须修,还是观察项。
  • confidence:这个判断来自人工、sub agent,还是二者一致。

这不是为了把写作变成表格。

它是为了让 coding agent 少猜一点。尤其当 agent 之间靠文档传递信息时,结构化字段能减少“我以为你说的是另一个问题”的概率。

图 4:把 bad case 和 good case 分别沉淀为 boundary 与 exemplar

双信号:只积累 boundaries 效果一般

最开始我顺着 harness 的思路,主要在积累 boundaries。

这个方向是对的,但效果一般。

原因也很简单:只有 bad case,系统只知道哪里不能去,却不知道哪里值得保留。

每个 bad case 都在告诉 agent 不要做某件事:不要让产品太小,不要让 logo 泄漏,不要让画面太乱,不要让镜头太跳。规则越加越多,输出就越像安全模板。

但视频风格不是只要“不坏”就够。

有些东西恰恰是风险带来的:手持感、偶然构图、轻微过曝、素材里不那么商业的生活气、镜头切换里的不规整节奏。

所以我开始想把反馈做成双向的、系统化的。

一边是 boundaries,记录“什么条件下会坏”。

另一边是 exemplars,记录“哪些东西要保留”。

比如某个版本虽然产品没有最大化展示,但它保住了参考品牌的画面语气;某个 case 虽然有一点噪声,但整体最像真实 Instagram post;某个 prompt 结构虽然不够干净,但它减少了 AI 默认的棚拍感。

这就是 Good Case 回放。

good case 的作用不是证明系统很棒,而是给 coding agent 一个正面参照:下一轮修问题时,不要把这些东西一起修掉。

Golden Set:防止修一个坏一个

双信号再往前走,就会自然走到 Golden Set。

如果某些 good case 已经被人工确认过,下一轮修改就不应该破坏它们。否则 agent 会对最新评论过拟合。

我刚评论完“产品主体太弱”,它下一轮就可能把所有 case 的产品都推到画面中心;我刚评论完“参考风格不够强”,它又可能让源品牌元素卷土重来。

Golden Set 的作用是让 coding agent 先证明:这轮修复没有把已经成立的行为打坏。

它不一定一开始就有完整自动化。

最小版本可以很土:固定拿一批人工确认过的 case 回放,对比关键维度有没有下降。等 workflow 稳定后,再把它升级成 Regression Gate:通过率下降超过阈值,本轮修改就不能直接放行。

这就是我后来方法论文档里写的 Golden Set + Regression Gate。

图 5:Golden Set 和 Regression Gate 防止修复引入退化

Active Probing:从随机撞问题到主动找边界

早期测试更多是随机 case 或自然 case。

这种方式能发现问题,但效率不高。很多失败要撞运气才会出现。

比如一个边界可能不是“短转场一定坏”,而是“慢节奏叙事里短转场坏,快节奏音乐里短转场可以接受”。如果只靠随机 case,可能很久都看不清这个边界。

所以后续方法论里,我把它扩展成 Active Boundary Probing。

Probe Agent 的任务不是普通生成 case,而是围绕已有 boundary 构造边界附近的测试:

  • 在已知 bad case 的参数附近微调,找真正的临界点。
  • 把两个边界条件交叉组合,看是否出现新失败。
  • 专门生成 judge 低置信度的 case,逼出未知区域。

这部分不是我最初完整实践过的模块,而是从“随机 case 效率低”这个问题继续推出来的下一步。

Convergence:不要让循环变成无限修补

还有一个后续才变清楚的问题:什么时候该停?

agent 迭代很容易变成无限修补。每一轮都能找到一点问题,每一轮也都能改一点。但继续改不代表继续变好。

所以方法论里需要一组收敛信号。

这些信号可以很简单:

  • Golden Set 是否稳定。
  • 新 bad case 的数量是否下降。
  • 新增 boundary 是否还在快速增长。
  • 每轮 fix 后,原 bad case 变好的比例是否足够高。
  • sub agent 和人工判断的一致性是否稳定。

我不想把这部分写成“当时已经搭了完整 dashboard”。

更准确的说法是:实践先暴露了“靠感觉停不下来”的问题,后来方法论才把它扩展成 Convergence Metrics。

方法演化:从一套实践到一组工程模块

这套方法不是一开始设计出来的。

它是这样长出来的:

  1. 我先记录每轮 video agent 生成结果,用来在开发 meeting 里对齐效果。
  2. 记录文档变成 shared context,开始承担外部记忆和审阅界面的角色。
  3. 我加入 sub agent,让它在独立上下文里做 AI review。
  4. 我发现 sub agent 也有主观偏差,所以人工 review 变成 judge calibration。
  5. 我按已有 harness 思路积累 bad case 和 boundaries。
  6. 我发现只积累负反馈效果一般,于是加入 good case 和 exemplars。
  7. 我发现修复会破坏原本好的 case,于是需要 Golden Set 和 Regression Gate。
  8. 我发现随机 case 探索效率低,于是继续推到 Active Probing。
  9. 我发现循环需要停止条件,于是补出 Convergence Metrics。

这比给它起一个新名字更重要。

名字可以不要,但这组模块应该保留下来:Trace、Shared Context、AI Review、Human Calibration、Boundary Store、Exemplar Store、Golden Set、Regression Gate、Active Probing、Judge Calibration、Convergence Metrics。

它们共同解决的是一个问题:如何让每一轮实践产生的经验,真的进入下一轮修改。

最小可复用版本

如果把这套流程压到最小,我会保留六个模块。

Case Trace

每轮结果必须可回看。至少要能看到 case、版本、输入、输出链接、关键中间产物和 tool calls。对 video agent 来说,只看最终视频不够,最好能看到素材分析、manifest 和 render prompt。

Shared Review Doc

评论必须挂在具体结果上。不要只在聊天里说“这一版不行”,而是把评论放到具体 case、具体阶段、具体输出旁边。

Isolated AI Review

让没有参与修改的 sub agent 做 review。它不负责最终拍板,但负责发现 coding agent 可能忽略的副作用。

Human Calibration

人工评论负责方向、审美和取舍,同时校准 sub agent 的评审偏差。

Boundary / Exemplar Store

confirmed bad case 进入 boundary,confirmed good case 进入 exemplar。前者告诉 agent 哪些条件下会坏,后者告诉 agent 哪些东西不要被下一轮修掉。

Golden Set / Regression Gate

每轮修改后回看一批人工确认过的好 case。先保证不退化,再继续探索新问题。

这个最小版本已经能解决很多 agent 迭代里的走偏问题。

Active Probing、Judge Calibration 指标化、Convergence Metrics,可以作为下一阶段增强件接上。

关键 takeaway

  • 共享文档不是普通日志,而是 agent 迭代里的 shared context、external memory 和 review surface。
  • sub agent review 的价值在于上下文隔离,但它仍然需要人工校准和自身迭代。
  • 只积累 boundaries 不够,必须同时保存 exemplars 和 Golden Set,否则 agent 很容易越修越保守。
  • 从实践里长出来的 harness,本质是在设计反馈系统,而不是让 coding agent 凭感觉多跑几轮。

参考

我在实践中明确想起并对照过的文章:

后续和 agent 讨论这套方法论时补充的理论参照: