KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

01 · 九个可比槽位:把「Agent Harness」拆成可比较的零件 — keel 龙骨

四门解析课各讲了一家 harness,但每家的术语、切分方式、甚至「什么叫主循环」都不一样。要把五家(四家已有解析课 + E 平台)放进同一个坐标系,第一步是把「Agent Harness」这个含混的词拆成九个互相独立、每家都必然要回答的槽位(slot)。本课的四门前置解析课中,五家核心事实均有源码级出处;E 平台 为公司内部平台,只在各槽位做定性参与,无公开源码级证据。

四门解析课各讲了一家 harness,但每家的术语、切分方式、甚至「什么叫主循环」都不一样。要把五家(四家已有解析课 + E 平台)放进同一个坐标系,第一步是把「Agent Harness」这个含混的词拆成九个互相独立、每家都必然要回答的槽位(slot)。本课的四门前置解析课中,五家核心事实均有源码级出处;E 平台 为公司内部平台,只在各槽位做定性参与,无公开源码级证据。

九个槽位不是产品功能清单,而是机制切分:任何一家把 agent 跑起来的系统,都必须在每一格给出一个答案——哪怕答案是「我们没有这一层」。

槽位的入选标准有两条:一是独立性——任意两格之间不允许「改了一格必然改另一格」的强耦合(有依赖关系的格子会标注);二是不可回避性——跳过任何一格,系统要么跑不起来,要么在运行时以事故的形式替你补上答案(没有结果预算的系统迟早被一次并行 grep 打爆上下文)。九格按「从宿主到智能」排列:前三格是骨架(进程、循环、工具),中三格是内脏(安全、上下文、会话),后三格是生态(扩展、渠道、记忆)。每格先给一句引导,再放五家的一句话答案;引号内的机制名与常量值都出自四门解析课,可按代码地图回查。

一、进程模型与宿主形态(process model & hosting)

家 一句话答案
Claude Code 单进程 REPL(REPL.tsx 896KB 与 print.ts 215KB 共享同一个 query()),子 agent 是同进程 async generator;只有 daemon、远程桥、BYOC 执行器三类才起真子进程
DeepSeek (dsh) 单进程 Node 运行时 + vendored Cordis 响应式插件内核;浏览器 UI 是独立的 59 个 client 包,PTC 程序跑在专用子进程里
Hermes 一个 Python 内核(AIAgent)套七张壳:CLI/TUI、消息网关、HTTP API、ACP、cron、batch、dashboard;容器里是 s6-overlay 监督树
OpenClaw 单例 Gateway 本地控制平面:文件锁 + 崩溃熔断保证一个 operator 一个控制面,CLI、渠道、插件全部连到这一个进程
E 平台 HTTP 与执行彻底解耦的云原生多进程:HTTP 落 ARQ 队列由 worker 执行,多租户 workspace scope(定性,无公开源码级证据)

这一槽的分歧是九格里最大的:单进程(Claude Code、dsh)、多宿主进程树(Hermes)、单例常驻(OpenClaw)、HTTP/worker 分离(E 平台)是四种真正不同的工程立场,各自决定了后面八格的形状。注意两个「单进程」也不相同:Claude Code 的单进程是连 UI 一起(vendored Ink 在同一进程里渲染),dsh 的单进程是内核单进程 + UI 外置(client 59 包跑在浏览器)——后者是向平台形态过渡的单进程。

二、主循环与停止条件(agent loop & stop conditions)

家 一句话答案
Claude Code query() 壳 + queryLoop() 心,跨迭代状态是显式九字段 State;10 个终止 reason 与 7 个继续 transition 全部字面量化,maxTurns 只是其中一条出口
DeepSeek (dsh) while (await this.turn()) {} 一行驱动 turn/step 双层循环,无 maxSteps;停止只靠 concludesTurn、preStep reject、abort、error 四机制
Hermes 循环条件是三个变量的合取:max_iterations(默认 90)× IterationBudget.remaining × 宽限一轮标志;退出原因是贯穿全流程的诊断字符串
OpenClaw 无 maxTurns:硬边界只有 48 小时墙钟超时 + 六种循环检测器(warning 10 / critical 20)+ critical 二次命中硬终止
E 平台 AgentRunner 驱动至模型自然收尾,或协作式取消(stop_triggered → RunCancelledEvent);未见轮次上限的公开证据(定性)

这一格是「任务长度假设」的显影:给交互式编码工具配 90 轮上限很安全,给常驻助理配同样的上限就是事故。Claude Code 的枚举路线还有一层别家没有的收益——transition 字段让测试可以直接断言「这轮走的是哪条恢复路径」,而不必翻消息内容。

三、工具并发与结果预算(tool concurrency & result budget)

