AI 工程实践

并行不省 Token:Agent 成本怎么算

拆解 Agent 全链路成本,区分并行的时间收益与 Token 账单,并给出工具和多 Agent 协作的选择方法。

Kane约 23 分钟阅读
  • Coding Agent
  • Token 成本
  • 多 Agent
  • 模型路由

旨在解决一个问题:在不降低正确率和证据质量的前提下,如何用更少的总成本获得可验收结果?

AI Coding Agent 的成本不只由模型单价决定。 真正影响成本的是一整条工作链:重复上下文、模型路由、工具输出、无效往返、失败重试,以及多个 Agent 之间的重复读取。

更低成本 =
  更少重复上下文(RTK、Caveman、headroom、context-mode、会话管理)
+ 更合理模型路由(任务匹配、Skill 绑模型)
+ 更精准代码检索(Graphify、CodeGraph)
+ 更清晰 Agent 分工(subagent 隔离、worktree 并发、记忆外置)

主要有六类成本:

成本 典型来源 首要手段
固定上下文 System Prompt、AGENTS.md、常驻 Skill 和工具定义 精简、分层、按需加载
会话历史 旧任务、多轮补充、无关讨论 一个会话一个目标、/new、/compact、/handoff
工作材料 文件、网页、日志、MCP 和浏览器快照 精准引用、先提取再汇总、输出压缩
模型调用 所有任务使用同一强模型 角色路由和条件升级
失败与重试 模糊需求、错误工具、窄验证、返工 一次说清、约束输出、证据驱动验证
协作开销 多 Agent 重复读取背景、结果冲突 清晰边界、结构化交接、只并行独立任务

范式:

  • herdr 解决多会话的持续运行、布局、状态可见和重新连接,传递 agents 之间的信息。
  • codex/claude code -> gpt 5.6 sol(max)/claude fable -> 计划/审阅
  • omp/pi -> k3/dsv4flash/gpt luna/claude sonnet -> 执行

通过工具减少 token 消耗

层级 工具 是否必装 解决的问题 什么时候安装
命令输出 RTK 推荐按需 压缩测试、Git、构建等终端输出 命令输出经常占满上下文时
综合上下文代理 headroom 按需 压缩文件、工具返回、会话历史,可选记忆和代码图谱 多类材料反复进入上下文时
MCP 结果压缩 context-mode 按需 压缩浏览器、数据库、文档等大型 MCP 返回 MCP 快照是主要上下文来源时
回复压缩 Caveman 按需 缩短 Agent 的自然语言回复 已明确输出格式,回复仍持续过长时
静态代码图谱 Graphify 二选一 先定位入口、符号和关系,再读源码 大仓库入口难找、语言较多时
持久代码图谱 CodeGraph 二选一 调用追踪、影响分析、持久化图查询 经常做跨模块追踪和重构影响分析时
真实页面验收 Kimi-webbridge/BrowserSkill/ego lite Web UI 必需 验证布局、交互、登录态和浏览器行为 交付条件包含真实网页体验时
并发代码隔离 Git worktree 按需,Git 自带 防止多个 Worker 同时修改同一工作区 多个独立代码任务需要并发修改时
多会话工作台 Herdr 按需 持久运行多个 Agent、窗格管理、状态可见、断开后继续运行 需要长任务、多 Agent 或独立 Reviewer 时

专项上下文工具

工具可以分成三类:压命令输出、压模型回复、压进入上下文的材料。第四类代码图谱工具解决「读哪里」,并不直接压缩文本。**先有可观测瓶颈,再装工具;每次只引入一个变量,比较安装前后数据。**这些工具对应第一章成本表的「工作材料」行。

症状 先做什么 再考虑什么
测试与 Git 输出过长 限定命令范围、使用 RTK 自定义过滤规则
Agent 回复太长 明确输出契约 Caveman
MCP 快照巨大 缩小查询或元素范围 context-mode
多类材料反复进上下文 改会话边界与提取流程 headroom
Agent 不知道该读哪些文件 给入口、用 LSP/代码搜索 Graphify 或 CodeGraph
仓库很小、调用关系简单 保持原工具链 通常不需要图谱

RTK:压缩终端命令输出

作用:过滤 ANSI、进度条、重复告警、注释和空行,减少测试、Git、构建和搜索输出进入 Agent 上下文的体积。透明过滤,无感知。

安装:

# macOS(推荐)
brew install rtk

# Linux / WSL
curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/master/install.sh | sh

# 按 Agent 启用
rtk init -g                    # Claude Code(默认)
rtk init -g --codex            # Codex
rtk init -g --gemini           # Gemini CLI
rtk init -g --agent cursor     # Cursor
rtk init -g --agent omp         # omp(Fork 版)

重启 Agent 后生效,透明过滤,无感知。

