Context Engineering 实战 01Context Engineering ≠ Prompt Engineering 2.0到底在工程什么AIReview 系统的 Code Review Agent 上线一个月效果一般。eval 通过率 62%——能抓住明显 bug但对业务逻辑问题基本无感。团队开始优化 prompt。第一周改措辞。把请检查代码质量改成按以下维度逐项检查正确性、安全性、性能、可维护性。加了 few-shot 示例展示好的 review 长什么样。从 800 token 到 2400 token通过率 62% → 71%。第二周继续加内容。团队的 review 规则库有 200 条规则——安全类 38 条、性能类 27 条、风格类 45 条、业务逻辑类 52 条、其他 38 条。“反正 context window 放得下全塞进去让模型参考”。Prompt 从 2400 涨到 6200 token。通过率跌到 55%。加了 200 条正确的规则比不加还差。优化手段 prompt 大小 eval 通过率 ────────────── ────────── ────────── 初版 800 tokens 62% 措辞优化一周 2400 tokens 71% 全量规则注入两周 6200 tokens 55% ← 更多规则反而更差200 条规则都是对的——每条都是团队从真实 code review 里沉淀出来的。全塞进去为什么效果还退步了排查问题不在写了什么在模型看到了什么做了一件事手动检查 AI 输出的 review 意见逐条比对它实际遵循了哪些规则。200 条规则注入后AI 的行为分布 规则遵循情况 数量 占比 ────────── ──── ──── 正确遵循且跟当前代码相关 23条 12% 正确遵循但跟当前代码无关 31条 16% ← 看到规则就乱套 完全忽略 146条 73%73% 的规则被完全忽略。16% 被强行套用到不相关的代码上。只有 12% 被正确使用。“强行套用是什么意思比如一条规则是数据库查询必须有超时设置”——AI 把它套用到一个纯前端组件的 review 上硬说这里应该加超时设置。还有一条并发操作需要加锁——AI 在一个同步的配置解析函数里也建议加锁。AI 不是不懂规则——它在 6000 token 的规则海洋里失去了判断力。该看的没看到不该用的却用了。当时团队有人说了一句话“它不像是没读懂 prompt更像是什么都看了但什么都没看仔细。”这句话是突破口。对照实验同一个 prompt不同的 context 组装为了验证问题在 context 组装而不是 prompt 措辞做了一个对照实验。两组用完全相同的 system prompt 措辞、角色定义、输出格式要求。唯一区别是规则注入方式A 组静态全量注入200 条规则全部写进 context每次 review 都看到同样的 200 条B 组动态选择注入先分析当前 diff 的文件类型和变更内容从 200 条中选 10-15 条相关规则注入100 条测试用例结果指标 A组全量注入 B组动态选择 差异 ────── ───────── ───────── ──── 规则遵循率 45% 83% 84% 误报率套用不相关规则 22% 4% -82% context token 消耗 6000 500 -92% eval 综合通过率 55% 86% 56%Prompt 一个字没改。只改了模型看到哪些规则通过率 55% → 86%。更值得注意的是误报率22% → 4%。全量注入时那些硬套规则的行为几乎消失了——因为模型只看到了跟当前代码相关的规则没有多余的规则可以乱套。这就是 Prompt Engineering 和 Context Engineering 的分界线。Prompt Engineering 在优化你怎么说Context Engineering 在优化模型看到什么。前者是语言问题后者是信息工程问题。为什么 200 条不如 15 条注意力的零和博弈Transformer 的 attention 不是无限的——它是零和博弈。每个 token 生成时模型要对 context 里的所有 token 做注意力分配。Softmax 归一化后总和是 1。context 越长每条信息分到的注意力越少。200 条规则6000 tokens 每条规则的平均注意力 ≈ 1/200 0.5% 15 条规则500 tokens 每条规则的平均注意力 ≈ 1/15 6.7% 差距13 倍而且实际的注意力分布不是均匀的——是 U 形的。开头和结尾的信息拿到更多注意力中间大段信息落入注意力凹陷区。注意力权重 ↑ │ █ █ │ █ █ █ █ │ █ █ █ █ █ █ │ █ █ █ █ █ █ █ █ │ █ █ █ █ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ █ █ █ █ │ █ █ █ █ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ █ █ █ █ ├─────────────────────────────────────────── context 开头 中段 结尾200 条规则全量注入时大部分规则挤在中间——注意力凹陷区。模型看到了这些规则但没有给它们足够的注意力权重来真正遵循。这解释了之前发现的 73% 忽略率不是 prompt 没写清要遵守规则是这些规则在 context 里的物理位置决定了它们拿不到足够的注意力。这也是为什么误报率会上升——中间凹陷区的规则被部分激活模型隐约记得有这么条规则但不清楚具体适用条件就粗暴地套用了。三轮优化实录理解了注意力机制后优化方向从改措辞变成了改 context 的组装方式。三天做了三轮。第一轮按文件类型粗筛200 → 60 条deffilter_by_file_type(rules,file_path):extPath(file_path).suffix tag_map{.py:[python,general],.ts:[typescript,general],.sql:[sql,database,general],}tagstag_map.get(ext,[general])return[rforrinrulesifr.categoryintags]review 一个.py文件时TypeScript 规则、SQL 规则自动排除。200 条 → 60 条。结果55% → 68%。有提升但 60 条还是太多。第二轮按变更内容语义匹配60 → 15 条defsemantic_rank(rules,diff_text,top_k15):diff_embembed(diff_text)scored[]forruleinrules:simcosine_similarity(diff_emb,rule.embedding)scored.append((rule,sim))scored.sort(keylambdax:x[1],reverseTrue)return[rforr,_inscored[:top_k]]对 diff 内容做 embedding跟每条规则的 embedding 算相似度选 top-15。结果68% → 82%。跃升 14 个点——这一轮贡献最大。第三轮利用 U 形曲线排列规则位置高优先级规则放 context 开头注意力高区次优先级放结尾第二高区普通规则放中间。defarrange_by_attention(rules):by_prioritysorted(rules,keylambdar:r.priority,reverseTrue)highby_priority[:5]# 最重要 → 开头lowby_priority[5:10]# 次重要 → 结尾mediumby_priority[10:]# 一般 → 中间returnhighmediumlow# 注意力 U 形分布结果82% → 86%。提升幅度小了但这 4 个点纯粹来自规则的物理排列一行 prompt 都没改。优化轮次 动作 通过率 token 消耗 ──────── ────────── ────── ───────── 基线 全量注入 200 条 55% 6000 第一轮 按文件类型筛选到 60 条 68% 1800 第二轮 语义匹配选 15 条 82% 500 第三轮 U 形排列 86% 500三轮下来token 消耗 6000 → 500-92%通过率 55% → 86%56%。Prompt 措辞一字未改。模型看到的全部信息比你以为的大优化 context 时大部分人只盯着自己写的 system prompt。但模型的 context window 里远不止这些。一次 AIReview 的 review 请求实际的 context 构成组成部分 token 占用 你的控制程度 ──────── ───────── ────────── System Prompt 2400 完全控制 Review 规则动态注入 500 完全控制 待 review 的 diff 3000-15000 部分控制可截取关键段 工具定义8 个工具 900 容易忽视 ← 对话历史 2000-8000 需要主动管理 ────────────────────────────────────────────── 总计 8800-26800两个容易被忽视的开销工具定义占 900 token。AIReview 有 8 个工具search_code、read_file、run_test 等每个工具的 description parameter schema 大约 100-150 token。这 900 token 是隐性固定开销每次请求都在你的规则和 diff 要跟它们竞争注意力。对话历史是会膨胀的。如果不是第一轮 review——比如模型已经检查了 3 个文件——之前的对话可能积累了 5000-8000 token。你花力气把规则从 6000 压到 500但对话历史悄悄加回来 5000总体 context 又膨胀了注意力又被稀释。这就是 Context Engineering 的范畴你要管理的不是自己写的那一段 prompt 文本而是模型每次推理时实际看到的全部信息。System prompt、动态注入的规则、检索到的外部知识、工具定义、对话历史——五个来源任何一块膨胀都会稀释其他部分的注意力。什么时候 Prompt Engineering 就够了不是所有场景都需要 Context Engineering。判断方法很简单如果你的系统只有一种输入模式一个固定 prompt 能覆盖所有情况——Prompt Engineering 够用。翻译、单次分类、简单文本处理——这些任务输入类型单一、不需要外部知识、不需要多轮对话、不用工具。一个写好的 prompt 就是最终答案。一旦你的系统有以下任何一个特征就进入了 Context Engineering 的领域特征 为什么 PE 不够 ───────── ────────── 输入类型多样3 种 不同输入需要不同的规则和示例 需要外部知识RAG / 规则库 检索质量直接决定输出质量 多轮对话5 轮 对话历史的膨胀和遗忘需要主动管理 工具数量 3 工具 description 吃 token选择准确率受描述质量影响 输出要求随场景变化 需要动态切换约束和格式AIReview 全中——多种文件类型、200 条规则库、多轮 review 循环、8 个工具。在这种系统上继续打磨 prompt 措辞就是在局部最优解上死磕。PE 和 CE 的一个直觉区分如果你做的事情只需要打开一个文本文件就能完成——那是 Prompt Engineering。如果你需要写代码来决定模型看到什么——写检索逻辑、写过滤规则、写排序算法、写组装 pipeline——那就是 Context Engineering。PE 的工程量在编辑器里CE 的工程量在代码里。AIReview 这个案例的具体对比Prompt Engineering 的工作量 打开 system_prompt.txt 把检查代码改成逐行检查以下维度... 加 2 个 few-shot 示例 跑 eval 看效果 → 一周通过率 9%62% → 71% Context Engineering 的工作量 写规则的 embedding 索引embed_rules.py 写按文件类型过滤的逻辑filter.py 写语义匹配的排序逻辑ranker.py 写 context 组装 pipelineassembler.py 跑 eval 看效果 → 三天通过率 31%55% → 86%一周 9% vs 三天 31%。不是 PE 没用——是在 AIReview 这类系统上信息选择的杠杆远大于措辞优化。Prompt 是你写的文本Context 是模型做决策时看到的一切——后者才是工程的对象。别再优化措辞了去优化信息供给。