深入浅出 LangChain —— 第八章:RAG 检索增强生成

快速上手LangChain(三)构建检索增强生成(RAG)应用 典型的 RAG 应用程序有两个主要组件 * 索引:一个从源头摄取数据并对其进行索引的管道。这**通常离线进行**。 * 检索和生成:实际的 RAG 链,它在运行时获取用户查询,从索引中检索相关数据,然后将其传递给模型。 阅读详情

📖 本章学习目标

完成本章后,你将能够:

  • ✅ 理解 RAG 的核心价值和应用场景
  • ✅ 掌握 RAG Pipeline 的五个阶段及其实现
  • ✅ 选择合适的文档切割策略和 Embedding 模型
  • ✅ 根据业务需求选择向量数据库
  • ✅ 实现进阶检索策略(混合检索、查询改写、重排序)
  • ✅ 诊断和优化 RAG 系统的常见问题

一、为什么需要 RAG

LLM 有两大固有知识型缺陷,RAG 正是为了解决这些问题而生。

💡 提示: RAG是一整套技术体系,涉及文本处理、向量数据、优化等多个知识体系,请关注后续推出的完整的RAG教程。

1、LLM 的局限性

问题 1:知识截止

现象:

// 用户问:"2025 年诺贝尔文学奖得主是谁?"
// LLM 回答:"抱歉,我的训练数据截止到 2024 年..."

原因:

  • LLM 的知识来自静态的训练数据
  • 训练完成后,知识就固定了
  • 无法知道最新发生的事件
问题 2:私有数据缺失

现象:

// 用户问:"我们公司的产品退货政策是什么?"
// LLM 回答:"我不知道贵公司的具体政策..."

原因:

  • LLM 没有访问你公司内部数据的权限
  • 训练数据不包含你的私有文档
  • 每个公司的业务流程都不一样

2、RAG 的解决方案

RAG = Retrieval(检索)+ Augmented(增强)+ Generation(生成)

核心思路:在提问时,先从知识库里找到最相关的内容,再把它作为上下文提供给模型,让模型"带着资料"回答。

这有点类似你在参加考试:

  • ❌ 不使用 RAG:闭卷考试,只能靠记忆
  • ✅ 使用 RAG:开卷考试,可以查阅参考书

显然,开卷考试的答案更准确、更可靠。

3、RAG 的工作流程

用户问题

Embedding 化

向量检索
找出最相关的文档片段

构建 Prompt
问题 + 检索到的上下文

LLM 生成回答

最终回答
基于真实知识库

知识库
向量数据库

关键优势:

优势说明效果
实时性可以随时更新知识库回答最新信息
准确性基于真实文档回答减少幻觉
可追溯可以显示引用来源便于验证
成本低不需要重新训练模型经济高效

二、RAG Pipeline 的五个阶段

完整的 RAG 系统包含两个主要阶段:索引阶段(离线)和检索生成阶段(在线)。

整体架构图

生成阶段
每次查询执行

检索阶段:每次查询执行

索引阶段:离线执行一次

1. 文档加载
Loaders

2. 文档切割
Splitters

3. Embedding 生成
Embeddings

4. 向量存储
Vector Store

用户问题

问题 Embedding

5. 相似度检索

相关文档片段

构建 Prompt

LLM 生成

最终回答

接下来,我们逐一详解每个阶段。


三、阶段 1:文档加载(Document Loaders)

文档加载器的作用是将各种格式的文件转换为统一的 Document 对象。

1、Document 对象结构

interface Document {
  pageContent: string;   // 文档内容
  metadata: Record<string, any>;  // 元数据(来源、页码等)
}

示例:

{
  pageContent: "产品的保修期为一年...",
  metadata: {
    source: "./docs/warranty.pdf",
    page: 5,
    author: "TechCorp"
  }
}

2、常见文档加载器

LangChain.js 提供了丰富的文档加载器,支持几乎所有常见格式。

(1)PDF 文档
import { PDFLoader } from "@langchain/community/document_loaders/fs/pdf";

const pdfLoader = new PDFLoader("./docs/product-manual.pdf");
const pdfDocs = await pdfLoader.load();

console.log(`加载了 ${pdfDocs.length} 个页面`);
// 每个页面对应一个 Document 对象
(2)Word 文档
import { DocxLoader } from "@langchain/community/document_loaders/fs/docx";

const docxLoader = new DocxLoader("./docs/guide.docx");
const docxDoms = await docxLoader.load();
(3)CSV 表格
import { CSVLoader } from "@langchain/community/document_loaders/fs/csv";

const csvLoader = new CSVLoader("./data/products.csv");
const csvDocs = await csvLoader.load();

// 每行数据转换为一个 Document
// pageContent: "产品名称: iPhone 15, 价格: 7999"
// metadata: { row: 1 }
(4)网页内容
import { CheerioWebBaseLoader } from "@langchain/community/document_loaders/web/cheerio";

const webLoader = new CheerioWebBaseLoader("https://example.com/doc");
const webDocs = await webLoader.load();

