尽管大型语言模型(LLM)在理解和生成人类语言方面拥有出色的能力,但它们的行动能力常受其固有架构限制。它们主要处理文本数据,缺少与外部系统直接交互的机制,无法获取实时信息,或进行超出其训练数据范围的精确计算。为了构建不仅能进行智能对话,还能有效行动的智能体,我们必须赋予它们使用外部工具和功能的能力。这里阐述了集成这些功能的方法和考量,使你的智能体能执行更多样化的任务,并更有效地与环境互动。集成外部工具的理由将外部工具集成到大型语言模型(LLM)智能体中,解决了几个基本局限性:获取最新信息:大型语言模型(LLM)基于数据集训练,但这些知识有截止日期。工具允许智能体查询实时数据源,如新闻API、金融市场追踪器或天气服务,从而提供对许多应用而言很重要的最新信息。执行行动:为了产生影响或完成任务,智能体通常需要执行发送电子邮件、调用第三方服务API(如预订系统、电子商务平台)或控制物联网设备等操作。工具为这些交互提供了桥梁。专项计算:大型语言模型(LLM)本身并未优化用于复杂算术、符号数学或运行特定算法等任务。外部工具,如Python解释器、Wolfram Alpha API或专用数据分析库,可以准确高效地执行这些计算。与专属系统交互:许多企业应用要求智能体与内部数据库、私有API或遗留软件交互。可以开发定制工具来安全受控地访问这些系统。提升效率和成本效益:对于某些任务,专用工具可能比试图强制大型语言模型(LLM)执行它们显著更快或更具成本效益,特别是对于重复性或计算密集型操作。通过启用工具使用,我们将智能体从纯粹的认知实体转变为实际的问题解决者,能够进行复杂交互。核心机制:函数调用和API使用基于大型语言模型(LLM)的智能体使用外部工具的主要方式是通过一种机制,通常被称为“函数调用”或“工具使用”。这通常涉及一个由智能体控制逻辑协调的多步骤过程:工具定义:你为智能体定义一套可用的工具。每个工具都通过其名称、明确说明其功能,以及其预期输入参数的结构(包括名称、类型和说明)来描述。此定义会提供给大型语言模型(LLM),通常作为其系统提示的一部分或通过专门的API功能。大型语言模型(LLM)决策:基于用户的查询和可用工具的说明,大型语言模型(LLM)判断是否需要工具来完成请求。如果需要,它会识别合适的工具并生成必要的参数,通常以JSON等结构化格式。例如,如果用户询问:“伦敦的天气怎么样?英镑兑美元的当前汇率是多少?”,大型语言模型(LLM)可能会决定调用两个工具:get_weather(location: "London")get_exchange_rate(base_currency: "GBP", target_currency: "USD")编排与执行:你的应用程序代码(“编排器”)接收大型语言模型(LLM)的结构化输出。它解析此输出,识别请求的工具和参数,然后执行相应的函数或进行相关的API调用。结果反馈:工具的输出(例如,天气数据、汇率)然后返回给编排器。大型语言模型(LLM)响应生成:编排器格式化工具的输出并将其反馈给大型语言模型(LLM)。大型语言模型(LLM)然后使用这些新信息合成对用户的最终响应。例如,“伦敦天气为15°C,多云。当前汇率为1英镑=1.25美元。”以下图表说明了智能体使用外部工具时的这种一般交互流程:digraph G { rankdir=TB; graph [fontname="Arial", fontsize=10]; node [shape=box, style="rounded,filled", fillcolor="#e9ecef", fontname="Arial", fontsize=10]; edge [fontname="Arial", fontsize=9]; User [fillcolor="#a5d8ff", label="用户"]; AgentLLM [label="智能体 LLM\n(推理与生成)", fillcolor="#bac8ff"]; Orchestration [label="编排逻辑", fillcolor="#96f2d7"]; ExternalTool [label="外部工具 / API\n(例如,天气服务,计算器)", shape=cylinder, fillcolor="#ffec99"]; User -> AgentLLM [label="1. 查询 / 任务"]; AgentLLM -> Orchestration [label="2. 工具调用请求\n(例如,{\"tool_name\": \"get_weather\", \"args\": {\"location\": \"London\"}}技术,以提升大型语言模型智能体的能力。")]", color="#1c7ed6", fontcolor="#1c7ed6"]; Orchestration -> ExternalTool [label="3. 执行工具\n(API调用,函数执行)", color="#0ca678", fontcolor="#0ca678"]; ExternalTool -> Orchestration [label="4. 工具输出 / 结果\n(例如,{\"temperature\": \"15°C\", \"condition\": \"cloudy\"})", color="#f76707", fontcolor="#f76707"]; Orchestration -> AgentLLM [label="5. 格式化结果到LLM", color="#1c7ed6", fontcolor="#1c7ed6"]; AgentLLM -> User [label="6. 合成最终响应"]; }此图表展示了用户查询如何引导大型语言模型(LLM)决定使用工具,工具调用的编排,以及随后大型语言模型(LLM)使用工具输出生成响应的整个流程。主要的LLM供应商(如OpenAI、Google、Anthropic)和框架(如LangChain和LlamaIndex)都提供内置的函数调用支持,标准化了工具定义和大型语言模型(LLM)输出的格式。这显著简化了使用工具的智能体的开发。设计有效的工具接口大型语言模型(LLM)正确选择和使用工具的能力,很大程度上取决于该工具的描述质量。为你的智能体设计工具接口时,请考虑以下做法:描述的清晰性和准确性:工具的名称和描述至关重要。描述应清楚说明工具的用途、功能以及何时使用。使用明确的语言。例如,与其说“获取数据”,不如说“检索给定股票代码的当前股价”。参数明确:名称:参数名称应具有描述性(例如,target_currency 而非 tc)。类型:准确指定数据类型(例如,字符串、整数、布尔值、数字、数组、对象)。许多函数调用功能支持使用JSON Schema进行类型定义。描述:每个参数都应有描述,解释其含义和任何特定的格式要求(例如,“日期格式为YYYY-MM-DD”)。必填与可选:明确指出哪些参数是必填项。大型语言模型(LLM)需要此信息来生成有效请求。原子性:目标是让工具执行单一、明确定义的任务。过于复杂、操作模式过多的工具会使大型语言模型(LLM)感到困惑。如果一项任务涉及多个步骤,通常最好定义几个原子工具,让大型语言模型(LLM)可以串联使用,或者在更高级的工作流中管理此序列(如第4章所述)。结构化和可预测的输出:工具返回的数据应采用一致的、结构化格式(JSON很常见)。这使得你的编排代码更容易解析,也使大型语言模型(LLM)更容易理解。信息丰富的错误处理:当工具失败时,应返回有意义的错误消息。这使得大型语言模型(LLM)(或编排逻辑)能够理解出了什么问题,并可能使用不同参数重试或适当地通知用户。例如,一个简单货币转换工具的定义可能如下所示(采用JSON格式):{ "name": "get_currency_conversion", "description": "使用当前汇率将金额从源货币转换为目标货币。", "parameters": { "type": "object", "properties": { "amount": { "type": "number", "description": "要转换的金额。" }, "source_currency": { "type": "string", "description": "源货币的三字母代码(例如,USD、EUR)。" }, "target_currency": { "type": "string", "description": "目标货币的三字母代码(例如,JPY、GBP)。" } }, "required": ["amount", "source_currency", "target_currency"] } }这种详细程度有助于大型语言模型(LLM)生成准确的请求,例如: {"tool_name": "get_currency_conversion", "args": {"amount": 100, "source_currency": "USD", "target_currency": "EUR"}}与外部API集成许多工具将涉及与外部API(应用程序编程接口)交互。这需要注意以下几点:认证和授权:安全地管理API密钥、令牌(例如OAuth)或其他凭证。避免硬编码敏感信息;使用环境变量或专门的秘密管理服务。确保你的智能体或其工具拥有访问API所需的必要权限,并遵循最小权限原则。速率限制和配额:注意API速率限制。对临时错误或超出速率限制错误,实施带指数退避的重试机制。设计智能体高效使用工具,避免不必要的配额限制。错误处理:网络问题、API停机或无效请求都可能发生。你的工具执行逻辑必须优雅地处理HTTP错误代码(4xx, 5xx)和API特有的错误响应,将它们转换为大型语言模型(LLM)或用户可以理解的信息。数据解析和转换:API返回各种格式的数据(通常是JSON或XML)。你的工具包装器需要解析这些数据,并可能在将其发送回大型语言模型(LLM)之前进行转换或摘要。大型语言模型(LLM)的上下文窗口是有限的,因此避免用过于冗长的API响应来填充它。代码执行环境一种更高级的工具集成形式涉及允许智能体在沙盒环境中生成和执行代码,通常是Python。这对以下任务很有用:数据分析和可视化:生成Python代码以使用Pandas或Matplotlib等库。复杂计算:执行超出简单算术范围的计算。动态脚本编写:创建小脚本以自动化一系列操作。然而,代码执行带来了重要的安全考量:沙盒化:绝对有必要在高度受限、隔离的沙盒中运行大型语言模型(LLM)生成的代码(例如,使用Docker容器、WebAssembly运行时或专门的安全执行环境),以防止它访问敏感系统资源或执行恶意操作。资源限制:对智能体执行的任何代码施加严格的CPU时间、内存使用、网络访问和执行时间限制。输入/输出净化:仔细净化提供给代码的任何输入以及由其生成的任何输出。权限控制:限制执行环境的能力。例如,除非明确允许特定、受信任的操作,否则禁止任意文件系统访问或网络调用。尽管功能强大,但直接代码执行功能应以极其谨慎的态度和安全措施来实施。对于许多使用场景,对预先编写的、受信任的代码进行明确定义的函数调用(通过标准工具集成)是更安全的替代方案。工具使用的高级考量随着多智能体系统复杂度增加,工具集成中的几个高级议题变得相关:工具发现:如果智能体可以访问大量工具,大型语言模型(LLM)可能难以高效选择最合适的工具,特别是当工具描述的提示大小变得过大时。利用工具描述的向量相似性搜索来检索相关工具等技术可以提供帮助。动态工具管理:系统可能需要无需重启整个智能体即可添加、移除或更新工具。这涉及设计你的编排层以动态加载和管理工具定义。工具使用管理:在多智能体系统或企业环境中,你可能需要机制来控制哪些智能体可以访问哪些工具,跟踪工具使用情况以进行审计,并执行策略。顺序工具调用(链式):通常,一个任务需要一系列工具调用,其中一个工具的输出成为另一个工具的输入。大型语言模型(LLM)可以被提示来规划这些序列,或者像LangChain这样的框架提供了特定的结构(例如“链”或“图”)来管理此类多步骤工具调用。优化成本和延迟:每次工具调用,特别是对外部API或代码执行环境的调用,都会引入延迟和潜在的经济成本(例如,大型语言模型(LLM)处理结果的令牌成本、API使用费)。考虑:缓存:如果数据不是高度易变的,缓存具有相同参数的频繁调用工具的结果。并行化:如果需要调用多个独立工具,探讨并行执行它们以降低整体延迟。摘要:指示大型语言模型(LLM)或工具包装器在将冗长工具输出重新注入大型语言模型(LLM)上下文之前进行摘要,从而节省令牌和处理时间。集成外部工具和功能是构建真正有能力的大型语言模型(LLM)智能体的基本步骤。通过精心设计工具接口、安全管理API交互以及考量编排逻辑,你可以将智能体的能力拓展到远超简单文本生成,使它们能够获取信息、执行行动,并以更扎实和有效的方式解决复杂问题。这为我们将在后续章节中讨论的更复杂的工作流编排和协作行为奠定了坚实基础。