上下文即一切:理解 LLM 的认知边界与工程应对之道


一、从根基说起:LLM 的记忆与认知机制

要理解如何高效地使用大语言模型,首先必须理解它的"大脑"是如何工作的——尤其是它与人类认知的结构性差异。

1.1 LLM 的记忆特征

  • Context Window(上下文窗口):有限且为一维序列,是 LLM 唯一的"工作记忆"
    • 可达 200k-1m tokens
    • 窗口内推理效率极高;超出则需压缩,必然伴随信息丢失
  • 参数固定:不能实时学习,唯一获取新知识的途径是把内容塞进 context window
  • 无真正的长期记忆:只能通过 RAG(Retrieval-Augmented Generation)+ Index 检索来动态获取外部信息
  • I/O 特征
    • 输入(prefill):速度较快,可快速载入上下文
    • 输出(next token prediction):每秒几十 token

关键组件说明

  • RAG:外置工具,本质是 LLM 根据关键词检索信息后拼入上下文
  • Index:代码关键词搜索、搜索引擎关键词等
  • External Information Base:代码库、私有信息库、搜索引擎等任意外置信息源

1.2 人类的记忆特征

  • 短期记忆:空间极小(仅约几十 tokens),复杂任务需频繁切换上下文
  • 长期记忆:容量巨大,但检索效率低,依赖联想机制进行随机检索
    • 记忆效率低,但一旦记住就能与旧知识产生关联,形成知识网络
  • 可实时学习:能不断更新长期记忆
  • I/O 特征:眼睛、手、声音等,带宽极低
    • 输入速度:最大 Kb 级 / 分钟
    • 输出速度:仅几十 token / 分钟
  • 联想机制(Imagination):跳跃性强,具有创造力

1.3 核心差异对比

专长对比:

维度LLM 擅长人类擅长
上下文特征长度在窗口范围内、上下文连贯且非跳跃上下文较短但跳跃性强
逻辑复杂度逻辑不过于复杂的任务逻辑高度复杂的任务
典型场景独立 UI 系统编写、独立脚本复杂系统(一个文件依赖多个类,需长期学习掌握整个关系网)

效率对比:

维度LLM人类
短期效率Context Window 内极高,远超人类理解速度永远很慢,理解与输出都慢
衰减特征上下文超出窗口后准确率急剧下降无此问题
长期积累无法跨会话学习擅长长时间思考和输出,可持续数小时编码,经年累月积累后越来越强

核心洞察:LLM 在有限窗口内是"超级大脑",一旦超出窗口则是"半瞎子"。这一根本特征,催生了整个上下文工程学科。


二、什么是上下文工程(Context Engineering)?

2.1 核心定义

所有 LLM 都受到有限上下文窗口的限制。上下文工程就是将这个窗口视为一种稀缺资源,围绕它设计一整套系统(检索、记忆、工具集成、提示等),确保模型只将有限的**注意力预算(Attention Budget)**花在真正有价值的 Token 上。

2.2 与 Prompt Engineering 的区别

维度Prompt EngineeringContext Engineering
关注点提示词文本本身(尤其是 System Prompt 的措辞)模型看到的整个输入上下文系统
范围Prompt 是一个局部子集包含 System 指令、工具输出、外部数据、消息历史、MCP 等全部输入
适用阶段早期单轮分类 / 生成任务Agent 多轮推理、长时程复杂任务

关键洞察: Prompt 只是 Context 的一部分。真正决定模型输出质量的,往往不只是那段 instruction,而是整个上下文的构造过程

2.3 从单轮到 Agent:上下文复杂度的跃迁

  • 单轮请求场景: 输入只有 System Prompt + User Message → 简单的一问一答。
  • Agent 场景: 执行流程是一个循环式工作流(Agent Loop),典型步骤为:
    1. 先查看当前上下文
    2. 决定是否调用工具(Tool Call)
    3. 拿到 Tool Result(Observation)
    4. 把结果放回上下文
    5. 继续下一轮推理

Agent 不是一次性输入输出,而是需要从不断膨胀的上下文中 "捞出"并"整理"出最正确的素材——这就是 Context Engineering 的核心任务。


三、上下文腐烂:为什么 Context Engineering 不可或缺?

3.1 什么是 Context Rot(上下文腐烂)?

即使模型号称拥有百万级甚至千万级的上下文窗口,其对信息的处理并非"一视同仁"。随着上下文变长,模型提取和处理信息的能力会逐渐衰减,这种现象被称为Context Rot(上下文腐烂)