// 自动提取网页的文本内容,去除 HTML 标签
(5)GitHub 仓库
import { GithubRepoLoader } from "@langchain/community/document_loaders/web/github";

const githubLoader = new GithubRepoLoader(
  "https://github.com/langchain-ai/langchainjs",
  { 
    branch: "main",
    recursive: false,  // 是否递归加载子目录
    unknown: "warn"    // 遇到未知文件类型的处理方式
  }
);
const codeDocs = await githubLoader.load();

// 适合构建代码问答机器人

3、批量加载多个文件

使用DirectoryLoader可以实现多个文档的加载。

import { DirectoryLoader } from "langchain/document_loaders/fs/directory";

// 加载整个目录
const directoryLoader = new DirectoryLoader(
  "./docs",
  {
    ".pdf": (path) => new PDFLoader(path),
    ".docx": (path) => new DocxLoader(path),
    ".txt": (path) => new TextLoader(path),
  }
);

const allDocs = await directoryLoader.load();
console.log(`总共加载了 ${allDocs.length} 个文档`);

四、阶段 2:文档切割(Text Splitters)

LLM 的上下文窗口有限,不能直接塞进整个文档,这是就需要对文档进行适当的切割,而切割策略直接影响检索质量。

1、为什么要切割?

问题场景:

假设你有一个 100 页的产品手册:

  • ❌ 不切割:整个手册 50,000 字符,超出 Context Window
  • ❌ 按页切割:可能把一个完整的话题截断
  • ✅ 智能切割:按语义边界切割,保持话题完整性

2、RecursiveCharacterTextSplitter(推荐)

这是Langchain.js提供的最常用的文档切割器,会尝试多种分隔符,优先在语义边界处切割。

(1)基础用法
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";

const splitter = new RecursiveCharacterTextSplitter({
  chunkSize: 1000,       // 每个 chunk 的最大字符数
  chunkOverlap: 200,     // 相邻 chunk 的重叠字符数
  separators: [
    "\n\n",   // 优先在段落之间切割
    "\n",     // 其次在换行处切割
    "。",      // 中文句号
    ",",      // 中文逗号
    " ",       // 空格
    ""         // 最后才按字符切割
  ],
});

const chunks = await splitter.splitDocuments(pdfDocs);
console.log(`切割为 ${chunks.length} 个 chunks`);

参数详解:

参数作用推荐值说明
chunkSize每个块的最大字符数500-1500太小会丢失上下文,太大会稀释相关性
chunkOverlap相邻块的重叠字符数chunkSize 的 10-20%防止关键信息在边界处被截断
separators分隔符优先级列表如上所示从粗到细尝试切割
(2)可视化切割过程
原始文档:
"第一段内容...\n\n第二段内容...\n\n第三段内容..."

切割过程:
1. 尝试在 "\n\n" 处切割 → 成功
2. 如果某段超过 chunkSize,尝试在 "\n" 处切割
3. 如果还超,尝试在 "。" 处切割
4. 依此类推...

结果:
Chunk 1: "第一段内容..."
Chunk 2: "...第一段内容...\n\n第二段内容..."  (有重叠)
Chunk 3: "...第二段内容...\n\n第三段内容..."

3、其他切割器

(1)Markdown 专用切割器

MarkdownTextSplitter 专门用于切割Markdown文档。

import { MarkdownTextSplitter } from "@langchain/textsplitters";

const mdSplitter = new MarkdownTextSplitter({
  chunkSize: 1000,
  chunkOverlap: 200,
});

// 会识别 Markdown 标题层级,优先在标题处切割
const mdChunks = await mdSplitter.splitDocuments(mdDocs);
(1)代码专用切割器
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";

const codeSplitter = RecursiveCharacterTextSplitter.fromLanguage(
  "typescript",  // 支持 python, java, javascript 等
  {
    chunkSize: 1000,
    chunkOverlap: 200,
  }
);

// 会识别代码结构(函数、类等),避免在中间切割
const codeChunks = await codeSplitter.splitDocuments(codeDocs);

4、⚠️ 切割策略的常见误区

误区 1:chunkSize 越大越好

❌ 错误做法:

chunkSize: 10000  // 太大!

问题:

  • 一个 chunk 里包含多个话题
  • 检索时相关性计算被稀释
  • 浪费 Token

✅ 推荐做法:

chunkSize: 800-1200  // 根据文档类型调整
误区 2:忽略 chunkOverlap

❌ 错误做法:

chunkOverlap: 0  // 没有重叠

问题:

  • 关键信息可能在边界处被截断
  • 上下文不连贯

✅ 推荐做法:

chunkOverlap: chunkSize * 0.15  // 15% 的重叠
误区 3:中文文档用英文分隔符

❌ 错误做法:

separators: ["\n\n", "\n", " ", ""]  // 缺少中文标点

✅ 推荐做法:

separators: ["\n\n", "\n", "。", ",", ";", " ", ""]

五、阶段 3:Embedding 生成

