RAG 入门:检索增强生成核心原理

RAG 入门:检索增强生成核心原理

什么是 RAG?

大模型的"阿喀琉斯之踵"

想象一个场景:你问一个 AI 助手"我们公司的最新政策是什么?",它要么胡说八道,要么说"我不知道"------因为它训练时的知识截止到几个月前,甚至没有公司内部的私有政策文档。

这就是大模型的核心痛点:

问题 说明 前端类比
知识截止 模型训练后知识就固定了 就像打包后的静态网站,内容无法更新
幻觉问题 不知道的事情会编造 类似 undefined 被强制转成字符串
私有知识 无法访问企业内部文档 无法读取 localhost 的 API

RAG 的解决方案

RAG(检索增强生成) 的核心思想很简单:先查资料,再回答问题

javascript 复制代码
// 传统 LLM:直接回答
const answer = await llm.ask("公司最新政策是什么?");
// 可能输出:编造的内容

// RAG:先查资料,再回答
const docs = await searchDocs("公司最新政策");  // 从知识库检索
const answer = await llm.askWithContext(docs, "公司最新政策是什么?");
// 输出:基于真实文档的回答

用前端技术栈类比 RAG

复制代码
用户提问 → 向量检索(类似数据库查询) → 上下文增强(类似状态注入) → LLM 生成(类似模板渲染)

整个过程可以理解为:大模型在回答问题时,先"翻书查资料",然后根据查到的内容来回答------就像开卷考试,而不是闭卷瞎蒙。

RAG 的核心价值

价值 说明
实时更新知识 无需重新训练,更新知识库即可
降低幻觉 回答基于检索到的真实文档
可溯源 可以告诉用户答案来自哪份文档
成本可控 比模型微调便宜得多

RAG VS 模型微调:选型对比

核心差异速览

维度 RAG 模型微调
知识更新 即时(更新知识库即可) 需重新训练(数小时到数天)
开发成本 低(调用 API + 向量数据库) 高(需要 GPU 资源和训练经验)
幻觉控制 强(基于检索内容) 中(依赖训练数据质量)
私有知识 ✅ 天然支持 ⚠️ 需要训练数据
可解释性 ✅ 可溯源到文档 ❌ 黑盒
前端适配性 ✅ 轻量,调用 API 即可 ⚠️ 需要后端训练服务

什么时候选 RAG?

场景 原因
企业内部知识库问答 文档经常更新,需要实时同步
客服问答系统 需要可溯源的答案,回答必须准确
代码文档助手 需要基于最新 API 文档回答
个人学习助手 成本低,快速搭建

什么时候选微调?

场景 原因
改变模型风格/语气 如让模型模仿特定人物说话
提升特定任务能力 如代码生成、SQL 改写
大批量相同格式输出 如固定格式的报告生成

两者也可以结合

在实际生产环境中,RAG 和微调并非互斥,而是互补关系:

复制代码
用户提问 → RAG 检索(获取相关文档)→ 微调后的模型(生成回答)

例如:先微调让模型学会"客服语气",再用 RAG 注入企业最新政策文档。

RAG 全流程执行链路拆解

整体架构

