图片来源网络,侵权联系删。
在这里插入图片描述

LightRAG系列文章
LightRAG系列1:为什么 Web 开发者需要关注 RAG?

LightRAG系列2:什么是 LightRAG?它和 LangChain 有什么区别?

LightRAG系列3:LightRAG 环境准备与快速启动

LightRAG 系列 4:核心技术解析——检索模块详解(上)

LightRAG 系列 5:核心技术解析——HNSW 索引机制与 Web 应用中的毫秒级检索

LightRAG 系列 6:核心技术解析——检索策略:Top-K + 重排序(Re-ranking)提升精度

LightRAG 系列 7:核心技术解析——整合检索与生成模块,完整走通 LightRAG 的端到端工作流

LightRAG 系列8:最佳实践与避坑指南

引言:让沉睡的知识库“开口说话”

企业内部往往堆积了大量 PDF 手册、FAQ、制度文档,但员工查找信息仍需反复询问 HR 或 IT。知识若不能快速流转,便毫无价值。本章将指导您用 LightRAG + FastAPI 构建一个私有化、低延迟、可溯源的内部问答机器人,全程无需联网,且完全掌控数据流向。

💡 架构视角

这不仅是一个“功能 Demo”,更是一个最小可行智能服务(MVIS)——它涵盖了数据注入、索引构建、服务暴露三大核心环节,为企业级 RAG 系统奠定基础。

整体架构概览

公司 FAQ PDF
文本解析
LightRAG 知识注入
HNSW 向量索引 + 知识图谱
FastAPI 服务
前端 / Slack / 企业微信
  • 数据流:PDF → 文本 → 向量+图 → 可查询知识库
  • 部署模式:单机本地运行(后续可容器化)
  • 安全边界:数据全链路内网,无外泄风险

在这里插入图片描述

步骤 1:上传公司 FAQ PDF 并解析为文本

技术选型原则

  • 轻量:避免重型 OCR(除非扫描件)
  • 保留结构:维持段落、标题层级
  • 中文友好

推荐工具:pdfplumber(优于 PyPDF2)

pip install pdfplumber

解析脚本(parse_pdf.py

import pdfplumber
import os

def extract_text_from_pdf(pdf_path: str) -> str:
    text = ""
    with pdfplumber.open(pdf_path) as pdf:
        for page in pdf.pages:
            # 保留换行与结构
            page_text = page.extract_text(layout=True, keep_blank_chars=True)
            if page_text:
                text += page_text + "\n\n"
    return text

# 批量处理
for filename in os.listdir("./faqs"):
    if filename.endswith(".pdf"):
        raw_text = extract_text_from_pdf(f"./faqs/{filename}")
        with open(f"./texts/{filename}.txt", "w", encoding="utf-8") as f:
            f.write(raw_text)

最佳实践

  • 若 PDF 为扫描件,先用 OCRmyPDF 转为可搜索版
  • 长文档建议按章节拆分,避免单 chunk 过大

在这里插入图片描述

步骤 2:使用 LightRAG 构建本地向量库

关键决策(架构视角)

决策项 推荐选择 理由
Embedding 模型 BAAI/bge-small-zh-v1.5 中文优化、开源、本地运行
是否启用图 ✅ 是 支持“多跳问题”(如“谁负责报销?”)
是否启用重排序 ✅ 是 提升首条准确率

初始化与注入(build_kb.py

from lightrag import LightRAG
import glob

# 初始化(首次运行会下载模型)
rag = LightRAG(
    working_dir="./internal_kb",
    embedding_model="BAAI/bge-small-zh-v1.5",
    llm_model_func=None  # 使用默认本地 LLM
)

# 批量注入文本
for txt_file in glob.glob("./texts/*.txt"):
    with open(txt_file, "r", encoding="utf-8") as f:
        content = f.read()
    rag.insert(content, meta={"source": os.path.basename(txt_file)})
    print(f"✅ 已注入 {txt_file}")

⚠️ 注意

  • 首次运行需 5–10 分钟(模型下载 + 索引构建)
  • working_dir 包含:向量索引、图数据、原始文本副本

在这里插入图片描述

步骤 3:通过 FastAPI 暴露 /ask 接口

设计目标

  • 支持 Local/Global 自动路由
  • 返回答案 + 引用来源
  • 兼容前端、Slack Bot、企微机器人

服务代码(api.py

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from lightrag import LightRAG, QueryParam
import asyncio
import logging

# 初始化(全局单例)
rag = LightRAG(working_dir="./internal_kb")

app = FastAPI(title="Internal KB Bot")

class AskRequest(BaseModel):
    query: str
    mode: str = "auto"  # "local", "global", or "auto"

def route_mode(query: str) -> str:
    if any(kw in query for kw in ["怎么", "是否", "多少", "步骤"]):
        return "local"
    return "global"

@app.post("/ask")
async def ask(req: AskRequest):
    try:
        mode = route_mode(req.query) if req.mode == "auto" else req.mode
        
        loop = asyncio.get_event_loop()
        result = await loop.run_in_executor(
            None,
            lambda: rag.query(
                req.query,
                param=QueryParam(
                    mode=mode,
                    top_k=3,
                    rerank=True  # 启用重排序提升精度
                )
            )
        )
        
        return {
            "answer": result["response"],
            "sources": [
                {"content": ref["content"], "source": ref.get("source", "unknown")}
                for ref in result.get("references", [])
            ],
            "mode_used": mode
        }
    except Exception as e:
        logging.error(f"Query failed: {e}")
        raise HTTPException(status_code=500, detail="Internal error")

启动服务

uvicorn api:app --host 0.0.0.0 --port 8000 --reload

调用示例

curl -X POST http://localhost:8000/ask \
  -H "Content-Type: application/json" \
  -d '{"query": "如何申请年假?"}'

响应:

{
  "answer": "员工需在 HR 系统提交年假申请,直属领导审批后生效。",
  "sources": [
    {
      "content": "年假申请流程:登录 HR 系统 → 填写日期 → 提交审批",
      "source": "hr_policy_2025.txt"
    }
  ],
  "mode_used": "local"
}

进阶建议:迈向生产就绪

能力 实现方式
自动同步 Confluence 定时任务调用 API → 生成文本 → rag.insert()
前端界面 Streamlit/Vue 快速搭建聊天 UI
权限控制 FastAPI 集成企业 LDAP/OAuth2
可观测性 记录 query 日志,分析“未命中问题”
容器化部署 Dockerfile,挂载 ./internal_kb 为持久卷

在这里插入图片描述

结语:让知识流动起来

这个项目虽小,却完整覆盖了数据→知识→服务的闭环。更重要的是,它完全在您的掌控之下——无数据泄露风险,无 API 费用,无黑盒模型。

下一步,您可以:

  1. ./internal_kb 目录纳入 Git(仅元数据,不含敏感内容)
  2. 添加每日增量更新脚本
  3. 接入企业通讯工具(如飞书机器人)

真正的智能,始于让已有知识变得可问、可信、可用。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