第一部分:基础篇——上下文工程的ABC Part One: Fundamentals — The ABC of Context Engineering
什么是上下文?为什么它决定了AI的智商?
当你走进一家熟悉的咖啡店,还没开口,店员就微笑着问:“还是老样子,冰美式加燕麦奶对吗?”你点点头,心里涌起一股莫名的舒适感。这家店员不需要你重复解释自己的口味偏好,因为他们记住了——上一次、之前的很多次,你都点的是同样的东西。
这种“不需要重复说明”的默契,就是上下文在发挥作用。
现在,把这个场景切换到与AI对话。你可能有过这样的经历:辛辛苦苦和AI聊了几十轮,解决了一个复杂的技术问题,最后刷新页面,一切归零。你不得不从头解释你是谁、你在做什么项目、遇到了什么问题。这感觉就像每次去咖啡店都要重新办一张会员卡一样令人沮丧。
这就是上下文工程的用武之地。它是一门关于“如何让AI记住、理解和利用对话中的信息”的技术——一门让AI从“每句话都像第一次见面”的健忘症患者,变成“记得你所有偏好”的贴心助手的学问。
本章将带你理解上下文的本质。你会从日常生活的角度理解什么是上下文,然后深入了解它在大型语言模型中的工作原理。我们会介绍上下文工程的三大支柱:压缩、检索和状态管理。最后,你会清楚地知道,为什么即使你是一个刚刚接触AI的初学者,了解上下文工程也会让你的AI使用效率提升数倍。
---
上下文的定义:从日常对话到AI交互的类比
上下文的三种面孔
让我们从一个简单的对话开始:
对话A: > 甲:明天天气怎么样? > 乙:会下雨,记得带伞。
对话B: > 甲:这个项目进展如何了? > 乙:昨天完成了用户调研,数据还在分析中,预计周五出报告。
在对话A中,乙的回答之所以有意义,是因为“天气”是唯一的解释对象。而在对话B中,乙的回答依赖于大量未明说的信息:这是什么项目?用户调研是什么时候开始的?报告要交给谁?如果我们把这段对话截取出来给一个不了解情况的人看,他可能会完全摸不着头脑。
这就是上下文的力量。同样的词汇和句子,在不同的上下文中承载完全不同的含义。
在日常生活中,上下文以三种形式存在:
第一种:共享经验(Shared Experience)
你和老朋友之间积累的共同记忆就是上下文。你们提到“那次在东京迷路的经历”,双方都能立刻回想起具体的场景、当时的对话、甚至当时吃的难吃的拉面。这种基于共享经验的上下文,让你们的交流异常高效。
第二种:场景信息(Situational Context)
你正在开一个紧急会议,手机响了。即使不看来电显示,你也能从铃声判断出:这大概是外卖到了。在会议室这个场景中,“电话响了=外卖到了”这个推断就是场景上下文在起作用。
第三种:语言惯例(Linguistic Convention)
在编程社区里,你说“Stack Overflow报错”,大家秒懂你说的是程序员问答网站。但如果你在普通聊天群里这样说,别人可能会以为你在说堆叠的什么东西。语言惯例也是一种上下文——它规定了特定词汇在特定社群中的含义。
AI眼中的上下文
现在,让我们把这些类比迁移到AI交互中。当你和ChatGPT对话时,你输入的每一句话并不是孤立的。AI会把你的输入放进一个更大的“容器”里,这个容器里还装着:
- **对话历史**:你之前说了什么,AI回复了什么
- **系统提示词**:AI被设定扮演什么角色,有什么约束
- **用户信息**:如果AI被告知你是谁、你的偏好是什么
- **世界知识**:AI训练时学到的通用知识
- **当前任务**:你正在解决什么问题
这个“容器”,就是上下文窗口(Context Window)。
打个更形象的比喻。想象你在准备一场考试。如果你有一张写得密密麻麻的草稿纸(上下文),上面记录了所有重要的公式、定理、例题,你答题时就能随时翻阅。但这张纸是有限大小的——也许只能写1000个字。
大型语言模型也有这样一张“草稿纸”。GPT-4的上下文窗口是128K tokens(大约相当于10万汉字),Claude 3支持200K tokens,而最新的模型可能更大。这听起来很大,但当你处理一个复杂的项目时,这些限制很快就会显现出来。
一个生活中的类比:点菜与上下文
让我用一个更加具体的类比来说明上下文的重要性。
假设你是一个美食博主,正在探访一家米其林餐厅。
场景一:没有上下文 服务员端上第一道菜,只说了一句话:“这是主厨的特选。”然后就走了。 你看着盘子里的东西,完全不知道这是什么食材、用什么烹饪手法、应该用什么顺序品尝、吃的时候要注意什么。这道菜对你来说就是一团信息黑洞。
场景二:有完整上下文 服务员详细介绍了这道菜的来历:这是日本�的�的蓝鳍金枪鱼,捕捞后经过72小时熟成的,今天是最佳赏味期。建议先用筷子夹取一小块,品尝它本来的鲜味,然后蘸取旁边的柚子胡椒,感受层次的变化。 现在你知道了:你吃的不只是一块鱼,而是厨师几个月准备、一整条供应链、以及数百年烹饪传统的结晶。
上下文就是那个让你理解“你在吃什么、为什么重要”的信息。
在AI交互中,同样的道理。你给AI的信息越丰富、越结构化、越准确,AI的输出就越能击中要害。如果你只是丢给AI一句“我代码报错了”,AI只能给你一堆泛泛的通用建议。但如果你告诉AI你用什么语言、什么框架、具体的错误信息是什么、你已经尝试过什么——你就给AI提供了一道完整的“菜单介绍”,它就能精准地帮你定位问题。
---
上下文在LLM中的工作机制:注意力机制的可视化解释
从“读全部”到“找重点”
理解了什么是上下文之后,你可能会问:AI是怎么利用上下文的?
这就要涉及到大型语言模型的核心技术:注意力机制(Attention Mechanism)。
让我用一个生活中的例子来解释。假设你在一间嘈杂的咖啡馆里工作,背景里混杂着几十个人的对话、咖啡机的轰鸣、背景音乐的旋律。但当你的名字被旁边的人提起时,你几乎立刻就能捕捉到。这就是人类大脑的“注意力”——我们不是均匀地处理所有信息,而是有选择性地关注重要的部分。
Transformer架构(目前几乎所有主流大语言模型都基于此)的核心创新,正是让AI学会了类似的“选择性注意力”。
注意力机制的工作原理
当AI处理一句话时,它会计算每个词与其他所有词之间的关系强度。让我用一句话来演示:
> "小明把红色的书给了小红,因为她的颜色正好配她的书包。"
这句话里有一个著名的歧义:“她”指的是谁?
- 如果你只看到第一个分句,“她”似乎指的是小明——但这不合逻辑。
- 如果你联系“红色的书”和“配她的书包”,“她”指的是小红,因为小红的书包需要匹配红色。
这就是上下文消歧——根据上下文来确定代词指代的对象。
注意力机制做的事情与此类似,但它在数学层面计算的是“相关性分数”。对于句中的每个词,AI会计算它应该“关注”其他哪些词,关注多少。
```mermaid flowchart LR subgraph Input["句子: '小明把红色的书给了小红'"] A["小明"] B["把"] C["红色"] D["的"] E["书"] F["给了"] G["小红"] end
subgraph Attention["注意力权重可视化"] A1["小明"] E1["书"] C1["红色"] G1["小红"] end
subgraph Output["上下文理解"] O1["小红收到了红色的书"] end
Input --> Attention Attention --> Output
style A1 fill:#ff6b6b style E1 fill:#ff6b6b style C1 fill:#feca57 style G1 fill:#48dbfb ```
在这个简化的例子中,当AI处理“书”这个词时,它会高权重地“注意”旁边的“红色”和“给了”;当处理“小红”时,它会注意到“给”的动作执行到了她身上。通过这种交叉计算,AI建立了对整个句子的理解。
上下文窗口的物理限制
注意力机制虽然强大,但它有一个关键约束:它只能在上下文窗口内的信息之间建立联系。
这意味着什么?
假设你在和AI讨论一个长达50页的项目文档。你把前30页的内容粘贴给了AI,然后问:“根据我们之前讨论的架构方案,这个API应该返回什么格式?”
如果关键的“架构方案”出现在第31页,而那一页不在当前的上下文窗口内,AI就不知道你在说什么。它可能会根据通用的最佳实践给出一个答案,但这个答案很可能与你团队的实际方案不符。
这就是为什么上下文管理如此重要。你需要确保AI“看到”的内容包含了它理解你的问题所需的所有信息。
一个更形象的比喻:想象你是一个法官,正在审阅一桩复杂的商业纠纷案。你的办公桌上只能同时摊开500页材料。当事人双方都提交了堆积如山的证据,但你的桌子只有这么大。你必须精心选择把哪些材料放在桌上,哪些暂时收进档案柜——否则你就会遗漏关键证据,做出错误判断。
上下文窗口就是AI的“办公桌”,而上下文工程就是“如何整理桌面”的艺术。
自注意力与交叉注意力的区别
在大语言模型的语境中,你可能会听到两种注意力机制:
自注意力(Self-Attention):模型在处理当前输入时,关注同一段输入内其他部分的关系。比如在处理一段文档时,模型会关注这段文档内不同段落、句子、词之间的关系。
交叉注意力(Cross-Attention):模型在处理当前内容时,关注外部参考资料的关系。比如你给AI提供一段参考文档,让它在回答问题时“参考”这个文档的内容。
当你使用“给AI附加文档然后提问”的场景时,交叉注意力就在发挥作用。模型需要判断:当前问题与参考资料中的哪些段落相关?相关程度如何?这些都是通过注意力权重来计算的。
---
上下文工程的三大支柱:压缩、检索、状态管理
现在我们已经理解了上下文是什么,以及AI如何利用上下文。接下来,让我们了解管理上下文的三个核心技术方向,我称之为上下文工程的三大支柱。
支柱一:压缩(Compression)——如何在有限空间里装更多信息
压缩的核心问题是:当上下文窗口不够用时,如何在有限的“桌面”上保留最重要的信息?
想象你在准备一场考试,你的笔记有1000页,但你的草稿纸只能写1000字。你必须把1000页的内容“压缩”成1000字,同时保留最关键的信息。这不是简单地删减——你需要判断什么是重要的,什么可以忽略,什么需要用更简洁的方式表达。
有损压缩 vs 无损压缩
在数字世界里,压缩有两种类型:
- **无损压缩**:比如把文件打成ZIP包,解压后内容和原文件一模一样。信息没有损失,但压缩率有限。
- **有损压缩**:比如把高清图片转成JPEG,虽然文件变小了,但细节也丢失了。
上下文压缩更像是后者——你需要“智能地丢弃”不太重要的信息,同时尽可能保留对当前任务有意义的内容。
实践中的压缩策略
在实际应用中,有几种常见的压缩策略:
第一种是摘要压缩。你把一段长文本交给AI,让它先总结出核心要点。这就像把一本书读薄成一张思维导图。比如,一份50页的产品需求文档,可以被压缩成200字的关键需求列表。
第二种是选择性保留。不是所有对话历史都同样重要。你最近几轮讨论的内容可能很关键,而一个月前的闲聊可能已经无关紧要。通过识别“关键转折点”或“重要决策点”,你可以选择性地保留那些塑造了当前状态的信息。
第三种是结构化提炼。把非结构化的对话转换为结构化的数据。比如,把一系列讨论提取成一个决策清单、一个待办列表、或一个技术方案概览。结构化信息比自然语言更紧凑,AI处理起来也更高效。
支柱二:检索(Retrieval)——如何找到正确的信息
如果说压缩是“把所有东西变小”,那么检索就是“只取我需要的那一小部分”。这是一个互补的策略:你不需要压缩整个上下文窗口,而是让AI在需要时“查资料”。
检索增强生成(RAG)的原理
检索增强生成(Retrieval-Augmented Generation,简称RAG)是目前最流行的上下文增强技术之一。它的核心思想是:
1. 把你的文档、数据库、知识库分割成小块(chunks) 2. 为每个小块生成一个“向量表示”(可以理解为文档的“数字指纹”) 3. 当用户提问时,把问题也转换成向量 4. 在向量数据库中搜索与问题最相关的文档块 5. 把检索到的内容加入上下文,供给AI使用
```mermaid flowchart TD subgraph Knowledge["知识库"] D1["文档1"] D2["文档2"] D3["文档3"] end
subgraph Indexing["向量化索引"] V1["向量1"] V2["向量2"] V3["向量3"] end
subgraph Query["用户查询"] Q["问题:如何部署容器?"] QV["问题向量"] end
subgraph Retrieval["检索"] R["相似度匹配"] end
subgraph Context["上下文构建"] C["相关文档块"] end
subgraph LLM["大语言模型"] L["生成回答"] end
D1 --> V1 D2 --> V2 D3 --> V3
Q --> QV QV --> R V1 --> R V2 --> R V3 --> R
R --> C C --> L
style C fill:#48dbfb,stroke:#0abde3 style L fill:#ff6b6b,stroke:#ee5a24 ```
这个过程就像一个图书管理员。当你说“我想了解人工智能的历史”,管理员不会把整个图书馆都搬给你,而是会走到特定的书架,取出《人工智能简史》《AI发展里程碑》《图灵传》这几本书的相关章节,送到你面前。
什么时候用压缩,什么时候用检索?
这是一个很关键的选择。一般来说:
- 如果信息量适中,可以在上下文窗口内容纳,选择**压缩**策略
- 如果信息量巨大、更新频繁、需要精准引用,选择**检索**策略
- 在复杂的生产系统中,两者往往会结合使用——先检索相关文档,再对检索结果进行压缩
支柱三:状态管理(State Management)——如何保持对话的连贯性
第三个支柱解决的是“如何在多轮对话中保持状态”的问题。
当你使用ChatGPT时,你可能已经注意到:如果对话太长,AI会开始“遗忘”早期讨论的内容。这是因为上下文窗口满了,新的内容会挤掉旧的内容。
状态管理要解决的核心问题是:如何在上下文有限的情况下,保持对“当前状态”的持续感知。
显式状态 vs 隐式状态
在对话中有两种状态:
隐式状态是AI根据对话历史“推断”出来的状态。比如你们聊了几轮关于Python编程的话题,AI可能推断你现在是一个正在学习Python的开发者。但这种推断是基于模式的,不是精确的记录。
显式状态是你主动告知AI的当前状态。比如你可以在对话开始时说:“我现在是一个初级Python开发者,正在学习面向对象编程,目前卡在继承这一章。”这种主动的状态声明比让AI自己推断要可靠得多。
会话状态的管理模式
在实际应用中,有几种常见的状态管理模式:
第一种是完整历史模式。把整个对话历史都放入上下文。这最简单,但上下文窗口会迅速耗尽。
第二种是摘要压缩模式。定期把对话历史压缩成摘要。比如每10轮对话后,让AI总结一次之前的核心要点,然后把摘要和问题压缩后继续对话。
第三种是外部状态模式。在外部系统(如数据库、Redis、文件)中存储对话状态和关键信息,AI在需要时主动查询这些外部状态。
第四种是主动上下文注入。用户或系统主动管理哪些信息应该留在上下文中。在对话的每个关键时刻,主动更新上下文声明,确保AI始终有正确的背景信息。
---
为什么初学者也需要了解上下文工程
一个常见的困境:为什么AI“不记得”你说的话?
让我们从一个真实的场景开始。
小李是一个刚毕业的市场专员,正在用AI辅助写一份营销方案。他这样开始了对话:
> 小李:帮我写一份新产品的营销方案
AI给出了一个框架。小李觉得不错,继续说:
> 小李:产品叫“智控智能插座”,主打远程控制和能耗监测
AI更新了方案,把产品信息加了进去。然后小李说:
> 小李:目标用户是一线城市的年轻白领,预算大概30万
AI又更新了方案。用户画像和预算加进去了。
对话进行到第15轮,小李说:
> 小李:等等,刚才说的那个“智控智能插座”,品牌名叫什么来着?
AI犹豫了一下,给出了一个看起来不太确定的回答。
小李困惑了:我明明在第2轮就说了产品名啊,AI怎么不记得了?
这个场景揭示了一个关键事实:大语言模型并不会主动“记住”你说过的所有话。它们只是根据当前上下文窗口内的信息来生成回复。当对话足够长,早期的信息被挤出上下文窗口后,AI就会“遗忘”它们。
如果你了解上下文工程,你会知道解决方案很简单:在对话开始时,用一个结构化的方式声明所有关键信息;或者,定期回顾和确认关键信息;在长对话中,主动把关键信息重新注入上下文。
上下文工程让你成为更高效的AI使用者
了解上下文工程能给你带来什么?
第一,减少重复劳动
不了解上下文工程的你,可能会在长对话中反复解释同一个背景。不了解上下文工程的你,可以用一个清晰的“项目卡片”开始每次对话,把所有必要信息一次性注入上下文。
第二,获得更精准的输出
AI的输出质量很大程度上取决于输入的上下文质量。不了解上下文工程的人,给AI的是模糊、零散的信息碎片;了解上下文工程的人,给AI的是结构清晰、关键信息完备的上下文。
第三,更好地使用高级功能
当你想使用检索增强、插件调用、代码执行等高级功能时,它们本质上都是上下文工程的具体应用。了解底层原理,你才能更好地配置和使用这些