LangChain 模型调用工具:bind_tools 与 tool_calls,模型动手能力的底层协议

简介: 本文深入剖析Agent工具调用的底层协议,聚焦`bind_tools`(工具注册与Schema生成)、`tool_calls`(模型意图的标准输出)、`ToolMessage`(结果回传闭环)三大核心机制;详解`tool_choice`五种控制模式、并行调用与`tool_call_id`对应关系;对比手动循环与`create_agent`适用场景。助你穿透“黑盒”,掌握大模型应用开发的地基能力。

摘要:Agent 很神奇,但拆开看核心只有一层协议——模型怎么"知道"有哪些工具、怎么"表达"要用哪个工具、结果怎么"送回"给它。本文把 tool calling 的底层机制一次讲透:bind_tools 绑定工具时发生了什么(四种工具定义形式与 Schema 生成);AIMessage.tool_calls 的标准结构(模型表达意图的唯一出口);tool_choice 五种模式从自由到强制的控制光谱;并行调用与 tool_call_id 的对应关系;手动执行工具循环的完整代码——这是理解 create_agent 自动循环的前提。最后回答一个关键问题:什么时候手动管理循环,什么时候交给 Agent。

关键词:LangChain、bind_tools、tool_calls、工具调用、tool_choice、ToolMessage、tool_call_id、Agent 循环、大模型应用开发


一、Agent 的魔法,拆开只有一层协议

看一个 Agent 自动查天气、查完再回答,很多人的第一反应是"模型学会动手了"。

其实没有任何魔法。模型从头到尾只做一件事:生成文本。所谓"调用工具",是模型在输出里塞了一段结构化的"意图声明"——工具名 + 参数。真正执行工具的,是外层的循环代码;执行结果,再作为消息送回模型。

这层协议有三个角色:

  1. bind_tools:告诉模型"你有哪些工具可用";
  2. tool_calls:模型表达"我想调哪个工具、传什么参数";
  3. ToolMessage:把执行结果送回模型,继续推理。

理解了这三者,Agent 就从"黑盒魔法"变成"白盒协议"。官方 LangChain 博客的原话:这套标准化接口让所有支持工具调用的模型(OpenAI、Anthropic、Gemini、Mistral……)行为完全一致——换模型不改代码。

在这里插入图片描述


二、bind_tools:把工具"注册"给模型

绑定工具只需要一行:

from langchain_core.tools import tool

@tool
def get_weather(city: str) -> str:
    """获取给定城市的当前天气。city 使用中文城市名。"""
    return f"{city} 天气晴朗,26℃"

llm_with_tools = llm.bind_tools([get_weather])

绑定瞬间发生了什么?LangChain 把工具转换成 Schema 描述(名称、描述、参数结构),随每次请求发给模型。注意:绑定不会执行任何东西,它只是让模型"看得见"这个工具。

bind_tools 接受四种工具定义形式,全部自动转成 Schema:

# 形式一:@tool 装饰器(推荐)——类型注解 + docstring 就是 Schema
@tool
def get_weather(city: str) -> str:
    """获取给定城市的当前天气。"""
    ...

# 形式二:Pydantic 类——只要定义,不要实现(模型先"报名")
from pydantic import BaseModel, Field

class Multiply(BaseModel):
    """返回 x 和 y 的乘积。"""
    x: float = Field(description="第一个因子")
    y: float = Field(description="第二个因子")

# 形式三:普通函数——docstring 与类型注解同样生效
def subtract(x: float, y: float) -> float:
    """用 x 减去 y。"""
    return x - y

# 形式四:原始 dict(OpenAI 格式)——极端情况手写 Schema

四种形式的共同点:Schema 都从类型注解和 docstring 自动生成。这也再次印证了前一篇的结论——类型注解和 docstring 不是代码整洁问题,是协议的一部分,直接决定模型的调用准确率。


三、tool_calls:模型意图的唯一出口

