概览
构建智能体(或任何 LLM 应用)的困难部分是使它们足够可靠。虽然它们可能适用于原型,但在现实用例中经常会失败。智能体为何失败?
当智能体失败时,通常是因为智能体内部的 LLM 调用采取了错误的操作/没有执行我们预期的操作。LLM 因以下两个原因之一失败:- 底层 LLM 能力不够
- “正确”的上下文没有传递给 LLM
智能体循环
典型的智能体循环由两个主要步骤组成:- 模型调用- 使用提示和可用工具调用 LLM,返回响应或执行工具的请求
- 工具执行- 执行 LLM 请求的工具,返回工具结果
你可以控制什么
要构建可靠的智能体,您需要控制智能体循环的每个步骤以及步骤之间发生的情况。瞬态上下文
LLM 在单次调用中看到的内容。你可以修改消息、工具或提示,而不改变状态中保存的内容。
持久上下文
各个回合中状态中保存的内容。生命周期钩子和工具写入会永久修改这一点。
数据来源
在整个过程中,您的智能体访问(读取/写入)不同的数据源:| 数据来源 | 也称为 | 范围 | 示例 |
|---|---|---|---|
| 运行时上下文 | 静态配置 | 对话范围 | 用户 ID、API 密钥、数据库连接、权限、环境设置 |
| 状态 | 短期记忆 | 对话范围 | 当前消息、上传的文件、身份验证状态、工具结果 |
| 存储 (Store) | 长期记忆 | 交叉对话 | 用户偏好、提取的见解、记忆、历史数据 |
它是如何运作的
LangChain中间件是使上下文工程对于使用 LangChain 的开发人员来说变得实用的底层机制。 中间件允许您连接到智能体生命周期中的任何步骤,并且:- 更新上下文
- 跳转到智能体生命周期中的不同步骤
模型上下文
控制每个模型调用的内容 - 指令、可用工具、使用哪个模型以及输出格式。这些决策直接影响可靠性和成本。系统提示
开发人员向 LLM 发出的基本指示。
消息
发送给 LLM 的完整消息列表(对话历史记录)。
工具
智能体可以访问以采取操作的实用程序。
模型
要调用的实际模型(包括配置)。
响应格式
模型最终响应的架构规范。
系统提示
系统提示设置 LLM 的行为和能力。不同的用户、上下文或对话阶段需要不同的指令。成功的智能体利用记忆、偏好和配置来为当前对话状态提供正确的指令。-
状态
-
存储 (Store)
-
运行时上下文
从状态访问消息计数或对话上下文:
消息
消息构成发送给 LLM 的提示。 管理消息内容至关重要,以确保 LLM 拥有正确的信息来做出良好的回应。-
状态
-
存储 (Store)
-
运行时上下文
当与当前查询相关时,从 State 注入上传的文件上下文:
工具
工具允许模型与数据库、API 和外部系统交互。如何定义和选择工具直接影响模型能否有效完成任务。定义工具
每个工具都需要一个清晰的名称、描述、参数名称和参数描述。这些不仅仅是元数据,它们指导模型关于何时以及如何使用该工具的推理。选择工具
并非每种工具都适合每种情况。太多的工具可能会压垮模型(超载上下文)并增加错误;太少限制了能力。动态工具选择根据身份验证状态、用户权限、功能标志或对话阶段来调整可用的工具集。-
状态
-
存储 (Store)
-
运行时上下文
仅在某些对话里程碑后启用高级工具:
模型
不同的模型有不同的优势、成本和上下文窗口。为手头的任务选择正确的模型, 在智能体运行期间可能会发生变化。-
状态
-
存储 (Store)
-
运行时上下文
根据州的对话长度使用不同的模型:
响应格式
结构化输出将非结构化文本转换为经过验证的结构化数据。当提取特定字段或为下游系统返回数据时,自由格式文本是不够的。 工作原理:当您提供架构作为响应格式时,模型的最终响应将保证符合该架构。智能体运行模型/工具调用循环,直到模型完成调用工具,然后将最终响应强制转换为提供的格式。定义格式
模式定义指导模型。字段名称、类型和描述准确指定输出应遵循的格式。选择格式
动态响应格式选择根据用户偏好、对话阶段或角色来调整模式——尽早返回简单格式,并随着复杂性的增加而返回详细格式。-
状态
-
存储 (Store)
-
运行时上下文
根据对话状态配置结构化输出:
工具上下文
工具的特殊之处在于它们可以读取和写入上下文。 在最基本的情况下,当工具执行时,它会接收 LLM 的请求参数并返回工具消息。该工具完成其工作并产生结果。 工具还可以获取模型的重要信息,使其能够执行和完成任务。读
大多数现实世界的工具需要的不仅仅是 LLM 的参数。它们需要用于数据库查询的用户 ID、用于外部服务的 API 密钥或当前会话状态来做出决策。工具从状态、存储和运行时上下文中读取以访问此信息。-
状态
-
存储 (Store)
-
运行时上下文
读取State来检查当前会话信息:
写
工具结果可用于帮助智能体完成给定的任务。工具都可以将结果直接返回给模型 并更新智能体的内存,以便为未来的步骤提供重要的上下文。-
状态
-
存储 (Store)
使用命令写入状态以跟踪特定于会话的信息:
生命周期上下文
控制发生的事情之间核心智能体步骤 - 拦截数据流以实现横切关注点,例如汇总、护栏和日志记录。 正如您所见模型上下文和工具上下文 , 中间件是使上下文工程变得实用的机制。中间件允许您连接到智能体生命周期中的任何步骤,并且:- 更新上下文- 修改状态和存储以保存更改、更新对话历史记录或保存见解
- 生命周期跳跃- 根据上下文移动到智能体循环中的不同步骤(例如,如果满足条件,则跳过工具执行,使用修改后的上下文重复模型调用)
示例:总结
最常见的生命周期模式之一是在对话历史过长时自动压缩。与模型上下文中展示的瞬态消息裁剪不同,摘要会持续更新状态——用为未来各轮保存的摘要永久替换旧消息。 LangChain为此提供了内置中间件:
SummarizationMiddleware
自动地:
- 使用单独的 LLM 调用总结旧消息
- 将它们替换为状态中的摘要消息(永久)
- 保持最近消息的上下文完整
有关内置中间件、可用挂钩以及如何创建自定义中间件的完整列表,请参阅中间件文档
.
最佳实践
- 从简单开始- 从静态提示和工具开始,仅在需要时添加动态
- 增量测试- 一次添加一项上下文工程功能
- 监控性能- 跟踪模型调用、令牌使用情况和延迟
-
使用内置中间件- 杠杆作用
SummarizationMiddleware,LLMToolSelectorMiddleware, ETC。 - 记录您的情境策略- 明确正在传递的上下文以及原因
- 了解瞬态与持久:模型上下文更改是暂时的(每次调用),而生命周期上下文更改会持续到状态