产生机制: 每一轮 Agent 循环(模型调用 → 工具执行)的返回都会不断拼接到 Context 中,尤其是 Tool Result(Observation)往往特别长,不断堆积后很容易超出模型的最大上下文长度。

3.2 Context Rot 导致的四大严重后果

  1. 准确性的"雪崩"(Accuracy Collapse)

    • 模型提取关键事实的能力并非线性下降,而是可能在某个临界点突然跳水
    • 例如:把"A 公司收购了 B"记成"B 公司收购了 A"——记住了关键词,却搞错了逻辑关系
  2. 指令漂移与"性格"崩坏(Instruction Drift)

    • Prompt 开头设定的规则、约束和语气,会随着 Context Rot 加剧而逐步失效
    • 例如:原本要求"严禁输出代码",但对话进行到 50 轮后,模型因抓取不到开头的强约束而开始输出代码
  3. Agent 的"逻辑死循环"(Recursive Failure)

    • Agent 忘记自己已经尝试过某个 API 调用并失败了,反复尝试同一个错误动作,直到耗尽 Token 预算
  4. 调试的"不可预测性"(Non-Deterministic Flakiness)

    • 上下文短时表现完美,变长后开始报错
    • Bug 具有随机性,受干扰项的位置、语义相似度等复杂因素影响,很难通过简单测试找到失效边界

四、Context Engineering 最佳实践

核心目标:在不超出 Token 限制的前提下,将最高价值的信息精准送达模型最敏感的"注意力区域"

4.1 压缩策略(Compression)

本质:在尽量保留**原始语义(Information Integrity)**的前提下,通过算法减少 Token 数量。

方法原理示例
级联摘要(Incremental Summarization)将历史对话分块,用更小、更便宜的模型对每块生成摘要每 10 轮对话压缩成 3-5 句话
Token 级硬裁剪(Selective Context / Pruning)利用小模型计算 Token 概率,删掉"即便删了模型也能猜出来"的低信息量 Token去除冗余虚词和礼貌用语
精炼 Tool Output对工具返回的原始 JSON 等进行裁剪,只保留核心字段{"status":200, "data":{"user":{"id":1,"name":"Alice","bio":"..."}}}Found user: Alice (ID: 1)
语义软压缩使用专门算法(如微软的 LLMLingua)将松散句子重构成极度紧凑的"密文",只有 AI 能读懂人类不可读但语义完整的压缩格式

4.2 子代理架构(Sub-agent Architectures)

核心思想: 与其让一个 Agent 维护整个项目的庞大状态,不如让专门的子代理在各自干净的上下文窗口中处理特定任务。

架构示例(重构整个项目):

主代理(Manager)
├── 子代理 A(Linter):扫描语法错误 → 只返回错误列表
├── 子代理 B(Researcher):读取文档 → 只返回 API 调用规范
└── 子代理 C(Coder):接收 A 和 B 的精炼结论 → 在干净窗口中编写代码

关键收益:

  • 每个子代理可能消耗数万 Token 进行深度探索,但最终只向主代理返回精简摘要(约 1000~2000 Token)
  • 编写代码的 Agent 不会被上千行语法报错日志或冗长库文档干扰注意力

类比: 这类似于游戏引擎 ECS 架构中各 System 独立处理自己的 Component 数据,最终只把必要结果写回共享状态,而不是每个 System 都加载全部数据。

4.3 文件系统作为外部上下文(File System as Context)

问题背景:

  • 即使 Context Window 可达 200k+,Tool Result 可能非常大
  • Agent 多轮交互中需保存大量 reasoning 信息,再长的 Context 也不够用
  • 过度压缩不可避免地导致信息丢失

解决方案: 将文件系统作为外部 Context 来使用:

  • 让 Agent 在 Scratchpad 文件中实时记录:
    • ✅ 当前已完成的任务步骤
    • ✅ 已确认的事实(如:"auth.py 的报错是因为版本不兼容")
    • ✅ 接下来的行动计划
  • 提供一套精准操作文件系统的工具,Agent 后续通过 headtailgrep 等命令渐进式查看,或一次性读取整个文件

优势: 既减少了上下文占用,又保留了完整信息,有效解决长时程任务中的 Context Rot 问题。

4.4 上下文拼接的六条实战法则

法则一:按顺序拼接,对抗"Lost in the Middle"效应

模型对 Prompt 两端的信息敏感度最高,中间部分最容易被忽略。

推荐拼接顺序:

① System / Global Instructions        ← 最重要,放最前
② User Profile / Long-term Memory
③ Relevant Conversation History
④ Current Task / Current Question
⑤ Retrieved Knowledge / Tool Results
⑥ Working Summary / Constraints / Output Format  ← 最重要,放最后

实用技巧: 如果中间数据太长,建议在底部 Query 之前增加一句提示:"请基于上述 <context> 里的信息回答以下问题:"

法则二:Tool Result / 检索文档放在当前问题后面

模型最容易理解的链路是有关联的顺序链

✅ 问题 → 证据 → 回答
❌ 证据A → 旧history → 证据B → memory → question

后者容易让模型搞不清哪些证据是给当前任务用的。

法则三:结构化标记(Structured Tagging)

使用明确的 XML 标签Markdown 标记来隔离不同信息块,显著降低模型对"数据"和"指令"的混淆:

<system_instructions>
  你是一个代码审计专家。请遵循 <security_policy> 进行分析。
</system_instructions>
 
<security_policy>
  1. 严禁泄露 API Key。
  2. 优先检查 SQL 注入漏洞。
</security_policy>
 
<context_data>
  [RAG 检索到的代码片段或文档]
</context_data>
 
<tool_outputs>
  [上一步执行 grep 或 linter 的原始输出]
</tool_outputs>
 
<user_query>
  基于以上背景,分析 src/auth.py 的安全性。
</user_query>

法则四:信息精炼,防止"Context 污染"

在拼接之前,必须对各部分内容进行预处理,提升信号密度(Signal Density)

策略做法
工具结果去噪API 返回 2000 行 JSON → 只抽取核心 data 字段,丢弃 headers、metadata
历史消息"关键帧"化保留最近几轮完整对话,更早的对话只保留 Summary
去重(Deduplication)RAG 检索常召回重复/高度相似片段 → 通过语义对比或哈希值过滤去重

法则五:Token 预算动态分配

为各部分设置权重,防止某一部分过长导致挤掉核心指令:

模块建议权重/策略溢出处理
System Prompt100% 保留(最高优先级)绝不截断
Current Query100% 保留(最高优先级)绝不截断
RAG Context~40% 预算按相似度评分从低到高丢弃
History~30% 预算采用滑动窗口或摘要化
Tool Results~20% 预算只保留最新结果,旧结果仅保留结论

法则六:选择性注入(Selective Injection)

并非所有上下文都需要同时存在于 Context Window 中。

通过 LLM 驱动的路由逻辑,系统根据当前查询的性质和业务领域,动态决定注入哪些知识片段

  • 用户询问财务问题 → 注入财务相关文件与对话历史
  • 话题转向技术问题 → 动态替换为技术文档

类比: 这类似于 GPU 渲染中的视锥体剔除(Frustum Culling)——不在视野内的物体根本不提交给渲染管线,只加载当前帧真正需要的资源。Context Engineering 中的选择性注入同理:只把当前推理步骤真正需要的信息送入上下文窗口。


五、实战透视:LLM 编程的能力边界

理解了上下文工程的原理之后,我们可以更清晰地分析 LLM 在编程这一高频应用场景中的真实表现——它的优势和崩溃点,本质上都是上下文窗口特性的直接映射。

5.1 LLM 编码的基本逻辑

以 Claude 为代表的 AI 编程工具,其基本流程为:

  • 核心环节是搜索——Claude 会花大量时间检索相关代码片段和上下文,积累足够信息后才开始写代码
  • 这与人类程序员的逻辑本质相同:先理解和记忆代码,再着手实现
  • 差异在于速度:LLM 的学习与编码效率可能是人类的 100–1000 倍

5.2 三个根本性缺陷

缺陷一:一维序列 vs 图结构

这是 LLM 编程最根本的结构性限制:

  • LLM 的 context window 本质是一维序列,代码本身也是一维字符序列
  • 单文件场景:代码是完整、逻辑自洽的一维系统,可以完美嵌入 context window → LLM 最擅长的场景

  • 多文件场景:文件间存在依赖关系,系统结构变为图结构(Graph)

  • 这是一个多维结构,要压缩进一维 context window 必然造成信息损失
  • 这就是 Context Engineering 的本质——工程师通过 import 语句、注释或提示帮 LLM "猜测"和"理解"文件间关系

缺陷二:规模效应与崩溃点

