「吴恩达Agentic AI模块3简报」工具使用与模型上下文协议(MCP)
概述
本简报综合分析了大型语言模型(LLM)通过“工具使用”实现代理式(Agentic)能力的核心概念、实现机制和未来趋势。关键洞察如下:
- 工具是LLM能力的延伸:工具是开发者提供给LLM调用的外部函数,使其能够超越预训练知识的限制。这使得LLM能够执行获取实时信息、查询数据库、进行网络搜索和执行复杂计算等任务,从而极大地增强了应用的实用性。
- 代理式决策是核心:工具使用的关键在于LLM能够自主决定是否、何时以及调用哪个工具来完成任务。这种非硬编码的决策过程是实现代理式工作流的基础,其标准流程为:LLM接收提示 -> 决定调用工具 -> 外部代码执行工具并返回结果 -> 结果反馈给LLM -> LLM生成最终输出。
- 实现方式的演进:工具调用的实现已从早期依赖特定提示词(如输出“FUNCTION: function_name”)的繁琐方法,演变为现代LLM原生的、基于特定语法的调用方式。诸如AISuite之类的库通过自动从函数文档字符串生成JSON Schema来描述工具,进一步简化了开发流程,使开发者能更便捷地集成工具。
- 代码执行是最强大的工具之一:为LLM提供一个通用的代码执行工具,比创建无数个特定功能的工具更具灵活性和扩展性。LLM能够通过编写和执行代码来解决复杂的数学、逻辑和数据处理问题。然而,这也带来了严峻的安全风险。最佳实践是在沙盒环境(如Docker)中执行代码,以防止潜在的数据丢失或系统损坏。
- 模型上下文协议(MCP)推动生态标准化:MCP是由Anthropic提出并被广泛采用的一项新标准,旨在解决开发者在集成各类API(如Slack、GitHub)时重复造轮子的问题。它通过定义统一的客户端(应用)与服务端(工具提供者)交互协议,将社区开发工作量从M×N(应用×工具)的复杂性降低到M+N,极大地促进了一个可共享、可复用的工具生态系统的形成。
工具使用的核心概念与价值
工具使用是赋予LLM代理能力、使其能够与外部世界交互并执行具体行动的关键机制。它将LLM从一个单纯的文本生成器转变为一个能够主动解决问题的智能体。
1.1 什么是工具?
在LLM的语境下,“工具”是指开发者编写并提供给模型使用的外部代码函数。当LLM认为需要执行某个操作或获取特定信息时,它不会直接执行代码,而是会请求调用这些预先定义的函数。
- 功能示例:
- 信息获取:
getCurrentTime()
获取当前时间,网络搜索工具获取最新资讯。 - 数据操作:
queryDatabase()
从销售数据库中查询特定客户信息。 - 计算任务:
calculateInterest()
执行精确的金融计算。 - 系统交互:
makeAppointment()
在日历中创建会议邀请。
- 信息获取:
1.2 工具使用的代理式决策过程
工具使用的核心特征在于其**代理式(Agentic)**本质,即LLM根据上下文自主决策,而非由开发者硬编码指定何时调用函数。
- 决策自主性:当面对一个问题时,LLM会评估其可用的工具集。
- 如果问题(如“绿茶中有多少咖啡因?”)能直接用其内部知识回答,它将不会调用任何工具。
- 如果问题(如“现在几点了?”)需要外部信息,它会决定调用最合适的工具(如getCurrentTime())。
- 标准工作流程:
- 输入提示:用户向LLM提出请求。
- LLM决策与请求:LLM分析请求,并从可用工具集中选择一个或多个进行调用。它生成一个符合特定格式的请求。
- 工具执行与结果返回:开发者编写的外部代码捕获LLM的请求,执行相应的函数,并将函数的返回值(如具体时间“下午3:20”)获取。
- 结果反馈与最终生成:函数返回值被送回LLM,作为其对话历史的一部分。LLM基于这个新信息,生成最终的、对用户更有帮助的回答。
这一流程可以连续进行,LLM在一个任务中可能会按顺序调用多个工具,例如先通过checkCalendar查找空闲时间,再通过makeAppointment创建日程。
2. 实现工具调用的机制
工具调用的技术实现经历了从手动、繁琐到自动化、标准化的演进。
2.1 早期实现方式:基于提示词的指令
在LLM原生支持工具调用之前,开发者需要通过详细的系统提示(System Prompt)来“教”会模型如何请求工具。
- 机制:开发者在提示词中明确规定一种特殊格式,例如:“如果你需要调用getCurrentTime工具,请输出文本‘FUNCTION: getCurrentTime’。”
- 开发者工作:
- 编写代码来解析LLM的输出文本。
- 使用正则表达式等方式检测是否存在关键词“FUNCTION:”。
- 如果检测到,则提取函数名和参数。
- 手动执行该函数,并将结果拼接回LLM的输入中。
- 缺点:这种方法非常“笨拙”(clunky),且高度依赖于提示词的稳定性和LLM的遵循能力,缺乏鲁棒性。
2.2 现代实现方式:原生语法与自动化
现代主流的LLM(如GPT-4o)经过专门训练,能够理解并使用一种标准化的工具调用语法。开发者不再需要手动设计提示词格式。
- 机制:开发者通过API将工具列表直接提供给LLM。这些工具通常通过一个结构化的JSON Schema来描述。
- JSON Schema的角色:
- 它向LLM清晰地描述了每个工具的功能、名称和所需参数。
- name:函数名,如 getCurrentTime。
- description:功能的详细描述,如“获取指定时区的当前时间”。LLM依靠此描述来判断何时使用该工具。
- parameters:函数所需的输入参数及其类型和描述。
- 自动化库(如AISuite):像AISuite这样的开源库极大地简化了这一过程。开发者只需提供Python函数,库会自动检查函数的文档字符串(docstring)和类型注解,并为其生成符合规范的JSON Schema。一个API调用(如client.chat.completions.create)就能完成从LLM决策、工具调用到结果反馈的整个循环。
3. 代码执行:一种特殊的超级工具
在所有可用的工具中,允许LLM编写并执行代码的工具尤为强大和灵活,它将LLM的计算和逻辑推理能力提升到了新的高度。
3.1 灵活性与强大功能
与其为加、减、乘、除、开方、幂运算等每一个数学操作都创建一个独立的工具,不如提供一个通用的“代码执行器”。
- 可扩展性:LLM可以自行编写代码来解决几乎任何可以通过计算解决的问题,从简单的数学题到复杂的利息计算,无需开发者预先定义每一个具体功能。
- 案例:当被问及“2的平方根是多少?”时,LLM可以生成并请求执行以下Python代码:
import math
result = math.sqrt(2)
- 执行后返回的结果1.4142…被反馈给LLM,使其能够给出精确答案。
3.2 安全风险与最佳实践
允许LLM执行任意代码伴随着巨大的安全风险。
- 真实风险案例:一个代理式编码工具曾错误地决定执行rm *.py命令,删除了一个项目目录下的所有Python文件。尽管该智能体事后“道歉”,但文件已被删除,幸运的是项目有备份。
- 最佳实践:沙盒环境:为了降低数据丢失、敏感信息泄露或系统损坏的风险,所有由LLM生成的代码都应在沙盒(Sandbox) 环境中执行。
- 沙盒技术:像Docker容器或轻量级的E2B等工具可以创建一个与主系统隔离的执行环境。即使代码包含恶意或破坏性命令,其影响也被限制在沙盒内部。
3.3 反思与调试
代码执行工具可以与“反思”(Reflection)机制相结合。如果LLM生成的代码在执行时出错,可以将错误信息(如堆栈跟踪)反馈给LLM,使其能够分析错误原因、修改代码并再次尝试,从而提高任务的成功率。
4. 模型上下文协议(MCP):工具生态的标准化
随着工具使用的普及,开发者社区面临着大量的重复性工作。模型上下文协议(MCP)的出现旨在解决这一问题,推动工具生态的标准化和协作。
4.1 MCP解决的问题
在MCP出现之前,如果多个开发团队都需要在其应用中集成Slack、Google Drive和GitHub等服务,每个团队都必须独立编写用于调用这些服务API的封装函数(工具)。
- M×N 问题:如果有 M 个应用和 N 个工具/数据源,社区总的工作量与 M×N 成正比,造成了巨大的资源浪费。
- MCP的解决方案:MCP提出了一套标准化的协议,让工具的提供方和使用方能够解耦。这使得社区的总工作量转变为 M+N:N 个工具只需被封装一次(成为MCP服务端),就可以被 M 个应用(作为MCP客户端)复用。
4.2 MCP的运作方式
MCP生态系统由客户端和服务端组成:
- MCP客户端(Client):需要访问工具或数据的应用程序。
- MCP服务端(Server):提供对工具或数据源(在MCP文档中称为“资源”)访问的软件封装层。例如,一个GitHub MCP服务端可以提供获取代码仓库文件、列出拉取请求等工具。
4.3 实际应用示例
一个集成了MCP的云桌面应用(客户端)可以连接到GitHub MCP服务端,以完成复杂任务:
- 用户请求:用户请求:“总结一下 AI-Suite 仓库的 readme.md 文件。”
- MCP交互:
- 应用(客户端)向GitHub服务端发送一个标准化的请求:“请从AI-Suite仓库获取readme.md文件。”
- 服务端执行请求,返回文件的全部内容。
- LLM处理:文件内容被送入LLM的上下文,LLM随后生成该文件的摘要。
通过这种方式,应用开发者无需关心如何具体调用GitHub的API,只需使用遵循MCP标准的客户端即可接入整个生态的工具。MCP正在成为构建强大、可扩展的代理式应用的重要标准。