Skip to content

自带模型路由 ​

Claude-Code 风格的 Agent 定义通常通过 sonnet、opus 这类稳定别名引用模型。使用 dsh-cc 时你不必改写它们:每条逻辑通道都会被路由到部署中配置的 provider/model,Agent 定义保持稳定,你可以按自己的环境、成本和任务特点选择实际模型。

别名通道 ​

Claude Code 风格 Agent 定义通常通过别名引用模型:

yaml
model: sonnet

dsh-cc 可以把这些别名路由到部署中配置的 provider/model。概念上映射如下:

text
sonnet / draft      -> <provider>/<general coding model>
opus / blueprint    -> <provider>/<reasoning model>
haiku / sketch      -> <provider>/<fast model>
fable / masterplan  -> <provider>/<maximum-reasoning model>
architect           -> parent agent route (planning / orchestration)
gauge               -> typed-decision cheap lane (System One models; not generative)
inherit             -> parent agent route

关键点:别名只是配置,不会硬编码到某家模型供应商。 你可以保留熟悉的 Agent 定义,同时根据自己的环境选择合适的模型。

gauge 是面向 System One 模型的纯决策通道,供权限分类器这类类型化决策的使用方选用。绝不要把它用作 Agent frontmatter 的 model:。 未配置时它跟随 haiku。routes 服务会以 SystemOneChatModelError(code SYSTEMONE_NOT_CHAT_MODEL)拒绝任何发往 System One 模型的聊天请求。

TIP

dsh-cc 项目本身就使用这套路由进行日常开发——当前开发映射见项目 README 的 Dogfooding dsh-cc 章节。那只是项目自身的真实配置,不是强制默认值。

分层级联路由(moa) ​

@dsh-cc/moa 插件把主对话轮次路由到 sketch / draft / blueprint / masterplan 四条通道别名上:每个用户轮次由一次 System One 决策调用分类到足够用的最便宜层级,可选的验收判定器会把被拒绝的回答升级到上一层级。

moa 默认关闭——moa.enabled: false 时插件不挂载任何东西,也不产生任何开销。子代理和 fork 永远不会被叠加该路由。

配置位于 moa settings 命名空间:

键默认值含义
enabledfalse在主 agent 上启用分层路由
acceptance.enabledfalse运行验收判定器并按拒绝结果行动
acceptance.shadowfalse运行判定器,但只记录判定结果
acceptance.tau0.7当 P(acceptable) < tau 时判定拒绝
max-escalations1每条消息的升级上限(读取时钳制到 3)
judge-route别名 gauge别名或 {provider, model, protocol};未设置时使用 gauge 通道别名,它必须解析到一条 System One 路由,否则 moa 保持未启用状态
classify-budget-tokens4000分类输入预算
call-budget-ms8000每条消息的级联时限

验收判定器运行在上文介绍的 gauge 通道上——即 System One 模型的类型化决策廉价通道——因此 judge-route 未设置时,能解析到 System One 路由的 gauge 映射是启用判定的前提。

模型记账的真实化 ​

当 moa overlay 处于激活状态时,以下机制保证会话如实呈现当前真正在服务的模型:

  • 过滤幽灵通知。 在 overlay 之下,harness 几乎每一步都会重新发出 [model changed: …] 通知,声称一个 overlay 并不会使用的续写模型。一个 sanitizer 只在 overlay 激活时精确丢弃这些行;其余所有状态(moa 禁用、已解除、校验失败或根本没有 moa)下,harness 通知逐字节原样透传。
  • /model 会解除 moa。 会话中途用 /model 选到启动模型对以外的选择,会在下一个轮次分类之前解除 moa——链路上真正服务你选中的模型(此前在 overlay 下这个切换会被静默忽略)。切回启动选择后,moa 从下一个轮次重新启用。
  • 人格声明实际生效的模型。 只要 overlay 生效,系统提示中的 provider/model 变量会被改写为解析后的层级模型对;任何 fail-open(分类失败或超时、偏离启动选择、禁用)时,harness 自己的选择变量原样透传,提示词与链路始终保持一致。
  • 状态栏展示实际模型对。 overlay 激活时,状态栏渲染 <resolved-model> ◂ <tier-alias>(例如 <provider-model> ◂ sketch),而不是裸的层级别名;自定义状态栏载荷会获得 moa: {tier, model} 字段。切走后该段会被清除。
  • 状态栏展示 moa 未启用的原因。 当 moa.enabled: true 但启用被拒绝(路由不可用、层级阶梯退化、judge-route 窗口失败)时,状态栏渲染 moa:unarmed — <reason>,配置错误不再藏在一条 warn 日志里。

路由范围仅限主对话——子代理会话永远不会被分类、叠加 overlay 或判定。

用 /provider 管理供应商 ​

/provider 命令在覆盖层中管理已配置的模型供应商:

命令作用
/provider打开供应商覆盖层
/provider list列出当前路由
/provider add <preset-id>通过向导添加内置预设(Moonshot、Z.AI/智谱、DeepSeek)或完全自定义的端点
/model为当前会话重新选择 provider/model