注意:装完用 rtk gain 验证;若命令不存在,可能是装了同名的 Rust Type Kit,需卸载重装。

常用命令:

  • rtk gain(看节省统计)
  • rtk gain --history
  • rtk discover(扫描未覆盖的命令)
  • rtk git status
  • rtk git diff
  • rtk test cargo test
  • rtk vitest run
  • rtk proxy <cmd> 直通不过滤

headroom:压缩进入上下文的多类内容

作用:压所有进上下文的内容(文件、工具返回值、会话历史)。 可逆压缩(CCR):原始数据留本地,按需取回。 代理层还含 CacheAligner(稳定前缀促缓存命中)、ContentRouter(按类型分流),可选记忆和代码图谱能力。

会注册三个工具:headroom_compress、headroom_retrieve、headroom_stats。

接入:

# 先这样试
# 安装
uv tool install --python 3.13 "headroom-ai[all]"
npm install headroom-ai

# 验证
headroom doctor

# 基础接入
headroom wrap omp
headroom wrap omp --memory --code-graph   # 推荐:跨 session 记忆 + 代码图谱
headroom wrap codex

# 做 3~5 个你平常会做的长任务

# 看效果
headroom perf
headroom dashboard

# 恢复
headroom unwrap omp

MCP 模式(不想用 wrap):

headroom mcp install

上线前验收:

  • 被压缩引用能否回取;
  • 代码块是否完整;
  • 关键错误日志是否被误压;
  • 记忆和缓存存在哪里;
  • 敏感数据是否离开本机或项目边界。

这类代理层工具改变了 Agent 实际看到的材料,属于「物理外挂」。 Token 下降 + 完成率持平,就有实用价值;Token 下降 + 漏信息增加,压缩策略仍需要调。

context-mode:压缩 MCP 工具结果并维持会话连续性

作用:

  • Sandbox 工具输出(官方示例 315KB→5.4KB,约 98% 压缩,未复现;如 Playwright 快照);
  • 跨 /compact 会话连续性(本地 SQLite + FTS5,压缩后只检索相关事件);
  • ctx_execute() 用代码代替读文件;
  • 不干预输出格式。
路径 命令 路由合规
插件(推荐) omp plugin install context-mode → 重启 → omp plugin doctor ~98%,自动注册 MCP

验证(omp 会话内):

  • ctx stats(按工具看节省)、
  • ctx doctor(全部正常)、
  • ctx insight(本地看板)。

典型场景:

  • 浏览器快照体积很大;
  • 数据库查询或文档工具频繁返回大块内容;
  • /compact 前后的工具材料需要本地可检索连续性。

Graphify:静态代码图谱(与 CodeGraph 二选一)

作用:Tree-sitter 解析代码建图谱,AI 查图代替反复读文件。

生成 graphify-out/ 下三份产物(graph.html / GRAPH_REPORT.md / graph.json); 官方称 52 文件语料下减少 71x+ Token;支持 30+ 语言; git hook 或 --watch 增量更新。

安装:

uv tool install graphifyy
# 或
pipx install graphifyy

接入 omp:graphify install --platform omp / graphify omp install 不存在。

当前 CLI 只有 install(Claude Code skill)、vscode install、claude install、hook install、benchmark 等子命令。

omp 下用 MCP 接入:在 ~/.omp/agent/mcp.json 配置 graphify <项目路径> --mcp(官方用法 /graphify <path> --mcp,即启动 MCP stdio server)。

典型场景:入口难找、语言较多或模块关系复杂的仓库;小项目可能不值得承担索引维护成本。

CodeGraph:持久化代码图数据库(与 Graphify 二选一)

作用:MCP Server + 持久化图数据库(Neo4j/KuzuDB)。

核心工具:codegraph_context(找入口)、codegraph_trace(追调用路径)、codegraph_impact(重构前影响分析)。

benchmark:平均 62% 更少 Token、88% 更少 Tool Call、44% 更低成本;大型 Rust/TypeScript 项目收益最显著,中小 Java/Go 项目收益有限。

安装:

npm i -g @colbymchenry/codegraph
cd your-project
codegraph init -i

接入 omp(文章路径,已核验有效):

{
  "mcpServers": {
    "codegraph": {
      "type": "stdio",
      "command": "codegraph",
      "args": ["serve", "--mcp"]
    }
  }
}

图谱工具怎么选

需求 选
大仓库入口难找、语言多、静态符号导航 Graphify
跨模块调用追踪、重构前影响分析、持久化图查询 CodeGraph
都没有 不装,先靠 grep/glob/lsp

先在一个真实任务上测试一种工具,不要同时安装后再凭感觉判断收益。

Caveman:压缩 Agent 回复

作用:作用于输出端,压缩 AI 回复(输出 Token),工具方声明平均省 65–75%(未复现)。四档:lite / 默认 full / ultra / wenyan。

