有人问过这样一个问题“为啥非要自创协议而不是沿用 MCP 呢自然语言是各个模型最通用的语言语言理解力达标就能用对格式从而规避 MCP 时期让模型直接输出 JSON 的不稳定。况且现在模型训练 Function Calling 的方法也证实了自然语言对 JSON 是更优越的。比如 DS内部的工具表示是 DSML 而不是 JSON。”这段话里其实藏着四个关键问题值得逐一拆开自然语言和严格 JSON哪个更适合模型来表达工具调用MCP到底是干什么的它和 Function Calling 是什么关系DeepSeek 为什么用DSML而不是 JSON我们到底该不该自创协议本文会把这些问题讲清楚并配上具体示例。一、先分清两层模型侧 vs 协议侧很多人把MCP和Function Calling混为一谈这是理解偏差的起点。层级名称解决什么问题典型形式模型侧Function Calling / Tool Use模型如何表达我要调用哪个工具、参数是什么JSON Schema 模型输出结构化参数协议侧MCPModel Context Protocol工具如何被发现、如何被不同客户端复用、鉴权怎么做JSON-RPC 2.0一个简单的类比Function Calling 是模型说我想点一杯咖啡大杯、少糖。MCP 是咖啡店的标准菜单系统任何 App 都能连上去点单而不用每家 App 都单独对接一次。MCP并没有取代模型的 Function Calling它是在 Function Calling 之上加了一层标准化协议。模型仍然需要决定调用什么只是工具的定义和执行被抽到了独立的 Server 里。二、为什么模型直接吐 JSON 会不稳定模型是在海量自然语言上预训练的对自然语言的理解和生成能力远强于严格的结构化格式。常见失败模式当要求模型输出严格 JSON 时经常出现多写或少写大括号、引号字段名幻觉location写成city类型错误数字写成字符串在 JSON 前后夹杂自然语言长参数时格式崩溃这些错误在早期 Function Calling 中非常常见尤其是较小模型或复杂参数场景。研究证据Natural Language ToolsNLT2025 年有一篇重要论文Natural Language Tools: A Natural Language Approach to Tool Calling In Large Language AgentsarXiv:2510.14453提出用自然语言替代严格 JSON 做工具选择。核心做法是把工具选择解耦让模型对每个工具回答YES / NO而不是生成完整 JSON。工具描述用自然语言。实验结果跨 10 个模型、6400 次试验准确率从69.1% → 87.5%18.4 个百分点方差下降约70%Token 消耗降低约31%后续复现研究2026在 14 个模型、8560 次试验中也得到了类似结论NLT 平均提升 14.9 个百分点关键错误减少 93%。结论对很多模型来说自然语言描述 简单决策比强制生成复杂 JSON 更稳定、更准确。三、DeepSeek 的选择DSMLDeepSeek 没有选择让模型直接生成标准 JSON而是设计了DSMLDeepSeek Markup Language。DSML 示例模型内部生成的工具调用大致长这样DSMLtool_callsDSMLinvokenameread_fileDSMLparameternamepathstringtruesrc/app.ts/DSMLparameter/DSMLinvoke/DSMLtool_calls或者一个更完整的搜索示例DSMLcallsDSMLinvokenamesearchDSMLparameternamequeriesstringtrue小柴胡冲剂 布洛芬 相互作用 一起吃/DSMLparameter/DSMLinvoke/DSMLcalls服务端再转换成标准格式推理框架 / API Server 会把 DSML 解析成 OpenAI 兼容的tool_calls{tool_calls:[{type:function,function:{name:read_file,arguments:{\path\:\src/app.ts\}}}]}为什么这样设计XML 风格的标记对模型来说更容易稳定生成标签有明确起止。参数值直接写在标签之间避免复杂的 JSON 转义。服务端负责解析和校验模型只需说清楚意图。这正是自然语言或模型友好格式优先的实践体现。四、标准 Function Calling 示例对比OpenAI / 兼容接口风格工具定义{type:function,function:{name:get_weather,description:Get weather of a location,parameters:{type:object,properties:{location:{type:string,description:The city and state, e.g. San Francisco, CA}},required:[location]}}}模型输出理想情况{tool_calls:[{id:call_abc123,type:function,function:{name:get_weather,arguments:{\location\: \Hangzhou, Zhejiang\}}}]}ClaudeAnthropic风格工具定义使用input_schema{name:get_weather,description:Get the current weather for a given city.,input_schema:{type:object,properties:{city:{type:string},unit:{type:string,enum:[celsius,fahrenheit]}},required:[city]}}模型返回的是tool_usecontent block而不是tool_calls数组。五、MCP 协议示例协议层MCP 使用JSON-RPC 2.0。下面是典型的工具发现与调用流程。1. 列出工具tools/list请求{jsonrpc:2.0,id:1,method:tools/list,params:{}}响应{jsonrpc:2.0,id:1,result:{tools:[{name:get_weather,description:Get current weather information for a location,inputSchema:{type:object,properties:{location:{type:string}},required:[location]}}]}}2. 调用工具tools/call请求{jsonrpc:2.0,id:2,method:tools/call,params:{name:get_weather,arguments:{location:Hangzhou}}}响应{jsonrpc:2.0,id:2,result:{content:[{type:text,text:Current weather in Hangzhou: 24°C, Cloudy}],isError:false}}注意MCP 客户端拿到工具定义后仍然是通过模型的 Function Calling 能力把这些工具交给模型再把模型的决策转成tools/call请求发给 Server。六、四种思路对比方案优点缺点适合场景严格 JSON Function Calling结构清晰、易解析、生态成熟模型容易格式错误Token 开销大工具少、参数简单、模型强有严格模式DSML / 模型友好标记生成更稳定模型友好需要专用解析器DeepSeek 等自研模型Natural Language Tools准确率高、方差小、Token 少参数复杂时表达能力受限工具选择为主、参数简单的场景MCP工具一次编写、多客户端复用有协议开销Token 可能更多需要跨应用、跨团队复用工具时七、实践建议模型侧优先考虑模型友好如果是自研模型或开源模型可以像 DeepSeek 一样设计更易生成的格式DSML、XML、甚至自然语言 解析而不是强行让模型当 JSON 生成器。协议侧按需选择 MCP只给自己的产品用 → 直接 Function Calling 就够了。要给多个客户端Claude Desktop、Cursor、自己的 Agent共用工具 → MCP 很有价值。工具数量非常多时注意 Token 成本有人开始转向 CLI-first 方案。两者可以共存MCP Server 对外暴露标准协议内部执行时仍然可以用任何模型友好的方式让模型决策。生产中建议加一层校验与修复即使模型很强也建议对工具调用结果做 schema 校验、重试或 fallback。八、总结自然语言或模型友好格式是模型最擅长的表达方式强制严格 JSON 会带来不必要的不稳定。DeepSeek 用 DSML、NLT 论文的实验都在验证这一点。但 MCP 解决的是另一层问题——工具的标准化发现与复用它和模型怎么表达工具调用并不矛盾。正确的理解是模型怎么说话→ 尽量贴合模型优势自然语言 / DSML 等。工具怎么被连接→ 需要协议层MCP 或其他方案来做标准化。不要把模型侧的格式选择和协议侧的生态标准混为一谈。两者解决的是不同问题也都可以根据实际场景灵活选择。