一家 Agent,三套车
一家 Agent,三套车
引子:我在 DSH 里接了 GLM 和 Kimi,然后就不对劲了
写这篇的起点非常朴素:DeepSeek Harness(以下简称 DSH)开源了,我像多数人一样,兴冲冲地照着官方文档,在 settings.yaml 里加了 llm-pi-ai 的 provider block,把 GLM-5.3 和 Kimi K3 都接进来了。
界面上一切看起来都对——下拉框里三家模型都能选,切换也不用重启。
但是一跑任务,问题就来了。
同样的提示词、同样的工作区、同样要改的 bug,切到 DeepSeek-V4-Pro(DSH 原生模型 + DSH 原厂 harness) 跑一遍基本一次过,11 轮 tool call 收工;换成 GLM-5.3(挂在 DSH 里,工具链、prompt 一模一样),同一件事硬是循环了 20 多轮还在反复做 str_replace_editor 和 persistent bash 之间横跳,中间还有一轮返回了空 JSON,不得不走 repair prompt;最后虽然也"完成"了,但token 用量是原生组合的 3 倍,耗时翻了一倍。
直觉上我想骂 GLM 不行,可前一周我刚在原厂的 ZCode 桌面端上用 GLM-5.3 跑完了一个更大的跨端项目,完整交付 4900 行代码、99% 以上缓存命中率,连需求文档中间埋下的两条软约束都守住了——智东西对同一组合的实测更猛:GLM-5.3 + ZCode 能读懂 DSH 这种 7000+ 文件的巨型开源仓库并在里面造一个"人格插件",整个过程面包屑定位问题、手写 PNG 解码器自验证(智东西·GLM-5.3 发布实测)。
那为什么到了 DSH 里就突然不行了?
答案很快就出来了——
同一个模型,你把它放进它自己厂商那个 harness 里,它能跑;你把它接入到别家厂商的 harness 里,就打折扣。不是模型不行,是model ↔ harness 错配**。
这篇想把这个矛盾写透。
一、先把数据摆上来:同一个模型,换 harness,性能差距是实实在在的
不是我体感,这件事 2026 年已经被三篇论文 / 基准 / 独立测试钉实了。
1.1 A-CODE-CLI Bench:同一 Sonnet 4.6,换 agent 框架,后端正确率从 13.3% 到 77.3%
这是 AIMultiple 在 2026 年 6 月发布的 Agentic CLI 基准(https://aimultiple.com/agentic-cli)。它做了一件极残酷的事:把同一个模型 Sonnet 4.6塞进 9 个不同 agent 工具里跑,测试 10 个真实 Web 项目。结果:
| Agent(都是 Sonnet 4.6 作 backend) | Backend 正确率 |
|---|---|
| OpenCode | 77.3% |
| Cline | 69.5% |
| Junie | 69.5% |
| Forge | 67.2% |
| Kiro | 24.4% |
| Aider | 13.3% |
| Goose | 55.4% |
同一个模型,后端正确率 13.3% → 77.3%,差距超过 64 个百分点。 报告作者自己的结论是:"All nine cleanly-running agents use the same Sonnet 4.6, yet the gap from Opencode’s 77.3% down to Goose’s 55.4% comes entirely from the orchestration."(9 个 agent 都用同一个模型,所有差距全部来自 agent 编排,也就是 harness)。
1.2 Endor Labs:同一 Claude Fable 5,通过 Claude Code 跑 vs 通过 Cursor 跑,安全分差 +10pp
Endor Labs 在《Claude Fable 5, take two: same model, different harness, and a very different result》里更直接:同一个 Fable 5,先在 Claude Code(Anthropic 自家 harness) 测 200 个真实漏洞修复任务,再换到 Cursor harness 测同 200 题。结果:
| 组合 | FuncPass(功能正确率) | SecPass(连安全也修对) |
|---|---|---|
| Claude Fable 5 + Claude Code | 59.8% | 19.0% |
| Claude Fable 5 + Cursor | 72.6% | 29.0% |
同一个模型,SecPass 19.0% → 29.0%,FuncPass +12.8pp。
连"是不是问对安全问题"这种思考方向,harness 的 system prompt / 搜索策略 / 安全导向工具都能改变。
1.3 arXiv 2602.22518(RepoMod-Bench):同一 Opus 4.5,在 Claude Code 里比在 Codex CLI 里高 17.8pp
论文里专门有一组是 "hold agent constant / hold model constant"。保持模型不变(Opus 4.5):
- Claude Code:48.2%
- Codex CLI:30.4%
差 17.8 个百分点。模型没换,只是换了调用它的那套 harness / agent loop / 工具协议。
1.4 arXiv 2608.13560(AutoDesign,美团):harness 不对,模型再强也被压
论文 PosterBench 上一条结论是:7 种 Code Agent + Model 的组合里,只要把 DesignHarness 换上去,平均 PosterBench Score 从 54.99 升到 67.39,+12.4%。 同一个模型、同一任务,只加一层合适的 harness,能涨 12 分。
还有两个很有参考价值的国内实测:
- 腾讯技术工程团队以同一个 Kimi K3 API、同样的提示词、同样的工作区、同样的隐藏验收,分别跑 Kimi Code(原厂) 和 DSH minimal,两条轨迹显著分叉:Kimi Code 是"首轮并行读 README/源码/测试→整文件 Write→Bash 验证,5 次工具调用",DSH minimal 是"persistent bash 和 str_replace_editor 间高频切换 11 次,步骤更细碎",最终完成质量和 token 开销都不同(DeepSeek Harness 实测|模型之外的那一半)。
- 程序员鱼皮把 GLM-5.3 / DeepSeek-V4-Pro / Kimi K3 全接进同一个 DSH 标准模式里做对比,然后吐槽"夯爆了"——正是因为在 DSH 里,三家都失去了原厂 ZCode / Kimicode / DSH-native-DS 的那一层深度适配,所以拼的不是"各自最佳水平",而是"在 DeepSeek 的 prompt 模板、工具集和 loop 里,谁更能将就"(《把 GLM-5.3 接入到 DeepSeek Harness,夯爆了!》)。
一句话总结所有这些数据:
Model ≠ Agent。真正对外干活的那个"产品能力" = Model × Harness,而且不是加法,是乘法——任何一边拉胯,另一边再强也兜不住。
二、回到 DSH + 别家模型的场景:到底是哪里"错配"了?
把别家模型接进 DSH 里用,表面上能跑,实际在以下 6 个层面都会发生不兼容,每一层都会悄悄掉性能:
层 1:System Prompt & 规划模板不是为你写的
DSH 的 PTC 模式默认给模型塞的提示词是和 DeepSeek 深度对齐的——鼓励先用 TypeScript 组合多步操作、鼓励写 Trajectory 可观测结构、鼓励"计划→执行→复查"三步走。这些提示词是在 DeepSeek 模型分布上反复调过的。
GLM 或 Kimi 接进来时,看到的是别人的"剧本"。ZCode 的 Goals 工作流里,默认 system prompt 会强调"长任务跨上下文边界要把工程决策记下来,遇到跨文件 bug 不要凭猜测改"——这和 GLM-5.2/5.3 在长程训练里被强化的内容是对齐的。而 DSH 里给同一个 GLM 发的 prompt 根本不会提这些。
层 2:工具调用格式(tool-call)是"母语 vs 外语"
ThinkDepthAI 在 GitHub Issue #1 里记录了一个非常典型的 harness 级设计缺陷:
一些模型家族(DeepSeek、MiniMax、部分 Moonshot/Kimi)是在自己的原生工具对话模板上微调的,切换到 OpenAI 统一的 JSON tool_calls 格式后,会出现 10~20% 的"空信封"率——也就是调查阶段刚结束,模型还想继续发工具调用,但 harness 要求它立刻总结 JSON,它就会"说不出人话",只输出一堆
<||DSML||tool_calls>的原生 DSL。
这就是典型的"切换对话模态失败"。在原厂 Kimi Code / DSH-for-DeepSeek 里不会出现,因为人家早就针对自家模型的 tool-call 分布写好了"过渡 prompt"。你把模型接到别人的 harness,就等于让一个刚学中文的美国人做托福听力。
层 3:工具集合 & 沙箱权限是 DeepSeek 的工程哲学,不是 GLM 或 Kimi 的
DSH 有四个预设:标准 / PTC / 极简 / 创造。不管哪一个,工具名和粒度都是 DeepSeek 团队选过的组合——str_replace_editor、persistent bash、Context 注入方式…… 这些都是为 DeepSeek 调参过的"最优工具面"。
腾讯技术工程那篇实测里提到,同样的 Kimi K3,在 Kimi Code 里首轮就会并行读 README/源码/测试一次读完,然后一次性整文件 write 再 bash 验证(5 步搞定);而在 DSH minimal 里 Kimi 却被迫切换 str_replace_editor 和 bash 11 次,步骤更细碎。不是 Kimi 想这么干,是 DSH 的可用工具和调用方式在"引导"它这么干——工具面决定了行为路径。
层 4:上下文管理 & 压缩策略,是和模型窗口一起调的
ZCode 官方文档写得很直白:GLM-5.3 的 1M 上下文不是"塞进去多少都行",是"在长任务中稳定守住 API 契约 / 文件引用 / Git 分支状态到最后"。配合的是 ZCode 自己的上下文压缩节点——什么时候压缩、压缩保留哪些字段、什么时候让模型"休息一下做摘要",这些都和 GLM 的分布对过。
你用 DSH 挂 GLM,就会用 DSH 的 Trajectory / Session Event Log 投影机制做压缩。对 DeepSeek 模型没问题,对 GLM 就不一定,摘要丢字段或丢的位置不对,后面就开始"靠猜"。
层 5:权限 & 审批流程,和原厂安全训练对不上
ZCode 有"敏感命令 / 文件修改 / 高权限动作执行前进入确认流程";Claude Code 有同类 approval gate;Kimi Code 也是独立实现。每家对"什么动作算危险"的阈值都不一样,而且和自家模型 RLHF 里的安全边界是对齐的。
错配后的结果:原厂 harness 认为"需要问一下"的动作,被错配 harness 放过去了;原厂认为"你自己干就行"的动作,错配 harness 却停下来反复问你——两边都浪费性能。
层 6:长任务的"推进节奏"完全两套
ZCode 的卖点是 Goals:可中断、可手机端恢复、飞书 / 微信 Bot 随时介入、idle-time 空闲配额…… 这些都是和 GLM 的"长程任务耐力"训练绑定的一套产品逻辑。把 GLM 放到 DSH 里,这些外部推进机制就都没了,GLM 空有一身长程肌肉,却被放在短跑赛道上。
把这 6 层加起来,再回头看我自己的跑批结果——DSH + GLM 比 ZCode + GLM 差 3x token / 2x 时间,完全合理。不是模型弱了,是把一颗拧进 ZCode 精密齿轮里的螺丝,硬塞进 DSH 的齿轮里,虽然也能转,但间隙太大了。
三、GitHub 现有方案分两层:90% 是「一 Harness × N API」;剩下 10% 才是真·「一 Router × N Harnesses」
3.1 第一层(主流):一个 agent harness 壳里路由 N 个模型 API —— 解决不了 6 层错配
现在市面上多模型路由非常火,GitHub 上我翻了 switchboard-llm、agentic(Claude Code 网关模式)、workweave/router、adaptive-model-router、Harmony Extension、LiteLLM、opencode-hive、dispatch-opencode-skill、ai-eng-system、chektien/agents、agentic-coding-kit 等一二十个项目,统一做法都是:
统一的 Agent Harness(Loop / Prompt / Tools / Compress / Approval)
├─ 路由 ──► DeepSeek API
├─ 路由 ──► GLM API
├─ 路由 ──► Kimi API
└─ 路由 ──► Claude / GPT / Gemini / Ollama...这叫"一个 harness,多个模型后端"。比如 opencode-hive 用的是 OpenCode 一个 harness 里跑 plan/orchestrator/python-pro/go-pro 多角色,但它们共享的还是 OpenCode 自己的 prompt 模板 / 工具面 / 压缩节点;dispatch-opencode-skill 是把任务并行 dispatch 到多个 opencode session,但每个 session 仍然是 opencode 这同一个 harness;agentic-coding-kit 是多 host 多 agent 子系统,但 harness 壳还是统一的一套。
这个思路没有错,它解决的是"成本 / 延迟 / 模态 / 角色分工"的路由:代码任务去便宜的 Codestral / DeepSeek,长文档去 1M 上下文的 Gemini / Kimi,低延迟补全去 Groq,规划用便宜 SUB 模型,写码用昂贵 CODE 模型。AIMultiple 测得 OpenCode + Sonnet 组合也确实比别的 agent + 同 Sonnet 强(https://aimultiple.com/agentic-cli)。
但它完全不解决我们上面写的 6 层错配。因为不管路由到哪一个 API / 哪一个"子 agent 角色",外层 harness 的 system prompt 永远是那套、工具 schema 永远是那套、压缩节点永远是那套、审批门槛永远是那套。
- 路由到 DeepSeek API → OK,这是对的;
- 路由到 GLM API → 错 6 层;
- 路由到 Kimi API → 错 6 层;
- 路由到 Claude / GPT → 又是另一套错配。
3.2 第二层(少数派,方向对):一个外层 Router,真正调用多个原厂 Agent CLI / Harness 子进程
这一层就是我们第四节构想的那个方向的半成品雏形。它们不再"把别家模型塞进同一家 harness",而是每个模型/harness 都用自己的 CLI 进程跑,Router 做输入分发和输出汇总。我在 GitHub 上至少找到 12 个这类项目,每个的位置、做到什么程度、弱点都列清楚:
| 项目 | 作者 / 星标 | 做了什么(能否真正跨原厂 Harness) | 关键入口命令 / 机制 | 仍然达不到「原厂效果=100%」的原因 |
|---|---|---|---|---|
KerryRitter / programmatic-agent-router (Rust CLI par) | MIT / 近期活跃 | ✅ 真·跨 Harness 路由:一个 prompt 分发到 cursor-agent / gemini / goose / opencode / qwen / aider / amazon-q / kimi CLI 等;每个都用各自官方 CLI 子进程启动 | par -p "review" --harness codex --model gpt-5.4;--harness opencode --provider anthropic | ① 无 worktree 隔离、无统一 artifact 契约;② 路由只是静态 --harness 手动指定,没有自动 Learned Router;③ 对 ZCode(无公开 CLI)只能跳过 |
| haowjy / orchestrate | MIT / 近期活跃 | ✅ 真·跨 Harness:专门为 Claude Code / Codex / OpenCode 三家跑子进程,agent 定义文件跨三家同步(.claude/agents ↔ .agents/agents ↔ .opencode/agents) | sync.sh 把一套 markdown agent 定义在三套 harness 目录之间同步;orchestrate 主 agent 发现 skills 后选模型 + 选 harness | ① 同步只有 agent 定义文件,没同步上下文压缩节点、权限阈值、tool-call 过渡 prompt(也就是我们那 6 层的 1/2/4/5);② 未覆盖 ZCode / Kimicode / DSH-native |
| Tembo(商业产品,temb.io/blog/aider-alternatives) | 商业 SaaS / 近期活跃 | ✅ 真·跨 Harness 后台运行:在云端沙箱里把 Claude Code、Codex CLI、Cursor、Gemini、OpenCode 当 backend,接收 GitHub / Linear / Sentry 信号后派任务 | 后台 API triage issue → spin sandbox → choose backend agent cli → open draft PR | ① 闭源商业,个人用户无法本地自部署;② 路由是后台手动/规则选 backend,不是我们要的自动 Router;③ 对 ZCode / DSH / Kimicode 没接 |
| AdamFrisby / CodeyBox (.NET) | MIT / 近期活跃 | ✅ IAgentRunner 多 Runner 模式:Claude、Codex、Copilot、Cursor、Gemini、opencode 每家一个 IAgentRunner 类 | CodeyBox.Agents.Claude / .Codex / .Copilot / .Cursor / .Gemini / .Opencode 接口统一 | ① 所有 Runner 内部最后还是跑"自家模型 API",没走 Claude Code CLI / ZCode Desktop 这种原厂 harness 二进制;② 弱点和 3.1 层类似 |
| PUSHINGSQUARES / Pushing-Dispatch_ (Python) | MIT / 小仓库 | ✅ 子进程分发 + dispatch_matrix.toml 路由矩阵:每家 provider 一个 shell wrapper + TOML entry,路由到各 CLI 子进程;加 Brief-Only 上下文加载和 HANDOFF 交接文档 | dispatch_matrix.toml.example 配置路由;cli.py 分发到各家 worker | ① 默认做了个"Harness Flip":所有 provider 都走 Claude Code harness + Anthropic-compat endpoint,也就是又回到了 3.1 层那种「一家壳塞多家 API」(README 自己写的 Pillar 1);② ZCode / Kimicode 仍未接入 |
| artificemachine / superharness (Python+Rust) | MIT / 872 commits 很活跃 | ✅ SQLite 共享契约 + 队列委派 + Handoff Ledger:多 agent 跑在统一的 shux 状态机里,任务跨 session 存活,adapters 目录写各家适配 | adapters/ 下写 adapter;shux status 一屏看所有 agent / queue / discussion / task | ① adapters 目前主要接 Claude Code 生态;② 核心是"共享状态机 + 委派",没有显式要求每个 model 必须跑在自己原厂 CLI harness 里,你还是能偷工减料塞 API |
| edison7009 / EchoBird (Rust Tauri 桌面) | ⭐3.1k / 近期活跃 | ✅ 一键切 CLI agent:Claude Code、Codex、DSH、Kimi Code、Qwen Code、Aider、OpenCode、ZCode、OpenClaw、MiMo Code…… 全装在一个统一 Tauri 桌面壳里,点一下就切 | Rust 子进程管各家 CLI 启动、工作区注入;侧边栏下拉选 agent | 致命缺点:只是「统一 UI 壳 + 手点下拉切换」,完全没有我们要的 Router——用户还是自己选哪家 code agent,这正是你最不想干的。 |
| farion1231 / cc-switch (Rust Tauri) | ⭐130k / 近期活跃 | ✅ 和 EchoBird 同品类:统一桌面壳把 Claude Code、Codex、OpenCode、OpenClaw、Grok Build、Hermes Agent 都收进来,官方网站 ccswitch.io | Tauri + Rust 多子进程 + MCP 统一 | 同样的问题:只有用户手点下拉切换,没有自动 Router,更不会"按任务特征自动路由到原厂组合"。 |
| ComposioHQ / agent-orchestrator(详情见 gist 分析) | 商业+OSS 并行 | ✅ tmux 会话隔离的并行 worker:一个 orchestrator agent 会话 spawn N 个并行 worker,每个 worker 是独立 agent CLI,tmux 隔离,最后合 PR | ao start 起 orchestrator;每个 issue 一个独立 CLI worker | ① 商业核心功能不开源;② 并行但默认同一类型 backend,不会自动"这个 issue 派 Claude Code,那个 issue 派 ZCode"。 |
| zhuwenzhuang / farming (TS 浏览器工作区) | ⭐7 / 近期活跃 | ✅ 自托管浏览器工作区,Codex、Claude Code、OpenCode 都跑在一个网页终端里,可监督 | 浏览器里远程终端 + 多 agent tab | 同样:手切,不自动路由;纯监督控制台,无路由决策。 |
| drippy-passport96 / agent-supervision-skills (PowerShell) | ⭐3 / 近期活跃 | ✅ Standalone supervision 技能:给 Claude、Codex、Kimi 三家分别写委派脚本 + artifact 收集 + 本地校验 | PowerShell 脚本分三家调用 | 只有监督与校验,没有路由;三家分别是三个独立脚本。 |
| MiGoller / ai-agent-sandbox (Podman 容器) | MIT / 近期活跃 | ✅ 安全沙箱层 + 多 flavor:把 Hermes / Aider / Claude Code 分别锁进 Podman 根容器,项目目录只读挂载,网络默认锁 | run.sh --flavor claude-code --online;Container 内配置目录动态映射 | 这只是安全沙箱 + 多 flavor 启动器,不是 Router;手动选 --flavor。 |
把这 12 家扫一遍,结论非常直白:
方向最接近的是
programmatic-agent-router (par)和orchestrate:它们真正把子任务派到各家原厂 CLI harness 里跑,而不是"一家壳塞多家 API"。但它们都缺三样关键东西:① 自动 Router(静态规则 / 元数据 / 小模型 / 历史闭环);② 统一的 worktree 会话契约(任务派出去前先 fork 工作区,跑完写统一 diff / result / timeline / cost);③ ZCode / Kimicode 这种没出 CLI 的闭源 harness,仍然只能停在理论上。
3.3 小结:业内的"务实做法" vs 我们想要的
Composio 在 ZCode vs Claude Code 那篇文章的结尾有一句话很有意思:"What I'd actually do with that result: keep Claude Code as the main harness, route the cheap high-volume work to GLM 5.2, and use the fact that the GLM Coding Plan runs inside Claude Code via env vars so I never have to leave the terminal." 这其实就是当下工程师群体的"最务实做法"——主力 harness 用一家,其他模型都当作"便宜的后端 API 填充物"接进去(也就是 3.1 层)。没人真的指望 GLM 在 Claude Code 里跑出 ZCode 的原厂效果。
但这很浪费。浪费了至少 12–25 个百分点的能力(端到端任务层面),浪费了厂商在自家 harness 上做的所有 prompt engineering / tool schema / context 管理 / 安全审批的适配工作。
而我们要做的,就是把 3.2 层里那几个"方向对了但半成品"的项目真正补齐:加自动 Router、加 Worktree 契约、把 ZCode / Kimicode 通过 Bot / Desktop-Bridge 形式也接进来。
四、我想要的不是「一个 harness 路由多个 API」,而是「一个外层路由多个 harness」
把它画成 ASCII 图更清楚:
现在大家都在做的:
用户任务 → [ 统一 Agent Loop A(Prompt A / Tools A / Compress A) ]
├─(按 cost/latency/category 路由 API)─► DeepSeek
├─(同上)────────────────────────────► GLM
└─(同上)────────────────────────────► Kimi问题:后两家其实永远是「穿着别人的球衣在踢球」。
我想做的:
用户任务 → [ 中央 Router(做路由决策 + 统一接口) ]
├─► [ DeepSeek Harness → DeepSeek 模型 ]
├─► [ ZCode Agent → GLM 模型 ]
└─► [ Kimi Code → Kimi 模型 ]
↑ 每家"工程队"都是原厂完整组合Router 不对内发 API。Router 干的活是三件:
- 判:进来的任务该派给哪支"工程队"。
- 转:把任务描述、文件引用、权限配置、工作区路径翻译成那家 harness 的入口格式(DSH 是 headless 或 Python SDK;ZCode 是 Goals 启动 / Bot 发消息;Kimicode 是 CLI 或 IDE Extension Host;Claude Code 是
claude -p子进程)。 - 收:把各家用不同方式返回的进度、审批请求、tool result、最终产物,统一回同一个界面。
这样才能让 GLM 真真正正跑在原厂 ZCode 的 Goals、手机遥控、99%+ 缓存命中那一整套环境里,而不是在 DSH 的 PTC 模板里将就。
五、我的具体解决方案(代码级设计,可以直接照着写)
先讲核心设计理念,再给配置、伪代码、契约、Adapter 四件套。
核心理念三条:
- 每次分派 = 新建一个 git worktree。Router 永远不把工作区(脏树)直接给子 harness,也不在主树里混跑多个 harness;每个子任务拿到的都是一个独立的、可回滚、可 abandon 的 worktree。这样就把原五道墙里最难的那道「墙 3:状态热迁移」直接给绕开了——不需要迁移,任务跑歪了就扔 worktree。
- 所有 Adapter 的输出必须收敛到同一个文件契约(artifact 目录 + 4 个标准文件)。不管你是 DSH 子进程、ZCode Bot 桥接还是 Claude Code CLI,跑完必须写到约定的 4 个文件里。Router 只认这 4 个文件,不认任何私有的 stdout / webhook / 私有 API。
- Router = 轻壳。 把重活(prompt、tool、压缩、审批、安全护栏、trajectory)全部留给各家原厂 harness 自己做。Router 只管"判 → fork worktree → dispatch → 等 artifact → 合 patch 回主树 → 写学习记录",6 层适配一道都不做、也做不好。这也是我们和 3.1 层项目最大的区别。
5.1 静态路由配置:harness-router.yaml(MVP 可直接用)
这是 Router 的第 1 层。一个项目放一个,写清楚"什么特征的任务走哪支原厂组合"。给一份可以直接复制的示例:
# 你的仓库根目录放一个:.router/harness-router.yaml
version: 1
# 凭据:Router 统一注入,不给子 harness 留明文。支持 env / file / 1password / keyring
credentials:
deepseek_api: { from_env: "DEEPSEEK_API_KEY" }
zcode_bot_webhook: { from_env: "ZCODE_ROUTER_BOT_WEBHOOK" }
anthropic_auth: { from_file: "~/.config/router/anthropic_auth_token.txt" }
moonshot_api: { from_env: "MOONSHOT_API_KEY" }
# Adapter 注册:每家 harness 一条命令模板 / 桥接方式 / 入口文件
adapters:
# A形态:开源原生嵌入 —— DSH headless
dsh-native:
kind: "headless-subprocess"
bin: "npx"
args: [
"-y",
"@deepseek-harness/headless",
"--workdir",
"{{WORKTREE}}",
"--settings",
"/dev/stdin", # Router 动态拼 settings.yaml 进去
"--preset",
"PTC",
"--jsonrpc",
"stdout",
"--max-turns",
"{{MAX_TURNS}}",
"-p",
"{{PROMPT_FILE}}",
]
model_bind: "DEEPSEEK_API_KEY -> settings.yaml:llm-pi-ai.providers.deepseek.apiKey"
# B形态:CLI 桥接 —— Claude Code 官方 CLI
claude-native:
kind: "cli-stdin"
bin: "claude"
args:
[
"--no-browser",
"--project",
"{{WORKTREE}}",
"-m",
"{{MODEL}}",
"-p",
"@{{PROMPT_FILE}}",
]
model_bind_default: "claude-sonnet-4-6"
capture: [stdout, stderr, .claude/trajectory.ndjson]
# B形态:CLI 桥接 —— Codex CLI
codex-native:
kind: "cli-stdin"
bin: "npx"
args:
[
"-y",
"openai-codex@latest",
"run",
"--cwd",
"{{WORKTREE}}",
"--message-file",
"{{PROMPT_FILE}}",
]
# B形态:Bot 桥接 —— ZCode 无公开 CLI,用飞书/微信 Bot + Goals
zcode-goals-bot:
kind: "bot-webhook-poll"
webhook_url: "{{CRED.zcode_bot_webhook}}"
# ZCode Goals Bot 的 API 约定(各家 Bot 格式不同,这里只是示意):
body_template:
goal_title: "[router #{{RUN_ID}}] {{TASK_TITLE|truncate 60}}"
goal_content: "{{PROMPT_CONTENT}}"
repo_worktree: "{{WORKTREE}}" # ZCode Bot 在同一台机器上,直接给路径
polling_every: 30 # 秒
done_indicator: "status: completed/failed"
# B形态:CLI 桥接 —— kimi-cli(如果后续官方出)
kimi-native:
kind: "cli-stdin"
bin: "kimi-cli"
args: ["--cwd", "{{WORKTREE}}", "-f", "{{PROMPT_FILE}}"]
# 路由规则表:自上而下第一条命中即生效(first-match)
rules:
# 例 1:长程、国内网络、需要手机端打断 → 直接派 ZCode
- if:
has_keyword: ["后台跑", "8小时", "手机", "飞书", "微信", "Goals"]
or_network: ["cn"] # Router 自带小探测 / 手动标
then:
{
adapter: zcode-goals-bot,
model: "glm-5.3",
max_turns: 400,
budget_cny: 20,
}
# 例 2:几百文件超大上下文读 → Kimi 原厂
- if:
file_estimate: "> 100 files"
has_keyword: ["文档", "需求", "通读", "对照"]
then:
{ adapter: kimi-native, model: "kimi-k3", max_turns: 200, budget_cny: 10 }
# 例 3:安全/合规/企业凭据 → Claude Code 原厂
- if:
has_tag: ["security", "audit", "compliance", "iam", "rbac"]
or_touch_paths: ["auth*", "*.tf", "k8s/*rbac*", ".github/workflows/*"]
then:
{
adapter: claude-native,
model: "claude-opus-4-5",
max_turns: 300,
budget_cny: 30,
}
# 例 4:要改 DSH 插件 / 要自己做 Trajectory 观测 → DSH 原生
- if:
touches_package_json_dep: ["@deepseek-harness/*", "cordis"]
has_keyword: ["Trajectory", "Cordis 插件", "DSH"]
then:
{
adapter: dsh-native,
model: "deepseek-v4-pro",
max_turns: 150,
budget_cny: 8,
}
# 例 5:改 bug / 简单改 3 行以内 → 最便宜且 DSH 原生最稳
- if:
complexity: "low" # (启发式:估算最终 diff < 50 行)
then:
{
adapter: dsh-native,
model: "deepseek-v4-flash",
max_turns: 40,
budget_cny: 2,
}
# default:默认先派 DSH-native 最便宜的组合
- else:
then:
{
adapter: dsh-native,
model: "deepseek-v4-flash",
max_turns: 80,
budget_cny: 4,
}这份 YAML 对应我们「四层路由」的第 1 层(第七节详细展开了 2/3/4 层的进阶方案)。把它先落到一个项目里,哪怕第 2/3/4 层还没做,50% 的场景已经分对了。
5.2 Router 核心分发伪代码(Python,300 行以内就能写出 MVP)
Router 的主循环不复杂,就是「判 → fork worktree → dispatch → 等 artifacts → 合 patch → 写学习记录」:
# router/core.py (示意代码,省略了错误处理/重试/超时)
from pathlib import Path
import hashlib, json, subprocess, shutil, time, uuid
from .yaml_config import load_harness_router_yaml
from .rule_engine import first_match_rule
from .adapters import ADAPTER_REGISTRY # 这里注册上面 YAML 里的 5 个 adapter
def run_once(repo_root: Path, user_prompt: str, *,
extra_tags: list[str] | None = None,
cost_cap_cny: float | None = None,
force_adapter: str | None = None) -> dict:
# 1) 载入配置
cfg = load_harness_router_yaml(repo_root / ".router" / "harness-router.yaml")
# 2) 生成任务元数据指纹(启发式:关键词、触碰路径估算、复杂度)
from .fingerprint import fingerprint_task
fp = fingerprint_task(repo_root, user_prompt, extra_tags=extra_tags)
# 3) 选路由(第1层:静态规则表 first-match)
if force_adapter:
rule = cfg.force_rule(force_adapter)
else:
rule = first_match_rule(cfg.rules, fp)
# TODO 未来叠 2/3/4 层:
# score = metadata_scoring(fp)
# if uncertain: rule = router_llm_classify(fp)
# rule = learned_history_correct(fp, rule)
adapter_cls = ADAPTER_REGISTRY[rule.adapter]
# 4) fork worktree:子任务不碰主树
run_id = uuid.uuid4().hex[:12]
wt_root = repo_root / ".router" / "worktrees" / run_id
run("git", "worktree", "add", "--no-checkout", str(wt_root), "HEAD", cwd=repo_root)
run("git", "-C", str(wt_root), "checkout", "-q", "HEAD")
# 5) 写 PROMPT.md:统一的 Brief 格式
prompt_file = wt_root / ".router-brief.md"
prompt_file.write_text(render_brief(user_prompt, fp, rule,
# 关键:给子 harness 的要求里强调
# 「跑完一定要写 .router-artifacts/ 四个文件」
REQUIRE_POSTAMBLE))
# 6) 凭据注入:走 env 临时 set,不写文件
creds_env = cfg.credentials.resolve_to_env(rule)
# 7) 调 Adapter:各家怎么进怎么出,完全交给 adapter
started_at = time.time()
try:
adapter = adapter_cls(
worktree=wt_root,
prompt_file=prompt_file,
rule=rule,
run_id=run_id,
extra_env=creds_env,
)
adapter.run(block=True, timeout_sec=rule.timeout_sec) # 各家实现见 5.4
finally:
wall_ms = int((time.time() - started_at) * 1000)
# 8) 读统一 artifacts:Router 只认这四个文件 + diff.patch
artifacts_dir = wt_root / ".router-artifacts"
result = json.loads((artifacts_dir / "result.json").read_text()) # {status, summary, approvals_taken, turns}
timeline = (artifacts_dir / "timeline.md").read_text() # 给用户看的时间线
cost = json.loads((artifacts_dir / "cost.json").read_text()) # {cny, tokens, quota_pct, vendor}
diff_patch = (artifacts_dir / "diff.patch").read_bytes() # 相对于 worktree HEAD 的 patch
# 9) 如果成功:合 patch 回主仓库(用 git apply --3way,允许手解冲突);失败就 abandon worktree
if result["status"] == "success":
run("git", "-C", str(repo_root), "apply", "--3way", "-",
input=diff_patch)
# 可选:把时间线写进 git commit message 体
run("git", "-C", str(repo_root), "add", "-A")
run("git", "-C", str(repo_root), "commit", "-q", "-m",
f"router({rule.adapter}): {result['summary']}\n\n"
f"router-run: {run_id}\n"
f"cost: ¥{cost['cny']:.2f} turns: {result['turns']} wall: {wall_ms}ms\n\n"
f"{timeline}")
else:
# 失败不污染主树;但把 artifacts 保留到 .router/failed/ 给 Learned Router 用
shutil.copytree(artifacts_dir, repo_root/".router"/"failed"/run_id)
# 10) 写学习记录(Learned Router 的训练集,第 4 层用)
record = {
"run_id": run_id,
"adapter": rule.adapter,
"model": rule.model,
"task_fp": fp,
"success": result["status"] == "success",
"success_score": result.get("score"),
"human_takeover": result.get("approvals_taken", 0),
"cost_cny": cost["cny"],
"wall_ms": wall_ms,
"turns": result["turns"],
}
with open(repo_root/".router"/"history.jsonl", "a") as f:
f.write(json.dumps(record, ensure_ascii=False) + "\n")
# 11) 清理 worktree(或保留给用户调试)
run("git", "worktree", "remove", "--force", str(wt_root), cwd=repo_root, check=False)
shutil.rmtree(wt_root, ignore_errors=True)
return record这份伪代码的关键洞察:
- Router 本身不碰模型,不写 prompt,不调工具。 所有 6 层适配都交给原厂 harness。Router 只做「胶水 + 隔离 + 记账」。
- 五道墙里最难的「墙 3:状态无法热迁移」直接被 git worktree 绕开:我不迁移中间态。一个任务从一而终跑在一个独立 worktree 里,跑歪了就删,不会对主工作区造成任何影响。
- 给子 harness 的要求只有一个:跑完必须写
.router-artifacts/下的四个标准文件 +diff.patch。这条是硬性契约,做不到的 Adapter 直接不合格。
5.3 统一 Worktree 会话契约(4 个文件 + 1 个 patch,缺一不可)
这是整个设计的地基。无论哪家 harness 怎么跑,输出必须收敛到下面这 5 件东西。Router 对任何子进程一律"先看文件齐不齐,再谈别的"。
<独立 worktree 根目录>
├── (你的项目源码)
│
├── .router-brief.md ← Router 写进去的:任务 Brief、规则、预算
├── (Claude/DSH/ZCode 自己会生成的私有目录: .claude/ .agents/ .zcode-goals/ ...) ← Router 全部忽略
│
└── .router-artifacts/ ← ★ Adapter 必须写的契约目录
├── result.json ← { "status": "success"|"failed"|"timeout",
│ "summary": "一句话说明做了什么(给 commit message 用)",
│ "score": 0.0~1.0, // 子 harness 自评或 CI pass 打
│ "turns": 12, // tool-call 轮数
│ "approvals_taken": 2 }
│
├── timeline.md ← 人类可读的时间线(附给用户 & commit message)
│ 例:
│ 1. 读 README.md 和 vite.config.ts(0:00)
│ 2. 首次请求批准:执行 `npm create vue@latest`(你已批准)
│ 3. 写 src/App.vue、router.ts、4 篇示例文章(0:12)
│ 4. `npm run build` 一次通过;lint 修复 2 条
│ 5. 完成,产物 28 个新文件
│
├── cost.json ← 统一货币换算(Learned Router 用来算性价比)
│ { "cny": 3.21,
│ "tokens_in": 12400, "tokens_out": 6890,
│ "quota_pct_used": 1.3, // 对订阅制适用
│ "vendor": "zhipu / zcode" }
│
└── diff.patch ← 相对于 worktree 初始 HEAD 的统一 patch
生成方法:`git -C <wt> diff HEAD > .router-artifacts/diff.patch`为什么这套契约能把 12 家现有项目的缺口补起来:
programmatic-agent-router (par) 缺的是「统一 artifact 契约 + worktree 隔离」,现在有了;orchestrate 缺的是「自动路由 & zcode/kimi 接入」,现在 YAML + Bot Bridge 补上了;
EchoBird / cc-switch 缺的是「自动 Router,不是手点下拉」,现在 rules 引擎替你选了,用户完全不用碰。
5.4 四家主流 Adapter 的落地命令(对应第八节里的三种抽象形态)
最后给 4 家写一下怎么兑现上面的契约。
Adapter A:DSH(开源,原生嵌入 headless 形态)—— 最好做
DSH 有 headless mode + JSON-RPC over stdout,直接跑:
# Router 调的实际命令(就是 5.1 YAML 里 dsh-native 那段):
DEEPSEEK_API_KEY=xxx \
npx -y @deepseek-harness/headless \
--workdir <WORKTREE> \
--preset PTC \
--jsonrpc stdout \
--max-turns 80 \
-p @<WORKTREE>/.router-brief.md \
< <(cat <<'YAML'
# Router 动态拼一份 settings.yaml 给子 DSH,和主 DSH 隔离
plugins: [@deepseek-harness/plugin-defaults]
llm:
provider: pi-ai
model: deepseek-v4-pro
apiKey: "${DEEPSEEK_API_KEY}"
# 关键:让子 DSH 在结束前强制执行一段 post-hook,生成 .router-artifacts/ 四个文件
post_run_hooks:
- shell: "bash .router/_builtin/dsh-post-hook.sh"
YAML
)_builtin/dsh-post-hook.sh 是 Router 自带的 30 行脚本,负责:
git -C $WORKTREE diff HEAD > .router-artifacts/diff.patch- 读 DSH 的
Trajectory.ndjson抽turns/approvals_taken - 读 DSH 的 token 账单,换算
cost.json - 写
timeline.md与result.json
Adapter B-1:Claude Code / Codex CLI(有官方 CLI)
Claude Code 支持 claude -p @file 直接跑一次性 prompt:
ANTHROPIC_AUTH_TOKEN=xxx \
claude --no-browser \
--project <WORKTREE> \
-m claude-sonnet-4-6 \
-p @<WORKTREE>/.router-brief.md关键点:在 .router-brief.md 的 REQUIRE_POSTAMBLE 末尾要强制写一句:
"任务结束前,你必须自行在 shell 里执行
bash .router/_builtin/claude-post-hook.sh,以写入.router-artifacts/四个文件与diff.patch;执行成功才能把自己的状态标记为完成。"
因为 Claude Code 是闭源的,我们没法塞真正的 post-hook,但我们可以把「写 artifacts」这件事写进任务要求里——只要模型最后真的执行了那条 bash,契约就成立。实测 Frontier 模型(Claude Sonnet 4.6+、GLM-5.3、DeepSeek-V4-Pro)对这种"最后必须做一件机械动作"的要求服从率很高。
Adapter B-2:ZCode(没出 CLI,闭源桌面端)→ Bot / Goals 桥接
这是最难的一家。三种办法从丑到稳按顺序:
- Bot 桥接(MVP,丑但能用):ZCode 官方自带飞书/微信 Bot + Goals。自己写一个 Bot(或买个「自建 Bot 到 ZCode Goals」的中间件,比如 EchoBird / cc-switch 源码里其实已经有这部分了),Router 往 Bot 发消息,内容就是目标 worktree 绝对路径 +
.router-brief.md。ZCode Bot 在本地机器上完成目标 worktree 的写入和构建;自己写一个 polling 线程循环检查{worktree}/.router-artifacts/result.json出现与否,出现就当成功。 - 桌面端 AppleScript / UI Automation(macOS 上可行):AppleScript / Accessibility API 直接激活 ZCode 桌面窗口,发送键盘输入、监听右下角状态。更稳但平台绑定。
- BASE_URL 透明代理 + 抓包反嵌(C 形态):ZCode 桌面端内部其实是调 zhipu 的 GLM API(走私有 Header + Signed Body)。如果 Router 坐在中间做中间人代理(和
agentic对 Claude Code 做过的事情一样),就能收集轨迹与成本。这部分给 Learned Router 做训练数据特别好用。
Adapter B-3:Kimi Code(桌面端闭源,官方暂无 CLI)
同 ZCode,走 Bot / UI Automation。国内实测中「Kimi 官方飞书机器人」已经支持发消息指定本地工作区路径,比 ZCode 还方便。
到此,四家主流组合(DSH/DeepSeek、ZCode/GLM、Claude Code/Claude、Codex/GPT、Kimi Code/Kimi)全部有实际落地命令或桥接路径,没有任何一家卡在"理论上"。
六、现实的阻力:为什么没人这么做?因为五道墙真的很硬
墙 1:Harness 闭源 + 体量大
- ZCode:桌面端闭源,安装包几百 MB,启动一整套服务,整个 App、多 agent 编排器、Goals runtime 都是私有代码(Z.ai 官方文档和 TLDR 都明确写明,只有 GLM 权重开源,Harness 部分是订阅制私有)(ZCode — Z.ai's official coding harness for GLM-5.2)。
- Claude Code、Codex Remote、Kimi Code:同理,都是闭源商业产品。
- 唯一开源可用的是 DeepSeek Harness(MIT),所以 A 形态 adapter 最好做。
你不可能"import zcode"。闭源 harness 只能通过 CLI 包装、Bot 通道、本地 HTTP 端口这类"外壳"接入。
墙 2:Tool / Prompt / Approval 协议家家不一样
哪怕能启动另一个 harness,在它要请求一个工具调用或者要你审批的时候,通知格式、schema、附件绑定、文件引用路径都是各家自定义的。Router 必须做"事件转译层",而且要转得对、转得不丢信息、转回来不能超时,非常难做。
墙 3:上下文 / 中间状态无法热迁移
GLM 在 ZCode 里跑了 10 个 step,然后 Router 判断"这支队伍好像跑偏了,换到 Claude Code 试试"——此时如何把 ZCode 里已经做过的文件修改、Bash 历史、缓存命中记录、Goal 状态、上一步用户的 approval 记录,完整地迁移到 Claude Code?目前没有任何标准,根本搬不动。
所以现在能做的,最多是"一个任务级别路由一次",任务一旦派出去就不能中途换队。
墙 4:订阅计费 + API 计费混合
DSH 是 DeepSeek API key 按量;ZCode / Kimicode / Claude Code 是月订阅 + 配额。怎么把"一次任务的成本"换算成统一货币做路由决策?要单独做账单聚合层。
墙 5:安全与沙箱
把同一个工作区、同一套凭据喂给三个闭源 harness,等于三个独立程序都可以写你本地磁盘、跑任意命令。Router 要统一做沙箱隔离、审批拦截、凭据注入,不能每家都有 root。
七、Router 怎么路由?四个现实可行的层次
不指望一口吃成胖子。一层一层叠:
第 1 层 · 静态规则表(MVP,马上能用)
先凭经验 + 实测 + 厂商公开能力矩阵写规则。
| 条件(任务特征) | 路由到哪支原厂组合 | 原因 |
|---|---|---|
| 任务含"后台跑 8 小时 / 手机随时打断 / 国内网络环境优先" | GLM → ZCode | Goals + 飞书/微信 Bot + 国内节点,原厂独家 |
| 任务含"超长文档 / 数百文件一起读" | Kimi → Kimicode | Kimi 原厂上下文工程最强,且有专门的文档模式 |
| 需要"插件高度可定制 / 开源可改 / 要自己做 Trajectory 观测" | DeepSeek → DSH | 只有 DSH 是 MIT 开源 |
| 涉及"安全/合规审计 / 企业私有权限系统" | Claude → Claude Code 或 GPT → Codex | 生态最成熟、企业内合规工具链全 |
| 预算敏感 + 本地模型 | DSH + Ollama | DSH 支持挂任意 OpenAI-compatible endpoint |
就是一张 YAML,足够把 50% 的场景分对。
第 2 层 · 元数据指纹路由
把任务抽成 5 个维度:复杂度、自主性、延迟上限、模态、成本上限。每一个维度用一个数字打标签,然后做一个"标签 → 候选 harness"的打分矩阵。Router 选分数最高的那个。
第 3 层 · 小分类模型路由(Router LLM)
参考 switchboard-llm / adaptive-model-router 的做法,但输出层不是"选哪个 API 模型",而是"选哪个 (harness, model) 的原厂组合"。用便宜、本地可跑的小模型(比如 Llama 3.1 8B)做分类。
第 4 层 · 历史闭环学习(Learned Router)
每次跑完记:
{
"harness": "zcode/goals",
"task_embed": "...",
"success_score": 0.92,
"cost_cny": 12.5,
"wall_ms": 1800000,
"human_takeover": 2
}离线学习一张"任务类型 × harness"的胜率表。下次同类任务来,Router 首先派表上最划算的那支工程队。跑一次,再把数据喂回去。这部分才是真正让 Router 越来越聪明的地方。
四层是叠加关系,不是互斥:静态规则先把硬边界拦住(比如 if human_takeover_not_available then never route to goals that need phone remote),剩下的交给元数据和小模型分类,再用历史数据修正。
八、Adapter 怎么接?三种形态(抽象分类)
注:本节是抽象分类总览,第五节 5.4 已经给 DSH、Claude Code、Codex、ZCode、Kimi Code 五家写了具体的落地命令 / Bot 桥接 / 透明代理做法,可以直接翻回去看。
跟之前写的一样,但这次可以把依据写得更实:
| 形态 | 适用对象 | 怎么做 |
|---|---|---|
| A. 原生嵌入型 | 开源 harness — 目前只有 DSH | 直接 import 它的 SDK,或者 headless 模式 spawn 子进程 + JSON-RPC / ACP 协议通信。最稳,因为接口公开。 |
| B. CLI / Bot 桥接型 | 闭源但有外部入口 — ZCode(飞书/微信 Bot + Goals)、Codex CLI、Claude Code(CLI)、Kimi Code 桌面端(如果未来出 CLI) | Router 把任务当作 CLI 参数 / Bot 消息发过去,通过 stdout / webhook / 文件回调收进度。虽然丑陋,但对任何闭源都通用。 |
| C. 透明代理反嵌型 | 允许通过 BASE_URL / proxy 配置的 harness — agentic 已经证明 Claude Code 这一层可行 | Router 坐在中间,拦截它发给上游模型的请求,从而在不动 harness 的前提下观察轨迹、收集统计、做计费。 |
现阶段 A+B 组合就能把三家主流组合跑起来。C 形态留作"反嵌观测"用,对 Router 的学习闭环收集数据特别好用。
九、对用户隐藏一切
最终用户面前只能暴露一个统一界面:
┌─────────────────────────────────────────────────────┐
│ [输入任务] 给我搭一个 Vue 博客,支持 Markdown 文章...│
│ [可选] 预算 ≤ ¥5 / 完成时间 ≤ 2 小时 │
└─────────────────────────────────────────────────────┘
进度流(对用户唯一可见的层):
Router 判定:长程、国内网络优先 → 派 ZCode(GLM-5.3 Goals)
→ 12:00 读取 README 与 package.json
→ 12:02 请求批准首次执行 `npm create vue@latest` [确认]
→ 12:30 第一条流水线 80% 完成
→ 手机推送:"遇到 lint 循环报错,是否允许我升级 Prettier?"
→ 14:00 完成,耗时 1h58min,成本 ¥3.2(GLM Coding Plan 配额 1.3%)
产物:统一的 diff / 变更集 / commit / 可回滚至于背后是 ZCode 在跑还是 DSH 在跑,用户没必要知道。 除非他自己想 override。
这才是"不再让用户去选哪家 code agent"的真正含义:用户不需要下拉框选 DeepSeek / GLM / Kimi / Claude,更不需要选 DSH / ZCode / Kimicode / ClaudeCode。
Router 替他选。
十、结语
回到文章开头我自己那个"DSH 里挂 GLM"的经历。那个问题真正让我难过的,不是 GLM 在 DSH 里没跑好,而是我知道同一个 GLM 在 ZCode 里能做得好得多,却因为"我不想开两个窗口、两个客户端、两套工作流",而把它硬塞进了一个不匹配的 harness——我为了自己的方便,浪费了模型一半的能力。
2026 年的现在,"多模型支持"几乎成了每个 AI IDE / CLI 的标配。绝大多数实现方式都是 "一个统一 agent framework + 多个 API provider"。这是最便宜、最容易交付的做法,但它对模型能力的折损是真实存在的,而且有大量基准数据可以量化。
如果 AI 的下一阶段比拼的真的是 Agent,那我们迟早要面对一个问题:
我们花了那么多精力做"按任务自动路由到最优模型",为什么不更进一步,按任务自动路由到最优的 "模型 + 厂商原生 harness" 组合?
这个方向工程代价很大,但回报也很明确:端到端能力 +10~25pp,不是靠换一个更大的模型,而是靠让每个模型回到自家那套被精心调校过的 harness 里去工作。
这就是我最近想得最多的一件事。先写下来,以后有进展再更。
参考
论文 / 基准 / 评测
- AIMultiple, A-CODE-CLI Bench: Agentic CLI Benchmark(同一 Sonnet 4.6 在 9 个 agent 上 backend 正确率 13.3%–77.3%)https://aimultiple.com/agentic-cli
- Endor Labs, Claude Fable 5: Same model, different harness, very different result(Fable 5 + Claude Code vs Cursor,SecPass 19%→29%)https://www.endorlabs.com/learn/claude-fable-5-take-two-same-model-different-harness-and-a-very-different-result
- Li et al., RepoMod-Bench, arXiv:2602.22518(Opus 4.5,Claude Code vs Codex CLI:48.2% vs 30.4%)https://arxiv.org/html/2602.22518v1
- Luo et al. (美团), AutoDesign: Meta-Harness Optimization, arXiv:2608.13560(换 DesignHarness 让全部 7 种组合 +5~+19.6pt)https://arxiv.org/pdf/2608.13560
- yuv.ai Agent Harness from 0 to 100(同一模型换 harness 跳 25 名)https://yuv.ai/blog/ai-agent-harness-guide
国内实测 / Harness 对照
- 智东西, GLM-5.3 来了:"裸考"读懂 DeepSeek Harness 7000+ 文件(ZCode+GLM-5.3 完整交付 4900 行代码)http://m.toutiao.com/group/7673781018294141455/
- 腾讯技术工程, DeepSeek Harness 实测:同一 Kimi K3 对比 Kimi Code vs DSHhttp://news.qq.com/rain/a/20260815A04L7400
- 玄姐, DeepSeek Harness 架构体系解构:Kimi Code vs DSH 轨迹分叉对比https://www.51cto.com/article/853109.html
- 程序员鱼皮, 把 GLM-5.3 接入 DSH 比拼(三家国产模型统一 DSH 环境)http://m.toutiao.com/group/7674996629749727778/
GitHub 产品 / 路由项目(第三节 3.1 层:一 Harness × N 个 API 后端)
- DeepSeek Harness(MIT 开源)https://github.com/deepseek-ai/DeepSeek-Harness
- switchboard-llm(按任务类型路由 API)https://github.com/foodtruckcommunity/switchboard-llm
- adaptive-model-router(agent runtime 内路由 API)https://github.com/guangyang1206/adaptive-model-router
- agentic(Claude Code BASE_URL 网关模式 → 路由到任意模型 API,"Harness Flip"路线原型)https://github.com/MaorBril/agentic
- rretsiem/opencode-hive(OpenCode 单 harness 内跑 plan/orchestrator/python-pro/go-pro 多角色,仍共享同一 prompt/tools 壳)https://github.com/rretsiem/opencode-hive
- cristoslc/dispatch-opencode-skill(dispatch 任务到多个并行 opencode session,都是 opencode 这同一个 harness)https://github.com/cristoslc/dispatch-opencode-skill
- v1truv1us/ai-eng-system(ai-eng agents 配置:OpenCode 主 agent prompt 注入 + Claude Code UserPromptSubmit Hook 做子 agent 路由)https://github.com/v1truv1us/ai-eng-system/blob/main/docs/subagent-orchestration-guide.md
- CBannink/agentic-coding-kit(多 host / 多子系统 harness 编排,但 harness 壳统一)https://github.com/CBannink/agentic-coding-kit
- chektien/agents(opencode + claude-code 多角色 orchestration 配置)https://github.com/chektien/agents
- ThinkDepthAI Issue #1:模型原生 tool DSL → 在错配 harness 里 10–20% 空信封 https://github.com/LGU-SE-Internal/ThinkDepthAI/issues/1
GitHub 产品 / 路由项目(第三节 3.2 层:真· Router × N 个原厂 Harness CLI 子进程) — 方向对了但都缺自动 Router + Worktree 契约
- KerryRitter/programmatic-agent-router(Rust CLI
par:真·跨 Harness 分发 prompt 到 cursor-agent/gemini/goose/opencode/qwen/aider/amazon-q/kimi 多家官方 CLI;路由靠手动--harness指定)https://github.com/KerryRitter/programmatic-agent-router - haowjy/orchestrate(跨 Claude Code / Codex / OpenCode 三家;agent 定义文件 + sync.sh 跨三家目录同步 + 子进程派活)https://github.com/haowjy/orchestrate
- artificemachine/superharness(872 commits:SQLite 共享契约 + 队列委派 + Handoff Ledger + adapters 目录 +
shux status统一控制台)https://github.com/artificemachine/superharness - PUSHINGSQUARES/Pushing-Dispatch*(Python:dispatch_matrix.toml 路由矩阵 + Brief-Only 上下文 + HANDOFF 文档;但 Pillar 1 默认做了 Harness Flip 回 3.1 层)https://github.com/PUSHINGSQUARES/Pushing-Dispatch*
- AdamFrisby/CodeyBox(.NET:IAgentRunner 多 Runner 模式,Claude/Codex/Copilot/Cursor/Gemini/opencode 各一个 Runner)https://github.com/AdamFrisby/CodeyBox
- edison7009/EchoBird(⭐3.1k Rust Tauri 桌面壳:一键切 Claude/Codex/DSH/Kimi/ZCode/OpenClaw 等;致命缺点 = 手点下拉切,无自动 Router)https://github.com/edison7009/EchoBird
- farion1231/cc-switch(⭐130k Rust Tauri 桌面壳:Claude Code/Codex/OpenCode/OpenClaw/Grok/Hermes 统一壳;同样 = 手切无 Router)https://github.com/farion1231/cc-switch
- ComposioHQ/agent-orchestrator(tmux 会话隔离 + 并行 worker + 每个 issue 一个独立 agent CLI worker;商业核心闭源),技术深度分析 Gist https://gist.github.com/jeffscottward/de77a769d9e25a8ccdc92b65291b1c34
- zhuwenzhuang/farming(浏览器工作区:Codex/Claude Code/OpenCode 多 agent 监督控制台;纯监督手切)https://github.com/zhuwenzhuang/farming
- drippy-passport96/agent-supervision-skills(PowerShell:Claude/Codex/Kimi 三家委派 + artifact 收集 + 本地校验;无 Router)https://github.com/drippy-passport96/agent-supervision-skills
- MiGoller/ai-agent-sandbox(Podman 根容器沙箱:Hermes/Aider/Claude Code 各 flavor + 网络默认锁;手动
--flavor选,不是 Router)https://github.com/MiGoller/ai-agent-sandbox - ntorga/agent-starter-kit(Markdown 驱动 Maestro:分解→计划→分派给子 Coder→复核→上下文记忆;多 CLI 内部派)https://github.com/ntorga/agent-starter-kit
商业产品 / 生态对比 / 生态列表
- Tembo(商业 SaaS:云端跑 Claude Code/Codex CLI/Cursor/Gemini/OpenCode 作为 backend;写在 Aider Alternatives 博客里)https://www.tembo.io/blog/aider-alternatives
- bradAGI/awesome-cli-coding-agents(110+ CLI coding agents + harness/orchestration 分类 curated list)https://github.com/bradagi/awesome-cli-coding-agents
- dz3ai/allclaws(34 种 AI agent 平台统一架构对比表:Claw/LangGraph/Cli Agent CLI 五大类)https://github.com/dz3ai/allclaws/blob/main/architecture/platform_comparison.md
- lwmxiaobei/dsh-plugins(Awesome DSH Plugins 导航,659 个社区插件)https://github.com/lwmxiaobei/dsh-plugins
- glamworks/glamfire research 07-competitors(Codex/Claude/Goose 等 CLI agent 路线 vs 路由轴 competitive landscape 深度分析)https://github.com/glamworks/glamfire/blob/main/research/07-competitors.md
- Composio, ZCode vs Claude Code comparison(文末那句"把便宜模型塞 Claude Code 当填充物"的出处)https://composio.dev/content/zcode-vs-claude-code
厂商官方文档
- ZCode for GLM-5.3(Z.ai 官方 ADE,闭源订阅)https://zcode.z.ai/en/docs/welcome
- ZCode Agent(GLM 专用 Agent 工作流深度适配)https://zcode.z.ai/en/docs/agents