随着文件数量和系统复杂度增加:

  1. 信息维度增加 → 压缩损失加剧
  2. 复杂度超过阈值后,LLM 性能趋近**"崩溃"**,几乎无法生成有效代码
  3. 关键洞察:这不是 Context Window 大小的问题,而是 LLM 本身是 "半瞎子"
    • Claude 的 Context Window 已达 200k,足以塞入中等规模项目,但仍无法掌控,说明问题出在理解能力而非容量

缺陷三:对人类工程师的高度依赖

  • 复杂场景下,高水平工程师可以通过需求拆解上下文设计逐步引导 LLM 完成任务
  • 高度依赖工程师自身能力,对代码初学者几乎不可能独立完成
  • 实际经验:Infra 类项目中,超过十个较大文件时 LLM 就往往无法自行掌控,需人类提供先验知识
  • Agents.md 本质就是一种结构化的"先验知识"提供方式
  • 即使借助 Plan Mode 实现自动化的需求拆解,或通过 TDD 建立验证闭环,方法的选择、路径的判断、结果的审核仍然高度依赖工程师的经验与技术直觉——工具可以加速执行,但无法替代决策。

5.3 为什么前端更适合 LLM 编程?

前端特征对 LLM 的友好度
组件通常有唯一 id便于 LLM 精确查找
各组件相对独立、规模小更容易被完整嵌入 context window
语法集合有限、逻辑较简单降低推理复杂度
整体规模庞大但单元简单重复性高,LLM 效率优势明显

→ 前端领域 LLM 往往展现出比人类更强的生产力优势

5.4 社区的两极分化

阵营观点
VibeCode 派所有代码都应由 LLM 生成,手动读代码和 Debug 是低效行为
守旧派LLM 编码水平不足,应用场景窄,不堪大用

分歧根源:使用者的背景、编码水平、使用场景差异巨大,在不同语境下自然得出截然不同的结论。理解了上下文窗口的能力边界,就能理解双方各自"正确"的语境。


六、总结与最佳实践

6.1 Context Engineering 核心思维模型

┌──────────────────────────────┐
│    Context Window (稀缺)      │
└──────────────┬───────────────┘

  ┌─────┬──────┼──────┬──────┬──────┐
  ▼     ▼      ▼      ▼      ▼      ▼
压缩  子代理  文件系统  结构化  动态   预算
策略  架构    扩展    标记    注入   分配

一句话概括: Context Engineering 本质是一套信息物流系统——对上下文进行压缩、路由、隔离、排序、动态分配,让模型有限的注意力预算,始终花在最有价值的 Token 上。

6.2 编码能力 vs 项目规模的核心规律

  • 小项目:LLM 理解和编写效率均高于人类
  • 大项目:代码关系复杂,LLM 能力出现断崖式下跌,开始低于人类
  • LLM 主导的项目,代码质量下跌速度一定高于人类主导的项目
  • 结论:除非是固定的小型项目(如短期脚本),所有有可能变大的项目一定要人类主导编码

6.3 最佳实践:Human-in-the-Loop 模式

LLM 负责的部分:

  • 模板化、重复性高的小规模代码生成(代码框架设计、API 封装、测试样例)
  • 快速原型PoC(Proof of Concept)
  • 语言转换、框架迁移(如 Python → Java、React → Vue)

人类负责的部分:

  • 架构设计与全局把控——需要理解整个系统的图结构
  • 复杂问题的 Debugging 与异常处理——需要跳跃性思维和经验积累
  • 长期维护与知识沉淀——尤其是隐性业务逻辑,需要长期记忆支撑

6.4 对游戏引擎 / 渲染工程师的启示

对于游戏引擎和渲染工程这类典型的大型复杂系统:

  • 引擎代码文件间依赖关系极其复杂(渲染管线、资源管理、ECS 架构等形成高度耦合的图结构),属于 LLM 能力崩溃区域
  • LLM 适合做:单个 Shader 编写、工具脚本、API 封装、测试用例生成、配置文件模板等局部自包含任务
  • 架构设计、渲染管线优化、跨模块 Debugging 等仍需人类工程师深度主导
  • 随着项目生命周期延长,人类积累的隐性知识(如特定硬件的渲染 quirks、历史决策的 trade-off)是 LLM 无法替代的核心价值

Context Engineering:让 Coding Agent 成功率翻倍的 10 个习惯


核心问题:Context Rot(上下文腐烂)

什么是 Context Rot

  • 一个 coding agent 在第 5 分钟和第 35 分钟是 完全不同的东西 ——随着 context window 膨胀,模型性能 持续衰减
  • Chroma Research 测试 18 个大模型的结论: context 越长,性能越差 ,且 从一开始就在下降 ,而非接近上限时才下降
  • "Lost in the Middle" 现象(Liu et al.):相关信息落在 context 中间位置时,模型性能 下降超过 30%

