AI编程会遇到过这种情况 开局聊得挺好结果越聊越不对劲——它开始忘记你十分钟前说过的约束引用一个根本不存在的文件或者把一个早就解决掉的 bug 又修了一遍。你以为是模型变笨了。其实大多数时候不是模型笨而是喂给它的上下文出了问题。Karpathy 说过一句话Agent 不缺记忆缺的是知道自己有记忆。这句话背后是整个 AI 工程范式的切换从 Prompt Engineering提示词工程1.0走向Context Engineering上下文工程2.0。这篇文章是系统研究 Claude Code 后的一次完整复盘。聊一聊什么是上下文工程、为什么它比提示词重要 10 倍、以及 5 个可以直接抄作业的上下文管理机制。01 | 提示词工程解决听懂上下文工程解决做对先厘清一个最常见的误解。Prompt Engineering 关心的是模型能不能听懂我于是大家研究角色扮演、思维链、Few-shot……一句话把话说漂亮。Context Engineering 关心的是模型手里有没有正确的材料模型再聪明如果它打开的是错误的文件、读到的是过期的需求、记住的是无关的历史输出必然是错的。就像你让一个顶级厨师做菜但冰箱里只有过期食材——厨艺再好也白搭。一个 Agent 的上下文其实由五部分构成短期上下文对话历史、当前问题、工具返回结果长期记忆全局 CLAUDE.md、自动记忆项目记忆项目里的 CLAUDE.md、规则目录、Skills外部上下文MCP 工具调用、Hook 注入状态持久化子代理报告、流水线中间结果注意核心命题来了上下文不是越多越好而是越准越好。塞太多 → 模型注意力被稀释关键信息淹没在噪声里。塞太少 → 模型无从推理只能靠猜。上下文工程的全部艺术就是在这两个极端之间走钢丝。02 | 一行代码通过率 80%上下文工程的神奇瞬间先讲一个让我印象极深的实验来自 Karpathy 的 Autoresearch 项目。一个自主 Agent连续执行多轮研究任务。前面十几个版本团队不断优化工具、优化流程效果始终差一口气。第 19 个版本突破来了。改动有多大一行代码。# v19 突破仅一行代码ctxfTask #{n1}. Memory:{mem_count}tool outputs saved.就是在 prompt 里告诉模型一句话“这是第 N 个任务你已经存了 M 条工具结果在记忆里。”结果通过率 80%总 token 643K基准是 641K——额外开销只有 0.3%。用 0.3% 的成本换来通过率的质变。这一行代码做的事本质上就是上下文工程不是给模型更多信息而是给模型正确的元信息——让它知道自己手里有什么牌。记住这个感觉后面所有机制都是它的延伸。03 | 五个上下文管理机制Claude Code 实战拆解机制一CLAUDE.md 四级记忆层级Claude Code 的记忆不是一个文件而是一套分层的记忆系统按优先级从低到高层级位置存什么用户级~/.claude/CLAUDE.md个人偏好跨项目生效项目级./CLAUDE.md项目 DNA团队共享进 git本地级./CLAUDE.local.md本机特有必须加 .gitignore规则目录./.claude/rules/*.md按主题拆分的细则设计哲学很像操作系统的配置覆盖越具体、越局部优先级越高。反面教材警告千万别把 CLAUDE.md 写成 1000 行的项目百科全书。它每次对话都会占住上下文窗口——你写得越全留给真正对话的空间就越少。记忆文件的目标是最少必要信息不是应有尽有。机制二Skills 渐进式披露这是最优雅的设计。一个 Skill技能包分三层加载frontmatter约 50 tokens——启动时全量加载只包含名字和描述让模型知道它存在SKILL.md 正文约 2K tokens——触发时才加载references/ 参考文件——按需加载用多少读多少像查字典你先翻目录再读词条而不是把整本字典背下来。怎么衡量你的 Skills 设计得好不好三个指标加载率 实际加载 / 总大小理想5–15%命中率 实际引用 / 加载总量理想70–90%维护成本 一次修改要动几个文件理想1–2 个加载率太高说明 frontmatter 写太多命中率太低说明加载了一堆用不上的东西——这两个数一高一低上下文就漏了。机制三SubAgent 上下文隔离子代理启动时主对话的上下文不会被带过去除非你显式传入。子代理拿到的是自己的 system prompt 一段任务描述。然后它自己读文件、自己推理、自己干活最后只回传一段摘要给主对话——不是全部中间过程。这解决了什么主对话的上下文窗口不会被探索过程污染。你让子代理去排查一个 bug它可能读了 20 个文件、跑了 10 条命令、走了 3 条弯路——这些过程对主对话毫无价值有价值的只是结论“bug 在 auth.ts 第 47 行原因是 token 过期没刷新。”隔离的意义不在于保护子代理在于保护主对话。机制四Hook 上下文压缩Hook 是在特定事件点自动触发的脚本两种典型用法PostToolUse 自动格式化工具跑完自动 lint/format避免噪声输出污染后续对话SubAgentStop 验收子代理结束时自动把报告汇总到状态文件形成持久化沉淀一句话让清理上下文这件事自动化不依赖人的自觉。机制五主动压缩与清零长对话中Claude Code 会自动压缩早期内容保留关键决策、文件路径、错误信息丢弃过程性输出你也可以手动干预/compact# 摘要式压缩保留决策和结论丢掉过程/clear# 会话清零只留 CLAUDE.md 和项目记忆原则只有一句话任务有连续性就别 compact发生阶段切换就果断 clear。最常见的翻车场景任务做到一半无脑/compact压缩完 Agent 忘了刚才读过什么一切推倒重来。04 | Token 经济学三个立竿见影的省钱技巧Token 消耗有三大来源模型推理输出、工具调用输入输出、系统提示每次会话固定。我们能压的主要是前两项。三个直接能用的技巧① grep 优于 Read。想确认 30 个文件里有没有某个 pattern一条grep -rn pattern src/搞定。别让 Agent 一个个 Read——30 次工具调用30 份文件全文进上下文账单和注意力一起爆炸。② git diff 优于文件全文。Review 改动时你只关心 diff未改动的部分是纯噪声。③ 批处理优于循环。一个 Bash 调用里跑 5 条命令比发 5 次 Bash 调用便宜 5 倍——因为系统提示只算一次。这个差距在规模化使用时会非常惊人。05 | 进阶视野上下文工程之后是什么上下文工程不是终点。行业前沿已经在探索下一层Anthropic 的 Plan-Execute-VerifyPEV闭环把 Agent 的每一步变成可验证的工程对象Plan as Contract规划不只是步骤分解而是写明文件范围、预期不变量、验证命令、回滚点的契约Sandboxed Execution在隔离的文件系统与权限边界中执行Daytona、E2B、OpenHandsPermissioned State Transition多级权限模型只读 → 沙箱编辑 → 完全访问高风险操作必须人工确认HITLDeterministic Verification用 Linter、测试、静态分析这些确定性手段验证而不是让模型自说自话另一个有意思的方向是工具 Schema 白盒化Hermes 范式——在工具定义里显式声明风险等级exportdefaultdefineTool({name:Read,description:Read a file from the filesystem...,input:z.object({...}),risk:low,// ← 显式告诉 Agent 这个工具的危险等级asyncexecute({file_path}){...}});注意那个risk: low。对比 Claude Code 的隐式风控只能靠 deny 规则硬拦这是把安全信息前置进上下文让 Agent 自主选工具时就能参考。如果说上下文工程是给模型正确的材料那 PEV 和白盒工具就是在回答下一个问题给了材料之后怎么保证它不乱来——这就是 Harness Engineering范式 3.0的地盘了。06 | 四个最常见的坑踩过的人都懂最后盘点一下高频翻车现场上下文堆太多。什么都往对话里塞模型注意力稀释关键信息被淹没。记住越准不是越多。CLAUDE.md 写成百科全书。1000 行的记忆文件占满上下文窗口真正对话的空间被挤光。记忆文件要做减法。压缩时机错误。长任务做到一半/compactAgent 瞬间失忆刚读过的文件全部作废。阶段切换才 clear任务连续别 compact。描述不够详细。Skill 和工具的描述写得太简略Agent 不知道该什么时候触发、去哪找正确的上下文行为开始混乱。描述就是入口入口模糊全盘皆输。写在最后回到开头那个越聊越笨的 AI。现在你知道了模型没有变笨它只是在一个被污染、被稀释、或者干脆错误的上下文里苦苦挣扎。Prompt Engineering 的时代我们学习怎么跟 AI 说话。Context Engineering 的时代我们学习怎么给 AI 搭一个好的工作台。而后者才是 AI 工程真正的分水岭——因为模型能力是大家共享的上下文质量才是你自己的护城河。那一行让通过率飙到 80% 的代码就是最好的注脚给模型正确的上下文而不是更多的上下文。