第三章:给四套工程建立共同坐标
3.1 先看职责,不先背目录
面对大型仓库,逐个打开目录很容易迷路。更有效的做法是先找五类入口:应用启动、代理循环、工具注册、会话存储与外部能力。把名字填入同一张表,再顺着一个具体任务阅读。
| 职责 | Claude Code 快照 | DeepSeek Harness | Pi | Codex |
|---|---|---|---|---|
| 会话或代理编排 | QueryEngine.ts |
ReactLoopAgent |
Agent / AgentSession |
CodexThread / Session |
| 模型循环 | query.ts |
agent-loop/src/agent.ts |
agent-loop.ts |
session/turn.rs |
| 工具路由 | tools.ts 与执行服务 |
ctx.tools |
Agent 工具集合 | ToolRouter |
| 历史到模型视图 | 消息规范化与压缩模块 | Session surface / deriveMessages | buildSessionContext / convertToLlm | history 与 StepContext 相关流程 |
| 扩展方向 | 工具、技能、插件、钩子 | Cordis 服务与事件 | 库接口与应用扩展 | Rust 模块、协议与运行时 |
这是一张定位图,不是声称每一格都是一一对应的同级对象。例如 Pi 的 Agent 属于更底层的可组合库,完整 coding-agent 还增加了会话与界面;Codex 的工具执行也不只发生在一个文件里。
3.2 固定版本才能讨论差异
本书的 DeepSeek Harness、Pi、Codex 分别固定到 687f282、16f5f0a、57d4fac。Claude Code 使用保存 2.1.88 业务提取源码的镜像提交 08d2207。完整提交号与文件哈希位于来源附录。
固定提交的目的,不是宣称这些版本最新,而是让读者能复核。若你手里的代码名字不同,先比较提交与职责,再判断是否真的产生架构差异。把两个日期的目录结构混在一起,会得到一些看似精彩却无法复现的结论。
3.3 四种阅读起点
Claude Code 适合从异步生成器和工具执行服务切入,观察多种事件怎样交付给调用者。DeepSeek Harness 适合从日志与投影切入,追踪哪些事实必须持久化,哪些事件只服务于活跃进程。Pi 适合从模型流函数注入切入,理解底层库如何留出宿主策略。Codex 适合沿输入通道、Turn 与执行编排器阅读,理解上下文快照、审批和实际执行之间的连接。
这些只是本书选择的教学视角,不能当作产品的唯一设计目标。每套工程都包含更多子系统,也可能同时采用上述模式。好的对照应指出证据与范围,而不是把每个项目贴成只有一个特点的标签。
3.4 阅读时做一份小账本
每读到一个关键函数,记下四项:它接受什么、修改什么、等待什么、失败后留下什么。读完一条主路径,再加入取消或重试。这样会形成可解释的控制图,而不是一长串文件名。
第一次不必完整跟进所有辅助函数。先把“结果从哪里回来”找清楚,下一遍再沿权限、存储或性能深入。源码索引在本书末尾提供固定链接与短摘录,既能帮助定位,也能防止仅根据函数名推断实现。