Embedding 是将文本转换为向量,使得语义相似的文本在向量空间中距离更近。

1、什么是 Embedding?

直观理解:

Embedding 就像给文本分配一个"语义坐标":

  • “猫” → [0.1, 0.8, -0.3, …]
  • “狗” → [0.2, 0.7, -0.2, …] (与"猫"接近)
  • “汽车” → [-0.5, -0.1, 0.9, …] (与"猫"远离)

这样,我们可以通过计算向量距离来判断文本相似度。

2、常用的 Embedding 模型

(1)OpenAI Embeddings(推荐)
import { OpenAIEmbeddings } from "@langchain/openai";

const embeddings = new OpenAIEmbeddings({
  model: "text-embedding-3-small",  // 性价比最高
  // model: "text-embedding-3-large",  // 效果更好,但更贵
});

// 生成向量
const vector = await embeddings.embedQuery("你好,世界");
console.log(vector.length);  // 1536 维(small)或 3072 维(large)

模型对比:

模型维度性能成本(每 1M tokens)适用场景
text-embedding-3-small1536⭐⭐⭐⭐$0.02大多数场景
text-embedding-3-large3072⭐⭐⭐⭐⭐$0.13对精度要求极高
text-embedding-ada-0021536⭐⭐⭐$0.10旧项目兼容
(2)开源模型(自托管)
import { HuggingFaceTransformersEmbeddings } from "@langchain/community/embeddings/hf_transformers";

const embeddings = new HuggingFaceTransformersEmbeddings({
  modelName: "Xenova/all-MiniLM-L6-v2",  // 轻量级模型
});

// 优点:免费、隐私性好
// 缺点:效果略逊于 OpenAI,需要本地计算资源

3、批量生成 Embedding

// 单个文本
const vector1 = await embeddings.embedQuery("第一个文本");

// 批量文本(更高效)
const vectors = await embeddings.embedDocuments([
  "第一个文本",
  "第二个文本",
  "第三个文本",
]);

console.log(vectors.length);  // 3
console.log(vectors[0].length);  // 1536

六、阶段 4:向量存储

向量数据库专门你负责存储和检索 Embedding 向量。

1、向量数据库选型矩阵

数据库部署方式适用场景特点学习曲线
Pinecone云端托管生产环境首选零运维,按量付费,高性能⭐⭐
Chroma本地/云端开发测试、小规模开源,嵌入式,易上手⭐
PGVector自托管已有 PostgreSQL直接在 PG 里存向量,运维简单⭐⭐
Weaviate自托管/云端混合检索场景支持关键词+向量混合搜索⭐⭐⭐
Qdrant自托管/云端高性能需求Rust 实现,资源消耗低⭐⭐⭐
Milvus自托管超大规模分布式,亿级向量⭐⭐⭐⭐

2、Pinecone(生产环境推荐)

(1)安装依赖
pnpm add @langchain/pinecone @pinecone-database/pinecone
(2)创建索引
import { Pinecone } from "@pinecone-database/pinecone";

const pinecone = new Pinecone({ 
  apiKey: process.env.PINECONE_API_KEY! 
});

// 创建索引(只需执行一次)
await pinecone.createIndex({
  name: "my-knowledge-base",
  dimension: 1536,  // 与 Embedding 维度一致
  metric: "cosine",  // 相似度度量:cosine / euclidean / dotproduct
  spec: {
    serverless: {
      cloud: "aws",
      region: "us-east-1",
    },
  },
});
(3)存储向量
import { PineconeStore } from "@langchain/pinecone";
import { OpenAIEmbeddings } from "@langchain/openai";

const embeddings = new OpenAIEmbeddings();
const index = pinecone.Index("my-knowledge-base");

// 从 Documents 批量写入
const vectorStore = await PineconeStore.fromDocuments(
  chunks,           // 切割后的文档块
  embeddings,       // Embedding 模型
  { 
    pineconeIndex: index,
    namespace: "product-docs",  // 可选:命名空间隔离
  }
);

console.log("向量存储完成");

3、Chroma(开发测试推荐)

pnpm add chromadb
import { Chroma } from "@langchain/community/vectorstores/chroma";

const vectorStore = await Chroma.fromDocuments(
  chunks,
  embeddings,
  {
    collectionName: "my-collection",
    url: "http://localhost:8000",  // Chroma 服务地址
  }
);

启动 Chroma 服务:

docker run -p 8000:8000 chromadb/chroma

4、PGVector(PostgreSQL 用户推荐)

pnpm add @langchain/community pg
import { PGVectorStore } from "@langchain/community/vectorstores/pgvector";
import { Pool } from "pg";

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

const vectorStore = await PGVectorStore.initialize(
  embeddings,
  {
    pool,
    tableName: "documents",
    columns: {
      idColumnName: "id",
      vectorColumnName: "embedding",
      contentColumnName: "content",
      metadataColumnName: "metadata",
    },
  }
);

// 添加文档
await vectorStore.addDocuments(chunks);

