概述
构建智能体(或任何大语言模型(LLM)应用)的难点在于让它们足够可靠。虽然它们在原型阶段可能有效,但在实际使用场景中往往会失败。为什么智能体会失败?
当智能体失败时,通常是因为智能体内部的 LLM 调用采取了错误的操作/没有按照我们的预期执行。LLM 失败的原因有两个:- 底层 LLM 能力不足
- 没有向 LLM 传递”正确的”上下文
智能体循环
典型的智能体循环包含两个主要步骤:- 模型调用 - 使用提示词和可用工具调用 LLM,返回响应或执行工具的请求
- 工具执行 - 执行 LLM 请求的工具,返回工具结果

你可以控制什么
要构建可靠的智能体,你需要控制智能体循环中每个步骤发生的事情,以及步骤之间发生的事情。瞬态上下文
LLM 在单次调用中看到的内容。你可以修改消息、工具或提示词,而不改变保存在状态中的内容。
持久上下文
跨轮次保存在状态中的内容。生命周期钩子和工具写入会永久修改它。
数据源
在整个过程中,你的智能体会访问(读/写)不同的数据源:工作原理
LangChain 中间件是底层机制,使上下文工程对使用 LangChain 的开发者来说变得实用。 中间件允许你钩入智能体生命周期的任何步骤,并:- 更新上下文
- 跳转到智能体生命周期的不同步骤
模型上下文
控制每次模型调用中包含的内容——指令、可用工具、使用哪个模型以及输出格式。这些决策直接影响可靠性和成本。系统提示词
开发者给 LLM 的基本指令。
消息
发送给 LLM 的完整消息列表(对话历史)。
工具
智能体可用于执行操作的工具。
模型
要调用的实际模型(包括配置)。
响应格式
模型最终响应的 schema 规范。
系统提示词
系统提示词设置 LLM 的行为和能力。不同的用户、上下文或对话阶段需要不同的指令。成功的智能体会利用记忆、偏好和配置来为当前对话状态提供正确的指令。- 状态
- 存储
- 运行时上下文
从状态中访问消息数量或对话上下文:
消息
消息组成发送给 LLM 的提示词。 管理消息的内容至关重要,以确保 LLM 拥有正确的信息来做出良好的响应。- 状态
- 存储
- 运行时上下文
当与当前查询相关时,从状态中注入上传的文件上下文:
工具
工具让模型与数据库、API 和外部系统交互。你如何定义和选择工具直接影响模型是否能有效完成任务。定义工具
每个工具需要清晰的名称、描述、参数名称和参数描述。这些不仅仅是元数据——它们指导模型关于何时以及如何使用工具的推理。选择工具
并非每个工具都适合每种情况。太多的工具可能会让模型不堪重负(上下文过载)并增加错误;太少则限制能力。动态工具选择可以根据认证状态、用户权限、功能标志或对话阶段来调整可用的工具集。- 状态
- 存储
- 运行时上下文
仅在达到特定对话里程碑后启用高级工具:
模型
不同的模型有不同的优势、成本和上下文窗口。为当前任务选择合适的模型,这在智能体运行期间可能会发生变化。- 状态
- 存储
- 运行时上下文
根据状态中的对话长度使用不同的模型:
响应格式
结构化输出将非结构化文本转换为经过验证的结构化数据。当提取特定字段或为下游系统返回数据时,自由格式的文本是不够的。 工作原理: 当你提供 schema 作为响应格式时,模型的最终响应保证符合该 schema。智能体运行模型/工具调用循环,直到模型完成工具调用,然后最终响应被强制转换为提供的格式。定义格式
Schema 定义指导模型。字段名称、类型和描述指定了输出应该遵循的确切格式。选择格式
动态响应格式选择可以根据用户偏好、对话阶段或角色来调整 schema——在早期返回简单格式,随着复杂度增加返回详细格式。- 状态
- 存储
- 运行时上下文
根据对话状态配置结构化输出:
工具上下文
工具的特殊之处在于它们既读取又写入上下文。 在最基本的情况下,当工具执行时,它接收 LLM 的请求参数并返回一条工具消息。工具完成其工作并产生结果。 工具还可以为模型获取重要信息,使其能够执行和完成任务。读取
大多数真实世界的工具不仅仅需要 LLM 的参数。它们需要用户 ID 来进行数据库查询、API 密钥来访问外部服务,或当前会话状态来做决策。工具从状态、存储和运行时上下文读取以访问这些信息。- 状态
- 存储
- 运行时上下文
从状态读取以检查当前会话信息:
写入
工具结果可以用来帮助智能体完成给定的任务。工具既可以直接向模型返回结果,也可以更新智能体的记忆,使重要上下文可用于未来的步骤。- 状态
- 存储
使用 Command 写入状态以跟踪会话特定信息:
生命周期上下文
控制核心智能体步骤之间发生的事情——拦截数据流以实现横切关注点,如摘要、护栏和日志记录。 正如你在模型上下文和工具上下文中看到的,中间件是使上下文工程变得实用的机制。中间件允许你钩入智能体生命周期的任何步骤,并执行以下操作之一:- 更新上下文 - 修改状态和存储以持久化更改、更新对话历史或保存洞察
- 在生命周期中跳转 - 根据上下文移动到智能体循环的不同步骤(例如,如果满足条件则跳过工具执行,使用修改后的上下文重复模型调用)

示例:摘要
最常见的生命周期模式之一是在对话历史变得太长时自动压缩。与模型上下文中展示的瞬态消息裁剪不同,摘要持久更新状态——用为所有未来轮次保存的摘要永久替换旧消息。 LangChain 为此提供了内置中间件:SummarizationMiddleware 会自动:
- 使用单独的 LLM 调用来总结较旧的消息
- 用摘要消息替换状态中的旧消息(永久替换)
- 保持最近的消息完整以提供上下文
有关内置中间件的完整列表、可用钩子以及如何创建自定义中间件,请参阅中间件文档。
最佳实践
- 从简单开始 - 先使用静态提示词和工具,仅在需要时添加动态功能
- 增量测试 - 一次添加一个上下文工程功能
- 监控性能 - 跟踪模型调用、Token 使用量和延迟
- 使用内置中间件 - 利用
SummarizationMiddleware、LLMToolSelectorMiddleware等 - 记录你的上下文策略 - 明确说明正在传递什么上下文以及原因
- 理解瞬态与持久:模型上下文更改是瞬态的(每次调用),而生命周期上下文更改会持久化到状态
相关资源
将这些文档连接到 Claude、VSCode 等工具,通过 MCP 获取实时答案。

