# 0. 阅读说明与源码边界
# 0.1 源码位置
- Claude Code:
claude-code-complete-original仓库;后文路径均相对该仓库根目录。 - Codex:
codex仓库;后文路径均相对该仓库根目录。 - 岗位要求:
Agent岗位HC梳理-技术要求分级.md。
Claude Code 目录是从发布包与 source map 还原的代码快照,部分重复的 src/cli/src/... 文件只是类型占位;本文优先引用包含实际实现的根 src/...。Codex 是 Rust 多 crate 工程,核心循环主要位于 codex-rs/core,长期记忆、沙箱、技能和追踪分别拆到独立 crate。
# 0.2 面试回答的证据等级
- 源码事实:能在本地源码中直接定位到结构、状态或控制流。
- 架构推导:源码没有同名类,但可以从多个模块的协作关系得出,例如“SuperAgent 路由”。
- 工程设计:岗位要求存在,但开源快照没有完整产品实现,需要给出合理设计,而不能冒充源码事实。
# 0.3 岗位优先级
| 优先级 | 知识维度 | 岗位侧原因 |
|---|---|---|
| P0 | Harness、Runtime、Agent Loop、Tool Use、Context、Memory、可观测、权限、沙箱 | 多数 Harness/架构岗位直接要求,决定系统能否生产化 |
| P0 | MCP、Multi-Agent、Session/状态持久化 | 多个岗位要求协议接入、子 Agent 编排、长任务恢复 |
| P1 | Skill、Planning、长期/短期记忆、上下文压缩与窗口 | 决定能力扩展、长程任务成功率与成本 |
| P1 | Agent 交互体验、Prompt/Context Engineering | 前端、全栈、AI Native 岗位重点 |
# 0.4 源码阅读方法:从文件名定位到可验证调用链
阅读两套源码时不要从类名猜架构,而应固定追踪五个问题:入口是谁、状态归谁、外部副作用在哪里发生、事实在哪里持久化、失败后从哪里恢复。
- Claude Code:先从
query.ts/QueryEngine.ts找模型循环,再沿 ToolUse 进入toolOrchestration.ts → toolExecution.ts → 具体 Tool;状态侧沿sessionStorage.ts/conversationRecovery.ts,安全侧沿permissions/* → sandbox-adapter.ts,最后用 UI/Telemetry 文件确认用户可见投影。源码快照中存在src/cli/src/...等类型占位,必须优先打开含真实函数体的根src/...。 - Codex:从
core/src/tasks/regular.rs进入session/turn.rs,再沿run_sampling_request → ToolRouter/Handler → sandboxing;Conversation Item 与协议 Event 分别追到state.history/Rollout和事件通道。跨 crate 类型要继续追到protocol/skills/sandboxing/otel,不能只看调用端 trait。 - 验证顺序:先确认数据结构,再确认创建点和消费点,最后确认异常/取消分支。只有定义没有调用可能是 Stub;只有 Feature 名没有启用路径不能视为默认能力。
- 引用原则:面试中优先引用“稳定职责 + 调用链”,行号只用于现场核查。源码版本变化后行号会漂移,但
Session → Turn → Step → ToolCall等领域关系和安全不变量更稳定。
建议为每个结论保留一条最短证据链,例如:模型产生 ToolUse → Schema 校验 → Hook → 权限 → 沙箱 → ToolResult → Rollout。如果无法把结论落到至少两个相邻环节,就应降级为架构推导而不是源码事实。
源码阅读最终要还原的不是“有哪些文件”,而是三个互相约束的模型:领域模型解释 Session、Turn、Step、ToolCall 等对象分别拥有哪段状态;控制模型解释正常、重试、取消、压缩和恢复怎样迁移;信任模型解释模型、外部工具、Hook、MCP、子 Agent 与 OS 各自能提出什么、又由谁强制执行。后续每章都按这三个模型展开,因此同一段源码可能同时出现在 Runtime、Session 和可观测章节,但解释角度不同。
# 0.5 术语使用约定
本文优先使用容易理解的中文。确实属于工程领域的固定术语,在第一次出现时说明含义:
- 终态(terminal state):状态机中不会再回到运行阶段的最终状态,例如完成、失败或取消。
- Turn 与 Step:Turn 是围绕一次用户目标展开的完整执行过程;Step 是其中一次“构建上下文并调用模型”的步骤。一个 Turn 通常包含多个 Step。
- 快照(snapshot):某一时刻固定下来的状态副本,用来保证一次判断和执行看到相同数据。
- 投影(projection):根据事件记录计算出的查询或展示视图;它可以重新生成,不是原始记录。
- 幂等(idempotency):同一个请求重复执行,不会产生额外副作用。
- 原子操作(atomic operation):一组更新要么全部成功,要么完全不生效,其他线程或恢复过程看不到只完成一半的中间状态。
- 检查点(checkpoint):保存到持久化存储中的恢复位置;重启后可从这里继续,而不必从头执行。
- 背压(backpressure):生产事件的一方过快时,由队列上限、暂停读取或丢弃低价值进度等方式保护消费方。
- 熔断(circuit breaker):外部服务连续失败时暂时停止调用,等待恢复后再试,避免故障持续拖慢整个 Agent Loop。
- 执行产物(Artifact):计划文件、代码补丁、完整日志、图片等需要独立保存,并通过 ID 或路径引用的结果。
- 来源记录(provenance):记录一条信息来自哪个会话、工具或文件,以及经过了哪些提取、摘要或合并步骤。
- 事件游标(event cursor)与递增事件序号(ordinal):前者表示客户端已收到哪个位置,后者表示事件在会话中的稳定顺序,两者共同支持断线续传。
- 检查与执行之间发生变化的问题(TOCTOU):系统完成权限检查后,真正执行前,路径、工作目录或目标对象发生变化,导致实际动作不再是刚才批准的动作。
- Rollout / Transcript:按发生顺序保存的会话与执行记录,用于恢复、回放和审计;本文在解释原理时统称“原始事件记录”。
- 租约(lease)与防过期令牌(fencing token):租约限制 Worker 的执行时间;防过期令牌用于拒绝租约已经失效的旧 Worker 提交结果。
- 控制面与执行面:控制面决定允许做什么,执行面负责真正执行并强制限制。
本文不使用含义不清的自造简称。凡是可以直接说明动作或状态的地方,统一写成“创建 Turn 并先持久化”“持久化事件记录”“连接版本”“不破坏调用配对的切分位置”和“缩小到最小权限范围”等直白表达。
# 0.6 先看全局:用一条 Agent Loop 主线理解全书
第一次阅读不需要立刻记住所有模块。先抓住一条主线:用户提出目标,Runtime 为本次 Step 构建 Context,模型决定回答或调用工具;工具经过权限与沙箱执行,结果先持久化,再进入下一次 Step;直到系统验证任务完成,Turn 才能结束。 Memory、Skill、MCP、Planning、Multi-Agent、安全和可观测都服务于这条主线。
这张图先建立五个关键认识:
- Harness 是外壳:它把 Runtime、Context、工具、安全、状态和观测组合成可运行系统。
- Agent Loop 是主链:一次 Turn 可以包含多次 Step;每次工具结果都可能触发下一次模型采样。
- 模型只有提议权:模型不能直接操作文件、网络或进程,副作用必须经过权限和沙箱。
- Context 是本轮输入,不是全部 Memory:Context Builder 从历史、Skill、Memory 和环境中选择有限内容发送给模型。
- 恢复依赖持久化事件:ToolCall、ToolResult、审批和计划版本必须有稳定 ID,进程重启后才能判断从哪里继续。
# 0.6.1 一次 Turn 的精简流程
上下文压缩通常发生在“准备下一次模型采样”之前:当前历史可能尚未超限,但加上新的用户输入、工具结果、环境变化和工具 Schema 后,预计输入将接近窗口上限。第 9、10 章解释具体触发条件,第 25.5 节给出完整流程图。
# 0.6.2 建议学习顺序
| 学习阶段 | 建议章节 | 需要回答的问题 |
|---|---|---|
| 先掌握主链 | 1 → 2 → 4 → 14 → 17 | Harness 如何围绕 Session、Turn、Step 和 ToolCall 运行? |
| 再理解模型看到什么 | 11 → 12 → 10 → 9 → 5 → 7 → 8 → 15 | Prompt、Context、窗口、压缩、Skill 和 Memory 如何协作? |
| 再理解复杂任务 | 16 → 3 → 6 | 计划如何变成任务,子 Agent 如何协作,MCP 如何提供外部工具? |
| 再补生产边界 | 19 → 20 → 13 → 18 | 权限和沙箱如何限制副作用,用户如何观察和控制,系统如何定位问题? |
| 最后做系统设计 | 23 → 24 → 25 | 如何把正常流程、异常恢复、安全和质量闭环串成完整架构? |
| 按需查证与备考 | 21、22 | 到哪里找源码证据,哪些知识需要优先掌握? |
推荐采用“两遍地图法”:开始学习时只看本节的精简地图,知道每章处于 Agent Loop 的哪个位置;学完专题后再回到第 25 章,用全景架构图、端到端时序图、状态恢复图、Context–Memory 图、安全执行图和 Multi-Agent 图检查知识是否真正连通。
# 0.6.3 核心对象如何组织
理解 Agent 系统最容易混淆的地方,是把 Session、Turn、Step、Task 和 Agent 都当成“任务”。它们实际处于不同维度:前三者描述一次会话怎样执行,Task 描述工作怎样拆分,Agent 描述由谁执行。
需要记住四条边界:
- Session 包含多个 Turn,Turn 包含多个 Step;工具结果通常结束一个 Step,但不一定结束 Turn。
- ToolCall 属于某个 Step;Approval 和 ToolResult 必须通过同一个
call_id与它关联。 - Plan 与 Task 不等于模型历史;它们是可持久化、可验证的结构化工作状态。
- Agent 是执行者,不是 Task 本身;任务可以更换负责人,Agent 退出也不代表任务已经完成。
# 0.6.4 六层架构与各层职责
这不是严格的网络分层,而是职责分层。判断模块放在哪一层时,可问:它是在接收用户意图、控制流程、执行动作、提供能力、保存证据,还是强制资源边界?例如 Approval 属于控制层,Sandbox 属于基础设施强制边界;二者都与安全有关,但不能互相替代。
# 0.6.5 什么情况会进入特殊流程
面对异常时,先判断事实状态,再选择动作:是否已经产生副作用、结果能否确认、操作是否幂等、策略是否允许重试、旧 Context 是否仍有效。不能只根据错误字符串决定“重试还是停止”。第 25 章会把这些判断展开成完整决策树。