上下文工程:LLM应用的新范式
第1章:上下文工程:LLM应用的新范式
从一个失败案例说起:为什么同样的模型,不同的效果?
2023年秋天,某大型电商平台的算法团队遇到了一个让他们百思不得其解的问题。他们部署的客服对话系统在上线第一周就收到了大量用户投诉,核心问题只有一个:明明用的是同一家厂商的GPT-4模型,为什么隔壁产品团队做的问答机器人流畅得像在跟朋友聊天,而他们的客服系统却像是患上了“老年痴呆症”——聊着聊着就忘了之前说过什么,要么重复问同样的问题,要么突然跳转到完全无关的话题?
这个团队的工程师们最初的反应是检查模型参数。他们调高了temperature,增加了top_p值,反复尝试各种解码策略。但效果始终不尽如人意。用户依然在抱怨,客服满意度评分一度跌破了60%的红线。
直到他们请来了一位外部顾问。
这位顾问没有动任何模型参数。他只做了一件事:重新设计了系统与模型的“对话方式”——也就是本书要深入讨论的核心议题。修改后的系统在两周内上线,用户满意度迅速回升到85%以上,工单数量下降了40%。
这个故事揭示了一个当时很多人还没有意识到的事实:在LLM应用开发中,模型本身往往不是瓶颈,真正决定成败的是你如何与模型对话、如何组织它需要处理的信息。
让我们把时间拨回到2019年。那一年,OpenAI发布了GPT-2,这个拥有15亿参数的语言模型在当时已经算是“庞然大物”。当时的开发者们普遍采用一种简单粗暴的方式使用它:写一段prompt,然后期待模型“神奇地”给出正确答案。这种方式在模型能力有限、应用场景简单的年代勉强够用。但随着GPT-3、GPT-4以及Claude、Gemini等模型的相继问世,游戏规则发生了根本性变化。
现代LLM的能力边界已经远远超出了“根据一段文字续写下一个词”的范畴。它们可以遵循复杂指令、执行多步骤推理、扮演特定角色、与外部工具交互——但前提是,你要用正确的方式“告诉”它们你想做什么。
这就是上下文工程的起点。
当我们审视一个失败的LLM应用时,常常会发现问题的根源不在于模型不够强大,而在于输入给模型的上下文信息缺乏结构、缺乏策略、缺乏对模型认知机制的理解。一个典型的反面教材可能是这样的:开发者把用户的所有对话历史、几十条系统提示、上百个相关文档片段全部塞进context window,期待模型能自己“理解”哪些信息重要、哪些可以忽略。这种做法不仅浪费了宝贵的context空间,还会让模型产生“信息过载”导致的困惑和幻觉。
真正的问题在于:LLM应用开发正在经历一场范式转变。我们不再是在“使用”一个现成的工具,而是在“构建”一个由人类意图和模型能力共同驱动的智能系统。在这个系统中,上下文——从用户输入、系统提示、对话历史到外部知识——是驱动一切的“燃料”。如何设计、构造、传递和管理这些上下文信息,直接决定了系统的最终表现。
这也正是本书想要回答的核心问题:为什么上下文工程正在成为LLM应用开发的核心竞争力?它与传统prompt工程的本质区别是什么?你的团队应该如何开始这场实践?
上下文工程的定义与核心原则
什么是上下文工程
在深入讨论之前,我们需要先明确一个关键概念:上下文(Context)在LLM应用中的含义远比它的日常语义丰富。
在传统编程中,“上下文”通常指程序执行的当前环境——变量状态、调用栈、运行环境等。在LLM领域,上下文有了更广义的内涵:它指的是模型在生成响应时所能“看到”和“考虑”的所有信息。这包括但不限于:
- **用户输入**:用户当前的提问或指令
- **对话历史**:之前的交互记录(多轮对话场景)
- **系统级指令**:通过system prompt传递的角色定义、行为规则
- **外部知识**:检索到的文档、数据库内容、实时API数据
- **隐式上下文**:模型在预训练阶段学到的世界知识
上下文工程(Context Engineering)则是设计、管理和优化这些与LLM交互信息的系统化方法。它涵盖从需求分析、信息架构设计,到prompt撰写、上下文组装、结果解析的完整链条。
如果用建筑来类比,传统的prompt engineering更像是“装修”——在已有的房屋结构上刷漆挂画;而上下文工程则是从“选址和规划”开始的系统建设——它要回答的是:这个智能系统需要什么样的信息基础?这些信息如何组织才能被模型高效利用?系统的“知识边界”在哪里,如何防止模型“信口开河”?
四大核心原则
经过大量的实践探索和理论研究,上下文工程领域逐渐形成了几个被广泛认可的核心原则:
原则一:上下文是有限的资源,需要精心设计
现代LLM的context window虽然已经从GPT-3的2048个token扩展到了数十万甚至上百万token,但这并不意味着上下文是“免费”的无限资源。每一个token的输入都会增加推理的计算成本和延迟。更重要的是,当context中充斥着大量无关或冗余信息时,模型的注意力机制会被分散,导致它难以准确识别真正重要的信息。
一个经过精心设计的上下文系统,可能只需要3000个token就能实现比粗犷塞入15000个token更好的效果。这就像优秀的建筑师懂得用简洁的设计创造空间感,而不是用堆砌材料来填充每一个角落。
原则二:结构化优于非结构化
当我们在context中传递信息时,信息的组织方式直接影响模型的理解效率。研究表明,即使是强大的LLM,在处理高度非结构化的长文本时也会出现“中间丢失”(lost in the middle)的问题——模型倾向于关注context的开头和结尾,而忽略中间部分。
相比之下,通过清晰的格式、分隔符、层级结构来组织信息,可以显著提升模型对关键信息的捕获能力。这包括:使用XML标签或Markdown格式来标记不同类型的信息,在长列表中插入摘要或索引,对复杂信息进行预结构和模式化。
原则三:显式优于隐式
很多开发者在设计prompt时,倾向于假设模型能“自己想明白”很多隐含的规则和期望。但研究表明,LLM对模糊指令的遵循能力虽然令人印象深刻,却并不稳定。特别是在复杂任务中,那些在人类看来“显而易见”的期望,往往需要被明确表述才能被可靠地执行。
这并不意味着prompt要写得冗长繁琐。恰恰相反,最有效的策略是用最少的文字传递最清晰的指令——但每一个词都应该是必要的。比如,与其在system prompt中写“希望助手能够专业地回答问题”,不如明确表述“回答应基于事实,避免编造数据;在不确定时主动承认”。
原则四:迭代优于一次性设计
上下文工程不是“写好一个prompt就完事了”的工作。真正有效的上下文设计需要经过持续的测试、评估和优化。这个过程涉及:建立可靠的评估指标和测试用例,系统性地尝试不同的上下文策略,记录和分析失败的案例,以及随着模型能力演进和用户需求变化不断调整设计。
正如软件工程中的敏捷开发理念,上下文工程也强调“小步快跑、持续改进”的工作方式。一个优秀的上下文工程师,不是那些能够“一次写对”的人,而是那些建立了高效反馈循环、能够快速定位和解决问题的人。
上下文工程 vs Prompt Engineering:继承与超越
Prompt Engineering的黄金时代与局限
要理解上下文工程的独特价值,我们需要先回顾prompt engineering的发展历程。
Prompt engineering作为术语在2020年前后开始流行,主要指的是如何通过精心设计输入文本来引导LLM产生期望输出的一系列技术。few-shot learning、chain-of-thought prompting、role prompting等技术的出现,让人们意识到:模型输出的质量高度依赖于输入prompt的设计。
在那个时期,prompt engineering几乎就是“有效使用LLM”的代名词。互联网上充斥着各种“咒语”和“模板”,教你如何通过特定的话术技巧让ChatGPT表现得更好。这个阶段的prompt engineering有几个典型特征:
首先,它关注的是个体prompt的优化——如何写一个更好的system prompt,如何构造few-shot examples,如何组织用户指令。其次,它更多依赖经验和直觉——很多技巧来自于“试出来的”,缺乏系统的理论支撑。第三,它的可迁移性有限——在一个模型、一个任务上有效的prompt,在另一个场景中可能完全失效。
然而,随着LLM应用逐渐从“玩具demo”走向“生产系统”,prompt engineering的局限性开始显现。
从点到面:从单个prompt到上下文系统
当你的应用需要处理多轮对话时,prompt engineering的思路就显得力不从心了。你不能简单地给每一轮对话都写一个“完美prompt”,因为对话是一个动态的过程,用户输入是不可预测的,你需要的是一个能够自适应、能够处理各种边缘情况、能够持续稳定工作的系统。
上下文工程正是从这个需求出发,将视野从“单个prompt”扩展到了“整个上下文系统”。它关注的问题包括:
信息流动的设计。在一个聊天机器人中,用户的历史消息、系统的中间状态、外部检索的结果、用户画像等各类信息如何组装成最终的context?这个组装过程需要遵循什么规则和优先级?
系统边界的划分。哪些能力应该由prompt来定义,哪些应该通过后处理实现,哪些需要单独的微调或训练?上下文工程帮助你在这些不同的技术路径之间做出明智的权衡。
质量保障的机制。当模型输出不符合预期时,是prompt的问题、context的问题、还是模型本身的问题?如何建立监控和诊断能力?上下文工程提供了一套系统化的排查和优化方法论。
从艺术到工程
如果用一句话概括上下文工程相对于prompt engineering的核心超越,那就是:从艺术走向工程。
早期的prompt engineering确实带有相当的艺术成分——依赖个人经验、直觉判断、反复试错。这种方式在小规模、探索性的场景下是可接受的,但无法支撑企业级的LLM应用开发。
上下文工程则引入了一整套工程实践:
- **可复用的设计模式和反模式**:哪些上下文结构是经过验证的有效方案,哪些是已经被证明容易出问题的陷阱。
- **系统化的评估方法**:如何构建测试集、如何定义评估指标、如何进行A/B测试。
- **文档化的知识积累**:将团队在不同项目中的经验沉淀为可查阅的设计指南和最佳实践。
- **自动化的工具链**:从prompt版本管理到上下文组装到输出验证的完整工具支持。
这并不意味着prompt engineering的技巧变得无关紧要。恰恰相反,prompt的撰写依然是上下文工程的核心技能之一——但它现在是一个更大的工程体系中的一个组成部分,而不是全部。
继承与融合
需要指出的是,上下文工程并非要彻底否定prompt engineering的价值。很多在prompt engineering发展过程中积累的洞察和方法,在上下文工程框架下依然发挥着重要作用。
Chain-of-thought prompting揭示的推理过程外化策略,被整合进了更复杂的上下文设计模式。Role prompting探索的角色定义技巧,依然是构建AI agent行为规范的重要手段。In-context learning的机制研究,帮助我们更好地理解上下文信息的组织方式对模型行为的影响。
上下文工程更像是prompt engineering的“升级版”——它继承了前者的核心洞察,同时提供了更系统化的方法论和更广阔的工程视野。
本书的知识体系与学习路径
上下文工程的四层架构
在展开讨论之前,让我们先鸟瞰一下本书将覆盖的知识版图。通过大量的实践案例和理论分析,我们发现上下文工程的知识体系可以组织为四个递进的层次:
第一层:基础层(Foundations)
这一层回答的问题是:上下文在LLM中是如何工作的?为什么上下文的设计会影响模型输出?这一层包括:LLM的工作原理与上下文机制、Transformer架构中的注意力机制、context window与token的概念、以及上下文对模型行为影响的理论解释。
理解基础层的内容,不需要你成为机器学习专家,但需要建立足够的直觉来理解“为什么这样做有效”的底层逻辑。这将帮助你在面对新问题时做出更好的判断,而不是盲目套用别人的模板。
第二层:设计层(Design)
这一层聚焦于如何设计有效的上下文结构。包括:system prompt的设计原则与最佳实践、用户输入的预处理与格式化、多轮对话中的上下文管理、外部知识的检索与整合、以及上下文压缩与摘要策略。
设计层的内容是本书的核心篇幅。你将学到如何从零开始为不同类型的应用设计上下文架构,如何处理复杂的边角案例,以及如何建立你自己项目的上下文设计规范。
第三层:工程层(Engineering)
这一层关注的是如何将上下文设计落地为可维护的工程系统。包括:上下文组装管道的架构设计、prompt版本管理与A/B测试、上下文工程中的监控与诊断、工具与框架的选择、以及团队协作与知识管理。
工程层的内容将帮助你从“个人技巧”升级为“团队能力”,让你的上下文工程成果能够被持续维护和改进。
第四层:进阶层(Advanced)
这一层探讨前沿话题和高级应用。包括:多模态上下文的设计、AI agent的上下文策略、自主推理与上下文的协同演化、以及未来技术趋势的展望。
进阶层的内容面向希望在领域内深耕的读者,每一节都可以独立成篇,根据你的兴趣和时间选择阅读。
学习路径建议
根据你的背景和学习目标,我们提供几种不同的学习路径:
路径一:快速上手(适合时间有限的项目经理或产品经理)
如果你希望快速建立上下文工程的直觉,以便更好地指导团队工作,建议按照以下顺序阅读:第1章(本章)→ 第3章(System Prompt设计)→ 第5章(上下文组装基础)→ 第7章(评估与迭代)。跳过基础层的理论细节,重点关注可以直接应用的设计原则。
路径二:系统掌握(适合需要独立完成项目的开发者)
建议按章节顺序完整阅读本书,特别关注第2章(上下文机制理论)和第4章(设计模式)的内容,这些将为你的实践提供坚实的理论支撑。务必完成每章的实践练习,它们是内化知识的关键环节。
路径三:深度研究(适合AI工程师或研究员)
建议完整阅读所有章节,包括进阶层的所有内容。同时推荐补充阅读每章末尾的延伸阅读推荐,建立更完整的学术视野。这类读者还可以在GitHub上参与本书的勘误和案例讨论。
章节地图
以下是本书15章的完整导览:
第1-2章构成导论篇,回答“上下文工程是什么”和“为什么重要”的问题。
第3-4章是原理篇,深入讲解上下文的工作机制和设计的基础原则。
第5-8章是核心篇,覆盖上下文设计的四大支柱:组装、管理、检索、压缩。
第9-10章是进阶篇,探讨评估体系和多轮对话的复杂性。
第11-12章是工程篇,解决生产环境中的实际问题。
第13-14章是架构篇,讨论AI agent和多智能体系统的上下文策略。
第15章是展望篇,总结核心洞察并展望未来。
在深入技术细节之前,我们需要先理解上下文作为“资源”的本质——这将引出第二章关于上下文经济学的话题。
案例:重构一个失败的聊天机器人
背景:那个让团队头疼的客服机器人
让我们回到本章开头的那个电商平台案例。当时的客服机器人团队面临的问题很典型:
业务背景:一个日均处理5万次咨询的电商客服系统,用户问题涵盖订单查询、退换货处理、商品咨询、投诉建议等多个类别。系统需要在30秒内给出回复,且满意度需要维持在75%以上。
技术栈:后端使用Python + FastAPI,对接OpenAI的GPT-4 API,部署在AWS上,前端是移动App和网页端。
原始实现:开发者写了一个简单的system prompt,描述了助手的角色定位,然后简单地把用户的历史消息和当前消息拼接在一起,发送给API。
问题很快就暴露了:
- 对话稍微长一点(超过10轮),模型就开始“失忆”
- 模型经常把用户的订单信息和另一个用户的混淆
- 当用户表达复杂情绪(既有抱怨又有需求)时,模型只回应了一部分
- 生成的回答长度不可控,有时一个简单问题会输出500字的“论文”
诊断:识别上下文设计的核心问题
在重构之前,团队首先进行了系统性的问题诊断。通过分析1000条真实对话日志,他们发现了几个典型的失败模式:
问题一:上下文膨胀但不相关
原始实现把所有历史消息都塞进context,导致在长对话中,真正与当前问题相关的信息被淹没在不相关的历史记录中。比如,用户可能先问了一件衣服的尺码,然后在6轮对话后问了一个完全不同的订单物流问题,但模型依然会把前面6轮的尺码对话当作“上下文”参考。
问题二:缺乏信息结构化
所有消息都平铺直叙地放在一起,用户输入、系统指令、对话历史没有任何格式区分。这让模型难以快速定位关键信息。
问题三:缺少边界和约束
System prompt只是简单地说“请扮演一个有帮助的客服助手”,没有明确的行为边界。导致模型在有些回答中过于冗长,在另一些场景下又过于简短。
问题四:外部知识不可达
当用户问及具体订单状态时,模型只能根据训练数据“猜测”,而不是真正查询后台系统。这导致了大量幻觉和错误信息。
重构:上下文工程的实践应用
基于诊断结果,团队采用上下文工程的思路进行了系统性重构:
步骤一:重新设计System Prompt
```markdown 【角色定义】 你是一个专业、高效的电商客服助手,名称为"小E"。你的主要职责是帮助用户解决订单相关问题。
【行为准则】 1. 回答简洁明了,平均长度控制在50-150字 2. 只回答用户当前问题,不主动延伸话题 3. 如需查询信息,明确告知用户你正在查询 4. 无法回答的问题,礼貌转接人工客服
【信息格式】 回答时使用以下格式:
- 订单信息:直接引用订单号和状态
- 时间信息:使用用户本地时间
- 金额信息:保留两位小数,单位为元
【边界规则】
- 不承诺无法兑现的优惠或时间
- 不提供超出平台范围的政策建议
- 涉及退款金额时,提示用户以最终确认为准
```
这个重写的system prompt遵循了“显式优于隐式”的原则,将所有关键期望都明确写出,避免依赖模型的“猜测”。
步骤二:设计上下文组装策略
团队引入了一个“上下文组装器”(Context Assembler)的组件,负责在每次请求时动态构建context:
```python class ContextAssembl