Files
group_fqcd_jr/开发文档/D4.2-客服模块清除影响面清单.md
张胜宇 bc61d5c579 docs: 入库权威文档目录(客服agent/ 24 份 + 开发文档/ 50 份,替换旧命名的过期副本)
## 为什么做这一步

权威文档 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...`),
  末尾带省略号,是接口文档的示意值,**不是可用凭据**。
2026-09-20 15:03:15 +08:00

173 lines
13 KiB
Markdown
Raw Permalink 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.
# 客服 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 个临时探测文件(已删除)。