Langchain-Chatchat 知识库问答流程深度剖析

从文档上传到模型应答,一步步解构知识增强问答系统的底层逻辑。

一、什么是知识库问答(RAG)?

传统大模型在回答专业问题时,常会编造(hallucination) ,因为它的"知识"来自训练语料,而非实时信息。为此,Langchain-Chatchat 构建了知识增强问答系统(RAG) ,通过"文档检索 + 模型生成"组合提升回答的准确性。

RAG 的基本流程是:

graph LR 用户问题 --> 检索相关文档 --> 搭建提示词 --> 输入语言模型 --> 输出更准确回答

二、知识库问答的整体流程图(逻辑视角)

graph TD 文档上传 --> B[文本预处理: 分段/清洗] --> C[向量化: Embedding] --> D[向量索引构建: FAISS等] --> E[知识库建立完成]; E --- 用户提出问题 --> F[查询向量检索: Retriever] --> G[构造提示词: Prompt] --> H[模型回答: LLM] --> 最终输出回答;

本地安装部署 Langchain-Chatchat

  1. 安装 Langchain-Chatchat
bash 复制代码
pip install langchain-chatchat -U

模型部署框架 Xinference 接入 Langchain-Chatchat 需要额外安装对应的 Python 依赖库,因此如需搭配 Xinference 框架使用时如下安装方式:

bash 复制代码
pip install "langchain-chatchat[xinference]" -U
  1. 模型推理框架并加载模型

启动 Langchain-Chatchat 项目前,首先进行模型推理框架的运行,并加载所需使用的模型。本文中 Embedding 模型使用 bge-large-zh-v1.5 通过 Xinference 本地运行,LLM 使用 deepseek-chat 在线API。

  1. 初始化项目配置与数据目录

    • 设置 Chatchat 存储配置文件和数据文件的根目录(可选): export CHATCHAT_ROOT=xxx
    • 执行初始化:chatchat init
    • 修改配置文件
      • 配置模型(model_settings.yaml)
      • 配置知识库路径(basic_settings.yaml)(可选)
      • 配置知识库(kb_settings.yaml)(可选)
  1. 初始化知识库

进行知识库初始化前,请确保已经启动模型推理框架及对应 embedding 模型,且已按照上述步骤3完成模型接入配置。

复制代码
chatchat kb -r
  1. 启动项目
css 复制代码
chatchat start -a

三、每个阶段的实现细节

1. 文档上传与解析

文档上传

  • 模块位置:server\knowledge_base\kb_doc_api.py
  • API路由:knowledge_base/upload_docs
  • 函数名称:upload_docs
python 复制代码
def upload_docs(
        files: List[UploadFile] = File(..., description="上传文件,支持多文件"),
        knowledge_base_name: str = Form(
            ..., description="知识库名称", examples=["samples"]
        ),
        override: bool = Form(False, description="覆盖已有文件"),
        to_vector_store: bool = Form(True, description="上传文件后是否进行向量化"),
        chunk_size: int = Form(Settings.kb_settings.CHUNK_SIZE, description="知识库中单段文本最大长度"),
        chunk_overlap: int = Form(Settings.kb_settings.OVERLAP_SIZE, description="知识库中相邻文本重合长度"),
        zh_title_enhance: bool = Form(Settings.kb_settings.ZH_TITLE_ENHANCE, description="是否开启中文标题加强"),
        docs: str = Form("", description="自定义的docs,需要转为json字符串"),
        not_refresh_vs_cache: bool = Form(False, description="暂不保存向量库(用于FAISS)"),
) -> BaseResponse:
    """
    API接口:上传文件,并/或向量化
    """

文档解析成文本

  • 模块位置:server\file_rag\document_loaders
python 复制代码
class KnowledgeFile:
    def __init__(
        self,
        filename: str,
        knowledge_base_name: str,
        loader_kwargs: Dict = {},
    ):
        """
        对应知识库目录中的文件,必须是磁盘上存在的才能进行向量化等操作。
        """
        ...
        self.document_loader_name = get_LoaderClass(self.ext)
        ...

    def file2docs(self, refresh: bool = False):
        if self.docs is None or refresh:
            ...
            loader = get_loader(
                loader_name=self.document_loader_name,
                file_path=self.filepath,
                loader_kwargs=self.loader_kwargs,
            )
            ...

