LangChain RAG 核心入门:原理、完整流程与文档加载实战 我挖掘了一个巨牛的 人工智能 学习网站通俗易懂风趣幽默忍不住分享一下给大家。点击跳转到网站。引言搜索引擎知道一切但不会总结大模型会总结但对你的私有数据一无所知。有没有一种方案能把两者的优势结合起来有。它叫 RAG检索增强生成——目前大模型落地应用最主流、最成熟的技术方案。无论是企业知识库、智能客服还是 AI 搜索产品背后几乎都跑着这套逻辑。本文将从核心概念、完整工作流程到基于 LangChain 的实战代码带你一步步搭建一个属于自己的 RAG 问答系统。文章配套完整代码复制即可运行。一、RAG 核心概念与诞生背景1.1 大模型与传统搜索引擎的优缺点想要理解 RAG我们可以通过「AI 大模型 搜索引擎」的组合逻辑快速吃透核心思想AI 大模型擅长语义理解、文本总结、逻辑推理、对话生成但存在致命短板——训练数据有截止日期无法获取实时信息也无法读取本地、企业私有数据。传统搜索引擎擅长抓取全网公开实时数据但缺点是信息零散、冗余需要人工筛选、总结、整合无法自动生成精准答案。简单来说大模型有智商但没新知识、没私有知识搜索引擎有海量实时数据但无理解和总结能力。而 RAG 技术的核心就是将两者结合给大模型配备「专属私有活字典」让模型可以实时查阅自定义知识库输出精准、合规、实时的答案。1.2 RAG 与 AI 搜索的核心区别AI 搜索知识库是互联网公开数据通过联网检索全网信息辅助回答。RAG 检索增强生成知识库是本地文档、企业私有文档、自定义数据不依赖公网完全私有化部署。当用户向大模型提问时RAG 会先在私有知识库中做语义检索匹配相关上下文再将「用户问题 检索到的私有上下文」一并交给大模型最终生成贴合业务、贴合私有数据的精准答案。二、RAG 完整工作流程RAG 整体分为两大核心阶段离线数据处理、在线实时检索生成也是 LangChain 整套组件的核心学习地图。2.1 离线数据处理知识库构建原始的 PDF、Markdown、Word 等文档无法直接用于向量检索需要经过标准化处理构建成可检索的结构化知识库核心步骤如下文档加载Document Loading通过 LangChain 各类加载器读取 PDF、MD、数据库、网页等百余种数据源统一转为Document文档对象。文本分割Splitting将超长文档切割为固定大小、语义完整的文本块解决大模型上下文窗口限制、检索粒度粗糙的问题。向量化存储Embedding Storage通过嵌入模型将文本块转为向量数据最终持久化存储到向量数据库完成私有知识库构建。2.2 在线检索生成用户问答阶段检索Retrieval用户输入问题后系统将问题向量化在向量数据库中匹配相似度最高的文本块。生成输出Output将「用户问题 检索得到的私有上下文」传入大模型模型基于专属知识库生成精准、可靠的回答。三、RAG 完整实战演示本节基于「脚手架级微服务租房平台QA」文档这里的文档你可以随意替换成你自己的快速搭建最简 RAG 问答系统实现自定义文档智能问答要求模型精简作答最多三句话。注意文档内容越详细、语义越清晰RAG 生成的回答就越精准、贴合业务。四、LangChain Document 文档核心类Document是 LangChain 所有 RAG 应用的基础数据载体所有文档加载、分割、存储操作最终都是对 Document 对象处理。4.1 Document 类核心参数page_content核心文本内容字符串格式存储文档正文。metadata元数据字典存储文档来源、路径、页码、分类等附属信息。id可选唯一标识推荐 UUID 格式用于精准区分文档块。4.2 手动创建 Document 对象from langchain_core.documents import Document # 自定义文档对象列表 documents [ Document( page_content狗是很好的伴侣以忠诚和友好而闻名。, metadata{source: mammal-pets-doc}, ), Document( page_content猫是独立的宠物经常享受自己的空间。, metadata{source: mammal-pets-doc}, ), ]通常单个 Document 对象对应原始文档的一个分页或一个文本块是 RAG 处理的最小单元。五、实战PDF 文档加载PyPDFLoaderLangChain 提供PyPDFLoader专门用于解析本地 PDF 文件自动将 PDF 每一页转换为一个独立的 Document 对象。5.1 PDF 加载代码from langchain_community.document_loaders import PyPDFLoader file_path ../Docs/PDF/脚手架级微服务租房平台QA.pdf loader PyPDFLoader(file_path) # 加载PDF每页对应一个Document docs loader.load() # 查看文档基础信息 print(fPDF 文件的总页数为\n{len(docs)}\n) print(f第一页文本内容前200字符\n{docs[0].page_content[:200]}\n) print(f第一页元数据\n{docs[0].metadata})5.2 运行结果问PDF 文件的总页数为 32 问第一页文本内容的前200个字符是 脚手架级微服务租房平台 通用问题 1. 为什么做这个项目 • 回答1出于兴趣爱好开发 大学期间我和同学在外合租过一段时间使用了一些租房平台于是我有个想法自己能不能开发一个租房平台可以让我将理论知识与实践相结合。我希望通过实际项目来加深对Java编程语言和相关技术的理解。于是我便查找了一些资料看了一些开源项目进行了一些改进。 • 回答2开源项目的解释 这个 问第一页元数据 {producer: pdfcpu v0.8.1 dev, creator: Chromium, creationdate: 2025-08-28T17:52:3408:00, moddate: 2025-08-28T17:52:3408:00, source: ../PDF/脚手架级微服务租房平台QA.pdf, total_pages: 32, page: 0, page_label: 1}拓展对于含图片、图表、扫描件的复杂 PDF可将页面转为图片通过多模态大模型解析精度远高于纯文本解析。并且PDF文档解析不了图片六、实战Markdown 文档加载UnstructuredMarkdownLoaderMarkdown 是技术文档主流格式LangChain 通过UnstructuredMarkdownLoader实现 MD 文件加载支持两种加载模式适配不同业务场景。6.1 环境依赖安装pip install unstructured[md] nltk6.2 single 模式整文档单对象加载默认模式将整个 MD 文件合并为单个 Document 对象适合整体读取文档、简单分割场景。from langchain_community.document_loaders import UnstructuredMarkdownLoader from langchain_core.documents import Document markdown_path ../Docs/Markdown/脚手架级微服务租房平台QA.md loader UnstructuredMarkdownLoader(markdown_path) data loader.load() # 校验结果仅生成一个文档对象 assert len(data) 1 assert isinstance(data[0], Document) print(data[0].page_content[:200]) print(data[0].metadata)6.3 elements 模式结构化拆分加载按文档元素类型拆分将标题、段落、列表、表格、图片单独拆分为 Document 对象保留文档层级结构适合精细化解析、结构化检索场景。from langchain_community.document_loaders import UnstructuredMarkdownLoader markdown_path ../Docs/Markdown/脚手架级微服务租房平台QA.md loader UnstructuredMarkdownLoader(markdown_path, modeelements) data loader.load() print(f文档总个数\n{len(data)}\n) print(前三个文档元素详情) for document in data[:3]: print(f{document}\n) # 查看所有文档元素类型 print(文档包含的所有元素类型) #生成器表达式的写法 print(set(doc.metadata[category] for doc in data))补充生成器表达式的写法以及调用流程顺序描述书写表达式 for 变量 in 数据源执行流程右侧for document in docs先取出一个 document运行左侧表达式得到一个值将该值送入 set 做去重存储循环直到 docs 全部遍历完3.我对生成表达式的理解set(表达式 for document in docs)会完整遍历一次 for 循环每一轮循环拿到 document 后执行前面的表达式算出一个值把算出的值存入集合自动去重。对于上面的代码含义就是从data列表中取出每一个文档doc找到它的元数据metadata里的category字段把所有不同的值收集起来打印出来。举个极简例子验证nums [1,2,2,3] res set(x*10 for x in nums)循环过程 x1 → 11010 → 放入集合x2 → 21020 → 放入集合 x2 → 21020 → 重复丢弃x3 → 31030 → 放入集合 最终 {10,20,30} 这里x*10是计算不是把 x 赋值给x*10。6.4 运行结果与元素类型解析运行后文档被拆分为441 个结构化文档对象包含以下核心元素类型Title各级标题包含层级深度、父子关联 IDNarrativeText正文叙述段落ListItem有序/无序列表项Table表格内容Image图片资源UncategorizedText脚注、注释、页眉页脚等未分类文本通过parent_id和element_id可以还原 MD 文档完整层级结构实现精准的结构化检索。整体代码七、总结本文我们从零梳理了 RAG 的核心思想与完整工作流程并通过 LangChain 实战演示了 PDF、Markdown 文档的加载与解析。总结一下关键要点RAG 大模型 私有知识库解决模型“有智商无知识”的痛点知识库构建分为两步文档加载 → 文本分割 → 向量存储LangChain 的 Document 是所有 RAG 操作的最小数据单元PyPDFLoader按页加载 PDFUnstructuredMarkdownLoader支持按元素结构化拆分 MD当然这只是 RAG 的入门第一步。后续我们还将深入文本分割策略如何切分才能不丢失语义向量嵌入与检索优化如何让召回更精准高级 RAG 技术HyDE、RAPTOR、Self-RAG 等如果你也对 RAG 感兴趣欢迎点赞、在看、转发三连你的支持是我持续更新的最大动力有任何问题也欢迎在评论区留言交流我会尽量回复