git clone https://github.com/studyzy/caveman
cd caveman && ./install.sh

使用:安装后通过 /caveman 启用,stop caveman 关闭。

典型场景:人只需要简洁结论;常规开发回复过长,已经明确输出契约仍有大量冗余。

不要使用:需要完整推理或审计记录;长篇文稿;必须严格符合 JSON schema 的机器输出。

注意:激进 brevity 提示词已被证实可能损害推理/编码质量。优先用「指定输出格式」约束,效果不够再加 Caveman。

多 Agent 工作台:Herdr

多 Agent 工作流落到真实终端后,会出现一组新的工程问题:

进程如何持续运行、窗口怎样组织、哪个 Agent 正在工作、断开终端后任务是否还活着、Reviewer 如何保持独立。

Herdr 是面向 AI Coding Agent 的终端多路复用器:用工作区、标签页和窗格管理长期运行的 Agent 进程,并通过集成识别生命周期状态。它不会替你拆任务,也不会自动保证并行安全;任务边界、共享数据和验收证据仍需在工作流层明确。

心智模型

按以下层级理解:

  1. Session(会话):持久运行的后台服务器;
  2. Workspace(工作区):项目级容器,通常对应一个仓库或一项独立调查;
  3. Tab(标签页):工作区内的一套窗格布局,例如 planner、workers、server、logs;
  4. Pane(窗格):真实终端进程;客户端断开后,窗格仍可继续运行;
  5. Agent(智能体):Herdr 在窗格中识别出的 AI Coding Agent 进程;
  6. Mode(操作模式):终端输入、前缀操作和持续导航三类交互状态。

最容易混淆的是 Session 与 Agent:Herdr Session 是承载工作区和终端进程的后台服务;OMP Session 是某个 Agent 的对话与会话树。前者保证进程持续,后者保存 Agent 上下文。

Agent 状态:

状态 含义
working 正在处理任务
blocked 等待批准、权限或用户回答
done 后台任务已完成,但对应标签页尚未查看
idle Agent 可接收输入,且标签页已被查看
unknown 已识别进程,但无法可靠判断生命周期

状态是调度信号,不是质量信号。done 只说明进程认为自己完成,不能证明实现正确。

安装与 OMP 集成

Linux 和 macOS 使用官方稳定版安装脚本:

curl -fsSL https://herdr.dev/install.sh | sh
herdr --version

安装 OMP 集成:

herdr integration install omp
herdr integration install claude
herdr integration install codex
herdr integration status

然后在 Herdr 新窗格中启动新的 OMP 进程:

herdr
# 在 Herdr 窗格内
omp

集成安装前已经运行的 OMP 进程不会自动加载新扩展,应重启该 OMP 进程。OMP 集成默认写入 ~/.omp/agent/extensions/herdr-omp-agent-state.ts。

可选:让支持开放 Skill 的 Agent 学会从窗格内控制 Herdr:

npx skills add herdrdev/herdr --skill herdr -g

先读取当前版本的权威能力和快捷键:

herdr --skill

进入 Herdr 后使用 prefix+? 查看实时键位。prefix 默认表示先按 Ctrl+B,松开,再按操作键。

实测基线(Herdr 0.8.0 stable,2026-08-22):后台连接正常、协议版本兼容;OMP 集成 current (v8),文件为 ~/.omp/agent/extensions/herdr-omp-agent-state.ts;Agent Skill 全局启用且 healthy(~/.agents/skills/herdr);窗格冒烟通过。它是安装后的验收清单,不是当前版本保证。

最少需要记住的操作

第一次进入优先通过鼠标熟悉结构:单击工作区、标签页、窗格或 Agent 聚焦;右键创建、分屏、重命名或关闭;拖动分隔线调整大小;终端内拖选复制。先看懂对象层级,再学前缀键。

操作 默认按键
查看当前快捷键 prefix+?
新建标签页 prefix+c
向右分屏 prefix+v
向下分屏 prefix+-
窗格间移动 prefix+h/j/k/l
打开工作区导航 prefix+w
缩放当前窗格 prefix+z
关闭当前窗格 prefix+x
分离客户端 prefix+q

静态表只用于入门,升级后以 prefix+? 为准。

分离、重连与停止

prefix+q             分离客户端,后台任务继续
关闭外层终端         通常同样只分离
从外部运行 herdr     重新连接
herdr server stop    停止服务器及所有窗格进程

herdr server stop 是破坏性操作:布局和受支持的 Agent 会话可能可恢复,但普通 shell 命令、开发服务器和其他任意进程已经终止。不要在 Herdr 的现有窗格里嵌套启动另一个不带参数的 herdr;应从外部普通终端重新连接。长任务离开前,先确认产物会持续落盘——进程活着不代表中间状态可恢复。