绑定之后调用模型,返回的 AIMessage 上多了一个字段:

resp = llm_with_tools.invoke("北京今天天气怎么样?")

resp.tool_calls
# [{
   
#     "name": "get_weather",
#     "args": {"city": "北京"},
#     "id": "call_00_Y1R8gZ...",
#     "type": "tool_call",
# }]

这个列表就是模型"动手意图"的唯一标准出口:工具名、参数字典、本次调用的唯一 ID。三个要点:

  1. 模型不执行任何东西——它只是声明了"我想调 get_weather,参数是北京";
  2. id 是对应关系的钥匙——执行结果回传时必须带上这个 id(下一节);
  3. 没打算调工具时列表为空——此时 resp.content 就是普通文本回答。

各厂商原始的工具调用格式互不兼容(OpenAI 用 tool_calls,Anthropic 用 input_schema,Gemini 又是另一套),LangChain 把它们全部归一到这个标准结构——这就是"统一模型接口"在工具层的落地。


四、ToolMessage:结果回流的闭环

拿到 tool_calls 后,执行并把结果送回去:

from langchain_core.messages import ToolMessage, HumanMessage

messages = [HumanMessage(content="北京今天天气怎么样?")]
ai_msg = llm_with_tools.invoke(messages)
messages.append(ai_msg)

for tc in ai_msg.tool_calls:
    result = get_weather.invoke(tc["args"])          # 真正执行
    messages.append(ToolMessage(
        content=str(result),
        tool_call_id=tc["id"],                        # 关键:id 对应
    ))

final = llm_with_tools.invoke(messages)               # 模型基于结果作答
print(final.content)   # "北京今天晴朗,26℃。"

tool_call_id 的对应关系是闭环的关键:一次对话可能有多个工具调用,模型靠 id 把"哪个结果对应哪次请求"对上号。漏掉 id 会直接报错——这不是可选项。

这个手动循环就是 Agent 的全部底层。create_agent 做的事,就是把"调模型 → 执行工具 → 结果回传 → 再调模型"这个 while 循环自动化,外加中间件和状态管理。理解了手动版本,Agent 的行为就完全透明。

在这里插入图片描述


五、tool_choice:从自由到强制的控制光谱

默认情况下,模型自行决定调不调工具、调哪个。tool_choice 参数提供五个档位:

取值 行为 适用
"auto" 模型自由决定(含不调) 大多数情况
"none" 禁止调用 临时关闭工具能力
"any" / True 强制至少调一个 抽取类任务
"工具名" 强制调用指定工具 路由到固定工具
False / None 默认行为 ——
# 强制每次都走搜索工具
llm_forced = llm.bind_tools([search], tool_choice="any")

# 强制调用指定工具
llm_route = llm.bind_tools([search, calc], tool_choice="search")

强制模式在结构化提取场景特别有用——上一篇文章讲的 ToolStrategy,底层正是"强制模型调用结构化输出工具"(tool_choice 指向 Schema 工具)。两篇文章在这里会师。


六、并行调用与 strict 模式

并行调用是默认开启的能力。问"北京和东京的天气",模型会一次返回两个 tool_calls:

resp = llm_with_tools.invoke("北京和东京的天气怎么样?")
# tool_calls: [
#   {"name": "get_weather", "args": {"city": "北京"}, "id": "call_1"},
#   {"name": "get_weather", "args": {"city": "东京"}, "id": "call_2"},
# ]

两个调用相互独立,可以并行执行再一起回传。需要禁用时(比如保证执行顺序):

llm.bind_tools([get_weather], parallel_tool_calls=False)

strict 模式(部分厂商支持)则是给 Schema 上锁:

llm.bind_tools([get_weather], strict=True)

开启后模型输出保证严格匹配工具定义的 JSON Schema,参数校验由厂商兜底。生产环境建议开启——它把上一篇文章 Pydantic 校验的可靠性又提高了一档。


七、手动循环 vs create_agent:怎么选

