跳到主要内容
进阶

上下文工程

提示工程关乎你选择的词语。上下文工程关乎你交给模型的工作空间——里面有什么、顺序如何、以及你刻意省略了什么。

这个区别很重要,因为上下文窗口不是一张便笺纸。它是一种有限、昂贵、关乎注意力的资源。你如何填充它,会改变模型聚焦于什么、它让你付出多少成本,以及随着会话增长它是否还保持有用。

What you'll learn
  • 分清上下文工程和提示工程——并理解这个领域为何发生了转变
  • 把上下文窗口当作注意力预算,而非储物箱
  • 在上下文腐烂和“迷失在中间”毁掉一场长会话之前发现它们
  • 把指令放在注意力真正落脚的地方——顶部、末尾,绝不埋在中间
  • 运用三大主力战术:压缩、记笔记和即时检索

上下文预算

每个模型都有一个最大上下文大小——一个以 token 衡量的硬性上限。把它想象成一笔预算。你把它花在:

  • 你的系统提示和常驻指令
  • 检索到的文档、代码库片段、工具定义
  • 对话历史
  • 模型的输出(在多轮会话中,它同样要占用窗口)

当你用完时,总得有所取舍。要么旧内容被丢弃,要么会话撞上一堵墙。

大多数入门指南把上下文窗口当作“越多越好”。上下文工程把它当作一种需要谨慎分配的资源:把它花在模型这一轮真正需要的东西上,而不是花在一切可能相关的东西上。Anthropic 把整个学科框定为对“尽可能小的一组高信号 token”的求索——你添加的每一个 token 都在争夺有限的注意力预算,这是 transformer 把每个 token 与其他每个 token 相关联这一机制的直接后果。

上下文腐烂与“迷失在中间”

在长上下文 LLM 中有一个有据可查的现象:模型对靠近上下文开头结尾的内容投入不成比例的注意力,而对埋在中间的内容回忆能力会退化。研究这一效应的学者称之为“迷失在中间”。

实际后果是:如果你往一个 10 万 token 的上下文里塞满文档,并把最关键的指令埋在第 60,000 个位置,模型可能实际上会忽略它——不是因为它读不到那么远,而是因为注意力并非在整个窗口上均匀分布。

“上下文腐烂”是更宽泛的模式:随着会话增长,回应的质量往往会漂移。早期指令被稀释。反复来回挤占了原始任务。模型开始含糊其辞、自我重复,或丢失了你真正所要求之事的线索。

这些不是你靠更好的提示就能彻底修复的 bug。它们是注意力在大规模下运作方式的结构性特性。工程上的应对之道是让上下文保持更小、更锐利,而不是把它填满然后寄希望于运气。

顺序很重要

你把内容放在哪里和你包含什么同样重要。公认的良好实践:

位置该放什么
最顶部(系统提示)稳定、持久的指令。人设、规则、格式要求。
系统提示之后当前任务,用直白的话说清楚。
紧挨着最后一次用户发言之前针对这个确切请求的、最关键、最具体的上下文。
中间支撑文档、检索到的片段——按相关性排序,而非按时间顺序。
对话历史只保留维持连贯性所必需的内容。要积极裁剪。

总的规则是:越靠近当前这一轮,得到的注意力越多。只存在于长历史中段的关键指令是有风险的。

指令的“恰当海拔”

一个系统提示可能以两种相反的方式失败。太低,你就会硬编码出脆弱的、若此即彼的逻辑,一旦现实有所不同就崩溃。太高,你写出的就是含糊的指引,它假定了模型并不具备的上下文。Anthropic 把目标称为**“恰当海拔”**——那个恰到好处的区间,它“足够具体以有效引导行为,又足够灵活以提供强有力的启发式”。瞄准那里:具体的规则和示例,而不是一棵决策树,也不是一种氛围。

检索优于塞满

诱惑在于把一切都放进去:所有文档、整个代码库、整段对话。要抵制它。

更好的做法是选择性检索:识别模型为这个具体请求真正需要什么,并只注入那些内容。一段检索得当的、来自正确文档的 2,000-token 片段,胜过一份 40,000-token 的倾倒,因为后者的答案藏在中间某处。

这正是检索增强生成(RAG)存在的原因——不仅是为了克服上下文限制,更是通过保持上下文经过策划来提升质量。其智能体版本是即时检索:智能体不预先加载每一份文档,而是持有轻量级标识符(文件路径、ID、查询),只在需要的那一刻才把实际内容拉进上下文。