诊断顺序

遇到「Agent 没显示」「状态不更新」「无法重新连接」时,按层排查:

herdr status
herdr status server
herdr status client
herdr agent list
herdr integration status
herdr agent explain <target> --json

agent explain 可以帮助区分:当前状态来自原生集成,还是仅根据终端画面推测。只看到 unknown 时,不要立即判断 Agent 卡死;先检查集成状态和进程输出。

herdr --default-config
herdr server reload-config

60 秒冒烟演练

  1. 运行 herdr;
  2. 用 prefix+? 打开快捷键帮助;
  3. 用 prefix+v 创建右侧窗格;
  4. 在新窗格运行 pwd;
  5. 用鼠标和前缀键在窗格之间切换;
  6. 关闭临时窗格;
  7. 用 prefix+q 分离客户端;
  8. 从外部普通终端再次运行 herdr;
  9. 确认原布局和剩余进程仍在;
  10. 启动 OMP 后运行 herdr agent list、herdr integration status、herdr agent explain <name> --json,确认状态来自原生集成,而不是终端画面推测。

这个演练验证的是最重要的运行契约:分屏、聚焦、分离与恢复。

推荐布局

不要为了「像黑客终端」开十个没有边界的 Agent。先为每个标签页定义职责:

Workspace: current-project
├── Tab: planner
│   └── Pane 1: Orchestrator / Planner
├── Tab: implementation
│   ├── Pane 1: Implementer A
│   └── Pane 2: Implementer B(仅在文件范围独立时)
├── Tab: verification
│   ├── Pane 1: tests / build / server
│   └── Pane 2: 独立 Reviewer
└── Tab: evidence
    ├── Pane 1: logs
    └── Pane 2: diff / benchmark

布局只提供可见性。派工前仍需写清:每个 Agent 的目标、允许读取和修改的文件、输入与输出路径、依赖关系、何时可并行、验收证据。需要 Agent 间通信时,先阅读当前版本的 herdr --skill 和 CLI 帮助;不要从旧文章猜命令,也不要把完整会话历史互相复制,优先传结构化结果文件。

典型场景

  • 长时间迁移或测试修复,人离开终端后任务继续;
  • Planner、Implementer、Reviewer 使用独立会话,避免上下文互相污染;
  • 多个互不依赖的模块并行实现;
  • 单独保留测试、开发服务器、日志和 benchmark 窗格;
  • 需要快速看到哪个 Agent 正在工作、阻塞或等待查看。

不适合:任务很小、只有一个短会话,或多个 Worker 必须持续修改同一文件。

多 Agent 协作与 Orchestrator-Worker

为什么单 Agent 越用越贵

复杂项目里,单 session 很容易演变成这样:规划、写代码、跑测试、Code Review 全在一个会话;上下文越积越长(所有历史都往一个 session 里塞);所有任务用同一个模型配置,便宜活也用最贵模型。

职责越混,上下文越胖,成本越高。多 Agent 的潜在收益来自两点:每个 Worker 只看当前步骤需要的材料;不同角色可以使用不同模型,并对独立任务并行执行。但拆分也有成本:启动提示词、重复背景、数据交接、结果汇总和冲突处理。如果每个 Agent 都要读同一批文件,多拆只会更贵。这部分对应第一章成本表的「协作开销」行。

四种手段,别混用

/new、/compact、subagent、worktree 都和「上下文变轻」有关,但解决的问题完全不同:

手段 解决什么 历史怎么处理 代码改动怎么处理 适用场景
/new 切断无关任务 直接开新会话 仍在同一仓库 换话题、换需求
/compact 压长会话历史 保留摘要,不保留完整过程 仍在当前工作区 长任务续做
subagent 拆子任务 只给子任务需要的上下文 默认不做代码隔离 搜索、分析、验证
worktree 隔离并发改动 历史不是重点 独立 git worktree 多任务并行开发

一句话:/new 管任务边界,/compact 管历史长度,subagent 管职责拆分,worktree 管代码并发。

subagent:任务隔离的最低成本方式

omp 的 Skill 里可以直接调用 Agent tool,把子任务分发出去:

使用 Agent tool 分析这个 PR 的影响范围,然后把结果返回给我,不需要读具体实现文件。

每个 subagent 都应该有独立的上下文边界——它只看到自己需要的内容,主 session 只看到结果。

前提是子任务真的能拆开;如果每个 Agent 都要重复读同一批背景,拆得越多,反而越贵。

典型分工:

主 session(规划 + 决策)
  ├── subagent A:影响分析(只看图谱,不读源码)
  ├── subagent B:写实现(只看相关文件)
  └── subagent C:跑测试 + 生成报告

subagent 可以单独绑定便宜模型。规划用强模型,执行用便宜模型,两者在不同 session 里,互不干扰。

