news 2026/5/10 11:37:58

AI-Agent工具调用深度实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI-Agent工具调用深度实战

AI Agent工具调用(Function Calling)深度实战:从原理到生产级架构

工具调用是AI Agent的核心能力——让大语言模型不仅能"说",还能"做"。本文从协议原理到生产级实现,手把手带你掌握Function Calling的每一个细节。

前言

2024年以来,AI Agent的概念火遍整个技术圈。但你有没有想过,一个Agent到底是怎么"动手"操作外部世界的?答案就是工具调用(Tool Use / Function Calling)

我在实际项目中踩过无数坑:参数解析失败、工具名幻觉、循环调用死循环、并发工具调用竞态……这些问题官方文档很少提及,但每一个都可能让你的Agent在生产环境中翻车。

这篇文章会从协议层面讲清楚工具调用的原理,然后用真实的Python代码带你从零实现一个生产级的工具调用框架。


一、Function Calling 协议原理

1.1 核心概念

Function Calling的本质是:让LLM输出结构化的工具调用请求,由外部系统执行后将结果返回给LLM

整个流程是这样的:

用户输入 → LLM推理 → 输出工具调用请求(JSON) → 外部系统执行工具 → 将结果返回LLM → LLM整合结果生成最终回复

关键点在于:LLM本身不执行任何工具,它只是决定"要调用什么工具、传什么参数"。真正的执行发生在你的应用层代码中。

1.2 三大厂商协议对比

不同厂商的Function Calling协议有细微但重要的差异:

OpenAI 协议
# OpenAI 的工具定义格式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"]}}}]response=client.chat.completions.create(model="gpt-4o",messages=[{"role":"user","content":"北京今天天气怎么样?"}],tools=tools,tool_choice="auto"# auto | none | required | {"type":"function","function":{"name":"xxx"}})

OpenAI返回的工具调用在message.tool_calls中:

# 返回结构message=response.choices[0].messageifmessage.tool_calls:fortcinmessage.tool_calls:print(tc.function.name)# "get_weather"print(tc.function.arguments)# '{"city":"北京","unit":"celsius"}'print(tc.id)# "call_abc123",用于后续提交结果
Anthropic (Claude) 协议
# Claude 的工具定义格式 - 注意差异!tools=[{"name":"get_weather","description":"获取指定城市的天气信息","input_schema":{# 注意:Claude用 input_schema,不是 parameters"type":"object","properties":{"city":{"type":"string","description":"城市名称"}},"required":["city"]}}]response=client.messages.create(model="claude-sonnet-4-20250514",max_tokens=1024,messages=[{"role":"user","content":"北京今天天气怎么样?"}],tools=tools)

Claude的返回结构也不同:

# Claude 返回在 content 数组中,类型为 tool_useforblockinresponse.content:ifblock.type=="tool_use":print(block.name)# "get_weather"print(block.input)# {"city": "北京"} - 注意是 dict,不是字符串!print(block.id)# "toolu_abc123"
Google Gemini 协议
# Gemini 的工具定义importgoogle.generativeaiasgenaidefget_weather(city:str,unit:str="celsius")->dict:"""获取指定城市的天气信息"""pass# Gemini 支持直接传入 Python 函数!model=genai.GenerativeModel('gemini-2.0-flash',tools=[get_weather]# 自动从函数签名生成Schema)# 也可以用 FunctionDeclaration 手动定义fromgoogle.generativeai.typesimportFunctionDeclaration,Tool weather_func=FunctionDeclaration(name="get_weather",description="获取指定城市的天气信息",parameters={"type":"object","properties":{"city":{"type":"string","description":"城市名称"}},"required":["city"]})model=genai.GenerativeModel('gemini-2.0-flash',tools=[Tool(function_declarations=[weather_func])])

1.3 关键差异总结

特性OpenAIClaudeGemini
Schema字段名parametersinput_schemaparameters
返回格式字符串JSON原生dict原生dict
工具ID自动生成自动生成无(靠name匹配)
并行调用支持(多个tool_calls)支持(多个tool_use块)支持(多个function_call)
强制调用tool_choice="required"无直接支持无直接支持
原生函数支持不支持不支持支持(Python函数直接传入)

二、工具定义的 JSON Schema 最佳实践

2.1 常见错误:模糊的描述

# ❌ 错误:描述太模糊,LLM不知道怎么调用{"name":"search","description":"搜索","parameters":{"type":"object","properties":{"q":{"type":"string"}}}}# ✅ 正确:描述清晰,包含使用场景和约束{"name":"search_products","description":"在商品库中搜索产品。支持关键词模糊匹配。返回最多20条结果,按相关性排序。当用户询问商品信息、价格比较、购买建议时使用此工具。","parameters":{"type":"object","properties":{"query":{"type":"string","description":"搜索关键词,如'无线蓝牙耳机'、'iPhone手机壳'"},"category":{"type":"string","enum":["electronics","clothing","food","books"],"description":"商品分类筛选,可选。不指定则搜索全部分类"},"max_price":{"type":"number","description":"最高价格限制(元),可选"},"sort_by":{"type":"string","enum":["relevance","price_asc","price_desc","sales"],"description":"排序方式,默认按相关性排序"}},"required":["query"]}}

2.2 嵌套对象与数组

当工具需要复杂参数时,Schema的定义变得关键:

# 复杂参数的正确定义{"name":"create_order","description":"创建订单。当用户确认购买意向后调用。","parameters":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"product_id":{"type":"string","description":"商品ID,格式为'PROD-XXXX'"},"quantity":{"type":"integer","minimum":1,"maximum":99,"description":"购买数量"}},"required":["product_id","quantity"]},"description":"订单商品列表"},"shipping_address":{"type":"object","properties":{"province":{"type":"string"},"city":{"type":"
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 11:36:54

LinkSwift:免费高效的网盘直链下载助手完整指南

LinkSwift:免费高效的网盘直链下载助手完整指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 /…

作者头像 李华
网站建设 2026/5/10 11:35:00

如何快速从图表图片中提取数据:WebPlotDigitizer完整指南

如何快速从图表图片中提取数据:WebPlotDigitizer完整指南 【免费下载链接】WebPlotDigitizer Computer vision assisted tool to extract numerical data from plot images. 项目地址: https://gitcode.com/gh_mirrors/we/WebPlotDigitizer 在科研和数据分析…

作者头像 李华
网站建设 2026/5/10 11:31:59

别再只用Verilog-A了!聊聊Verilog-AMS里的wreal数据类型:它到底是模拟仿真的加速器还是精度杀手?

Verilog-AMS中的wreal数据类型:混合信号设计的双刃剑 在当今SoC和复杂混合信号芯片设计中,工程师们常常陷入仿真速度与精度之间的两难抉择。传统SPICE级仿真虽然精确,但对于大规模系统来说耗时过长;而纯数字仿真又无法满足模拟电路…

作者头像 李华
网站建设 2026/5/10 11:30:32

Quartus Prime 18.0 标准版安装Cyclone V器件库,别再傻傻双击图标了!

Quartus Prime 18.0标准版安装Cyclone V器件库的完整避坑指南 当你第一次尝试在Quartus Prime 18.0标准版中安装Cyclone V器件库时,可能会遇到一个看似简单却令人困惑的问题——明明按照常规操作双击软件图标,却在点击"Install Device..."时遭…

作者头像 李华
网站建设 2026/5/10 11:29:32

极化码ORBGRAND译码算法与FPGA实现研究【附代码】

✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导,毕业论文、期刊论文经验交流。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)固定参数ORBGRAND译码器的低复杂度设计&#xff1a…

作者头像 李华