从踩坑到实战:RAG与向量数据库入门指南

最近在做一些业务向量化的工作,发现自己也踩了一些坑,于是有了这篇文章。顺便推荐一下我的博客:llm与RAG的学习与优化 – 黑白の世界,欢迎留言交流。

以下是正文。

一、前言

这是一篇拖延了半年的文章。

年初计划做一些基于大模型的应用,正好公司有业务需求,于是开始学习 RAG 相关知识。一边研究字节开源的 eino 框架,一边补充 Agent、MCP、RAG 等概念。

当时就打算写一篇总结,但后来事情太多,一直搁置。今天终于决定把它写出来。

我也是边学边探索,如果你有更好的建议,欢迎在评论区留言。

二、AI 基础知识

2.1 大模型的分类

如果你只用过 AI 工具,没有接触过 AI 开发,可能会对下面这些名词感到困惑。

  • LLM(大语言模型):利用机器学习技术来理解和生成人类语言的模型。常见的 DeepSeek、GPT-4.1、Claude Sonnet 4 都属于这一类。
  • 嵌入模型(Embedding Model):将文本、图片等数据转化为向量的模型。不同的嵌入模型在各自擅长的领域表现更好。
  • 多模态模型:能够理解图片、视频、文本等多种数据类型的模型,而不仅仅是文字对话。

2.2 OpenAI 标准调用

不同厂商有不同的 API 标准,比如 OpenAI、Anthropic、Gemini、Ollama 等。其中,OpenAI 标准是最常用的,大多数平台都提供这种接入方式。

下面是一个使用 curl 调用 OpenAI chat/completions 接口的示例:

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-4",
    "messages": [
      {
        "role": "system",
        "content": "你是一个乐于助人的助手。"
      },
      {
        "role": "user",
        "content": "你好!"
      }
    ],
    "stream": false,
    "temperature": 0.7
  }'

关键参数说明:

  • model:指定使用的模型,如 gpt-4gpt-3.5-turbo
  • messages:消息列表,包含 role(system/user/assistant)和 content
  • stream:是否启用流式传输,实现打字机效果
  • temperature:控制输出的随机性,值越高越随机
  • Authorization:API 密钥

三、RAG 与向量数据库

3.1 什么是 RAG

RAG(Retrieval Augmented Generation,检索增强生成)是为了解决大模型的”幻觉”问题而提出的。

大语言模型虽然看起来无所不能,但经常会一本正经地胡说八道。在编程场景下,这个问题不大,跑一下就知道对不对。但在医疗、法律等领域,这种错误可能造成严重后果。

RAG 的核心思路是:在与 AI 交互时,把相关知识内容写入 prompt(尤其是 system 部分),让 AI 基于这些资料回答问题,而不是凭空编造。

相关论文:Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks

3.2 向量的概念

简单来说,向量就是一串数字,像一个”语义坐标”,代表文本在多维空间中的位置。意思相近的文本,它们的坐标在空间中也会靠得很近。

当知识库变得庞大后,把所有资料塞进 prompt 的方法就失效了:

  • 模型有上下文 token 限制,资料太多反而会导致幻觉
  • 成本太高,大量资料只用到一点,造成 token 浪费

解决方案是:把资料存入向量数据库,根据用户问题的向量去匹配相关内容,只把匹配到的 Top-K 结果交给 LLM。这样既节省成本,又能保证资料可靠。

3.3 两种匹配方式

向量搜索主要有两种流派:

  • 稠密向量(语义搜索):通过嵌入模型将文本语义压缩成连续向量。优点是能捕捉真实意图,搜索”AI编程”可以找到”人工智能程序设计”。缺点是对精确匹配的关键词可能不够准确。
  • 稀疏向量(关键词搜索):传统搜索引擎的思路,如 BM25 算法。优点是关键词精确匹配效果好,适合专有名词、产品型号等场景。缺点是无法理解同义词。
  • 混合搜索:现代 RAG 系统通常同时使用两种方式,然后通过重排序融合结果,兼具语义理解和精确匹配的优点。

3.4 向量索引类型

  • 基于图的方法(HNSW):把向量组织成网络图,从一个点快速跳到目标附近。目前最流行、性能最好的索引之一。
  • 基于聚类的方法(IVF):先把向量分成几千个”堆”,搜索时先判断属于哪个堆,再在堆内精确搜索。
  • 基于哈希的方法(LSH):用特殊方式给向量降维编码,让相似向量有很大概率得到相同编码。

