首页 / 文章

基于MCP服务器且背后连接Pinecone向量数据库的语义搜索服务

一种可重复使用的语义搜索服务:将PDF文件分割成小块,将嵌入向量存储在Pinecone向量数据库中,然后让任何智能体通过FastMCP服务器查询这些数据。

发布者:REACTAPP.TOP阅读约 7 分钟1589 词

来源: Building a Semantic Search Pipeline with Pinecone and MCP

语言模型只能依据训练时所见的内容来回答问题。工程标准、政策手册、产品规格以及内部维基文档对它来说是不可见的,除非在提问时提供这些资料。此处描述的流程可解决PDF文档集的这一问题:文档一旦被嵌入Pinecone,任何AI智能体都可以通过基于FastMCP SDK构建的MCP服务器来查询它们。

为何关键词搜索不够理想

简单的关键词搜索看似是显而易见的解决方案,但人们很少用文档中确切的用词来表述问题,因此相关内容往往会被遗漏。同义词词典和查询扩展虽能有所帮助,但两者都依赖于人工定义的词汇关系,且都无法理解这些词汇的实际含义。

语义搜索采用不同的方式。文档和查询都会被转换为能够编码含义的向量嵌入,然后通过余弦相似度来判定相关性,该指标用于衡量两个向量在嵌入空间中指向同一方向的接近程度。分数越高,语义关联越强,因此即使词汇完全不同,相关的段落也会被检索出来。比如“植物如何将阳光转化为能量?”这样的问题,即便文本中没有出现“叶绿体”和“光合作用”这两个词,也能找到相关内容。

两个组成部分:向量数据库与MCP服务器

该系统分为两个可独立变化的部分:数据摄取流程和MCP服务器。数据摄取针对每份文档执行一次,之后任何连接的智能体都可以通过服务器反复查询相同的索引知识。

该数据摄取流程可将原始 PDF 转换为可搜索的向量。它首先提取文本,将其分割成重叠的片段,使用 Pinecone Inference 生成嵌入向量,然后将这些向量写入 Pinecone 索引中。为大量文档生成嵌入向量需要消耗大量计算资源,因此简单的日志记录功能可以避免重复处理。对于每个已索引的文件,系统都会存储其最近一次生成嵌入向量的时间。在下一次运行时,流程会将该文件的当前修改时间与存储的时间进行比较:如果文档有变动,则会重新生成嵌入向量;如果文档未变,则保留原有的向量。这样一来,数据库就能随时反映文档的变更情况,同时避免不必要的嵌入向量生成操作。

基于FastMCP构建的MCP服务器会接收来自智能体的自然语言问题,将其嵌入后,在Pinecone中进行相似度搜索,最终返回得分最高的片段。由于采用MCP接口,多个AI应用无需了解向量数据库或背后的嵌入模型,即可共享同一检索服务。

刻意将这两部分分开设计,这样即便更换嵌入模型、调整分块方式或重建向量索引,也不会影响到MCP接口或依赖它的任何智能体。

构建嵌入与分块流程

PDF文件是为人类阅读设计的,而非用于机器检索,因此必须先将其转化为能够体现含义的格式。该处理流程首先使用Python的pypdf库从每个文件中提取文本,逐页读取并将结果合并为一个字符串,以便后续处理。它既支持单个文件,也支持整个目录,因此无需更改检索部分即可对新的文档集进行索引。

选择分块方式

提取文本后,文档会被分割成称为“块”的较小部分,而这一决策被证明是整个处理流程中最为关键的因素之一。嵌入模型具有固定的上下文窗口,因此无法将整份文档作为一个向量来嵌入。即便文档大小符合要求,对整个文件进行单次嵌入也会产生过于宽泛且模糊的表示,因为多个无关主题会被挤在一起,从而导致检索精度下降。

因此,每个文档会被分割成大小固定且相互重叠的片段,这样每个嵌入向量就能代表更短、更具体的文本范围。确定片段大小需要在上下文覆盖度与精确度之间取得平衡。较小的片段通常能更准确地检索信息,因为每个嵌入向量所表达的概念更为狭窄,但它们会产生更多的向量,增加索引时间和存储开销。较大的片段则能保留更多周边上下文,减少向量数量,不过每个嵌入向量所涵盖的信息范围更广,可能会降低精确度。虽然存在基于语义或句子结构的更复杂的分段方式,但对于通用检索而言,简单的固定大小分段已被证明是一种简单有效的基准方法。

chunks = [
    text[i:i+500]
    for i in range(0, len(text), 450)
]

/*
Fixed-size overlapping chunk generation used during document ingestion.
A chunk length of 500 characters and a stride of 450 characters preserve
contextual continuity while maintaining semantic specificity.
*/

使用 Pinecone 生成嵌入向量

接下来,文本块会被转换为嵌入向量。嵌入向量是文本的密集数值表示,能够编码其含义。语义搜索并非通过匹配关键词来实现,而是通过比较向量值,因此即使词汇不同,相关的段落也能被匹配到。在嵌入空间中,“猫”和“狗”的向量值彼此靠近,而“猫”和“飞机”的向量值则相距甚远,这样就可以通过数学方法计算相似度,而无需完全依赖单词的精确匹配。

