通过MCP实现了PC端应用与IMA知识库的“隐秘”交流,即在PC端应用中形成的问题通过MCP提交给IMA,由LLM调用自己在IMA的专用知识库进行解读,并把结果回传的PC端应用,全程无需人为干预均在后台完成,看不到PC端与IMA的认证、链接、选库等过程,该实现过程可参见前期公众号文章《通过IMA-Copilot-MCP实现与IMA的“隐秘”交流》。

    实现了与IMA丝滑的后台交流,即解决了LLM解读专用知识库的问题,也极大地提高了应用效率。但目前与LLM交互的程序基本上是问答式、串连的,如果实际应用中问题比较多,交互IMA的效率将直接影响整个应用效率,于是接下来做了两个方面的尝试:

第一,能不能把 MCP 方式改成 CLI

第二,如果继续使用 MCP,能不能把原来的串行问答改成并发问答?

    于是围绕这两个问题,进行了一轮实际改造。

    最后的结果是:

    CLI 可以实现,但对于这个项目来说,把 MCP 包装成 CLI 并没有真正改变 IMA 的访问方式;真正值得优化的,是 MCP 模式下的并发问答。

一、从MCP 到 CLI:本想换一种调用方式,结果发现并没有那么简单

1. 最初的想法很简单

    原来的程序是通过 MCP 调用 IMA。

    所以最初的想法其实非常直接:

    既然MCP 已经提供了 IMA 的问答工具,那能不能不通过原来的MCP程序调用,而是直接在命令行里调用MCP暴露的工具?

    从概念上看,这似乎并不复杂。

    比如:

    命令行调用 MCP 工具得到 IMA 的回答

        于是开始尝试做一个 CLI 版本。

    2. 真正做起来才发现:MCP 工具并不是一个可以直接调用的函数

        实际开始改造以后,很快发现事情没有想象中那么简单。

        表面上看,我们需要调用的似乎只是一个:

        

      ask_with_kb

          但这个工具真正能够工作,并不是因为调用了一个简单的函数。

          它背后实际上依赖了一整套环境和实现。

          首先是IMA 的登录认证状态

          包括 Cookie、BKN、USKEY 等认证信息。

          其次是知识库的配置和 ID

          程序需要知道到底访问哪个 IMA 知识库,以及知识库名称如何解析成对应的 ID。

          再往下,还有MCP Client 与 MCP Server 之间的连接和初始化

          而真正向 IMA 发起问答请求时,又涉及 IMA 内部接口、SSE 数据解析、Token、重试以及并发控制等逻辑。

          也就是说,所谓:

      “调用一下 MCP 工具”

          实际上是建立在下面这一整套链路之上的:

        CLIMCP ClientMCP Server认证信息知识库配置IMA ClientIMA 内部问答接口

            所以,MCP 工具并不是一个拿过来就可以独立运行的“黑盒函数”。

        3. 这时候问题就变成了:CLI 到底是在取代 MCP,还是在包装 MCP?

            如果 CLI 自己重新实现上面这些东西,那么它确实可以最终直接访问 IMA。

            但这样一来,CLI 就必须自己负责:

          IMA 登录态··Cookie 等认证信息··知识库 ID··MCP 原本承担的连接逻辑··IMA 接口调用··SSE 解析··Token 刷新··重试··并发控制·

              这实际上已经不是简单的“把 MCP 改成 CLI”了。

              而是:

              把MCP Server 中原本负责 IMA 访问的核心逻辑,重新搬到 CLI 里面。如同只需一条命令行,现在需要一个批命令BAT了。

              这样做当然技术上可行,但也意味着要重新维护一套与 MCP Server 高度重复的代码。

              于是还有另外一种更简单的办法:

                          CLI 不自己实现这些功能,而是继续调用 MCP。

              这就变成:

            CLIMCP ClientMCP ServerIMA

                CLI 只是负责:

            通过命令行调用MCP 提供的工具。

            4. 结论:CLI 可以做,但对于这个项目没有改变访问方式

                做到这里,答案其实已经比较明确了。

                如果目标只是:

            “我想有一个可以在命令行中使用的 IMA 工具。”

                那么 CLI 当然有价值。

                但如果最初的目标是:

            “我想把 MCP 换掉,不再依赖 MCP Server。”

                那么简单地增加一个 CLI 并没有实现这个目标。

                因为底层仍然是:

              CLIMCPIMA

                  真正访问 IMA 的,依然是 MCP Server。

                  所以这次尝试最终得到的结论是:

                  CLI 并没有取代 MCP,只是把 MCP 工具包装成了 CLI。

                  而对于当前这个项目来说,这种改变并没有带来实质性的访问方式变化。

              二、既然CLI 没有必要,那就回到 MCP:真正的问题是什么?

                  既然 CLI 只是 MCP 的包装,那么继续折腾 CLI 就没有太大意义。

                  与其换一种调用方式,不如回到原来的 MCP 架构,看看真正影响程序体验的问题是什么。

                  很快就发现:

                  原来的多问题问答是串行的。

              1. 原来的问答方式:一个接一个

              假设程序需要向 IMA 提出三个问题:

                问题1等待答案1问题2等待答案2问题3等待答案3

                    也就是说:

                    前一个问题没有完成,后一个问题不会开始。

                    而且原来的程序还有一个特点:

                        一个问题完成以后,答案会立即显示。

                    所以它的特点其实是:

                  串行执行+即时输出

                      这在逻辑上没有问题,但如果三个问题彼此独立,那么显然存在进一步优化的空间。

                  2. 第一次尝试:让多个问题并行

                  既然三个问题互相独立,那么自然想到:

                  图片

                      理想情况下:

                      三个问题同时开始,哪个先得到答案,就先显示哪个。

                      例如:

                          问题1:8 秒

                          问题2:5 秒

                          问题3:6 秒

                      串行执行需要大约:

                          8 + 5 + 6 = 19 秒

                      而真正并行时,理论上只需要等待最慢的那个:

                          max(8, 5, 6) = 8 秒

                      当然,实际速度还会受到 IMA 服务端、网络以及各种通信开销的影响,但方向是明确的:

                  如果服务端允许并发,多问题问答没有必要一个一个等待。

                  3. 但第一次并发尝试,结果反而更慢了

                      问题来了。

                      把提问改成并发以后,实际运行却发现:

                      并没有变快,甚至比原来的串行方式更慢。

                      这就说明:

                          客户端能够并发,不代表整个调用链能够并发。

                      于是继续向下检查 MCP Server。

                  4. 真正的瓶颈:MCP Server 把并发限制成了 1

                      最终在.env中找到关键配置:

                          IMA_ASK_CONCURRENCY_LIMIT=1

                      也就是说,MCP Server 默认只允许一个 IMA 问答同时执行。

                      因此,即使客户端同时发出三个请求:

                  图片

                      到了服务端以后仍然会变成:

                          请求1 → 执行

                          请求2 → 等待

                          请求3 → 等待

                      所以所谓“并发”,实际上只是:

                      客户端并发发起,服务端排队执行。

                      而且之前的并发方案还额外创建了多个 MCP 会话,需要分别进行初始化。

                      结果不仅没有获得并发带来的收益,反而增加了额外开销。

                      这也解释了为什么第一次并发尝试会比串行更慢。

                  5. 找到瓶颈之后,真正的优化方向就明确了

                      问题已经不是:

                      CLI 还是 MCP?

                      而是:

                      MCP Server 是否允许多个 IMA 问答同时进行?

                      于是决定回到原来的 MCP 架构。

                      先调整.env文件中的:

                          IMA_ASK_CONCURRENCY_LIMIT

                      从:1 调整为:2 

                      这一步才是真正打开并发能力的关键,如图:

                  图片

                   

                  6. 新版本:真正并发,而不是“假并发”

                      新的程序使用ThreadPoolExecutor 同时发起多个 MCP 请求。

                      结构变成:

                  图片

                      MCP Server 允许两个问答同时执行。

                      因此,客户端的并发才真正有机会转化为服务端的并发。

                  7. 谁先完成,谁先显示

                      并发以后,还有一个问题:

                          三个问题的完成顺序可能不一样。

                      例如:

                    问题1 → 8 秒问题2 → 5 秒问题3 → 6 秒

                        那么实际显示顺序应该是:

                      5 秒 → 答案26 秒 → 答案38 秒 → 答案1

                          而不是等问题1完成以后才显示问题2。

                          因此新版本采用:

                          哪个请求先完成,就立即回调显示哪个答案。

                          但是最终结果仍然按照原始问题顺序归位:

                        问题1问题2问题3

                            这样既保证了实时性,也不会影响后续结果处理。

                        8. 最终验证:这次是真正的并发

                            修改以后,通过带延迟的模拟 MCP Client 对程序进行了测试。

                            重点验证的是:

                        在第一个请求完成之前,其他请求是否已经发起。

                        测试结果确认:

                        图片

                        三个请求确实可以在前一个请求完成之前全部发出。

                        同时验证了:

                          ·双问可以并发;··三问可以并发;··谁先完成谁先显示;··最终结果仍按照原问题顺序排列;··MCP Server 的并发限制已经调整为 2;··原来的meihua_yishu_web.py 保持不变。·

                          至此,真正的并发问答才算实现。

                          三、最后的结论

                              回头看这次改造,其实解决的是两个不同的问题。

                          第一个问题:MCP 能不能改成 CLI?

                              能。

                              但如果 CLI 只是:

                              CLI → MCP → IMA

                              那么它只是 MCP 的命令行包装。

                              如果真的想摆脱 MCP,就必须把 MCP Server 中的 IMA 访问、认证、SSE、Token、重试等逻辑重新搬到 CLI 中。

                              对于当前项目来说,这样做成本更高,而且没有明显收益。

                              所以:

                              没有必要为了CLI 而放弃 MCP。

                          第二个问题:MCP 能不能优化?

                              能,而且值得优化。

                              真正的问题并不是 MCP 本身,而是:

                              IMA_ASK_CONCURRENCY_LIMIT=1

                              导致多个问答只能串行执行。

                              把服务端并发限制提高以后,再配合客户端并发请求,就可以实现:

                            多个问题同时发起谁先完成谁先显示最终结果按原顺序归并

                            这才是这次改造真正有价值的地方。

                            Logo

                            欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

                            更多推荐