基于 LangChain 实现 RAG 知识库问答系统:完整指南

基于 LangChain 实现 RAG 知识库问答系统:完整指南

背景介绍

大语言模型(LLM)很强,但让它回答私有知识库里的问题,一直是个工程难题。直接把所有文档喂给 LLM 不太现实——知识可能过时,覆盖不了特定领域,而且模型还会编答案。

检索增强生成(Retrieval-Augmented Generation,RAG) 是目前最流行的解决方案。简单说就是:先从外部知识库找到相关信息,然后把这段信息连同问题一起发给 LLM,让它基于真实内容回答。

LangChain 是做 LLM 应用开发的主流框架,工具链很成熟。本文会一步步教你用 LangChain 搭建一个完整的 RAG 问答系统。

问题描述

实际业务中,AI 通常需要处理这些内容:

  • 企业内部文档
  • 技术手册和 API 文档
  • 产品知识库
  • 历史对话记录

直接喂给 LLM 的问题在哪:

  1. 上下文不够长:LLM 有输入上限,文档多了装不下
  2. 找不到重点:没办法快速定位和问题相关的段落
  3. 花钱太多:输入 token 越多,费用越高
  4. 答案不稳定:无关内容会干扰 LLM 的判断

RAG 用向量检索和智能分块来解决这些问题,只让 LLM 看到最相关的少量内容。

详细步骤

1. 环境准备

先装必要的 Python 包:

pip install langchain langchain-community langchain-openai faiss-cpu pypdf python-dotenv

每个包的作用:

  • langchain:核心框架
  • langchain-community:社区集成
  • langchain-openai:OpenAI LLM 集成
  • faiss-cpu:向量搜索库
  • pypdf:处理 PDF

2. 文档加载与处理

from langchain_community.document_loaders import PyPDFLoaderfrom langchain.text_splitter import RecursiveCharacterTextSplitterloader = PyPDFLoader("knowledge_base.pdf")documents = loader.load()text_splitter = RecursiveCharacterTextSplitter(    chunk_size=1000,    chunk_overlap=200)chunks = text_splitter.split_documents(documents)print(f"分割后的块数量: {len(chunks)}")

3. 向量嵌入与存储

from langchain_openai import OpenAIEmbeddingsfrom langchain_community.vectorstores import FAISSembeddings = OpenAIEmbeddings(model="text-embedding-3-small")vectorstore = FAISS.from_documents(documents=chunks, embedding=embeddings)vectorstore.save_local("faiss_index")

4. 构建检索链

from langchain_openai import ChatOpenAIfrom langchain.chains import create_retrieval_chainfrom langchain.chains.combine_documents import create_stuff_documents_chainfrom langchain.prompts import PromptTemplatellm = ChatOpenAI(model="gpt-4o", temperature=0.7)prompt = PromptTemplate(template="你是问答助手。\n{context}", input_variables=["context"])combine_docs_chain = create_stuff_documents_chain(llm=llm, prompt=prompt)retriever = vectorstore.as_retriever(search_kwargs={"k": 3})qa_chain = create_retrieval_chain(retriever=retriever, combine_docs_chain=combine_docs_chain)

5. 开始问答

response = qa_chain.invoke({"input": "如何安装 LangChain?"})print(response["answer"])

完整代码示例

import osfrom dotenv import load_dotenvfrom langchain_community.document_loaders import PyPDFLoader, TextLoaderfrom langchain_community.vectorstores import FAISSfrom langchain_openai import OpenAIEmbeddings, ChatOpenAIfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain.chains import create_retrieval_chainfrom langchain.chains.combine_documents import create_stuff_documents_chainfrom langchain.prompts import PromptTemplateload_dotenv()class RAGQASystem:    def __init__(self, api_key):        self.embeddings = OpenAIEmbeddings(model="text-embedding-3-small", openai_api_key=api_key)        self.llm = ChatOpenAI(model="gpt-4o", temperature=0.7, openai_api_key=api_key)        self.vectorstore = None        self.qa_chain = None        def load_documents(self, file_paths):        documents = []        for fp in file_paths:            if fp.endswith(".pdf"): loader = PyPDFLoader(fp)            elif fp.endswith(".txt"): loader = TextLoader(fp, encoding="utf-8")            else: continue            documents.extend(loader.load())        return documents        def build_index(self, docs, chunk_size=1000, chunk_overlap=200):        splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)        chunks = splitter.split_documents(docs)        self.vectorstore = FAISS.from_documents(chunks, self.embeddings)        return self        def setup_qa_chain(self):        retriever = self.vectorstore.as_retriever(search_kwargs={"k": 3})        prompt = PromptTemplate(template="你是助手\n{context}", input_variables=["context"])        combine = create_stuff_documents_chain(self.llm, prompt)        self.qa_chain = create_retrieval_chain(retriever, combine)        return self        def ask(self, q): return self.qa_chain.invoke({"input": q})["answer"]if __name__ == "__main__":    rag = RAGQASystem(os.getenv("OPENAI_API_KEY"))    docs = rag.load_documents(["docs/faq.pdf"])    rag.build_index(docs).setup_qa_chain()    print(rag.ask("LangChain 支持哪些格式?"))

运行结果

已处理 156 个文档块RAG 检索链构建完成!问题: LangChain 支持哪些文档格式?答案: LangChain 支持好几种文档格式:PDF、文本文件、Word、HTML、Markdown、JSON等。

总结

本文介绍了如何用 LangChain 搭建 RAG 知识库问答系统:

  1. 处理大量文档很高效
  2. 支持各种文档格式
  3. 容易扩展
  4. 省钱

后续可优化的方向:换更好的 Embedding 模型、用混合检索、加 rerank 模型、支持多轮对话等。

RAG 是企业 AI 应用的核心技术,学会这个能做很多实用的 AI 产品。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