零、一些前言
首先感谢锦恢 @LSTM-Kirigaya 佬深入浅出的fc原理分析:大模型调用 MCP 工具 (function calling) 的两种基本方法和原理 - 资源荟萃 - LINUX DO。大家对这部分比较感兴趣的话可以先看下佬对于fc的介绍,然后根据这个帖子补充一些具体细节即可。
中午有佬说jetbrains ai有可能支持mcp,所以便开始着手研究如何把fc功能加入进去,目前基础思路已经走通,但奈何下午和晚上有事,无法立即实现。如果大伙看完本帖由想法,欢迎大伙提交PR,让该渠道成为claude code的后备力量。(不建议直接把这个帖子喂给AI一步生成,我怕AI恐怖的幻觉会侵扰原本简单的思路)
一、jetbrain2api (以下简称jb)function calling 可能性分析
通过抓包/user/v5/llm/chat/stream/v7
接口,可知jb的请求体包含了functions的相关信息,且以llm.parameters.functions
的json
格式进行声明。
为了便于理解,一个示例如下:
{
// 注:前面的system和user、assistant交互信息已略去,且参数信息也有简化
"parameters": {
"data": [
{
"type": "json",
"fqdn": "llm.parameters.functions"
},
{
"type": "json",
"value": "[
{
\"name\": \"exact_search\",
\"description\": \"搜索代码实体或文件\",
\"parameters\": {
\"type\": \"object\",
\"properties\": {
\"searchType\": {
\"type\": \"string\",
\"enum\": [\"symbols\", \"classes\", \"files\", \"methods\"]
},
\"query\": {
\"type\": \"string\",
\"description\": \"搜索查询\"
}
},
\"required\": [\"searchType\", \"query\"]
}
},
{
\"name\": \"find_text\",
\"description\": \"在文件内容中搜索文本\",
\"parameters\": {
\"type\": \"object\",
\"properties\": {
\"pattern\": {
\"type\": \"string\",
\"description\": \"搜索模式\"
}
},
\"required\": [\"pattern\"]
}
},
{
\"name\": \"search_web\",
\"description\": \"搜索网络信息\",
\"parameters\": {
\"type\": \"object\",
\"properties\": {
\"query\": {
\"type\": \"string\",
\"description\": \"搜索查询\"
}
},
\"required\": [\"query\"]
}
}
]"
}
]
}
}
通过查阅资料可知,value
里的内容是标准的openai格式下的tools声明。大伙可以自行对比。
现在我们知道了jb是怎么声明tools的,那 他是如何调用的呢? 我们继续往下看。当我们在pycharm(或其他IDE)中成功调用了一次MCP时,我们在小黄鸟中就可以看到这样的data type:FunctionCall
。这个声明意味着jb正在调用tools,且观测数据流内容可以知道其返回过程基本上就是声明调用的tool -> 流式传输参数
让我们对比着看一下openai格式下的tool calls(这里以流式为例),你会发现逻辑是差不多一致的,这就意味着我们只需做一次格式适配即可完整的发起一次tool calling。
但到这里还没有完结,我们还需要知道如何返回给jb工具调用所获得的信息。所以我们紧接着看下一个包(没错,当jb返回了"reason": "function_call"
后,MCP会调用得到结果并返回给jb,然后jb会携带这个mcp的调用结果再发送一次请求)。观察这个包的请求体(忽略示例图中的content即可),你会发现其形式非常简单,直接在messag数据里多了一条function_message
就完事了。
再结合看一下openai官方给出的tools调用信息返回示例,你会发现,哇简直美好,又是一个简单的格式适配就完事了~(不过通过观察可知这里的tool call id需要我们在tool calling那一步就适配生成)
至此,思路上全部走通,jb2api是有极大可能支持openai 官方function calling的! 所以大伙赶紧摩拳擦掌吧~
二、补充一下cherry studio那种更粗暴的调用方式
我们知道cherry studio甚至能让逆向渠道调用fc,那这么离谱的操作是怎么做的呢?其实锦恢佬已经给出了答案,没错就是粗暴的在system prompt中进行声明(甚至用了奖金大法!),然后强迫大模型以xml格式严格调用mcp,这样就让原本不支持tools的逆向渠道也支持fc了。
( 这下知道有些中转是怎么用fc来标榜自己是官转了吧
)
// 注:一个示例,重点看最后的$1,000,000,哈哈哈哈哈
{
"role": "system",
"content": "In this environment you have access to a set of tools you can use to answer the user's question. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.\n
\n## Tool Use Formatting
... ...
\n# User Instructions\n
\n\nNow Begin! If you solve the task correctly, you will receive a reward of $1,000,000.\n
"
}
而cherry返回给LLM fc调用结果的方式也更加简单粗暴,即直接写一个user信息返回给LLM(是真夸张啊)
那这么简单轻松的实现如果直接在2api server端实现是什么效果,不用我多说了吧?(诶,等等,这不会给号商思路了吧 不过号商应该忙着捞钱,没空看200字以上的内容吧)