AI Agent 工具调用(Tool Use)实战指南

AI Agent 工具调用(Tool Use)实战指南

AI Agent 工具调用(Tool Use)实战指南

工具调用(Tool Use / Function Calling)是 AI Agent 从"会思考"到"能动手"的关键能力。本文将从原理到实战,全面讲解如何为 Agent 设计、注册和调用工具。

一、什么是工具调用?

工具调用是指 LLM 根据用户输入,主动判断需要调用哪个外部函数/API,并生成结构化参数,由外部系统执行后将结果返回给模型。

用户:"北京今天天气怎么样?" |LLM 分析:需要查询天气 -> 调用 weather_api(city="北京", date="今天") |外部系统执行 API -> 返回 {"temperature": 25, "condition": "晴"} |LLM 生成回复:"北京今天天气晴朗,气温25度。"

二、工具的核心结构

一个标准的工具定义包含:

字段 说明 | 示例 ------------|------name工具名称(英文,无空格) |get_weatherdescription功能描述(影响模型决策) | "获取指定城市的天气信息"parameters参数定义(JSON Schema) |{"city": {"type": "string"}}function实际执行函数 |def get_weather(city): ...

三、OpenAI Function Calling 基础

1. 定义工具

import json

tools = [ { "type": "function", "function": { "name": "get_weather", "description": "获取指定城市的当前天气信息", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,如'北京'、'上海'" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "温度单位" } }, "required": ["city"] } } }]

2. 调用流程

from openai import OpenAI

client = OpenAI()

第一轮:模型决定是否调用工具

response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": "北京今天多少度?"}], tools=tools, tool_choice="auto")

message = response.choices[0].message

如果模型决定调用工具

if message.tool_calls: tool_call = message.tool_calls[0] function_name = tool_call.function.name arguments = json.loads(tool_call.function.arguments) print(f"模型决定调用: {function_name}") print(f"参数: {arguments}") # 输出:get_weather, {'city': '北京', 'unit': 'celsius'} # 执行函数(实际业务逻辑) result = {"temperature": 25, "condition": "晴朗", "city": arguments["city"]} # 第二轮:将结果返回给模型 response2 = client.chat.completions.create( model="gpt-4", messages=[ {"role": "user", "content": "北京今天多少度?"}, {"role": "assistant", "content": None, "tool_calls": [tool_call]}, {"role": "tool", "tool_call_id": tool_call.id, "content": json.dumps(result)} ], tools=tools ) print(response2.choices[0].message.content) # 输出:北京今天天气晴朗,气温25摄氏度。

四、LangChain 工具封装

LangChain 提供了更高级的工具封装,让开发更简单。

1. 使用 @tool 装饰器

from langchain.tools import tool

@tooldef search_web(query: str) -> str: """使用搜索引擎查找互联网上的信息。 Args: query: 搜索关键词 """ # 实际实现:调用搜索API return f"搜索结果:关于 '{query}' 的相关信息..."

@tooldef calculate(expression: str) -> str: """执行数学计算表达式。 Args: expression: 数学表达式,如 '2 + 3 * 4' """ try: return str(eval(expression)) except Exception as e: return f"计算错误: {e}"

工具会自动解析函数名、参数和描述

print(search_web.name) # search_webprint(search_web.description) # 函数docstring

2. 自定义工具类

from langchain.tools import BaseToolfrom pydantic import BaseModel, Field

class WeatherInput(BaseModel): city: str = Field(description="城市名称") date: str = Field(description="日期,格式YYYY-MM-DD", default="today")

class WeatherTool(BaseTool): name = "get_weather" description = "获取指定城市的天气信息" args_schema = WeatherInput def _run(self, city: str, date: str = "today") -> str: # 调用天气API return f"{city} {date} 天气:晴,25C" async def _arun(self, city: str, date: str = "today") -> str: # 异步实现 return self._run(city, date)

weather_tool = WeatherTool()

五、实战:构建工具Agent

from langchain_openai import ChatOpenAIfrom langchain.agents import create_tool_calling_agent, AgentExecutorfrom langchain_core.prompts import ChatPromptTemplatefrom langchain.tools import toolimport requests

1. 定义工具

@tooldef get_baidu_index(keyword: str) -> str: """获取百度指数搜索趋势数据(模拟)""" return f"关键词 '{keyword}' 近30天搜索指数呈上升趋势,日均搜索量约5000次。"

@tooldef translate(text: str, target_lang: str = "en") -> str: """将文本翻译成目标语言""" return f"[翻译结果] {text} -> {target_lang}: Translated content here"

@tooldef read_file(path: str) -> str: """读取本地文件内容""" try: with open(path, 'r', encoding='utf-8') as f: return f.read()[:1000] # 限制长度 except Exception as e: return f"读取失败: {e}"

tools = [get_baidu_index, translate, read_file]

2. 创建Agent

llm = ChatOpenAI(model="gpt-4", temperature=0)

prompt = ChatPromptTemplate.from_messages([ ("system", "你是一个智能助手,可以使用工具帮助用户解决问题。"), ("placeholder", "{chat_history}"), ("human", "{input}"), ("placeholder", "{agent_scratchpad}")])

agent = create_tool_calling_agent(llm, tools, prompt)executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

3. 运行测试

executor.invoke({"input": "'AI Agent'这个关键词的搜索热度怎么样?顺便把它翻译成英文。"})

六、工具设计最佳实践

1. 描述要清晰

# 不好的描述description = "搜索工具"

好的描述

description = "用于在互联网上搜索实时信息,包括新闻、天气、股价、技术文档等。当用户询问需要最新数据的问题时,应该使用此工具。"

2. 参数设计要简洁

# 参数过多过复杂{"name": "api", "params": "{"type":"weather","city":"xxx","date":"xxx"}"}

扁平化参数

{"city": "北京", "date": "2025-01-15"}

3. 处理工具执行错误

def safe_tool_execute(tool_func, kwargs): try: result = tool_func(kwargs) return {"status": "success", "result": result} except Exception as e: return {"status": "error", "error": str(e), "hint": "请检查参数是否正确"}

4. 工具权限控制

class PermissionedTool: def __init__(self, tool, allowed_users=None): self.tool = tool self.allowed_users = allowed_users or [] def run(self, user_id, kwargs): if user_id not in self.allowed_users: return "错误:您没有权限使用此工具" return self.tool.run(kwargs)

七、总结

工具调用是 Agent 的"手",让模型从纯文本推理走向实际操作。掌握工具设计、注册和调用的方法,是构建实用 Agent 的必备技能。记住:好的工具描述胜过复杂的代码,模型的决策质量很大程度上取决于你如何描述工具的能力。

---

下一篇将介绍多Agent协作系统,探索如何让多个Agent分工合作完成复杂任务。