#mermaid-svg-vYbzNeD8gLQqINaM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vYbzNeD8gLQqINaM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vYbzNeD8gLQqINaM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vYbzNeD8gLQqINaM .error-icon{fill:#552222;}#mermaid-svg-vYbzNeD8gLQqINaM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vYbzNeD8gLQqINaM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vYbzNeD8gLQqINaM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vYbzNeD8gLQqINaM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vYbzNeD8gLQqINaM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vYbzNeD8gLQqINaM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vYbzNeD8gLQqINaM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vYbzNeD8gLQqINaM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vYbzNeD8gLQqINaM .marker.cross{stroke:#333333;}#mermaid-svg-vYbzNeD8gLQqINaM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vYbzNeD8gLQqINaM p{margin:0;}#mermaid-svg-vYbzNeD8gLQqINaM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vYbzNeD8gLQqINaM .cluster-label text{fill:#333;}#mermaid-svg-vYbzNeD8gLQqINaM .cluster-label span{color:#333;}#mermaid-svg-vYbzNeD8gLQqINaM .cluster-label span p{background-color:transparent;}#mermaid-svg-vYbzNeD8gLQqINaM .label text,#mermaid-svg-vYbzNeD8gLQqINaM span{fill:#333;color:#333;}#mermaid-svg-vYbzNeD8gLQqINaM .node rect,#mermaid-svg-vYbzNeD8gLQqINaM .node circle,#mermaid-svg-vYbzNeD8gLQqINaM .node ellipse,#mermaid-svg-vYbzNeD8gLQqINaM .node polygon,#mermaid-svg-vYbzNeD8gLQqINaM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vYbzNeD8gLQqINaM .rough-node .label text,#mermaid-svg-vYbzNeD8gLQqINaM .node .label text,#mermaid-svg-vYbzNeD8gLQqINaM .image-shape .label,#mermaid-svg-vYbzNeD8gLQqINaM .icon-shape .label{text-anchor:middle;}#mermaid-svg-vYbzNeD8gLQqINaM .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vYbzNeD8gLQqINaM .rough-node .label,#mermaid-svg-vYbzNeD8gLQqINaM .node .label,#mermaid-svg-vYbzNeD8gLQqINaM .image-shape .label,#mermaid-svg-vYbzNeD8gLQqINaM .icon-shape .label{text-align:center;}#mermaid-svg-vYbzNeD8gLQqINaM .node.clickable{cursor:pointer;}#mermaid-svg-vYbzNeD8gLQqINaM .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vYbzNeD8gLQqINaM .arrowheadPath{fill:#333333;}#mermaid-svg-vYbzNeD8gLQqINaM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vYbzNeD8gLQqINaM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vYbzNeD8gLQqINaM .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vYbzNeD8gLQqINaM .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vYbzNeD8gLQqINaM .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vYbzNeD8gLQqINaM .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vYbzNeD8gLQqINaM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vYbzNeD8gLQqINaM .cluster text{fill:#333;}#mermaid-svg-vYbzNeD8gLQqINaM .cluster span{color:#333;}#mermaid-svg-vYbzNeD8gLQqINaM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vYbzNeD8gLQqINaM .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vYbzNeD8gLQqINaM rect.text{fill:none;stroke-width:0;}#mermaid-svg-vYbzNeD8gLQqINaM .icon-shape,#mermaid-svg-vYbzNeD8gLQqINaM .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vYbzNeD8gLQqINaM .icon-shape p,#mermaid-svg-vYbzNeD8gLQqINaM .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vYbzNeD8gLQqINaM .icon-shape .label rect,#mermaid-svg-vYbzNeD8gLQqINaM .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vYbzNeD8gLQqINaM .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vYbzNeD8gLQqINaM .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vYbzNeD8gLQqINaM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 在线问答阶段
用户提问

Query
向量检索

Retrieval
LLM 生成

Generation
离线索引阶段
文档处理

Loading
向量化

Embedding
存储索引

Storing
向量数据库

阶段一:文档处理(索引侧)

目标:将原始文档转换为可检索的格式。

步骤 任务 说明
文档加载 读取各类格式文档 PDF、Markdown、Word、网页等
文本分割 将长文档切分成小块 控制每块大小(如 500-1000 字符)
元数据提取 记录来源信息 文件名、页码、章节等
javascript 复制代码
// 代码示例:文本分割
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";

// 创建分割器
const splitter = new RecursiveCharacterTextSplitter({
  chunkSize: 1000,
  chunkOverlap: 200,
});

// 定义要分割的文本内容
const longText = `
这里是你要分割的超长文本内容。
可以是文章、文档、说明、任意内容。
`;

const chunks = await splitter.splitText(longText);

阶段二:向量化与存储(索引侧)

目标:将文本块转换为向量并建立索引。

步骤 任务 说明
嵌入生成 调用 Embedding 模型 将文本转为向量(如 1536 维)
向量存储 存入向量数据库 Chroma、Pinecone、Qdrant 等
索引构建 建立高效检索结构 HNSW、IVF 等算法
javascript 复制代码
// 代码示例:向量化与存储
import { OpenAIEmbeddings } from "@langchain/openai";
import { Chroma } from "@langchain/community/vectorstores/chroma";

