“上下文工程”这个词之所以流行,是因为它直观地捕捉到了我们在构建大语言模型解决方案时实际在做的事情。“提示词”听起来像是一个简短的查询;而“上下文”则意味着我们为 AI 准备的更丰富的信息状态。
撇开语义不谈,为什么这个转变如此重要?因为它标志着我们 AI 开发心态的成熟。我们已经认识到,生产环境中的生成式 AI 不像念一句魔法咒语,而更像是为 AI 设计一个完整的工程环境。一次性的提示词或许能做出炫酷的演示,但对于稳健的解决方案,你需要在每一步都控制模型“知道”什么和“看到”什么。这通常意味着检索相关文档、总结历史记录、注入结构化数据或提供工具——无论需要什么,只要能让模型不是在黑暗中猜测。结果是,我们不再将提示词视为我们希望 AI 能理解的一次性指令。我们开始从上下文管道的角度思考:所有那些为 AI 成功铺路的信息和交互片段。
•它是动态的,因地制宜。与单个硬编码的提示词不同,上下文的组装是根据每个请求进行的。系统可能会根据查询或对话状态包含不同的信息。如果是一场多轮对话,你可能会包含对话至今的摘要,而不是完整的记录,以节省空间(和理智)。如果用户的问题引用了某个文档(“设计规范中关于 X 是怎么说的?”),系统可能会从维基中获取该规范并包含相关的摘录。简而言之,上下文工程的逻辑会响应当前的状态——很像程序的行为取决于输入一样。这种动态性至关重要。你不会为翻译的每一句话都给翻译模型完全相同的提示词;你会每次都给它新的句子。同样,在一个 AI 智能体中,随着状态的演变,你会不断更新你提供的上下文。
•它融合多种类型的内容。LangChain将[5]上下文工程描述为一个涵盖至少三个方面上下文的保护伞:(1)指令性上下文——我们提供的提示词或指导(包括系统角色指令和少样本示例),(2)知识性上下文——我们提供的领域信息或事实,通常通过从外部来源检索获得,以及(3)工具性上下文——来自模型环境通过工具或 API 调用获得的信息(例如,网络搜索、数据库查询或代码执行的结果)。一个稳健的大语言模型应用通常需要所有这三种:关于任务的清晰指令、插入的相关知识,以及可能让模型使用工具并将工具结果整合回其思考过程的能力。上下文工程就是管理所有这些信息流并将它们连贯地合并起来的学科。
•格式与清晰度至关重要。不仅是你在上下文中包含什么内容,还有你如何呈现它。与 AI 模型沟通与和人沟通有惊人的相似之处:如果你扔给它一大堆非结构化的文本,模型可能会感到困惑或抓不住重点,而一个组织良好的输入则会引导它。上下文工程的一部分工作是找出如何压缩和组织信息,以便模型能抓住重点。这可能意味着总结长文本,使用项目符号或标题来突出关键事实,甚至将数据格式化为 JSON 或伪代码,如果这有助于模型解析的话。例如,如果你检索了一个文档片段,你可能会在它前面加上类似“相关文档:”的前缀,并将其放在引号中,这样模型就知道这是参考材料。如果你有一个错误日志,你可能只显示最后 5 行,而不是 100 行的堆栈跟踪。有效的上下文工程通常涉及创造性的信息设计——使输入对大语言模型来说尽可能易于消化。
让我们直接面对批评。许多经验丰富的开发者认为“上下文工程”要么是换了层皮的提示词工程,要么更糟,是伪科学的流行词创造。这些担忧并非空穴来风。传统的提示词工程专注于你给大语言模型的指令。而上下文工程则涵盖了整个信息生态系统:动态数据检索、内存管理、工具编排,以及跨多轮交互的状态维护。当前许多 AI 工作确实缺乏我们期望于工程学科的那种严谨性。有太多的试错,太少的衡量,以及不充分的系统化方法论。说实话:即使有完美的上下文工程,大语言模型仍然会产生幻觉,犯逻辑错误,并在复杂推理上失败。上下文工程并非万能灵药——它是在当前约束下的损害控制与优化。
•管理状态和记忆:许多应用涉及多轮交互或长时间运行的会话。上下文窗口不是无限的,因此上下文工程的一个主要部分是决定如何处理对话历史或中间结果。一个常见的技术是摘要压缩——每几次交互后,对其进行总结,并使用该摘要继续,而不是全文。例如,Anthropic 的 Claude 助手在对话变长时会自动这样做,以避免上下文溢出(你会看到它生成一个“[先前讨论的摘要]”来浓缩早期的轮次)。另一种策略是明确地将重要事实写入外部存储(文件、数据库等),然后在需要时检索它们,而不是在每个提示词中都带着它们。这就像一个外部记忆。一些先进的智能体框架甚至让大语言模型生成“给自己的笔记”,这些笔记被存储起来,并可以在未来的步骤中被回忆起来。这里的艺术在于弄清楚保留什么、何时总结,以及如何在正确的时机重新呈现过去的信息。做得好,它能让 AI 在非常长的任务中保持连贯性——这是纯粹的提示词工程难以做到的。
•工具使用和环境上下文:现代 AI 智能体可以使用工具(例如,调用 API、运行代码、浏览网页)作为其操作的一部分。当它们这样做时,每个工具的输出都成为下一次模型调用的新上下文。在这种情况下,上下文工程意味着指导模型何时以及如何使用工具,然后将结果反馈回来。例如,一个智能体可能有一条规则:“如果用户问一个数学问题,调用计算器工具。” 使用后,结果(比如 42)被插入到提示词中:“工具输出:42。” 这需要清晰地格式化工具输出,并可能添加一个后续指令,如“根据这个结果,现在回答用户的问题。” 智能体框架(如 LangChain 等)中的大量工作本质上是围绕工具使用的上下文工程——给模型一个可用工具的列表、调用它们的语法指南,以及如何整合结果的模板。关键在于,你,作为工程师,编排了模型与外部世界之间的这种对话。
•问题分解和控制流:稳健的系统通常不是将用户查询视为一个单一的庞大提示词,而是将问题分解为子任务或多步工作流。例如,一个 AI 智能体可能首先被提示概述一个计划,然后在后续步骤中被提示执行每一步。设计这个流程(以什么顺序调用哪些提示词,如何决定分支或循环)是一个经典的编程任务——只不过这里的“函数”是带有上下文的大语言模型调用。上下文工程在这里的作用是确保每一步的提示词都有所需的信息,但决定要有步骤本身是一个更高层次的设计。这就是为什么你会看到一些框架,你基本上是在编写一个协调多个大语言模型调用和工具使用的脚本。
•模型选择和路由:你可能会为不同的工作使用不同的 AI 模型。也许一个轻量级模型用于简单任务或初步回答,一个重量级模型用于最终解决方案。或者一个代码专用模型用于编码任务,而一个通用模型用于对话任务。系统需要逻辑来将请求路由到适当的模型。每个模型可能有不同的上下文长度限制或格式要求,上下文工程必须考虑到这些(例如,为一个较小的模型更积极地截断上下文)。这方面更多是工程而非提示:可以把它看作是为工作匹配合适的工具。
•工具集成和外部操作:如果你的 AI 可以执行操作(如调用 API、数据库查询、打开网页、运行代码),你的软件需要管理这些能力。这包括为 AI 提供可用工具的列表和使用说明,以及实际执行这些工具调用并捕获结果。正如我们讨论的,结果随后成为进一步模型调用的新上下文。从架构上讲,这意味着你的应用通常有一个循环:提示模型 -> 如果模型输出指示使用工具 -> 执行工具 -> 整合结果 -> 再次提示模型。可靠地设计这个循环是一个挑战。
•护栏和安全:在生产环境中,你必须考虑滥用和错误。这可能包括内容过滤器(以防止有毒或敏感的输出)、工具的身份验证和权限检查(这样 AI 就不会因为指令里有就删除数据库),以及对输出的验证。有些设置使用第二个模型或规则来复核第一个模型的输出。例如,在主模型生成答案后,你可能会运行另一个检查:“这个答案是否包含任何敏感信息?如果是,请编辑掉。”这些检查本身可以用提示词或代码来实现。在任何情况下,它们通常都会在上下文中添加额外的指令(比如一个系统消息:“如果用户要求不允许的内容,请拒绝。”是许多已部署提示词的一部分)。所以上下文可能总是包含一些安全样板。平衡这一点(确保模型遵守政策而不损害帮助性)是这个拼图的又一块。
•评估和监控:不用说,你需要不断监控 AI 的表现。记录每个请求和响应(在用户同意和保护隐私的前提下)可以让你分析失败和异常值。你可能会整合实时评估——例如,根据某些标准对模型的答案进行评分,如果分数低,就自动让模型重试或转交人工处理。虽然评估不属于生成单个提示词内容的一部分,但它会随着时间的推移反馈到改进提示词和上下文策略上。本质上,你把提示词和上下文组装当作可以利用生产数据进行调试和优化的东西。
我们实际上在谈论的是一种新型的应用架构。在这种架构中,核心逻辑涉及管理信息(上下文)并通过一系列 AI 交互来适应它,而不仅仅是运行确定性函数。Karpathy 列出了控制流、模型调度、内存管理、工具使用、验证步骤等元素,这些都在上下文填充之上。它们共同构成了他戏称为 AI 应用的“一个正在兴起的厚重软件层”——厚重是因为它做了很多事!当我们构建这些系统时,我们本质上是在编写元程序:编排另一个“程序”(AI 的输出)来解决任务的程序。
• 我们在代码中重视模块化和抽象。现在我们实际上是将任务抽象到高层次(描述任务,给出示例,让 AI 实现),并构建 AI + 工具的模块化管道。我们是在编排组件(一些是确定性的,一些是 AI),而不是自己编写所有逻辑。
• 我们在传统开发中实践测试和迭代。现在我们正将同样的严谨性应用于 AI 行为,编写评估并改进提示词,就像在性能分析后改进代码一样。
在拥抱上下文工程时,你实际上是在说:我,作为开发者,对 AI 的行为负责。它不是一个神秘的预言家;它是我需要用正确的数据和规则来配置和驱动的一个组件。
这种心态的转变是赋能的。它意味着我们不必将 AI 视为不可预测的魔法——我们可以用扎实的工程技术(加上一点创造性的提示词艺术)来驯服它。
实际上,你如何在工作中采纳这种以上下文为中心的方法呢?
•投资于数据和知识管道。上下文工程的一大部分是拥有可注入的数据。所以,去构建你的文档的向量搜索索引,或者设置你的智能体可以使用的数据库查询。将知识源视为开发中的一等公民。例如,如果你的 AI 助手是用于编码的,请确保它可以从代码仓库中拉取代码或参考风格指南。你从 AI 中获得的大量价值来自于你提供给它的外部知识。
•监控和检测一切。在生产环境中,记录输入和输出(在隐私限制内),以便你以后可以分析它们。使用可观察性工具(如 LangSmith 等)来追踪每个请求的上下文是如何构建的。当输出不好时,追溯并查看模型看到了什么——是否缺少了什么?是否有东西格式不佳?这将指导你的修复。本质上,将你的 AI 系统视为一个有点不可预测的服务,你需要像监控任何其他服务一样监控它——提示词使用情况、成功率等的仪表板。
•让用户参与其中。上下文工程不仅仅是关于机器对机器的信息;它最终是关于解决用户的问题。通常,如果以正确的方式提问,用户可以提供上下文。考虑那些 AI 提出澄清问题或用户可以提供额外细节来完善上下文(如附加文件,或选择哪个代码库部分是相关的)的用户体验设计。术语“AI 辅助”是双向的——AI 辅助用户,但用户可以通过提供上下文来辅助 AI。一个设计良好的系统会促进这一点。例如,如果一个 AI 答案是错误的,让用户纠正它,并将该纠正反馈到下一次的上下文中。
•培训你的团队(和你自己)。使上下文工程成为一个共享的纪律。在代码审查中,也开始审查提示词和上下文逻辑(“这个检索是否抓取了正确的文档?这个提示词部分是否清晰无歧义?”)。如果你是技术负责人,鼓励团队成员提出 AI 输出的问题,并集思广益,探讨如何通过调整上下文来解决它。知识共享是关键,因为这个领域是新的——一个人发现的一个聪明的提示词技巧或格式化见解很可能对其他人有益。我个人就从阅读他人的提示词示例和 AI 失败的事后分析中学到了很多。
随着我们前进,我预计上下文工程将成为第二天性——就像今天编写 API 调用或 SQL 查询一样。它将成为软件开发标准技能的一部分。已经有很多人在为问题抓取上下文时,进行快速的向量相似性搜索已经不再三思;这只是流程的一部分。几年后,“你把上下文设置好了吗?”将成为和“你处理好那个 API 响应了吗?”一样常见的代码审查问题。
在拥抱这一新范式时,我们并非抛弃旧的工程原则——我们是以新的方式重新应用它们。如果你花了多年时间磨练你的软件技艺,那份经验现在非常宝贵:它让你能够设计合理的流程,发现边缘情况,确保正确性。AI 并没有让这些技能过时;它放大了它们在指导 AI 中的重要性。软件工程师的角色并没有减弱——它正在演变。我们正在成为 AI 的导演和编辑,而不仅仅是代码的编写者。而上下文工程就是我们有效指导 AI 的技术。
开始从你提供给模型的信息的角度思考,而不仅仅是你问什么问题。去实验它,迭代它,并分享你的发现。通过这样做,你不仅能从今天的 AI 中获得更好的结果,而且你也在为即将到来的更强大的 AI 系统做好准备。那些懂得如何喂养 AI 的人将永远拥有优势。