家 一句话答案
Claude Code isConcurrencySafe 分批、写工具严格串行、并行批 contextModifier 延迟到批次末按序提交;结果预算三级(50K 字符 / 100K token / 单消息聚合 200K),超限落盘回喂 2000 字节预览
DeepSeek (dsh) dispatch 可重叠执行,但提交严格按 model order(slots + committed 游标),上限默认 10;abort 时为未启动调用补合成错误结果保 replay 合法
Hermes 8 路并发 worker,配起始顺序门(120s)与授权门(360s)两道超时;单工具结果上限超大落临时文件
OpenClaw 任一工具声明 sequential 就整批串行(保守判据);结果截断两级——单条固定 8000 字符 + 按上下文预算的第二级
E 平台 DynamicTool 惰性加载 + embedding 查找,控制暴露给模型的工具面大小(定性,无公开源码级证据)

四家的共同不变量是「结果体积必须有上界」,分歧在上界挂在哪:Claude Code 挂在常量组(50K/100K/200K),dsh 挂在提交顺序不变量上(顺序本身就是 replay 的前提),OpenClaw 挂在两级截断(第一级保线格式、第二级保上下文预算),Hermes 挂在超时门(防的是饿死而非爆炸)。

四、权限与执行安全(permission & execution safety)

家 一句话答案
Claude Code 5 外部模式 + 四级(实为十步)规则链,deny 优先、放行最后;Bash 有 23 项专项检查;沙箱可用时才把「整把工具 ask」换成命令级检查
DeepSeek (dsh) 沙箱三后端 fail-closed(bwrap/landlock、seatbelt、windows-acl)+ 拒绝方言按后端归一 + 单向升级阶梯:模型只能申请放宽,永远不能自己放宽
Hermes 审批三模式 manual / smart / off,决策 once / session / always / deny;hardline 命令永不可绕;判词「唯一安全边界是操作系统」
OpenClaw 四层策略只能收紧不能放宽(Profile × allow/deny × 会话权限模式 × exec 审批),safe-bin 校验的是 argv 不只是 bin 名,审批是两阶段(先注册再解析)
E 平台 平台侧统一审批,工具可见性与执行权限由 workspace scope 决定(定性,无公开源码级证据)

五、上下文与压缩(context & compaction)

家 一句话答案
Claude Code 五级压缩各司其职、顺序固定:结果预算落盘 → snip → microcompact → contextCollapse → autocompact,真正的摘要由 fork 出来的模型调用完成(maxTurns 1、skipCacheWrite)
DeepSeek (dsh) 压缩是往 append-only 日志里写一条 surface replace 事件——历史不改写,被遮蔽节点仍可查,消息历史是派生结果
Hermes 压缩交接不可执行(compaction_handoff_not_actionable)也是退出原因之一;程序化工具调用经 refund() 退还不占迭代预算
OpenClaw 压缩两档 default / safeguard(配了 provider 直接提升为 safeguard);硬要求保留 tool-call / toolResult 配对切割
E 平台 上下文压缩阈值约 75%,越线触发压缩(定性,无公开源码级证据)

六、会话持久化与恢复(session persistence & resume)

家 一句话答案
Claude Code append-only JSONL transcript,读取设 50MB 闸门;rewind 靠文件历史快照,上限 100 个
DeepSeek (dsh) append-only 事件流是唯一真相(59 种事件类型),surface 投影派生消息;fork / resume / replay 消费同一条事件流
Hermes SQLite SessionDB + FTS5 全文检索(CJK 走独立 trigram 表),恢复有过大硬闸 SessionResumeTooLargeError
OpenClaw 状态目录双 schema 版本(state 9 / agent 17)各自迁移;审计库只存元数据、保留 30 天
E 平台 Redis Stream 存流式事件,客户端按 offset 断线续传、可重放(定性,无公开源码级证据)

恢复能力的分水岭在「事件流是不是真相」:dsh 与 E 平台 的恢复是重放(replay),Claude Code 与 Hermes 的恢复是重读(reload),OpenClaw 居中——transcript 是事实来源,但续跑有 TranscriptNotContinuableError 这类前置校验(最后一条是 assistant 就拒绝继续,防悬空 tool call)。

七、扩展与插件(extension & plugin)

家 一句话答案
Claude Code 扩展面刻意最小:agent markdown 定义 + MCP 工具 + 27 个 hook 事件;构建期用 feature() 裁剪,不设运行时插件总线
DeepSeek (dsh) vendored Cordis 响应式插件(inject epoch 指纹驱动挂卸),54 类 307 个子包,装配靠 YAML 补丁而非代码
Hermes plugin.yaml + entry-points 懒发现,36 个 provider 与 22 个渠道全部是插件;内核只认识协议与注册表
OpenClaw bundled 插件与第三方守同一条 SDK 边界 + 双重声明(package.json 清单分离)+ 官方目录 Ed25519 阈值签名
E 平台 平台内置工具注册与 DynamicTool 机制,扩展形态未公开(定性,无公开源码级证据)

