LLM 工具调用与 MCP 机制
主题LLM 如何被提供可用工具、工具调用协议、MCP 工具发现机制、以及多模型参数差异的抹平方式。一、工具调用整体流程工具调用Function Calling / Tool Use本质是一套「声明 → 决策 → 执行 → 回填」的循环在请求里声明「有哪些工具可用」(tools 定义)LLM 根据用户问题决定「是否调用 / 调用哪个 / 传什么参数」应用程序真正执行工具拿到结果把结果回填给 LLMLLM 生成最终自然语言回答关键认知LLM 本身不执行工具它只输出「我想调用某工具 参数」的结构化意图真正的执行由应用代码负责。二、如何提供可用工具工具声明主流做法在 API 请求中传入一个tools数组每个工具用 JSON Schema 描述。OpenAI 格式{model:gpt-4,messages:[],tools:[{type:function,function:{name:get_weather,description:查询指定城市的实时天气,parameters:{type:object,properties:{city:{type:string,description:城市名如 杭州},unit:{type:string,enum:[celsius,fahrenheit]}},required:[city]}}}],tool_choice:auto}Anthropic (Claude) 格式{model:claude-sonnet-4,messages:[],tools:[{name:get_weather,description:查询指定城市的实时天气,input_schema:{type:object,properties:{city:{type:string}},required:[city]}}]}关键点name工具唯一标识description最重要模型靠它判断何时调用要写清楚用途/触发条件parameters/input_schema用 JSON Schema 约束参数类型、枚举、必填项三、工具调用协议关键要素1. 调用控制字段 tool_choiceauto模型自行决定是否调用none禁止调用required/any强制必须调用某工具指定具体工具名强制调用该工具2. 模型返回工具调用意图OpenAI{role:assistant,tool_calls:[{id:call_abc123,type:function,function:{name:get_weather,arguments:{\city\: \杭州\}}}]}Anthropic{role:assistant,content:[{type:tool_use,id:toolu_abc123,name:get_weather,input:{city:杭州}}],stop_reason:tool_use}3. 回填执行结果协议核心执行完工具后必须用特定角色/类型把结果塞回对话历史并通过 id 关联OpenAI —— 用role: tooltool_call_id{role:tool,tool_call_id:call_abc123,content:{\temp\: 28, \desc\: \晴\}}Anthropic —— 用role: user里的tool_resulttool_use_id{role:user,content:[{type:tool_result,tool_use_id:toolu_abc123,content:{\temp\: 28, \desc\: \晴\}}]}4. 多轮循环回填后再次请求模型模型可能继续调用下一个工具多步/链式调用或生成最终回答stop_reason: end_turn/finish_reason: stop。5. 并行工具调用现代模型支持一次返回多个 tool_call。协议要求每个 tool_call 有独立 id回填时每个结果按 id 一一对应返回缺一不可应用可并行执行这些工具以提速6. 常见协议注意事项事项说明arguments 是字符串OpenAI 的 arguments 是 JSON 字符串需二次解析Anthropic 的 input 已是对象id 必须匹配回填结果 id 与调用 id 不匹配会报错完整对话历史每轮请求需带上包含 tool_call tool_result 的完整 messagesschema 越清晰越准description 和 enum 约束能显著降低幻觉/传错参错误也要回填工具执行失败时把错误信息作为 tool_result 返回让模型决定重试或换方案四、MCP支持哪些工具是怎么告诉 LLM 的核心结论LLM 本身并不直接知道有哪些 MCP它只认标准的 tools 定义。中间的 MCP Client宿主程序负责去各 MCP Server 发现工具再翻译成 LLM 的工具协议喂给它。整体链路MCP Server提供工具 ↑ MCP 协议 (tools/list, tools/call) MCP Client / Host如 Claude Desktop、IDE、Agent 框架 ↑ 把 MCP 工具翻译成 LLM 的 tools 定义 LLM API 请求 (tools: [...])第一步宿主如何知道支持哪些 MCP—— 靠配置{mcpServers:{filesystem:{command:npx,args:[-y,modelcontextprotocol/server-filesystem,/path]},github:{command:npx,args:[-y,modelcontextprotocol/server-github],env:{GITHUB_TOKEN:xxx}},my-remote:{url:https://example.com/mcp,transport:sse}}}宿主启动时按配置逐个连接本地用 stdio 启子进程远程用 SSE / HTTP。第二步MCP 协议的工具发现底层 JSON-RPC 2.0握手初始化{jsonrpc:2.0,id:1,method:initialize,params:{protocolVersion:2024-11-05,capabilities:{}}}列出工具 tools/list// Client → Server{jsonrpc:2.0,id:2,method:tools/list}// Server → Client{jsonrpc:2.0,id:2,result:{tools:[{name:read_file,description:读取指定路径的文件内容,inputSchema:{type:object,properties:{path:{type:string}},required:[path]}}]}}MCP Server 除了 tools还能暴露 resourcesresources/list和 promptsprompts/list发现机制类似。第三步翻译成 LLM 的 tools 定义宿主把所有 MCP Server 返回的工具聚合转换成 LLM 工具格式注入 API 请求。MCP 的 inputSchema 与 LLM 的 input_schema/parameters 几乎同构都是 JSON Schema。命名冲突处理多 Server 可能有同名工具宿主通常加前缀区分例如filesystem__read_file、github__create_issue。第四步调用回路1. LLM 返回 tool_use: { name: filesystem__read_file, input: {...} } 2. 宿主识别前缀路由到对应 MCP Server 3. 宿主向该 Server 发 tools/call 4. Server 执行返回 result 5. 宿主把 result 作为 tool_result 回填给 LLMtools/call 示例// Client → Server{jsonrpc:2.0,id:3,method:tools/call,params:{name:read_file,arguments:{path:/a.txt}}}// Server → Client{jsonrpc:2.0,id:3,result:{content:[{type:text,text:文件内容...}]}}动态更新工具列表变化通知{jsonrpc:2.0,method:notifications/tools/list_changed}宿主收到后重新 tools/list并在下一轮请求里更新给 LLM 的 tools 定义。完整图景配置文件 → 宿主知道「连哪些 MCP Server」 tools/list → 宿主知道「每个 Server 有哪些工具」 Schema 翻译聚合 → 拼成 LLM 的 tools 定义 API 请求 → 这一刻 LLM 才「知道」有哪些工具可用 tool_use → LLM 决定调用 tools/call → 宿主路由回对应 Server 执行 tool_result 回填 → LLM 生成最终回答一句话总结支持哪些 MCP 由宿主的配置决定宿主通过 MCP 的 tools/list 发现工具再翻译聚合成标准 tools 定义在每次 API 请求里告诉 LLM。LLM 全程只跟标准工具协议打交道对 MCP 本身无感知。五、不同模型参数格式差异的抹平核心结论差异主要在「客户端 / Agent 框架层」通过适配器Adapter / Provider 抽象抹平。抹平的是「协议格式」抹不平的是「模型能力和行为」。抹平发生在哪一层业务代码 ↓ 统一接口抹平层 ┌─────────────────────────────┐ │ Provider / Adapter 抽象层 │ │ OpenAIAdapter / ClaudeAdapter / GeminiAdapter │ └─────────────────────────────┘ ↓ 各自原生 API 格式 OpenAI API Claude API Gemini API两种常见实现方式Agent / SDK 框架内置适配LangChain、LlamaIndex、Vercel AI SDK、Spring AI 等定义统一的 Tool / Message 抽象内部为每个厂商写 adapter。网关 / 代理服务如 LiteLLM、OneAPI对外统一暴露 OpenAI 格式内部转译成各厂商格式。具体抹平了哪些差异以工具调用为例差异点OpenAIAnthropicGemini抹平方式工具定义键名function.parametersinput_schemafunctionDeclarations.parametersadapter 改字段名schema 本体同构调用意图tool_calls[]content[].tool_usefunctionCall统一解析成内部 ToolCall参数载荷argumentsJSON 字符串input对象args对象adapter 统一 parse 成对象结果回填role:“tool” tool_call_idrole:“user” 里 tool_result tool_use_idfunctionResponse统一封装成 ToolResult 按厂商拼回system 提示messages 里 role:“system”顶层独立 system 字段systemInstructionadapter 搬运到对应位置强制调用tool_choicetool_choicetoolConfig.mode统一枚举映射本质一套内部中间表示IR业务定义统一 Tool │ ▼ 内部 IR中立表示Message / Tool / ToolCall / ToolResult │ serialize按 provider 出站翻译 ▼ 各厂商原生请求格式 │ 调用 API ▼ 各厂商原生响应 │ parse入站翻译回 IR ▼ 内部 IR → 业务统一处理伪代码classToolCall:# 中立表示id:strname:strargs:dict# 统一是对象不管厂商用字符串还是对象classOpenAIAdapter:defto_request(self,tools,messages):...defparse_response(self,resp)-list[ToolCall]:# OpenAI 的 arguments 是字符串这里 json.loads 抹平成 dict...classClaudeAdapter:defto_request(self,tools,messages):...defparse_response(self,resp)-list[ToolCall]:...能抹平 vs 抹不平能抹平格式/协议层字段名、消息结构、system 位置参数是字符串还是对象工具定义、调用、回填的封装形式流式事件格式抹不平能力/行为层是否支持并行工具调用是否支持工具调用本身老模型/小模型可能不支持只能降级为提示词模拟 ReActJSON Schema 支持程度enum、嵌套对象、$ref 遵守度不同指令遵循度 / 幻觉率上下文窗口、token 计费、stop_reason 语义差异多模态、思维链thinking等特有能力对能力差异框架只能做「能力探测 降级策略」而非真正抹平。结论格式差异在 Agent / 框架 / 网关的适配层根据 provider 自动抹平业务代码通常无感。能力差异抹不平只能靠能力标记 降级 / 兼容策略处理。这也是很多框架有「provider」或「model capability」概念的原因——既做格式翻译也记录每个模型支持什么运行时决定走原生工具协议还是模拟方案。

相关新闻

手把手教你用PDFTranslator处理多语言技术文档

手把手教你用PDFTranslator处理多语言技术文档

做技术文档翻译的同学应该都遇到过这个问题:一份英文技术白皮书或API文档,翻译后表格错位、代码块丢失、图片和文字混成一团,最后还不如直接看原文。 今天分享一个实测好用的在线PDF翻译工具 PDFTranslator,它能比较好地保留原始排…

2026/9/30 9:28:43 阅读更多 →
AI论文写作工具对比:千笔AI与学术猹的技术解析与应用

AI论文写作工具对比:千笔AI与学术猹的技术解析与应用

1. 项目概述:AI论文写作工具的行业价值 去年帮导师审稿时,我连续遇到7篇明显由AI生成的论文,从医学影像分析到供应链优化研究,不同领域的文章却有着相似的"套路化"表达。这让我意识到:AI论文工具已经从早期的…

2026/9/28 17:56:11 阅读更多 →
ARM Cortex-M低功耗设计:时钟门控原理与Tiva™实战配置

ARM Cortex-M低功耗设计:时钟门控原理与Tiva™实战配置

1. 项目概述 在嵌入式系统开发,尤其是电池供电的物联网节点、便携式医疗设备或远程传感器中,功耗管理从来都不是一个“锦上添花”的选项,而是决定产品成败的核心指标。我经历过不止一个项目,前期功能跑得飞起,一到功耗…

2026/9/27 22:25:38 阅读更多 →

最新新闻

围棋小程序多Agent架构实战:七个Agent的职责拆分与提示词设计

围棋小程序多Agent架构实战:七个Agent的职责拆分与提示词设计

1. 为什么一个围棋小程序要拆出七个 Agent先说结论:把七个 Agent 塞进一个围棋小程序,不是为了炫技,而是被逼出来的。围棋这个场景有个很讨厌的特点——它同时要求规则绝对严谨、表达足够自然、交互还得跟得上手。你如果只用一个通用大模型硬…

2026/9/30 9:28:27 阅读更多 →
YOLOv11实时异常行为检测与智能告警系统实战

YOLOv11实时异常行为检测与智能告警系统实战

简介:《安防监控升级-基于YOLOv11的实时异常行为检测与智能告警系统》是一份41页的完整技术文档,面向安防从业者、算法工程师及计算机视觉学习者,系统阐述如何利用YOLOv11单阶段检测算法实现监控视频中的实时异常行为识别与智能告警。文档从传…

2026/9/30 9:28:27 阅读更多 →
PPT一键转视频:Python+LibreOffice+ffmpeg自动化管线详解

PPT一键转视频:Python+LibreOffice+ffmpeg自动化管线详解

加班赶PPT到凌晨三点,甲方突然来一句"顺便做个视频版本吧"——这种场景干过内容的人都不陌生。手动录屏、剪辑、卡点、压字幕,一版十分钟的片子折腾一晚上。后来我把整条流水线用代码打通了:AI生成讲解词和配图,python脚…

2026/9/30 9:28:27 阅读更多 →
Python新手避坑指南:从REPL、类型转换到pip与数据分析实战

Python新手避坑指南:从REPL、类型转换到pip与数据分析实战

1. 装好之后先别急着写代码:把"交互式环境"和"脚本文件"这两个概念掰扯清楚 1.1 命令行里的 >>> 才是你最好的练功房 安装完 Python 之后,很多新手做的第一件事就是打开记事本开始敲代码,这恰恰是最容易劝退的…

2026/9/30 9:28:27 阅读更多 →
Python logging模块详解:从零到生产级日志配置实战指南

Python logging模块详解:从零到生产级日志配置实战指南

1. 从"会用logging"到"真正懂logging":我踩过的那些坑先讲个真实的经历。几年前我在做一个分布式爬虫项目,代码写得很顺,日志模块也按网上最常见的教程配好了——basicConfig加FileHandler,level设成INFO&…

2026/9/30 9:28:27 阅读更多 →
C++ STL:list 底层结构、模拟实现与 vector 对比

C++ STL:list 底层结构、模拟实现与 vector 对比

1. list 的介绍 list 是 STL 中非常重要的序列式容器之一,它可以在常数时间 O(1) 内在任意位置进行插入和删除元素。 list 的底层结构是带头结点的双向循环链表: 每个节点包含一个数据域 data、一个前驱指针 prev 和一个后继指针 next;头结…

2026/9/30 9:27:26 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 8:16:59 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/29 8:24:48 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/29 3:55:56 阅读更多 →