现在你能看清两者的边界了:

维度 手动 bind_tools 循环 create_agent
控制粒度 每一步自己把控 框架托管
代码量 多(循环、消息管理全手写) 少(声明式配置)
适用 单轮工具调用、自定义路由逻辑 多轮任务、需要记忆/中间件
学习价值 理解协议本质 快速交付

实践建议很清晰:单次"调工具拿结果"用 bind_tools 手动循环就够——比如查询增强(先强制搜索再回答),三行代码;多轮推进、需要状态和管控的任务交给 create_agent。先写一遍手动循环再上手 Agent,是理解这套体系最快的路径。


八、给 Java / 大数据工程师的对照

  • bind_tools ≈ 注册 RPC 接口:把接口签名(Schema)暴露给调用方,调用方(模型)按签名发请求;
  • tool_calls ≈ RPC 请求报文:方法名 + 参数 + 请求 ID,只是"调用方"是概率性的模型;
  • tool_call_id 对应 ≈ 请求-响应关联:异步消息系统里靠 correlation_id 配对,这里同构;
  • 手动循环 ≈ 写了一遍 Flink 的迭代算子:数据流入 → 处理 → 结果回流 → 再触发,直到没有新工具调用(收敛)。

九、小结

工具调用协议的检查清单:

  1. Schema 质量决定一切——类型注解 + docstring 就是给模型的接口文档;
  2. tool_calls 是意图出口,模型不执行——执行永远在你的代码里;
  3. tool_call_id 必须回传——多工具调用场景对不上号就崩;
  4. tool_choice 从 auto 到强制是一段完整控制光谱,抽取场景用强制;
  5. 生产开 strict——厂商级 Schema 校验兜底。

这套协议是 Agent、结构化输出、RAG 工具增强的共同地基。把它吃透,LangChain 的一切"智能体魔法"都是它的组合。


本文基于 LangChain 官方博客与 v1.0 文档整理,代码在 Python 3.13 + langchain 1.2.0 环境下验证通过。

目录
相关文章
|
5天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
2429 16
|
6天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
1067 3
|
云安全 安全 网络安全
|
5天前
|
Linux 开发工具 iOS开发
Codex保姆级教程(下载+安装+登录+使用,含所有版本,2026最新)
Codex是OpenAI推出的开源AI编程智能体,本地运行,可理解整个代码库,支持自然语言指令改代码、执行命令、跑测试、修Bug,兼容Win/macOS/Linux。(239字)
|
6天前
|
安全 算法 定位技术
《高性价比人生指南》完整原版:普通人用最少的资源,过好这一生的底层逻辑~How To Live Better
📖《高性价比人生指南》是一份基于实证、拒绝焦虑的生存手册,倡导以“人生时薪”为视角,重新计算时间、金钱与精力的成本与收益。它不承诺逆袭,只教人算清账:省下的钱若耗掉时间便亏;买体验比买物品更值;睡眠是最高杠杆的健康投资;关系贵在情绪价值而非表面热络;学习重在改变行为而非自我安慰。核心理念:用低成本、高回报的微小行动,换取长期的选择权——不是成为谁,而是掌控自己人生的主动权。
|
18天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
3219 50
|
12天前
|
JavaScript 安全 前端开发
Nodejs Brotli decoder 代码执行漏洞 (CVE-2026-111497)10629
Node.js发布安全更新修复Brotli解码器高危RCE漏洞(CVE-2026-111497),建议受影响版本用户立即升级。
2116 2
|
11天前
|
人工智能 JSON Linux
【保姆级】ComfyUI部署教程(下载+安装+配置+工作流,2026最新)
ComfyUI 是一款开源节点式AI生成工具,支持图像、视频、音频及3D内容创作。通过拖拽连线组合模型加载、提示词、采样等节点,构建可复用、易修改的工作流,兼容SD1.5、SDXL、Flux、Qwen Image等主流模型。

热门文章

最新文章