从静态工具到运行时上下文,让模型开始真正“做事”;这一篇也是理解 Agent 为什么不只是一个普通聊天模型的关键。
走到这一篇时,前面的模型和消息已经足够支撑"理解输入输出";现在开始补上行动能力。Tools 是 LangChain 从"会说"走向"会做"的第一步。
1. 介绍
工具能够拓展智能体的能力 —— 让它们获取实时数据、执行代码、查询外部数据库,并在现实场景中采取行动。
在底层实现中,工具是具备明确定义输入与输出的可调用函数,这些函数会被传递给对话模型 。模型会根据对话上下文判断何时调用工具,以及提供哪些输入参数。
2. 创建工具
(1) 基础工具定义
创建工具最简单的方式是使用@tool装饰器。默认情况下,函数的文档字符串会成为工具的描述,帮助模型理解何时使用该工具:
Python3
点击展开代码
展开代码
注意类型提示是必需的,因为它们定义了工具的输入架构。文档字符串应内容详实且简洁,以帮助模型理解工具的用途。
(2) 自定义工具属性
我们可以给工具添加一个别名来Override,比如:
Python3
点击展开代码
展开代码
或者自定义工具的描述:
Python3
点击展开代码
展开代码
或者再高级一点,用schema定义,同样可以用pydantic、json schema等,这里用pydantic实例:
Python3
点击展开代码
展开代码
不过注意有两个保留名称,不能用作工具参数,分别是config和runtime。config保留用于内部向工具传递RunnableConfig;runtime保留用于ToolRuntime参数(访问状态、上下文、存储)。
3. 访问上下文
当工具能够访问运行时信息(如对话历史、用户数据和持久化内存)时,其功能最为强大。本节将介绍如何在工具内部访问和更新这些信息。
工具可通过ToolRuntime参数访问运行时信息,该参数提供以下能力:
| 组件 | 描述 | 用例 |
|---|---|---|
| State | 短期内存 —— 当前对话中存在的可变数据(消息、计数器、自定义字段) | 访问对话历史,追踪工具调用次数 |
| Context | 调用时传入的不可变配置(用户 ID、会话信息) | 根据用户身份个性化响应内容 |
| Store | 长期内存 —— 跨对话持久保存的数据 | 保存用户偏好设置,维护知识库 |
| Stream Writer | 在工具执行过程中发送实时更新 | 展示耗时操作的执行进度 |
| Config | 执行所用的 RunnableConfig | 访问回调函数、标签和元数据 |
| Tool Call ID | 当前工具调用的唯一标识符 | 关联日志与模型调用中的工具调用记录 |
这张图说明了 ToolRuntime 在 LangChain 工具体系中的位置。
一次工具调用发生时,工具拿到的不只是普通参数,还可以通过 ToolRuntime 访问运行时环境中的多种资源,包括当前会话状态(State)、调用上下文(Context)、长期存储(Store)以及流式输出能力(Stream Writer)。
正因为工具可以访问这些额外信息,所以它不再只是一个简单函数,而可以演变为:
- 能感知用户和会话信息的上下文工具;
- 能依赖当前对话状态工作的有状态工具;
- 能结合长期记忆的记忆增强工具;
- 能边执行边输出进度的流式工具。
换句话说,ToolRuntime 让工具从"静态函数"升级成了"运行时感知组件"。
(1) State Access (短时记忆)
Tools可通过runtime.state访问当前对话状态:
Python3
点击展开代码
展开代码
不仅如此,还可以用Command更新智能体的状态:
Python3
点击展开代码
展开代码
(2) Context Access
上下文提供在调用时传递的不可变配置数据,可用于用户ID、会话详情或对话过程中不应更改的应用特定设置。通过runtime.context访问上下文:
Python3
点击展开代码
展开代码
(3) Store Access (长时记忆)
BaseStore提供可跨对话持久保存的存储功能。与状态(短期记忆)不同,存储中保存的数据在后续会话中依然可用。
通过runtime.store访问存储。存储采用命名空间或者key的模式来组织数据。
Python3
点击展开代码
展开代码
(4) Stream Writer
在执行过程中流式传输来自工具的实时更新。这对于在长时间运行的操作期间向用户提供进度反馈非常有用。
使用runtime.stream_writer来发送自定义更新:
Python3
点击展开代码
展开代码
4. ToolNode
ToolNode是一个预构建节点,用于在 LangGraph 工作流中执行工具。它会自动处理工具并行执行、错误处理和状态注入。这一块应该会在LangGraph中应用比较多。
这个部分主要是用于精细控制工具执行模式的自定义工作流,不然可以直接使用create_agent。换句话说,它是支撑智能体工具执行的基础组件。
由于这部分主要是LangGraph的内容,所以我将暂时跳过。
5. Tools的返回值
自定义工具@tool后,可以为工具选择不同的返回值:
- 返回string,用于生成人类可读的结果。
- 返回object,用于生成模型需要解析的结构化结果。
- 返回Command(可附带消息),用于需要写入状态的场景。
(1) String返回值
Python3
点击展开代码
展开代码
- 返回值会被转换为ToolMessage。
- 模型会读取该文本并决定下一步操作。
- 除非模型或其他工具后续修改,否则不会更改任何智能体状态字段。
如果结果是人类可阅读的样子,应该选择此种返回。
(2) Object返回值
Python3
点击展开代码
展开代码
- 该对象会被序列化后作为工具输出返回。
- 模型可读取特定字段并基于这些字段进行推理。
- 与字符串返回值类似,此操作不会直接更新图状态。
当下游推理可从显式字段而非自由格式文本中获益时,使用此方式。
(3) Command返回值
Python3
点击展开代码
展开代码
- 该命令通过update更新状态。
- 更新后的状态可在同一次运行的后续步骤中使用。
- 对于可能被并行工具调用更新的字段,请使用 reducer。
当工具不仅返回数据,还会修改智能体状态时使用此方法。
6. Prebuilt tools
LangChain 提供了大量适用于网络搜索、代码解析、数据库访问等常见任务的预制工具与工具包。这些开箱即用的工具可直接集成到你的Agent中,无需编写自定义代码。详见这里。
7. Server-side tool use
部分聊天模型具备由模型提供商在服务器端运行的内置工具。这些工具包括网络搜索、代码解释器等功能,你无需自行定义或托管工具逻辑。详见这里和这里这里。
专题阅读
LangChain
这篇文章属于同一条阅读链。你可以直接在这里切换,不用再回到列表页重新找。
部分信息可能已经过时
留言区
留言
欢迎纠错、补充、交流。昵称和评论内容必填;如果你愿意,也可以留下联系方式,仅站主可见。