最近在折腾MCP(模型上下文协议)对接DeepSeek API,想搞个能自动查天气和数据库的Agent。环境是Python 3.10 + FastMCP库,DeepSeek用的是chat模型。结果设置完tools之后,发送查询请求,DeepSeek那边一直返回空response,偶尔报个“函数调用参数格式错误”。我查了官方文档,tool定义里parameters写的是JSON Schema格式,应该没毛病啊……是不是MCP的tool调用方式和普通function calling有区别?还是说DeepSeek本身对MCP支持不完善?有没有踩过坑的老哥指点一下,感激不尽。
MCP对接DeepSeek时,模型一直返回空响应,是我姿势不对吗?
全部回复
共 189 条这问题我上个月刚踩过坑,跟你说几个排查点。
首先,MCP的tool定义和OpenAI那种function calling虽然底层都是JSON Schema,但实际传参结构有差异。DeepSeek的chat模型对tool的调用格式要求比较严格,尤其是parameters里如果用了$ref或者嵌套的allOf/oneOf,它可能直接不识别。建议你先用最简单的参数结构,比如纯type: object加properties,不要搞复杂校验,看能不能跑通。
其次,你说偶尔报“函数调用参数格式错误”,大概率是tool定义里required字段写错了。DeepSeek这边对required的处理有点迷,有时候就算参数是可选的,它也会强行塞一个空字符串进去,导致校验失败。你可以试试把所有参数都设为optional,或者把required列表清空,看空响应是否消失。
另外,FastMCP的底层实现可能和DeepSeek的API有兼容问题。我后来直接用了httpx手动构造请求,把tool列表塞到tools字段里,用tool_choice: "auto"强制触发调用,反而稳定了。你可以抓一下FastMCP实际发出的请求体,跟DeepSeek官方文档里的tool调用示例比对一下,特别是function字段名和arguments的序列化方式。
最后,建议你开一个最简单的测试,只定义1个无参tool(比如返回固定字符串),排除掉参数解析的干扰。如果连这个都返回空,那大概率是MCP协议和DeepSeek的tool dispatch逻辑之间有点不匹配,得考虑换种集成方式。
检查下tools的parameters里有没有漏掉required字段,DeepSeek对这块卡得挺严的。
哎这个坑我确实踩过,MCP的tool调用和OpenAI那种function calling底层逻辑其实不太一样,它会多一层协议封装,所以参数格式上容易出问题。你检查下FastMCP库版本,我遇到过老版本对JSON Schema的嵌套结构解析有bug,换成0.3.2之后就好了。另外DeepSeek的chat模型对MCP支持确实有点迷,它返回空响应有时候是因为tool定义里required字段没写对,或者parameters里的type写成了string但实际传了object,DeepSeek的容错率比OpenAI低很多。建议你先去掉所有tool,只发一个最简单的query,确认API连通性没问题再逐步加tool。还有个小技巧:把MCP的日志级别调到debug,看它实际发给DeepSeek的请求体长啥样,我当时就是发现它把tool定义里的$schema字段给传进去了,DeepSeek直接不认。如果还搞不定,可以试试换成DeepSeek的function calling接口直连,绕开MCP那层封装,虽然麻烦点但至少能跑通。
我上周也踩过这个坑,MCP的tool调用和直接function calling确实不太一样,它的parameters里必须严格遵循JSON Schema的$defs嵌套结构,尤其注意type和properties的层级。你检查下是不是把enum或者required写错位置了?另外DeepSeek对MCP支持其实还行,但建议先用OpenAI兼容模式测一下tool定义对不对。
同款坑踩过,折腾了三天才搞明白。MCP的tool定义确实跟OpenAI那套function calling有细微差别,主要卡在parameters的格式上——DeepSeek对JSON Schema的strict模式特别敏感,你检查一下tool定义里有没有多余的空格、缩进是不是统一用两个空格,还有那个“required”字段的位置是不是严格按照规范写的。我之前就因为把required写在了properties外面,结果一直报参数格式错误,调成内嵌到具体参数里就好了。另外建议你用MCP inspector抓一下实际发给DeepSeek的请求体,看看tools数组是不是真的被正确序列化了,有时候FastMCP库版本太新会自己加些元数据字段,DeepSeek反而不认。还有个小细节:MCP的tool调用结果要返回符合特定格式的content块,不能直接用print输出,得包装成TextContent或者ResourceContent对象才行。你要是还搞不定,可以去DeepSeek官方GitHub的issues区搜“MCP”,最近有好几个类似案例的修复记录。
MCP的tool调用和普通function calling确实有区别,你可以试试把参数格式改成MCP规范里的JSON-RPC结构。
我之前也遇到过类似的问题,后来发现是FastMCP库对tool的parameters解析要求比官方文档更严格,比如必须显式声明每个字段的"type"和"description",缺了"description"就容易返回空。另外DeepSeek的chat模型对MCP的支持确实还在迭代,建议先用OpenAI兼容模式测一下function calling,如果正常就说明是MCP层的适配问题。可以试试把tool定义里的"required"字段补全,或者换个低版本的FastMCP看看。
之前折腾MCP也遇到类似空响应的情况,后来发现是tool的parameters里嵌套层级没对齐,DeepSeek对strict格式要求比别的模型高。可以试试把JSON Schema写成最简平的字段结构,别用$ref这种引用,另外检查下FastMCP是不是最新版,老版本对MCP协议支持有坑。
检查下tools定义的parameters里有没有漏掉required字段,DeepSeek对这块卡得特别死。
最近试过类似方案,建议检查下FastMCP里tool定义是不是漏了strict参数,默认false会导致DeepSeek解析出错。
检查下tool的parameters里有没有把type: "object"和required字段写全,DeepSeek对schema要求挺严的。
之前我也遇到过类似问题,后来发现是DeepSeek的tool调用要求parameters里必须带"type": "object"这个顶层字段,而且properties里的字段描述不能为空字符串。MCP的schema解析可能更严格,建议检查下你传给FastMCP的tool定义里有没有遗漏这些细节。
检查下tools定义里是不是漏了required字段,DeepSeek对参数校验挺严格的,缺这个就容易返回空。
我也遇到过类似情况,排查下来发现是MCP的tool参数传递方式跟DeepSeek原生function calling不太一样,FastMCP默认会把参数包装成对象,而DeepSeek那边需要严格按JSON Schema展平。你可以试试在定义tool时手动指定参数格式,或者抓包看看实际发给API的请求结构,大概率是格式转换那步出了偏差。
DeepSeek对MCP的tool调用确实有点挑,试试把parameters里的type字段改成全小写,我之前卡这坑里了。
我也遇到过类似问题,后来发现是MCP的tool调用里parameters必须用strict的JSON Schema格式,而DeepSeek对某些宽松写法兼容性差。建议检查下schema里是不是漏了required字段,或者把多余的description去掉试试。另外FastMCP库版本更新后接口有点变动,我换成官方的mcp包重新写了一遍才通。
检查下tools的parameters里有没有漏掉required字段,DeepSeek对这块卡得特别死。
碰到过类似的问题,后来发现是DeepSeek对MCP的tool定义里某些JSON Schema字段解析有问题,比如“default”和“examples”这些非必需字段可能会干扰调用。建议先精简tool参数,只保留“type”“properties”“required”三个核心字段试试。另外FastMCP库的tool注册方式跟原生function calling确实有区别,得确认下是不是把参数结构嵌套在“inputSchema”里了。
老哥这个问题我上个月刚踩过,大概率不是MCP协议本身的问题,而是FastMCP库对DeepSeek的适配有点小坑。我之前也是用FastMCP搭Agent,发现它默认生成的tool定义里,parameters的JSON Schema格式和DeepSeek官方要求的function calling参数格式在嵌套结构上有细微差别,特别是当参数里有$ref或者allOf这种复杂引用时,DeepSeek的解析逻辑会直接卡住,返回空响应或者报参数格式错误。你可以试试把tool定义简化成最基础的type+properties结构,别用任何高级schema特性,然后手动在代码里把每个参数的description写详细点,甚至加个枚举值列表,这样DeepSeek的模型更容易理解。另外检查一下MCP发请求时的role顺序,我遇到过一次因为把tool结果当成system消息塞进去,导致模型上下文错乱。如果还不行,建议先绕过FastMCP,直接用requests调DeepSeek的chat/completions接口试一下同样的tool定义,排除是库的序列化问题。我最后是换了另一个MCP库才跑通的,感觉DeepSeek对传统function calling的支持比MCP这种新协议要稳得多。
我也遇到过类似的情况,后来发现是MCP里tool的parameters需要严格按照DeepSeek的function calling格式来写,尤其是required字段和嵌套结构,FastMCP自动转换时容易出偏差。建议检查一下MCP返回的tool schema是不是符合DeepSeek API的预期,或者直接打印原始请求对比官方示例。另外空响应有时候是模型没理解tool该怎么用,试试在system prompt里加一句“请使用提供的工具完成用户请求”这类引导。