const embeddings = new OpenAIEmbeddings({ model: "text-embedding-3-small" });
const vectorStore = await Chroma.fromTexts(
  chunks,
  chunks.map((_, i) => ({ id: i, source: "knowledge" })),
  embeddings,
  {
    collectionName: "knowledge_base",
  }
);

阶段三:检索增强(查询侧)

目标:根据用户问题检索相关知识。

步骤 任务 说明
问题向量化 将用户问题转为向量 使用相同 Embedding 模型
相似度检索 查找最相似的文档块 余弦相似度、欧氏距离等
结果重排序 优化检索结果顺序 可选,提升相关性
javascript 复制代码
// 代码示例:相似度检索
const relevantDocs = await vectorStore.similaritySearch(question, 5);
// 返回最相似的 5 个文档块

阶段四:生成回答(查询侧)

目标:结合检索结果生成最终回答。

步骤 任务 说明
上下文构建 将检索结果拼接到提示词 格式:文档1 文档2...
提示词增强 注入检索内容和回答要求 "只根据以下内容回答"
LLM 生成 调用大模型生成答案 保证回答基于检索内容
javascript 复制代码
// 代码示例:构建增强提示词
const prompt = `
请根据以下文档内容回答用户问题。

【文档1】${doc1}
【文档2】${doc2}

用户问题:${question}

注意:
1. 如果文档中没有相关信息,请明确说"没有找到相关信息"
2. 不要使用你自己知识库中的内容
3. 回答要简洁准确

回答:
`;

const answer = await llm.invoke(prompt);

前端落地 RAG 应用场景

场景一:企业文档智能问答

需求:公司内部有大量文档(员工手册、技术规范、产品说明),员工查找困难。

前端实现

typescript 复制代码
// 企业文档问答界面
class CompanyDocQA {
  async search(question: string) {
    // 1. 检索相关文档片段
    const docs = await vectorStore.similaritySearch(question, 3);
    
    // 2. 显示来源引用
    return {
      answer: await this.generateAnswer(question, docs),
      sources: docs.map(d => ({ file: d.metadata.file, page: d.metadata.page })),
    };
  }
}

前端 UI 要点

  • 显示答案来源(支持点击跳转到原文)
  • 支持文档预览浮层
  • 提供答案有用/无用的反馈按钮

场景二:前端技术知识库

需求:搭建团队内部的技术文档问答系统(React/Vue 官方文档、组件库文档、最佳实践沉淀)。

数据来源

  • 框架官方文档爬取
  • 团队内部技术沉淀
  • GitHub 仓库 README

前端适配优势

  • Markdown 友好,前端天然擅长渲染
  • 可以集成到 IDE 插件或浏览器扩展
  • 支持代码高亮和示例预览

场景三:代码库问答助手

需求:让 AI 理解公司代码库,新人可以问"这个函数怎么用?"

typescript 复制代码
// 代码库 RAG 流程
// 1. 离线阶段:解析代码文件
const codeChunks = parseCodeFiles(repoPath, {
  language: "typescript",
  chunkBy: "function",  // 按函数分割
});

// 2. 向量化存储
await vectorStore.addDocuments(codeChunks);

// 3. 在线问答
const answer = await ragChain.invoke({
  question: "auth 模块的 login 函数怎么用?",
});

场景四:客服知识库

需求:搭建智能客服系统,回答常见问题。

优势

  • 无需训练,直接导入 FAQ 文档
  • 更新即时,新增问题立即生效
  • 可溯源,用户可查看原始文档

场景五:个人学习助手

需求:上传 PDF 文档(论文、书籍),随时提问。

前端实现要点

  • 拖拽上传 PDF
  • 显示问答历史和文档来源
  • 支持导出对话记录

学习 RAG 必备知识储备

技术栈概览

