知识库 Copilot — 权限感知 RAG 智能问答系统
基于混合检索(BM25 + 向量 + RRF)的企业知识库 RAG 系统。支持 PDF / Word / Markdown / HTML 多格式文档,具备 JWT 认证、多租户权限控制、SSE 流式输出、审计日志等企业级功能。
# 1. 配置环境变量
cp .env.example .env
# 编辑 .env,填入 DASHSCOPE_API_KEY 和 JWT_SECRET_KEY
# 2. 一键启动
docker compose up -d
# 3. 访问
# http://localhost — 前端应用
# http://localhost:8001 — 上传管理后台
# http://localhost:8000/docs — API 文档
浏览器 :80
│
▼
nginx (前端静态文件 + 反向代理)
│
├── /api/* ──→ backend-qa :8000 问答 / 认证 / 对话 / 审计
└── /upload/* → backend-upload :8001 文档上传 / 权限管理
│
┌────┴────┐
│ │
ChromaDB SQLite
(向量存储) (用户+对话+审计)
层
技术
后端框架
FastAPI + Pydantic
向量数据库
ChromaDB (HNSW 索引)
LLM
阿里云百炼 qwen-plus (OpenAI 兼容接口)
Embedding
text-embedding-v4
混合检索
BM25 自研 (中文 bigram 分词) + 向量 + RRF 融合
认证
JWT (HS256) + bcrypt
前端
React 18 + Vite 6
部署
Docker + docker-compose + nginx
日志
structlog → JSON → stdout
用户名
密码
角色
部门
说明
admin
admin123
executive
管理员
管理员,全部可见
gaoguan
gg123
executive
高管
查看所有部门文档
hr_zhang
hr123
hr
HR
只看 HR 部门
rd_li
rd123
rd
研发
只看研发部门
caiwu_wang
cw123
finance
财务
只看财务部门
pr_zhao
pr123
pr
公关
只看公关部门
用户提问 ──→ text-embedding-v4 ──→ ChromaDB HNSN 向量相似度检索 ──┐
│ │
└──────→ BM25 关键词检索 (中文 bigram + unigram 分词) ────────→ RRF 融合 → Top-K → LLM
BM25 自研 :纯 Python,零外部依赖,CJK bigram 分词
RRF (Reciprocal Rank Fusion) :排名融合,同一条 chunk 在两路命中则得分累加
三层过滤确保 LLM 看不到越权内容:
用户请求 → JWT 解析 → UserContext
→ ChromaDB where-filter (向量检索前预过滤)
→ BM25 后置 Python 权限检查
→ Safe Prompt (LLM 提示词禁止泄露上下文外信息)
维度
规则
租户隔离
tenant_id 必须匹配
密级门控
用户密级 ≥ 文档密级 (1-4)
高管
当前租户下全部可见
部门
本部门 + public 文档
可见性
public / department / private / role / group
项目
说明
Docker 容器化
docker compose up -d 一键启动
结构化日志
structlog JSON 格式,docker logs 查看
LLM 容错
超时/连接/限流自动重试,异常分类 (502/503)
全局异常处理
FastAPI exception_handler 统一兜底
API 流式输出
SSE (Server-Sent Events),禁用代理缓冲
多服务架构
问答(8000) + 上传(8001) 分离,nginx 反向代理
安全加固
bcrypt 密码哈希、JWT 密钥无默认值、CORS 白名单
cd backend
pip install fastapi uvicorn chromadb openai pydantic pydantic-settings PyJWT bcrypt python-dotenv langchain-text-splitters structlog httpx
# 启动问答服务
uvicorn main:app --reload --port 8000
# 启动上传服务(新终端)
uvicorn upload_service:app --reload --port 8001
# 启动前端(新终端)
cd frontend && npm install && npm run dev
curl -X POST http://localhost:8000/auth/login \
-H " Content-Type: application/json" \
-d ' {"username":"admin","password":"admin123"}'
curl -X POST http://localhost:8000/chat/secure \
-H " Content-Type: application/json" \
-H " Authorization: Bearer <token>" \
-d ' {"question":"年假怎么申请?","conversation_id":null}'
curl -X POST http://localhost:8000/chat/secure/stream \
-H " Content-Type: application/json" \
-H " Authorization: Bearer <token>" \
-d ' {"question":"详细说明"}'
cd backend
python -m pytest tests/ -v
# 89 tests, < 12 秒
backend/
├── main.py # 问答服务入口 (:8000)
├── upload_service.py # 上传服务入口 (:8001)
├── config.py # 统一配置 + 日志初始化
├── rag_chain.py # 公开 RAG 链路
├── rag_chain_permission.py # 权限感知 RAG 链路
├── hybrid_retriever.py # BM25 + RRF 混合检索
├── vector_store.py # ChromaDB 向量存储
├── vector_store_permission.py # 权限感知向量存储
├── conversation_store.py # 对话持久化 (SQLite)
├── splitter.py # 文本切块
├── document_loader.py # 多格式文档解析
├── auth/
│ ├── jwt_handler.py # JWT 签发/校验
│ └── middleware.py # 认证依赖注入
├── permissions/
│ └── filter_builder.py # ChromaDB 权限过滤
├── audit/
│ └── audit_logger.py # 审计日志
├── services/
│ └── user_service.py # 用户管理 + bcrypt
├── models/
│ ├── user.py # 用户/权限模型
│ ├── document.py # 文档/chunk 元数据
│ └── audit.py # 审计日志模型
└── tests/ # 89 个测试用例
frontend/
├── src/
│ ├── App.jsx # 根组件
│ ├── api.js # API 层
│ └── components/
│ ├── Login.jsx # 登录
│ ├── ChatBox.jsx # 聊天
│ └── ConversationSidebar.jsx # 对话列表
Dockerfile.backend # 后端镜像
Dockerfile.frontend # 前端多阶段构建
docker-compose.yml # 服务编排
nginx.conf # 反向代理