跳到正文
coograph 17

模型

Coograph 会把活分给六个代理,而它们的需求相差一个数量级。explore 读得多、判断少;debugger 读得少、判断全靠它。六个都跑在同一个模型上,要么为读的部分多花钱,要么让思考的部分力不从心。

Claude Code 一直支持给每个代理、每次调用单独指定模型。Coograph 现在用上了,而且会先问你。

五个工具,而模型清单是你的。 Claude Code、Cursor、VS Code Copilot、Codex CLI 和 OpenCode 都能给每个代理单独指定模型,所以 Coograph 会把映射写到那个工具读的地方。它做不到的是猜你手上有哪些模型:这五个工具要的模型 id 各不相同。所以由你声明一份清单,建议就按你的模型、你的价格来算。Aider 和 Cline 是完全另一回事 —— 见下面的覆盖范围

它从不替你决定

全新安装带的是 models.mode: unset。那不是一套默认映射,而是没有映射:每个代理都继承你当前会话的模型,和以前完全一样。

项目里的第一个工单会问一次,在调查之后、提案之前——因为那是第一次真正了解这活长什么样的时刻:

Coograph 可以让每个代理跑在不同模型上。你想所有代理用同一个模型、存一套映射,还是每个工单都问一次?

你的答案写进 openspec/config.yaml,然后无论你选了什么,这个问题都不会再出现。每个工单都问一遍,正是那种会让好功能因为错误原因被关掉的摩擦。

四种模式

模式行为
unset出厂状态。下一个工单问一次,之后再也不问。
off每个代理继承会话模型,永远不再提出建议。
preset静默套用已保存的映射,只有异常工单才会冒出建议。
per-task每个工单都先给出建议再使用。
# openspec/config.yaml
models:
  mode: preset
  preset:
    explore: haiku
    search: haiku
    verifier: sonnet
    reviewer: opus
    debugger: opus
    planner: opus
    retro: opus

sync 从不覆盖 config.yaml,所以你的选择能扛过模板更新。

两条命令

/coograph-suggest-multi-models 给出一套映射,针对项目或针对手头这个工单。每一行都写明代理、模型、一句基于你这次改动的理由,以及相对会话模型的预计成本差。你可以改任何一行、整体接受、或者拒绝。在你接受之前什么都不会写。它也是重新开启一个已关闭项目的入口。

/coograph-disable-multi-models 一步把 mode 设成 off。不会再问你一遍确认,因为这条命令只干这一件事。已保存的映射会留着,所以再打开时不用从零开始。

每次运行都告诉你是哪个模型干的

一次委派运行结束时会有一行:

models: reviewer=opus (mapping), explore=haiku (mapping)

它在每种模式下都打印。offunset 时它显示 (inherited) 并写出你的会话模型。这一行就是关键:没有它,你分不清映射是生效了还是被悄悄忽略了,而一个看不见的功能和一个坏掉的功能没有区别。

你的模型清单

一份映射只有在它写的模型你的工具能加载时才有意义,而没有两个工具的写法是一样的。Cursor 要 composer-2。OpenCode 要 provider/model-id。Copilot 只认它自家厂商的模型。由我们发一张 Anthropic 别名表,对大多数人是错的,对其余的人是错得您无声无息。

所以清单是你的。每个别名绑定到你的工具能加载的 id,加上大致的每百万 token 价格——正是后者让建议能用你的口径而不是我们的口径报出成本差:

# openspec/config.yaml
models:
  mode: preset
  catalog:
    cheap:   { id: claude-haiku-4-5, in: 1,  out: 5  }
    mid:     { id: claude-sonnet-5,  in: 2,  out: 10 }
    capable: { id: claude-opus-5,    in: 5,  out: 25 }
  preset:
    explore: cheap
    search: cheap
    verifier: mid
    reviewer: capable
    debugger: capable

上面那些 id 是例子,不是默认值。Coograph 一份清单都不附带。

没有清单,什么都不变。 在 Claude Code 上,四个内置别名照旧能用。在其他工具上,建议会请你先声明一份清单,而不是编一个加载时会报错的 id。它从不从 API key、已装的 SDK 或你正在用的工具去推测清单。

preset 里出现一个清单没定义的别名,是错误,不是猜测:它会说出是哪个别名,然后停下。

哪个代理配哪一档

角色映射到你的别名,所以重要的是形状而不是名字:

代理档位理由
exploresearch最便宜大量阅读与归纳。token 量大、判断少,能省最多。
verifier中档跑命令、把结果对照既定标准检查。机械性工作。
debugger强档找根因正是便宜模型靠猜、把省下的钱又烧回去的地方。
reviewer强档抓到一个真缺陷,就把差价赚回来很多倍。
planner强档量小、杠杆高,它决定了后面一切的形状。
retro强档读一份确定性报告并据此论证。

建议会随活的性质调整。一个文件、改法显而易见的改动,不需要昂贵的审查;并发 bug、数据迁移、鉴权路径或任何碰钱的东西,结论正好相反。最高档通常是中档的好几倍价,只有真正困难、长周期的活才值得。

值得知道的代价

提示缓存是按模型隔离的。六个代理分到四个模型,就是六个缓存命名空间而不是一个,而一次短的代理运行,缓存未命中损失的可能比按 token 省下的还多。这正是便宜模型只配给读得多的代理的原因:它们跑得够久,能摊薄这笔开销。这也是为什么一条提出三个或更多模型的建议会明说这一点。

还有两条限制,直说:建议是根据工单文字和文件数量猜的,所以有时会猜错——这就是为什么不经你接受什么都不会套用。还有上面那张价格表会过期;命令本身会重申记录日期,并说明这些是估算。

覆盖范围

有五个工具会把活分给 Coograph 的代理,所以按角色选模型在那里是一个真实的设置。每个工具要求写的地方不同,Coograph 就写到那里:

工具映射写到哪里
Claude CodeAgent 调用上的 model 参数
Cursor.cursor/agents/.claude/agents/ 下子代理 markdown 的 model: frontmatter
VS Code Copilot.github/agents/*.agent.mdmodel: frontmatter
Codex CLI~/.codex/agents/ 下的 TOML 代理定义,还能带推理强度
OpenCodeopencode.json 里的代理,id 用 provider/model-id 形式

你没有映射的角色会继承,不会被钉死。

写不了的映射会被拒绝,而不是拿个差不多的顶上。 VS Code Copilot 只能解析它自家厂商的模型,所以清单里写了别的 id 会被驳回,并说明是哪个 id、受什么限制。写一个接近的值、等工具加载时才报错,比直接说不更糟。

Aider 和 Cline

不支持,也不在计划内 —— 因为根本没有可支持的东西。

Coograph 在这两个工具里是以规则的形式跑的。只有一个代理,它包干所有活,所以没有角色可以配模型。Aider 的 --editor-model--weak-model,以及 Cline 分开的 Plan 和 Act 模型,都是那些工具自己的流水线阶段。把 Coograph 的 reviewer 挂到 Aider 的 editor 槽位上,不是把七个角色有损地压成三个;运行时压根儿就没有一个 reviewer 可压。

如果你用这两个,选一个模型自己设就行。这就是全部答案,把它说成“即将支持”只会暗示一份永远不该到来的工作。