最近在折腾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时,模型一直返回空响应,是我姿势不对吗?
全部回复
共 2 条这问题我上个月刚踩过坑,跟你说几个排查点。
首先,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逻辑之间有点不匹配,得考虑换种集成方式。
我也遇到过类似的情况,后来发现是MCP的tool定义里parameters的嵌套层级和DeepSeek要求的JSON Schema有点不一样,它更严格。你可以试试把tool的input_schema直接写成不带额外包装的纯JSON Schema格式,别用FastMCP默认的封装。另外,有些模型对工具名大小写敏感,检查一下是不是这里出了问题。