我是从 GPT-4 开始用 LLM,一开始也就是对话,一来一回的跟玩赛尔号似的,然后后来突然提出了 MCP 这个东西,给模型提供了“扩展能力”的统一协议。
然后一开始我记得还是靠提示词约束让模型返回 JSON(这个记不清楚了,因为我用的各种2api,我隐约记得当时很多llm的接口都没有function call能力),然后工具解析器去解析处理,那时候大家似乎也没啥上下文控制的意识,毕竟就只是对话。
如果mcp来的晚一点,在大家有了控制上下文的意识后,设计之初,就设计成这样的架构,似乎更好?以下内容为我扯犊子,“Tool Search” 咋实现的我还没看 ^-^
只暴露 1 个 tool,用来查询这个 MCP 有哪些sub tool和执行 subtool,subtool 才是真正的“tool”
描述和 skill 的描述一样,说明此 MCP 是干什么的、什么时候用、各个 subtool「是什么,什么时候用」(整体的描述,比如说一个网络兼网页抓取搜索工具,以 exa 为例就是:此工具用于网络搜索及页面抓取,subtool 为 fetch页面抓取 与 search页面搜索),然后通过 type 来区分语义,举一个不那么恰当的例子,具体协议肯定要设计的更精妙一些:
传入参数 sub tool 的名称 ,查询subtool的用法:
{
"type": "sub_tool_query",
"main_tool_name": "exa",
"sub_tool_name": "fetch"
}
返回结果是 subtool 的具体用法:
{
"type": "sub_tool_query_result",
"subtool": "fetch",
"schema": [
{
"name": "url",
"type": "string",
"required": true,
"description": "要抓取的内容url"
},
{
"name": "outputformat",
"type": "string",
"required": false,
"enum": ["markdown", "json"],
"description": "输出格式,选一个"
}
]
}
调用 subtool:
{
"type": "mcp_sub_tool_call",
"main_tool": "xxxx",
"sub_tool": "xxx",
"sub_tool_input_scheme": {
*略*
}
}
灵活性似乎是不如skill,但如果把mcp的定义json也搞的精细化一点,工具的描述用默认值+可覆盖,这样大家还能自己diy描述,写上自己的喜好,比如exa让他做论文搜索,tavily做日常生活内容搜索工具;这样的话大家都用一样的协议岂不是生态会非常繁荣,模型也会内化,用的飞起。
skill 就完全可以和他“父母”——“command”一样(个人拙见,skill给我的感觉就是一个优化版的command,而command就是给叽里咕噜一大段提示词一个快捷方式,一键输入),单纯地用来描述这个业务怎么去做、这类任务怎么去解决,而不是塞个 script 目录下面放各种脚本或者可执行文件。然后在 skill 里塞上脚本或者可执行文件的用法,那不是白渐进式披露了吗?叽里咕噜说一堆脚本的用法,不如用 MCP 封装。当然脚本也能封装,但是协议不统一啊。MCP 协议统一,大家都一个用法,预训练里就学会怎么用了,到时候都不用教模型,自己库库就干了 ^-^