3.5 常见向量数据库

  1. Elasticsearch:开源分布式搜索引擎,支持大数据场景,适合混合搜索。缺点是配置和维护有一定复杂度。
  2. Redis:从 Redis 7 开始支持向量搜索,可以轻松集成到已有架构。缺点是基于内存,不适合海量数据。
  3. PostgreSQL + pgvector:通过插件为 PG 提供向量检索能力,对已使用 PG 的团队集成成本极低。
  4. Milvus:专门为向量搜索设计的数据库,支持云原生,可动态扩展,官方宣称支持十亿级数据。缺点是需要依赖 etcd 等组件。

3.6 基础 RAG 流程

  1. 用户提问
  2. 将问题通过嵌入模型转化为向量
  3. 用向量在数据库中匹配 Top-K 个结果
  4. 将结果放入 system,问题放入 user,发送给 LLM
  5. 返回答案
LLM模型向量数据库嵌入式模型RAG程序用户LLM模型向量数据库嵌入式模型RAG程序用户1. 提问2. 将问题文本向量化返回问题向量3. 使用问题向量进行搜索返回Top-K相似文档4. 构造Prompt(相似文档 + 原始问题)生成最终答案5. 返回答案

3.7 一个常见误区

刚接触 RAG 的人(包括我自己)容易犯一个错误:把向量匹配当成问答系统。

向量是从数据生成的,但我们却用问题的向量去匹配。比如:

  • 向量内容:岗位名称:Go 开发工程师
  • 提问:我这里有一个简历,内容是预期岗位 Go…

这样或许也能匹配到,但匹配系数通常较低。当数据量增大后,容易匹配出奇怪的结果。

四、RAG 调优

基础 RAG 流程虽然简单,但召回的上下文质量直接决定了最终答案的优劣。RAG 调优可以分为三个阶段:预处理、检索、后处理。

4.1 预处理:优化数据质量

分块(Chunking)

将文档切分成合适的语义单元是 RAG 最关键的第一步。

为什么需要分块?

  • 太小的块可能丢失关键信息,太大的块可能引入噪声
  • LLM 有上下文长度限制
  • 合适的块大小能让向量更好地代表核心语义

常见分块策略:

  • 固定大小分块:按固定字符数(如 1000 字符)和一定重叠(如 200 字符)切分。简单快速,但容易切断完整语义。
  • 递归字符分割:按分隔符(如 \n\n\n、空格)递归分割,尽可能保持段落和句子完整。这是 LangChain 等框架的默认方式。
  • 语义分块:我最喜欢的方法,最初在 eino 框架的社区扩展 eino-ext 中看到。它先做递归分割,再对每个片段做余弦相似度对比,获得最符合语义的片段。缺点是 token 开销更大。

4.2 检索:优化查询与召回

元数据过滤(Metadata Filtering)

存储向量时,通常会附带元数据(如文档来源、记录类型等),可以用于优化检索。

  • 预过滤:先根据元数据筛选文档子集,再在子集中做向量搜索。速度快,但可能漏掉相关文档。
  • 后过滤:先做向量搜索得到 Top-K 结果,再应用元数据过滤。保证搜索完整性,但性能可能较低。

查询转换(Query Transformation)

用户的问题可能与文档表述存在语义鸿沟,查询转换可以提升召回率。

  • 假设性问题:数据入库时,让 LLM 为每个文档块生成”这个文档块可以回答什么问题”,然后将这些问题向量化。查询时实现”问题-问题”匹配,通常比”问题-文档”匹配效果更好。
  • 多查询检索:让 LLM 根据原始问题生成多个不同角度的相似问题,并行检索后合并结果,扩大召回广度。

还有一种最简单的优化:让用户提问先过一遍 LLM,做标准化处理。

4.3 后处理:优化最终上下文

重排序(Reranking)

向量搜索追求”快”和”广”,可能包含不太相关的结果。重排序是在召回之后、生成之前,用更精确的模型对结果二次排序。

重排序模型(如 Cohere Rerank)会同时评估原始问题和每个召回的文档块,给出更精确的相关性分数。这是提升 RAG 效果最有效的手段之一。

五、结语

以上是我在大模型学习、RAG 开发和向量数据库构建中的一些总结。

大模型从 2022 年到现在发展迅速。去年还主要用于提示词和问答,现在已经可以真正用于实际开发了。从 GitHub Copilot 到 Cursor 到 Claude Code,工具越来越可靠、越来越现代化。当然,也有些养懒了大脑。

写文档时 AI 也帮了很多忙。可以看到本文谈到 RAG 调优时格式有些变化——到这里我有些懒了,手写思路和大纲后,直接让 AI 优化,再手改一番。

本文只涉及 RAG 知识库和向量数据库的技术点。下一篇打算聊聊 AI Agent 和 MCP。

发表评论