Tools | 产品经理学Langchian

内容纲要

Tools 定位:扩展模型能力 → 让 Agent “能行动”

  • 创建方式:<code>@tool</code>、自定义名称描述、Pydantic/JSON schema、保留参数约束
  • Server-side tool use:OpenAI/Anthropic/Gemini 等内置
  • 运行时上下文:<code>ToolRuntime</code> 访问 state/context/store/stream/config/tool_call_id
  • 状态更新:使用 <code>Command</code> 修改 Graph state(如清空历史)
  • 存储:<code>runtime.store</code> 读写长期记忆
  • Streaming:<code>runtime.stream_writer</code> 实时推送执行进度
  • 关联模块:Agents(路由调用)、Messages(ToolMessage 回写)、Models(tool calling 能力)

概述

Tools 工具是 Agent 调用外部 API/数据库/文件系统的标准封装,包含函数本体 + 输入 schema,帮助模型以结构化方式触发操作。

Tools 工具通过让模型能够借助定义明确的输入和输出来与世界交互,从而扩展了模型的能力。工具封装了一个可调用的函数及其输入模式。这些可以传递给兼容的聊天模型,使模型能够决定是否调用工具以及使用哪些参数。在这些场景中,工具调用使模型能够生成符合指定输入模式的请求。

产品经理在PRD 需明确:可暴露的工具列表、输入输出字段、错误策略、运行时上下文(ToolRuntime)与合规限制。

工具定义

LangChain 既支持本地自建工具(<code>@tool</code> 装饰器/Pydantic schema)也支持部分模型自带的 server-side 工具(如搜索、代码解释器)。

创建工具最简单的方法是使用<code>@tool</code>装饰器;装饰器可自行询问大模型Python语法。默认情况下,函数的文档字符串会成为工具的描述,帮助模型了解何时使用该工具。如:

@tool
def search_database(query: str, limit: int = 10) -&gt; str:  # 类型提示:
    &quot;&quot;&quot;Search the customer database for records matching the query.&quot;&quot;&quot;
    # - query: str → 参数 query 类型为字符串
    # - limit: int = 10 → 参数 limit 类型为整数(默认值 10)
    # - -&gt; str → 函数返回值类型为字符串
    return f&quot;Found {limit} results for &#039;{query}&#039;&quot;

代码中对输入进行了很详细的约定,这些类型提示是必需的,因为它们定义了工具的输入模式,又比如:

类型提示形式 作用
<code>参数名: 基础类型</code>(如 <code>str</code>、<code>int</code>) 限定简单参数的类型
<code>-> 返回值类型</code>(如 <code>-> str</code>) 限定函数返回值的类型
<code>Literal["a", "b"]</code> 限定参数仅允许特定枚举值
<code>Pydantic 模型字段类型</code>(如 <code>location: str</code>) 定义复杂结构化输入的类型
<code>ToolRuntime</code> / <code>ToolRuntime[Ctx]</code> 标注上下文参数的类型(关联状态 / 内存)
<code>dict[str, Any]</code> 等复合类型 限定复杂参数(如字典)的结构

工具当然支持自定义,包括名字、参数等。

访问上下文

工具只是简单的一来一去的调研的确很简单,但复杂的Agent中工具的使用需要与上下文进行深入的交互。当工具能够访问agent状态、运行时上下文和长期记忆时,工具就能够做出具有上下文感知的决策、个性化响应,并在对话中保持信息的连贯性。Runtime context运行时上下文提供了一种在运行时将依赖项(如数据库连接、用户ID或配置)注入工具的方法,这使得工具更易于测试和重用。

工具可以通过<code>ToolRuntime</code>参数访问运行时信息,该参数提供:

信息类别 核心作用 示例
State(状态) 存储工具执行过程中动态变化的临时数据,数据生命周期与当前流程绑定 统计当前对话中用户提问次数:从 State 读取对话消息列表,筛选用户消息计数,计数结果暂存回 State
Context(上下文) 提供不可修改的基础配置,为工具提供身份识别、场景约束等固定信息 根据 Context 中的 “用户账户类型” 判断权限:Premium 用户可查看详细账单,Standard 用户需升级后查看
Store(存储) 跨对话持久化保存数据,实现信息在多次对话中的复用 用户设置 “温度单位为华氏度” 后存入 Store,下次查询天气时,工具自动从 Store 读取该偏好并应用
Stream Writer(流编写器) 工具执行中实时推送中间状态,避免用户等待时的信息空白,提升交互体验 查询大型数据库时,实时推送 “开始执行查询→已连接数据库→正在整理结果” 等进度反馈
Config(配置) 提供框架级执行参数,控制工具执行规则(如超时、重试),保障执行稳定性 调用外部 API 时,从 Config 读取 “15 秒超时设置”,若 15 秒内未响应则终止调用并提示超时
Tool Call ID(工具调用 ID) 唯一标识单次工具调用,用于区分多次调用、追踪执行链路、排查问题 用户一次对话中两次查询天气:通过 “tool_call_111”“tool_call_222” 两个 ID,分别关联两次调用的日志和结果