类别 技术 说明
框架 LangChain.js 链路编排,支持中文社区
Embedding text-embedding-v3 / qwen 国内可用,阿里云百炼提供
向量数据库 Chroma / Qdrant 轻量级,适合前端项目
LLM 通义千问 / DeepSeek RAG 生成阶段使用

知识储备要求

知识点 重要性 学习建议
LangChain 基础 ⭐⭐⭐⭐⭐ 先完成基础教程
异步编程 ⭐⭐⭐⭐ 掌握 Promise、async/await
向量基础概念 ⭐⭐⭐ 了解嵌入和相似度即可
提示词工程 ⭐⭐⭐⭐ 掌握 prompt 编写技巧

向量基础速成

对于前端开发者来说,理解以下三个核心概念就足够入门:

1. 什么是向量?

  • 向量就是一组数字,例如 [0.1, -0.5, 0.8, ...](通常几百到几千维)
  • 每个文本(句子、段落)都可以转换成一个向量
  • 关键:语义相似的文本,它们的向量在空间中也彼此靠近

2. 什么是相似度检索?

  • 比较两个向量的距离(余弦相似度)
  • 距离越近,文本越相关
  • 找到与用户问题向量距离最近的那些文档块

3. 常用的 Embedding 模型

  • OpenAI:text-embedding-3-small(1536 维)
  • 阿里云百炼:text-embedding-v3(1024 维)
  • BGE(国产开源)

国内模型适配 RAG 的注意事项

Embedding 模型选择

模型 维度 中文效果 推荐指数
阿里云 text-embedding-v3 1024 ⭐⭐⭐⭐⭐ 首选
OpenAI text-embedding-3-small 1536 ⭐⭐⭐⭐ 需代理
BGE-large-zh 1024 ⭐⭐⭐⭐ 开源免费

阿里云百炼配置

typescript 复制代码
// 阿里云百炼 Embedding 配置
import { OpenAIEmbeddings } from "@langchain/openai";

const embeddings = new OpenAIEmbeddings({
  apiKey: process.env.DASHSCOPE_API_KEY,
   configuration: {
     baseURL: process.env.DASHSCOPE_API_URL,
   },
  model: "text-embedding-v3",  // 阿里云百炼模型
});

前端适配注意事项

注意事项 说明
Embedding 模型一致性 索引和查询必须使用相同模型
中文支持 选择中文效果好的 Embedding 模型
分段策略 中文按语义切分(段落/句子),避免截断
上下文长度 检索结果过多会超 LLM 窗口,建议 3-5 条

结语

通过这篇教程,我们系统了解了 RAG 的核心原理、选型对比和落地场景。

对于文章中错误的地方或有任何疑问,欢迎在评论区留言讨论!

相关推荐
LiuJun2Son1 小时前
Claude Code + Skill 做 UI 的实战工作流
人工智能·ui
继续商行1 小时前
大模型推理优化实战:从KV Cache到流式响应的全链路性能提升
人工智能
pe7er1 小时前
AI为啥会写出if(obj != null && obj.ifEnabled)这样的代码
前端·后端·架构
冬奇Lab1 小时前
Agent 系列(15):Agent 记忆系统进阶——短期、长期、压缩,三层记忆架构
人工智能·llm·agent
大雨淅淅1 小时前
【机器人】ROS2 机械臂控制(MoveIt2)从入门到实战
人工智能·python·神经网络·学习·算法·机器学习·机器人
m0_564876841 小时前
怎么写好一个好的skill
人工智能·深度学习·职场和发展
zhangfeng11331 小时前
把权重写死在芯片的架构 Taalas(HC1)芯片:车载 GPU / 智能驾驶 / 机器人 / 算力卡适配总结
人工智能·深度学习·语言模型·架构·机器人·gpu算力·芯片
芝士爱知识a1 小时前
【2026量化新纪元】深度评测:以AlphaGBM为核心的顶级AI量化分析软件推荐及全维度选型指南
人工智能·机器学习·因子挖掘·ai量化·alphagbm·量化交易软件测评
OBiO20131 小时前
精准靶向血管平滑肌AAV在心血管疾病研究中的应用
人工智能