深入浅出LangChain AI Agent智能体开发教程(九)—LangChain从0到1搭建知识库

前言

本系列分享前八篇分别讲述了

上篇文章分享了LangChain便捷接入MCP的完整实现流程。当今大模型应用领域能和Agent开发平起平坐的应用形式当属RAG检索增强生成知识库系统。RAG知识库系统可以将私有知识(例如私有文档等)存储在数据库中,为大模型提供关键的上下文逻辑支持,确保大模型回答准确,是大模型减少"幻觉"的关键。RAG技术被广泛应用于智能客服问答、企业信息处理等各个关键领域。作为Agent应用开发的"扛把子",LangChain对RAG开发也提供了良好的支持。本期内容笔者将手把手分享如何利用LangChain从0到1开发小型PDF RAG系统。阅读本篇文章前希望大家已经了解RAG的基础概念,不太了解的读者可以阅读笔者的RAG技术专栏,掌握RAG的基本执行流程。

本系列分享是笔者结合自己学习工作中使用LangChain&LangGraph经验倾心编写,力求帮助大家体系化快速掌握LangChain&LangGraph AI Agent智能体开发的技能!大家感兴趣可以关注笔者掘金账号和系列专栏。更可关注笔者同名微信公众号: 大模型真好玩 , 每期分享涉及的代码均可在公众号私信: LangChain智能体开发获得。

一、环境搭建

本期实战内容我们会通过Streamlit前端界面,结合LangChain框架与DashScope向量嵌入服务,实现一个轻量化的RAG智能问答系统。该系统支持上传多个PDF文档,系统将自动完成文本提取、分块、向量化,并构建基于FAISS的检索数据库。用户可以在前端页面输入任意问题,系统会调用DeepSeek-Chat模型对PDF进行语义理解和回答生成。

项目的第一步还是要安装我们所需环境,在之前创建的anaconda虚拟环境langchainenv中执行如下命令安装相关依赖:

复制代码
pip install streamlit PyPDF2 dashscope faiss-cpu

二、LangChain知识库智能体核心逻辑

  1. 引入相关依赖,编写如下代码。不借助库从0到1搭建RAG需要大量的代码和开发时长,LangChain的出现大大降低了智能体RAG系统的开发难度。可以看到LangChain对RAG系统的文本分块分块向量存储向量检索大模型生成 等基本环节都作了成熟的封装,用户只需设计组织逻辑并调用相应的api即可快速完成RAG系统开发。 创建langchain搭建pdf解析rag系统.py文件并写入如下代码:
python 复制代码
import streamlit as st #用来快速构建前端页面
from PyPDF2 import PdfReader # PDF文档读取、处理的依赖库
from langchain.text_splitter import RecursiveCharacterTextSplitter # LangChain封装的文档切分库
from langchain_core.prompts import ChatPromptTemplate # LangChain提示词模板组件
from langchain_community.vectorstores import FAISS # LangChain使用FAISS向量数据库保存切分后短文档的文本块向量
from langchain.tools.retriever import create_retriever_tool #RAG中的R,把RAG系统中的检索功能封装成工具,提供检索文本块向量功能
from langchain.agents import AgentExecutor, create_tool_calling_agent #LangChain中高层封装的Agent
from langchain_community.embeddings import DashScopeEmbeddings #调用阿里云百炼平台的Embedding模型
from langchain.chat_models import init_chat_model # LangChain封装大模型组件
  1. 设置向量模型和大语言模型,向量模型使用了阿里云百炼提供的text-embedding-v1模型,使用前需要注册阿里百炼的api_key。大语言模型使用DeepSeek-V3.1模型,也需要申请深度求索的api_key。申请api_key的详细操作大家可以参考我的文章【最新整理】全网免费接入DeepSeek-R1平台清单,包含网站和API使用(建议收藏)
python 复制代码
# 初始化向量模型
embeddings = DashScopeEmbeddings(
    model="text-embedding-v1",
    dashscope_api_key='你在阿里云百炼注册的api_key'
)

#初始化大语言模型
llm = init_chat_model(
    model='deepseek-chat',
    model_provider="deepseek",
    api_key='你在DeepSeek官网注册的api_key'
)
  1. 利用PDFReader读取上传的PDF文档内容并将其切分成文本块。每个文本块包含1000个词,相邻两个文本块之间有200个词重合。
python 复制代码
#读取pdf上传的内容
def pdf_read(pdf_doc):
    text = ""
    for pdf in pdf_doc:
        pdf_reader = PdfReader(pdf)
        for page in pdf_reader.pages:
            text += page.extract_text()
    return text


def get_chunks(text):
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
    chunks = text_splitter.split_text(text)
    return chunks

我们用图片直观展示文本切分的流程:

  1. 文本切分后的文本块需要使用embedding模型转换并存入向量数据库中,文本块向量用来与用户输入的问题进行关联性匹配并加入到模型提示词的上下文中扩展大模型相关知识边界。LangChain存储文本块向量的操作十分简单,代码如下:
python 复制代码
def vector_store(text_chunks):
    vector_store = FAISS.from_texts(text_chunks, embedding=embeddings)
    vector_store.save_local("faiss_db")

我们用图片表示文本块向量转化和存储的流程:

  1. 构建知识库回答逻辑链。RAG检索增强系统的核心原理是大模型根据用户提问,从文本块向量库中查找与问题相似度高的文本向量将其添加到上下文中,由智能体完成"读取问题->查询->补充上下文->回答"的流程。大家来回忆一下构建LangChain构建智能体的三要素:工具模型提示词

    • 工具: 使用LangChainretrievercreate_retriever_tool构建内容检索工具
    • 大模型: 前面代码构建的llm, 本次使用的是deepseek-v3.1模型
    • 提示词: 使用ChatPromptTemplate构建提示词,保留chat_history历史占位信息和agent_scratchpad工具内容占位信息

    具体代码如下:

python 复制代码
# 构建知识库回答逻辑链
def check_database_exists():
    """检查FAISS数据库是否存在"""
    return os.path.exists("faiss_db") and os.path.exists("faiss_db/index.faiss")

def user_input(user_question):
    # 检查数据库是否存在
    if not check_database_exists():
        st.error("❌ 请先上传PDF文件并点击'Submit & Process'按钮来处理文档!")
        st.info("💡 步骤:1️⃣ 上传PDF → 2️⃣ 点击处理 → 3️⃣ 开始提问")
        return

    try:
        # 加载FAISS数据库
        new_db = FAISS.load_local("faiss_db", embeddings, allow_dangerous_deserialization=True)

        retriever = new_db.as_retriever() #将数据转化为LangChain检索工具
        retrieval_chain = create_retriever_tool(retriever, "pdf_extractor",
                                                "This tool is to give answer to queries from the pdf")
        get_conversational_chain(retrieval_chain, user_question)

    except Exception as e:
        st.error(f"❌ 加载数据库时出错: {str(e)}") # 前端界面报错
        st.info("请重新处理PDF文件") # 前端界面info提示

def get_conversational_chain(tools, querys):
    prompt = ChatPromptTemplate.from_messages([
        (
            "system",
            """你是AI助手,请根据提供的上下文回答问题,确保提供所有细节,如果答案不在上下文中,请说"答案不在上下文中",不要提供错误的答案""",
        ),
        ("placeholder", "{chat_history}"),
        ("human", "{input}"),
        ("placeholder", "{agent_scratchpad}"),
    ])

    tool = [tools]
    agent = create_tool_calling_agent(llm, tool, prompt)
    agent_executor = AgentExecutor(agent=agent, tools=tool, verbose=True)

    response = agent_executor.invoke({"input": querys})
    print(response)
    st.write("🤖 回答: ", response['output'])

三、LangChain知识库系统UI设计

  1. 完成核心逻辑代码的编写后,下一步我们编写主界面逻辑。本部分使用streamlit库快速构建系统UI。主界面包含标题数据库管理 ,输入框(只有当数据库存在才能提问) ,侧边栏包含PDF上传器提交按钮(处理上传的PDF->分片->向量化->存储) 等。这部分内容不是我们的重点就不加赘述,streamlit的语法类似我们编写markdown文档,大家可以快速阅读了解。
