这是一篇运行时对运行时的对照。它不比较 GPT 和 Claude 哪个模型更聪明,而是比较模型在一轮工作中怎样被驱动、受什么约束、从哪里恢复状态、看见什么上下文、怎样调用工具,以及工具究竟在哪个运行环境中落地。
#先看地图:一轮 Coding Agent 从开始到结束
Harness 可以拆成六个要素:流程、约束、持久化、上下文、工具、运行环境。它们不是六个并列功能页,而是一条会反复循环的执行链。本文沿着任务真实经过的顺序下钻:先决定这一轮怎么走,再加载边界和状态,组装模型输入,处理工具调用,最后在宿主环境执行并把结果写回。
flowchart TD
S([开始:用户提交“修复 checkout 超时”]) --> F["① 流程<br/>决定单 Agent、委派、继续、重试或结束"]
F --> C["② 约束<br/>规则、技能、审批、Hook、权限策略"]
C --> P1["③ 持久化读取<br/>history、summary、附件、项目状态"]
P1 --> X["④ 上下文<br/>把任务、约束、状态、已选能力装成 prompt"]
X --> M["模型推理"]
M --> T{"需要工具或子任务?"}
T -- 否 --> P2["③ 持久化写回<br/>保存答复与当前状态"]
T -- 工具 --> U["⑤ 工具<br/>发现、校验、调度、截断、规范化"]
T -- 子任务 --> F
U --> R["⑥ 运行环境<br/>PTY、沙箱、工作目录、网络、MCP transport"]
R --> P2
P2 --> D{"任务完成?"}
D -- 否 --> N["下一轮:携带新状态"]
N --> F
D -- 是 --> E([结束:交付结果与可审计记录])
R -. "风险:副作用、网络边界、环境漂移" .-> RR["运行风险"]
P2 -. "风险:摘要丢失早期证据" .-> PR["状态风险"]
#阅读路线
| 章节 | 在上图中的位置 | 它回答的问题 |
|---|---|---|
| 1. 流程 | 开始、分支、下一轮 | 谁决定继续、委派、重试或停止? |
| 2. 约束 | 模型与执行器前 | 哪些项目规则和权限边界必须同时生效? |
| 3. 持久化 | 读取与写回 | 跨回合究竟保存什么,压缩时又改写什么? |
| 4. 上下文 | 模型调用前 | 本轮 prompt 怎样由任务、规则、history 和能力组成? |
| 5. 工具 | 模型调用后 | 工具说明何时入窗,结果如何不撑爆下一轮? |
| 6. 运行环境 | 工具真正落地时 | shell、网络、MCP 到底在哪个边界内执行? |
一句话结论:Codex 更倾向把流程、策略、会话与执行环境的开关显式交给宿主;Claude Code 2.1.88 更倾向把探索、工具包装和会话整理封装为默认运行时策略。前者的价值是可配置、可审计,后者的价值是低摩擦、默认路径完整。
#版本与四层证据边界
| 角色 | Codex | Claude Code | OpenCode |
|---|---|---|---|
| 主要证据:解释内部机制 | Codex 源码备份,ae057e0 | CC 2.1.88 镜像备份,c8cd253 | OpenCode 源码备份,d2bd7ea |
| 辅助证据:解释用户实践 | OpenAI Cookbook | Claude Code 官方手册 | OpenCode 官方文档 |
本文的证据纪律很简单:
- 源码回答“某段 runtime 实际读了什么、写了什么、走了什么分支”。
- Cookbook回答“开发者可怎样把这类能力用于任务设计”。它不证明 Codex 内部一定采用某个 cookbook 模式。
- CC 官方手册回答“今天产品向用户承诺什么”。它不反向证明 2.1.88 内部对象仍然相同。
- OpenCode 官方源码/文档只证明固定 release 的公开实现或当前可配置行为;Issue 和 PR 一律只是演进信号。
- CC 2.1.88 是从 npm source map 提取的非官方历史快照;其版本背景可参见 官方仓库记录。所有 CC 代码段都只解释历史实现。
#源码链怎样证明一个 Harness 模块
一段孤立代码通常只能说明“存在一个字段或函数”,不能说明一个模块真正怎样工作。本文每条源码链都只证明一个最小闭环:
| 链路位置 | 要回答的问题 | 不能越界推断的内容 |
|---|---|---|
| ① 读取/恢复 | 状态、规则或请求从哪里来? | 它不单独证明后续一定执行。 |
| ② 决策/执行 | 什么条件改变路径、预算、权限或委派? | 它不单独证明结果已写回。 |
| ③ 写回/回传 | 哪个对象回到 history、父线程或外部环境? | 它不单独证明被保留的信息无损。 |
因此,代码块中的 A/B/C 是同一机制切片,不是完整调用栈。为避免把跨文件片段伪装成可直接编译的程序,块内省略了无关类型、错误处理和参数,且只保留连接三步所必需的语句;每个片段的真实文件和行号都在紧邻段落中列出。相邻的链路 I/O 会用同一任务输入把三步连起来;图中的 ①/②/③ 节点与它们一一对应。
#1. 流程:一轮任务由谁推进、何时换人
#模块目标
流程模块的输入是用户任务、当前回合状态和可选子任务;输出是一个明确的下一步:继续模型回合、执行工具、委派子会话、重试或结束。它的核心不变量是:复杂探索可以离开主线程,但回到主线程的必须是可用结论,而不是无限增长的原始过程。
#用人话说
这像项目负责人安排工作:能直接答的就答,需要查资料的派人查,查完再决定继续还是收工。流程模块要保证“派人”和“回来汇报”都有边界。
#常用场景
- 修复 checkout 超时前,先并行定位支付入口、测试失败点和最近改动。
- 一条命令失败后,决定缩小查询、改用另一工具,还是终止任务。
- 主线程不应装入陌生仓库侦察产生的全部 grep 命中。
#模块机制图
flowchart TD
S([开始:收到任务与当前回合状态]) --> A["① 读取任务、已有状态与委派参数"]
A --> B{"可由主线程直接完成?"}
B -- 是 --> C["运行模型回合"]
B -- 否 --> D{"需要独立探索?"}
D -- 是 --> E["② 创建子会话,分配 history 与策略"]
E --> F["③ 子会话返回证据、结论、未解项"]
F --> C
D -- 否 --> C
C --> G{"继续、重试还是完成?"}
G -- 继续 --> H["把下一动作交给工具或下一轮"]
H --> I([结束:进入约束与状态读取])
G -- 完成 --> J([结束:交付最终答复])
E -. "风险:子任务带入过多 history 或权限" .-> R["隔离失效"]
读图结论:流程模块不是“多 Agent 功能列表”,而是控制面。子 Agent 只是其中一条分支,必须在返回主线程前压缩成对主任务有用的证据。
#Codex 源码解读
下面不是完整调用栈,而是一条委派最小闭环:先读取调用方给定的 history 语义,再创建受策略约束的 child,最后把 child turn 的结论交还主流程。片段 A 见 codex_delegate.rs,第 63–98 行,片段 B/C 见 第 105–138 行(公开源码备份,2026-03-31 快照)。
// 片段 A:读取。调用者没有指定时,默认是 New history。
let history = initial_history.unwrap_or(InitialHistory::New);
// 片段 B:决策/创建。父级执行策略不是子会话的隐式全权限。
let child = Codex::spawn(CodexSpawnArgs {
conversation_history: history,
inherited_exec_policy: Some(inherited_exec_policy),
config: child_config,
skills_manager,
}).await?;
// 片段 C:写回。主流程消费的是 child turn 的结果,不是 child 内存。
let result = run_child_turn(child, task).await?;
return Ok(result);
| I/O 项 | 链路 I/O:查找支付链路 |
|---|---|
| 输入 | 主线程委派“找出支付入口、签名校验、回调处理文件”,并选用 InitialHistory::New。 |
| 状态变化 | A 把 history 定义为 New 或继承;B 将该选择与父级策略写入 child;C 等待并取得 child 的完成结果。 |
| 输出 | 主流程得到子会话回传的文件路径、调用顺序和未确认分支。 |
| 用户可见结果 | 主线程得到可继续验证的摘要,而不是所有搜索噪声。 |
| 误判风险 | New history 也会丢掉业务限定;任务描述模糊时可能查到错误支付链路。 |
Cookbook 实践旁证(辅助,不证明上述实现):Cookbook 的 Orchestrating Agents: Routines and Handoffs 将“按任务转交给另一 routine”作为工作流设计手法。它支持本文的实践建议:只有当子任务能用清晰产物回传时才委派;但它不说明 Codex 内部如何 spawn 子会话。
#CC 2.1.88 源码解读
CC 2.1.88 的相应闭环由运行入口和 Agent 定义共同构成:入口准备子会话,Explore 定义收窄其角色,运行结果再回到父调用。片段 A/C 见 runAgent.ts,第 85–217 行,片段 B 见 exploreAgent.ts,第 24–56 行(非官方历史快照备份)。
// 片段 A:入口选择 agent definition,并建立 agent session。
const definition = resolveAgent(agentName);
const session = await createAgentSession(definition, input);
// 片段 B:Explore 的可用动作和模型被定义为只读探索。
const exploreAgent = {
tools: ['Glob', 'Grep', 'Read'],
model: 'haiku',
skipClaudeMd: true,
};
// 片段 C:运行器将完成结果格式化后回给 Task 的父调用。
const result = await runAgent(session, definition, prompt);
return formatAgentResult(result);
| I/O 项 | 链路 I/O:查找支付链路 |
|---|---|
| 输入 | 主 Agent 把同一条支付链路侦察任务交给 Explore。 |
| 状态变化 | A 为 agent 创建执行状态;B 决定其工具面和模型;C 把运行结果转为父工具调用可消费的产物。 |
| 输出 | 返回文件定位、可能调用链和下一步验证建议。 |
| 用户可见结果 | 主会话不被大量目录、grep 命中和阅读过程淹没。 |
| 误判风险 | 2.1.88 的 skipClaudeMd 会让探索更轻,却可能漏掉项目专有规则。 |
当前官方手册旁证(辅助):Subagents 文档 说明当前产品支持独立上下文、工具和模型配置;它不能证明当前 Explore 仍使用上述工具或跳过规则。
#实现对比与取舍
| 维度 | Codex | CC 2.1.88 | 直接结论 |
|---|---|---|---|
| 目标达成 | 调用方显式指定 New/继承 history 与执行策略。 | Explore 默认收窄为只读探索,并封装模型路由与提示。 | Codex 保留编排权;CC 2.1.88 缩短仓库侦察的设置路径。 |
| 可观察性 | spawn 参数直接暴露子会话输入和策略。 | Agent 定义可读,但证据仅覆盖历史快照。 | Codex 更适合复现“子 Agent 为什么这样做”;CC 的当前行为要回到官方手册核验。 |
| 默认自动化 | 主 Agent 必须自行决定怎样拆分和回收任务。 | Explore 默认隔离搜索噪声,并禁止写文件。 | Codex 的代价是调度代码更多;CC 的代价是 Explore 可能跳过项目专有上下文。 |
| 成本与风险 | 并发数、history 模式和回传体积都由调用方负责限制。 | 默认角色降低上手成本,但摘要仍可能遗漏关键证据。 | Codex 适合需要精确控制的并行;CC 适合先建立只读证据,再由主线程执行改动。 |
| 适合任务 | 多个独立验证、需继承指定策略的实现任务。 | 陌生仓库侦察、只读依赖追踪。 | 改动关键路径前,Codex 与 CC 都应让主线程复查源码或测试结果。 |
#OpenCode:现状与改进路线
| 已具备的公开能力 | 相对本章目标仍需补强的闭环 | 建议改进方向 |
|---|---|---|
| 官方 Agents 文档 公开了 Task 子 Agent 与工具权限;稳定参考点固定为 v1.15.11 的 d2bd7ea。 | Task 子 Agent 的公开模型更接近“顺序运行、返回后终止”;多 Agent 并行、可选 fork/new history、结构化 join 不是同一条稳定主链的已证实保证。 | 让 Task 显式携带 history mode、返回 schema 与父级策略;先实现可审计的 join,再引入并行和协作消息。有关团队协作的 Issue 只作为演进信号,不是已发布能力。 |
#适用场景
| 明确结论:优先选 Codex | 明确结论:优先选 CC 2.1.88 | 共同警戒 |
|---|---|---|
| 要继承架构决策、审计子会话或控制并发时,选 Codex。 | 只读侦察陌生仓库、隔离搜索噪声时,选 CC 2.1.88。 | 子 Agent 的摘要不是证据;关键路径仍要读源码或跑测试。 |
#2. 约束:哪些规则必须在模型前和执行时都生效
#模块目标
约束模块将系统指令、项目规则、技能、审批、Hook 与权限策略转成可执行边界。输入是仓库和宿主提供的规则、工具请求和风险目标;输出是受约束的 prompt、允许/拒绝/待审批的动作。核心不变量是:模型看见一条规则不等于运行时会执行它,真正的副作用还需在执行点复核。
#用人话说
规则像施工图和门禁:施工图告诉工人不能拆承重墙,门禁则在真要进机房时拦下来。只把规则写进 prompt,相当于只贴了提示牌;只在执行时阻拦,又会让模型白做规划。
#常用场景
- 项目规定只能改 src/payment,不能改数据库 schema。
- 访问 api.example.com:443 前必须让用户单次确认。
- 团队用 Hook 阻止未经测试的提交或生产写操作。
#模块机制图
flowchart TD
S([开始:任务与候选动作进入]) --> A["① 读取系统、项目、技能与策略规则"]
A --> B["把稳定约束提供给上下文装配"]
B --> C{"模型请求是否触及受控动作?"}
C -- 否 --> D["保留约束快照"]
C -- 是 --> E["② 运行时按审批和权限策略复核"]
E -- 允许 --> D
E -- 拒绝或待确认 --> F["③ 写回拒绝或审批请求"]
D --> G([结束:进入状态读取或工具调用])
F --> G
E -. "风险:只靠 prompt、策略粒度过宽" .-> R["约束绕过"]
读图结论:约束有两次落点:进入 prompt 时影响计划,进入执行器时阻止副作用。本文把前者放在“上下文”的输入中,把后者留在“运行环境”的真实边界。
#Codex 源码解读
Codex 的约束闭环需要同时看“规则怎样进入 session”和“动作怎样在执行点被复核”。片段 A 是 compact.rs,第 191–223 行 中稳定上下文重建;片段 B/C 是 network_approval.rs,第 77–127 行 的审批与结果分支(公开源码备份)。
// 片段 A:读取。稳定规则来自 session,而不是只靠模型记住。
let initial_context = sess.build_initial_context(turn_context.as_ref()).await;
// 片段 B:决策。审批对象由目标主机、协议和端口共同组成。
let key = HostApprovalKey { host, protocol, port };
let decision = approval_policy.check(&key);
// 片段 C:写回或执行。AskUser 产生事件,不等同于放行。
match decision {
Allow => execute_request(),
AskUser => request_network_approval(key),
Deny => deny_request(),
}
| I/O 项 | 链路 I/O:首次访问 api.example.com:443 |
|---|---|
| 输入 | 模型要求请求 https://api.example.com:443/v1/status,策略中尚无预授权。 |
| 状态变化 | A 恢复稳定约束;B 把请求解析成审批键;C 将策略结果落实为执行、拒绝或待审批事件。 |
| 输出 | 请求执行、返回拒绝,或生成等待用户确认的 approval。 |
| 用户可见结果 | 用户可针对具体目标确认,而不是笼统地“允许联网”。 |
| 误判风险 | 重定向、子域名和不同端口不自动继承这一次授权。 |
Cookbook 实践旁证(辅助):OpenAI Cookbook 目录 中的工具与 agent recipe 可用于设计 guardrail 与人工确认工作流;截至本文查阅,没有一篇直接描述 Codex 的 host/protocol/port 审批键,因此不以 cookbook 取代源码。
#CC 2.1.88 源码解读
CC 2.1.88 的机制链由 context 规则来源、MCP 包装的权限调用与 client 调用分支共同组成。片段 A 见 context.ts,第 152–188 行,片段 B/C 见 MCPTool.ts,第 27–75 行(非官方历史快照备份)。
// 片段 A:读取。项目规则和记忆先聚合为执行上下文。
const context = await buildContext({ messages, claudeMd, memory });
// 片段 B:决策。MCP 包装把工具名和参数送进外层权限链。
const permission = await context.canUseTool(this.name, input);
// 片段 C:写回或执行。拒绝被透传,允许后才调用服务。
if (!permission.allowed) return permission.result;
return this.client.callTool(this.serverName, this.toolName, input);
| I/O 项 | 链路 I/O:首次访问 api.example.com:443 |
|---|---|
| 输入 | MCP 工具参数含 api.example.com 目标。 |
| 状态变化 | A 聚合可用规则来源;B 调用通用权限链;C 把拒绝回传或将获准请求交给 client。 |
| 输出 | 允许时执行;否则把拒绝或待确认结果回传。 |
| 用户可见结果 | 权限交互由上层策略统一呈现,而不是由每个 MCP 工具自行决定。 |
| 误判风险 | 此片段不能证明 CC 2.1.88 采用 host/port 粒度;它只证明存在先判定后调用的边界。 |
当前官方手册旁证(辅助):Permissions 与 Hooks 说明当前用户可配置的权限和生命周期约束;不要把它们的当前配置名外推回 2.1.88。
#实现对比与取舍
| 维度 | Codex | CC 2.1.88 | 直接结论 |
|---|---|---|---|
| 目标达成 | 审批键直接包含 host、协议和端口。 | MCP 工具将请求交给统一的外层权限链。 | Codex 便于按网络目标最小授权;CC 便于复用团队已有的 MCP 策略。 |
| 可观察性 | 审计记录可直接对应到目标 host、协议和端口。 | 可看到是否经过 canUseTool,细粒度由外层策略决定。 | Codex 更容易回答“放行了哪个地址”;CC 必须继续检查外层规则是否足够细。 |
| 默认自动化 | 拒绝、询问、允许由显式策略分支决定。 | MCP 工具复用同一套权限判断。 | Codex 每个目标都可单独确认;CC 减少重复判断,但共享策略会同时影响所有匹配工具。 |
| 成本与风险 | 细粒度规则带来更多配置与确认。 | 宽泛的外层规则会扩大每个匹配 MCP 的权限。 | Codex 的代价是操作更慢;CC 的风险是一次宽放行覆盖多项能力。 |
| 适合任务 | 生产网络访问、最小授权、需留痕的团队。 | 已有统一 MCP 权限层的工作流。 | 涉及写操作或重定向时,Codex 与 CC 都要按真实目标重新判定权限。 |
#OpenCode:现状与改进路线
| 已具备的公开能力 | 相对本章目标仍需补强的闭环 | 建议改进方向 |
|---|---|---|
| Agents 文档 公开 allow、ask、deny 和基于工具名模式的权限配置。 | 公开配置能说明“允许哪个工具”,但本文选取的 Codex 对照还要求把项目规则、目标级能力和执行审计形成同一条可追踪链。 | 将项目规则编译为可引用的约束快照;将高风险网络/MCP 调用发成含目标、理由和结果的 capability event。不要把工具 wildcard 当作环境级最小授权。 |
#适用场景
| 明确结论:优先选 Codex | 明确结论:优先选 CC 2.1.88 | 共同警戒 |
|---|---|---|
| 要按目标审计网络访问、显式处理审批时,选 Codex。 | 已有统一 MCP 权限与 Hook 体系时,选 CC 2.1.88。 | 规则不能只写进 prompt;拒绝宽通配符和生产默认放行。 |
#3. 持久化:跨回合留下什么,窗口满时改写什么
#模块目标
持久化模块负责从 session 中恢复可继续工作的状态,并在一轮完成后写回新的消息、工具结果、摘要和附件关系。输入是已存 history 与当前回合产物;输出是下一轮能读取的状态。核心不变量是:压缩可以是有损的,但必须保住当前目标、标记边界,并让稳定规则不只寄托于摘要。
#用人话说
这像交接班。下一班不需要重看所有监控录像,但必须知道事故还没结束、已经排除了什么、报告附件在哪里。压缩不是删除历史的借口,而是写一份能继续干活的交接单。
#常用场景
- 120 轮排障后又出现一批测试日志。
- 用户隔天回来继续同一个修复任务。
- 长会话里既有文本、工具输出又有附件。
#模块机制图
flowchart TD
S([开始:① 读取 session history 与附件]) --> A{"窗口是否足够?"}
A -- 足够 --> B["恢复原 history"]
A -- 不足 --> C["选择旧 history、近期目标、附件"]
C --> D["② 生成 compact summary"]
D --> E{"摘要请求是否超窗或失败?"}
E -- 否 --> F["重建 boundary、summary、保留消息与附件"]
E -- 是 --> G["退避:裁短输入后重试"]
G --> C
B --> H["写入本轮新消息与工具结果"]
F --> H
H --> I([结束:③ 保存下一轮可恢复状态])
F -. "风险:早期反例被摘要吞掉" .-> R["状态失真"]
读图结论:持久化不是数据库名词,而是让下一轮能继续做对事的状态迁移。压缩策略的关键在于保留对象、失败退避与边界标记。
#Codex 源码解读
Codex 的持久化闭环由 history 快照、超窗退避和 replacement history 重建组成。片段 A/C 见 compact.rs,第 191–223 行,片段 B 见 第 154–230 行与 324–389 行(公开源码备份)。
// 片段 A:读取。先取得本轮可替换的 session history 快照。
let history_snapshot = sess.clone_history().await;
let history_items = history_snapshot.raw_items();
// 片段 B:决策。compact 自身超窗时,按最早项退避再重试。
if turn_input_len > 1 {
history.remove_first_item();
continue;
}
// 片段 C:写回。summary、近期用户目标与重建规则组成新 history。
let new_history = build_compacted_history(Vec::new(), &user_messages, &summary_text);
sess.replace_history(new_history).await;
| I/O 项 | 链路 I/O:120 轮排障后再次超窗 |
|---|---|
| 输入 | history 含 120 轮消息和工具结果;最新请求是“继续验证支付回调是否重复扣款”。 |
| 状态变化 | A 读取当前可替换状态;B 对过长摘要请求删除最早项并重试;C 用摘要和保留对象写回 replacement history。 |
| 输出 | 生成更短 replacement history,或向上层返回最终失败。 |
| 用户可见结果 | 会话通常可继续,当前目标更可能留在新状态中。 |
| 误判风险 | 保住最新目标不等于保住早期日志中的关键反例。 |
Cookbook 实践旁证(辅助):OpenAI Cookbook 目录 收录的长文总结和 agent 状态处理类示例可帮助设计“摘要后仍可验证”的工作流,但没有直接公开 Codex compact 的保留算法;本文的删除顺序与重试结论只来自源码。
#CC 2.1.88 源码解读
CC 2.1.88 的闭环是:检测压缩边界、生成摘要、用 boundary/消息/附件构成新数组。片段 A/C 见 compact.ts,第 325–334 行,片段 B 见 第 596–610 行(非官方历史快照备份)。
// 片段 A:读取。compact 选择保留的消息与附件。
const { messagesToKeep, attachments } = selectPostCompactState(messages);
// 片段 B:决策。旧 history 被折叠为模型生成的 summary。
const summary = await createCompactSummary(messages);
// 片段 C:写回。新的边界、摘要、近期消息和附件按顺序重建。
return [
createCompactBoundaryMessage(),
createSummaryMessage(summary),
...messagesToKeep,
...attachments,
];
| I/O 项 | 链路 I/O:120 轮排障后再次超窗 |
|---|---|
| 输入 | 同一长 history、当前支付回调目标,且有一份仍需引用的报表附件。 |
| 状态变化 | A 选择保留对象;B 将旧对话压为 summary;C 把边界、summary、近因消息和附件重建为新状态。 |
| 输出 | 一个结构化的 post-compact message 列表。 |
| 用户可见结果 | 后续回合能知道状态已压缩,附件也不会只剩一段文字描述。 |
| 误判风险 | 边界标记不等于摘要准确;遗漏的反例仍会消失。 |
当前官方手册旁证(辅助):Context window 确认当前产品会管理上下文窗口;它不能确定今天仍以 2.1.88 的对象顺序重建 history。
#实现对比与取舍
| 维度 | Codex | CC 2.1.88 | 直接结论 |
|---|---|---|---|
| 目标达成 | 用最近用户目标和摘要续接任务,并在超窗时退避重试。 | 用 boundary、summary、保留消息和附件重建 history。 | Codex 优先维持会话连续;CC 2.1.88 显式保留附件与压缩边界。 |
| 可观察性 | 删除最早项和重试路径可在公开源码定位。 | 重建数组结构清楚,但只由历史镜像证明。 | 调试压缩故障时,Codex 的证据更稳定;CC 的当前对象顺序不能据此断言。 |
| 默认自动化 | 重试减少会话被超窗直接打断。 | boundary 将摘要后的 history 切出明确分界。 | Codex 用额外延迟换连续性;CC 用固定边界换可读性。 |
| 成本与风险 | 多轮摘要重试会拉长回合时间。 | 摘要偏差会被写进新的 boundary,随后持续影响推理。 | Codex 要监控重试次数;CC 要把关键事实保存在摘要之外的持久载体。 |
| 适合任务 | 需要查清压缩退避行为的长调试。 | 带附件的长研究或文档会话。 | 证据、堆栈和关键配置不应只存在于 Codex 或 CC 的摘要中。 |
#OpenCode:现状与改进路线
| 已具备的公开能力 | 相对本章目标仍需补强的闭环 | 建议改进方向 |
|---|---|---|
| OpenCode 公开源码备份含 session compaction 服务,官方产品也有 session 概念。 | “压缩后 durable instructions 是否稳定重注入、附件和证据怎样可回放”不能仅从已有公开入口推断。社区关于规则在压缩后丢失的报告只能视为问题信号。 | 让 compact 输出成为带版本的结构化 envelope:保留规则快照、摘要来源范围、附件引用和丢弃清单;再为每次 compact 写入可查询 trace。 |
#适用场景
| 明确结论:优先选 Codex | 明确结论:优先选 CC 2.1.88 | 共同警戒 |
|---|---|---|
| 要追踪压缩退避、删除与重试时,选 Codex。 | 附件必须跨压缩保留、需要显式 boundary 时,选 CC 2.1.88。 | 合规证据、堆栈和关键配置不得只存在于摘要。 |
#4. 上下文:本轮模型究竟带了哪些行李
#模块目标
上下文模块把已生效约束、恢复状态、当前用户任务和此刻必要的工具说明装配成模型请求。输入来自前三章,输出是本轮 prompt。核心不变量是:稳定规则要能重注入,易失 history 要有预算,工具 schema 要按必要程度进入,而不是无差别塞满窗口。
#用人话说
Agent 出门要带工作证、目的地、上次交接单和必要工具。把所有仓库资料和所有工具说明都装进背包会超重;只带摘要又会忘记“不能改 schema”这种硬约束。
#常用场景
- 有目录、测试、审批限制的仓库修复。
- 从已经压缩过的会话继续实现。
- 同时接入许多 MCP、技能和工具,但首轮 token 预算有限。
#模块机制图
flowchart TD
S([开始:① 接收任务、约束与可恢复状态]) --> A["读取稳定规则与当前用户目标"]
A --> B["取回 history、summary、附件引用"]
B --> C{"哪些能力本轮必要?"}
C -- 常驻 --> D["② 加入必要工具 schema 与技能说明"]
C -- 按需 --> E["② 保留 Tool Search 等发现入口"]
D --> F["按预算装配 prompt"]
E --> F
F --> G([结束:③ 向模型发送本轮输入])
F -. "风险:规则漏注入、schema 过大、摘要被当原文" .-> R["上下文失真"]
读图结论:上下文不是历史的原样拼接,而是一个预算内的装配产物。约束、持久化和工具三层在此相遇,但它们的治理逻辑各自独立。
#Codex 源码解读
Codex 的上下文闭环可分成三层:从 history 提取近期目标、从 session 重建稳定约束、把两者插入 replacement history;按需工具发现再避免未使用 schema 长驻。片段 A/B 见 compact.rs,第 191–223 行,片段 C 见 tool_search.rs(公开源码备份)。
// 片段 A:读取。近期用户目标从 history snapshot 提取。
let user_messages = collect_user_messages(history_items);
// 片段 B:决策/装配。稳定规则由当前 session 重建后插入新 history。
let initial_context = sess.build_initial_context(turn_context.as_ref()).await;
new_history = insert_initial_context_before_last_real_user_or_summary(
new_history, initial_context);
// 片段 C:按需能力。Tool Search 只在模型选择发现时返回匹配工具说明。
let discovered = tool_search_handler(query, deferred_tools).await?;
| I/O 项 | 链路 I/O:修复 checkout 超时 |
|---|---|
| 输入 | 旧测试输出已压缩;session 仍有“只能改 src/payment、不得改 schema”的项目约束。 |
| 状态变化 | A 提取近期意图;B 从 session 恢复并插入稳定规则;C 只在需要时发现额外能力。 |
| 输出 | 新 history 同时带近期意图、summary、重注入规则和少量已选工具说明。 |
| 用户可见结果 | 下一轮模型仍能看到不能改 schema,不必完全依赖摘要记住。 |
| 误判风险 | 重注入规则不代表旧日志、旧工具输出或全部项目资料也被恢复。 |
Cookbook 实践旁证(辅助):OpenAI Cookbook 目录 中的 agent、prompt 与工具示例能帮助开发者把稳定指令、状态和工具描述拆层;它不提供 Codex 的 initial_context 组装顺序,因此顺序结论仍仅由源码支持。
#CC 2.1.88 源码解读
CC 2.1.88 的链同样不应只看 Tool Search:先聚合 messages、CLAUDE.md 和 memory,再以 query 选 deferred tools,最后把它们送给本轮模型。片段 A/C 见 context.ts,第 152–188 行,片段 B 见 ToolSearchTool.ts,第 21–45 行(非官方历史快照备份)。
// 片段 A:读取。会话、项目规则和 memory 汇入 context。
const context = await buildContext({ messages, claudeMd, memory });
// 片段 B:决策。deferred tools 由 query 选择,而不是全量注入。
const tools = searchDeferredTools(query);
// 片段 C:写入模型输入。context 与已选 tools 共同构成请求。
return createModelRequest({ context, tools, messages });
| I/O 项 | 链路 I/O:修复 checkout 超时 |
|---|---|
| 输入 | 当前任务、会话消息、CLAUDE.md/memory 与一组 deferred tools。 |
| 状态变化 | A 聚合规则与会话;B 选择匹配工具;C 把两者写为模型请求。 |
| 输出 | 供模型使用的 context 与一小部分被发现的工具能力。 |
| 用户可见结果 | 首轮不必背负所有工具 schema,项目记忆更贴近任务。 |
| 误判风险 | 自动载入的记忆也会占预算;历史实现显示的加载细节不代表当前产品。 |
当前官方手册旁证(辅助):How Claude Code works 说明当前产品如何使用项目指令与上下文;今天具体的自动加载时机仍以官方文档为准。
#实现对比与取舍
| 维度 | Codex | CC 2.1.88 | 直接结论 |
|---|---|---|---|
| 目标达成 | 压缩后显式重注入 session 的稳定上下文。 | 聚合项目记忆、会话和 deferred tool 发现。 | Codex 让长期规则的来源更清楚;CC 2.1.88 用自动聚合降低首次配置量。 |
| 可观察性 | initial_context 的重建与插回可沿源码检查。 | 聚合路径更自动,细节仅由历史快照说明。 | Codex 更适合审计 prompt 构成;CC 的当前加载细节需要查官方手册。 |
| 默认自动化 | 宿主维护需要重注入的上下文清单。 | 项目记忆和按需工具默认贴近当前任务。 | Codex 的代价是规则漏配;CC 的代价是自动记忆和工具说明占用 token 预算。 |
| 成本与风险 | 漏掉稳定规则会让新会话失焦。 | 无关记忆会挤掉当前任务或关键工具结果。 | Codex 应将重注入清单纳入项目配置;CC 应限制自动载入规则的范围和长度。 |
| 适合任务 | 多仓库、强规则、需要审计 prompt 构成。 | 规则和任务记忆较稳定、偏好低摩擦探索。 | Codex 与 CC 都应把硬规则写成短句,并分别记录规则、history 与 schema 的 token 预算。 |
#OpenCode:现状与改进路线
| 已具备的公开能力 | 相对本章目标仍需补强的闭环 | 建议改进方向 |
|---|---|---|
| Agents 文档 公开 agent prompt、工具面和权限配置;Tools 文档 公开内建与 MCP 工具。 | 用户能配置上下文来源,不等于能观察每轮 prompt 中规则、history、schema 各占多少预算或何时被移除。 | 引入 context manifest:每轮列出规则、历史、工具 schema 的 token 账本和来源;将按需 MCP 搜索作为稳定能力,而不是仅依赖演进中的 lazy-MCP PR。 |
#适用场景
| 明确结论:优先选 Codex | 明确结论:优先选 CC 2.1.88 | 共同警戒 |
|---|---|---|
| 强项目约束、需审计 prompt 构成时,选 Codex。 | 偏好项目记忆与按需能力自动贴合任务时,选 CC 2.1.88。 | 不要把“模型看过”误认为规则一定执行。 |
#5. 工具:模型说要做,工具结果怎样安全回流
#模块目标
工具模块把模型的工具调用转成可校验请求,把异构原始输出转成下一轮可读取的 tool result。输入是工具 schema、调用参数与原始结果;输出是规范化、截断状态可见、可写入 history 的结果。核心不变量是:工具发现、调用和结果治理是三件相连但不同的事。
#用人话说
工具像一间器材室。模型先要知道有哪些器材,再借某一件,最后拿回结果。拿回一整车 10,000 行日志会堵住走廊,所以 Harness 要裁剪,还得贴上“已裁剪”的标签。
#常用场景
- CI、构建和宽搜索产生数千行日志。
- MCP 服务返回大 JSON、表格或分页数据。
- 工具很多,希望 schema 不全部常驻 prompt。
#模块机制图
flowchart TD
S([开始:① 模型提出工具调用]) --> A["定位已注册工具或执行 Tool Search"]
A --> B["② 校验工具名、参数与调用协议"]
B --> C["把请求交给运行环境执行"]
C --> D["取得原始 stdout、文件或 MCP 结果"]
D --> E{"超过结果预算?"}
E -- 否 --> F["规范化完整 tool result"]
E -- 是 --> G["截断并保留截断事实"]
F --> H["③ 写回 history"]
G --> H
H --> I([结束:模型获得下一轮证据])
G -. "风险:根因在被裁掉的尾部" .-> R["需二次窄读"]
读图结论:Tool Search 解决“说明何时入窗”,截断解决“结果如何回流”。二者都节省上下文,却不能互相替代。
#Codex 源码解读
Codex 的工具结果闭环至少有三处:先按需发现工具说明,再保留原始执行字节,最后按 token 预算形成写回文本。片段 A 见 tool_search.rs,片段 B/C 见 tools/context.rs,第 284–362 行;PTY 的原始字节上限见 pty/src/lib.rs,第 10 行。
// 片段 A:读取/发现。只返回模型查询命中的 deferred tool 定义。
let tools = tool_search_handler(query, deferred_tools).await?;
// 片段 B:保存执行事实。原始字节与模型回流预算分离。
let output = ExecCommandToolOutput {
raw_output,
max_output_tokens,
original_token_count,
};
// 片段 C:写回。将字节转文本后按 token 预算裁剪为 tool result。
let text = String::from_utf8_lossy(&output.raw_output).to_string();
let visible = formatted_truncate_text(&text, TruncationPolicy::Tokens(max_tokens));
history.push_tool_result(visible);
| I/O 项 | 链路 I/O:10,000 行测试日志 |
|---|---|
| 输入 | raw_output 约 8,000 token,max_output_tokens 为 1,000。 |
| 状态变化 | A 仅选入需要的工具说明;B 保存原始字节与预算;C 截断并把可见结果写回 history。 |
| 输出 | 约 1,000 token 的结果,且可携带原始 token 规模。 |
| 用户可见结果 | 模型应意识到日志不完整,改用 tail、grep 或定点读文件。 |
| 误判风险 | 截断边界不保证保留真正的失败根因。 |
Cookbook 实践旁证(辅助):OpenAI Cookbook 目录 的 function calling、MCP 与 agent tool 示例适合说明“工具要设计成窄输入、窄输出”;没有一篇直接规定 Codex 的 token 截断算法,因此上限与对象字段仍只据源码。
#CC 2.1.88 源码解读
CC 2.1.88 的工具链包括 deferred tool 发现、MCP Tool 的容量定义与结果截断识别,而不是只是一条 maxResultSizeChars 常量。片段 A 见 ToolSearchTool.ts,第 21–45 行,片段 B/C 见 MCPTool.ts,第 27–75 行(非官方历史快照备份)。
// 片段 A:读取/发现。query 选择 deferred tools。
const discovered = searchDeferredTools(query);
// 片段 B:决策。MCP Tool 将结果字符预算声明为协议的一部分。
const mcp = buildTool({ isMcp: true, maxResultSizeChars: 100_000 });
// 片段 C:写回提示。结果被回传前提供截断状态。
const truncated = isOutputLineTruncated(output);
return createToolResult({ output, truncated });
| I/O 项 | 链路 I/O:130,000 字符 MCP 返回 |
|---|---|
| 输入 | 支付状态 MCP 返回 130,000 字符 JSON。 |
| 状态变化 | A 选择所需能力;B 将容量预算附在工具定义;C 形成带截断事实的回流结果。 |
| 输出 | 上限内 tool result 与截断判断信号。 |
| 用户可见结果 | 模型应分页、缩小字段或读取特定资源。 |
| 误判风险 | 字符上限不是业务对象边界,尾部字段仍可能消失。 |
当前官方手册旁证(辅助):Tools reference 与 MCP 描述当前可用工具和 MCP 使用方式;当前结果上限不由 2.1.88 片段推断。
#实现对比与取舍
| 维度 | Codex | CC 2.1.88 | 直接结论 |
|---|---|---|---|
| 目标达成 | shell 输出按 token 裁剪,原始规模可单独保留。 | MCP Tool 声明字符预算并检测截断。 | Codex 以 token 控制模型输入;CC 2.1.88 在 MCP 包装层统一管理结果容量。 |
| 可观察性 | 原始字节、裁剪文本和原始 token 数可分别检查。 | MCP 调用统一经过 Tool 层。 | Codex 更容易定位日志为何被截断;CC 更容易给所有 MCP 套用同一结果协议。 |
| 默认自动化 | 调用侧可设置 max_output_tokens。 | 容量策略写在工具定义中。 | Codex 允许按任务收紧或放宽预算;CC 让每个 MCP 遵守同一默认上限。 |
| 成本与风险 | token 裁剪仍可能丢掉失败位置的关键行。 | 字符裁剪可能截断 JSON,破坏对象完整性。 | Codex 应按文件、测试名或行号二次窄读;CC 应让 MCP 返回分页或字段筛选后的结构化结果。 |
| 适合任务 | CI 排障、构建失败、宽搜索日志。 | 多 SaaS/MCP 集成、结构化资源查询。 | Codex 与 CC 都不应以无限提高结果上限替代缩小查询范围。 |
#OpenCode:现状与改进路线
| 已具备的公开能力 | 相对本章目标仍需补强的闭环 | 建议改进方向 |
|---|---|---|
| Tools 文档 已公开内建工具、MCP 与权限控制。 | “所有工具默认可用”的便利性并不自动提供 token 级结果预算、截断事实、按需 schema 发现与回写 trace。 | 为每个工具引入结果预算、original-size 与 truncation 字段;把 MCP lazy mode 作为可测试的稳定接口。当前 mcp-search PR 只能视为演进信号。 |
#适用场景
| 明确结论:优先选 Codex | 明确结论:优先选 CC 2.1.88 | 共同警戒 |
|---|---|---|
| 高频 CI/测试排障,需控制日志 token 预算时,选 Codex。 | 大量结构化 MCP 查询,需统一包装结果时,选 CC 2.1.88。 | 截断不是完整结果;schema 全量常驻会压垮 prompt。 |
#6. 运行环境:工具真正在哪儿跑,副作用由谁承接
#模块目标
运行环境模块是工具调用真正发生的宿主:PTY、工作目录、文件系统、沙箱、网络通道和 MCP transport 都在这里起作用。输入是已校验、已获准的工具请求;输出是执行结果、错误、审批事件和审计痕迹。核心不变量是:模型和工具协议不能越过宿主边界直接拥有环境副作用。
#用人话说
工具模块像下了一张工单,运行环境才是实际施工现场。命令在哪个目录跑、能访问哪些文件、能不能出网、MCP 请求送到哪里,决定了同一张工单最后会发生什么。
#常用场景
- 在受限工作目录运行测试、构建或迁移预览。
- 访问外部 API、浏览器自动化或企业 MCP 服务。
- 排查“模型已经请求执行,但为什么被沙箱、端口或环境变量拦住”。
#模块机制图
flowchart TD
S([开始:① 收到已校验的工具请求]) --> A["绑定工作目录、沙箱与执行策略"]
A --> B{"请求类型?"}
B -- shell / 文件 --> C["② PTY 或本地执行器"]
B -- 网络 --> D["② 按 host、protocol、port 经过审批"]
B -- MCP --> E["② MCP client / transport 调用服务"]
C --> F["采集退出码、stdout、stderr"]
D --> F
E --> F
F --> G["形成执行事件与原始结果"]
G --> H([结束:③ 交给工具模块规范化和写回])
A -. "风险:cwd、沙箱、重定向、服务端副作用" .-> R["环境漂移或越权"]
读图结论:运行环境不是“工具的另一个名字”。工具层管理调用协议与结果回流;运行环境决定请求能否在真实机器、网络和服务端产生副作用。
#Codex 源码解读
Codex 的运行环境闭环不能只看 PTY 常量:工作请求先携带策略进入执行器,PTY 限制原始输出,网络目标再落到审批事件或真实请求。片段 A 是 network_approval.rs,第 77–127 行,片段 B 是 pty/src/lib.rs,第 10 行,片段 C 回到 tools/context.rs,第 284–362 行(公开源码备份)。
// 片段 A:读取/准入。网络执行先从 target 构造审批键。
let key = HostApprovalKey { host, protocol, port };
let decision = approval_policy.check(&key);
// 片段 B:执行环境。PTY 对单个进程积累的原始输出设硬边界。
pub const DEFAULT_MAX_OUTPUT_BYTES: usize = 1024 * 1024;
let pty = spawn_pty(command, cwd, exec_policy).await?;
// 片段 C:写回。进程事件和原始输出成为工具层的输入。
let raw_output = pty.collect_output().await?;
return ExecCommandToolOutput::from(raw_output);
| I/O 项 | 链路 I/O:在受控仓库运行测试 |
|---|---|
| 输入 | 模型请求在当前工作目录运行测试,命令产生持续 stdout/stderr。 |
| 状态变化 | A 检查网络/执行准入;B 以 cwd、策略和 PTY 启动进程;C 将退出事件和原始输出交给工具层。 |
| 输出 | 进程退出状态与受限原始输出,随后由工具层按 token 再次治理。 |
| 用户可见结果 | 大日志不会无限积累;超出边界时应改为更窄命令。 |
| 误判风险 | 1 MiB 是输出缓存边界,不保证测试本身完成,也不等于模型看到的 token 上限。 |
Cookbook 实践旁证(辅助):OpenAI Cookbook 目录 的 coding、MCP 与工具执行范例强调将外部副作用封装成受控工具调用;没有直接公开 Codex PTY 或其沙箱实现,故本文不把 cookbook 当作环境机制证据。
#CC 2.1.88 源码解读
CC 2.1.88 的外部运行边界同样可拆成三段:请求进入 MCP Tool、外层权限决定是否允许、client 将获准调用送到 server 并把结果返回。片段 A/C 见 MCPTool.ts,第 27–75 行,其调用调度上下文见 runAgent.ts,第 85–217 行(非官方历史快照备份)。
// 片段 A:读取。Agent 调度将模型选择的工具调用送入 MCP Tool。
const request = { serverName: this.serverName, toolName: this.toolName, input };
// 片段 B:准入。环境调用前仍由外层权限决定。
const permission = await context.canUseTool(this.name, input);
if (!permission.allowed) return permission.result;
// 片段 C:执行/写回。client 调用 server,结果交回 Tool 层。
const result = await this.client.callTool(request.serverName, request.toolName, input);
return formatToolResult(result);
| I/O 项 | 链路 I/O:读取企业 MCP 的支付状态 |
|---|---|
| 输入 | 获准的 MCP 工具名、serverName、toolName 和支付查询参数。 |
| 状态变化 | A 形成 transport 请求;B 在 client 调用前拒绝或放行;C 返回服务端结果或 transport 错误给 Tool 层。 |
| 输出 | 服务端结果或 transport 错误,返回 Tool 层继续规范化。 |
| 用户可见结果 | 即使模型会调用工具,服务不可达或服务端拒绝仍会成为可见执行失败。 |
| 误判风险 | 这段包装代码不描述 server 内部权限、网络隔离或副作用;那些仍在外部服务边界。 |
当前官方手册旁证(辅助):MCP 与 Permissions 说明当前 MCP 接入与授权体验;本文不从 2.1.88 推断今天的 transport 实现。
#实现对比与取舍
| 维度 | Codex | CC 2.1.88 | 直接结论 |
|---|---|---|---|
| 目标达成 | PTY 与网络审批将本地执行边界建模为可见对象。 | MCP client 将获准请求交给外部服务。 | Codex 适合控制本机 shell 与网络目标;CC 2.1.88 适合接入已有企业服务。 |
| 可观察性 | 原始输出预算和网络审批键可在公开源码定位。 | 可看到 permission 到 client 的交接,无法从 client 代码看到服务端实际动作。 | Codex 可审计本机执行条件;CC 还必须从 MCP 服务端日志确认是否读取、写入或触发外部操作。 |
| 默认自动化 | 执行器与策略分层,宿主可独立配置。 | MCP 包装统一常规服务调用路径。 | Codex 的配置面更大;CC 降低接入成本,但 MCP 服务端仍需自行实现权限、幂等和回滚。 |
| 成本与风险 | 错误的 cwd、沙箱或网络规则会阻断本地任务。 | 服务端可用性、服务端权限和服务端副作用都成为依赖。 | Codex 失败时先查宿主环境与策略;CC 失败时还要查 MCP 服务健康、授权和实际执行记录。 |
| 适合任务 | 本地仓库、终端排障、需要精确网络审批。 | 企业服务、知识库与 MCP 集成。 | 生产写操作应先限定目标与权限,再保留可回滚的执行记录。 |
#OpenCode:现状与改进路线
| 已具备的公开能力 | 相对本章目标仍需补强的闭环 | 建议改进方向 |
|---|---|---|
| Tools 文档 公开 shell、文件、MCP 等执行面,Agents 文档公开对 bash/MCP 的权限控制。 | 工具权限、cwd、子进程、网络目标、服务端副作用若分散在配置与工具实现中,用户难以得到一条统一执行 trace。 | 将每次执行写成 capability trace:工作目录、策略判定、实际命令/目标、退出码、输出预算、外部服务结果一并记录;再逐步把高风险网络操作收窄到目标级能力。 |
#适用场景
| 明确结论:优先选 Codex | 明确结论:优先选 CC 2.1.88 | 共同警戒 |
|---|---|---|
| 本地 shell、网络目标和输出预算都要审计时,选 Codex。 | 主要依赖企业 MCP 与统一 client 调用时,选 CC 2.1.88。 | 检查 cwd、沙箱、重定向和服务端写副作用;失败别盲目重试。 |
#从地图回到选择:任务形状决定 Harness 策略
六要素的差异只有放回任务链路才有意义:流程决定是否隔离探索;约束决定哪些计划根本不可执行;持久化决定长任务还能记住什么;上下文决定模型当轮能推理什么;工具决定证据怎样回流;运行环境决定副作用最终在哪发生。
| 任务形状 | 更偏向的选择 | 原因 |
|---|---|---|
| 长日志排障,必须解释截断、压缩和重试 | Codex | 工具输出、compact 退避、PTY 和审批均有公开源码落点。 |
| 首次进入大仓库,只需只读摸清模块 | CC 2.1.88 的 Explore 思路 | 默认隔离、只读工具与模型路由降低主会话噪声。 |
| 跨文件改动,子任务必须理解已有架构决策 | Codex | New/继承 history 与执行策略是显式编排参数。 |
| 带附件的长研究任务 | CC 2.1.88 的 post-compact 思路 | boundary、摘要、保留消息与附件分层重建。 |
| 高风险生产网络访问 | Codex | host、protocol、port 给出更具体的审批对象。 |
| 团队主要使用企业 MCP | CC 的 MCP 包装思路 | 统一权限判断后转交 MCP client,便于集中治理。 |
最短的结论仍然是:Codex 把更多 Harness 开关留给宿主,因此更适合强调审计、编排和环境治理的工程团队;CC 2.1.88 把更多常见策略封装成默认 runtime,因此更适合先隔离探索、再回收结论的低摩擦工作流。二者都不能替代对规则、关键证据与外部副作用的人工复核。
#OpenCode 的三阶段改进路线
这里的“改进”只针对本文选取的 Harness 保证,不比较模型质量、生态规模或产品偏好。
| 阶段 | 先补的闭环 | 可验证的完成标准 |
|---|---|---|
| 1. 正确性 | 压缩后重注入 durable rules;把权限从 prompt 提示延伸到运行时决策。 | 每次 compact 都能复查保留/丢弃对象;高风险工具有明确 allow、ask、deny 事件。 |
| 2. 可观察性 | 为 context、工具输出和执行环境写入统一 trace。 | 能回答“本轮哪些规则、history、schema 入窗”“结果是否截断”“命令/服务实际执行了什么”。 |
| 3. 协作性 | 为 Task 增加 history mode、结构化结果与父线程 join,再谨慎引入并行。 | 子任务可独立复现,父线程只接收约定产物,并发不会扩大权限或让结果无序回灌。 |
这条路线的收益不是“功能更多”,而是把现有工具、session、权限和 MCP 连接成可验证闭环;任何尚未合入的 PR 或 Issue 都只能作为候选方向。
#附录 A:六要素证据矩阵
| 要素 | Codex 源码链 | CC 2.1.88 源码链 | OpenCode 固定源码 | Cookbook | CC 手册 | OpenCode 文档 | 证据限制 |
|---|---|---|---|---|---|---|---|
| 流程 | delegate A + B/C | runAgent + Explore | release | 辅助:Orchestrating agents | 辅助:Subagents | 辅助:Agents | OpenCode Issue 只作路线信号。 |
| 约束 | context + approval | context + MCPTool | release | 辅助:Cookbook | 辅助:Permissions | 辅助:Agents | Cookbook 不证明审批键。 |
| 持久化 | compact A/C + B | compact A/C + B | compaction | 辅助:Cookbook | 辅助:Context window | 辅助:Agents | CC 为历史;OpenCode 压缩规则需按 commit 复核。 |
| 上下文 | context A/B + search | context + search | release | 辅助:Cookbook | 辅助:How it works | 辅助:Tools | 文档不等同于 prompt 组装代码。 |
| 工具 | search + result | search + MCP | release | 辅助:Cookbook | 辅助:Tools | 辅助:Tools | lazy MCP PR 不是稳定能力。 |
| 运行环境 | approval + PTY | MCP + run | release | 辅助:Cookbook | 辅助:MCP | 辅助:Tools | 外部服务边界需另行审计。 |
#附录 B:怎样正确使用四层证据
| 想回答的问题 | 应优先引用 | 不应做的推断 |
|---|---|---|
| 某变量、阈值、分支、history 对象如何变化? | 固定 commit 的源码 | 用 Cookbook 或产品文档猜内部实现。 |
| 开发者应如何拆任务、收窄工具输出、设计回传? | Cookbook 与章节场景建议 | 把 cookbook 模式当作 Codex 的运行时承诺。 |
| 今天 Claude Code 对用户提供什么能力? | Claude Code 官方手册 | 用 2.1.88 镜像证明当前默认配置。 |
| 某个历史 CC 内部路径怎样工作? | 2.1.88 镜像,附历史标签 | 把该路径表述为 Anthropic 当前官方实现。 |
- 每段代码只解释紧邻片段直接读取、写入或分支的对象;未展示部分不作确定断言。
- 文中的 I/O 例子是从相邻代码可直接推演的最小案例,不是性能基准或 UI 录屏。
- 若决策依赖当前 Claude Code 行为,先复查官方手册与实际安装版本;若依赖 Codex 实现,使用本文固定 commit,而非未来变化的 main 分支。