标头图片来自 Dex Horthy 在 Twitter 上发布。
上下文工程是构建动态系统,以正确的格式提供正确的信息和工具,从而使 LLM 能够合理地完成任务。
大多数时候,当代理无法可靠运行时,根本原因在于未能将适当的上下文、指令和工具传达给模型。
LLM 应用正从单一提示演变为更复杂、更动态的代理系统。因此,上下文工程正成为 AI 工程师可以发展的最重要技能。
什么是上下文工程?
上下文工程是构建动态系统,以正确的格式提供正确的信息和工具,从而使 LLM 能够合理地完成任务。
这是我喜欢的定义,它建立在 Tobi Lutke、Ankur Goyal 和 Walden Yan 近期观点之上。让我们来分解一下。
上下文工程是一个系统
复杂的代理很可能从多个来源获取上下文。上下文可以来自应用程序的开发者、用户、先前的交互、工具调用或其他外部数据。将所有这些整合在一起需要一个复杂的系统。
这个系统是动态的
这些上下文的许多部分可以动态地获取。因此,构建最终提示的逻辑也需要是动态的。它不仅仅是一个静态提示。
你需要正确的信息
代理系统不工作的常见原因是它们根本没有正确的上下文。LLM 无法读心术——你需要提供正确的信息。垃圾进,垃圾出。
你需要正确的工具
LLM 并不总能仅凭输入来解决任务。在这些情况下,如果你想让 LLM 能够做到这一点,你需要确保它拥有正确的工具。这些工具可以是用于查找更多信息、执行操作或介于两者之间的任何工具。为 LLM 提供正确的工具与其提供正确的信息一样重要。
格式很重要
就像与人类沟通一样,与 LLM 的沟通方式也很重要。一条简短但描述性的错误消息比一个大的 JSON 块要有效得多。这也适用于工具。工具的输入参数在你确保 LLM 可以使用它们时非常重要。
它能合理地完成任务吗?
在考虑上下文工程时,这是一个很好的问题。它强调 LLM 不是读心者——你需要为它们成功做好准备。它还有助于区分失败模式。是失败是因为你没有提供正确的信息或工具?还是它拥有所有正确的信息,只是搞砸了?这些失败模式有非常不同的修复方法。
为什么上下文工程很重要
当代理系统出错时,很大程度上是因为 LLM 出错了。从基本原理出发,LLM 可能出于两个原因出错:
- 底层模型本身出了错,它不够好
- 底层模型没有获得适当的上下文来生成好的输出
(尤其是随着模型越来越好)大多数时候,模型错误更多是由第二个原因造成的。传递给模型的上下文可能因为几个原因而不好:
- 模型需要做出正确决策时,缺少上下文。模型不是读心者。如果你不给它们正确的上下文,它们就不会知道它的存在。
- 上下文格式不正确。就像人类一样,沟通很重要!在将数据传递给模型时,你如何格式化数据绝对会影响它的响应。
上下文工程与提示工程有何不同?
为什么从“提示”转向“上下文”?早期,开发人员专注于巧妙地措辞提示以获得更好的答案。但随着应用程序变得越来越复杂,人们越来越清楚,向 AI 提供完整且结构化的上下文比任何魔法般的措辞都重要得多。
我还认为,提示工程是上下文工程的一个子集。即使你拥有所有上下文,如何将它们组合到提示中仍然至关重要。不同之处在于,你并不是在构建提示以使其与一组静态输入数据良好配合,而是要处理一组动态数据并正确格式化它。
我还想强调,上下文的一个关键部分通常是关于 LLM 如何行为的核心指令。这通常是提示工程的关键部分。你会说,提供关于代理如何行为的清晰详细的说明是上下文工程还是提示工程?我认为两者都有点。
上下文工程的例子
一些良好的上下文工程的基本例子包括:
- 工具使用:确保代理如果需要访问外部信息,则拥有可以访问它的工具。当工具返回信息时,它们的格式对于 LLM 来说是最大程度可消化的。
- 短期记忆:如果一段对话持续了很长时间,则创建对话摘要并在将来使用它。
- 长期记忆:如果用户在先前的对话中表达了偏好,则能够获取该信息。
- 提示工程:关于代理应该如何行为的指令在提示中清楚地列出。
- 检索:动态检索信息,并在调用 LLM 之前将其插入提示。
LangGraph 如何实现上下文工程
当我们构建 LangGraph 时,我们的目标是使其成为最可控的代理框架。这也可以完美地实现上下文工程。
使用 LangGraph,你可以控制一切。你决定运行哪些步骤。你决定确切地什么进入你的 LLM。你决定在哪里存储输出。你控制一切。
这使你可以进行任何你想要的上下文工程。代理抽象(大多数其他代理框架都强调这一点)的一个缺点是它们限制了上下文工程。在某些地方,你可能无法更改确切进入 LLM 的内容,或者确切地更改之前运行的步骤。
题外话:Dex Horthy 的 “12 Factor Agents” 是一个非常好的读物。其中许多观点都与上下文工程有关(“拥有你的提示”、“拥有你的上下文构建”等)。这篇博文的标头图片也来自 Dex。我们非常欣赏他传达空间重要事物的方式。
LangSmith 如何帮助上下文工程
LangSmith 是我们的 LLM 应用可观测性和评估解决方案。LangSmith 的一个关键功能是能够 跟踪你的代理调用。虽然“上下文工程”这个词在我们构建 LangSmith 时并不存在,但它恰当地描述了这种跟踪的帮助作用。
LangSmith 允许你查看代理中发生的所有步骤。这使你可以查看收集发送到 LLM 的数据所执行的步骤。
LangSmith 允许你查看 LLM 的确切输入和输出。这使你可以确切地看到进入 LLM 的内容——它拥有的数据以及它是如何格式化的。然后,你可以调试它是否包含任务所需的所有相关信息。这包括 LLM 可以访问的工具——这样你就可以调试它是否获得了适当的工具来帮助完成当前的任务。
沟通至关重要
几个月前,我写了一篇题为 “沟通就是一切” 的博文。主要观点是与 LLM 沟通很难,并且没有得到足够的重视,而且通常是许多代理错误的根本原因。其中许多观点都与上下文工程有关!
上下文工程不是一个新想法——代理构建者在过去一两年里一直在做这件事。这是一个新术语,恰如其分地描述了一项日益重要的技能。我们将在此主题上撰写和分享更多内容。我们认为我们构建的许多工具(LangGraph、LangSmith)都非常适合实现上下文工程,因此我们很高兴看到对这一概念的重视程度不断提高。