优势:

  • ✅ 无需额外部署向量数据库
  • ✅ 可以利用 PostgreSQL 的事务和备份
  • ✅ 适合已有 PG 基础设施的团队

七、阶段 5:检索与生成

这是 RAG 的在线阶段,每次用户提问时执行。

1、基础检索

(1)创建检索器
// 从向量存储创建检索器
const retriever = vectorStore.asRetriever({
  k: 5,  // 返回最相似的 5 个文档
});

// 执行检索
const docs = await retriever.invoke("产品的退货政策是什么?");

console.log(docs.length);  // 5
console.log(docs[0].pageContent);  // 最相关的文档内容
console.log(docs[0].metadata);     // 元数据(来源、页码等)
(2)相似度阈值过滤
const retriever = vectorStore.asRetriever({
  k: 5,
  filter: {
    similarityThreshold: 0.7,  // 只返回相似度 > 0.7 的文档
  },
});

2、构建 RAG Prompt

import { ChatPromptTemplate } from "@langchain/core/prompts";

const ragPrompt = ChatPromptTemplate.fromMessages([
  [
    "system",
    `你是一个专业的知识库问答助手。请根据以下上下文信息回答用户的问题。

重要规则:
1. 只基于提供的上下文回答问题
2. 如果上下文中没有相关信息,请明确告知"根据现有文档,我无法回答这个问题"
3. 不要编造答案
4. 在回答末尾标注信息来源

上下文:
{context}`,
  ],
  ["human", "{input}"],
]);

关键点:

  • 明确告诉模型只基于上下文回答
  • 提供"不知道"的出口,避免幻觉
  • 要求标注来源,便于验证

3、完整的 RAG Chain

import { ChatOpenAI } from "@langchain/openai";
import { createStuffDocumentsChain } from "langchain/chains/combine_documents";
import { createRetrievalChain } from "langchain/chains/retrieval";

const model = new ChatOpenAI({ 
  model: "gpt-4o", 
  temperature: 0  // 确定性输出
});

// 第一步:创建文档合并链
const combineDocsChain = await createStuffDocumentsChain({
  llm: model,
  prompt: ragPrompt,
});

// 第二步:创建检索链
const ragChain = await createRetrievalChain({
  retriever,
  combineDocsChain,
});

// 第三步:执行
const result = await ragChain.invoke({
  input: "产品的退货政策是什么?",
});

console.log(result.answer);     // 基于知识库的回答
console.log(result.context);    // 检索到的文档片段

返回结果结构:

{
  input: "产品的退货政策是什么?",
  context: [
    Document { pageContent: "退货期限为购买后30天...", metadata: {...} },
    Document { pageContent: "退款将在7个工作日内处理...", metadata: {...} },
    // ...更多相关文档
  ],
  answer: "根据产品手册,退货政策如下:\n1. 退货期限:购买后30天内\n2. 退款时间:7个工作日内处理\n\n来源:product-manual.pdf 第5页"
}

4、显示引用来源

// 提取来源信息
const sources = result.context.map(doc => ({
  content: doc.pageContent.slice(0, 100) + "...",
  source: doc.metadata.source,
  page: doc.metadata.page,
}));

console.log("引用来源:");
sources.forEach((src, i) => {
  console.log(`${i + 1}. ${src.source} (第${src.page}页)`);
  console.log(`   ${src.content}\n`);
});

八、检索策略进阶

基础的相似度检索能覆盖大多数场景,但在实际业务中,往往需要更精细的检索策略。

1、混合检索(Hybrid Search)

(1)为什么需要混合检索?

纯向量检索的局限:

  • 对精确关键词匹配不够敏感
  • 例如搜索产品型号"X-2000",向量检索可能找不到

混合检索的优势:

  • 结合关键词搜索(BM25)和向量搜索
  • 兼顾语义相似性和关键词匹配
(2)实现方式

使用 Weaviate:

import { WeaviateStore } from "@langchain/weaviate";

const vectorStore = await WeaviateStore.fromDocuments(
  chunks,
  embeddings,
  {
    client: weaviateClient,
    indexName: "Documents",
    textKey: "text",
    metadataKeys: ["source"],
  }
);

// 混合检索
const hybridRetriever = vectorStore.asRetriever({
  searchType: "hybrid",
  searchKwargs: {
    alpha: 0.5,  // 0: 纯关键词, 1: 纯向量, 0.5: 各一半
  },
});

const docs = await hybridRetriever.invoke("X-2000 产品规格");

alpha 参数调优:

alpha 值检索类型适用场景
0.0纯关键词搜索精确的产品型号、代码
0.5平衡模式大多数场景
1.0纯向量语义搜索、概念性问题

2、查询改写(Query Rewriting)

(1)问题场景

用户的原始问题有时候表述不清:

  • “它有几年历史了?”("它"指代什么?)
  • “这个怎么样?”("这个"是什么?)
  • “多少钱?”(什么的价格?)
(2)解决方案

让 LLM 先对问题做改写,再检索:

import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";

// 定义查询改写 Prompt
const queryRewriterPrompt = ChatPromptTemplate.fromMessages([
  [
    "system",
    `你是一个查询优化助手。将用户的问题改写为更适合向量检索的格式:
1. 去除指代词(它、这个、那个)
2. 补充完整语义
3. 提取核心实体
4. 只输出改写后的查询,不要解释`,
  ],
  ["human", "原始问题:{question}"],
]);

const model = new ChatOpenAI({ model: "gpt-4o-mini" });
const rewriteChain = queryRewriterPrompt.pipe(model);

// 改写查询
const rewrittenQuery = await rewriteChain.invoke({
  question: "它有几年历史了?",
});

console.log(rewrittenQuery.content);
// 输出:"Apple 公司成立多少年了?"

// 用改写后的查询进行检索
const docs = await retriever.invoke(rewrittenQuery.content as string);
(3)多步查询改写

对于复杂问题,可以进行多轮改写:

// 第一轮:澄清指代
const clarified = await clarifyReferences(originalQuestion);

// 第二轮:扩展缩写
const expanded = await expandAbbreviations(clarified);

// 第三轮:提取关键词
const keywords = await extractKeywords(expanded);

// 最终查询
const finalQuery = `${expanded} ${keywords}`;

3、重排序(Reranking)

(1)为什么需要重排序?

问题:

  • 向量检索返回的结果按相似度排序
  • 但相似度 ≠ 相关性
  • 可能返回语义相似但不相关的文档

解决方案:

  • 先用向量检索召回较多结果(如 20 个)
  • 再用专门的重排序模型精排
  • 取前 N 个最相关的
(2)使用 Cohere Reranker
import { CohereRerank } from "@langchain/cohere";

const reranker = new CohereRerank({
  apiKey: process.env.COHERE_API_KEY,
  topN: 3,  // 重排序后取前 3 个
  model: "rerank-multilingual-v2.0",  // 支持多语言
});

// 第一步:粗检索(召回 20 个)
const coarseResults = await retriever.invoke(query, { k: 20 });

// 第二步:精排序(取前 3 个)
const refinedResults = await reranker.compressDocuments(
  coarseResults, 
  query
);

console.log(refinedResults.length);  // 3

效果对比:

策略召回数量准确率延迟成本
纯向量检索570%快低
向量 + 重排序20→390%中中
混合检索 + 重排序20→395%慢高
(3)其他重排序模型
模型提供商特点成本
Cohere RerankCohere效果好,支持多语言$0.02/100次
Jina RerankerJina AI开源,可自托管免费
BGE RerankerBAAI中文效果好免费

九、RAG 的常见问题与调优

1. 问题诊断矩阵

问题现象可能原因诊断方法解决方案
回答不准确chunk 太大,相关内容被稀释检查 chunk 大小和内容减小 chunkSize 到 500-800
找不到相关内容语义距离太大检查检索结果的相似度分数1. 尝试查询改写
2. 切换更好的 Embedding 模型
3. 增大 k 值
来源文档不准确关键词检索失效检查是否包含精确关键词使用混合检索
回答跨段落混乱chunk 之间上下文丢失检查 chunkOverlap增大 chunkOverlap 到 20-25%
频繁出现"无法回答"检索到的文档不相关检查检索结果的相关性1. 加入重排序步骤
2. 调整相似度阈值
3. 优化文档切割
响应速度慢检索或生成耗时过长监控各环节耗时1. 减小 k 值
2. 使用更快的 Embedding 模型
3. 缓存常见查询

2. 调优建议

(1)文档切割优化
// 针对不同类型的文档使用不同的切割策略

// 技术文档:较小的 chunk
const techSplitter = new RecursiveCharacterTextSplitter({
  chunkSize: 600,
  chunkOverlap: 100,
});

// 故事/文章:较大的 chunk
const storySplitter = new RecursiveCharacterTextSplitter({
  chunkSize: 1200,
  chunkOverlap: 200,
});

// 代码:使用语言感知切割
const codeSplitter = RecursiveCharacterTextSplitter.fromLanguage(
  "typescript",
  { chunkSize: 800, chunkOverlap: 150 }
);
(2)Embedding 模型选择
// 根据预算和精度要求选择

// 预算充足,追求精度
const premiumEmbeddings = new OpenAIEmbeddings({
  model: "text-embedding-3-large",
});

// 性价比之选(推荐)
const balancedEmbeddings = new OpenAIEmbeddings({
  model: "text-embedding-3-small",
});

// 预算有限,自托管
const freeEmbeddings = new HuggingFaceTransformersEmbeddings({
  modelName: "Xenova/all-MiniLM-L6-v2",
});
(3)检索参数调优
// 从小 k 值开始,逐步增加
const retriever = vectorStore.asRetriever({
  k: 3,  // 从 3 开始测试
});

// 监控检索结果的相关性
const docs = await retriever.invoke(query);
docs.forEach((doc, i) => {
  console.log(`文档 ${i + 1} 相关性:${doc.metadata.score}`);
});

