上下文工程实战:让 Agent 不跑偏的 6 个手法

很多人的直觉是:模型上下文窗口越大,Agent 就越强。

副标题:窗口开到 100 万 token 也救不了你。真正决定 Agent 好不好用的,是你在每个时刻往窗口里放了什么东西。

原创声明:本文为 vergex.cn 原创一手实战记录,代码与配置均本地实跑验证。

标签:上下文工程 / Context Engineering / Agent / Claude Code / 提示词 / 大模型工程化


一、先打破一个误解

很多人的直觉是:模型上下文窗口越大,Agent 就越强。

这个直觉是错的,而且错得很贵。

SWE-bench 的维护者在实测中发现了一个硬事实:模型在上下文达到约 100 万 token 时会撞上性能天花板,超过这个点,即使技术上的窗口还装得下,模型准确使用其中任意一条信息的能力也会明显下降。

为什么会这样?因为 Transformer 的注意力机制里,每个 token 都要和其他所有 token 建立关系,关系数是平方级的。塞进去 500 个文件不会让模型更懂你的项目,只会让它在噪音里更难找到该找的那行。

所以更长的窗口不是解决方案,只是给了你更多绳索。

还有一组更扎心的成本数据:

  • Agent 类交互的 token 消耗约为聊天的 4 倍,多 Agent 系统约 15 倍
  • Agent 负载的输入输出比常达 100:1 甚至更差 —— 这意味着 Agent 的成本瓶颈是输入,不是输出
  • 有团队报告 Claude Code 在同等任务下比 Cursor 少用 5.5 倍 token,差距几乎全部来自上下文管理

换句话说:上下文工程做不好,你付的是双份钱——效果差 + 账单高。

Martin Fowler 有一句话把这事说透了:"上下文现在是编码 Agent 的瓶颈。"

那问题来了:既然窗口不能靠堆大,那到底该怎么管?


二、核心心法:上下文是预算,不是仓库

整个领域可以收敛成一句话(也是目前流传最广的一句表述):

目标是在能达成目标的前提下,用最小的、高信号的 token 集合。

不是最多的 token,是对的 token。

把上下文当成"注意力预算"来理解,很多决策立刻就清楚了:

  • 每个 token 都在花你的注意力预算
  • 塞进去的每一条无关信息,都在稀释模型对真正关键信息的感知
  • 无相关的上下文不是"没用",是"有害" —— 它会主动拉高幻觉率

那具体怎么做?四个动作。


三、四个动作

动作一:Write —— 把要活下去的写到窗口外面

窗口会满,但有些东西不能被挤掉:关键决策、待解决的疑问、踩过的坑。

做法是给 Agent 一个能写和能读的地方:

  • 笔记文件(NOTES.md / SCRATCHPAD.md)
  • 记忆工具(Anthropic 的 memory tool,让 Claude 能跨会话存取信息到记忆目录)
  • 规则文件(CLAUDE.md / AGENTS.md,见下文)

检验标准很硬:Agent 崩了、重启了、拿着一个全新的空窗口,它能不能读自己的笔记接着干?

做不到,说明你的 Write 只是往窗口里又塞了一堆字。

⚠️ 一个必须知道的坑:Anthropic 的文档里明确写了,持久化上下文有风险——"恶意路径输入可能尝试访问 /memories 目录之外的文件,你的实现必须校验所有路径"。别以为模型自己会守住边界。

动作二:Select —— 只取这一步真正要用的

这是最容易被做错的动作。常见错误是预先把一切都塞进去:


❌ 开局就把整个代码库、全部文档、所有历史塞进窗口
✅ 只放轻量级引用(文件路径、查询 ID、链接),需要时再拉

这个转变的关键叫 just-in-time retrieval(按需检索) —— 从"推理前检索"(把所有东西 embedding 好,top-k 塞进 prompt)转向"智能体式搜索":模型拿着轻量标识自己导航,按需加载。

元数据在这里干实活:一个文件的名字、位置、时间戳,是在告诉模型"要不要点开它"。

这就像人用文件系统而不是把整本语料库背下来。

动作三:Compress —— 清掉不再挣回位置的内容

上下文快满时怎么办?不是无脑截断,是有策略地压缩。

按安全性从高到低排:

| 手段 | 做法 | 安全性 | 适合 |

|---|---|---|---|

| 工具结果清理 | 把旧的工具输出换成简短摘要或直接删 | ★★★ 最高 | 首选 |

| 滑动窗口 + 锚点 | 保留系统提示 + 最近 N 轮,中间压缩;关键决策类的"锚点"始终保留 | ★★ | 稳定期 |

| 对话整体压缩 | 总结历史 + 用摘要重启 | ★ | 接近满时 |