每个路由的详情页支持轮换密钥、刷新模型列表、设为默认和删除。关于凭据:

  • API 密钥通过掩码输入框录入,保存到凭据存储 ~/.dsh/.credentials.yaml——不写入 settings。
  • 由环境变量提供的密钥只读展示。
  • 变更对新会话立即生效(凭据按请求解析);当前会话保持原供应商,直到用 /model 重新选择。

按任务选择:别名与 Agent frontmatter ​

子代理定义位于每个工作区的 .claude/agents 目录,使用 Claude Code 风格的 frontmatter,其中包括 model: 字段。dsh-cc 派发子代理时,人格来自定义的 systemPrompt,frontmatter 中的 model: 别名则通过 ccModelRoutes 别名服务解析——每次 spawn 都会查询——因此定义里的 model: haiku 会落到当时代入 haiku 通道的那个 provider/model。

同样的解析也适用于其他引用别名的地方:解析 model: 字段的 hook executors 同样走 ccModelRoutes(省略 model 时回退到 haiku 廉价通道)。

WARNING

别名解析覆盖 Agent frontmatter 和 hook executors。主会话默认模型的别名化是已知的后续事项,且 ANTHROPIC_* 环境变量没有 Anthropic 语义——详见 parity matrix 的 Models 章节。

别名解析语义 ​

解析按固定顺序查找:settings 覆盖层 → config 默认值 → 内置回退。别名键不区分大小写(合并和查找时统一折叠为小写)。

别名条目有两种写法:

  • 字符串形式——sonnet: deepseek-v4-flash:只写模型 id,provider 继承。
  • 对象形式——opus: { provider: deepseek-official, model: deepseek-v4-pro, reasoningEffort: max }:显式路由,可附带 effort。

几个值得了解的边界行为:

  • inherit(任意大小写)表示不覆盖——子 agent 继承父路由。
  • 只有 settings 层可以把条目设为 null,用来删除同名的 config 默认条目(按条目浅删除)。删除内置别名时会落到内置回退,即继承父路由——config 不允许出现 null。
  • 未配置的内置别名(fable/opus/sonnet/haiku 和 dsh-cc 通道)继承父路由。未配置的自定义别名(如 turbo)没有回退:它作为字面模型 id 原样透传,并记录一条警告。
  • 字符串形式的目标如果指向另一个别名,只跟随一跳——这一跳会携带 reasoningEffort。对象形式的目标是具体路由,不会再被当作名字跟随。

廉价通道的可观测性 ​

未配置的内置别名静默继承父路由时,解析器会记录一条警告——每个别名只记一次。该警告由 model-aliases settings 命名空间中的 warnOnInherit 键控制(默认 true;设为 false 可关闭)。

用 Ctrl+P 循环切换模型 ​

在 TUI 中,Ctrl+P / Shift+Ctrl+P 会在 cc-model-cycling.cycleOrder 的别名列表中循环切换,并通过同一个别名解析器解析。无法解析或未被公布的条目会被跳过并弹出提示。切换只在内存中生效,不会写入 settings。

model$level:在模型引用上指定 effort ​

任何模型引用——agent frontmatter 的 model:、别名目标的 model id、或 auto-mode 分类器的 route——都可以带一个 `$<level>` 后缀(opus$high、glm-5.3$xhigh):

  • 后缀在 id 离开解析器之前被剥离,所以定价、熔断器和 pin 都按裸模型 id 记账。
  • level 挂在解析路由的 reasoningEffort 上,并覆盖别名目标已声明的 reasoningEffort。
  • 未知的 level 拼写不会被剥离或丢弃,而是带到 harness 边界,请求以 UNSUPPORTED_REASONING_EFFORT 失败。
  • 畸形后缀(末尾悬空的 $、空或含非法字符的 level、provider 段里出现 $)原样透传。

effort 优先级 ​

多个来源同时声明 reasoning effort 时,按以下顺序取值(高优先级不会改动低优先级的值):

  1. 显式的 `$level` 后缀。
  2. 别名目标声明的 reasoningEffort。
  3. agent frontmatter 的 effort(spawn 时应用)。
  4. /effort 的会话选择。
  5. catalog/harness 的路由默认值。

见 /reference/commands 中的 /effort 行。

示例:端到端演练 ​

从一个空部署到让任务跑在快速通道上的最短路径:

sh
# 1. Add a provider through the preset wizard
/provider add <preset-id>

# 2. Inspect the current routes
/provider list

# 3. In the per-route detail view, set the default
#    and map the lanes (haiku/sketch -> fast model)

# 4. Re-pick the model for the current session if needed
/model

通道映射完成后,任何固定到某条通道的 Agent 定义都会跑在那条通道上。例如 .claude/agents/lookup.md 中的一个快速查询 Agent:

yaml
---
name: lookup
description: Fast codebase lookups
model: haiku
---

You are a read-only codebase scout. Return paths and line numbers.

派发这个 Agent 时,haiku 会在 spawn 时通过 ccModelRoutes 解析——之后重新映射快速通道到别的供应商,也无需修改这个定义。

下一步 ​

dsh-cc 不是 Claude Code,也不是 Claude Code 的包装器。与 Anthropic 无关联,亦未获其背书。