<img src="https://ymmcheer-1257617206.cos.ap-nanjing.myqcloud.com/typora/image-20251124225408587.png" alt="image-20251124225408587" style="zoom: 50%;" />

该部分的内容涉及Langgragh的细节,建议可先初步了解,在后续Langgragh中进行深入研究。

需求关注点

模块 关键信息 产品关注
Tool 定义 使用 <code>@tool</code> 将 Python 函数暴露给模型,docstring 即说明书 需求需列出工具清单+用途说明,方便模型理解
自定义命名/描述 <code>@tool("web_search", description="...")</code> 当函数名不直观时必须自定义,保持业务语义
Schema Type hints 必填;复杂输入用 Pydantic/JSON schema PRD 中要定义字段类型、是否必填、默认值
保留参数 <code>config</code>、<code>runtime</code> 禁止作为 tool 形参,只能通过 <code>ToolRuntime</code> 获取 避免开发时撞保留字导致 runtime error
Server-side 工具 部分模型自带搜索/代码工具,在云端执行 需确认供应商支持度及敏感数据是否允许出站
ToolRuntime 统一入口:state(消息等)、context(用户 ID)、store(长记忆)、stream_writer、config、tool_call_id 明确哪些上下文需要注入,如用户权限、Session
State/Command 工具可返回 <code>Command(update=...)</code> 修改图状态或清空消息 PRD 描述允许的状态操作及安全限制
Store <code>runtime.store</code> 支持跨会话记忆读写 指定存储范围、加密要求与淘汰策略
Streaming <code>runtime.stream_writer</code> 持续输出自定义日志 UI 需支持实时展示工具执行进度

适用场景(问题 → 方案 → 价值)

  1. 订单查询助手
    • 问题:客服 Bot 需实时查询订单状态并在多轮对话中引用结果。
    • 方案:用 Pydantic schema 定义 <code>query_order</code> 工具(字段:order_id、need_history);在 ToolRuntime 中获取当前用户 ID 写入审计。
    • 价值:模型调用结构化接口,避免自由文本错误,日志可追踪“谁查了哪笔订单”。
  2. 合规问答 + 服务器端执行
    • 问题:某些数据只能在企业内网执行,不允许模型直接访问。
    • 方案:封装 server-side tool,模型只发出调用请求,工具在后端执行并返回结果;若失败通过 ToolMessage 通知。
    • 价值:隔离敏感数据,满足合规要求,同时保留智能问答体验。

常见问题(FAQ)

  1. 工具与函数调用有何区别?→ Tools 自带 schema 与描述,Agent 可根据上下文选择调用并解析结构化结果。
  2. docstring 真的重要吗?→ 模型依赖描述判断是否调用工具,PRD 需提供清晰易懂的用途说明。
  3. 可以使用复杂输入吗?→ 是,推荐用 Pydantic/JSON schema 定义嵌套字段与枚举。
  4. 为什么 <code>runtime</code> 不能作为参数?→ 该名称保留给 LangChain,真实上下文需通过 <code>ToolRuntime</code> 注入,否则报错。
  5. 如何访问当前会话消息?→ 在工具中通过 <code>runtime.state["messages"]</code> 读取,便于总结或诊断。
  6. 可以更新状态吗?→ 返回 <code>Command(update=...)</code> 修改 Graph state,例如清除历史或更新用户信息。
  7. 如何读写长期记忆?→ 使用 <code>runtime.store</code> 以键值形式存储用户配置或偏好。
  8. 工具执行可实时反馈吗?→ 可以,<code>runtime.stream_writer</code> 用于流式输出,如“正在调用 CRM…”。
  9. Server-side 工具如何接入?→ 依赖供应商(OpenAI/Anthropic 等)提供的 built-in tool 接口,需配置对应模型。
  10. 工具出错时如何提示模型?→ 返回标准异常或结果字符串,Agent 会生成 ToolMessage;PRD 中需描述重试与降级策略。

扩展信息

滚动至顶部