LangChain:调用工具Ⅲ

绑定工具Ⅱ中,我们通过 model.bind_tools(tools) 得到了一个 Runnable 实例 model_with_tools。这个实例就像一个普通的聊天模型,可以接受消息并给出回复,但它多了一个能力:在需要的时候,回复中会包含工具调用的请求

本篇文章会聚焦在一个完整的调用流程上:定义工具 → 绑定模型 → 用 .invoke() 触发调用 → 解读返回的 AIMessage


1、准备工具:用 @tool 装饰器定义函数

python 复制代码
from langchain_openai import ChatDeepSeek
from langchain.core.messages import HumanMessage
from langchain.core.tools import tool
from typing_extensions import Annotated

# 定义大模型
model = ChatDeepSeek(model="deepseek-chat")

@tool
def add(
    a: Annotated[int, "First integer"],
    b: Annotated[int, "Second integer"]
) -> int:
    """Add two integers."""
    return a + b

@tool
def multiply(
    a: Annotated[int, "First integer"],
    b: Annotated[int, "Second integer"]
) -> int:
    """Multiply two integers."""
    return a * b

关于 Annotated
Annotated[int, "First integer"] 这种写法告诉 LangChain 这个参数的类型是 int,并且附加了人类可读的描述 "First integer"。这样在生成工具调用的 JSON Schema 时,模型就能更准确地理解每个参数的含义。

现在,addmultiply 已是两个标准的 LangChain 工具对象,可以被 bind_tools() 识别。


2、绑定并调用

python 复制代码
tools = [add, multiply]
model_with_tools = model.bind_tools(tools)

# 调用工具
result = model_with_tools.invoke("9乘6等于多少?")
print(result)

这里的关键是 .invoke()。我们直接传了一个中文问题 "9乘6等于多少?",模型需要判断:

  1. 这个问题是否需要工具?

  2. 如果需要,选哪个工具?

  3. 调用该工具时需要什么参数?

结果 result 是一个 AIMessage 对象:

python 复制代码
AIMessage(
    content='',
    additional_kwargs={
        'tool_calls': [{
            'id': 'call_mbNxNYVfA0rExEETcdECG1',
            'function': {'name': 'multiply', 'arguments': {'a': 9, 'b': 6}},
            'type': 'function'
        }],
        'refusal': None
    },
    response_metadata={
        'token_usage': { ... },
        'model_name': 'deepseek-chat',
        'finish_reason': 'tool_calls',
        ...
    },
    id='run--1f43e942-d5bb-46dd-8df3-f45b75ed0836-0',
    tool_calls=[{
        'name': 'multiply',
        'args': {'a': 9, 'b': 6},
        'id': 'call_mbNxNYVfA0rExEETcdECG1',
        'type': 'tool_call'
    }],
    usage_metadata={'input_tokens': 86, 'output_tokens': 17, 'total_tokens': 103}
)

content (消息正文)

  • 值为空字符串 ''

  • 表示模型这次没有生成文本回复 ,而是直接选择调用工具。如果模型想同时给出文字说明,content 中就会包含那段话。

additional_kwargs

  • 这是附加的有效负载数据,通常由模型提供程序直接编码。

  • 其中的 tool_calls 是一个列表,包含了模型计划调用的工具信息:

    • id:这次工具调用的唯一标识。

    • function{'name': 'multiply', 'arguments': {'a': 9, 'b': 6}},指出要调用的函数名及参数。

    • type'function',固定表示函数调用。

response_metadata

  • 存放响应的元数据,例如:

    • token_usage:本次请求消耗的 token 数。

    • model_name:实际作答的模型版本。

    • finish_reason:结束原因,这里是 'tool_calls',说明模型因要调用工具而停止生成。这也是我们判断是否需要进行工具调用的一个重要标志。

tool_calls (最常用)

  • LangChain 为了方便开发者,直接解析了 additional_kwargs 中的工具调用信息,放在了顶层的 tool_calls 属性里。

  • 它是一个列表,每个元素是一个字典,包含:

    • name:工具名('multiply')。

    • args:参数字典({'a': 9, 'b': 6})。

    • id:调用唯一 ID。

    • type:类型。

  • 实战中我们通常直接使用 result.tool_calls 来获取工具调用请求 ,而不必手动钻入 additional_kwargs

usage_metadata

  • 统计了本次调用的 token 使用情况,方便计费和性能监控。
字段 含义 关键作用
content 模型的文本回复 为空字符串 '' 表示模型这次没有生成文本回复,而是直接选择调用工具。如果模型想同时给出文字说明,这里会包含对应的文本。
additional_kwargs 附加的有效负载数据 由模型提供程序直接编码,其中的 tool_calls 列表包含了模型计划调用的工具信息。
tool_calls LangChain 解析后的工具调用信息 最常用的字段,直接包含了工具名、参数和调用 ID,实战中通常用 result.tool_calls 获取调用请求。
response_metadata 响应的元数据 包含 token_usage(本次请求消耗的 token 数)、model_name(实际作答的模型版本)、finish_reason(结束原因)。其中 finish_reason='tool_calls' 是关键标志,说明模型因要调用工具而停止生成。
usage_metadata token 使用统计 方便计费和性能监控,和 response_metadata 中的 token_usage 信息一致。

3、小结

通过 .bind_tools() + .invoke(),我们让模型从"纯聊天"升级为"能主动提出工具调用需求"的智能体。返回的 AIMessage 中,tool_calls 是核心字段,它明确指出了要调用的函数名和参数。

相关推荐
醉舞经阁半卷书12 小时前
深入掌握LangChain
python·langchain
CDN3602 小时前
[硬核] 你的DNS正在“裸奔”?用Python手撕DNS劫持与隧道检测逻辑
开发语言·网络·python
kybs19912 小时前
springboot视频推荐系统--附源码72953
java·spring boot·python·eclipse·asp.net·php·idea
BU摆烂会噶3 小时前
【LangGraph】运行时上下文(Runtime Context)
人工智能·python·langchain
xingbuxing_py4 小时前
精华贴分享|北交所:小市值策略的“甜蜜陷阱”还是“弹性引擎”?——一份轻度理解
python·金融·股票·理财·量化投资·股市·炒股
yj15584 小时前
在装修预算有限的情况下,哪些地方可以省?
python
Aision_4 小时前
LangGraph 中 State、Node、Edge 是怎么协作的?
langchain·prompt·aigc·embedding·ai编程·ai写作·agi
TickDB4 小时前
Python 接入国内期货 Tick 行情:从 CTP 到统一 API 的工程实践
python·websocket
趣知岛4 小时前
2026最新Python零基础入门教程,从环境搭建到实战精通(附源码)
python·青少年编程