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 是核心字段,它明确指出了要调用的函数名和参数。

相关推荐
java1234_小锋3 分钟前
Tornado 6.5,全面支持 Python 3.14
数据库·python·tornado
IT毕设梦工厂17 分钟前
计算机毕业设计选题推荐:基于大数据的印度上市公司财务指标数据可视化分析|毕业设计选题|计算机毕设|选题推荐|毕设指导|项目定制|源码|高质量项目
大数据·hadoop·python·信息可视化·spark·课程设计·大数据毕设项目
SEO_juper18 分钟前
你的服务器正在被 AI 爬虫“白嫖“带宽:2026 用日志把 Googlebot 和 AI 洪流分开算账(附脚本)
运维·人工智能·爬虫·python·chatgpt·seo
浩风祭月18 分钟前
GPT Image 2.5 Sunburst还是Flare?模型选型、Python接入与成本避坑
python·aigc·openai·图像生成·gpt image 2.5
泡干脆面就番茄41 分钟前
03_LBPH人脸识别算法原理与实战
python·opencv
Yanjun2i1 小时前
Agent学习记录四:多工具时如何处理
人工智能·python·学习·agent
XGeFei1 小时前
【LangChain—Advanced usage—Guardrails】
langchain
李少兄1 小时前
Java 中只有值传递吗?
java·开发语言·python
名字还没想好☜1 小时前
Spring @EventListener 事件驱动解耦实战:同步转异步、事务绑定与顺序控制
java·数据库·后端·python·spring
ellenwan20262 小时前
看到“最新 AI 量化学习”时,先让表达变清楚
人工智能·python