通过异步管道并发执行向量检索、文本检索和语义缓存,将混合搜索等待时间从17秒降至10秒,详细对比了同步与异步管道的性能差异。
一切都按顺序执行。
P1、P2 和 P3 是三个进程。
同步意味着 P2 会在 P1 开始并完成其工作后开始,P3 会在 P2 开始并完成其工作后开始。
并非所有时候都需要这样。
在检索阶段,以混合搜索为例,我们会先做向量搜索,再做文本搜索,然后做语义缓存/上下文搜索相关的任何工作。
目标是为 LLM 提供更相关的上下文。
向量搜索需要 10 秒 文本搜索需要 5 秒 语义缓存/上下文搜索需要 2 秒
如果是顺序处理,我们需要等待 17 秒才能获得上下文。
那么,有什么方法可以减少等待时间吗?
答案就是异步管道(Async Pipelines)。
在这里,我们会同时启动 3 个线程。
一个线程做向量搜索。
另一个线程做文本搜索。
第三个线程做语义缓存/上下文搜索。
它们的完成时间可能不同。
最多,我们只需要等待 10 秒就能获得上下文。
通过这种异步管道,我们正在降低延迟。
单个线程在需要时在多个任务之间切换。这也称为并行处理。
每个任务会被分配一个独立的线程。因此,它可以按自己的时间完成。
这些线程受限于可用的 CPU 核心。
在生产级别做这件事时,我们才能看到延迟方面的真正差异。
如果我们问"今天发生了什么?"这个问题,LLM 无法回答。
如果我们问 ChatGPT 或 Gemini 同样的问题,它会给出响应。为什么?
因为工具调用(tool calling),也就是为 LLM 附加一些工具或功能。工具的结果会被输入到 LLM 中。
应用开发者负责编写工具/功能的代码。
假设应用的功能是获取天气详情。
每个开发者可能都会写自己的代码来获取天气详情。最终,所有用户/开发者得到的结果大致相同。
这不是正确的方法。
所以,MCP 的概念应运而生。
提供天气详情的负责方/所有者会编写通用工具或协议(一套规则)。
消费者/开发者将使用通用工具/协议来获取结果。
在这里,开发者不需要自己编写代码。
这个通用工具/协议就是 MCP。
MCP 会有函数及其描述。LLM 会决定调用哪个函数。
我们可以通过以下方式调用工具:
MCP 在同一台机器内。
我们也可以使用 HTTP 方法来调用 MCP,比如调用 API。
然而,使用 HTTP 会引入延迟。
为 RAG 系统创建一个 MCP。
例如,假设我们已经用收集到的文档构建了一个 RAG 系统。
由于你有数据库和 RAG 系统,你是唯一可以直接调用 RAG 系统的人。
我们可以将 RAG 功能通过 MCP 暴露出去,而不是将其限制在你的应用中。
我们可以按不同的职责或部门来分离功能。
RAG 系统 → 负责从文档中检索相关信息
MCP → 将 RAG 功能作为通用工具暴露出来
LLM/应用 → 需要信息时可以调用 MCP 工具
现在,任何能访问 MCP 的人都可以使用 RAG 功能,而无需直接访问底层数据库或编写自己的检索代码。
这样,MCP 就充当了 RAG 系统与不同应用或 LLM 之间的通用接口。
RAG 系统继续处理文档检索,而 MCP 为其他应用或 Agent 提供了一种标准化的方式来访问该功能。