worktree 并发:多任务同时跑不冲突

有一批互相独立的任务要处理(比如修 5 个不相关的 Bug),可以用 worktree 模式并发:

主分支
  ├── worktree-1:修 Bug A(独立 git worktree)
  ├── worktree-2:修 Bug B(独立 git worktree)
  └── worktree-3:修 Bug C(独立 git worktree)

每个 Agent 在隔离的 worktree 里工作,改的是不同文件,互不冲突。怎么开:

开一个新的 worktree 分支修这个 Bug,修完后告诉我分支名,我来 review 再合并。

怎么合:worktree 没改动自动清理;有改动返回路径和分支名,自己决定 review 后合并。适用场景:互相独立的 Bug 修复;并行跑不同重构方案对比效果;同时生成多个文档。

Orchestrator-Worker 模式:把多 Agent 协作变成工程

把一个臃肿的长任务变成一个有分工的流水线:

Orchestrator(协调器 Agent)
  ├── 负责规划、拆解、调度、汇总
  ├── 通常不亲自读大量文件、不亲自跑命令(允许读关键状态文件)
  └── 只负责决策

Worker(子 Agent,按需派遣)
  ├── 每个 Worker 只做一件事
  ├── 只看自己需要的上下文
  └── 做完了把结果交回

为什么这个模式能省 Token?一个单 Agent 处理复杂任务时,它必须同时承载规划、代码阅读、工具调用、生成、验证的所有上下文——哪怕它当前正在做的只是「改一个函数」。Orchestrator-Worker 模式的本质,是让每个 Agent 只看和当前步骤相关的内容,而不是把整个任务的所有背景都塞进每一次调用。

统一口径(后续示例都按这个口径算):

总 Token 成本 = Orchestrator Token + Σ Worker Token + 汇总与重试 Token
墙上时间 ≈ 关键路径上各阶段耗时之和

并行只压缩墙上时间,不压缩 Token 成本——两个 Worker 各跑一轮,就是两次模型调用、两份账单。

典型成本对比(原始笔记的估算演示,无实验记录,仅展示数量级):

单 Agent 全程跑:
  System Prompt(5K) + 历史 (120K) + 规划 (10K) + 代码 (50K) + 工具结果 (30K)
  = 215K tokens × N 轮

Orchestrator + Worker 分工:
  Orchestrator 轮次:System Prompt(5K) + 任务状态 (2K) + 规划 (3K) = 10K tokens
  Worker A 轮次:目标 (1K) + 相关文件 (8K) + 工具结果 (5K) = 14K tokens
  Worker B 轮次:目标 (1K) + 测试文件 (6K) + 前步结果 (3K) = 10K tokens

  每轮成本约为单 Agent 的 1/5 到 1/10

在 omp 里,这个模式可以通过 Agent tool 直接实现——Orchestrator 在主 Skill 或会话里运行,通过 Agent tool 分发子任务,无需自建 Orchestrator 框架:

使用 Agent tool 执行以下子任务,上下文独立,不需要继承当前历史:

目标:定位 src/api/order.go 里的 CreateOrder Bug
上下文:只读 src/api/order.go 和 src/model/order.go
输出:把 Bug 描述和文件行号写入 .agent/findings.md

Orchestrator 不应只是「转发用户需求」。它必须在派工前定义接口:输入路径、允许修改范围、输出 schema、验收方式和依赖关系。它也不一定非要独立角色——单 Agent 顺序执行、每步手动裁剪上下文同样成立;Orchestrator 化只在该角色有持续多轮调度价值时才值得。

上下文隔离之后,数据怎么流转

上下文既然隔离了,Agent 之间怎么传递信息?

答案:通过共享外置文件,不通过会话历史。

会话历史是每个 Agent 私有的,不同 Agent 的历史无法互通。但文件系统是共享的。这意味着上下文隔离和信息共享可以同时成立:

Agent A 完成工作
  → 把结果写入文件(.agent/step1_result.json)
  → 上下文销毁

Agent B 开始工作
  → 读取文件(.agent/step1_result.json)
  → 只看这个文件,不看 A 的历史
  → 把自己的结果写入 .agent/step2_result.json

原则一:输出格式要结构化。自然语言在 Agent 之间传递时容易产生歧义,也难以精确定位所需信息。结构化的 JSON 更紧凑、更可靠,下游 Agent 只需要读它关心的字段。

示例发现文件 .agent/findings.json:

{
  "task": "locate-order-bug",
  "status": "completed",
  "findings": [
    {
      "file": "src/api/order.go",
      "line": 142,
      "issue": "错误路径未释放 inventory lock",
      "severity": "high"
    }
  ],
  "next_step": "fix-bug",
  "context_needed": ["src/api/order.go:120-165", "src/model/inventory.go:30-55"]
}

