在构建基于大型语言模型(LLM)的应用时,我们往往关注如何编写一个“好的”提示词。然而,随着AI应用的复杂度日益增加,仅仅依赖提示词已经不足以满足生产环境的需求。这时,上下文工程 (Context Engineering) 应运而生,它超越了传统的提示工程 (Prompt Engineering),专注于更全面地管理和构建LLM所见的信息环境,以确保模型输出的实用性、准确性和相关性。
什么是上下文工程?
上下文工程是提示工程的进阶实践,它精心构建和设计提供给大型语言模型(LLM)的输入(即上下文),从而确保LLM能够生成有用、准确且高度相关的输出。
举例来说:
弱提示:
Write about Paris.
→ 输出结果可能随机,涵盖历史、文化、地理或通用文本等,缺乏明确焦点。
优化提示(经过工程设计):
Write a 150-word travel blog post about Paris, focusing on food, local cafés, and romantic spots. Use a friendly and conversational tone.
→ 输出结果将变得有针对性、实用,并准确符合您的具体要求。
与仅关注编写巧妙的单行提示的“提示工程”不同,上下文工程的重点在于管理整个上下文窗口 (Context Window)。上下文窗口是模型在生成响应之前所能“看到”的信息集合,它包含了指令、示例、检索到的文档、系统消息、对话历史、约束条件等所有输入。
为何上下文工程如此重要?
LLM的上下文窗口相当于模型的短期记忆,它限制了模型一次性可以“看到”和处理的最大文本量(以令牌/Token 计算)。这个窗口包含了最新的提示、之前的对话轮次、系统指令以及任何插入的检索文档或示例。一旦输入信息(包括指令、历史和辅助资料)超出上下文窗口的限制,模型就会自动截断较旧的部分,从而导致关键信息的丢失。
长上下文失败的例子: 想象一下,您将一篇20页的研究论文以原始形式粘贴到LLM的输入框中,然后在顶部加上指令:“用300字为非技术受众总结这篇论文”。不幸的是,您在论文内容中又夹杂了一些无关信息,并在结尾处附加了一个相互冲突的指令:“让总结学术化”。 结果: 模型接收了过多的文本,早期的指令可能被后期的指令覆盖或稀释。最终的总结可能冗长、技术性强且前后矛盾,与您最初的意图背道而驰。
精心设计的短上下文例子:
相比之下,如果您的指令清晰地放在顶部:“用300字总结这篇研究论文,面向非技术受众,使用简单语言。”同时,只在上下文中包含论文的摘要、关键结果和讨论部分,并使用[Paper Abstract] …等格式标签进行区分。
结果: 模型仅关注到相关部分,清晰的指令指导了输出的语气和风格,从而生成了所需简洁的300字总结。
长而未经过滤的内容会使上下文窗口不堪重负,导致模型效率低下甚至出现幻觉。而精心策划、结构化的上下文则能使模型准确高效地运行。
“‘上下文工程’优于‘提示工程’。人们将提示与日常使用中给LLM的简短任务描述联系起来。但在每个工业级LLM应用中,上下文工程是精心艺术和科学地用恰到好处的信息填充上下文窗口,以进行下一步操作。”
—— Andrej Karpathy
对于大规模的LLM应用而言,持续高质量的输出至关重要。这需要以最优数量和最高质量的信息来精确填充上下文窗口。
如何获取上下文窗口的正确内容:
关键不是将所有内容都塞入上下文窗口,而是策划、过滤和注入最有效的内容。以下是上下文的关键组成部分:
1. 知识 (Knowledge)
模型正确推理任务所需的信息。
- 静态知识: 公司政策、产品手册、风格指南、FAQ等。这类信息通常存储在向量数据库(如 Pinecone, Weaviate, FAISS)中,并通过 RAG(检索增强生成) 技术在运行时检索。这确保了LLM能够提供事实性强且最新的数据,从而减少“幻觉”现象。
- 动态知识: 当前库存、最新定价、实时研究结果等。这类信息通过API或数据库按需获取,以保证实时性。
2. 指令 (Instructions)
约束和指导LLM,定义其“做什么”、“如何响应”以及“以何种风格”进行输出。
- 系统提示 / 角色定义: 例如,“你是一名旅行助手。始终以JSON格式响应。除非用户另有说明,否则优先选择预算友好的结果。”
- 格式要求: 例如,输出应为 Markdown、表格或结构化 JSON,以便下游应用程序使用。
- 示例(少量学习 / Few-shot Learning): 注入2-3个期望输出的示例,帮助模型模仿确切的结构和风格。
3. 工具和API调用 (Tools and API Calls)
在需要时获取最新数据,而不是用静态数据填充上下文窗口。
- API调用获取实时数据: 如天气 API(旅行应用)、股票 API(金融助手)、搜索 API(新闻摘要)。
- 数据库查询: 从 CRM 获取客户详情、从电商系统获取产品目录。
- 自定义工具(Agent): 代理 (Agent) 决定使用哪个工具(例如,航班预订 API 与酒店预订 API)。这些工具的执行结果会被追加到上下文窗口,以便LLM可以对其进行推理。
4. 过滤与优先级排序 (Filtering and Prioritization)
即使收集了知识、指令和工具输出,也无法将所有内容都塞入上下文窗口。必须采取策略:
- 优先选择 (Prioritize) 最相关的块(基于相似度搜索或排名)。
- 总结 (Summarize) 长文档后再插入。
- 将大输入分块 (Chunk) 成更小、适合上下文的片段。
- 选择性追加 (Selectively Append)(保留最后几次重要的交互,而不是整个对话历史)。
上下文工程的常见策略
上下文工程的核心在于通过以下四种策略高效地管理信息流:写入、选择、压缩和隔离。
1. 写入上下文(外部化信息)
当上下文信息量过大不适合直接放入上下文窗口时,需要将其写入外部存储并在以后检索。
- 暂存区 (Scratchpads): 用于分步规划、中间计算或保存可能被截断的计划的临时笔记。通常作为工具(文件写入)或运行时状态的一部分实现。例如,Agent 在执行多步骤任务时,可以把每一步的思考过程或结果记录在暂存区,供后续步骤参考。
- 记忆 (Memories): 跨会话持久存在的信息。如情景记忆(用户过去的偏好和行为)、程序记忆(应用的规则和指令)和语义记忆(事实性知识)。通过嵌入 (Embeddings)、检索 (Retrieval) 或知识图谱 (Knowledge Graph) 进行管理,以实现长期的个性化和一致性。
2. 选择上下文(选择要加载的内容)
决定哪些外部化信息应该被重新加载到当前的活动上下文窗口中。
- 暂存区选择: 通过工具调用或状态暴露机制,检索之前保存的笔记和中间结果。
- 记忆选择: 利用嵌入或知识图谱,仅获取与当前查询最相关的记忆(事实、规则或示例),避免无关信息的干扰。
- 工具选择: 对可用的工具元数据使用 RAG 技术,加载最相关的工具,防止混淆并提高 Agent 执行任务的准确性。
- 知识选择: 利用混合 RAG 技术(如抽象语法树 AST 解析、grep 搜索、嵌入搜索、重新排名等),高效地从大型代码库或企业数据集中检索精确的知识片段。
3. 压缩上下文(只保留重要内容)
当交互变长时,有效管理令牌预算是必不可少的。
- 总结 (Summarization): 让 LLM 生成上下文的总结,在保留主要意义的同时减少令牌负载。策略包括递归总结(分层总结)、分层总结或代理移交总结(例如,当上下文达到窗口容量的95%时,Claude Code 可以自动进行压缩)。
- 修剪/剪枝 (Pruning): 使用启发式方法(例如,删除旧的对话轮次)或训练方法(例如,Provence 这样的上下文修剪器)删除无关或过时的上下文信息。
4. 隔离上下文(分而治之)
跨 Agent 或环境分割上下文,以减少噪音和令牌膨胀,提高专业化。
- 多代理系统 (Multi-agent Systems): 将复杂任务分配给专业的 Agent,每个 Agent 都有自己独立的上下文窗口(例如,一个研究 Agent 负责资料收集,一个规划 Agent 负责制定策略,一个写作 Agent 负责内容输出)。
- 环境隔离(沙盒 / Sandbox): 在外部沙盒环境中执行结构化指令或代码,只将执行结果传递回 LLM,避免将大型代码或中间产物直接放入 LLM 的上下文窗口。
- 运行时状态隔离 (Runtime State Isolation): 维护一种模式,其中一些字段(如
[messages])暴露给 LLM,而另一些字段(如[knowledge])则保持隐藏,直到被明确检索。
上下文工程 vs. 提示工程
| 方面 | 提示工程 (Prompt Engineering) | 上下文工程 (Context Engineering) |
|---|---|---|
| 定义 | 制作指令或问题以引导LLM的行为。 | 设计和管理LLM的整个信息环境。 |
| 焦点 | 输入查询的措辞和结构。 | 查询周围的数据、历史和外部知识。 |
| 关键工具 | 指令、格式、少量示例 (Few-shot Examples) 和思维链 (Chain-of-Thought) 提示。 | 检索系统 (RAG)、知识图谱 (Knowledge Graph)、嵌入 (Embeddings) 和元数据注入。 |
| 可扩展性 | 有限——每个任务通常需要新的定制提示。 | 高——上下文管道 (Context Pipelines) 可以在不同领域和任务中重复使用。 |
| 可靠性 | 如果提示缺乏基础知识,可能导致幻觉 (Hallucinations)。 | 通过将输出建立在外部知识上,显著减少幻觉。 |
| 用例 | 快速原型设计、创意探索、一次性查询。 | 企业级 AI、生产级系统、领域特定任务。 |
| 类比 | 巧妙地提问。 | 在提问之前为模型构建正确的知识库和操作环境。 |
常见问题 (FAQ):
- 上下文工程与提示工程有何不同? 提示工程侧重于为LLM制作单一、结构良好的指令。上下文工程则管理更广泛的信息流——包括什么信息被存储、如何检索、如何压缩以及如何隔离,以进行有效推理。
- 为什么上下文工程对现实世界AI应用很重要? 在生产环境中,复杂任务通常会超出单个上下文窗口的限制。上下文工程确保相关信息可用,而不会让模型不堪重负,从而提高LLM的准确性、个性化和整体效率。
- 暂存区 (Scratchpads) 是什么,它们如何使用? 暂存区是存储在上下文窗口之外的临时笔记或中间步骤。它们帮助 Agent 模型规划、计算或跟踪进度,而不会丢失关键指令或思考过程。
- 记忆 (Memories) 如何在上下文工程中发挥作用? 记忆提供跨会话的持久知识,无论是记住过去的交互(情景记忆)、保存规则(程序记忆)还是存储事实(语义记忆)。这支持了个性化和连续性,使 Agent 能够随着时间推移积累经验和知识。
- 上下文工程可以应用于代码代理和企业系统吗? 是的,它非常适用。对于代码 Agent,上下文工程确保加载了正确的规则文件和相关知识,同时排除了无关数据。对于企业级应用,它通过 RAG 和混合搜索实现从大型数据集的高效检索和利用。
- 何时使用提示工程,何时使用上下文工程?
- 当需要快速实验、创意探索或轻量级用例时,使用提示工程。
- 当构建可扩展、领域特定且可靠的 AI 应用程序,并需要与外部数据源深度集成时,使用上下文工程。 实际上,这两种技术是互补的:强大的提示可以引导模型,但精心设计的上下文确保模型拥有准确回答所需的知识和结构。
结论
上下文工程代表了我们与 LLM 交互方式的下一次演进。它将焦点从“我们问什么”转移到“模型知道什么以及如何解释”。随着 AI 在各行业中普及,上下文工程将成为构建可扩展、值得信赖和智能系统的基石。与其将其视为提示工程的替代品,不如将其视为一个更大的图景;提示是火花,而上下文工程则是维持可靠性能的架构。
参考文献
- Context Engineering
- Don’t Build Multi-Agents
- How Long Contexts Fail
- Context Engineering Simply Explained
关于
关注我获取更多资讯