Agent 场景下的放大效应

  • 每次读文件、grep 搜索、走入死胡同,这些信息都 残留在 context window
  • Context 像 内存泄漏 一样膨胀,模型性能随之衰减
  • 实操数据:任务时间翻倍,失败率翻四倍(METR 基准测试)

关键引用

  • Phil Schmid:"大多数 agent 失败 不再是模型失败,而是 context 失败 "
  • CodeScene 研究:在 健康代码 上 agent 成功率 超过 60% ,在 烂代码 上只有 20% ——同一个 agent,同一个 prompt,三倍差距
  • Karpathy 从推广 vibe coding 转向 agentic engineering :自由发挥不可持续, 纪律才能规模化

两大核心原则

  1. 把 context 当内存来管 ——控制 context 大小,防止膨胀
  2. 给 agent 设计好 harness ——用测试、hooks、脚手架系统性压住 context 爆炸

第一部分:把 Context 当内存来管

Context window 就是 agent 的工作内存。 超过 50% 时模型就开始变笨,成本也开始飙升。最好的 GC 是 不需要 GC ——从源头控制,不让 context 膨胀到需要压缩。


技巧 1:新任务新 Session

核心规则

  • 做完一个任务,执行 /clear ,开始下一个
  • 不要在一个 session 里连续做多个不相关的事

不清 session 的两个后果

  1. 浪费钱 :50K token 的 context 里有 30K 是上一任务残留,每次交互都为这 30K 付费
  2. 模型变傻 :无关信息越多,模型对当前任务的 注意力越分散 ,输出质量肉眼可见地下降

进阶策略

  • 两次修正失败就重来 :同一个问题纠正了两次 agent 还搞不对,不要继续纠缠。Context 已被 污染 ——错误尝试、纠正、道歉全变成噪音。/clear 后花 30 秒写更精确的初始 prompt 重新开始。 干净 context 下的第一次尝试 > 污染 context 下的第五次修正
  • 有方向的压缩 :若无法清 session,用 /compact <指令> 做定向压缩,例如 /compact 聚焦 API 变更部分,丢弃调试过程 ,而非无脑 /compact
  • 在 CLAUDE.md 中加压缩规则 :"压缩时必须保留所有已修改文件列表和测试命令"

跨 Session 传递状态:progress.md

  • 每个 session 结束时更新 progress.md :当前进度、关键决策、下一步待办
  • 下个 session 开头读这个文件,3 秒恢复上下文
  • 文件记意图,Git 记事实 :commit message + diff 让新 session 快速理解"做了什么、为什么这么做"
  • 核心理念:Context window 是临时的,文件系统是持久的 ——把状态写进文件,每个 session 都能满血启动

技巧 2:写好 CLAUDE.md

定位

  • CLAUDE.md 是项目级的持久化知识——编码规范、架构约定、工作流程
  • 技巧 1 的 progress.md 是 GPS 定位 ,CLAUDE.md 是 地图
  • 本质是 system prompt ,但其影响力随对话变长而衰减——context 膨胀到 50K token 时,开头那段已被大量 tool output 稀释

该写什么

类别说明示例
项目结构地图 (最高优先级)Agent 最大的时间浪费是"找不到东西",tool output 占 70-80% 上下文src/models/ — 推荐模型,核心是 ranking_model.py
工具选择决策树Agent 默认用 grep 全局搜索,效率极低,需锚定到可观察特征"找配置项,直接看 configs/"
项目特有约定和陷阱Agent 不可能从代码推断的隐式知识"embedding_dim 改了必须同步改 model_config.yaml"
工作流程指令planning/execution 分离"涉及多文件修改:先列改动计划,确认后再执行"
  • Anthropic RL Engineering 团队做法:只写 具体的防错规则 ,如 run pytest not rundon't cd unnecessarily — just use the right path,不写空泛原则

不该写什么

  • 语言/框架通用知识 :Claude 已经知道,写了浪费 token,加速 attention decay
  • 过度详细的 API 文档 :CLAUDE.md 不是 reference manual
  • 空泛原则 :"写高质量代码"对 agent 决策没有任何帮助
  • 历史变更日志 :不是 CHANGELOG,只保留当前有效信息
  • 编码风格偏好 :Agent 对主流风格有很好的默认判断,逐条列偏好是 低 ROI 的 context 开销
  • 重复已有配置 :pyproject.toml 里有的不用再写

