
如何统一管理 Codex、Claude、DeepSeek 等不同的 AI Harness,让切换像换编译器一样简单
最近越来越多团队开始同时使用多个 Coding Agent:
- Codex 擅长在真实代码库中执行任务
- Claude 在长上下文理解和方案分析上表现突出
- DeepSeek 成本友好,适合高频调用或私有化场景
- 未来还会出现更多模型、CLI、IDE 插件和 Agent Runtime
真正的问题已经不是“哪个最好”,而是:
如何避免工作流被某一个 Harness 锁死?
这里说的 Harness,不只是模型,而是包裹在模型外面的整套执行环境:提示词加载、文件访问、Shell、工具调用、权限控制、上下文管理、任务状态和日志记录。
如果直接分别使用这些工具,你很快会遇到几个问题:
- 每套工具有自己的配置格式
- 同一条规则需要复制到多个文件
- 工具权限和执行行为不一致
- 会话状态无法迁移
- 切换 Harness 时,需要重新解释整个项目
- 团队成员得到的执行结果难以复现
解决办法不是再造一个“万能 Agent”,而是在不同 Harness 上面建立一层统一的控制面。
一、先统一任务,而不是统一模型
不要直接把一句自然语言交给某个 Agent。
先把任务定义成与 Harness 无关的结构:
task: id: fix-payment-timeout goal: 修复支付回调偶发超时 workspace: ./services/payment constraints: - 不修改公开 API - 不新增生产依赖 - 保留现有数据库结构 acceptance: - 相关测试全部通过 - 新增超时场景测试 - 输出变更摘要 permissions: filesystem: write shell: restricted network: deny
Codex、Claude 或基于 DeepSeek 构建的 Agent,拿到的都应该是同一份任务定义。
这样切换 Harness 时,变的是执行者,不是问题本身。
二、建立统一的项目上下文
一个项目最好只有一份“事实来源”,例如:
.agent/
├── project.md
├── architecture.md
├── conventions.md
├── commands.yaml
├── policies.yaml
└── tasks/
这里存放:
- 项目结构与核心模块
- 架构约束
- 编码规范
- 构建、测试、格式化命令
- 禁止修改的目录
- 权限与安全策略
- 任务验收标准
不同 Harness 所需的专属文件,比如 AGENTS.md、CLAUDE.md 或其他配置,应该尽量由这份统一配置生成,而不是人工分别维护。
原则很简单:
业务知识只写一次,平台配置自动适配。
三、为每个 Harness 编写 Adapter
不同 Harness 的差异应该被封装在适配器里。
适配器主要负责五件事:
- 把统一任务转换为对应 Harness 的输入
- 注入项目上下文和规则
- 映射文件、Shell、搜索等工具
- 收集执行事件、日志和最终结果
- 将结果转换成统一格式
例如:
harnesses: codex: adapter: adapters/codex model: gpt-5 capabilities: - filesystem - shell - patch claude: adapter: adapters/claude model: claude-sonnet capabilities: - filesystem - shell - long-context deepseek: adapter: adapters/openai-compatible model: deepseek-coder capabilities: - filesystem - patch
然后使用统一入口:
agent run fix-payment-timeout --harness codex
agent run fix-payment-timeout --harness claude
agent run fix-payment-timeout --harness deepseek
甚至可以为不同任务设置默认路由:
routing: architecture: claude implementation: codex batch-refactor: deepseek
关键不是配置文件长什么样,而是上层工作流不需要理解每个供应商的内部细节。
四、统一能力接口,不追求功能完全一致
不同 Harness 的工具能力不可能完全相同。
有的支持结构化补丁,有的只能编辑整个文件;有的可以控制浏览器,有的只能调用 Shell;有的支持子 Agent,有的只支持单会话执行。
因此,不要假装它们完全等价,而应该建立能力注册表:
required: - read_files - write_patch - run_tests optional: - browser - subagents - image_input
运行任务前先检查能力:
- 满足全部必需能力:直接执行
- 缺少可选能力:降级执行
- 缺少必需能力:拒绝运行或自动选择其他 Harness
统一管理的目标不是消灭差异,而是让差异变得显式、可检测、可处理。
五、把权限放在 Harness 之外
不要依赖 Agent 自己判断哪些操作安全。
统一控制层应该明确规定:
- 哪些目录可读
- 哪些目录可写
- 哪些命令允许执行
- 是否可以访问网络
- 是否可以读取环境变量
- 哪些操作必须人工确认
- 是否允许提交代码或创建 PR
例如:
policy: filesystem: read: - src/** - tests/** write: - src/** - tests/** deny: - .env - secrets/** shell: allow: - npm test - npm run lint confirm: - npm install deny: - git push - rm -rf
无论下面运行的是 Codex、Claude 还是 DeepSeek,都必须经过同一个权限层。
这比在提示词里写一句“请不要执行危险操作”可靠得多。
六、让状态属于任务,而不是属于聊天窗口
很多 Agent 工作流难以切换,是因为重要信息全部藏在会话历史里。
更稳妥的做法是把状态外置:
run: task: fix-payment-timeout status: testing base_commit: a18c9f2 completed: - 定位到回调客户端缺少读取超时 - 增加超时配置 - 添加单元测试 pending: - 运行集成测试 - 检查兼容性 artifacts: patch: runs/1042/change.diff log: runs/1042/events.jsonl
这样 Codex 执行到一半,也可以把任务交给 Claude 继续审查;Claude 给出方案后,也可以让 DeepSeek 批量实现。
交接的对象应该是:
任务状态、代码差异、验证结果和待办事项,而不是一大段聊天记录。
七、统一输出格式,才能真正比较
每个 Harness 最终都应返回相同的结果结构:
{ "status": "completed", "summary": "为支付回调增加读取超时和重试边界", "files_changed": [ "src/payment/client.ts", "tests/payment/client.test.ts" ], "checks": { "unit_tests": "passed", "lint": "passed", "integration_tests": "not_run" }, "risks": [ "生产环境需要配置 PAYMENT_READ_TIMEOUT" ] }
同时记录:
- 完成率
- 执行时间
- Token 与费用
- 工具调用次数
- 人工介入次数
- 测试通过率
- 回滚率
- 最终补丁质量
没有统一的结果协议,就无法判断某个 Harness 是真的更好,还是只是“说得更像完成了”。
八、切换 Harness 的正确姿势
真正的“随时切换”不是在同一个聊天框里更换模型,而是:
统一任务定义 ↓ 统一上下文与权限 ↓ Harness Adapter ↓ Codex / Claude / DeepSeek ↓ 统一结果、日志与状态
例如:
# 让 Claude 分析问题
agent run payment-timeout --harness claude --stage plan
# 让 Codex 根据同一份计划实现
agent resume payment-timeout --harness codex --stage implement
# 让 DeepSeek 做低成本的批量测试修复
agent resume payment-timeout --harness deepseek --stage verify
同一个任务可以按阶段选择不同 Harness,也可以在失败后自动切换:
fallback: - codex - claude - deepseek
但自动切换之前,必须保留完整的任务状态和工作区快照,否则下一个 Agent 很可能重复工作,甚至覆盖已有修改。
九、一个可落地的最小方案
一开始不需要建设复杂平台。
只需实现四样东西:
- 一份统一的项目说明
- 一种结构化任务格式
- 一个调用不同 Harness 的 CLI
- 一套统一的结果与日志格式
目录可以非常简单:
agent-control/
├── agent.yaml
├── context/
├── tasks/
├── adapters/
│ ├── codex.sh
│ ├── claude.sh
│ └── deepseek.sh
└── runs/
先解决“同一任务可以被不同 Harness 接收和验证”,再逐步加入:
- 能力发现
- 权限沙箱
- 自动路由
- 失败回退
- 成本控制
- 并行执行
- 多 Agent 协作
- 质量评测
最后
未来大概率不会由某一个模型或 Harness 统治所有开发场景。
模型会持续变化,价格会变化,能力边界也会变化。今天适合写代码的工具,明天可能更适合做审查;今天最强的闭源模型,未来也可能被更便宜的开源模型替代。
因此,真正值得长期建设的不是对某个 Agent 的依赖,而是自己的:
- 任务协议
- 上下文资产
- 工具接口
- 权限体系
- 执行记录
- 评测标准
把 Harness 当作可替换的执行引擎,而不是工作流本身。
当项目知识、任务状态和安全策略都掌握在自己手里时,从 Codex 切换到 Claude,或从 Claude 切换到 DeepSeek,就不再是一次迁移。
它只是一项配置。