向量化思维:使用 Elasticsearch 构建生产就绪的 RAG 流水线

发布: (2026年3月3日 GMT+8 17:22)
11 分钟阅读
原文: Dev.to

Source: Dev.to

Abstract

虽然传统的基于关键词的搜索已经为我们服务了数十年,但在生成式 AI 时代,它常常无法捕捉人类意图的细微差别。在本指南中,我们将探讨向 Vectorized Thinking 的转变。我们将使用 Elasticsearch Relevance Engine (ESRE)OpenAI embeddings 实现完整的检索增强生成(RAG)流水线,演示如何弥合词汇匹配与语义理解之间的鸿沟。阅读完本文后,您将了解如何构建、优化和部署一个既准确又可扩展的 RAG 系统。

1. 关键字搜索中的“语义鸿沟”

传统搜索引擎依赖词汇匹配,通常使用 BM25 算法。虽然 BM25 在查找精确词语方面表现出色,但它本质上对意义 盲目。这就产生了我们所说的 语义鸿沟

问题 – 想象一下用户向支持机器人询问:“我该如何恢复我的账户?”。如果你的知识库中仅包含短语 “使用忘记密码选项 重置密码”,标准的关键字搜索可能会失败。为什么?因为词语 恢复账户 并未出现在目标文档中。

这种鸿沟会导致 LLM(大语言模型) 出现 幻觉,因为在缺乏正确上下文的情况下,模型被迫猜测。向量搜索通过将意图表示为高维空间中的数学坐标来解决此问题,使系统能够“理解”在此上下文中 恢复重置 在语义上是相同的。

2. 什么是向量搜索?

向量搜索将非结构化文本转换为称为 embeddings 的密集数值表示。这些 embeddings 将词语、句子或整个文档映射到高维空间,在该空间中 “Account Recovery”“Password Reset” 在地理位置上非常接近。

Elastic Stack 的关键概念

ConceptDescription
Dense Vector Embeddings固定长度数组(例如 OpenAI 的 text‑embedding‑3‑small 为 1536 维),充当意义的数字指纹。
Cosine Similarity衡量两个向量之间的夹角;夹角越小,语义相似度越高。
HNSW (Hierarchical Navigable Small World)Elasticsearch 使用的高性能索引算法。它构建多层图结构,在毫秒级找到 最近邻,跳过数十亿无关文档。可将其视为多维空间的 “跳表”。

3. 系统架构

生产级别的 RAG 流水线不仅仅是一个脚本;它是由两个不同循环组成的生命周期。理解这一流程对于构建可靠的生成式 AI 应用至关重要。

[Diagram: The RAG Lifecycle]

摄取循环(离线)

Raw Documents → Chunking Service → OpenAI Embedder → Elasticsearch Index (Vector Store)

在此阶段,我们通过将文本转换为可搜索的向量来准备知识库。

推理循环(在线)

User Query → OpenAI Embedder → kNN Vector Search in Elastic → Context Injection → LLM Response

在此阶段,我们使用用户的查询在向量库中寻找最佳上下文,然后向 LLM 提出问题以获取答案。

Source:

4. 使用 Elastic Cloud 的实现指南

要按照本指南操作,您需要一个 Elastic Cloud 实例(托管环境,包含 Elasticsearch Relevance Engine (ESRE),可简化对 OpenAI 等外部模型提供商的集成)。

步骤 1:定义向量模式

PUT /rag-index
{
  "mappings": {
    "properties": {
      "text": {
        "type": "text"
      },
      "metadata": {
        "type": "keyword"
      },
      "embedding": {
        "type": "dense_vector",
        "dims": 1536,
        "index": true,
        "similarity": "cosine",
        "index_options": {
          "type": "hnsw",
          "m": 16,
          "ef_construction": 100
        }
      }
    }
  }
}

技术说明: m 定义每个新元素的双向链接数量(数值越大准确度越高,但索引时间会增加)。ef_construction 控制图构建过程中使用的动态列表大小。

步骤 2:智能分块与写入

对整篇文章进行嵌入会导致 语义稀释。最佳的 “Goldilocks” 区间是每块 500‑800 个 token,并保持 10 % 的重叠,以在块边界之间保留上下文。

def chunk_text(text, limit=500, overlap=50):
    """
    Split `text` into overlapping chunks.
    - `limit`  : maximum number of tokens per chunk
    - `overlap`: number of tokens to overlap between consecutive chunks
    """
    words = text.split()
    chunks = []
    for i in range(0, len(words), limit - overlap):
        chunks.append(" ".join(words[i:i + limit]))
    return chunks

写入循环示例

for chunk in chunk_text(raw_document):
    # Generate embedding via OpenAI
    response = client.embeddings.create(
        model="text-embedding-3-small",
        input=chunk
    )
    vector = response.data[0].embedding

    # Index into Elasticsearch
    es.index(
        index="rag-index",
        document={
            "text": chunk,
            "embedding": vector,
            "metadata": {"source": "kb"}   # optional metadata
        }
    )