下游 Agent 收到的指令里只需要包含:

读取 .agent/findings.json,针对其中的 findings 数组修复代码。
修复完成后将结果写入 .agent/fix_result.json,格式参考 .agent/findings.json。

原则二:用进度文件追踪状态。复杂任务里,Orchestrator 需要知道每个步骤是否完成、是否失败、是否需要重试。这个状态本身也应该外置。

示例进度文件 .agent/progress.json:

{
  "task_id": "fix-order-bug-20260609",
  "created_at": "2026-06-09T10:00:00Z",
  "steps": [
    {
      "id": "step-1-locate",
      "status": "completed",
      "worker": "investigator",
      "output_file": ".agent/findings.json",
      "completed_at": "2026-06-09T10:02:30Z"
    },
    {
      "id": "step-2-fix",
      "status": "in_progress",
      "worker": "implementer",
      "started_at": "2026-06-09T10:02:35Z"
    },
    {
      "id": "step-3-test",
      "status": "pending",
      "depends_on": "step-2-fix"
    }
  ]
}

Orchestrator 每次唤醒时,只需要读这一个文件就能知道任务进展,不需要回放任何 Agent 的历史会话。状态文件只记录协作所需事实,不要把它写成另一份会话日志。

原则三:每个 Worker 的 context 包精心裁剪。新开一个 Worker 时,Orchestrator 应该明确告诉它「只读哪些东西」,而不是让 Worker 自己去探索:

# Orchestrator 派遣 Worker 时的指令模板

任务:为 CreateOrder 修复编写单元测试
上下文:
  - 修复内容:读 .agent/fix_result.json 中的 diff 字段
  - 现有测试风格:读 src/api/order_test.go(前50行)
  - 不需要读其他文件

输出:
  - 新增测试写入 src/api/order_test.go
  - 把测试覆盖情况写入 .agent/test_result.json

约束:
  - 只修改 order_test.go,不动其他文件
  - 测试不超过 80 行

这个指令本身很短(约 150 tokens),但它让 Worker 的上下文精准到最小必要集合。

原则四:临时文件及时清理。 .agent/ 目录是临时工作区,任务完成后可以归档或删除(清理前先确认其中没有仍需审阅的证据):

# 任务完成后归档
mv .agent/ .agent-archive/fix-order-bug-20260609/

# 或直接清理
rm -rf .agent/

这样不会污染代码仓库,也不会把旧任务的上下文意外带入新任务。

并行执行:时间与成本要分开算

独立的子任务可以同时启动,不需要等待。omp 的 Agent tool 支持在一次 tool call 里发出多个并行指令:

同时启动以下两个独立任务(使用 Agent tool 并行调用):

任务 A:为修复后的代码写单元测试
  - 读 .agent/fix_result.json
  - 读 src/api/order_test.go
  - 输出 .agent/test_result.json

任务 B:生成本次变更的 changelog 条目
  - 读 .agent/fix_result.json 中的 diff 字段
  - 参考 CHANGELOG.md 的格式
  - 输出 .agent/changelog_entry.md

两个 Worker 各自读取自己需要的文件,输入基本不重叠;唯一共享的是只读的 fix_result.json——下游任务本来就需要同一份最终 diff,重复的只是这一份稳定输入,不是彼此的会话历史。

并行只减少墙上时间,不减少总 Token。两个 Worker 并行跑,就是两次模型调用、两份账单。若两个 Worker 重复读取同一批背景,总费用可能上升。实际加速倍数受任务独立性、Orchestrator 启动与汇总开销、I/O 竞争影响,达不到 N 倍;具体倍数需要你在真实任务上计时,原始笔记中的精确区间没有附任务、模型、轮次与计时方法,本文不采信。

适合并行:

  • 不同模块的 Bug 修复(改的文件没有交集);
  • 代码 + 测试 + 文档(三者可以同时生成);
  • 多个文件的格式化/重构(无依赖关系);
  • 影响分析 + 实现方案设计(可以同时推进);
  • 两种方案的隔离实验。

必须串行:

  • 有顺序依赖的步骤(先定位 Bug 才能修复);
  • 修改同一个文件的多个任务(会产生冲突);
  • 依赖上一步输出的任务(需要等待);
  • 下游输入 schema 尚未确定。

完整的编排流程:一个端到端示例

场景:给一个中型 Go 项目做 API 层重构——把分散的错误处理统一改成标准 Error Wrapper,同时补充缺失的单测,生成一份重构报告。

以下数字是原始笔记的估算演示,非实测;用于展示数量级与费用结构,不构成可复现的 benchmark。

如果用单 Agent:

整个任务在一个 session 里跑
→ 随着轮次推进,历史越来越长
→ 到第 10 轮已经带着 150K+ 的历史
→ 每一轮都重新处理同一批背景
→ 中途 /compact 后,活跃上下文只剩摘要,现场细节需要 /tree 回溯
→ 原始笔记估算总成本:约 800K–1.2M tokens