八、多渠道与多用户(channels & multi-user)

家 一句话答案
Claude Code 无渠道层:单 operator 交互式终端是第一公民,非交互模式复用同一个 query()
DeepSeek (dsh) api/ 九包把运行时暴露成 HTTP/JSON 给桌面与 Web 客户端;多会话经 preset 与 agent-preset-registry 区分
Hermes BasePlatformAdapter 抽象 + 22 个渠道插件,命令定义单一来源扇出到 CLI 与各渠道
OpenClaw 20+ 渠道收敛成统一 inbound envelope,路由 binding → agent;多用户是归因不是隔离——群聊共享同一 transcript
E 平台 多宿主产品面(Agent Chat / LLM Chat / Workflow / ChatFlow)+ 多租户 workspace 隔离(定性,无公开源码级证据)

这一格与第一格强耦合:没有常驻进程就没有渠道(Claude Code),HTTP/worker 解耦天然适合多租户(E 平台)。Hermes 与 OpenClaw 都有渠道层,差别在扩展哲学——前者跑一次发现才知道有哪些渠道,后者靠 manifest 不执行代码就能算出「有哪些渠道、哪些已就绪」。

九、记忆与自改进(memory & self-improvement)

家 一句话答案
Claude Code CLAUDE.md 四层层级 + 相关记忆每轮 5 槽位注入;无自改进闭环,一切沉淀靠人工维护记忆文件
DeepSeek (dsh) 无自改进闭环;技能经 skill 插件与 preset 静态挂载,改进发生在发版而非运行时
Hermes 唯一做了完整 self-improving 闭环的:skill_manage 工具 + 后台复盘 fork(白名单仅 memory + skill,预算 16 轮)+ curator(只 archive 不 delete)+ usage 遥测
OpenClaw 五层记忆(Instructions / Curated core / Episodic / Prospective / Review)+ DREAMS.md dreaming;记忆插件是单槽位
E 平台 以 workspace scope 组织租户内上下文;未见自改进闭环的公开证据(定性,无公开源码级证据)

这一格的谱系是「从无到全」:Claude Code 把沉淀交给人工维护的 CLAUDE.md,dsh 把改进放进发版节奏,OpenClaw 有记忆但写入者是系统流程(dreaming)而非模型自主决策,Hermes 让模型自己写自己要长期执行的技能——风险与能力在同一处增长,所以它的 curator 不变量(只 archive 不 delete)不是附赠品,而是闭环的前置条件。

代码地图

机制 位置 要点
单进程与 UI 边界 claude-code-harness/course/01-entry-and-layering.md REPL 与 print 共享同一 query();三类真子进程清单
显式 State 与 transition claude-code-harness/course/02-the-agent-loop.md 10 终止 reason / 7 继续 transition;hasAttemptedReactiveCompact 防无限循环
工具并发分批 claude-code-harness/course/03-tool-runtime.md isConcurrencySafe 保守默认;并行批 contextModifier 延迟提交
权限裁决链 claude-code-harness/course/04-permission-and-safety.md deny 优先放行最后;1e/1f/1g 三步 bypass 模式也绕不过
五级压缩顺序 claude-code-harness/course/05-context-management.md 预算→snip→micro→collapse→auto 的固定顺序与递归护栏
fork 与工具池保序 claude-code-harness/course/06-subagent-mcp-and-session.md 内置在前保序去重防 cache breakpoint 击穿
Cordis epoch 指纹 deepseek-harness/course/01-cordis-kernel.md 依赖集合变化压缩成一次字符串比较驱动插件挂卸
插件全景与接缝 deepseek-harness/course/02-plugin-landscape.md 54 类 307 包;「契约包 + 实现包」通用形状
无 maxSteps 循环 deepseek-harness/course/03-agent-loop.md 四种停止机制;abort 补合成结果保 replay
append-only 事件流 deepseek-harness/course/04-session-event-log.md 日志唯一真相、surface 投影、ignorable 兼容机制
沙箱 fail-closed deepseek-harness/course/06-sandbox-and-providers.md 三后端 + 拒绝方言归一 + 单向升级阶梯
七种运行宿主 hermes-harness/course/01-positioning-and-hosts.md 同一 AIAgent 七种进程模型;s6 监督树
90 轮预算 hermes-harness/course/02-conversation-loop.md 三变量循环条件 + 15 个退出原因字面量
审批链 hermes-harness/course/03-tools-and-approval.md manual/smart/off;hardline 永不可绕;YOLO 导入期冻结
self-improving 闭环 hermes-harness/course/04-skills-and-memory.md 复盘 fork 白名单 memory+skill;curator 只 archive
OS 边界判词 hermes-harness/course/05-providers-channels-and-security.md SECURITY.md:唯一边界是操作系统,进程内只是纵深
单例 Gateway openclaw-harness/course/01-positioning-and-gateway.md 文件锁 + 崩溃熔断;锁目录带 uid 后缀
循环检测 openclaw-harness/course/02-agent-loop-and-guardrails.md 六检测器 + critical 二次命中终止;48h 超时
四层执行策略 openclaw-harness/course/03-tools-and-exec-safety.md Profile × allow/deny × 权限模式 × 审批只能收紧
envelope 与路由 openclaw-harness/course/04-channels-and-routing.md inbound envelope + binding→agent;多用户是归因
插件边界与记忆 openclaw-harness/course/05-plugins-memory-and-deploy.md bundled 同边界 + Ed25519 阈值签名 + 五层记忆单槽位
会话库与检索 hermes-harness/course/04-skills-and-memory.md SQLite SessionDB + FTS5;CJK 走 trigram 表
preset 装配 deepseek-harness/course/05-presets-and-code-mode.md 四种 preset 是四份 YAML 补丁而非四套代码
续跑前置校验 openclaw-harness/course/02-agent-loop-and-guardrails.md 末条是 assistant 抛 TranscriptNotContinuableError
E 平台 事实来源 无公开源码(内部平台) 全部标注「定性对比」:ARQ 队列 / Redis Stream / DynamicTool / 75% 压缩阈值 / workspace scope