| 增量摘要 | 每 K 轮更新一次运行摘要,避免一次性压太长 | ★★ | 长任务 |

工具结果清理为什么最安全? 因为四十轮之前调用的工具,原始输出几乎不会再被重新引用。这是最不容易丢信息的压缩方式。

如果你的上下文只放得下 32K 模型,实用配置是:用量到 75%(约 24K)就触发压缩 —— 压缩成结构化摘要(目标/进展/阻塞/关键发现),用「摘要 + 系统提示 + 最近 3 轮」重启,把完整状态写进 MEMORY.md 留档。这样 32K 的模型能处理原本需要 200K+ 历史的任务。

⚠️ 压缩最大的陷阱是"越压越空"。 有研究(ACE)专门警告:警惕任何"靠把上下文变短来省事"的过程 —— 压缩是为了丢历史,不是为了丢你精心积累的知识。这两者的区别,是压缩会不会帮倒忙的分界线。

动作四:Isolate —— 隔开,别让一个窗口扛所有事

这是对抗上下文失控的"核选项":与其一个 Agent 硬撑,不如拆成多个各自干净的窗口。

主流模式:

  • 子 Agent 委派:协调 Agent 把任务派给专职子 Agent,每个子 Agent 有自己干净的窗口。它用掉几万 token 干活,只回传一两千 token 的结论,完整上下文直接丢弃。
  • 扇出/扇入:调研任务并行开多个 Agent 各自查一个方面,再由协调者综合。Cognition 的 Devin 就是这么处理复杂编码的。
  • 工具级隔离:返回超大输出的工具(网页搜索、大规模代码分析)在隔离的推理里跑,只把压缩后的结果回给主 Agent。
  • 上下文隔离区:可能有冲突的外部数据,先在隔离调用里评估、消解,再把干净的结论交给主上下文。

实证效果:Anthropic 的多 Agent 研究系统就是这么做的 —— 子 Agent 用隔离窗口运作、回传约一两千 token 的摘要,该系统在内部研究评测中比单 Agent 基线高 90.2%。

更实用的对照:三个各带 8K 精准上下文的 14B Agent,表现会超过一个泡在 100K token 里找不到北的 70B 模型。注意力质量 > 参数量,在这件事上体现得非常直接。


四、落地:最容易见效的三个改动

理论说完,直接给能抄的。

改动一:写好规则文件,而不是每次重复交代

CLAUDE.md(或 AGENTS.md)是投入产出比最高的一个动作 —— 社区已经把它当基础设施而不是可选配置。

它支持三级分层,自动合并,越具体的优先级越高:

| 层级 | 位置 | 作用范围 |

|---|---|---|

| 项目级 | 根目录 CLAUDE.md | 整个项目 |

| 模块级 | 子目录 CLAUDE.md | 只影响该模块 |

| 用户级 | ~/.claude/CLAUDE.md | 个人偏好,全局生效 |

关键原则:简洁优于完整。 它每次会话都会加载,每一行都必须是放之四海皆准的。只对某个模块生效的内容,写到那个模块的子目录文件里去。

一个可用的模板:


# 项目
Next.js 15, TypeScript, Tailwind, Drizzle ORM

# 架构
- 默认用 Server Components
- 变更操作用 Server Actions,放在 actions.ts
- API 路由在 /api 下
- 所有数据库操作走 Drizzle ORM

# 命令
bun run dev        # 开发服务器(端口 3002)
bun run build      # 生产构建
bun run typecheck  # 类型检查(提交前必跑)

# 约定
- 用 bun,不用 npm
- 优先编辑已有文件,不要新建
- 使用绝对导入(@/lib、@/components)
- 不要提交 .env

# 关键路径
src/app/api/            # API 路由
src/lib/db/schema.ts    # 数据库 schema(唯一真源)