// 如果相关性低,增大 k 或改进 Embedding
(4)Prompt 优化
// 不好的 Prompt
const badPrompt = ChatPromptTemplate.fromMessages([
  ["system", "回答问题:{input}"],
]);

// 好的 Prompt
const goodPrompt = ChatPromptTemplate.fromMessages([
  [
    "system",
    `你是专业的客服助手。基于以下上下文回答问题:

规则:
1. 只使用提供的信息
2. 如果信息不足,说"我需要更多信息"
3. 引用具体来源
4. 语气友好专业

上下文:
{context}`,
  ],
  ["human", "{input}"],
]);

十、本章小结

RAG 是让 LLM 具备实时知识和私有数据能力的关键技术,在减少AI输出幻觉和增加准确度上都非常重要。

📝 核心知识点回顾

阶段关键组件最佳实践
1. 文档加载PDFLoader, WebLoader 等选择适合的加载器,保留元数据
2. 文档切割RecursiveCharacterTextSplitterchunkSize 800-1200,overlap 15%
3. EmbeddingOpenAI text-embedding-3-small平衡成本和效果
4. 向量存储Pinecone, Chroma, PGVector根据场景选择
5. 检索生成Retriever + RAG Chain添加引用来源,控制幻觉

🎯 动手练习

尝试完成以下练习,巩固所学知识:

练习 1:构建产品知识库

  • 收集公司产品文档(PDF、Word、网页)
  • 实现完整的 RAG Pipeline
  • 测试常见问题,评估回答质量
  • 优化 chunkSize 和 k 值

练习 2:实现查询改写

  • 创建查询改写 Prompt
  • 测试指代消解效果
  • 对比改写前后的检索质量

练习 3:添加重排序

  • 集成 Cohere Reranker
  • 对比有无重排序的效果差异
  • 分析成本和收益

练习 4:性能优化

  • 监控各环节耗时
  • 实现查询缓存
  • 优化向量数据库配置
  • 目标:P95 延迟 < 2 秒

📚 延伸阅读


下一章:《第九章 —— 多 Agent 系统》

RAG实战案例:如何基于 LangChain 实现智能检索生成系统 检索增强生成 (RAG) 是一种使用来自私有或专有数据源的信息来辅助文本生成的技术。它将检索模型(设计用于搜索大型数据集或知识库)和生成模型(例如大型语言模型 (LLM),此类模型会使用检索到的信息生成可供阅读的文本回复)结合在一起。通过从更多数据源添加背景信息,以及通过训练来补充 LLM 的原始知识库,检索增强生成能够提高搜索体验的相关性。这能够改善大型语言模型的输出,但又无需重新训练模型。 阅读详情

相关推荐

检索增强生成(RAG)生成实战(langchain+chatglm)

检索增强生成(RAG)是一个概念,它旨在为大语言模型(LLM)提供额外的、来自外部知识源的信息。这样,LLM 在生成更精确、更贴合上下文的答案的同时,也能有效减少产生误导性信息的可能。问题当下领先的大语言模型 (LLMs) 是基于大量数据训练的,目的是让它们掌握广泛的普遍知识,这些知识被储存在它们神经网络的权重(也就是参数记忆)里。但是,如果我们要求 LLM 生成的回答涉及到它训练数据之外的知识——比如最新的、专有的或某个特定领域的信息——这时就可能出现事实上的错误(我们称之为“幻觉”)

xuezhangdaima的博客 1804

LangChain 1.3 完全教程:从入门到精通-Part 9: RAG(检索增强生成)做好软件测试你要学习这些

知识过时:模型的训练数据有截止日期,无法获取最新信息幻觉问题:模型可能"一本正经地胡说八道",生成不准确的内容缺乏私有数据:模型不了解你公司的内部文档、业务知识无法引用来源:模型无法告诉用户答案来自哪里。

lw的博客 536

RAG 技术实战:LangChain4j 的文档处理与检索增强生成

**文章摘要**: 本文深入解析 LangChain4j 中的 RAG(检索增强生成)技术,详细阐述其核心原理与应用场景。RAG 通过检索相关信息并注入提示,显著提升 LLM 的回答准确性,减少幻觉。文章从简单 RAG、基本 RAG 到高级 RAG 的实现路径逐步展开,涵盖文档加载、嵌入存储、内容检索等关键环节,并提供 LangChain4j 的 API 使用指南。通过优化查询转换、多源检索与内容聚合,RAG 技术在问答系统、知识库检索等领域展现出强大的实用性。本文为开发者提供从入门到精通的完整实践路径

洛阳泰山的博客 2800

LangChain入门系列:RAG检索增强生成全解析