关键取舍

九槽位是机制切分,不是功能清单,所以「没有这一层」也是有效答案。
Claude Code 在「多渠道」格的答案是空白,dsh 在「自改进」格的答案是空白——这两个空白本身就是信息:渠道层缺失意味着产品假设单 operator,自改进缺失意味着把改进放在发版节奏里。用功能清单对比例产品会漏掉这类「以缺席表态」的设计。

槽位之间有硬依赖,不能各格独立打分。
进程模型决定了会话形态(单例 Gateway ⇒ 状态有唯一属主),会话形态又决定了多用户的上限(OpenClaw 只能归因不能隔离);停止条件的立场决定了循环检测要不要存在(无 maxSteps ⇒ 必须把「卡住」做成可判定问题)。按单格「谁最好」打分会得到系统性错误的结论。

停止条件是五家分歧最大的一格,本质是对任务长度的假设不同。
Claude Code 假设任务以「轮」为单位(显式枚举每个出口),dsh 与 OpenClaw 假设任务可能任意长(去掉计数器、改用语义边界),Hermes 折中(90 轮 + 预算 + 宽限),E 平台 把终止权交给用户侧的协作式取消。这一格的选择会向下辐射到工具并发、压缩与恢复的所有设计。

E 平台 只做定性参与,是本坐标系刻意保留的局限。
E 平台 没有 source-level 证据,它的每一格答案都只描述机制形态(队列解耦、offset 续播、阈值压缩),不描述参数与实现细节。在「九槽位」里让它入座的价值是补上「平台化企业部署」这一形态——四家解析课覆盖的形态里没有这一档。

同一槽位内的参数差异往往比机制差异更能暴露立场。
同为「有上限」:Claude Code 的上限是类型系统强制每个出口给 reason,Hermes 的上限是 90 轮 + 宽限一轮,dsh 的 maxParallel 与 OpenClaw 的并发上限默认都是 10 但语义完全不同(一个保提交顺序、一个保副作用顺序)。读对比时先看机制、再看默认值,最后看默认值是否可覆盖。

自测题

  1. 把 Claude Code 的「显式 State + 10 reason」与 dsh 的「无 maxSteps 四机制」放在同一格里。请说明:如果给 dsh 补一个 maxSteps 计数器,它的哪些现有机制(提示:concludesTurn、abort 补写)会变得多余或冲突?
  2. OpenClaw 的多用户是「归因不是隔离」,E 平台 是「多租户 workspace」。请从进程模型一格推导:为什么单例 Gateway 架构做进程内多租户隔离的成本特别高?
  3. 五家的工具并发上限有 8(Hermes)、10(Claude Code、dsh)与「任一 sequential 整批串行」(OpenClaw)三种形状。请指出哪两家在保同一种不变量(提交/副作用顺序),哪一家的保守程度本质上不取决于数字。
  4. 九槽位里哪一格最能区分「个人工具」与「平台」?请用至少三家的证据论证,并说明为什么「权限与执行安全」不是最佳答案。
  5. E 平台 的 Redis Stream offset 续播与 dsh 的 append-only 事件流在「可重放」上目标一致。请说明两者服务对象(客户端 vs 重建逻辑)的差异,以及为什么前者可以不带 ignorable 这类兼容标记(推断)。

进入 keel 阅读