渐进式披露:分层加载

  • 顶层 CLAUDE.md 只放入口级信息 :项目结构、核心约定、关键路径
  • 具体工作流、详细 API 用法、领域 playbook 拆到独立文件 ,CLAUDE.md 里用路径指向它们
  • Agent 需要时再读,不需要时 不占 context
  • 把重复指令封装成 slash command :命令只在调用时才加载,不用时 零 context 开销
  • 思路如同好的 API 设计 ——顶层简洁,细节按需展开。CLAUDE.md 是 索引,不是百科全书

组织原则

  • 控制在 200 行以内
  • 高频信息放前面
  • 祈使句 ——"先看 xxx"而不是"建议先看 xxx"
  • 可操作永远优先于可理解

技巧 3:知道你的 Context 里装了什么

核心认识

  • 打开新 session,context window 并不是空的
  • CLAUDE.md、MCP server 定义、已安装插件和 skills、工具 schema—— 在你发第一条指令前就已占据 context 空间
  • /context 命令查看完整的初始 context 构成

有效容量计算

  • Context 有效容量不是名义上的 200K token
  • 超过 50% 性能就开始下降
  • 如果初始化就占了 30%,有效工作空间只剩 20% ——模型变笨的速度比想象中快

实操建议

  • 按需加载,不要预装 :每个 MCP server、插件、skill 都占 context。十几个 MCP server 的工具定义可能 占掉上万 token ,只装当前项目真正需要的
  • 工具越多,干扰越大 :模型每一步都要从所有可用工具中选择,无关工具是 决策噪音 ,增加选错工具概率
  • 定期审计 :项目换了但 MCP server 往往只增不减,定期用 /context 检查并清理

技巧 4:拆分 Task,每个极简

数据支撑

  • METR 基准测试:任务时间翻倍,失败率翻四倍
  • 主因是 context 膨胀——工具输出、错误尝试、中间状态全部堆积
  • 核心思路不是"事后压缩 context",而是 "任务本身就小到不需要压缩"
  • 一个 2-5 分钟 能完成的任务,context 根本来不及膨胀

动态拆分 vs 静态拆分

  • Anthropic 在 Building Effective Agents 中指出:coding 任务"你无法预测需要哪些子任务"
  • 不要 一次性规划 10 个子任务然后线性执行
  • 推荐 :只规划下一步,完成后根据结果决定再下一步
  • 每个子任务的输出是下一个子任务的 输入条件 ——每步都基于最新信息

动态拆分示例

任务:"给项目加用户认证"

  1. Plan mode 探索——读依赖、查文档、评估方案,写到 plan.md
  2. 第一步:集成 OAuth 库 → 发现库的 API 在最新版完全改了
  3. 若是静态 10 步计划,后 8 步全废;动态拆分下,基于实际 API 重新规划

判断粒度标准

  • 一个任务能不能用 一两句话 说清目标和验证条件?
  • 如果需要"然后……然后……然后……"才能描述,它太大了,

自动化拆分工具

  • Superpowers :开源 Claude Code skills 框架,自动把大任务拆成 2-5 分钟的 feature task,再派 sub-agent 独立执行

技巧 5:Sub-agent 做 Context 隔离

机制原理

  • 主 agent 把子任务派给 sub-agent ,sub-agent 在 独立的 context window 里执行
  • 几万 token 的探索最终压缩为 1000-2000 token 的结构化总结 返回给主 agent
  • 主 agent 的 context 始终干净
  • 任务边界天然就是 context 边界

Claude Code 内置三种 Sub-agent

类型模型权限用途
ExploreHaiku(轻量)只读搜索代码库、定位文件、理解结构
Plan继承主模型只读分析问题、制定方案
General-purpose全部工具可读可写执行复杂的多步骤任务

最佳实践

  • 读多写少 → Explore / Plan ;需要改代码 → General-purpose
  • 一个 sub-agent 一个明确目标 ,不超过 3-4 个
  • Sub-agent 不是越多越好——每个都有调度开销,拆太碎反而浪费

内置命令示例

  • /simplify :自动派 sub-agent 审查刚改过的代码,检查复用机会、代码质量和效率问题,在独立 context 里修复
  • 批量执行计划时:每个子任务一个独立 agent,做完返回摘要

