langChain实战:从零构建企业知识链问答系统

7 阅读6分钟

在企业场景里,「问答」通常不是一个单点功能,而是知识管理、合规协作、交付效率的底层能力。
我在这个项目里尝试把一个看似教学化的 RAG 示例,按企业可落地链路重构为一套可运行、可扩展、可部署的知识问答系统:

GitHub: github.com/suguangsong…

本文完整记录了这个从 0 到 1 的实现过程,并给出可直接复用的工程化设计思路。

一、为什么做这个项目

很多团队会用“内部文档 QA”做 PoC,但常见问题有四类:

  1. 只做了单文件 demo,无法支持多文档和稳定更新。
  2. 检索效果不稳定,语义 TopK 返回结果“看起来相关”,却经常漂移。
  3. 前后端耦合强,接口化程度低。
  4. 部署方式依赖本机环境,生产迁移成本高。

ChainKnowledge 的目标是把这 4 个问题在一个仓库里一并解决:

  • 覆盖 LangChain 核心能力(加载、切片、向量化、检索增强生成、记忆)
  • 支持 PDF/DOCX/CSV/HTML 等多格式文档上传与增量入库
  • 增加检索重排(Reranker)提升答案相关性
  • 增加 FastAPI API 层,支持前后端分离
  • 提供 Docker + docker-compose + Nginx 反向代理部署方案

二、项目架构(分层设计)

项目代码采用分层目录组织,核心目标是“每层只做一类事”:

src/chainknowledge/
  core/       # 配置、LLM、加载、切片、向量库、记忆、检索重排
  services/   # 文档入库、QA 组装
  ui/         # Streamlit 演示端
  api/        # FastAPI 接口层

配套还有:

  • frontend/index.html:纯前端静态页,可直接联调 API
  • Dockerfiledocker-compose.ymldocker/nginx.conf:部署层
  • requirements.txt.env.exampleREADME.md:运行与交付层

三、端到端链路设计

1. 文档入库链路

文档上传路径分为三段:

  • loader:按后缀选择 Loader(PDF、DOCX、TXT、CSV、HTML)
  • splitterRecursiveCharacterTextSplitter 分片(可配置 chunk 大小与重叠)
  • vector_storeChroma 持久化向量库,支持复用与可视化计数

核心收益是:

  • 对不同格式采用统一文档对象抽象
  • 语义切片粒度可控
  • 可持续增量入库

2. 问答链路(RAG)

qa_service 里,问题经过以下流程:

  1. 使用 vector_store.similarity_search_with_score 拉取候选文档
  2. 可选进入重排器 SimpleHybridReranker
  3. 按 top-k 组装上下文
  4. 与历史对话(ConversationBufferWindowMemory)拼接 prompt
  5. 调用 LLM 生成可追溯答案

回答返回时附带来源片段(source/page/snippet),满足“可解释问答”的企业要求。

3. 会话记忆

采用 ConversationBufferWindowMemory 维持窗口对话历史,避免一次性注入全部历史导致上下文污染。
memory_window 支持在前端动态控制,适合不同业务场景中平衡“上下文长度”和“成本开销”。

四、检索重排:从“语义 TopK”走向“可控排序”

单纯依赖向量相似度有时会“抓大不抓准”。
本项目通过 SimpleHybridReranker 引入关键字重排,显式加入 lexical signal,改进企业术语检索体验。

重排规则:

  • vector_score:将原始相似度分数转为越大越优的归一值
  • lexical_score:查询词与文档片段的 Jaccard 关键词重叠
  • final_score = alpha * vector_score + (1 - alpha) * lexical_score

配置参数:

  • RERANK_CANDIDATE_MULTIPLIER:扩大候选集(先放宽召回)
  • RERANK_TOP_K:重排后保留多少片段
  • RERANK_ALPHA:向量与关键词权重平衡(0~1)
  • RERANK_ENABLED:开关,方便线上快速 A/B 测试

同时 /api/chat 在响应中返回 candidate_kretrieved_countreturned_count,便于观测重排前后差异。

五、API 化设计(FastAPI)

相比传统 demo 的“页面触发式问答”,API 化后可以对接更广泛的客户端。
src/chainknowledge/api/main.py 提供以下核心能力:

  • GET /api/health:服务健康
  • GET /api/status:向量库状态与就绪信息
  • POST /api/documents:多文件上传入库
  • POST /api/chat:多轮问答
  • DELETE /api/sessions/{session_id}:清空会话记忆
  • POST /api/knowledge/clear:清空知识库

API 请求模型支持可选覆盖参数(每次调用可动态调参),包括:

  • provider / model / api_key / api_base
  • top_k / reranker_candidate_multiplier / reranker_top_k
  • reranker_alpha / reranker_enabled
  • memory_window

这样在 A/B、线上调优或排障时,不需要重启服务即可验证参数效果。

六、前后端分离实现

项目额外提供一个极简前端(frontend/index.html):

  • 支持文档上传与清空知识库
  • 支持会话提问与清会话
  • 实时展示服务状态
  • 展示来源片段和重排统计,便于人工确认检索质量

它演示了“API-first”之后最小可交付前端形态,工程上足够轻量,便于后续替换成企业内部界面。

七、部署方案:Docker + Nginx

docker-compose.yml 里定义了两类服务:

  • chainknowledge-api:构建并运行 FastAPI 后端(uvicorn
  • chainknowledge-nginx:托管静态前端并反代 /api

并通过命名卷持久化关键目录:

  • chroma_data:向量库
  • upload_data:原始上传文件

启动后可直接访问:

  • 前端:http://127.0.0.1:8080
  • 健康接口:http://127.0.0.1:8080/api/health

这意味着你的知识库在容器重启后仍可保留状态,降低运维风险。

八、为什么能值得使用

这个项目不是“堆模型组件”,而是在工程中明确落地了以下点:

  1. 配置驱动:通过 .env 控制 provider/model/参数,便于环境隔离
  2. 链路解耦:Loader、Splitter、Vector Store、QA、API 分离,便于单元替换
  3. 可复用接口:同一套核心服务可被 Streamlit 与 API 同时复用
  4. 可观测性:返回检索统计字段,便于排障与调优
  5. 部署友好:Docker + compose + 反代,能直接接入 CI/CD 与容器编排体系

企业在此基础上很容易继续演进:

  • 改为多租户 collection 切分
  • 接入鉴权与操作审计
  • 替换重排器为 CrossEncoder / rerank 模型
  • 接入企业内部向量库(Milvus、pgvector、Pinecone 等)

九、实用的调用示例

健康与状态检查:

curl http://127.0.0.1:8000/api/health
curl http://127.0.0.1:8000/api/status

查询示例(可直接运行):

curl -X POST http://127.0.0.1:8000/api/chat \
  -H "Content-Type: application/json" \
  -d '{
    "session_id":"demo",
    "question":"请说明公司请假流程",
    "provider":"openai",
    "top_k":4,
    "reranker_candidate_multiplier":3,
    "reranker_top_k":4,
    "reranker_alpha":0.7,
    "reranker_enabled":true,
    "memory_window":6
  }'

重点查看返回里的 candidate_k / retrieved_count / returned_count,能快速评估检索链路的召回质量。

十、总结

ChainKnowledge 的价值不在“我写了一个 ChatGPT 界面”,
而在于把一个教学型 RAG 系统,转化为一套能在企业中长期运行的服务化组件:

  • 功能闭环完整
  • 配置与参数可控
  • 接口清晰可复用
  • 部署路径可直接执行
  • 结果可追溯可复盘

如果你也在做企业知识库问答,这个仓库可作为你从 PoC 到生产的起点模板。