Skip to content

pstack 拆解 15 · 对抗:让模型互相挑错 ​

生成和评判要分开。这一篇讲两种让不同模型互相挑错的方式:把一块地切成片分头查,或者让多个模型对着同一份 diff 找问题。

swarm ​

有些工作可以切成互不重叠的片,有些可以让几路同时跑、事先声明怎么选赢家。切开了就能并行覆盖,而且每一片都有自己的检查,父进程只收一份合并后的报告。它和 arena 的差别不在并行,在目的:arena 是同一个 brief 的多解,swarm 是覆盖或赛跑。

swarm 把 N 个 worker 铺开,它们可以覆盖互不相同的切片、覆盖矩阵、gauntlet lane、探索分区,或者声明的竞速臂。每个 worker 有自己的范围和检查,回报 PASS、ISSUES 或 BLOCKED。父进程等所有人回来,只返回一份紧凑报告。

它的阶段是四个。

Phase A: Frame。 先声明完成谓词和这次要返回的产物或报告。然后选形状:切成互不重叠的切片、让 N 个 worker 跑同一个 brief 竞速,还是两者混合。

如果是竞速或混合,必须在发出去之前就声明选择规则:先到先得、全部排名,还是取最好。事后才知道要按什么选,那场竞速就没有意义。

然后定 worker 模型,给每个 worker 一份自己的可写输出。测量类的 brief 必须写明确切的 SHA 和方法(采样数、一个样本是什么、顺序),worker 要把这两样都记进结果。

Phase B: Fan out。 默认用云端 worker,一次消息全部发出去,每个 worker 一台机器,从根上避免共享写。必须本地跑时才用本地。

Phase C: Aggregate。 读每个 worker 的结论。一个没有记录 brief 里要求的 SHA 和方法的结果,直接丢掉,重派一次;第二次还没有,就记成一个缺口。而缺口不算通过。 覆盖形状下,每一个必需的切片都要有结果。竞速形状下,套用事先声明的规则。不要把 worker 的原始输出复制粘贴上来。

Phase D: Report。 交回一份合并报告:一张紧凑的表,一行一条带证据的 issue,明确的缺口或掉队,以及竞速时用到的规则。

interrogate ​

对抗信号来自模型差异,不是来自指定的人设。不同模型有不同的盲区,所以两个模型各自独立提出的发现,是最高置信度的信号;而同一个模型提出的、又和它自己生成的东西相关的判断,几乎没有信息。这正是"生成和评判分开"的一个具体形态。

interrogate 把同一份 diff、意图和 rubric 发给不同模型族上的 reviewer,让它们从各自的角度挑战这份改动。

它的步骤是这些。

确定范围。 你指了文件或 diff 就用那个;在功能分支上就跑 git diff main...HEAD 拿完整改动集;如果消息提到最近的工作,就把相关文件收集起来。它还要把理解这份代码所需的周边上下文一起打包。

先明说意图。 在派出任何 reviewer 之前,它把这次改动的意图写成一段话,来源是:你的消息、提交信息、PR 描述、以及代码本身。如果它不确定意图,它先问你。这一步是必要的,因为 reviewer 是在评判"这个改动有没有达到它想达到的目标",意图不清,评判就没有锚。

派 reviewer。 按配置好的模型列表,一个模型一个 reviewer,所有人拿到完全相同的 prompt:同一段意图、同一份 diff、同一套 rubric、同一个代码质量镜头。

合成。 把所有发现放在一起:共识(2 个以上模型独立提出)是最高信号;单独一个模型的发现仍然值得读,但权重要低;不同模型用不同方式描述同一个问题的,合并,并标出是哪些模型提的;一个模型报了什么、另一个明确说了相反的,这个分歧本身是好线索。

你来当 lead。 你是一个务实的资深工程师,不是中立的汇总器。把每条发现分进四个桶。

  • Act on:真的影响正确性、安全或可维护性,会挡住一个真实 PR。
  • Consider:合理,但不确定现在值不值得处理。
  • Noted:有效但不可行动,比如依赖上下文、过早优化、当前阶段影响很小。
  • Dismissed:错的、挑刺的,或者缺少上下文,给一句简短理由。

每条都要标明是哪些模型提出的,以及分到这个桶的原因。它不自动应用任何改动。

这里有一条重要的使用边界。interrogate 要用在 diff 上。你把对抗性审查指向一个还没有代码支撑的计划,reviewer 会凭空发明永远不会发生的风险和边界情况。先用原型把开放问题解决掉,再审查做出来的东西。

参考 ​

原文都在 pstack 上游仓库(cursor/plugins):