# 坑
- 开发服务器是 3002 端口,不是 3000
- Stripe webhook 需要 STRIPE_WEBHOOK_SECRET
- PostHog 走 /ingest/* 代理,不要直连

写规则文件时最容易犯的错:让 LLM 去干 linter 的活。 代码风格规范属于纯噪音——用 linter 和 formatter,然后把「跑 bun run lint」这一句写进规则文件。几乎无关的上下文会拉低表现。

另外:只记录"坑" —— 那些 Agent 自己发现不了的事(非标准端口、环境变量格式、部署怪癖、API 限流)。能从代码里自己读出来的,不要写。

改动二:加忽略文件,别让噪音进窗口

大多数人的 Agent 都在默默读着几 MB 的无关文件。

.claudeignore 的模式和 .gitignore 一样,但作用于 AI 上下文:


# 构建产物
dist/
.next/
build/
out/

# 依赖(永远不需要读)
node_modules/
.pnp.*

# 生成的代码
*.generated.ts
prisma/generated/

# 大二进制文件
*.woff2
*.png
*.jpg

这个文件通常几分钟就能写完,回报却是立竿见影的。

改动三:工具定义做减法

每一条工具定义都占 token,并且都会分散注意力。

  • 工具数量膨胀是首要失败模式
  • 如果人类工程师都说不清两个工具里该用哪个,Agent 也不可能判断对
  • 目标:5–8 个精炼工具,功能不重叠

五、成本:这是最容易被忽略的一节

我们用真实算一遍。

假设一个客服分诊 Agent:系统提示 + 工具 schema 共 6000 token,8 个步骤,每步新增约 1500 token 的工具结果和推理,每步输出约 300 token。

输入成本怎么算? 每一轮都要重发累计的上下文:

| 项 | 计算 | 结果 |

|---|---|---|

| 单轮输入 | 6000 + 1500 × 已走步数 | 递增 |

| 整轮总输入 | 6000 + 1500×(0+1+2+...+7) | 约 90,000 token |

| 总输出 | 300 × 8 | 2,400 token |

按当时的前沿价位(输入 $3 / 百万,输出 $15 / 百万):

  • 输入:约 $0.27
  • 输出:约 $0.04
  • 单任务合计约 $0.31

对比一下:同样系统提示做单次分类调用约 $0.02。

同一个"名义上的活",Agent 花了约 14 倍。 而这个差距全部来自上下文被反复重发。

再算优化:把稳定的系统提示做缓存(缓存读取价通常是基础输入的 1/10),同样的运行降到约 $0.18,省约 42%。每月 10 万任务量级,这一个改动值约 13,000 美元。

还有一条常被忽略的纪律:

只认「每个成功任务的成本」,不认「每次调用的成本」。

分诊 Agent 成功率 70%、失败重试一次,真实的单成功任务成本会显著高于单次运行数字 —— 失败的运行在失败前已经把 token 预算烧光了。


六、反模式清单

直接对照检查:

  • ❌ 把整个文件塞进上下文 —— 只取你真正需要的那几行
  • ❌ 没有任何压缩策略 —— 跑超过 10 轮的 Agent 一定需要压缩
  • ❌ 工具定义臃肿 —— 精简到 5–8 个
  • ❌ 把压缩当成丢知识 —— 压历史,不是压你积累的结论
  • ❌ 规则文件塞代码风格规范 —— 那是 linter 的活
  • ❌ 规则文件追求完整 —— 追求通用,模块特定内容下沉到子目录
  • ❌ 一个窗口扛所有事 —— 该拆就拆,子 Agent 只回传结论
  • ❌ 拿「每次调用成本」做预算 —— 按成功任务成本算
  • ❌ 以为大窗口能解决问题 —— 100 万 token 处有硬天花板

七、一句话总结

提示词工程是"这句话怎么说",上下文工程是"模型此刻该看见什么"。

前者是一次性的措辞,后者是运行时的持续决策。

提示词工程不会消失 —— 它会变成 token 预算里那 3% 的一部分,而不再是 100% 的手艺。

完整闭环是这样转起来的:

精选(Select)→ 按需检索 → 压缩(Compress)→ 存进记忆(Write)→ 保持窗口精简(Isolate)


📦 完整工程包(仅 vergex.cn)

上面是完整原理,但真正开工你需要能直接抄的配置和脚本。我整理好了:

  • 6 个上下文模板包:规则文件(CLAUDE.md / AGENTS.md)多场景模板、.claudeignore 生产级配置、子 Agent 编排配置
  • 压缩策略实现代码:Python 实现的增量摘要 + 锚点保留 + 32K 小模型的 75% 阈值触发方案,含结构化摘要模板(目标/进展/阻塞/关键发现)
  • 上下文质量检查清单(PDF,一页纸):发送前自查 9 个反模式
  • 上下文腐化现象速查表:不同 token 规模下的典型症状与对应手段对照

获取方式:搜索 VergeX|科技前沿 或访问 vergex.cn,在「上下文工程」栏目下载。


本文为 vergex.cn 原创首发。数据来自 Anthropic 官方工程博客、SWE-bench 维护者实测与公开生产案例,转载请注明出处。

技术深度解析

手把手教你搭一个 MCP Server:30 分钟从零跑通并接入 AI 客户端

2026-10-4 14:33:34

AI 前线

JavaScript 中文周刊 #221 - LibPDF:TypeScript 里的 PDF 解析与生成

2026-1-31 19:08:43

0 条回复 A文章作者 M管理员
VergeX|科技前沿
    暂无讨论,说说你的看法吧
❯
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索