进阶用法:写者-审阅者分离

  • 一个 agent 写代码 ,完成后派独立 sub-agent 做 review
  • 审阅者 context 里只有待审代码和项目规范—— 没有 实现过程中的试错和设计权衡
  • 天然没有确认偏差 :写者和审阅者物理上不共享 context

技巧 6:用 Plan Mode 想清楚再动手

机制

  • Claude Code 内置 Plan Mode :快捷键 Shift+Tab 切换
  • 开启后 agent 只思考、不执行 ——搜代码、读文档、分析依赖,但不写任何文件

为什么需要

  • Agent 默认"边想边做"——读到一半就开始改代码,改到一半发现方向不对,回滚再试
  • 每次试错都往 context 里塞 几千 token 的工具输出
  • Plan Mode 把 "想"和"做"分开 :先充分探索,形成完整方案,再一次性执行

使用流程

  1. 进入 Plan Mode ,描述目标(如"调研 OAuth 认证方案")。Agent 搜索、读依赖、评估选项,但 不改文件
  2. 审查计划 ,确认后切回执行模式(再次 Shift+Tab),按计划动手
  3. 复杂任务 :让 agent 把计划写到 plan.md/clear → 新 session 读 plan.md 执行。执行者的 context 里 只有计划本身 ,没有探索过程的残留

核心价值

  • Plan Mode 是 "先量后裁" :确保 agent 在动手前已 完整理解问题 ,大幅减少执行阶段的试错和回滚

第二部分:给 Agent 设计 Harness

不是手动管 context,而是用 harness (测试、hooks、代码质量、脚手架)来 系统性 地压住 context 爆炸。


技巧 7:Red/Green TDD

没有测试的 Agent 工作流问题

  • Agent 写完代码 → 问你"对吗?" → 你说"不对" → 它改 → 再问 → 三轮下来 context 塞满几千 token 的来回对话
  • 这些对话本质只传递一个信号:对,或不对
  • 测试把这个信号压缩到极致:一个 pass/fail 只占几个 token ,却比自然语言描述更精准、更无歧义

Red-Green TDD 三步流程

步骤操作目的
Red先写会失败的测试定义"成功长什么样"
Green让 agent 实现,直到测试变绿Agent 有明确目标函数——不是"写好代码",而是"让这 5 个测试通过"
验证确认测试从红变绿若一开始就绿,说明测试本身有问题

对 Agent 特别重要的两个原因(Simon Willison)

  1. 防止 写出不能用的代码 :pass/fail 直接验证
  2. 防止 写出没人用的代码 :测试定义了需要什么,防止多写

Tweag 工作流

  • 先写测试 → 审测试 → 让 agent 去实现
  • 测试是 需求的可执行版本 ——agent 不需要反复问"是不是这个意思",跑一下就知道

测试的指数级价值

  • 项目越大,每次新改动越可能破坏已有功能
  • 测试套件是 唯一可靠的防线
  • 没有测试的 agent 项目 → 越做越脆弱 ;有测试的 → 越做越稳固

与 Context 管理的关系

  • 没有测试 → 验证靠人肉对话 → context 膨胀
  • 有测试 → 验证自动完成 → 对话短 → context 精简
  • TDD 不只是代码质量工具,它是 agent 最高效的自我验证机制 ——用最少的 token 传递最准确的反馈

技巧 8:用 Hooks 做程序化反馈

与 TDD 的分工

  • TDD 验证 行为正确性 ——"功能对不对"
  • Hooks 验证 机械正确性 ——"格式对不对、类型对不对"
  • 两者都把人肉对话传递的信号压缩成 自动化的几个 token

Hook 机制

  • Claude Code 的 hooks 允许在 agent 关键动作( 写文件、跑命令、提交代码 )前后自动执行脚本
  • 最典型用法: PostToolUse hook 在每次文件编辑后自动跑 lint 和 typecheck
  • 错误信息以 结构化 JSON 直接返回给 agent → agent 当场修复
  • 零人肉对话,context 几乎不膨胀

实操建议汇总

场景Hook 类型做什么
最小起步PostToolUse(Write/Edit)eslintmypy,返回错误
压缩善后检测 compact 事件自动注入"当前任务状态 + 已修改文件列表"(配合 progress.md)
Pre-commit 拦截Pre-commitgit commit 前自动跑测试,失败就阻断
拦截危险命令PreToolUse模式匹配 rm -rfgit push --forceDROP TABLE,检测到直接阻断
拦截卡死命令PreToolUse检测交互式命令、等待输入的进程,直接拦截