步骤 3:语义检索(kNN)

我们检索的是 用户意图的向量,而不是原始文本。num_candidates 参数告诉 Elasticsearch 在 HNSW 图层中要考虑多少候选结果。

search_response = es.search(
    index="rag-index",
    knn={
        "field": "embedding",
        "query_vector": user_query_vector,
        "k": 3,                # top‑k results to return
        "num_candidates": 100 # candidates examined in the graph
    }
)

Source:

5. 高级优化:混合搜索与倒数排名融合 (RRF)

虽然纯向量搜索功能强大,但将其与传统词项搜索相结合往往能够兼顾两者的优势。

  • 混合搜索 – 同时对 BM25(或其他词项评分器)和向量字段进行查询,然后合并得分。
  • 倒数排名融合 (RRF) – 一种简单、与得分无关的方法,通过奖励在两个排序列表中都排名靠前的条目来合并两份排名。
POST /rag-index/_search
{
  "size": 5,
  "query": {
    "bool": {
      "should": [
        {
          "knn": {
            "embedding": {
              "vector": user_query_vector,
              "k": 5
            }
          }
        },
        {
          "match": {
            "text": {
              "query": user_query_text,
              "boost": 2.0
            }
          }
        }
      ]
    }
  }
}

在获取混合搜索结果后,在应用层使用 RRF 进行处理,以生成最终排名。

6. 部署 RAG 服务

  1. 容器化 数据摄取和推理脚本(Docker)。
  2. 暴露 一个轻量级 HTTP 接口(FastAPI / Flask),其功能包括:
    • 接收用户查询。
    • 调用 OpenAI 对查询进行嵌入。
    • 执行 kNN 检索。
    • 将 top‑k 片段格式化为上下文。
    • 将上下文 + 查询发送给 LLM(例如 gpt‑4o)。
  3. 扩展 服务,使用 Kubernetes 或 Elastic Cloud 的内置自动伸缩。

7. 监控与维护

指标为什么重要
索引延迟确保摄取能够跟上源数据的更新。
kNN 查询延迟保证用户体验响应迅速(典型 < 200 ms)。
嵌入成本跟踪 OpenAI token 使用量以控制费用。
LLM 幻觉率定期审计回复;高幻觉率表明上下文不足。

在 Elastic Observability(APM、日志、指标)中设置警报,以提前发现回归。

8. 弱点:精确术语匹配

如果用户搜索特定零件号,例如 “SKU‑9904‑X”,纯向量搜索可能返回“相似”零件,而不是准确的那一个。

解决方案 – 使用 Reciprocal Rank Fusion (RRF) 的混合搜索

RRF 让你将 BM25 关键字搜索k‑NN 向量搜索 的结果合并为一个统一的排序。

GET /rag-index/_search
{
  "query": {
    "match": {
      "text": "SKU-9904-X"
    }
  },
  "knn": {
    "field": "embedding",
    "query_vector": [0.12, 0.45, ...],
    "k": 10,
    "num_candidates": 100
  },
  "rank": {
    "rrf": {}
  }
}

通过合并这两种方法,你可以获得 “两全其美”——关键字匹配的精确度和语义搜索的直觉性。

Source:

9. 生产考虑因素:“战壕中的经验教训”

在生产环境中构建检索增强生成(RAG)流水线不仅需要逻辑,还需要对基础设施有充分的认识。

量化(标量量化)

  • 向量存储非常占用 RAM。
  • Elasticsearch 支持 int8 量化,将向量从 32 位浮点压缩到 8 位整数。
  • 实际上,这可以 节省约 75 % 的内存,而检索准确率下降 不到 1 %

熔断器

  • 你的嵌入提供商(OpenAI、Anthropic 等)是第三方依赖。
  • 实现 指数退避熔断器
  • 当嵌入服务宕机时,优雅地降级为 仅关键字搜索,而不是直接崩溃。

重排序器模式

  • 对于高风险应用,使用两阶段检索流程:
    1. Elasticsearch 返回 前 50 条文档。
    2. 交叉编码器 模型(例如 Cohere Rerank)挑选出最终的 前 3 条。
  • 这可以显著提升精确度。

10. Observations & Performance

50 000 篇技术文档 的数据集上测试此架构,得到:

指标结果
准确率LLM “幻觉” 减少了 40%。将模型基于检索到的事实进行 grounding,使答案更具事实性且更简洁。
延迟“语义跳跃”(调用嵌入 API)每次查询会额外增加 ≈150 ms。对于对延迟敏感的应用,请对常用查询缓存嵌入。

结论

向量化思维将关注点从关键词转向意图。通过利用 Elasticsearch Relevance Engine,开发者可以构建真正理解用户的搜索体验。无论是构建客服机器人还是复杂的研究工具,HNSW indexingHybrid SearchLLM augmentation 的组合为下一代 AI 驱动的应用提供了坚实的基础。

0 浏览
Back to Blog

相关文章

阅读更多 »

当工作成为心理健康风险时

markdown !Ravi Mishrahttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fu...