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

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

示例:摘要
最常见的生命周期模式之一,是在对话历史过长时自动进行压缩。与模型上下文中展示的临时消息修剪不同,摘要会持久化地更新状态——即用摘要永久替换旧消息,并保存下来供所有后续对话轮次使用。 LangChain 为此提供了内置中间件:SummarizationMiddleware 会自动:
- 使用单独的 LLM 调用总结较早的消息
- 在 State 中用一条摘要消息永久替换它们
- 保留最近的消息完整以提供上下文
要查看内置中间件、可用钩子以及如何创建自定义中间件的完整列表,请参阅 Middleware 文档。
最佳实践
- 从简单开始 - 从静态提示和工具入手,仅在必要时添加动态功能
- 逐步测试 - 一次只添加一个上下文工程特性
- 监控性能 - 跟踪模型调用、令牌使用量和延迟
- 使用内置中间件 - 利用
SummarizationMiddleware、LLMToolSelectorMiddleware等 - 记录你的上下文策略 - 明确说明传递了哪些上下文以及为什么传递
- 理解瞬时与持久化的区别:模型上下文的更改是瞬时的(每次调用),而生命周期上下文的更改会持久化到状态中
相关资源
- Context conceptual overview - Understand context types and when to use them
- Middleware - Complete middleware guide
- Tools - Tool creation and context access
- Memory - Short-term and long-term memory patterns
- Agents - Core agent concepts