2. 文本切分与清洗

  • 使用 TextSplitter(如 ChineseRecursiveTextSplitter
  • 模块位置 server\file_rag\text_splitter
  • 参数 chunk_size
    • 控制单个文本块的最大长度
    • 太大:容易超过模型上下文限制
    • 太小:语义不完整,影响 embedding 效果
  • 参数 chunk_overlap
    • 保证上下文的连续性
    • 防止信息"切断"导致语义断裂
    • 尤其在问答中保持跨段引用的可能性(如引用上一句)
python 复制代码
class KnowledgeFile:
    ...
    def docs2texts(
            self,
            docs: List[Document] = None,
            zh_title_enhance: bool = Settings.kb_settings.ZH_TITLE_ENHANCE,
            refresh: bool = False,
            chunk_size: int = Settings.kb_settings.CHUNK_SIZE,
            chunk_overlap: int = Settings.kb_settings.OVERLAP_SIZE,
            text_splitter: TextSplitter = None,
    ):
        docs = docs or self.file2docs(refresh=refresh)
        if not docs:
            return []
        if self.ext not in [".csv"]:
            if text_splitter is None:
                text_splitter = make_text_splitter(
                    splitter_name=self.text_splitter_name,
                    chunk_size=chunk_size,
                    chunk_overlap=chunk_overlap,
                )

3. 文本向量化(Embedding)

  • 使用 BGE、text2vec、GTE、MiniLM 等中文模型,本文使用 xinference 运行的 bge-large-zh-v1.5 模型。
    • BGE 系列模型(Bidirectional Generative Embedding)是北京智源人工智能研究院(BAAI) 发布的高质量中文文本向量化(embedding)模型。
  • 核心代码是函数 get_Embeddings 和 类 LocalAIEmbeddings。使用了 openai.Embedding 的进行向量化,因为 xinference 也是兼容 openai 接口格式的。

4. 向量索引构建(Vector Store)

  • 默认使用 FAISS
  • 模块位置:server\knowledge_base\kb_servicelangchain_community\vectorstores\faiss.py

5. 用户提问 → 检索相关片段

6. Prompt 构造:拼接文档 + 问题

  • API位置:server\api_server\chat_routes.py

  • Prompt 构造

7. 模型调用(LLM)

  • 支持本地模型(ChatGLM、Qwen、GLM4)
  • 支持远程模型(OpenAI、讯飞星火等)

8. 输出回答

  • 支持显示参考文档片段
  • 多轮对话(Memory)
  • Agent 工具调用(可选)

四、项目中各模块之间的协作结构图

graph TD A[前端UI] -- 提问 --> B[FastAPI 接口]; B --- B1[向量库查询]; B --- B2[文档拼接]; B --> C[大模型推理]; C1[模型适配器 OpenAI/GLM/Qwen] --- C; C --> D[结果生成 + 回传 UI];

五、知识库问答的优势与挑战

优势 挑战
🔍 提升回答准确性 📐 文本切分粒度需调优
💾 实时更新知识 ⚡ 向量库查询性能
🎯 定向回答专业内容 🤖 模型对上下文利用能力有限
🧱 架构清晰,可扩展 🔗 多文档融合效果需评估

✅ 总结

知识库问答(RAG)是 Langchain-Chatchat 最核心的能力之一,它以模块化设计方式将文档解析、向量化、检索与提示词拼接串联起来,实现了一个"接入你自己知识"的智能问答系统。理解它的每一环节,可以帮助你掌握如何构建可控、可追溯、可自定义的大模型问答系统。

相关推荐
JadePeng16 分钟前
Coze Studio:字节跳动 Coze 的开源版本来了!第一时间深度解析
agent
三桥君16 小时前
如何解决后端Agent和前端UI之间的交互问题?——解析AG-UI协议的神奇作用
人工智能·agent
聚客AI19 小时前
📊构建企业AI Agent中台:基于MCP的统一工具调用架构设计
人工智能·agent·mcp
老周聊大模型20 小时前
大模型如何突破“认知茧房”?RAG+MCP构建外部脑接口
langchain·agent·mcp
王吉伟频道21 小时前
收藏!国内120+AI Agent开发/构建平台大盘点(上):互联网、云计算、AI、传统软件厂商推出的智能体平台
agent·企业级·ai agent·智能体·agentic ai·智能体开发平台
ATM00621 小时前
MetaGPT源码剖析(三):多智能体系统的 “智能角色“ 核心实现——Role类
人工智能·大模型·agent·源码剖析·metagpt
AI大模型1 天前
超赞!本地程序调用云知识库实现RAG功能
程序员·llm·agent
夏宇AI实战笔记1 天前
零基础3分钟搭建Coze工作流,新人必看保姆级教程
agent
东哥说AI1 天前
守一晚上直播没抢到Trae SOLO邀请码,我反手用Builder模式一键开发出老师追着要的诗词抽背神器!
agent·ai编程·trae
繁依Fanyi1 天前
蚂蚁百宝箱|快速打造一款风水命理智能体
agent