# Step 45: 整合演示 —— Phase 4 收尾

一句话导读:Phase 4(35-44)装的十项能力,单看每个都平平无奇,串起来才是"Agent 智能内核"。这一步不加新功能,只用一张协作图讲清楚:它们如何串成「喂背景 → 定边界 → 拆解 → 探索 → 实施 → 兜底」的一条流水线。


# 一、这一步做了什么(What)

Phase 4 的收尾复盘。npm start 只打印一张协作图(本步 index.ts 约 50 行,纯展示;真实任务请到 step44 跑——它已是集大成的完整 app)。要讲清的是 35-44 这十项能力:

Step 能力 一句话
35 命令框架 /xxx 注册表 + AppState 收口状态
36 Hooks PreToolUse/PostToolUse 生命周期钩子
37 TodoWrite 把多步任务拆成可勾选清单
38 子代理 fork 一个子 QueryEngine 跑子任务
39 多代理 AgentBatch 并行 fan-out + 汇总
40 记忆 CLAUDE.md 注入系统提示(跨会话约定)
41 技能 渐进式披露:发现 + Skill 按需加载
42 计划模式 只读研究 → ExitPlanMode → 批准再动手
43 上下文工程 环境注入(cwd/平台/目录树) + @文件展开
44 真实压缩 结构化 6 小节摘要 + compact_boundary

# 二、面试官视角:为什么单独用一步来"整合"?(Why)

面试题:这十项功能都已经分别做完了,为什么还要专门花一步讲"它们怎么协作"?各自能跑不就行了?

因为**"每个功能能跑"和"它们能协同完成一个真实任务"是两回事**——后者才是 Agent 的价值所在,而它恰恰是最容易被忽视的部分。

面试里一个高频的判断点是:你是把 Agent 理解成一堆孤立工具的集合,还是理解成一条有编排关系的流水线?前者的心智模型是"给模型一堆函数任它调",后者是"用不同能力覆盖任务生命周期的不同阶段"。

视角 功能清单式理解 流水线式理解
上下文工程(43) "一个注入功能" 任务开始时喂背景,让后续决策有依据
计划模式(42)+Hooks(36) "两个独立开关" 定边界:只读研究阶段用钩子兜底安全
TodoWrite(37) "一个 todo 工具" 管进度:把大任务拆成可追踪的清单
子代理(38/39) "能 fork" 分担探索:把脏活外包,隔离上下文
压缩(44) "省 token" 兜底长度:长任务不至于失忆

一句话:能力是流水线,不是清单。这一步存在的意义,就是把读者的心智模型从"清单"扭到"流水线"。


# 三、原理:它们在一个真实任务里怎么协作(How)

# 任务:给 grep 工具加一个 -i 忽略大小写选项

输入处理   @tools/grep.ts → 文件内容自动附进消息                 (43)
背景就位   系统提示已带 CLAUDE.md 约定(40) + 目录树/平台(43) + 技能清单(41)
进计划模式 /plan → 钩子拦截 Write,AI 只能只读研究               (42+36)
拆解       AI 调 TodoWrite 列步骤①读懂②改schema③改execute④测    (37)
调研       Read/Grep 看代码,或派子代理调研更大范围              (38)
提计划     ExitPlanMode 给方案 → 你 y 批准 → 解除只读            (42)
实施       逐条勾 Todo;Write 改文件(钩子放行)                (37+36)
长对话     聊久了自动压缩成结构化摘要,关键上下文不丢            (44)
1
2
3
4
5
6
7
8

# 这条流水线的阶段结构

① 喂背景   43(环境+@) + 40(记忆) + 41(技能)   —— 让模型有依据,不瞎猜
② 定边界   42(计划模式) + 36(钩子)            —— 研究阶段只读,副作用被拦
③ 拆解     37(TodoWrite)                      —— 大任务变可追踪清单
④ 探索     38/39(子/多代理)                   —— 脏活外包,中间过程隔离
⑤ 实施     37(勾Todo) + 36(钩子放行)          —— 按清单落地,安全兜底
⑥ 兜底     44(压缩)                           —— 长对话不失忆
1
2
3
4
5
6

