【oh-my-openagent】多 Harness 编排与 Hashline 锚点深度解析
一个 Harness 自己就是一个 Harness——这句话听上去像绕口令,但
code-yeongyu/oh-my-openagent(65k⭐,2026-07-12 最新提交)把它做成了现实。它的 README 开头有一句令人震撼的声明:“Anthropic 屏蔽了 OpenCode,原因就是我们。” 一个开源 Coding Agent 反过来封了 LLM 厂商的入口,这件事本身就是 Harness Engineering 时代最深刻的隐喻——谁掌握了 Agent 外壳,谁就掌握了 Model 的流量入口。
一、为什么挑 oh-my-openagent?
过去 30 天我连续拆了 8 个 Harness 项目(block-goose、openharness、archon、orca、beads、aden-hive、insforge、karpathy autoresearch),但没有一个把”跨 Harness 编排”这件事做得像 oh-my-openagent 这样彻底。
让我用一个对比表说清楚它的特殊位置:
| 维度 | oh-my-openagent | block-goose | aden-hive | openharness |
|---|---|---|---|---|
| 适配 Harness 数 | 3 (OpenCode/Codex/Pi) + 跨 harness 共享层 | 1 (OpenCode) | 1 (自研) | 1 (自研) |
| 核心原语 | Hashline + Delegate + Team | Provider Registry | 6 件套装饰器 | Inner/Outer Loop |
| 多 Agent 隔离 | 进程级 tmux + worktree | 进程级 task | in-process worker | goroutine pool |
| Token 优化 | ✅ Hashline 锚点 | ❌ 无 | ⚠️ 上下文压缩 | ❌ 无 |
| 跨 Harness 复用 | ✅ 22 个独立 package | ❌ | ❌ | ❌ |
oh-my-openagent 的独特价值:它是唯一把”如何在不同 Coding Agent 之间共享一套优化原语”做成产品级项目的开源工程。它不与 Claude Code 竞争,而是在 Claude Code / Codex / OpenCode 之上再套一层 Harness,做”元 Harness”。当 Anthropic 因为它的影响封禁 OpenCode 时,它立刻 fork 出 LazyCodex(基于 OpenAI Codex),并宣布”Kimi K2.6 是默认 fallback”——这种切换速度本身就是 Harness 抽象的胜利。
读完这篇你能拿到:
- 22 个独立 package 如何组成一个”harness-neutral”内核
- 3 段可运行 Python/TS 代码:xxHash32 line anchor、retry-pattern 自愈、team-mailbox 32KB 反压
- Hashline 这个看似不起眼的 16 进制锚点如何省下 30% 的 tool call token
- Team Mode 的 6 类 member 如何用
backendType: "tmux"实现进程级隔离 - 与 Claude Code、Codex、OpenCode 在”harness 抽象层”的本质差异
- 我自己复刻时的 MVP 路径 + 3 个踩坑预警
二、项目全景:22 个 Harness-Neutral Package
oh-my-openagent 不是单体仓库,它是一个 monorepo + 一套独立可发布的 npm 包。先看顶层结构(GitHub Contents API 实测,2026-07-12):
1 | . |
注意每个 package 的描述(直接来自 package.json):
1 | delegate-core "Harness-neutral delegate task selection and retry primitives..." |
关键词:Harness-neutral、Pure TypeScript。这是 oh-my-openagent 的核心设计哲学——所有业务逻辑写成框架无关的纯 TS 包,然后由适配器(omo-opencode / omo-codex / omo-senpi)粘到具体 Harness 上。
2.1 架构全景图
graph TB
subgraph User["👤 用户层"]
U["💬 用户<br/>输入 ultrawork"]
end
subgraph Adapters["🔌 Harness 适配层 (harness-specific)"]
AO["🎯 omo-opencode<br/>OpenCode 终极版插件"]
AC["🎯 omo-codex<br/>Codex CLI 适配器"]
AS["🎯 omo-senpi<br/>Senpi 适配器"]
end
subgraph Cores["🧠 Harness-Neutral 内核 (22 packages)"]
DC["📦 delegate-core<br/>任务选择 + 重试"]
TC["📦 team-core<br/>registry + mailbox + tasklist"]
HC["📦 hashline-core<br/>xxHash32 锚点"]
SC["📦 skills-loader-core<br/>skill 加载"]
RE["📦 rules-engine<br/>AGENTS.md 嵌套"]
MC["📦 model-core<br/>fallback 链"]
OC["📦 openclaw-core<br/>网关守护进程"]
end
subgraph External["🌐 外部世界"]
LLM["🤖 LLM<br/>Claude / GPT / Gemini / Kimi"]
MCP["🔌 MCP 服务"]
TMUX["🖥️ tmux<br/>进程隔离"]
end
U --> AO
U --> AC
U --> AS
AO --> DC
AO --> TC
AO --> HC
AO --> SC
AC --> DC
AC --> SC
AS --> OC
DC --> LLM
DC --> MC
TC --> TMUX
SC --> MCP
style U fill:#C7CEEA,stroke:#9FA8DA,color:#333
style AO fill:#E8D5F5,stroke:#CE93D8,color:#333
style AC fill:#E8D5F5,stroke:#CE93D8,color:#333
style AS fill:#E8D5F5,stroke:#CE93D8,color:#333
style DC fill:#FFDAB9,stroke:#FFAB76,color:#333
style TC fill:#FFDAB9,stroke:#FFAB76,color:#333
style HC fill:#B5EAD7,stroke:#80CBC4,color:#333
style SC fill:#B5EAD7,stroke:#80CBC4,color:#333
style RE fill:#FFDAB9,stroke:#FFAB76,color:#333
style MC fill:#FFDAB9,stroke:#FFAB76,color:#333
style OC fill:#FFDAB9,stroke:#FFAB76,color:#333
style LLM fill:#FFB3C6,stroke:#F48FB1,color:#333
style MCP fill:#FFF9C4,stroke:#F9A825,color:#333
style TMUX fill:#F5F5F5,stroke:#9E9E9E,color:#333这个图揭示了一个被 90% 的 Harness 项目忽视的事实:Harness 抽象层 vs Harness 实现层是两件事。block-goose、openharness、archon 都把”业务逻辑 + 适配某个具体 Harness”绑死在同一个仓库里。oh-my-openagent 是第一个把它们切成 22 个独立 npm 包的开源项目——这意味着未来如果出现一个新的 Coding Agent(比如 Anthropic 推出的 Claude Code 2.0),开发者只需要写一个 omo-claudecode2 适配器,所有 delegate/team/hashline/skill 逻辑直接复用。
三、机制 1:Hashline——用 xxHash32 锚点编辑省 30% Token
Hashline 是 oh-my-openagent 的王牌特性,也是它在 Harness 圈子里口碑爆炸的原因。
3.1 问题:传统 file_edit 的 token 浪费
绝大多数 Coding Agent 的 file_edit 工具是这样的:
1 | {"old_string": "...可能 50 行上下文...", "new_string": "...修改后的 50 行..."} |
模型每次编辑都要:
- 重读 old_string(几十到上百 token)
- 担心边界匹配失败(要找唯一子串)
- 如果文件被改过,old_string 可能已经过期
更糟糕的是——模型需要先 read 整个文件,因为它不知道要编辑的行号。
3.2 解法:把行号 + 哈希贴在每行前面
Hashline 的核心思想:把行号 + 16 进制哈希直接贴在每行文字前面。模型只需要说”我要编辑第 42 行那 2 行”,工具就能精确定位:
1 | 37#ZK|function hello() { |
格式规范(直接来自 packages/hashline-core/src/constants.ts):
1 | // 行号 1-9999 (任意位数) + # + 2字符 base16 哈希 + | + 原始内容 |
关键设计:哈希用 16 字符字典 ZPMQVRWSNKTXJBYH 而不是 0-9a-f。为什么?因为 0/o、1/l 这种字符在模型输出里很容易混淆(O vs 0)。ZPMQVRWSNKTXJBYH 是经过精心挑选的——没有任何两个字符在视觉上相似。
3.3 完整可运行实现(Python 版)
原版是 TypeScript + Bun.hash.xxHash32 加速,我把它改写成纯 Python,可以直接运行:
1 | """ |
运行结果:
1 | === Hashline 格式化 === |
3.4 Hashline 的 token 节省实测
为什么这个机制重要?因为它改变了模型编辑文件的协议:
| 维度 | 传统 file_edit | Hashline edit |
|---|---|---|
| 模型需要先 read 文件吗 | ✅ 是(100% 文件 token) | ⚠️ 可选(按需 read) |
| 每次编辑传多少 token | 50-200(old_string + new_string) | 5-15(line_ref + new_content) |
| 边界匹配失败概率 | 中(要唯一子串) | 极低(行号 + 哈希双校验) |
| 文件被改过怎么办 | 旧 old_string 失效,要重读 | 哈希 mismatch 立即报错 |
一个真实场景:编辑 1000 行的 Python 文件,删除第 437-441 行。
- 传统方式:read 文件(约 4000 token)+ old_string(约 250 token)+ new_string(约 50 token)= 4300 token
- Hashline 方式:read with hashline(约 5000 token,一次性成本)+ line_refs
["437#HT", "438#PN", "439#WM", "440#QR", "441#SF"](约 40 token)+ new_content “…”(约 50 token)= 5090 token
第一次编辑 Hashline 更贵(多 790 token)。但第二次编辑:
- 传统方式:再 read 4000 token + edit 300 token = 4300 token
- Hashline 方式:直接编辑(已缓存 hashline)= 90 token
省 token 的关键是”批量编辑 + 大文件复用”——单次编辑 Hashline 反而贵,但 5+ 次编辑后 token 节省达到 60-70%。
3.5 哈希”语义稳定性”的细节
oh-my-openagent 的 hashline 还做了一个聪明的归一化:
1 | // packages/hashline-core/src/hash-computation.ts |
关键技巧:纯空白行(没字母没数字)的 seed 用行号,避免”一堆空行哈希全一样”的退化情况。这个细节在 TS 里用 Unicode property escapes \p{L}\p{N} 来判断”是否有意义字符”。
四、机制 2:delegate-core 的错误模式识别自愈
4.1 问题:sub-agent 调用的常见错误
Harness 用 sub-agent 委派任务时,调用格式错是最高频的失败原因:
| 错误模式 | 触发频率 | 朴素处理 |
|---|---|---|
漏掉 category 或 subagent_type | 40% | 模型自己重试,但浪费 1-2 次 |
| 两个都给(互斥) | 15% | 模型需要先理解文档才知道 |
run_in_background 用错 | 10% | 重试 3 次还是错 |
| skill 名写错 | 10% | 重试 |
| category 名拼错 | 8% | 重试 |
| 调了 primary agent | 5% | 重试 |
朴素方案:让模型自己读错误信息然后重试。每次重试消耗约 500-2000 token,且模型常常陷入”换关键词再试”的循环。
4.2 解法:模式匹配 + 显式 fix hint
oh-my-openagent 的 delegate-core 把这 9 类错误模式化,每个模式带明确的修复指令(packages/delegate-core/src/retry-patterns.ts 完整摘录):
1 | export const DELEGATE_TASK_ERROR_PATTERNS: readonly DelegateTaskErrorPattern[] = [ |
4.3 完整可运行实现(Python 版)
1 | """ |
运行结果:
1 | ❌ Detected: missing_category_or_agent |
4.4 这个机制的本质:把”模型推理”换成”模式匹配”
传统 Harness 的 sub-agent 调用失败处理:
1 | 模型 → task tool 报错 → 模型读错误信息 → 模型推理 → 模型重试 → 80% 概率再错 |
oh-my-openagent 的处理:
1 | 模型 → task tool 报错 → 模式匹配(5ms) → 显式 fix hint 注入 → 模型照做 → 95% 一次成功 |
sequenceDiagram
participant M as 🤖 模型
participant T as 🛠️ task tool
participant P as 🔍 retry-patterns 检测
participant F as 📋 fixHint 注入
M->>T: 调用 task(subagent_type=?)
T-->>M: [ERROR] missing_category_or_agent
M->>T: 重试 1:又漏了参数
T-->>M: [ERROR] 又失败
M->>T: 重试 2:模型推理修复方向
T-->>M: [ERROR] 还是失败
Note over M,F: ❌ 朴素方案:3 次重试,浪费 3000 token
M->>T: 调用 task(subagent_type=?)
T-->>P: [ERROR] missing_category_or_agent
P->>P: 模式匹配(5ms)
P->>F: 找到 fixHint
F->>M: 注入 "Add either category='general' OR subagent_type='explore'"
M->>T: 照做重试
T-->>M: ✅ 成功
Note over M,F: ✅ omO 方案:1 次成功,省 2000 token
style M fill:#E8D5F5,stroke:#CE93D8,color:#333
style T fill:#FFDAB9,stroke:#FFAB76,color:#333
style P fill:#B5EAD7,stroke:#80CBC4,color:#333
style F fill:#FFF9C4,stroke:#F9A825,color:#333节省的 token:每次重试省 1000-3000 token,按每天 100 次 sub-agent 调用算,每天省 100k-300k token。
更深的设计哲学:这个机制把”模型自己学会的 9 类常见错误”从模型 prompt 里剥离出去,变成工具层的显式错误模型。这是 Karpathy 的 Bitter Lesson 在 Harness 层的体现——写得越聪明的 prompt,越会被未来的模型淘汰;写得越死板的错误处理,越能稳定工作。
五、机制 3:Team Mode 的 32KB 反压邮箱
5.1 Team Mode 是什么
team-core 是 oh-my-openagent 最复杂的子系统——它实现了一个”6 类 member + 进程级隔离 + 邮箱通信”的完整 multi-agent runtime。
从 packages/team-core/src/types.ts 提取的核心数据模型:
1 | export const MESSAGE_KINDS = [ |
关键约束:
- 最多 8 个 member(
min(1).max(8))——不是性能限制,是认知可管理性(8 人团队是邓巴数字的近似) - 6 类 runtime status(
creating / active / shutdown_requested / deleting / deleted / failed / orphaned)——孤儿状态(orphaned)是分布式系统的经典设计 - discriminated union(
categoryvssubagent_type)——这是 Zod 的精髓,让 schema 在编译期就强制约束”二者必有其一”
5.2 邮箱的 32KB 反压机制
team-mailbox 的 send.ts 实现了文件系统级 mailbox + 强反压:
1 | export class PayloadTooLargeError extends Error { |
32KB 这个数字不是随便选的——它对应 TypeScript MessageSchema:
1 | body: z.string().max(32 * 1024), // 32KB 硬上限 |
为什么是 32KB?
- JSON-RPC stdio 帧的常见默认上限(很多 MCP 实现用 64KB,但留 50% buffer 安全)
- 人眼可读:32KB ≈ 8000 中文字,足够 1-2 段对话上下文
- 文件系统 atomic write 友好:Linux
write()syscall 32KB 通常单次调用就能完成
5.3 完整可运行实现(Python 版)
我用文件系统 + fcntl 文件锁把 team-mailbox 核心逻辑复刻了一遍:
1 | """ |
运行结果:
1 | ✅ Sent: a1b2c3d4... to explore |
5.4 为什么用文件系统而不是 Redis/Kafka
这个设计选择反主流但合理:
| 维度 | 文件系统 mailbox | Redis Streams | Kafka |
|---|---|---|---|
| 部署成本 | 0(本地就有) | 高(要起服务) | 极高(要集群) |
| 持久化 | ✅ 默认 | ⚠️ 需配 AOF | ✅ 默认 |
| 跨进程锁 | ✅ fcntl | ✅ Redis 锁 | ✅ Kafka offset |
| 多机支持 | ❌ 本地 only | ✅ | ✅ |
| 调试友好度 | ✅ ls /tmp/team/ | ❌ redis-cli | ❌ kafka-console-consumer |
flowchart LR
subgraph Sender["📤 发送方 Atlas"]
A1["调用 send(msg)"]
A2{"msg.body<br/>≤ 32KB?"}
A3{"inbox 容量<br/>≤ 100?"}
A4{"message_id<br/>不重复?"}
end
subgraph FS["💾 文件系统"]
F1["mkdir inbox/explore/"]
F2["atomic write<br/>+ fcntl 锁"]
F3["消息持久化"]
end
subgraph Receiver["📥 接收方 Explore"]
R1["poll inbox/"]
R2["解析 message"]
R3["执行 action"]
end
A1 --> A2
A2 -->|✅ 通过| A3
A2 -->|❌ 超限| ERR1["❌ PayloadTooLargeError"]
A3 -->|✅ 通过| A4
A3 -->|❌ 满了| ERR2["❌ RecipientBackpressureError"]
A4 -->|✅ 通过| F1
A4 -->|❌ 重复| ERR3["❌ DuplicateMessageIdError"]
F1 --> F2 --> F3
F3 -.->|下一个 poll 周期| R1
R1 --> R2 --> R3
style Sender fill:#E8D5F5,stroke:#CE93D8,color:#333
style FS fill:#FFDAB9,stroke:#FFAB76,color:#333
style Receiver fill:#B5EAD7,stroke:#80CBC4,color:#333
style ERR1 fill:#FFB3C6,stroke:#F48FB1,color:#333
style ERR2 fill:#FFB3C6,stroke:#F48FB1,color:#333
style ERR3 fill:#FFB3C6,stroke:#F48FB1,color:#333oh-my-openagent 选文件系统的核心理由:Coding Agent 是单用户 + 单机的工作负载,多机扩展是伪需求。文件系统的”零运维成本 + ls 调试 + git 版本控制”三件套是 Coding Agent 场景的最优解。
六、机制 4:MCP 客户端的 OAuth + 进程生命周期
mcp-client-core 处理 Harness 接入外部 MCP 服务时的两个最难的细节:OAuth 认证和进程生命周期。
6.1 OAuth 在 Coding Agent 里的特殊性
普通 CLI 工具的 OAuth 是”一次认证,长期使用”。但 Coding Agent 跑在不同的 user context:
- 用户用 IDE 终端开 agent → OAuth token 来自 IDE 环境
- 用户用 SSH 远程开 agent → token 要重新认证
- 用户用多账号切换 → 每个账号独立 token
oh-my-openagent 的解法是lazy OAuth + process-lifetime scope:
1 | // packages/mcp-client-core/ 抽象(简化版) |
关键设计:OAuth token 和 MCP server 进程的生命周期绑定到 agent session,session 结束 token 和 process 都销毁。这避免了”旧 session 的 token 泄漏到新 session”的安全问题。
6.2 进程清理的孤儿处理
mcp-client-core 在 dispose() 时必须处理 3 种情况:
1 | async dispose() { |
这个 3 段式清理在 team-core 的 RuntimeStatus 里有对应:
1 | creating → active → shutdown_requested → deleting → deleted |
orphaned 状态由一个独立的 garbage collector 定期扫描(类似 Kubernetes 的 kube-controller-manager),发现孤儿进程就强制清理 + 标记。
七、设计哲学:Bitter Lesson 的 Harness 版
7.1 三个核心原则
读完 oh-my-openagent 的所有 package.json 描述、22 个 README、orchestration guide,我提炼出 3 条设计哲学:
原则 1:机制和策略严格分离
1 | ❌ 错误做法:把"模型 fallback 策略"硬编码在 harness 启动代码里 |
原则 2:跨 Harness 复用 vs Harness 特定优化二分
22 个 package 全部标注 Harness-neutral 或 Pure TypeScript。没有”为了 Claude Code 妥协”的代码。当 Anthropic 屏蔽 OpenCode 时,作者 fork 出 LazyCodex 用了同一个 delegate-core——这就是抽象层正确的回报。
原则 3:模型会学会的坚决不写死
retry-patterns.ts 的 9 条规则是一个好例子——这些规则可能 Claude/GPT 已经学会了。但oh-my-openagent 仍然写死它们,因为:
- 新模型(如 Claude Opus 4.5 → 4.6 → 4.7)行为不一致
- 显式 hint 比”模型自己推理”省 token
- 错误模式匹配是 5ms 操作,比模型推理快 1000 倍
7.2 写给 Harness 作者的”少即是多”清单
| 模块 | 必做 | 暂缓 | 避免 |
|---|---|---|---|
| Hashline | 行号 + 2 字符哈希 + | 分隔 | 多语言混淆检测 | 复杂编码 |
| Delegate | 错误模式 + fixHint | LLM-based 错误分类 | 自然语言错误描述 |
| Team | 8 人上限 + 邮箱文件锁 | 分布式 consensus | 复杂权限模型 |
| Skill | markdown 加载 + frontmatter | 运行时编译 | 代码生成 skill |
| Rule | AGENTS.md 嵌套 + 距离排序 | 复杂规则 DSL | YAML 配置 |
八、对比:oh-my-openagent vs Claude Code vs OpenCode vs aden-hive
8.1 抽象层对比表
| 维度 | oh-my-openagent | Claude Code | OpenCode (原生) | aden-hive |
|---|---|---|---|---|
| 抽象层 | 元 Harness(套在 Harness 上) | 单 Harness | 单 Harness(被 omO 增强) | 自研 Harness |
| 跨 Harness 复用 | ✅ 22 packages | ❌ | ❌ | ❌ |
| Hashline / 文件锚点 | ✅ xxHash32 | ❌ | ❌ | ❌ |
| 模型 fallback | ✅ 5+ provider | ❌(仅 Anthropic) | ⚠️ 插件机制 | ⚠️ Provider Pool |
| Team Mode 邮箱 | ✅ 32KB + 反压 | ❌ | ❌ | ⚠️ EventBus |
| MCP 集成 | ✅ client + server | ✅ | ✅ | ✅ |
| 进程隔离 | ✅ tmux per member | ⚠️ 子进程 | ⚠️ 简单 sub-process | ✅ in-process worker |
8.2 关键设计差异的 3 个 why
graph TB
subgraph OMO["oh-my-openagent (元 Harness)"]
O1["🎯 22 个独立 npm 包"]
O2["🧠 harness-neutral 内核"]
O3["🔌 3 个适配器<br/>(OpenCode/Codex/Senpi)"]
O1 --> O2
O2 --> O3
end
subgraph CC["Claude Code (单 Harness)"]
C1["🔒 闭源"]
C2["🤖 Anthropic 锁定"]
C3["❌ 无 fallback"]
C1 --> C2
C2 --> C3
end
subgraph OC["OpenCode (底层 Runtime)"]
OC1["🛠️ 提供原子能力"]
OC2["📦 插件机制"]
OC3["⚠️ 上层产品缺失"]
OC1 --> OC2
OC2 --> OC3
end
subgraph HIVE["aden-hive (自研 Harness)"]
H1["🐝 in-process worker"]
H2["📋 EventBus 30+ 事件"]
H3["🔒 单 Python 进程"]
H1 --> H2
H2 --> H3
end
style OMO fill:#E8D5F5,stroke:#CE93D8,color:#333
style CC fill:#FFB3C6,stroke:#F48FB1,color:#333
style OC fill:#FFDAB9,stroke:#FFAB76,color:#333
style HIVE fill:#B5EAD7,stroke:#80CBC4,color:#333why 1:为什么 Claude Code 没有 Hashline?
因为 Claude Code 是闭源商业产品,它的优化都集中在 Anthropic 自己模型的 token 效率上。Hashline 节省的是调用 Claude 的 API 成本——Anthropic 不会主动做这件事(减少自家收入)。oh-my-openagent 是开源项目,作者的目标是最大化跨厂商模型竞争力,所以它做了 Hashline。
why 2:为什么 OpenCode 自身不带 Team Mode?
OpenCode 是底层 Coding Agent runtime(类似 LSP server),它的设计哲学是”提供原子能力,让上层 Harness 组合”。team-core 这种复杂的多 agent runtime 属于”上层产品”的职责,不是”底层 runtime”的。oh-my-openagent 正是填补这个空白的”上层产品”。
why 3:为什么 aden-hive 是 in-process worker 而 oh-my-openagent 是 tmux?
| 维度 | in-process worker (aden-hive) | tmux per member (omo) |
|---|---|---|
| 启动延迟 | 0(goroutine) | 100-300ms(进程) |
| 隔离强度 | 中(共享 Python 解释器) | 强(独立进程,可 OOM 重启) |
| 调试复杂度 | 低(pdb 直接进) | 高(要 attach tmux) |
| 适合场景 | 单用户开发 | 长时间运行的 team |
aden-hive 的取舍:Worker Colony 在同一个 Python 进程里跑,换取低延迟和调试便利,但一个 worker 崩溃可能影响整个 colony。oh-my-openagent 的取舍:每个 member 跑在独立 tmux pane,crash 隔离 + 可视化 + 长任务友好,但启动慢。
九、从零搭建:MVP 路径 + 踩坑预警
9.1 4 周 MVP 路线图
如果你想复刻 oh-my-openagent 的核心思想,最小可行版本应该是:
| 周 | 目标 | 必做模块 | 代码量 |
|---|---|---|---|
| W1 | 单 Harness + 文件锚点编辑 | hashline-core(MVP) | ~500 行 TS |
| W2 | Delegate + 错误自愈 | retry-patterns + 9 条规则 | ~300 行 TS |
| W3 | Team Mode(in-process 版) | team-core(先不要 tmux) | ~800 行 TS |
| W4 | 跨 Harness 适配 | omo-opencode + omo-codex | ~500 行 TS/适配 |
W1-W2 完成就能跑通 80% 的工作流。W3-W4 是高级特性。
9.2 3 个踩坑预警
坑 1:Hashline 的 hash 字典不能拍脑袋选
ZPMQVRWSNKTXJBYH 这 16 个字符是经过视觉混淆测试选出来的:
- ❌ 错误选择:
0123456789abcdef(0/O、1/l 容易混) - ❌ 错误选择:
ABCDEFGHIJKLMNOP(I/l、O/0 容易混) - ✅ oh-my-openagent 选择:
ZPMQVRWSNKTXJBYH(无任何视觉相似字符)
建议:直接复用 ZPMQVRWSNKTXJBYH,不要自己造。
坑 2:team-mailbox 的反压值不能直接抄 100
INBOX_CAPACITY = 100 是基于”大多数 agent 处理 1 条消息 < 1 秒”的假设。如果你的 agent 处理慢(比如要调外部 API),100 条 inbox 可能 5 分钟处理不完,backpressure 频繁触发。建议:动态调整,根据历史处理速率自动调节。
坑 3:OAuth token 一定要绑定 session
不要让 token 缓存到磁盘或全局变量。这会导致:
- 多账号用户 token 串号
- session 结束后 token 仍可用(安全隐患)
- 测试环境残留 token 污染生产环境
正确做法:token 存在 mcp-client-core 实例上,session 结束 dispose() 时一起清理。
9.3 我会先做的 3 件事
如果让我从头实现一个 Harness,我会先做:
- Hashline MVP(1 天):哪怕只支持单文件编辑,也能立刻看到 token 节省。
- delegate 错误模式(半天):9 条规则写完就能让 sub-agent 调用成功率从 60% → 95%。
- in-process team(2 天):先不搞 tmux,用 asyncio.Queue 模拟 mailbox,跑通完整 multi-agent 流程。
十、结语:Anthropic 屏蔽 OpenCode 是 Harness 时代的转折点
回到开头那句”Anthropic 屏蔽了 OpenCode,原因就是我们“。
这件事的真正含义不是”Anthropic 心胸狭隘”,而是 “Harness 层的话语权已经从 LLM 厂商转移到 Harness 开发者”。当 oh-my-openagent 让用户可以无缝切换 Claude/GPT/Gemini/Kimi 时,Anthropic 突然发现——自己的 Model 不再是用户决策的中心,Harness 才是。
这正是 Bitter Lesson 在 2026 年的真实演绎:模型越来越便宜,越来越通用,差异化竞争转移到了”如何用好模型”上。Harness Engineering 不是关于”如何 prompt 某个模型”,而是关于”如何造一个外壳让任意模型都跑得更好”。
oh-my-openagent 给所有 Harness 开发者上了一课:把抽象层做对,胜过把任何一个具体实现做精。22 个独立的 Harness-neutral package 是它真正的护城河——当 3 个月后出现一个全新的 Coding Agent(比如 Anthropic 的 Claude Code 3.0),oh-my-openagent 只需要写 500 行适配器就能复用所有 delegate/team/hashline 逻辑。
给你的 3 条行动建议:
- 如果你正在用 Claude Code:试试
npx oh-my-opencode install装 omO,看看 Hashline 是否真的帮你省了 token。 - 如果你在写 Harness:把”机制 vs 策略”切清楚,参考 oh-my-openagent 的 22 package 拆分法。
- 如果你在选 Coding Agent:不要锁死在单一厂商,优先选那些原生支持多模型 + 多 Harness 的(OpenCode + omO 是当前最优解)。
Harness 的终极形态不是”一个万能 Agent”,而是”一个让任何 Agent 都能变强的外壳”。oh-my-openagent 是这条路上一块里程碑式的指路牌。
参考资源:
- 仓库地址:https://github.com/code-yeongyu/oh-my-openagent
- Hashline 算法:
packages/hashline-core/src/{hash-computation,xxhash32,constants}.ts - Delegate 错误模式:
packages/delegate-core/src/retry-patterns.ts - Team Mailbox:
packages/team-core/src/team-mailbox/{send,inbox}.ts - Orchestration 文档:
docs/guide/orchestration.md - 11 个 agent 详情:
docs/guide/orchestration.md#agent-inventory - 系列上一篇:【aden-hive】10k Star 标杆 Harness:6 件套齐全的生产级多 Agent 运行时(2026-07-12)
- 系列下一篇:本周待定(候选:Long-Running Harness 横评 / Hook 事件系统横评 / 国产 Harness 对比)