此处使用的嵌入模型是 Pinecone 提供的托管型多语言 e5-large 模型,可通过 Pinecone Inference API 访问。由于是托管服务,无需单独部署或维护机器学习模型,因此数据处理代码可以专注于文档处理工作,整体架构也更为简单。

选择该模型是因为它专为语义检索优化,并支持一百多种语言。E5系列还将查询语句和文档片段视为不同的输入类型,这非常有利于检索工作。在索引阶段,数据块会被作为片段进行嵌入,因为它们才是可检索的内容。在查询阶段,用户的提问则会被作为查询语句嵌入。两者最终都会被置于同一个语义空间中,因此即便表述方式差异很大,也能提高找到合适内容的概率。

就吞吐量而言,数据块会以96个为一组发送到API,这是Pinecone Inference目前针对multilingual-e5-large模型允许的最大批次大小。与逐个发送数据块相比,每次请求发送更多数据块可以减少API调用次数,更高效地利用资源,并缩短索引构建时间。处理完成的嵌入向量及其元数据随后会被存储在Pinecone向量数据库中,以备检索使用。

embeddings = pc.inference.embed(
    model="multilingual-e5-large",
    inputs=batch,
    parameters={"input_type": "passage"}
)

用于语义搜索的MCP服务器

在文档被索引之后,智能体需要一种方式来访问这些数据。与其直接将向量数据库暴露给应用程序,不如使用基于FastMCP构建的模型上下文协议服务器来作为接口。MCP为AI应用程序提供了一种标准化的工具调用方式,因此任何兼容的客户端都可以在无需了解底层数据库或嵌入模型的情况下进行检索。这层额外的架构使得检索代码可以重复使用、易于维护,并且与使用它的各种应用程序保持解耦。

检索是该服务器的主要功能。当智能体提交问题时,服务器会使用与索引时相同的multilingual-e5-large模型对问题进行嵌入处理,然后在Pinecone索引上执行相似度搜索,最终返回排名最高的片段。由于在处理片段和查询时都使用同一模型,二者能保持在相同的语义空间中,这样才能实现有意义的比较。

为提升结果质量,该搜索工具仅返回余弦相似度高于0.82的匹配项。实验表明,超过这一阈值的分数通常意味着查询内容与对应片段之间存在较强的语义关联,而较低分数则表明两者最多只有较为松散的联系。剔除那些匹配度较低的项能为后续的语言模型提供更相关的上下文。即便文档中的用词有所不同,像“如何提交费用报销单?”这样的问题依然能够找到正确的政策页面。除搜索功能外,该服务器还提供了用于管理向量数据库的工具:插入向量、删除向量以及列出可用的索引。

由于该系统是为企业部署设计的,安全性是其设计的一部分。凭证来自 Azure Key Vault,且在执行任何数据检索之前,每个请求都必须拥有有效的 API 密钥。敏感的基础设施信息不会暴露给客户端应用程序,同时索引文档的访问也受到保护。

results = index.query(
    vector=query_embedding,
    top_k=5,
    include_metadata=True
)

该项目展示了RAG在处理内部文档方面的应用

一个高效的语义搜索系统既依赖于底层的语言模型,也取决于各种工程决策。分块策略、嵌入模型、批处理方式以及检索架构都会直接影响系统的质量、可扩展性和可维护性。将数据摄取与检索功能置于MCP服务器之后,能够构建出模块化系统,这种系统具备可复用性、易于维护,并且能够随着需求变化轻松扩展。

当前版本已具备坚实的基础,且仍有很大的发展空间。语义分块、模型重排序、混合搜索以及更丰富的元数据都可以在保持模块化结构不变的前提下进一步提升检索效果。随着检索增强生成在企业级人工智能中日益普及,可靠的语义检索正逐渐成为生产系统的基础构建要素,而将 Pinecone Inference 与 MCP 检索层结合,是一种实用且可扩展的构建可复用语义搜索的方法。

相关阅读

  • 以坐标表示含义:从嵌入模型到向量数据库与RAG:详细讲解句子嵌入、余弦相似度、向量数据库以及RAG流程,并通过四句关于狗、猫和巴黎的简短句子展示含义搜索的运作方式。
  • 使用pgvector和.NET在PostgreSQL中实现语义搜索:实用配置指南:将嵌入模型与关系型数据存储在一起,构建HNSW或IVFFlat索引,对混合排序结果进行过滤与整合,并判断何时pgvector足以满足应用需求。
  • 在 Ubuntu 24.04 上使用 Qdrant 为 LLM 应用实现语义缓存:通过按语义而非文本缓存答案来降低 LLM API 的使用成本:包括在 Ubuntu 24.04 上的 Qdrant 设置、租户隔离机制、每条路由的相似度阈值以及 IOPS 成本分析。