Tools 工具调用
工具(Tools)扩展了 Agent 的能力——让它们获取实时数据、执行代码、查询外部数据库,以及在真实世界中采取行动。在 LangChain 中,工具就是 Python 函数——带上一些元数据。
定义工具
使用 @tool 装饰器
创建工具最简单的方式是使用 @tool 装饰器。函数名自动成为工具名,文档字符串成为工具描述:
python
from langchain.tools import tool
@tool
def search_database(query: str, limit: int = 10) -> str:
"""搜索客户数据库。
Args:
query: 搜索关键词
limit: 最大返回结果数
"""
return f"找到 {limit} 条关于 '{query}' 的结果"@tool 装饰器自动:
- 使用函数名作为工具名(建议使用
snake_case) - 使用文档字符串作为工具描述
- 使用类型注解作为参数 schema
注意:类型注解是必须的,它们定义工具的输入 schema。
自定义工具属性
python
from langchain.tools import tool
# 自定义工具名
@tool("web_search")
def search(query: str) -> str:
"""搜索互联网信息"""
return f"关于 '{query}' 的搜索结果..."
# 自定义工具描述
@tool("calculator", description="执行算术运算。用于任何数学问题。")
def calc(expression: str) -> str:
"""计算数学表达式"""
return str(eval(expression))使用 Pydantic 定义复杂参数
对于更复杂的工具输入,推荐使用 Pydantic 模型:
python
from pydantic import BaseModel, Field
from typing import Literal
from langchain.tools import tool
class WeatherInput(BaseModel):
"""天气查询输入"""
location: str = Field(description="城市名或坐标")
units: Literal["celsius", "fahrenheit"] = Field(
default="celsius",
description="温度单位偏好"
)
include_forecast: bool = Field(
default=False,
description="是否包含 5 天预报"
)
@tool(args_schema=WeatherInput)
def get_weather(location: str, units: str = "celsius", include_forecast: bool = False) -> str:
"""获取当前天气和可选预报"""
temp = 22 if units == "celsius" else 72
result = f"{location}当前天气:{temp}度"
if include_forecast:
result += "\n未来5天:晴"
return result也可以使用 JSON Schema:
python
weather_schema = {
"type": "object",
"properties": {
"location": {"type": "string"},
"units": {"type": "string"},
"include_forecast": {"type": "boolean"}
},
"required": ["location", "units"]
}
@tool(args_schema=weather_schema)
def get_weather(location: str, units: str = "celsius", include_forecast: bool = False) -> str:
"""获取当前天气和可选预报"""
...将工具传入 Agent
python
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def get_weather(city: str) -> str:
"""获取指定城市的天气"""
return f"{city}: 晴,22°C"
@tool
def search(query: str) -> str:
"""搜索信息"""
return f"搜索结果: {query}"
agent = create_agent(
model="openai:gpt-5.5",
tools=[get_weather, search],
system_prompt="你是一个助手,可以使用工具回答问题",
)工具运行时上下文 (ToolRuntime)
工具最强大的地方在于它们可以访问运行时信息——对话历史、用户数据、持久化记忆。通过 ToolRuntime 参数实现:
ToolRuntime 提供以下组件:
| 组件 | 说明 |
|---|---|
| State | 短期记忆——当前会话的可变数据(消息、计数器、自定义字段) |
| Context | 上下文数据——通过 create_agent 的 context 参数传入的应用数据 |
| Store | 长期记忆——跨会话持久化的用户数据和知识 |
python
from langchain.tools import tool
from langchain.tools import ToolRuntime
@tool
def get_user_info(runtime: ToolRuntime) -> str:
"""获取当前用户信息"""
user_id = runtime.context.user_id
name = runtime.store.get(("users", user_id), "name")
return f"用户: {name}, ID: {user_id}"
@tool
def record_purchase(item: str, amount: float, runtime: ToolRuntime) -> str:
"""记录用户的购买行为"""
user_id = runtime.context.user_id
history = runtime.store.get(("users", user_id), "purchases")
purchases = history.value if history else []
purchases.append({"item": item, "amount": amount})
runtime.store.put(("users", user_id), "purchases", purchases)
return f"已记录购买:{item} ¥{amount}"保留参数名
以下参数名是保留的,不能用作工具参数:
| 参数名 | 用途 |
|---|---|
config | 内部传参 RunnableConfig |
runtime | ToolRuntime 参数(访问状态、上下文、存储) |
如果你使用 InjectedState、InjectedStore、get_runtime() 或 InjectedToolCallId 等旧版注入模式,请迁移到 ToolRuntime 参数。
动态工具选择
你可以在运行时通过 Middleware 动态限制 Agent 可用的工具子集:
python
from langchain.agents import create_agent
from langchain.agents.middleware import LLMToolSelectorMiddleware
agent = create_agent(
model="openai:gpt-5.5",
tools=[get_weather, search, calculator, send_email],
middleware=[
LLMToolSelectorMiddleware(
# 根据输入内容自动选择合适工具
selector="auto",
)
],
)或者直接在 create_agent 中传入不同工具集:
python
# 只包含部分工具
tools_limited = [get_weather, search]
agent_limited = create_agent(
model="openai:gpt-5.5",
tools=tools_limited,
)服务端工具
部分模型提供商(如 OpenAI、Google)内置了服务端工具(Web 搜索、代码解释器),这些工具由模型端执行:
python
from langchain.agents import create_agent
# OpenAI 内置 Web 搜索
agent = create_agent(
model="openai:gpt-5.5",
tools=[{"type": "web_search"}], # 服务端工具
)
# Google 内置 Web 搜索
agent = create_agent(
model="google_genai:gemini-3.5-flash",
tools=[{"type": "web_search"}],
)工具命名规范
- 使用
snake_case命名(如web_search而非Web Search) - 某些模型提供商可能拒绝包含空格或特殊字符的工具名
- 建议只使用字母、数字、下划线和连字符
最佳实践
- 工具描述要清晰:描述应该让模型准确理解工具用途和使用时机
- 参数类型要具体:使用精确的类型注解,让模型正确填写参数
- 避免参数名冲突:不要使用
config和runtime作为参数名 - 错误处理:工具内部做好异常捕获,返回友好的错误信息
- 幂等设计:工具应尽量设计为可重复安全执行
下一步
- Agents 智能体 —— 深入了解 Agent 框架
- Middleware 中间件 —— 通过中间件扩展工具行为
- Structured Output —— 结构化输出
- MCP 接入 —— MCP 协议集成