## 为什么做这一步 权威文档 74 份此前**只在本机**,评审者 clone 分支后看不到任何设计文档;而仓库里那两份同名目录 是 **2026-09-16 之前的过期副本,连文件名都是旧的**(无体系编号)。本次按「**权威覆盖过期**」入库。 ## 入库内容 | 目录 | 文件数 | 体积 | 说明 | |---|---|---|---| | `客服agent/` | 24 | 0.77 MB | `D2.1`~`D2.6` 对外交付四件套 + 演示脚本/答辩报告 + `_build` 构建工具 | | `开发文档/` | 50 | 2.16 MB | `D1.x` 索引与决策、`D3.x` 方案、`D4.x` 清除与重构留痕、`D5.x` 业务流程、`D6.x` 业务事实基座、`D7.x` 交付物、`D8.x` 规范 | **旧的过期副本整体移除**(`客服Agent执行Todolist.md` → `D2.1-客服Agent执行Todolist.md` 之类 的改名 + 新增 `D2.5`/`D2.6`),入库后目录内容与权威副本**逐文件一致(零差异,已复核)**。 ## 入库前的安全扫描(必须留痕) - 扫描规则:`sk-` 类密钥 / `Bearer` 长串 / `password=`、`api_key=` 赋值 / 会话中出现过的两把明文 key 片段。 - 结论:**真实密钥只出现在 `.env`**(已被 `.gitignore` 命中,未入库);`.env.example` 与 `config/risk.env.example` 只有**空占位**。 - 文档内唯一命中是 `D3.1` 里一处**截断的示例 JWT**(`Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`), 末尾带省略号,是接口文档的示意值,**不是可用凭据**。
13 KiB
客服 Agent 模块清除影响面清单
体系编号:
D4.2· 域:四、清除与重建留痕 · 编号体系见D1.1§4.0
文档编号:CS-PURGE-2026-007 日期:2026-09-16 用途:对「彻底清除客服 Agent 模块」指令做的逐文件影响面取证。本次未执行任何删除。 结论(一句话):客服模块的专属资产约 40 个文件可删;但「含表与迁移」的字面全清与「项目能正常构建运行」在技术上互斥——有 3 条级联会同时打挂员工端、公共平台端与整个 Portal 外壳。
0. 为什么先出清单而不直接删
本轮侦察发现三项事实,任何一项都足以要求先确认再动手:
| # | 事实 | 影响 |
|---|---|---|
| 1 | 客服 Agent 是需求文档 §4 Phase 1 F1.3 的交付物本身,也是 MVP 三条业务线之一 | 「清除」= 放弃交付物,与「重构」相反 |
| 2 | svc_handover_ticket 与前端挂件被投顾/风控/员工端/公共平台共用 |
删它 = 打挂另外几个模块,违反 AGENTS.md 规则 1/4 与 docs/00 不可变基线 |
| 3 | 本机无法验证:Managed Python 3.13.14 未安装任何项目依赖,仓库无 venv | 你要求的「构建正常 + 验证结果」当前无法真实执行 |
1. 客服专属资产(可删除,约 40 项 / ≈1900 行)
1.1 后端实现(8 文件 / 1743 行)
| 文件 | 行数 | 说明 |
|---|---|---|
app/service/agent/implementations/customer_service.py |
748 | CustomerServiceAgent 主逻辑 |
app/service/customer_service_handover_action_service.py |
289 | 转人工动作(assign/accept/resolve/close/cancel) |
app/service/customer_service_session_memory_service.py |
209 | Redis 短期记忆 |
app/core/customer_service_rules.py |
208 | 路由规则、热线、零容忍词 |
app/service/customer_service_handover_admin_service.py |
124 | 工单队列查询 |
app/service/agent/customer_service_routing.py |
87 | 一期路由(含 8 条注入拦截,当前无生产调用方) |
app/service/customer_service_handover_context.py |
73 | 工单上下文 |
app/service/agent/customer_service_agent.py |
5 | 向后兼容桩 |
1.2 前端(2 文件 / 173 行)
| 文件 | 行数 |
|---|---|
app/static/portal/common/customer-service-widget/widget.js |
146 |
app/static/portal/common/customer-service-widget/widget.css |
27 |
1.3 工具脚本(6 文件)
tools/ask_customer_service.py、tools/customer_service_check.py、tools/grant_customer_service_phase2_permissions.py、tools/publish_customer_service_config.py、tools/publish_customer_service_knowledge.py、tools/verify_customer_service_phase1.py
1.4 测试用例(14 文件)
集成 2:test_customer_service_handover_actions_mysql.py、test_customer_service_handover_admin_mysql.py
单元 12:test_customer_service_test_page.py、test_customer_service_rules.py、test_customer_service_agent.py、test_customer_service_chitchat_metadata.py、test_customer_service_handover_actions.py、test_customer_service_handover_admin_service.py、test_customer_service_handover_context.py、test_customer_service_search_query.py、test_customer_service_session_memory_service.py、test_customer_service_suitability.py、test_customer_service_topic_matrix.py、test_publish_customer_service_knowledge.py
1.5 文档与静态资产(约 10 项)
docs/24-客服Agent阶段性总结与下阶段计划.md、docs/41-客服Agent前端开发约束_v1.md、docs/客服Agent二期_画像投影协议_v1.md、docs/客服Agent接入底座扩展说明_v1.md、docs/客服Agent一期远程整合测试手册.md、docs/superpowers/specs/2026-09-10-customer-service-agent-design.md、docs/superpowers/plans/2026-09-10-客服Agent与RAG实施计划-qyqy版.md、docs/superpowers/handoff/2026-09-11-*.md(2)、docs/evidence/20260910-customer-service-knowledge-preflight.json
另有 app/static/index.html(客服联调专用页)。
注:
docs/**中还有约 40 个文件顺带提及客服(如docs/05-接口文档.md、docs/14、docs/06测试报告)。这些是历史记录,删除会破坏文档体系的完整性,不建议动。
2. 共享资产(不可删,只能「摘除客服引用」)
| # | 共享文件 / 表 | 客服相关行 | 同时服务谁(证据) | 为什么不能删 |
|---|---|---|---|---|
| 1 | app/service/agent/bootstrap.py |
L28 import、L431-434 注册 | 7 个 Agent 的统一注册入口(L416 register_business_agents) |
删文件 = 全部 Agent 注册失效 |
| 2 | app/service/agent_run_application_service.py |
L13/26/28/30 import、L55/77/80/118/126/147/154 客服分支 | 受理链路服务全部 Agent(HTTP + Worker 共用) | 客服专属方法(_load_customer_service_prior_context)寄生在底座文件内,须摘方法而非删文件 |
| 3 | app/service/agent_persistence_service.py |
建单段 L116-153 | worker/runtime.py 全 Agent 共用 |
同上 |
| 4 | app/worker/runtime.py |
L38-41 import、L134/196/228/930-940 客服分支、L303-363 工单 outbox 消费 | Worker 分发全部 Agent | 摘分支,不删文件 |
| 5 | app/core/conversation_privacy.py |
sanitize_customer_service_message |
public_platform_service.py:10,149 也在用 |
公共隐私函数,删了打挂公共平台 |
| 6 | app/core/compliance_context.py |
NEGATION_CUES 等 |
governance.review_output 对全部 Agent 生效 |
公共合规件 |
| 7 | app/model/platform.py |
L95 svc_handover_ticket 表定义 |
见下 §3.1 | 改表 = 违反 AGENTS.md 规则 4 |
| 8 | app/repository/platform_repository.py |
L16 表名白名单 | 平台通用仓储 | 公共件 |
| 9 | tools/seed_test_rbac.py |
9008 handover:create、9046 handover:read、9069 handover:write |
RBAC 权限码唯一来源(DELETE 重建) | 权限码需保留给员工端 |
| 10 | app/static/portal/common/layout/app-shell.js |
L8 import、L178 挂载 widget.css | 整个 Portal 的布局外壳(公开首页 / 基金产品页 / 客户工作台) | 删 widget 会让 shell 立刻 import 失败 |
| 11 | app/static/portal/common/api-client.js |
L50-59 共 7 个 admin 工单端点 | 员工端 API 客户端 | 摘端点,不删文件 |
| 12 | app/static/portal/employee-console/workspace/workspace.js |
L198 工单队列渲染 | 员工工作台 | 摘 UI 区块 |
3. 三个硬阻断
3.1 阻断一:svc_handover_ticket 被 3 个模块读写,删表即打挂员工端与访客端
app/model/platform.py:95 __tablename__ = "svc_handover_ticket" ← 表定义
app/api/controllers/admin.py:230-361 7 个 HTTP 端点 /admin/customer-service/handover-tickets*
app/api/schemas/admin.py 工单出入参模型
app/service/public_platform_service.py:140 访客提交转人工时 直接 INSERT HandoverTicket
app/service/public_platform_service.py:43 按 ticket_no + customer_id 查询(客户自查)
app/repository/platform_repository.py:16 进平台仓储表名白名单
app/worker/runtime.py:311 outbox 消费者 SELECT HandoverTicket
后果:删除该表 → 员工端工单队列 7 个端点全部 500;访客端「转人工」写入失败;conversation.transfer_requested outbox 消费者抛 OutboxHandlerError。
规范冲突:AGENTS.md 规则 1「docs/00 为不可变业务基线」+ 规则 4「禁止重命名/删除已有表」+ docs/14 §12;并直接违反你在 Todolist v5.0 A-09 中立的纪律「既有接口路径与签名不可改」——删除上述 7 个 /api/v1/admin/customer-service/handover-tickets* 端点,即改变既有接口面。
同样不可删的共享表:agent_run、request_idempotency、domain_event_outbox、outbox_delivery(服务全部 Agent)、agent_negative_word(按 applicable_agents 分租,表服务全部 Agent)。
3.2 阻断二:前端挂件是全 Portal 的公共依赖
app/static/portal/common/layout/app-shell.js:8 import { mountCustomerServiceWidget } from '.../customer-service-widget/widget.js'
app/static/portal/common/layout/app-shell.js:178 widget.css?v=20260913 挂载
后果:app-shell.js 是公开首页、基金产品页、客户工作台的公共外壳。删除 widget 目录 → 所有 Portal 页面在浏览器端 import 报错、白屏。
连带:visitor-token.js:2,7 的注释记录「访客令牌逻辑原先只写在客服浮窗里,产品页接入后抽出」——即该共享模块是从客服侧抽出来的,源文件不能删。
3.3 阻断三:「字面全清」与「构建通过」互斥
你的验收要求是「不出现因删除该模块而导致的报错、死代码或未使用依赖」。但按 §3.1/§3.2:
- 要让构建通过,就必须同步修改
admin.py、api/schemas/admin.py、public_platform_service.py、platform_repository.py、worker/runtime.py、app-shell.js、api-client.js、workspace.js、seed_test_rbac.py共 9 个服务于其它模块的文件; - 而修改这些文件 = 动投顾/风控/员工端,恰是
AGENTS.md规则 7 与docs/14§12 明令禁止的。
→ 两条要求不能同时成立,必须由你在 §4 中二选一。
4. 两种可执行的收敛形态
| 维度 | 形态 A:模块级全清(可执行、构建可通过) | 形态 B:字面全清(你当前所选) |
|---|---|---|
| 删除范围 | §1 全部客服专属资产(约 40 文件) | §1 + §2 中 9 个共享文件的客服引用 + 3 张共享表 |
| 共享表 | 保留(svc_handover_ticket 等不动) |
删除 svc_handover_ticket、agent_negative_word |
| 员工端工单队列 | 保留(7 端点不动) | 失效(须一并删端点/UI/权限码/前端客户端) |
| 访客端转人工 | 保留(公共平台链路不动) | 失效 |
| Portal 外壳 | 保留(摘掉 widget 挂载) | 保留(无法删,它是布局外壳) |
| 构建结果 | 可通过(须按依赖顺序摘引用 + 重跑门禁) | 无法通过,除非改 9 个跨模块文件 |
| 规范合规 | 合规(不碰不可变基线) | 违反 AGENTS.md 规则 1/4/7 |
| 可回退性 | git 分支可回退 | 表结构变更不可回退(Alembic downgrade 亦需重灌数据) |
| 工作量 | 约 40 文件删除 + 9 文件摘引用 + 全量门禁 | A 的全部 + 员工端/公共平台功能移除 + 迁移脚本 + 权限码重排 |
说明:即便选形态 B,
app-shell.js(Portal 外壳)、conversation_privacy.py(公共隐私)、compliance_context.py(公共合规)、agent_run/request_idempotency/domain_event_outbox/outbox_delivery(平台核心表)仍然不能删——「彻底」在这个仓库里存在物理上限。
5. 环境验证能力现状(重要)
按 docs/14 §13 验收命令集实测本机环境:
| 项 | 实测结果 |
|---|---|
| git | ✅ 可用,当前分支 qyqy_develop |
| Managed Python | ✅ 3.13.14 可执行 |
| 项目依赖(pytest / fastapi / sqlalchemy / pydantic / redis / pymilvus / alembic / httpx / dashscope) | ❌ 全部 ModuleNotFoundError |
仓库内 venv(.venv / venv / env) |
❌ 不存在 |
pyproject.toml / requirements.txt |
✅ 存在 |
结论:pytest tests/...、ruff check、mypy app、tools/audit_schema.py 当前均无法运行。
若要满足你要求的「验证结果」,需先补齐依赖(且 tests/integration/** 还需要 MySQL + Redis + Milvus 服务在线)。
当前可做的验证上限:
python -m py_compile全量语法校验(不依赖第三方包)- 静态引用扫描(确认无悬空 import / 未被引用的删除目标)
git status/git diff --stat变更核对
6. 待你拍板(1 件事)
在形态 A 与形态 B 之间选定一个。
- 选 A → 我立即开工:先建备份分支 → 按 §2 依赖顺序摘除 12 处共享引用 → 删 §1 约 40 文件 →
py_compile+ 静态扫描验证 → 出变更清单。 - 选 B → 我必须先书面告知:项目将无法构建,且会改动见 §3.3 的 9 个跨模块文件(含投顾/风控/员工端);同时你需要确认放弃「客服 Agent」这条 MVP 业务线与
需求文档F1.3 交付物。请回复「确认执行形态B,接受项目无法构建与放弃F1.3」,我才会动手。
若你的真实意图是「清理重构前的死代码」(
客服与投顾模块重构前代码清理建议-2026-09-15.md的范围),那是另一个量级:约 6-9 个文件、构建不受影响,告诉我即可,我按那个范围一次做完。
附:本次侦察未产生任何文件改动。 仅创建了本清单与 2 个临时探测文件(已删除)。