python 复制代码
def main():
    st.set_page_config("🤖 LangChain知识库系统开发")
    st.header("🤖 LangChain知识库系统开发")

    # 显示数据库状态
    col1, col2 = st.columns([3, 1])

    with col1:
        if check_database_exists():
            pass
        else:
            st.warning("⚠️ 请先上传并处理PDF文件")

    with col2:
        if st.button("🗑️ 清除数据库"):
            try:
                import shutil
                if os.path.exists("faiss_db"):
                    shutil.rmtree("faiss_db")
                st.success("数据库已清除")
                st.rerun()
            except Exception as e:
                st.error(f"清除失败: {e}")

    # 用户问题输入
    user_question = st.text_input("💬 请输入问题",
                                  placeholder="例如:这个文档的主要内容是什么?",
                                  disabled=not check_database_exists())

    if user_question:
        if check_database_exists():
            with st.spinner("🤔 AI正在分析文档..."):
                user_input(user_question)
        else:
            st.error("❌ 请先上传并处理PDF文件!")

    # 侧边栏
    with st.sidebar:
        st.title("📁 文档管理")

        # 显示当前状态
        if check_database_exists():
            st.success("✅ 数据库状态:已就绪")
        else:
            st.info("📝 状态:等待上传PDF")

        st.markdown("---")

        # 文件上传
        pdf_doc = st.file_uploader(
            "📎 上传PDF文件",
            accept_multiple_files=True,
            type=['pdf'],
            help="支持上传多个PDF文件"
        )

        if pdf_doc:
            st.info(f"📄 已选择 {len(pdf_doc)} 个文件")
            for i, pdf in enumerate(pdf_doc, 1):
                st.write(f"{i}. {pdf.name}")

        # 处理按钮
        process_button = st.button(
            "🚀 提交并处理",
            disabled=not pdf_doc,
            use_container_width=True
        )

        if process_button:
            if pdf_doc:
                with st.spinner("📊 正在处理PDF文件..."):
                    try:
                        # 读取PDF内容
                        raw_text = pdf_read(pdf_doc)

                        if not raw_text.strip():
                            st.error("❌ 无法从PDF中提取文本,请检查文件是否有效")
                            return

                        # 分割文本
                        text_chunks = get_chunks(raw_text)
                        st.info(f"📝 文本已分割为 {len(text_chunks)} 个片段")

                        # 创建向量数据库
                        vector_store(text_chunks)

                        st.success("✅ PDF处理完成!现在可以开始提问了")
                        st.balloons()
                        st.rerun()

                    except Exception as e:
                        st.error(f"❌ 处理PDF时出错: {str(e)}")
            else:
                st.warning("⚠️ 请先选择PDF文件")

        # 使用说明
        with st.expander("💡 使用说明"):
            st.markdown("""
                **步骤:**
                1. 📎 上传一个或多个PDF文件
                2. 🚀 点击"Submit & Process"处理文档
                3. 💬 在主页面输入您的问题
                4. 🤖 AI将基于PDF内容回答问题
    
                **提示:**
                - 支持多个PDF文件同时上传
                - 处理大文件可能需要一些时间
                - 可以随时清除数据库重新开始
                """)
if __name__ == "__main__":
    main()
  1. 在命令行激活langchainenv环境,执行streamlit run langchain搭建pdf解析rag系统.py运行脚本,脚本运行成功会自动在8501开启服务,用户可打开浏览器访问。

我们这边上传了一份名为DeepSeek高性能部署实战的pdf文档并点击提交并处理,系统提示我们文档处理完成被切分为37个切片。

输入问题:"请问DeepSeek-R1部署有哪些方案", 输入问题后,因为Agent构建时参数verbose=True我们可以看到后台日志会输出对文档的检索结果,最后将检索结果作为上下文给出答案:

核对系统给出的回答和我们的内容文档,确定一致,一个完整的RAG系统就构建完成了!大家可以在自己本地运行并上传多份文档进行实测~

完整的项目代码大家可关注笔者同名微信公众号: 大模型真好玩 , 并私信: LangChain智能体开发获得。

四、总结

本期分享我们通过Streamlit前端界面,结合LangChain框架retriever工具与DashScope向量模型服务、DeepSeek大模型服务,从0到1实现了轻量化的RAG知识库系统,支持上传多个PDF文档,系统将自动完成文本提取、分块、向量化,并构建基于 FAISS 的检索数据库。用户随后可以在页面中输入任意问题,系统会调用大语言模型(如 DeepSeek-Chat)对 PDF 内容进行语义理解和回答生成。LangChain应用开发的热门方式接入MCP, 知识库系统我们已经分享完成,下一期通过LangChian AI数据分析助手的综合实战进一步巩固我们所学内容,随后我们就即将步入LangGraoh分享的篇章啦!

本系列分享预计会有20节左右的规模,保证大家看完一定能够掌握LangChain&LangGraph的开发能力,大家感兴趣可关注笔者掘金账号和专栏,更可关注笔者的同名微信公众号:大模型真好玩 , 本系列分享的全部代码均可在微信公众号私信笔者: LangChain智能体开发 免费获得。

相关推荐
大志说编程几秒前
LangChain框架入门18: 十分钟带你搞定LLM工具调用
python·langchain·ai编程
听风.8255 分钟前
机器学习6
人工智能·机器学习·概率论
钢铁男儿13 分钟前
使用 TensorBoardX 实现 PyTorch 神经网络可视化:从入门到进阶
人工智能·pytorch·神经网络
苍何17 分钟前
DeepSeek V3.1正式发布,专为下代国产芯设计
人工智能
重启的码农19 分钟前
llama.cpp 分布式推理介绍(5) RPC 通信协议
c++·人工智能·神经网络
Gloria_niki21 分钟前
机器学习之数据预处理学习总结
人工智能·学习·机器学习·数据分析
听风.82521 分钟前
机器学习2
人工智能·机器学习
重启的码农22 分钟前
llama.cpp 分布式推理介绍(6) 张量序列化 (rpc_tensor)
c++·人工智能·神经网络
G等你下课22 分钟前
基于MCP构建一个智能助手
前端·node.js·mcp
Baihai_IDP41 分钟前
RAG 文档解析工具选型指南
人工智能·llm