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