检索增强生成(RAG)技术是大语言模型实现知识扩展的关键突破,其核心工作原理可概括为"现查现用"的智能增强机制。当大模型遇到超出其训练数据范围的问题时,RAG会实时从外部知识库检索相关信息,将这些新鲜知识智能整合到生成过程中,使模型能够结合最新数据给出准确回答。这一过程完美弥补了大模型固有的三大知识短板:训练数据的时效性局限、专有知识的缺失问题以及特定领域的深度不足。通过动态检索与智能融合的双重机制,RAG既保留了预训练模型的强大推理能力,又突破了静态知识库的边界,实现了"即需即学"的智能进化。这种技术特别

yihanss的博客 2091

Matlab/simulink频率响应分析方法

Matlab/Simulink仿真系列问题一.电气模块与信号模块 一.电气模块与信号模块

virtuoso~晓晓 3万+

Office Tool Plus:正版Office干净部署指南

Office部署是Windows新机配置的关键环节,涉及版本选择、架构匹配、语言支持与合规激活等基础技术问题。其核心原理基于微软官方Office Deployment Tool(ODT)的声明式XML配置机制,通过标准化流程确保安装可复现、可审计、无第三方捆绑。技术价值在于规避官网安装器的版本锁定、架构误配和语言缺失等常见风险,提升部署稳定性与安全性。典型应用场景包括企业批量部署、IT运维标准化、隐私敏感型用户自主安装。本文以Office Tool Plus为实践载体,深入解析ODT底层逻辑、XML配置规范

1185

9.LangChain框架(实现RAG)

大模型 LangChain

计算机王的博客 1364

接入穿山甲SDK时,Unity打Android包报错日志

SDK工程设置为Enable,项目工程设置为Disable。2、将unitypackage导入包名为:com.DefaultCompany.Myproject的另一个工程,打包报错。3、点击工程默认弹出Enable Android Auto-resolution 设置选项,点击Enable。1、新建一个空工程,设置包名为:com.ceshi.hewen,正常打包无报错,导出unitypackage。2、点击Reset to Defaults 重置参数,再点击ok关闭设置窗口。

不文不武的禾文 3585

LangChain之检索增强生成RAG

RAG全称为Retrieval-Augmented Generation,即检索增强生成,结合了检索和生成的能力,引入外部知识库为文本生成任务提供支持,增强模型生成能力,产生更丰富、准确、有根据的内容。

积跬步,至千里。 1344

手把手教你用海康威视相机+DLP4500搭建双目结构光系统(附避坑指南)

本文详细介绍了如何使用海康威视相机和DLP4500搭建双目结构光三维测量系统,涵盖硬件选型、系统搭建、双目标定及三维重建等关键步骤。特别针对预算有限的开发者和实验室团队,提供实用的避坑指南和优化技巧,帮助实现0.02mm的高精度测量。

weixin_42526087的博客 462

HT7533与1117稳压芯片动态特性对比:实测分析与优化策略

本文深入对比了HT7533与1117稳压芯片的动态特性,包括电压过冲和瞬态响应能力,并提供了实测数据与优化策略。HT7533适合低功耗设备,而1117在大电流和稳定性要求高的场景表现更优。文章还分享了PCB布局和电容选择的实用建议,帮助工程师根据项目需求选择合适的稳压芯片。

weixin_28454475的博客 610

LangChain入门(3):RAG(检索增强生成)

本文介绍了LangChain框架中的RAG(检索增强生成)技术,旨在解决大模型更新参数耗时且可能产生“幻觉”的问题。RAG通过将新知识作为文档提供给大模型,使其直接从文档中检索内容。

雨落倾城的博客 2553

华为OD机试真题 新系统2026-04-01 Python&JS 实现【空间占用计算】

员工A的磁盘空间经常被耗尽,他需要找到占用空间最大的目录或文件,然后决定如何清理文件释放空间。给定某一目录,请编写程序帮助他统计该目录内一级子目录和文件的占用空间,并返回目标目录一级子项(文件或子目录)中占用空间最大的项。

MISAYAONE的博客 1303

SpringBoot整合LangChain4j实现RAG (检索增强生成)

本文介绍了使用langchain4j,整合SpringBoot开发RAG应用的方法。

m0_71741473的博客 2207

YOLO26训练教程,训练自己的数据集教学,从源码下载,配置虚拟环境,准备数据集、训练、验证、推理测试 。实现0到1的完整教学过程。快速入门必看

本文详细介绍了YOLO26目标检测模型的配置与使用流程:1)下载YOLOv11源码并创建Python3.10虚拟环境;2)安装PyTorch2.5.1及相关依赖库;3)准备数据集并修改配置文件;4)编写训练脚本设置参数(640x640分辨率、500轮次);5)验证模型效果;6)使用训练好的模型进行推理测试;7)生成可视化热力图。整个过程涵盖了从环境搭建到模型应用的全流程,并提供了清华镜像源加速下载。

Ai缝合怪、助力小伙伴高效发论文 5284

华为非AI方向0603笔试真题-爆破小游戏(详细思路+多语言题解)

华为非AI方向0603笔试第二题【爆破小游戏】,提供详细思路讲解以及代码实现。

qq_45776114的博客 358

