LangChain 工具绑定:`bind_tools` vs `create_agent` 的区别
在 LangChain/LangGraph 中给模型添加工具有两种方式,它们的层级和用途完全不同。
一句话总结
model.bind_tools()— 只告诉模型有哪些工具可用,不负责执行create_agent(tools=...)— 自动处理整个工具调用循环,开箱即用
model.bind_tools() — 底层接口
代码
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
@tool
def get_weather(city: str) -> str:
"""查询城市天气。"""
return f"{city}: 晴天 25°C"
model = ChatOpenAI(model="gpt-4o-mini")
llm_with_tools = model.bind_tools([get_weather], tool_choice="any")
它做了什么?
- 把工具的 JSON Schema(名字、参数、描述)附加到模型请求中
- 模型知道可以返回
tool_calls - 仅此而已 — 不会自动执行工具
代码
from langchain.messages import HumanMessage, ToolMessage
# 1. 调用模型
response = llm_with_tools.invoke([HumanMessage(content="北京天气?")])
# 2. 手动执行工具
if response.tool_calls:
tool_call = response.tool_calls[0]
result = get_weather.invoke(tool_call["args"])
# 3. 手动把结果传回模型
tool_msg = ToolMessage(content=result, tool_call_id=tool_call["id"])
final = llm_with_tools.invoke([
HumanMessage(content="北京天气?"),
response,
tool_msg
])
print(final.content)
tool_choice 参数
| 值 | 含义 |
|---|---|
"auto" |
模型自己决定是否调工具(默认) |
"any" |
强制模型必须调用至少一个工具 |
"none" |
禁止调用工具 |
{"type": "function", "function": {"name": "get_weather"}} |
强制调用指定工具 |
create_agent(tools=...) — 高层封装
代码
from langchain.agents import create_agent
from langchain.messages import HumanMessage
agent = create_agent(
model=model,
tools=[get_weather],
system_prompt="你是一个天气助手。"
)
# 一行搞定,不用管中间过程
result = agent.invoke({
"messages": [HumanMessage(content="北京天气?")]
})
print(result["messages"][-1].content)
它做了什么?
内部自动完成了:
model.bind_tools(tools)— 绑定工具- 构建 StateGraph(推理节点 + 工具节点 + 条件边)
- 自动循环:模型决策 → 执行工具 → 结果传回 → 直到完成
你不需要写任何循环逻辑。
对比总结
model.bind_tools() |
create_agent(tools=...) |
|
|---|---|---|
| 层级 | 底层(模型级别) | 高层(Agent 级别) |
| 自动执行工具 | ❌ 需手动 | ✅ 自动 |
| 自动循环 | ❌ 需手动 | ✅ 自动 |
| 可定制性 | 高 | 低(固定 ReAct 模式) |
| 代码量 | 多(需要写循环) | 少(约 10 行) |
| 适用场景 | 自定义 StateGraph | 快速原型 |
什么时候用哪个?
用 bind_tools 的场景
- 你在自己搭建 StateGraph,需要完全控制节点和边
- 需要在工具调用前后加自定义逻辑(如审批、日志)
- 多 Agent 协作,每个 Agent 有不同的工具集
- 需要
tool_choice="any"等精细控制
# 典型用法:自定义图中的推理节点
def reasoning_node(state):
prompt = build_prompt(state)
result = llm_with_tools.invoke(prompt) # 用 bind_tools 后的模型
return {"messages": [result]}
用 create_agent 的场景
- 快速验证想法
- 标准的 ReAct 问答 Agent
- 不需要复杂的控制流
# 典型用法:10 行代码搞定
agent = create_agent(model=model, tools=[...], system_prompt="...")
result = agent.invoke({"messages": [...]})
它们的关系
graph TD
A["create_agent(tools=[...])"] --> B["内部调用 model.bind_tools(tools)"]
B --> C["构建 StateGraph"]
C --> D["添加推理节点 + 工具节点"]
D --> E["添加条件边(should_continue)"]
E --> F["编译输出可运行的 Agent"]
create_agent 是 bind_tools + StateGraph 的语法糖。当语法糖不够用时(需要自定义流程),你就退回到 bind_tools + 手动搭图。
实际项目中的选择
| 项目阶段 | 推荐方式 |
|---|---|
| 概念验证 / Demo | create_agent |
| 生产级 Agent(需要审批、分类、多步骤) | bind_tools + 自定义 StateGraph |
| 多 Agent 系统 | 每个子 Agent 用 bind_tools,Supervisor 协调 |

在 LangChain/LangGraph 中给模型添加工具有两种方式,它们的层级和用途完全不同
浙公网安备 33010602011771号