用 Orchestrator-Worker 编排:

阶段 0:初始化
  Orchestrator 读 graph.json,分析影响范围
  → 生成 .agent/plan.json(步骤、文件列表、依赖关系)
  → Orchestrator 本轮消耗:~8K tokens

阶段 1:分析(并行)
  Worker A:扫描每个 API 文件,找出非标准错误处理,结果写 .agent/audit.json
  Worker B:读现有测试,评估覆盖率缺口,结果写 .agent/test_gap.json
  → 各自 ~12K tokens;并行不合并计费,本阶段合计 ~24K tokens
  → 墙上时间约等于单个 Worker 的耗时

阶段 2:实现(可并行)
  Worker C:按 .agent/audit.json 逐文件替换 Error Wrapper(每次只处理一个文件)
  → 每次 ~6K tokens × 文件数(按 5 个文件计 ~30K)

阶段 3:补测(串行,依赖阶段 2)
  Worker D:读修改后的文件 + .agent/test_gap.json,补测试
  → ~10K tokens

阶段 4:汇总(并行)
  Worker E:生成重构报告(读 .agent/audit.json + git diff)
  Worker F:生成 PR 描述(读 .agent/plan.json + .agent/ 各结果文件)
  → 各自 ~8K tokens,合计 ~16K tokens

按上表加总:8K + 24K + 30K + 10K + 16K ≈ 88K tokens,再加 Orchestrator 各阶段的汇总轮次与失败重试,原始笔记给出的总量级为 100K–150K。对照单 Agent 的 800K–1.2M(10+ 轮长会话估算),即「节省 70–85%」这一口径的来源——两端都是估算,不是实测,实际比例取决于模型、轮次与仓库规模。

成本差异的机制是确定的:

  1. 每个 Worker 只看当前步骤的相关内容,不带全程历史;
  2. 便宜模型处理执行任务,强模型只用于规划和决策;
  3. 并行减少时间成本,等待时间从串行叠加变成并行中最长的那个;
  4. 进度文件替代会话历史,Orchestrator 不需要回放所有轮次。

独立 Review

为什么独立 Review 比「再想一遍」更可靠

论文《When Can LLMs Actually Correct Their Own Mistakes?》(arXiv 2406.01297,Kamoi et al.,TACL 2024,见附录 B)给出的实践结论是:没有可靠外部反馈(测试结果、工具输出)时,模型仅靠自我反思,很难稳定纠正错误。

有效 Review 的增量来自四类信息:

  1. 新的方法:从反方、失效条件或特定风险出发;
  2. 新的先验:并发、状态恢复、边界输入、测试污染等高风险点;
  3. 新的证据:需求、diff、测试、类型检查、日志、benchmark;
  4. 新的独立性:使用干净会话,必要时更换模型或角色。

任何一项接近零,Review 都容易退化成措辞不同的重复回答。

四种 Review 提示的质量差异

类型 示例 信息增量
无信息 Review 「检查一下有没有问题。」 几乎没有
有方法 Review 「站在反方立场,找出会让方案失败的条件。」 提供搜索方向
有风险先验 Review 「重点检查并发、恢复、边界条件和测试污染。」 缩小高风险空间
有外部证据 Review 「基于需求、diff、测试、lint、类型检查和日志判断。」 提供可验证事实

最强的提示不是最凶的语气,而是证据最完整、风险范围最明确。

质量模型

Review Quality ≈
  Reviewer Capability
× Risk Prior
× Verification Signal
× Independence

五阶段流程

阶段 1:计划

Planner 在独立标签页中输出并落盘:目标、非目标、调用方、风险、迁移顺序、回滚边界和验收命令。计划先落盘,不直接交给同一会话「自我审阅」。

阶段 2:计划 Review

Reviewer 使用新会话,只读取需求与计划,重点找:

  • 未覆盖的调用方;
  • 互相矛盾的约束;
  • 不可回滚步骤;
  • 验证范围小于改动范围;
  • 把假设写成事实的地方。

计划确认后再实现。

阶段 3:实现

Implementer 只读取最终计划与相关文件。独立模块可分窗格并行;共享文件或有顺序依赖的步骤必须串行。并发改动需要 Git worktree 隔离。

阶段 4:结果 Review

Reviewer 不读取 Implementer 的完整对话,只读取真实交付证据:

Requirements
+ final diff
+ changed-contract tests
+ typecheck / lint
+ runtime smoke test
+ relevant logs or benchmark

这样能降低「沿用实现者叙事」的锚定效应。

阶段 5:缺陷修复