对于交互式会话,同样的逻辑也适用:不要积累一切,而要定期压缩或清空历史,以移除对当前任务不再相关的内容。Claude Code 的 /compact/clear 命令是上下文工程工具,而不只是会话管理。在 API 上,同样的模式由记忆与上下文编辑自动完成——旧的工具结果从窗口中被裁剪掉,而重要的内容被写入一个持久的记忆存储。

三大主力战术

对于长周期工作,三种技术承担了大部分重活。它们可以叠加使用——大多数真实的智能体三者都用。

Guided walkthrough1 of 3
  1. 当一场会话接近窗口上限时,将其总结并用提炼后的版本重新初始化。保留承重的细节——架构决策、未解决的 bug、关键实现选择——并丢弃逐步流水账。这就是 Claude Code 中 /compact 所做的事。

成本视角

你发送的 token 就是你付费的 token——既在金钱上,也在延迟上。用松散相关的材料塞满上下文会让两者都膨胀。上下文工程和成本效率是同一个问题。

更具体地说:

  • 你从模板复制粘贴来的臃肿系统提示,会在每一次调用上被付费。
  • 你因为“也许有用”而一路携带的旧对话历史,会在每一次调用上被付费。
  • 你“以防万一”而注入的文档,会在每一次调用上被付费。

裁掉不需要存在的东西,既对质量更好,运行起来也更便宜。

给 Claude 用户的实用战术

在 Claude.ai 中:

  • 为不同的任务使用不同的对话。别让一个下午的离题闲扯污染一个专注项目的上下文。
  • 在问一个依赖于长线程的复杂问题之前,先把它总结一下。一份明确的摘要往往比原始历史更有用。
  • 把你想要的具体东西放在长消息的末尾,而不是埋在中间。

在 Claude Code 中:

  • 让你的 CLAUDE.md 文件保持精简。其中的每一行都会被注入到每一次会话中。参见 CLAUDE.md上下文管理
  • 当切换到一个确实不同的任务时使用 /clear。当你想继续但会话正在变大时使用 /compact
  • 当当前这一步并不需要完整文件时,用路径引用文件,而不是粘贴它们的内容。

在 API 层面:

  • 设计系统提示,使其只包含每个请求都真正需要的内容。把任务专属的指令移到用户发言中。
  • 对于文档密集的用例,检索并注入相关片段,而不是上传整个语料库。
  • 把提示组织成稳定、可复用的前缀放在最前面——这也能启用提示缓存,它是上下文工程的天然伴侣。

当你想把一份长文档交给 Claude 时,位置规则每次都胜过单纯的体量:

指令在先,末尾重述

任务:找出本合同中每一处对我方责任设限的条款,并连同其条款编号逐字引用每一条。

[... 在此粘贴完整的 40 页合同 ...]

任务提醒:列出上面每一条责任限制条款,逐字精确引用,并附条款编号。如果一条都没有,请明确说明。

同一条指令既坐落在顶部坐落在底部——这两个位置正是注意力所偏爱的——因此即便经过一段很长的中间,它也能存活下来。

心态的转变

提示工程问的是:“我该说什么?” 上下文工程问的是:“模型该看到什么、以什么顺序、以及我该刻意把什么挡在外面?”

第二个问题更难,但它才是真正在大规模下决定质量的那个问题。

Check yourself

0/3
  1. 提示工程和上下文工程之间的核心区别是什么?
  2. 你把那条最重要的指令埋在了一个 10 万 token 上下文的第 60,000 个 token 处。可能的结果是什么?
  3. 一个编码智能体在一个长任务上即将耗尽上下文。哪种战术最能保住进展?
把词汇牢牢记住
按 Enter 或空格键翻转卡片。使用左右方向键在卡片之间切换。已显示术语。
1 / 6
Key takeaways
  • 上下文窗口是注意力预算,不是存储——只把它花在高信号 token 上。
  • 位置胜过体量:关键指令放在顶部和紧挨最后一轮之前,绝不埋在中间。
  • 压缩、记笔记和即时检索是让长程智能体保持连贯的三大战术。
  • 策划上下文与削减成本是同一根杠杆——更少的 token、更好的答案、更低的账单。

相关内容