# 题眼:为什么这一切建立在 step30 抽好的 QueryEngine 上?

子代理(38)、多代理(39)、压缩(44) 全都复用同一个 QueryEngine 类。step30 当年「把对话循环抽成类」看着只是重构,价值在 Phase 4 集中兑现:因为引擎是个干净、可实例化的类,「fork 一个子代理」才是一行 new,「压缩一段历史」才能复用同一套调用逻辑。好的抽象会在后续持续付利息——这是整个 Phase 4 最值得记住的一点。


# 四、深入追问(面试常见 follow-up)

Q:这些能力有没有固定的调用顺序?是硬编码的流水线吗? A:不是硬编码。阶段结构是逻辑上的,实际由模型在 agent loop 里自主决策:它自己决定何时列 Todo、何时派子代理、何时提计划。我们只是把能力都装好、把边界(如计划模式只读)用钩子约束死,"何时用哪个"是模型的运行时决策,不是写死的 if-else 序列。

Q:既然是模型自主决策,那用 DeepSeek 时它每步都会规规矩矩调 TodoWrite / 子代理吗? A:是概率性的。能力都在,但用不用取决于模型。DeepSeek 可能跳过 TodoWrite 直接干、或不派子代理自己硬查;真 Claude 在同一套编排下决策更稳定、更倾向于按最佳实践走。这也说明:Agent 的上限由能力栈决定,实际表现由模型智能决定,两者是乘法关系。

Q:为什么计划模式(42) 偏偏要和 Hooks(36) 搭配,不能自己实现只读? A:能,但用钩子更干净。计划模式的本质是"研究阶段禁止副作用",而 Hooks 正是"在工具执行前拦截"的通用机制。让计划模式复用 PreToolUse 钩子去拦 Write/Edit,比在计划模式里另写一套拦截逻辑更正交——一个通用机制(钩子)承载多个上层特性(计划模式/权限)。

Q:上下文工程(43) 和压缩(44) 都在管上下文,它们冲突吗? A:不冲突,是一进一出的配合。43 负责"往上下文里放对的东西"(背景事实),44 负责"上下文满了怎么优雅地腾地方"(结构化压缩)。一个管注入、一个管淘汰,共同维持上下文窗口这个稀缺资源的健康——正好是流水线的"开头喂"和"结尾兜"两端。


# 五、设计权衡

  • 不加新功能是刻意的:整合步的价值在"讲清关系",塞新功能反而稀释主题。把复盘单独成步,是承认"理解协作"本身就是一项需要专门交付的产出。
  • 真实版没有这一步:真实 Claude Code 把这些能力直接融进同一条 query 主循环,不需要"演示图"。我们拆出来,纯粹是教学需要——先分步做懂每一个,再回头看它们如何合流。

# 六、与真实源码的对照

我们的实现 Claude Code 源码
Phase 4 协作图(展示用 index.ts) 真实版把这些能力融进同一条 query 主循环
上下文 + 计划 + Todo + 子代理 + 钩子 + 压缩 协作 真实版的 agent loop 编排同一套子系统
全部复用 QueryEngine 类 真实版同样一套引擎承载子代理/压缩
概率性调用(DeepSeek) 真实 Claude 在同一编排下决策更稳定

# 七、一句话总结

Phase 4 = 把十项能力串成一条覆盖任务全生命周期的流水线:43/40/41 喂背景、42+36 定边界、37 管进度、38/39 分担探索、44 兜底长度,全部建立在 step30 抽好的 QueryEngine 上——单看每个功能平平无奇,串起来才是"Agent 智能内核",而"何时用哪个"是模型的运行时决策。

# 下一节预告

引擎自身的"智能"已经齐了,Phase 5 开始接外部世界——下一步是 step46 网页工具(WebSearch + WebFetch)。