每个已证实缺陷建立边界清晰的修复会话。缺陷之间相互独立时,一个 Bug 一个 Session;同主题的连环小修可以合并到一次修复会话。修复后重新运行能证明该缺陷消失的最小场景,并检查是否引入回归。

可复制的 Reviewer 提示词

你是独立 Reviewer。不要沿用实现者的结论;只根据下列需求与证据判断。

输入:
- 需求:<path>
- 最终 diff:<path or command output>
- 相关测试结果:<path>
- 类型检查 / lint:<path>
- 运行时 smoke test 与日志:<path>

重点风险:
- 公开接口或调用方遗漏
- 并发与状态恢复
- 空值、边界输入和错误路径
- 测试污染、假阳性和验证范围不足

输出:
1. 仅列真实、可定位的问题,按严重度排序;
2. 每项给出文件与行号、触发条件、可观察影响;
3. 证据不足时写"未证实",并说明缺什么;
4. 没有问题时直接说明,并列出仍未被当前证据覆盖的风险。

这段提示词把 Review 变成反例搜索与证据审计,而不是礼貌性复述。

评估与审阅是两件事

  • 审阅(默认方法,证据驱动):按 11.4/11.5 执行,基于需求、diff、测试、lint、日志等外部证据判断。
  • 闭卷评测(专用场景,不是通用审阅方法):当你要评估模型对代码的独立理解时(例如选型或对比模型能力),禁止联网搜索、禁止外部工具、不依据此前对话或长期记忆,单纯依靠实现代码推理。它测的是「理解」,审阅验的是「交付」,两者目的不同;日常验收使用前者,不要用闭卷评测代替证据驱动 Review。

落地 SOP

  1. 收到需求,Codex + 强模型生成方案。
  2. 新开一个会话,对方案 Review(换模型,保证独立性)。
  3. omp + 便宜模型执行具体方案。
  4. 新开会话修复具体问题(缺陷间相互独立时,一个 Bug 一个 Session)。

验收 = 复现场景消失 + 回归检查 + 证据链完整。

典型场景操作卡

场景 A:日常单文件 Bug

安装:OMP;命令输出很长时加 RTK。

流程:

  1. /new;
  2. 用任务契约给出根因入口、允许修改范围和验收;
  3. 实现;
  4. 运行能复现该 Bug 的最小场景;
  5. 运行相关回归检查;
  6. 输出修改文件、根因和验证证据。

不需要 Herdr、多 Agent 或图数据库。

场景 B:跨模块重构

安装:OMP;大仓库按需选 Graphify 或 CodeGraph;需要独立 Review 时加 Herdr。

流程:

  1. /plan 找齐公开接口和调用方;
  2. 独立 Reviewer 审查计划;
  3. 按依赖顺序迁移;
  4. 只对互不重叠的模块并行;
  5. 运行 changed-contract tests、typecheck 和实际 smoke test;
  6. Reviewer 只读需求、最终 diff 和验证证据;
  7. /handoff 记录剩余工作。

场景 C:长时间测试修复或迁移

安装:OMP;需要离开终端时加 Herdr;输出噪声大时加 RTK。

流程:

  1. 用 /goal 写完整交付和验收;
  2. 设置 /goal budget <上限>;
  3. 机械重复步骤才使用 /loop;
  4. 在 Herdr 中保留 Agent、测试和日志窗格;
  5. 用 prefix+q 分离,不停止服务器;
  6. 返回后检查文件、退出状态、测试和日志——Herdr 的 done 状态只是进程视角,不等于验收通过。

场景 D:多个独立 Bug 并行修复

安装:OMP、Herdr、Git;按需使用 RTK。

流程:

  1. Orchestrator 先定义每个 Bug 的文件范围和验收;
  2. 每个 Worker 使用独立 worktree 和 OMP Session;
  3. 在 Herdr 中每个窗格只承载一个职责;
  4. Worker 输出结构化结果,不转发完整历史;
  5. 合并后统一运行最终测试和 smoke test;
  6. 独立 Reviewer 基于合并后的最终 diff 审查。

场景 E:MCP 或浏览器快照占满上下文

安装:先不加工具;确认问题持续后再加 context-mode。

流程:

  1. 缩小页面元素、查询字段或文档范围;
  2. 使用稳定输出 schema;
  3. 仍然过大时安装 context-mode;
  4. 用 ctx stats 观察收益;
  5. Web UI 的最终验收仍使用真实浏览器,不用压缩后的文本快照替代。

场景 F:Agent 不知道该读哪些文件

安装:先不加工具;大仓库再选择 Graphify 或 CodeGraph。

流程:

  1. 人工给出已知入口;
  2. 使用 LSP、符号搜索或代码搜索;
  3. 记录盲目读取的文件数和耗时;
  4. 选择一种图谱工具做同任务对照;
  5. 只有文件读取量、总时间或返工显著下降时保留。