# 大模型智能问答客服系统 · 技术方案(腾讯云 ADP 版) **日期:** 2026-04-30 **版本:** v1.0 **面向对象:** 技术评审、开发实施、运维部署 **技术栈:** Python / FastAPI / Vue3 / Element Plus / 腾讯云 ADP / 腾讯云 SMS / 腾讯云 COS / PostgreSQL / Redis --- ## 一、方案结论 本项目采用「腾讯云 ADP 提供知识库、文档解析、检索、生成和引用;自研业务系统提供账号、权限、会话、审计和调用代理」的架构。 不再自研文档解析、OCR、切片、向量化、召回、重排和引用对齐。自研系统只保留企业应用必须具备、且 ADP 不适合直接承担的能力: - 手机号短信验证码登录、JWT、账号禁用和角色控制 - 用户会话和问答消息长期留存 - ADP SSE 接口代理,避免 `bot_app_key` 暴露到浏览器 - 文档上传、标签、密级、解析状态和审计管理 - 基于角色的知识库标签过滤 - Token / PU 用量记录、限额和告警 该路径能显著降低 RAG 自研风险,尤其适合财务制度、报销流程、操作手册等复杂文档问答场景。 --- ## 二、系统边界 ### 2.1 ADP 负责 | 能力 | 说明 | |---|---| | 文档解析 | PDF、Word、Excel、图片等文档解析,包含 OCR 和结构化处理 | | 知识切片 | 按 ADP 应用配置完成切片、索引和向量化 | | 知识检索 | RAG / Agentic RAG、多轮检索、召回和重排 | | 答案生成 | 由 ADP 应用绑定模型、Prompt 和工作流 | | 引用来源 | 通过 SSE `reference` 事件返回文档、片段、URL 等来源信息 | | 文档 OpenAPI | 文档上传、列表、详情、修改、删除、解析重试、预览等 | | 多模态理解 | 截图通过 Markdown 图片 URL 传入 `content`,由 ADP 识别 | ### 2.2 自研系统负责 | 模块 | 说明 | |---|---| | 认证与用户 | 手机号 + 短信验证码登录,管理员创建账号,角色和禁用状态 | | 权限治理 | 将用户角色转换为 ADP `custom_variables`,控制可检索标签范围 | | 会话留存 | 保存会话、问题、答案、引用、模型、Token、PU 消耗 | | SSE 代理 | 后端持有 `bot_app_key`,统一鉴权、限流、转发和错误处理 | | 文档管理 | 包装 ADP 文档 API,叠加业务字段、标签校验和审计日志 | | 统计审计 | 用户用量、热门问题、失败请求、未命中问题、费用统计 | --- ## 三、总体架构 ```text 用户浏览器(Vue3 + Element Plus) | HTTPS | Nginx | FastAPI 业务后端 |-- 认证模块:手机号 / 短信验证码 / JWT / Refresh Token |-- 用户权限模块:角色 / 账号禁用 / KB 标签规则 |-- 会话模块:会话列表 / 消息落库 / 引用落库 |-- 对话代理模块:POST 流式接口 -> ADP SSE |-- 文档管理模块:透传并包装 ADP 文档 OpenAPI |-- 审计计量模块:Token / PU / 错误 / 操作日志 | |-- PostgreSQL:业务数据 |-- Redis:验证码、限流、Token 黑名单 |-- 腾讯云 COS:文档上传中转、截图临时存储 | +-- 腾讯云 ADP |-- 知识库:文档、标签、切片、索引 |-- 应用:模型、Prompt、工作流、检索配置 |-- 对话接口:/v1/qbot/chat/sse +-- 文档管理 API ``` --- ## 四、认证与账号设计 ### 4.1 登录方式 - 唯一登录方式:手机号 + 短信验证码 - 手机号格式:默认中国大陆 `+86`,字段预留 `country_code` - 自助注册:默认关闭 - 账号创建:由管理员后台创建用户,指定姓名、手机号、角色和状态 ### 4.2 验证码规则 - 6 位数字验证码 - Redis 保存,5 分钟有效 - 同一手机号 60 秒内不可重复发送 - 同一手机号 24 小时最多 10 次 - 同一 IP 每小时最多 10 次 - 单 IP 单小时超过 5 次后要求图形验证码 ### 4.3 Token 规则 - Access Token:JWT,2 小时有效 - Refresh Token:7 天有效,只保存哈希值 - 管理员禁用账号后,现有 Token 加入 Redis 黑名单并立即失效 - Refresh Token 支持主动吊销和单用户全量吊销 --- ## 五、文档管理设计 ### 5.1 采用路线 采用「自研后台包装 ADP 文档 OpenAPI」路线。业务管理员不直接进入 ADP 控制台,所有文档管理都在本系统完成。 这样做的原因: - 统一产品体验 - 能叠加部门、密级、上传人、审计状态等业务字段 - 能在上传前强制校验标签和权限 - 后续切换底层 RAG 服务时,前端接口可保持稳定 ### 5.2 核心 ADP 接口 | 接口 | 用途 | |---|---| | `DescribeStorageCredential` | 获取 COS 临时上传凭证 | | `SaveDoc` | 文件上传完成后保存到 ADP 知识库 | | `ListDoc` | 查询文档列表 | | `DescribeDoc` | 查询文档详情和解析状态 | | `ModifyDoc` | 修改文档属性和标签 | | `RenameDoc` | 重命名文档 | | `DeleteDoc` | 删除文档 | | `RetryDocParse` | 重试解析失败文档 | | `StopDocParse` | 停止解析任务 | | `GetDocPreview` | 获取文档预览 | | `DescribeSegments` | 查询切片,供调试和验收使用 | | `CreateQA` / `ListQA` / `ModifyQA` / `DeleteQA` | FAQ 问答库维护 | ### 5.3 上传链路 ```text 1. 管理员选择文件 2. 前端调用 /api/docs/upload-credential 3. 后端鉴权,调用 ADP DescribeStorageCredential 4. 前端使用临时凭证直传 COS 5. 前端调用 /api/docs/save,提交文件 URL、名称、密级、标签 6. 后端校验标签,调用 ADP SaveDoc 7. 后端写入 documents_meta 和操作日志 8. 前端轮询 /api/docs/{id},展示解析状态 ``` ### 5.4 标签与密级 第一期只使用一个强制标签维度: ```text level = public | internal | confidential ``` 建议规则: - `employee` 可检索:`public`、`internal` - `admin` 可检索:`public`、`internal`、`confidential` - 文档上传和修改时必须填写 `level` - 未打标签文档不得发布到可检索知识库 - 每日巡检 ADP 文档列表,发现空标签、异常标签立即告警 注意:ADP 按标签过滤时,需确认平台对「未打标签知识」的处理策略。为避免权限绕过,本系统必须从业务流程上禁止未打标签文档进入正式知识库。 --- ## 六、问答代理设计 ### 6.1 前后端交互 不采用 `EventSource GET /api/chat/sse?content=...` 承载问题内容。原因是问题文本、截图 URL 和上下文可能较长,放在 query 中存在 URL 长度、日志泄漏和编码问题。 推荐采用: ```text 前端 fetch POST /api/chat/stream body: { conversation_id, content, image_ids[] } 后端 POST ADP /v1/qbot/chat/sse 前端通过 ReadableStream 消费后端返回的流 ``` 如浏览器兼容性要求必须使用 EventSource,可改成两段式: ```text POST /api/chat/request 创建请求,返回 request_id GET /api/chat/sse 只携带 request_id 订阅流 ``` ### 6.2 ADP 请求组装 后端负责组装 ADP 请求体: ```json { "bot_app_key": "${BOT_APP_KEY}", "session_id": "adp-session-id", "visitor_biz_id": "user-id", "content": "用户问题 + Markdown 图片 URL", "custom_variables": { "level": ["public", "internal"] }, "streaming_throttle": 5 } ``` 其中: - `bot_app_key` 只保存在后端环境变量 - `visitor_biz_id` 使用我方用户 ID - `session_id` 与我方 `conversations.adp_session_id` 绑定 - `custom_variables` 由后端根据角色计算,前端不可传入或覆盖 ### 6.3 SSE 事件处理 后端需要处理并落库的事件: | 事件 | 处理方式 | |---|---| | `reply` | 增量转发给前端,并拼接完整答案 | | `reference` | 保存引用来源,前端用于展示来源文档 | | `token_stat` | 保存输入、输出、PU 消耗 | | `thought` | 默认不展示给普通用户,可配置为调试模式展示 | | `error` | 映射为业务错误码,记录日志并返回友好提示 | ### 6.4 中断与一致性 - 用户主动取消时,后端停止读取 ADP 流 - 浏览器断开时,后端关闭上游连接 - 若回答未完成,消息状态标记为 `interrupted` - 若 ADP 返回错误,消息状态标记为 `failed` - 完整回答、引用和 Token 统计应在同一事务或可恢复流程中写入 --- ## 七、截图上传设计 截图不再接入本地 OCR。处理方式: ```text 1. 前端上传截图到我方 COS 临时目录 2. 后端生成 5 分钟有效的签名 URL 3. 发送问题时,将图片以 Markdown 格式拼入 content 4. ADP 读取图片并完成多模态理解 5. 我方消息表保存内部对象 key,不长期保存临时 URL ``` 安全要求: - 截图与正式文档分桶或分目录存储 - 截图对象设置生命周期,默认 7-30 天清理 - 临时 URL 只用于本次 ADP 调用 - 历史会话回看如需展示截图,由我方重新签发短期 URL - 敏感截图是否允许进入 ADP 多模态识别,应由甲方合规确认 --- ## 八、数据模型 ```text users id, phone, country_code, external_id, role, is_active, display_name, created_at, updated_at sms_codes phone, code_hash, scene, expires_at, attempts refresh_tokens id, user_id, token_hash, expires_at, revoked_at, created_at token_blacklist jti, expires_at conversations id, user_id, title, adp_session_id, created_at, updated_at messages id, conversation_id, role, content, status, sources_json, adp_request_id, token_in, token_out, pu_cost, model_name, created_at documents_meta id, adp_doc_id, name, level, tags_json, status, uploaded_by, uploaded_at, updated_at role_kb_label_rules id, role, label_key, label_values_json, updated_at usage_log id, user_id, conversation_id, message_id, token_in, token_out, pu_cost, created_at operation_logs id, actor_id, action, target_type, target_id, detail_json, created_at ``` --- ## 九、部署方案 ### 9.1 初期部署 ```text 单台云服务器 |-- Nginx |-- Vue3 静态资源 |-- FastAPI + uvicorn workers |-- PostgreSQL |-- Redis +-- systemd 管理服务 外部云服务 |-- 腾讯云 ADP |-- 腾讯云 COS +-- 腾讯云 SMS ``` 推荐配置: - 4 核 8G 云服务器 - 系统盘 100G 起 - PostgreSQL 本机部署 - Redis 本机部署,`maxmemory 256mb` - Nginx 负责 HTTPS、静态资源和反向代理 ### 9.2 环境变量 ```text DATABASE_URL REDIS_URL JWT_SECRET ADP_BOT_APP_KEY ADP_API_SECRET_ID ADP_API_SECRET_KEY TENCENT_SMS_SECRET_ID TENCENT_SMS_SECRET_KEY COS_BUCKET COS_REGION ``` `.env` 文件权限设置为 `600`,生产环境不提交到代码仓库。 --- ## 十、测试与验收 ### 10.1 功能测试 - 手机号验证码登录、刷新 Token、退出登录 - 管理员创建、禁用、启用用户 - 文档上传、解析状态轮询、重试、删除 - 文档标签必填校验 - 普通用户问答、管理员问答、多轮会话 - 截图上传并参与问答 - 引用来源展示和点击预览 ### 10.2 权限测试 | 测试项 | 预期 | |---|---| | employee 查询 public 文档 | 可回答 | | employee 查询 internal 文档 | 可回答 | | employee 查询 confidential 文档 | 不可回答 | | admin 查询 confidential 文档 | 可回答 | | 文档未设置 level | 不允许保存或发布 | | 前端伪造 custom_variables | 后端忽略 | ### 10.3 异常测试 - ADP 超时 - ADP 5xx - ADP 限流 - 短信发送失败 - COS 上传失败 - SSE 中途断开 - 文档解析失败 - Token 过期或黑名单命中 --- ## 十一、风险与对策 | 风险 | 影响 | 对策 | |---|---|---| | ADP 密钥泄漏 | 外部直接调用并产生费用 | 密钥只在后端保存,前端永不接触 | | 标签权限失效 | 用户检索到越权文档 | 强制标签、后端注入、巡检空标签、权限测试矩阵 | | ADP 服务不可用 | 问答能力中断 | 统一降级提示,记录失败,必要时人工客服兜底 | | 费用不可控 | PU 或模型调用超预算 | usage_log、单用户日限额、管理员告警 | | 数据合规争议 | 文档不能进入云端知识库 | 立项前确认合规口径,必要时采购专属版或私有化 | | 厂商锁定 | 后续迁移成本增加 | `LLMProvider` 抽象、ADP 配置 YAML 备份、文档源文件自持 | --- ## 十二、人日估算 | 模块 | 估算 | |---|---:| | 项目初始化与基础框架 | 2 人日 | | 认证、短信、Token、限流 | 5 人日 | | 用户和角色权限 | 3 人日 | | ADP 文档 API 包装 | 5 人日 | | 对话流式代理 | 5 人日 | | 会话、消息、引用落库 | 3 人日 | | 截图上传与临时 URL | 2 人日 | | 前端登录和主布局 | 3 人日 | | 前端对话页 | 5 人日 | | 前端文档管理页 | 4 人日 | | 前端用户管理页 | 3 人日 | | 审计和用量统计 | 2 人日 | | ADP 应用配置与联调 | 4 人日 | | 测试、部署、验收修复 | 5 人日 | | Buffer | 4 人日 | | **合计** | **约 55 人日** | 说明:该估算比上一版更保守,主要补入了 SSE 异常处理、权限测试、标签巡检、截图安全和 ADP 联调成本。 --- ## 十三、参考资料 - 腾讯云智能体开发平台 ADP 产品页:https://cloud.tencent.com/product/adp - ADP 文档概述:https://cloud.tencent.com/document/product/1759/112702 - HTTP SSE 对话接口:https://cloud.tencent.com/document/product/1759/105561 - 应用接入业务系统:https://cloud.tencent.com/document/product/1759/125067 - ADP API 概览:https://cloud.tencent.com/document/api/1759/105114 - 知识库操作指南:https://cloud.tencent.com/document/product/1759/119282 - 计费概述:https://cloud.tencent.com/document/product/1759/127342