Files
kefu/wechat_rpa/KNOWLEDGE.md
T
2026-09-21 10:34:06 +08:00

174 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 聊天知识中心
本模块将归档中的单聊文本整理为待审知识,审核发布后由现有模型网关检索引用。知识默认不启用、草稿不会进入检索,原始归档保留。
## 首次使用
1. 更新管理 API、模型网关与前端,启动知识 Worker。
2. 管理端进入「知识中心 → 知识加工与检索」,选择具体客户端账号。
3. 点击「从聊天整理知识」,选择该租户的客服来源账号。建议先设置消息上限 10000,采用规则整理。
4. 在「加工任务」查看进度,在「知识与审核」逐条核对来源、事实、身份、脱敏结果和适用条件。
5. 保存草稿、审核通过、发布。健康或个体医疗信息需要专业审核并通用化,不能将患者个人情况当作普遍结论。
6. 在「检索测试」检查真实问题的召回结果,再开启该账号的「客服使用知识」。未命中时,模型会收到追问、不得编造业务事实的要求。
7. 通过「引用记录」查看网关每次使用的知识 ID、版本和检索耗时。发布后的编辑会退回草稿;旧版本可恢复为新草稿,重新审核发布。
所有写操作必须选择具体账号。「全部账号」只提供授权范围内的汇总视图。知识不跨租户共享。
## 第二版:整理与审核流程
- 「全部账号」下可以点击「选择账号开始整理」,展开账号选择;选择具体账号后进入整理向导。
- 先预览所选来源与日期内的单聊消息量、会话数、身份明确的有效文本量,以及本次最多读取条数。预览不创建任务,不调用模型,不返回聊天正文。
- 预览的有效文本条数覆盖整个选定范围,不代表本次一定生成的知识数。新任务在创建时重新确定截止水位和消息总数;预览后新增的归档可能使数字变化。
- 新任务展示「已读 / 实际计划消息数」、来源、整理方式和完成原因。旧任务缺少总数时只展示已读条数,不使用配置上限冒充实际总数。
- 支持暂停、继续和取消。取消只停止后续处理,已经生成的草稿保留;已发起的模型请求可能仍计费。取消某个任务不会自动关闭该来源的持续整理开关。
- 相同范围、整理方式与处理上限的任务在排队、处理中或暂停时,不能重复创建。可以继续原任务或取消后重建。
- 在知识列表勾选当前页的条目,进入批量审核。每条需要展开查看脱敏来源,核对事实和适用条件后分别勾选;缺少条件、版本变化或状态不符会单独提示。
- 支持批量发布、驳回、停用。每条分别调用现有鉴权接口、检查当前版本与来源并写入审计;操作不是一个整批事务,成功项保留,失败项逐条显示且不自动重试。
- 批量操作期间可以停止后续请求;已经发起的操作会完成。离开页面也会停止后续请求。刷新后按实际状态处理未完成项。
- 已过期知识不能审核通过或发布;只有已发布知识可停用。账号至少有一条有效、来源未失效的已发布知识,才能开启客服使用知识。
- 修复了消息上限恰好等于完整范围末尾时丢弃最后一个问答的问题。若上限确实截断后续上下文,末尾未闭合问答仍会丢弃。
本次任务统计保存在已有 `options_json`,不新增数据库列。旧任务、已有知识和来源追溯保持兼容。
## 启动与部署
本地开发:
```powershell
cd C:\kefu\wechat_rpa
python run_backend.py --db backend.db
```
启动器现在同时拉起管理 API、模型网关、知识 Worker。单独运行 Worker:
```bash
python knowledge_worker.py --db /data/backend.db
# 只执行一个批次,可用于诊断
python knowledge_worker.py --db /data/backend.db --once
```
当前生产部署使用根目录 `deploy/im-admin/compose.yaml`,已增加 `knowledge-worker` 服务,并复用现有镜像和数据库卷。不要使用已经过时的 `wechat_rpa/backend_deploy` 配置替代当前部署。
更新前备份 SQLite(使用 SQLite backup API 或停止写入后备份数据库及其密钥),保留当前镜像作为回退。构建前端后,在生产部署目录执行:
```bash
docker compose up -d --build api gateway knowledge-worker
docker compose logs --tail=100 knowledge-worker
```
API 启动时新增知识表、FTS5 表、来源失效触发器和归档扫描索引;首次索引构建时间取决于数据库与磁盘。建议低峰部署。现有管理角色自动获得新权限,其他角色需配置 `knowledge:read/write/review/publish/export`;加工和审核同时要求 `im:content:read`。
关闭「客服使用知识」即可回退到原回复链路。回滚代码前停止 Worker,保留新增表与数据,避免恢复旧库覆盖部署后的新增归档。
## 整理与增量更新
- 规则整理不调用模型。按单聊、连续发言及 30 分钟间隔整理完整问答,跨读取批次保留上下文。
- 只接受明确的客服来源账号;发送者身份还必须与来源账号匹配。群聊、未知方向、非文本、撤回消息和不完整片段不会自动产生可用知识。
- 每批规则任务读取最多 200 条,模型任务最多 20 条,使用游标和租约。任务、游标、草稿在数据库中持久化;Worker 崩溃后租约最长 5 分钟到期,可继续处理。
- 暂停会使在途批次失去提交权限。已经开始的模型请求不能撤销,重试可能产生额外调用,因此调用预算按发起前预扣。页面展示调用次数和字符量,不将字符数冒充 token 数或费用。
- 模型整理可指定管理端已启用的文本模型,创建时固定所选出口;仅发送规则预处理后的脱敏问答。输出始终为待审草稿,不能自动发布。
- 精确重复问答去重;同义问法和相互冲突的不同答案仍需审核。暂未实现自动语义合并。
- 任务固定截止时间并读取该时点的消息版本。上限截断时,最后一个未闭合问答会丢弃;增加范围重新加工可补齐,已生成草稿会去重。
- 创建任务时勾选「持续整理」后,该来源账号后续的消息插入或内容/状态变化会写入增量队列。会话静默 30 分钟后,Worker 只重新整理变化会话,使用规则方式生成草稿,不产生自动模型费用。可在加工任务页停用或恢复。
- 撤回、修改、删除消息时,关联知识立即标为来源失效,并删除关键词索引。向量库中的旧点即使尚未清理,也不能通过 SQL 租户、状态、版本和来源复核。重新加工、审核后才可再次使用。
## 检索配置
默认关键词检索使用 SQLite FTS5,对中文采用双字切分,英文采用词切分,不扫描整个归档。它无法完整覆盖同义表达;需要更好的语义召回时配置向量服务。
在 `deploy/im-admin/.env` 配置以下变量,重建 API、网关和 Worker 的容器环境:
```dotenv
KNOWLEDGE_QDRANT_URL=http://your-qdrant:6333
KNOWLEDGE_QDRANT_KEY=
# 完整 embeddings API 地址,不会自动补路径
KNOWLEDGE_EMBEDDING_URL=https://your-provider.example/v1/embeddings
KNOWLEDGE_EMBEDDING_MODEL=your-embedding-model
KNOWLEDGE_EMBEDDING_KEY=your-secret
```
向量接口需支持 `{model,input}` 请求及 `data[0].embedding` 响应。URL、模型、密钥只从服务端环境读取。发布知识时完成向量写入后才置为已发布;配置不完整或服务失败会阻止本次发布,不会假装索引已完成。未配置语义服务时,可正常发布为关键词知识。
不同 embedding 模型/地址使用不同集合,防止不同向量空间混用。更换模型或为已有关键词知识补建向量时:
```bash
python knowledge_worker.py --db /data/backend.db --reindex --tenant ACTUAL_TENANT_ID
```
重建期间现有关键词检索仍可用。查询使用关键词与向量结果融合,最多选 5 条且限制引用总长度;语义服务暂不可用时回退关键词,管理端显示回退状态。当前相关度阈值是初始值,需在真实业务评估集上校准。
只有网关的 `purpose=chat` 会检索,界面识别等内部用途不受影响。同一次网关请求的模型候选共享证据;不同工具轮会重新检索,不跨客户缓存检索结果。网关幂等缓存中的知识引用也会重新检查是否有效。
## 数据与追溯
- `knowledge_job`:任务、固定水位、处理游标、未闭合上下文、租约、用量。
- `knowledge_item` / `knowledge_revision`:当前知识与每次编辑、审核、发布的版本快照。
- `knowledge_source`:来源消息 ID、版本、角色及脱敏文本。
- `knowledge_fts`:关键词索引;Qdrant payload 只保存条目 ID、租户和版本,不保存正文。
- `knowledge_settings` / `knowledge_watch` / `knowledge_dirty`:启用状态及增量队列。
- `knowledge_retrieval_log`:网关引用的条目与版本、处理方式、耗时;日志不等于客服消息已成功发出。
「导出已发布知识」提供 UTF-8 JSONL,包含 `schema_version=knowledge-v1`、ID、版本、问题、答案、适用条件、分类及有效期。导出不包含原始聊天或患者信息字段;只导出当前租户的有效已发布知识。
自动脱敏覆盖已知发送者姓名、手机号、身份证号、长编号、邮箱、链接和带标签的地址;它不是完整的个人信息识别器,自由文本地址、第三方姓名等仍必须人工检查。
## 验证与上线评估
```bash
python -m unittest test_knowledge -v
python -m unittest test_model_gateway test_archive_api test_admin_api
```
前端:在 `admin-web` 执行 `pnpm --filter @vben/web-antd typecheck` 和 `pnpm --filter @vben/web-antd build`。
上线前先用独立问题集测试正确知识召回、回答准确性、无依据追问、权限隔离和延迟。相同客户、会话及近重复案例不应同时出现在知识构建样本与评估集。当前实现未处理语音、图片、附件,没有将生产 40 万条聊天自动送入模型,也没有执行模型微调。
## 第三版:模型任务恢复与驳回删除
- 创建模型任务时选择整理模型、单次等待时间(30–180 秒,默认 90 秒)及调用总上限;知识整理请求输出上限为 4096 token,独立于实时客服调用配置。Dify 应用自己的模型配置与限制仍由上游控制。
- 失败或暂停任务点击「配置 / 继续」,可换模型、增加等待时间或调用总上限,亦可改成规则整理。已完成草稿保留,新配置只作用于剩余问答。原模型停用时直接报错,不会偷偷切换到其他出口。
- 扫描游标和待处理问答先持久化,每生成一条草稿立即提交。失败重试不再重做该批已成功的问答;在途请求遇到暂停、取消或进程中断仍可能计费并需要重试。
- 错误区分超时、授权、限流、网络与输出格式问题,服务端不保存上游原始错误正文、密钥或地址。页面字符量统计成功处理的输入/输出,并非计费 token 数。
- 已驳回知识支持单条及批量确认删除,需知识编辑与来源正文查看权限。删除知识、来源快照、版本记录和关键词索引,保留原始聊天归档及删除审计;无法从管理界面恢复。租户内保留内容指纹,避免完全相同的已删除草稿被再次生成;不同模型改写仍需人工去重。
- 新增 `knowledge_discarded` 表,无需回填归档数据。任务待处理问答保存在私有 `state_json`,接口仅返回待处理数量。
回归检查:`python -m unittest test_knowledge test_knowledge_tasks test_model_gateway -q`;前端批量操作测试、类型检查及隔离浏览器中的失败换模型续跑与删除流程。
## 模型字段异常修复(2026-09-16)
模型返回空标题、分类、适用条件或非标准类型不再使整项任务失败:标题从有效问题生成,分类保留待分类,适用条件留空并要求人工补充,类型在校验后采用标准值。
标题可缩短至 160 字符;问题、答案和原始来源不静默截断。核心问答缺失、类型不正确、超过限制或 JSON 不完整时,该条转为保留原始脱敏问答的待审草稿,记录具体原因,后续候选继续处理。适用条件置空,未人工编辑补齐前不能审核或发布。格式异常次数、最近原因与输入输出字符量随单条结果一起保存。
网络、授权、模型限流、调用预算耗尽仍会暂停并报错,避免把服务故障误当作可用模型结果。待处理的旧任务继续兼容,无需重建或清零进度。
验证:`python -m unittest test_knowledge test_knowledge_tasks test_knowledge_model_output test_model_gateway -q`,外加本机隔离浏览器验收。真实失败响应未保存,无法还原具体缺失字段;线上只读检查与修复验收不重发真实聊天。
## 全量审核(2026-09-16)
知识与审核页支持指定账号或全部授权账号的一键审核,覆盖全部页面,不受当前搜索、状态筛选与勾选影响。对象是已经整理出的待审核知识草稿;原始聊天需先整理为草稿。审核通过只进入待发布,不发布、不启用客服检索、不调用模型。
流程:选择范围 → 预览待审/可通过/需处理数量与按账号统计 → 一次确认范围已完成必要审核 → 后台分批执行。预览以草稿 ID、租户、版本及更新时间固定快照,有效期 30 分钟;同一用户新预览使旧预览失效。之后新增、修改、删除、已驳回或已发布条目均不会被旧快照误审核。
SQL 检查必填及长度、适用条件、有效期、来源存在及最新版本。每批最多 100 条,状态、审核历史、审计、结果及进度在同一短事务内提交。后台在独立线程运行,不受模型网络调用阻塞;关闭页面、进程重启后按已提交进度继续,支持暂停、继续、停止。失败事务不会半批提交。
每批重查操作者的审核、知识读取、原文权限和账号授权。权限撤回或用户停用会暂停为需处理状态;某个账号授权撤回则跳过该账号。任务只对创建者可见,结果清单再次按当前账号权限分页过滤。未通过知识保持原状态并列出原因,可直接打开对应账号的知识详情。
表:knowledge_review_job、knowledge_review_target;应用启动自动创建。回滚旧应用保留这些表及任务进度,旧版不执行新审核队列,已完成审核保留为待发布。
接口(均要求 knowledge:read、knowledge:review、im:content:read):POST /api/v2/knowledge/review-tasks/preview?account_id=-1;GET /review-tasks;GET /review-tasks/{id};GET /review-tasks/{id}/results;POST /review-tasks/{id}/{start|pause|resume|cancel}。start 需 confirmed=true,重复提交不会重复入队,results 默认每页 30、最大 100。
验证:92 项后端回归,前端类型检查、生产构建、隔离浏览器跨页及跨账号流程。50 万条虚构知识预览 6.547 秒,连续 10 批共通过 1000 条、平均每 100 条 0.066 秒,Python tracemalloc 峰值 0.127 MB(不含 SQLite 原生内存和系统缓存),预览响应 636 字节;性能是本地模拟数据结果。线上部署验证不提交审核任务,不修改真实知识审核状态。
## 检索输入与错误提示修复(2026-09-16)
旧版在空白或单字问题点击检索时,会把 FastAPI 422 校验数组直接交给消息组件,显示 `[object Object]`。本机浏览器使用旧构建复现了同样提示。
检索输入现在先去除首尾空白,按 Unicode 字符数校验 2–2000 个字符,前端拦截非法请求并给出中文说明;后端同步先去除首尾空白再校验。失败时清空旧结果并展示可读原因,不产生未处理的 Promise 错误。公共请求错误处理把字符串、FastAPI 数组及嵌套错误消息转为文字,不直接展示对象或校验响应里的原始 input。
检索仍只返回当前账号的已发布、有效知识;未发布知识不会因为此修复进入检索。当前账号没有已发布知识时展示「先审核并发布」说明,合法问题正常返回空结果。
验证:96 项后端回归,10 项前端错误格式与批量操作测试,前端类型检查和构建。隔离浏览器覆盖空白、单字、2001 字符拦截,正常问题回车检索及首尾空白处理,422 数组提示,旧结果清理与空知识库;模拟账号 3 条知识中仅 1 条已发布,正确命中 1 条。