一文教会你用 LangChain 构建一个检索增强生成 (RAG) 应用

RAG 是一种通过额外数据增强大型语言模型知识的技术。大型语言模型可以推理广泛的主题,但它们的知识仅限于训练时使用的特定时间点的公共数据。如果您想构建能够推理私有数据或在模型截止日期后引入的数据的 AI 应用程序,您需要用模型所需的特定信息来增强模型的知识。将适当的信息引入并插入到模型提示中的过程称为检索增强生成(RAG)

fengshi_fengshi的专栏 1370

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

LangChain 24 对本地文档的搜索RAG检索增强生成Retrieval-augmented generation

RAG 是一种用额外的、通常是私人的或实时的数据增强LLM知识的技术。LLM可以推理广泛的话题,但它们的知识仅限于它们在特定时间点之前训练的公共数据。如果你想构建可以推理私人数据或模型截止日期之后引入的数据的人工智能应用程序,你需要用模型需要的具体信息增强模型的知识。将适当的信息带入并插入到模型提示中的过程被称为检索增强生成(RAG)。

AI架构师易筋 2217

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

LangChain-04 RAG Retrieval-Augmented Generation 检索增强生成 + ChatPromptTemplate

LangChain 中的 RAG(检索增强生成)通过“检索—增强—生成”三步实现精准问答:首先从向量数据库中检索相关文档片段,再结合问题筛选最优上下文,最后由大模型生成答案。这一机制能显著降低幻觉问题,提升回答准确率,并支持可追溯来源。典型应用涵盖智能客服、学术助手和企业知识管理,相比传统大模型,RAG在准确性、知识更新和透明性方面优势明显。LangChain 框架提供 Retriever 与 LLM 的组合接口,仅需少量代码即可构建 RAG 应用,并支持高级功能如多跳检索和重排序。同时,ChatPromp

谢谢你的喜欢 我们一起无限进步 5982

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

RAG(检索增强生成 )

RAG(检索增强生成)

weixin_61494821的博客 1583

第十一周:RAG(检索增强生成)+ Langchain和Llamaindex

本周对RAG结构进行了研究,从经典RAG介绍到了更现代的模块RAG。同时对LangChain和LlamaIndex两个LLM+RAG的开发框架进行了对比,个人更喜欢Llamaindex。

weixin_53834244的博客 1177

检索增强生成(RAG)入门

RAG是一个利用特定任务的外部知识来提高由生成模型驱动的应用性能的框架。RAG流水线的有不同组成部分,包括外部知识源、提示模板和生成模型,如何在检索、增强和生成。包括市场上流行的RAG使用案例和实现框架,例如LangChain、LlamaIndex和DSPy。最后本文涉及了一些专业的RAG技术,包括高级RAG方法、智能体RAG和图形RAG,以及用于评估RAG流水线的方法。目录1概要1.1生成模型的限制1.2检索增强生成 (RAG)是什么?2RAG架构3提示模板4RAG是如何工作的?

lyy2017175913的博客 1656

langchain4j之RAG 检索增强生成

摘要:RAG(检索增强生成)通过外部知识库检索增强大语言模型的专业领域回答能力,相比微调模型具有实时更新和低成本优势。其核心流程包括:文档加载(支持本地/网络/云存储多种来源)、文档解析(处理各类格式文件)、文档分割(按段落/句子/单词等切分)。RAG采用全文搜索、向量搜索或混合搜索方法,将检索结果与问题结合输入模型生成回答。适用于知识频繁更新的企业客服、医疗法律等场景,能有效解决大模型专业领域知识不足的问题。(149字)

分享 AI Agent、大模型与后端开发实战; 空门技术栈。 941

【大模型】RAG检索增强生成

RAG(Retrieval-Augmented Generation)是一种结合了信息检索(Retrieval)和生成(Generation)模型的混合型大模型架构,旨在解决传统生成模型在处理大规模外部知识时的局限性。简单来说,RAG通过在生成过程之前引入检索步骤,使得生成模型可以利用外部文档或知识库来增强其生成能力,提升对复杂问题的回答准确性。

zkw54334的博客 1744

使用LangChain建立检索增强生成(RAG)系统

RAG是一种通过附加数据增强 LLM 知识的技术。LLM 可以推理广泛的主题,但它们的知识仅限于在训练它们的特定时间点之前的公共数据。如果你想构建能够推理私有数据或模型截止日期后引入的数据的 AI 应用程序,则需要使用模型所需的特定信息来增强模型的知识。将适当的信息引入和插入模型提示的过程称为检索增强生成(Retrieval Augmented Generation)。LangChain 有许多组件旨在帮助构建问答应用程序,以及更普遍的 RAG 应用程序。注意:这里我们专注于非结构化数据的问答。

qingkahui24689的博客 701
上一篇: 深入浅出 LangChain —— 第七章:Agent 架构深度解析与LangGraph 核心概念
下一篇: 深入浅出 LangChain —— 第九章:多 Agent 系统
FrontAI
博客等级 码龄1年 61粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值