真实事故警示

  • 已有开发者因 agent 执行 rm -rf 丢失整个 home 目录
  • Replit 的 AI agent 曾在 code freeze 期间 删掉了生产数据库

核心思路

不要靠 agent 的记忆力,靠环境的确定性。 Hook 是确定性的,每次都执行,不会因为 context 膨胀而被"忘掉"。


技巧 9:代码健康度直接决定 Agent 成功率

核心数据

  • 健康代码 :agent 成功率 60%
  • 烂代码 :agent 成功率 20%
  • 同一个 agent,同一个 prompt,三倍差距

背后原因

  • 烂代码 = 更多 隐式依赖 、更长的函数、更模糊的接口
  • Agent 需要读 更多文件 才能理解上下文,走更多弯路
  • Context 膨胀 → 模型变笨 → 失败率上升

重新定义技术债

  • 过去:技术债影响"开发者体验"——软性论述,容易被业务优先级压下去
  • 现在:技术债 直接影响 AI 工具的 ROI —— 可量化的硬指标
  • 代码健康度从 7 掉到 5,agent 成功率可能从 50% 掉到 20%
  • CodeScene 研究:AI coding 不加约束时 缺陷风险反而上升 30% 以上 ——agent 倾向于 "搬移复杂度" 而非真正简化

怎么做

  1. 识别 Brain Method :几百行的上帝函数(高圈复杂度、深嵌套、高耦合)→ 开专门 session 让 agent 拆成小的内聚单元,每拆一个跑一次测试
  2. 每次 PR 前跑代码健康度检查 :CodeScene MCP Server 或 lint 规则控制函数长度和复杂度 → 让"健康度下降"变成 自动化拦截信号
  3. 重构和功能开发分开做 :不要在一个 session 里边加功能边重构。重构是独立任务——清 session、单独做、跑测试确认、提交

给 AI 一个干净的代码库,比给它更好的 prompt 更重要。


技巧 10:沉淀框架和脚手架,复用而非重复生成

常见浪费

  • 每次让 agent 做类似的事,它都 从头生成一套方案
  • 生成本身消耗 context,结果质量不稳定,还得验证
  • 同样的工作流跑过三次,为什么不把验证过的版本 固化 下来?

核心逻辑

把重复生成变成直接调用。 Agent 调用现成脚本,context 用量可能只有从头生成的 1/10 ,输出质量更稳定——因为工具本身已被验证过。

实操方式

方式说明
封装验证过的用法in-house 组件库或复杂部署命令,每次让 agent 用都要试错几轮消耗几千 token → 封装成可复用脚本/函数
把"怎么做"固化成工具部署、发布、数据迁移等重复工作流 → 变成能跑的脚本,不需要多完美,能跑就比每次重新生成靠谱
Skills/Commands 系统Claude Code 的 skills/commands → 把工作流固化为可复用命令,agent 直接执行

CLAUDE.md 与脚手架的关系

  • CLAUDE.md 告诉 agent"用什么工具、遵守什么规则"—— 说明书
  • 脚手架 是 agent 实际可以调用的工具—— 工具箱

OpenAI Codex 团队的核心洞察

瓶颈从来不是 agent 写代码的能力,而是缺乏围绕它的结构、工具和反馈机制。

  • 3 个工程师零手写代码,用 agent 产出 100 万行代码 、约 1500 个 PR,耗时约正常的 1/10
  • 核心经验不是 prompt 写得好,而是:"When Codex got stuck, they treated it as an environment design problem."
  • 给 agent 造好环境,比给它写好 prompt 重要得多

总结:从写代码到设计环境

10 个习惯速查表

#习惯类别核心效果
1新任务新 Session手动内存管理防止 context 污染
2写好 CLAUDE.md持久化知识项目级别的高效引导
3审计初始 Context了解内存现状精简初始占用
4拆分极简 Task控制任务粒度任务小到不需要压缩
5Sub-agent 隔离自动 context 隔离探索万 token → 返回千 token
6Plan Mode想做分离减少执行阶段试错
7Red/Green TDD行为验证pass/fail 替代人肉对话
8Hooks 程序化反馈机械验证lint/type 错误零对话修复
9代码健康度被动基础设施干净代码 = 高成功率
10沉淀脚手架主动造工具直接调用替代重复生成

一句话总结

你的工作不再是写代码,而是设计一个让 agent 能高效工作的环境。 管好 context(当内存管),造好 harness(测试 + hooks + 干净代码 + 脚手架)——这些都不复杂,简单的习惯做了,就已经是降维打击。