13 KiB
13 KiB
大模型智能问答客服系统系统设计文档
日期: 2026-03-31
状态: 已确认
技术栈: Python / FastAPI / Vue3 / DeepSeek / PostgreSQL / Redis
一、项目背景与目标
将企业内部的报销制度、软件操作手册、财务/科研流程、常见问题汇总等文档接入大模型,构建一套智能问答客服系统。用户可以用自然语言提问,系统给出答案并注明引用来源;支持上传截图辅助提问。
核心目标:
- 文档知识库化,降低重复人工咨询成本
- 答案可追溯,每条回答标注来源文档、章节、页码或段落
- 支持截图上传,辅助描述操作类问题
- 管理员可自助维护文档,无需开发介入
本期检索策略目标:
- 前期不引入向量数据库与 embedding
- 以“先选文档,再选章节,再定位段落”为主链路,优先保证准确率和可解释性
- 允许用大模型对候选文档和章节做重排,但不让大模型承担全库检索职责
二、用户角色
| 角色 | 权限 |
|---|---|
employee(员工/外部合作方) |
对话问答、查看本人历史会话 |
admin(管理员) |
文档上传/删除/管理、用户管理(创建/角色分配/禁用) |
三、整体架构
用户浏览器
├─ 员工:问答 + 截图上传
└─ 管理员:文档上传 / 文档管理 / 用户管理
│
▼
FastAPI 后端
├─ 认证模块
├─ 对话问答模块
├─ 文档管理模块
└─ 检索编排模块
│
├─ PostgreSQL
│ ├─ 用户/会话/消息
│ ├─ 文档元数据
│ ├─ 文档章节索引
│ └─ 文档段落索引
│
├─ Redis
│ ├─ 验证码 / 速率限制
│ └─ Celery Broker / Cache
│
├─ 本地文件系统
│ ├─ 原始文档
│ └─ 解析后的规范化文本
│
├─ DeepSeek Chat
│ ├─ 候选文档/章节重排
│ └─ 基于引用片段生成答案
│
└─ 阿里云 OCR
└─ 截图文字识别
四、核心模块设计
4.1 认证模块
- 账号名: 邮箱地址
- 注册管控: 关闭完全开放的自助注册;支持两种方式创建账号:
- 管理员后台手动创建(指定角色)
- 邮箱自助注册(仅限白名单域名,如
@company.com,可配置),默认角色employee
- 登录方式:
- 邮箱 + 密码
- 邮箱 + 验证码(6位数字,5分钟有效,存 Redis)
- 验证码防刷:
- 同一邮箱 60 秒内不可重复发送
- 同一 IP 每小时限制 10 次
- Token 机制:
- Access Token(JWT):有效期 2 小时
- Refresh Token:有效期 7 天,存 Redis,可主动吊销
- 管理员禁用账号时,将该账号现有 Token 加入 Redis 黑名单,立即失效
- 邮件服务: QQ 邮箱 SMTP(
smtp.qq.com:465,SSL,授权码鉴权)
4.2 文档管理模块
| 功能 | 说明 |
|---|---|
| 上传 | 支持 PDF、Word(.docx)、Excel(.xlsx),单文件限制 50MB;服务端验证 Magic Bytes + 扩展名双重校验 |
| 原始文件存储 | 原始文件保存到本地文件系统,按文档 ID / 版本号分目录存放 |
| 解析 | PDF 用 pdfplumber,Word 用 python-docx,Excel 按 Sheet 转为规范化文本或 Markdown 表格 |
| 结构化 | 解析后生成三级结构:document、section、chunk;章节标题、层级、页码范围、段落顺序均保留 |
| 规范化文本落盘 | 每份文档额外保存解析后的文本产物,便于调试、离线检查和兜底检索 |
| 索引入库 | 文档标题、文件名、标签、章节标题、段落正文、来源位置全部写入 PostgreSQL |
| 异步处理 | Celery + Redis;上传后后台解析、结构化、索引化,前端显示状态 |
| 状态机 | pending -> processing -> active / failed |
| 删除 | 先将文档标记 deleting,再删索引、删解析文本、删原始文件,任一步失败均可幂等重试 |
| 更新(版本切换) | 新版本先入库为 pending;索引就绪后原子切换为 active,旧版本转 superseded |
结构化原则:
- 文档级:文件名、别名、标签、摘要
- 章节级:目录项、一级/二级/三级标题、页码范围、Sheet 名称
- 段落级:正文、表格文本、所属章节、顺序号、来源位置
4.3 问答检索模块
本期不使用向量检索,主链路采用“规则召回 + 大模型重排 + 段落精定位”。
问答流程(SSE 流式输出):
用户输入(文本 + 可选截图)
-> OCR 识别截图文字(阿里云 OCR)
-> 合并为最终 Query 文本
-> Query 归一化(术语、别名、关键词、数字、表单名)
-> 文档候选召回(文件名 + 标签 + 文档摘要 + FTS)
-> 章节候选召回(目录项/章节标题/小节标题 + FTS)
-> 大模型重排候选文档与章节
-> 在最终候选章节内做段落精定位
-> 取命中段落及相邻段扩展上下文
-> 组装 Prompt(系统提示 + 引用片段 + 历史 5 轮 + 用户问题)
-> 调用 DeepSeek Chat API(SSE 流式输出)
-> 返回答案 + 引用来源(文档名 + 章节标题 + 页码/段落号)
设计原则:
- 大模型只负责候选重排,不负责全库检索
- 先缩小范围,再精确定位,优先提升召回准确率
- 只在少量明确候选章节中做正文定位,避免把无关文档片段带进 Prompt
- 若未命中足够可信的文档/章节,明确回答“未在当前知识库中找到依据”
查询归一化:
- 术语同义词映射,如“报销/报账”“出差/差旅”“附件/上传材料”
- 抽取数字、金额、日期、制度名、表单名
- 去除无意义停用词,保留关键短语
候选控制:
- 文档候选最多 5 个
- 章节候选最多 8 到 12 个
- 大模型重排后仅保留 1 到 3 个章节
- 最终送入生成模型的正文片段控制在 6 到 12 段
Prompt 设计原则:
- 模型只能基于提供的引用片段回答
- 依据不足时必须明确说不知道或未找到
- 在答案末尾输出引用片段编号,系统映射成文档名、章节、页码或段落号
- 多轮对话只携带最近 5 轮历史
后期扩展点:
- 检索层抽象为
RetrieverInterface - 重排层抽象为
RerankerInterface - 后期可平滑增加 BM25 增强、RRF 融合、向量检索、Reranker 模型
4.4 数据模型(核心表)
users
id, email, hashed_password, role, is_active, created_at
refresh_tokens
id, user_id, token_hash, expires_at, revoked
token_blacklist
jti, expires_at
documents
id, name, file_path, normalized_text_path, status, version_num,
supersedes_id, created_by, created_at, summary, tags_json
document_aliases
id, document_id, alias
document_sections
id, document_id, parent_section_id, title, level,
page_start, page_end, section_order, title_tokens
doc_chunks
id, document_id, section_id, chunk_index, text,
source_location, page_no, paragraph_no, tsv
conversations
id, user_id, title, created_at
messages
id, conversation_id, role, content, sources_json, created_at
说明:
documents.summary用于文档候选粗筛和大模型重排输入document_sections是本期准确率的关键索引层doc_chunks.tsv用于 PostgreSQL 全文检索source_location统一映射为“页码 / 段落号 / Sheet 名称 / 章节路径”
4.5 前端页面
| 页面 | 访问角色 | 核心功能 |
|---|---|---|
| 登录/注册页 | 所有人 | 双模式登录、邮箱注册(白名单域名)、验证码发送 |
| 对话页 | employee / admin | 左侧会话列表、右侧 SSE 流式对话、截图上传、引用来源展示 |
| 文档管理页 | admin | 文档列表、上传、删除、解析状态查看、版本切换状态 |
| 用户管理页 | admin | 用户列表、创建账号、角色分配、禁用(即时生效) |
五、技术选型
| 层次 | 选型 | 说明 |
|---|---|---|
| 前端 | Vue3 + Element Plus | 成熟后台组件生态 |
| 后端 | FastAPI + Python 3.11 | 异步支持较好,适合 AI 服务编排 |
| 关系数据库 | PostgreSQL | 存用户、会话、文档元数据、章节索引、段落索引;支持 FTS |
| 缓存 / 队列 | Redis | 验证码、黑名单、限流、Celery Broker |
| 文件存储 | 本地文件系统 | 存原始文档与解析后的规范化文本,挂载独立数据盘 |
| 异步任务 | Celery + Redis | 文档解析、结构化、索引化后台执行 |
| 检索方式 | PostgreSQL FTS + 规则打分 | 前期不引入向量库,优先准确率与可解释性 |
| 重排方式 | DeepSeek Chat | 对候选文档与章节做小范围重排 |
| OCR | 阿里云 OCR | 截图文字识别 |
| 生成模型 | DeepSeek Chat | 基于引用片段生成答案 |
| 流式输出 | SSE(Server-Sent Events) | FastAPI 原生支持,前端 EventSource 接收 |
| 邮件 | QQ 邮箱 SMTP(465/SSL) | 发送验证码,额外成本低 |
| 进程管理 | systemd | FastAPI(uvicorn)、Celery Worker 均以 systemd service 守护 |
| Python 环境 | venv | 应用依赖与系统 Python 隔离,requirements.txt 固定版本 |
| 敏感配置 | .env 文件 |
API Key、SMTP 授权码、OCR Key 等全部通过环境变量注入,文件权限 600 |
六、云端部署架构
所有服务部署在同一台物理服务器上,通过 systemd 管理各进程,无需容器化。
用户浏览器
|
HTTPS
|
【同一台服务器】
|
Nginx
|
+-- Vue3 静态资源(/var/www/llm_ask)
|
+-- FastAPI(uvicorn,systemd service)
|
+-- PostgreSQL(本机,unix socket 连接)
+-- Redis(本机,127.0.0.1:6379)
+-- Celery Worker(systemd service,concurrency=2)
+-- 本地文件系统(独立数据盘挂载点,如 /data/llm_ask)
+-- DeepSeek API(外部)
+-- 阿里云 OCR API(外部)
推荐初期服务器配置:
- 单台服务器:8核16G ECS/CVM
- PostgreSQL、Redis、FastAPI、Celery、Nginx 全部同机部署
- 数据盘单独挂载(存文档文件),系统盘与数据分离
- PostgreSQL 调优:
shared_buffers = 2GB,effective_cache_size = 6GB - Redis 限制:
maxmemory 512mb,maxmemory-policy allkeys-lru - Celery:
--concurrency=2,避免文档解析时内存峰值压垮其他服务
进程管理(systemd):
| 服务 | 启动命令 | 重启策略 |
|---|---|---|
llm-api |
uvicorn app.main:app --workers 2 --port 8000 |
Restart=always |
llm-celery |
celery -A app.worker worker --concurrency=2 |
Restart=always |
postgresql |
系统包自带 | Restart=on-failure |
redis |
系统包自带 | Restart=on-failure |
nginx |
系统包自带 | Restart=on-failure |
七、人日估算
| 模块 | 工作内容 | 人日 |
|---|---|---|
| 项目初始化 | 目录结构、venv、systemd service 模板、.env 规范 |
2 |
| 认证模块 | 邮箱注册/登录、验证码、防刷、JWT、Refresh Token、角色权限 | 6 |
| 文档管理后端 | 上传、校验、解析、结构化、章节索引、段落索引、状态机、补偿删除、版本切换 | 8 |
| 问答检索后端 | Query 归一化、文档召回、章节召回、LLM 重排、段落精定位、Prompt 组装、SSE 输出 | 7 |
| OCR 集成 | OCR 接入、与 Query 合并 | 2 |
| 前端:登录/注册 | 双模式登录、注册、验证码交互 | 2 |
| 前端:对话页 | 会话列表、SSE 流式渲染、截图上传、引用来源展示 | 7 |
| 前端:文档管理页 | 上传、列表、处理状态轮询、删除 | 3 |
| 前端:用户管理页 | 用户列表、创建、角色分配、禁用 | 2 |
| 集成测试 & 部署 | 云端部署、域名、SSL、systemd 服务配置、联调 | 5 |
| Buffer | 调试、需求微调、第三方 API 联调 | 6 |
| 合计 | 50 |
工期参考:
- 1 人独立开发:约 9 到 10 周
- 前后端 2 人并行:约 5 到 6 周可上线基础版本
- 后期升级到混合检索:额外约 5 到 8 人日
八、后期演进路线
- 检索增强: 从 PostgreSQL FTS 升级到 BM25 / 更细粒度规则打分
- 混合检索: 在现有
RetrieverInterface基础上增加向量检索,与词法检索融合 - 重排增强: 用专门的 reranker 模型替代通用聊天模型做候选重排
- 文件存储迁移: 本地文件系统迁移到阿里云 OSS
- SSO 集成: 对接企业 LDAP / 统一认证
- 用量统计: 统计问答次数、热门问题、未命中问题、低置信问题