工具学习(Tool Learning):Agent 如何自动理解并使用未见过的 API?
首先,我们得明确几个行业通用的核心概念锚点以Transformer为架构基础,通过预训练(Pre-training)海量文本数据获得通用知识和生成能力的AI模型,代表有GPT-4、Claude 3、Llama 3、Qwen 2.5等。具备感知(Perception)、推理(Reasoning)、决策(Decision-making)、行动(Action/Execution)和反馈(Feedback
工具学习(Tool Learning):Agent 如何自动理解并使用未见过的 API?
一、 引言 (Introduction)
钩子 (The Hook)
想象一下:你正在开发一个全能型旅行规划助手 Agent,目标是让它能帮用户完成「预订马尔代夫六星全包水屋 + 申请斯里兰卡ETA电子签证 + 预约当地水下摄影浮潜团 + 生成7天AI定制中文行程攻略」的全流程。但当你把这个需求拆解到API层面时,问题来了——你根本不可能提前训练Agent记忆全球所有OTA平台、签证中心、本地服务商的API文档格式,甚至很多小众服务只开放了临时、极简的单页API说明。更棘手的是:当你好不容易接入了Booking.com的酒店API,三天后它居然更新了接口参数(把「check_in_date」从ISO字符串改成了YYYY-MM-DD的Timestamp数组偏移量)、返回了全新的嵌套JSON错误码——你的Agent立刻就“卡壳”了,根本不会自动修复自己的调用逻辑。
这不是科幻小说,这是当前大语言模型(LLM)应用落地的第一大“杀手级痛点”:LLM本身虽然具备强大的自然语言理解(NLU)、推理(Reasoning)和代码生成(CodeGen)能力,但它的**「静态知识窗口」是有限的**(GPT-4 Turbo只有128K上下文,实际使用中还要考虑Token成本和记忆衰减),而且它无法直接感知和操作现实世界的数字/物理资源——比如查实时天气、订机票、控制智能家居设备、解析Excel表格中的财务数据。
而解决这个问题的核心技术,就是今天这篇文章要从零到一、从原理到代码、从基础到进阶,掰开揉碎讲清楚的「工具学习(Tool Learning)」——尤其是Agent如何自动理解并使用从未见过的“零样本/少样本API”。
定义问题/阐述背景 (The “Why”)
首先,我们得明确几个行业通用的核心概念锚点(这也是第二章的预铺垫,但引言提一下能快速建立共识):
- 大语言模型(LLM): 以Transformer为架构基础,通过预训练(Pre-training)海量文本数据获得通用知识和生成能力的AI模型,代表有GPT-4、Claude 3、Llama 3、Qwen 2.5等。
- 智能代理(Agent): 具备感知(Perception)、推理(Reasoning)、决策(Decision-making)、行动(Action/Execution)和反馈(Feedback)闭环能力的AI系统,其核心通常是LLM + 工具集(Toolkit)。
- 工具(Tool): Agent可以调用的、能获取外部知识或操作外部资源的“功能单元”——可以是API(Web API、RESTful API、GraphQL API、RPC API等)、可以是本地脚本(Python/Shell函数)、可以是数据库查询、可以是搜索引擎(比如Bing Search、Google Custom Search)、甚至可以是另一个Agent!
- 工具学习(Tool Learning): 研究如何让Agent自动发现、理解、选择、调用、调试工具的领域,是“LLM应用落地”和“通用人工智能(AGI)初步实现”的核心桥梁技术。
那为什么“自动理解并使用未见过的API”是工具学习中最难、也最有价值的子方向呢?我们可以从「需求端」和「供给端」两个维度来分析:
需求端:未见过的API是“常态”而非“例外”
- API的数量是爆炸式增长的: 根据ProgrammableWeb的数据,2024年公开注册的Web API数量已经突破3000万大关,而且每天还在以数万级的速度新增——你根本不可能提前为Agent构建所有API的调用模块。
- API的更新是高频且不可控的: 大部分商业API(比如OpenAI的API、Twitter/X的API、AWS的Lambda API)都会定期更新接口参数、返回格式、错误码、甚至授权机制——如果Agent不能自动适应这种变化,你的应用维护成本会“指数级上升”。
- API的使用场景是高度个性化的: 很多企业内部的API、小众服务的API、甚至临时生成的API(比如用FastAPI临时写的一个测试接口),根本没有统一的文档规范(比如OpenAPI 3.0、GraphQL SDL、Swagger 2.0),甚至可能只有一段模糊的自然语言描述、或者一个简单的curl示例——这对Agent的理解能力提出了极高的要求。
供给端:LLM的能力边界在倒逼工具学习的创新
- 传统的“硬编码工具调用”已经过时了: 在早期的LLM应用中,开发者通常会提前为Agent定义好一组固定的工具描述(Tool Description)、参数列表(Parameter Schema)、返回格式解析规则,然后让LLM通过“Function Calling”或“Tool Use”的能力来选择和调用——但这种方式的扩展性极差,完全无法应对“未见过的API”的场景。
- 静态的“Prompt工程微调”效果有限: 有些开发者会尝试把成千上万的API文档放入Prompt的上下文窗口,或者用低秩适应(LoRA)、全量微调(Full Fine-tuning)等方式让LLM记忆一些常用API的调用逻辑——但这种方式的Token成本极高(把3000万API文档放进去根本不可能)、记忆衰减速度极快(LoRA微调后的LLM对不常用API的调用准确率会在几周内大幅下降)、无法适应API的更新(微调一次需要几天甚至几周的时间,成本也很高)。
- LLM的“元学习(Meta-Learning)”和“Few-Shot/Zero-Shot Learning”能力已经成熟: 现在的大语言模型(比如GPT-4o、Claude 3 Opus、Llama 3.1 405B)已经具备了极强的“举一反三”能力——只要给它一个通用的“工具学习框架”,它就能通过阅读API的自然语言描述、观察API的调用示例、分析API的返回结果,自动学会如何调用从未见过的API——这为“自动理解并使用未见过的API”提供了技术基础。
亮明观点/文章目标 (The “What” & “How”)
读完这篇超过10000字的技术博客,你将彻底掌握工具学习的核心原理、Agent自动理解未见过API的完整流程、以及从0到1构建一个“通用型API调用Agent”的实战代码——具体来说,你将学到:
核心内容预告
- 第二章:基础知识/背景铺垫
- 工具学习的完整定义、核心分类、发展历史脉络(用markdown表格整理)
- Agent调用工具的经典闭环架构(Perception → Reasoning → Decision → Execution → Feedback,用mermaid交互关系图描述)
- 传统“Function Calling”的工作原理、局限性对比(用markdown表格整理不同LLM的Function Calling能力)
- 未见过的API的核心属性维度(规范性、复杂度、稳定性、可用性,用markdown表格整理不同类型API的属性差异)
- 第三章:核心内容/实战演练(从原理到代码)
- 原理层面:Agent自动理解未见过API的“5步核心流程”
- API发现与收集(API Discovery & Collection): 如何让Agent自动找到它需要的API?(从搜索引擎、API市场、内部文档库三个维度讲解)
- API文档解析与标准化(API Documentation Parsing & Normalization): 如何让Agent从“非结构化/半结构化的API说明”(自然语言、curl示例、OpenAPI/Swagger文档、GraphQL SDL、Postman Collection)中提取出“结构化的工具描述”?(用Python代码实现OpenAPI 3.0文档的解析器、自然语言工具描述的生成器)
- API调用推理与计划生成(API Call Reasoning & Plan Generation): 如何让Agent根据用户的请求,选择合适的API、生成合理的调用参数、甚至设计多步API调用的流程?(用mermaid流程图描述推理过程,用Python代码实现基于ReAct框架的推理引擎)
- API调用执行与结果解析(API Call Execution & Result Parsing): 如何让Agent安全、稳定地调用API、处理各种异常情况(比如网络错误、授权错误、参数错误、返回格式错误)、并从返回结果中提取出用户需要的信息?(用Python代码实现安全的API调用客户端、异常处理模块、结果解析器)
- API调用调试与能力迭代(API Call Debugging & Capability Iteration): 如何让Agent根据API的返回结果(尤其是错误结果),自动调整自己的调用逻辑、修正自己的参数、甚至更新自己对API的理解?(用Python代码实现反馈学习模块、工具描述更新器)
- 实战层面:从0到1构建一个“通用型未见过API调用Agent”
- 项目介绍: 这是一个什么样的Agent?它能解决什么问题?它的核心功能是什么?
- 环境安装: 如何配置开发环境?需要安装哪些Python库?(OpenAI、LangChain、Pydantic、Requests、BeautifulSoup4、FastAPI、Uvicorn、PyYAML等)
- 系统功能设计: 用“用例图(Use Case Diagram)”和“功能模块图(Functional Module Diagram,mermaid架构图)”描述系统的功能。
- 系统架构设计: 用“分层架构图(Layered Architecture Diagram,mermaid架构图)”描述系统的架构(Presentation Layer → Application Layer → Domain Layer → Infrastructure Layer)。
- 系统接口设计: 用“OpenAPI 3.0规范”描述系统的对外接口(比如Agent的查询接口、API文档的上传接口、工具描述的查询接口)。
- 系统核心实现源代码: 提供所有核心模块的Python源代码(超过500行),并加上详细的注释。
- 原理层面:Agent自动理解未见过API的“5步核心流程”
- 第四章:进阶探讨/最佳实践
- 常见陷阱与避坑指南: 新手在构建“通用型API调用Agent”时容易犯的10个错误(比如没有处理API的授权问题、没有限制API的调用频率、没有对用户的请求进行安全过滤、没有验证API的返回结果、没有设计合理的Prompt、没有考虑Token成本、没有实现能力迭代、没有处理多步API调用的依赖关系、没有选择合适的LLM、没有测试各种异常情况),以及如何避免这些错误。
- 性能优化/成本考量: 如何降低Agent的Token成本?(比如用更小的LLM做初步的API选择和参数生成、用缓存存储常用的API文档和工具描述、用结构化的Prompt替代自然语言的Prompt、用批量API调用替代单步API调用)如何提高Agent的调用准确率?(比如用Few-Shot示例、用Self-Consistency技术、用Reflexion框架、用Human-in-the-Loop机制)如何提高Agent的调用速度?(比如用异步API调用、用向量数据库做API文档的相似度检索、用边缘计算)
- 最佳实践总结: 提供15条专家级的建议和原则(比如“永远不要信任用户输入的API参数”、“永远不要硬编码工具描述”、“永远要实现异常处理和反馈学习”、“永远要对API的调用进行监控和日志记录”、“永远要选择合适的LLM做不同的任务”、“永远要考虑用户的隐私和数据安全”等)。
- 第五章:结论 (Conclusion)
- 核心要点回顾: 用几句话简明扼要地总结文章最重要的观点或步骤。
- 展望未来/延伸思考: 探讨工具学习的未来发展趋势(比如“通用工具学习框架的标准化”、“Agent的自主工具发现与创造”、“多Agent协作的工具学习”、“工具学习与强化学习的结合”、“工具学习在物理世界中的应用”),或者给读者留下一个开放性问题(比如“你认为工具学习会成为AGI的核心技术吗?为什么?”)。
- 行动号召 (Call to Action): 鼓励读者亲手尝试本文的实战代码、在评论区交流自己的想法、或者提供进一步学习的资源链接(相关文章、官方文档、开源项目、学术论文等)。
二、 基础知识/背景铺垫 (Foundational Concepts)
(注:本章内容超过12000字,详细讲解了工具学习的所有核心基础知识,为第三章的实战演练打下了坚实的基础。)
2.1 工具学习的完整定义与核心概念结构
2.1.1 核心概念:什么是工具学习?
在学术领域,工具学习的权威定义来自于2023年清华大学李涓子教授团队发表在《Nature Machine Intelligence》上的综述论文《Tool Learning with Foundation Models》——原文是这样写的:
Tool Learning(工具学习) 是指基于基础模型(Foundation Models,比如LLM、多模态基础模型)的智能系统,通过自动发现、理解、选择、调用、调试工具,来扩展自身的能力边界,解决仅靠自身静态知识无法解决的复杂任务的过程。
这个定义包含了5个核心要素,我们可以用一个概念ER实体关系图(mermaid架构图) 来描述它们之间的关系:
从这个ER图中,我们可以更清晰地理解工具学习的5个核心要素:
- 基础模型(Foundation Model): 工具学习的“大脑”——负责感知用户请求、推理任务目标、理解工具描述、选择合适的工具、生成调用参数、处理返回结果、调试调用逻辑、迭代自身能力。
- 智能代理(Agent): 工具学习的“载体”——是一个具备“感知-推理-决策-执行-反馈”闭环能力的完整系统,基础模型只是它的核心组件之一。
- 工具(Tool): 工具学习的“手脚”——是Agent可以调用的、能获取外部知识或操作外部资源的功能单元,本文的核心研究对象是Web API(尤其是未见过的Web API)。
- 工具学习的5个子过程(Core Sub-Processes):
- API发现与收集(API Discovery & Collection): 从外部资源中找到Agent需要的API。
- API理解与标准化(API Understanding & Normalization): 从API的文档/示例中提取出结构化的工具描述。
- API选择与推理(API Selection & Reasoning): 根据用户请求选择合适的API、生成调用参数、设计多步调用流程。
- API执行与结果解析(API Execution & Result Parsing): 安全、稳定地调用API、处理异常情况、提取用户需要的信息。
- API调试与能力迭代(API Debugging & Capability Iteration): 根据反馈调整调用逻辑、修正参数、更新工具描述。
- 反馈(Feedback): 工具学习的“动力源”——可以来自于API的返回结果(尤其是错误结果)、用户的评价、或者人类的干预(Human-in-the-Loop)。
2.1.2 核心概念:工具学习与相关领域的关系
工具学习不是一个孤立的领域,它与自然语言处理(NLP)、代码生成(CodeGen)、强化学习(RL)、元学习(Meta-Learning)、多智能体系统(MAS)、人机交互(HCI) 等多个领域都有密切的联系——我们可以用一个概念联系的mermaid架构图来描述它们之间的关系:
下面我们来逐个分析这些领域与工具学习的关系:
- 自然语言处理(NLP):
- 自然语言理解(NLU): 工具学习的基础——Agent需要用NLU来理解用户的自然语言请求、理解API的自然语言文档、理解API的自然语言错误信息。
- 自然语言生成(NLG): 工具学习的输出——Agent需要用NLG来生成工具描述、生成调用参数的自然语言说明、生成API返回结果的自然语言总结、生成调试过程的自然语言报告。
- 语义解析(Semantic Parsing): 工具学习的核心——Agent需要用语义解析来将用户的自然语言请求转换为“结构化的任务目标”,将API的自然语言文档转换为“结构化的工具描述”,将API的自然语言错误信息转换为“结构化的调试指令”。
- 代码生成(CodeGen):
- 函数调用代码生成: 早期工具学习的主要方式——Agent用CodeGen生成调用工具的Python/JavaScript代码,然后执行这些代码。
- API客户端代码生成: 进阶工具学习的方式——Agent根据API的文档自动生成完整的API客户端代码(比如Python的requests库封装、JavaScript的fetch库封装),然后使用这些客户端代码调用API。
- 测试代码生成: 工具学习的质量保证——Agent根据API的文档自动生成测试代码(比如单元测试、集成测试),用来验证API的可用性和自己的调用逻辑的正确性。
- 强化学习(RL):
- 马尔可夫决策过程(MDP): 可以用来建模工具学习的“感知-推理-决策-执行-反馈”闭环——Agent的状态(State)是当前的任务进度、已调用的工具、已获取的信息;Agent的动作(Action)是选择工具、生成参数、调用工具;Agent的奖励(Reward)是任务是否完成、调用是否成功、用户是否满意;Agent的策略(Policy)是根据状态选择动作的规则。
- 策略梯度(Policy Gradient)、PPO算法: 可以用来训练Agent的工具调用策略——让Agent在与环境(外部工具)的交互中不断学习,优化自己的策略,提高调用准确率和任务完成率。
- 元学习(Meta-Learning):
- 零样本学习(Zero-Shot Learning): 工具学习的核心目标之一——让Agent不需要任何训练样本,就能自动理解并使用从未见过的API。
- 少样本学习(Few-Shot Learning): 工具学习的常用方式之一——给Agent提供1-5个API的调用示例,让它快速学会如何调用类似的API。
- 模型无关元学习(MAML): 可以用来预训练基础模型的工具学习能力——让基础模型在大量的工具调用任务上预训练,学会“如何学习调用工具”,从而在面对新的API时能够快速适应。
- 多智能体系统(MAS):
- 工具共享: 多个Agent可以共享同一个工具库,避免重复发现和理解工具。
- 任务分配: 多个Agent可以协作完成复杂的任务——比如一个Agent负责发现和理解工具,另一个Agent负责选择和调用工具,第三个Agent负责调试和迭代能力。
- 协作推理: 多个Agent可以一起讨论和推理,选择最合适的工具、设计最合理的调用流程。
- 人机交互(HCI):
- 人类在回路(Human-in-the-Loop): 当Agent遇到无法解决的问题时(比如无法理解API的文档、无法调试API的错误、无法完成复杂的任务),可以请求人类的帮助——人类可以提供工具描述、调试指令、或者直接完成任务,然后Agent可以从人类的帮助中学习,提高自己的能力。
- 交互式学习: Agent可以与人类进行交互式的对话——人类可以不断地修正Agent的理解和决策,Agent可以不断地调整自己的行为。
- 可视化工具调用: Agent可以用可视化的方式(比如流程图、图表、动画)向人类展示自己的工具调用过程——让人类更容易理解Agent的行为,更容易发现Agent的错误。
2.1.3 核心概念:工具学习的核心属性维度对比
工具学习可以从多个维度进行分类,我们可以用一个markdown表格来整理这些维度的定义、示例、优缺点:
| 分类维度 | 定义 | 子分类/示例 | 优点 | 缺点 |
|---|---|---|---|---|
| 工具的可见性 | Agent是否提前知道工具的存在和使用方法 | 1. 已知工具学习(Seen Tool Learning) 2. 未知工具学习(Unseen Tool Learning) (本文核心研究对象) |
已知工具学习:调用准确率高、速度快、成本低 | 已知工具学习:扩展性差、无法适应工具的更新 |
| 工具的类型 | Agent可以调用的工具的类型 | 1. Web API(RESTful、GraphQL、RPC) 2. 本地脚本(Python、Shell) 3. 数据库查询(SQL、NoSQL) 4. 搜索引擎(Bing、Google) 5. 多模态工具(图像识别、语音合成) 6. 其他Agent |
支持多种工具:能力边界广、可以解决复杂的任务 | 支持多种工具:理解难度大、调用复杂度高、安全风险大 |
| 学习的样本数量 | Agent学习调用工具时需要的样本数量 | 1. 零样本工具学习(Zero-Shot Tool Learning) 2. 少样本工具学习(Few-Shot Tool Learning) 3. 多样本工具学习(Many-Shot Tool Learning) |
零样本/少样本:扩展性好、适应速度快、成本低 | 零样本/少样本:调用准确率低、容易犯错误 |
| 学习的方式 | Agent学习调用工具的方式 | 1. 基于Prompt的工具学习(Prompt-Based Tool Learning) 2. 基于微调的工具学习(Fine-Tuning-Based Tool Learning) 3. 基于强化学习的工具学习(RL-Based Tool Learning) 4. 基于元学习的工具学习(Meta-Learning-Based Tool Learning) |
基于Prompt的:简单、快速、不需要训练数据 | 基于Prompt的:Token成本高、受限于上下文窗口、调用准确率不稳定 |
| 反馈的来源 | Agent学习调用工具时的反馈来源 | 1. 工具返回结果反馈(Tool Result Feedback) 2. 用户评价反馈(User Evaluation Feedback) 3. 人类干预反馈(Human-in-the-Loop Feedback) |
工具返回结果反馈:自动、实时、成本低 | 工具返回结果反馈:反馈信号弱、有时候难以理解(比如模糊的错误信息) |
| 任务的复杂度 | Agent需要解决的任务的复杂度 | 1. 单步工具调用任务(Single-Step Tool Call Task) 2. 多步工具调用任务(Multi-Step Tool Call Task) 3. 复杂工具调用任务(Complex Tool Call Task)(需要多Agent协作、需要处理工具的依赖关系、需要处理工具的冲突) |
单步工具调用任务:简单、容易实现、调用准确率高 | 复杂工具调用任务:实现难度大、调用准确率低、成本高 |
2.2 工具学习的发展历史脉络
工具学习的发展历史可以分为四个阶段,我们可以用一个markdown表格来整理每个阶段的时间、核心事件、核心技术、代表作品:
| 发展阶段 | 时间范围 | 核心事件 | 核心技术 | 代表作品/研究成果 |
|---|---|---|---|---|
| 第一阶段:早期探索(Pre-LLM Era) | 1950s-2019s | 1. 图灵测试提出“机器需要具备操作外部工具的能力才能通过测试” 2. 专家系统(Expert System)使用内置的规则调用工具 3. 语义Web(Semantic Web)尝试用标准化的语言描述工具 4. Siri、Cortana、Google Assistant等语音助手使用硬编码的工具调用 |
专家系统规则、语义Web本体(OWL、RDF)、硬编码工具调用、语义解析 | 1. DENDRAL(1965年,第一个专家系统,用于分析有机化合物的结构) 2. Siri(2011年,第一个商用语音助手,使用硬编码的工具调用) |
| 第二阶段:LLM驱动的初步尝试(Early LLM Era) | 2020s-2022年中 | 1. GPT-3发布,具备强大的代码生成能力 2. 研究者开始尝试用GPT-3生成工具调用代码 3. LangChain、LlamaIndex等框架发布,简化了LLM调用工具的流程 4. OpenAI发布Code Interpreter(后来的Advanced Data Analysis),让GPT-4可以调用本地的Python脚本 |
基于Prompt的代码生成、LangChain/LlamaIndex等框架、Code Interpreter | 1. WebGPT(2021年,OpenAI发布,让GPT-3可以调用Bing Search) 2. LangChain(2022年,Harrison Chase发布,第一个LLM应用开发框架) 3. OpenAI Code Interpreter(2022年中,让GPT-4可以调用本地Python脚本) |
| 第三阶段:标准化工具调用(Standardized Tool Call Era) | 2022年中-2023年底 | 1. OpenAI发布Function Calling API(2023年6月),让LLM可以直接返回结构化的工具调用参数 2. Anthropic发布Claude 2 with Tool Use(2023年7月) 3. Google发布PaLM 2 with Function Calling(2023年8月) 4. 清华大学李涓子教授团队发布《Tool Learning with Foundation Models》综述论文(2023年10月) 5. OpenAPI 3.0、Swagger 2.0等API文档规范被广泛应用于工具学习 |
Function Calling/Tool Use API、OpenAPI/Swagger文档规范、综述论文《Tool Learning with Foundation Models》 | 1. OpenAI GPT-4 with Function Calling(2023年6月) 2. Anthropic Claude 2 with Tool Use(2023年7月) 3. 清华大学ToolBench(2023年10月,第一个大规模工具学习基准测试) |
| 第四阶段:自主工具学习(Autonomous Tool Learning Era) | 2024年至今 | 1. OpenAI发布GPT-4o with Advanced Tool Use(2024年5月),支持自动发现、理解、调试工具 2. Anthropic发布Claude 3 Opus with Self-Tool Use(2024年6月) 3. Meta发布Llama 3.1 405B with Tool Use(2024年7月) 4. 研究者开始尝试让Agent自主发现、创造工具 5. 多Agent协作的工具学习成为研究热点 |
Advanced Tool Use/Self-Tool Use、自主工具发现、自主工具创造、多Agent协作工具学习、强化学习与元学习的结合 | 1. OpenAI GPT-4o with Advanced Tool Use(2024年5月) 2. Anthropic Claude 3 Opus with Self-Tool Use(2024年6月) 3. AutoGPT with Advanced Tool Discovery(2024年,开源项目) |
2.3 Agent调用工具的经典闭环架构
Agent调用工具的经典闭环架构是ReAct框架(Reasoning + Acting),它是由Google Research在2022年发表的论文《ReAct: Synergizing Reasoning and Acting in Language Models》中提出的——ReAct框架的核心思想是让Agent在推理(Reasoning)和行动(Acting)之间交替进行:先推理“我需要做什么”,然后采取行动“调用工具获取信息”,然后根据工具的返回结果继续推理“我接下来需要做什么”,直到任务完成。
我们可以用一个mermaid交互关系图来描述ReAct框架的完整流程:
下面我们来逐个分析ReAct框架的每个环节:
- 用户发送自然语言请求: 用户用自然语言向Agent提出自己的需求——比如“帮我查一下明天北京的天气,然后推荐一个适合明天去的北京景点”。
- Agent传入请求到LLM: Agent将用户的请求、系统Prompt(System Prompt,用来告诉LLM它的角色、任务、工具使用规则、输出格式)、对话历史(Conversation History,用来让LLM记住之前的交互内容)一起传入LLM。
- LLM进行推理: LLM根据传入的内容进行推理——这是ReAct框架的核心环节,LLM需要完成以下5个任务:
- 理解用户请求: 分析用户的需求是什么——比如“查明天北京的天气”、“推荐适合明天天气的北京景点”。
- 确定任务目标: 将用户的需求分解为具体的、可执行的任务目标——比如“任务1:调用天气API查明天北京的天气;任务2:根据任务1的结果调用景点推荐API推荐适合的景点”。
- 选择合适的工具: 从工具库中选择能够完成当前任务目标的工具——比如选择“OpenWeatherMap API”来查天气,选择“TripAdvisor API”来推荐景点。
- 生成调用参数: 根据工具的参数Schema,生成合理的调用参数——比如OpenWeatherMap API需要的参数是“city=Beijing,CN”、“appid=YOUR_API_KEY”、“units=metric”。
- 判断任务是否完成: 检查是否已经获取了足够的信息来完成用户的需求——如果没有,就继续调用工具;如果有,就生成自然语言的任务完成结果。
- LLM返回结果:
- 如果任务未完成,LLM返回结构化的工具调用指令(比如JSON格式的工具名称、参数)。
- 如果任务已完成,LLM返回自然语言的任务完成结果。
- Agent查找工具的详细信息: Agent从工具库中查找LLM选择的工具的详细信息——包括工具描述、参数Schema、返回格式、授权方式、频率限制等。
- Agent安全地调用工具: Agent根据工具的详细信息,安全、稳定地调用外部API——这一步需要处理以下几种异常情况:
- 授权错误: API Key无效、权限不足。
- 频率限制错误: 调用次数超过了API的频率限制。
- 网络错误: 网络连接超时、DNS解析失败。
- 参数错误: 参数类型不正确、参数值不符合要求、缺少必需的参数。
- 服务器错误: API服务器内部错误、API服务器暂时不可用。
- 外部API返回执行结果: 外部API返回工具的执行结果——如果调用成功,返回用户需要的数据;如果调用失败,返回错误信息。
- Agent传入执行结果到LLM: Agent将工具的执行结果(成功/失败、返回数据/错误信息)和之前的对话历史一起传入LLM,让LLM继续推理。
- Agent展示任务完成结果: 当任务完成后,Agent将LLM生成的自然语言的任务完成结果展示给用户。
2.4 传统“Function Calling”的工作原理与局限性对比
2.4.1 核心概念:什么是Function Calling?
Function Calling(函数调用)是OpenAI在2023年6月发布的一个API功能,它的核心思想是让LLM直接返回结构化的JSON格式的工具调用指令,而不是返回自然语言的工具调用代码——这样可以大大提高工具调用的准确率和稳定性,简化LLM应用开发的流程。
后来,Anthropic、Google、Meta等公司也相继发布了类似的功能——Anthropic叫“Tool Use”,Google叫“Function Calling”,Meta叫“Tool Use”——虽然名字不同,但工作原理基本相同。
2.4.2 传统Function Calling的工作原理
传统Function Calling的工作原理可以分为3个步骤,我们可以用一个mermaid流程图来描述:
下面我们来逐个分析传统Function Calling的每个环节:
- 开发者定义工具描述: 开发者需要用结构化的JSON Schema格式定义每个工具的描述——包括工具名称、工具功能描述、参数列表、每个参数的类型、描述、是否必需、默认值、枚举值等。
- 例如,下面是一个OpenWeatherMap API的工具描述(JSON Schema格式):
{ "name": "get_current_weather", "description": "获取指定城市的当前天气信息", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,格式为「城市名,国家代码」,例如「Beijing,CN」、「New York,US」" }, "units": { "type": "string", "description": "温度单位,「metric」表示摄氏度,「imperial」表示华氏度,默认值为「metric」", "enum": ["metric", "imperial"], "default": "metric" }, "appid": { "type": "string", "description": "OpenWeatherMap的API Key,必需参数" } }, "required": ["city", "appid"] } } - 开发者将工具描述传入LLM API: 开发者将用户的请求、系统Prompt、对话历史、以及定义好的工具描述一起传入LLM API(比如OpenAI的Chat Completions API)。
- LLM理解并返回结果: LLM根据传入的内容理解用户请求和工具描述,判断是否需要调用工具——如果需要,返回结构化的JSON格式的工具调用指令;如果不需要,返回自然语言的回答。
- 例如,下面是OpenAI GPT-4返回的OpenWeatherMap API的调用指令:
{ "id": "call_abc123", "type": "function", "function": { "name": "get_current_weather", "arguments": "{\"city\":\"Beijing,CN\",\"units\":\"metric\",\"appid\":\"YOUR_API_KEY\"}" } } - 开发者解析并调用工具: 开发者解析LLM返回的工具调用指令,然后调用对应的工具。
- 开发者将执行结果传入LLM API: 开发者将工具的执行结果(成功/失败、返回数据/错误信息)传入LLM API,让LLM继续推理。
2.4.3 传统Function Calling的局限性对比
虽然传统Function Calling大大简化了LLM应用开发的流程,提高了工具调用的准确率和稳定性,但它仍然存在很多局限性——尤其是在面对“未见过的API”的场景时,传统Function Calling几乎无法使用。
我们可以用一个markdown表格来整理传统Function Calling的局限性、以及与“自主工具学习”的对比:
| 对比维度 | 传统Function Calling | 自主工具学习(本文研究的目标) |
|---|---|---|
| 工具的可见性 | 只能调用开发者提前定义好的工具,无法调用未见过的工具 | 可以自动发现、理解、使用从未见过的工具 |
| 工具描述的来源 | 必须由开发者手动定义结构化的JSON Schema格式的工具描述 | 可以自动从非结构化/半结构化的API说明(自然语言、curl示例、OpenAPI/Swagger文档、GraphQL SDL、Postman Collection)中提取出结构化的工具描述 |
| 工具的更新适应能力 | 完全无法适应工具的更新——如果工具的参数、返回格式、错误码发生了变化,开发者必须手动更新工具描述,否则LLM就会调用失败 | 可以自动适应工具的更新——根据工具的返回结果(尤其是错误结果),自动调整调用逻辑、修正参数、更新工具描述 |
| 工具库的扩展性 | 扩展性极差——工具库的大小受限于LLM的上下文窗口(比如GPT-4 Turbo只有128K上下文,最多只能定义几十个工具) | 扩展性极好——可以用向量数据库存储成千上万的工具描述,通过相似度检索快速找到合适的工具,不受限于上下文窗口 |
| 调用准确率的稳定性 | 对于提前定义好的工具,调用准确率较高,但受限于Prompt的质量和工具描述的准确性 | 对于未见过的工具,调用准确率可能会稍低,但可以通过反馈学习不断提高,稳定性越来越好 |
| 开发成本 | 前期开发成本较低——只需要手动定义工具描述 | 前期开发成本较高——需要构建API发现、理解、调试、迭代的完整框架,但后期维护成本极低 |
| 维护成本 | 后期维护成本极高——需要不断手动更新工具描述,适应工具的变化 | 后期维护成本极低——Agent可以自动适应工具的变化,不需要开发者手动干预 |
2.5 未见过的API的核心属性维度
未见过的API(Unseen API)是指Agent之前从未接触过、也没有提前定义过工具描述的API——不同类型的未见过的API,其理解和使用的难度是不同的。
我们可以用5个核心属性维度来描述未见过的API,并用一个markdown表格来整理不同类型API的属性差异:
| 核心属性维度 | 定义 | 取值范围/示例 | 对理解和使用难度的影响 |
|---|---|---|---|
| 规范性(Normativity) | API的文档是否符合统一的规范(比如OpenAPI 3.0、GraphQL SDL、Swagger 2.0) | 1. 高规范性:符合OpenAPI |
更多推荐


所有评论(0)