## 为什么做这一步 权威文档 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 模块清除执行报告(形态A:模块级全清)
体系编号:
D4.3· 域:四、清除与重建留痕 · 编号体系见D1.1§4.0
编号:CS-PURGE-2026-008 日期:2026-09-16 依据:
开发文档/D4.2-客服模块清除影响面清单.md(CS-PURGE-2026-007)§4 「形态A」+ 用户指令「按你的建议在本地项目进行删除或修改操作,先删客服模块」 范围:group_fqcd_jr/(分支qyqy_develop) 结论:删除 34 个客服专属文件 + 修改 17 个共享文件引用;610 个 .py 语法零错误、悬空 import 零条。
一、为什么是形态A(一句话)
svc_handover_ticket 工单表、员工端工单队列 7 个端点、访客端「转人工」链路、Portal 外壳、
sanitize_customer_service_message 隐私函数都是跨模块共享资产。字面全清会把投顾/风控/员工端
一起打挂,且直接违反 AGENTS.md 规则 1/4/7 与 Todolist A-09「既有接口路径与签名不可改」。
形态A = 清掉客服专属资产,摘掉共享文件里的客服引用,保留共享表与共享链路。
二、已删除(34 个文件,可回退)
| 类别 | 数量 | 文件 |
|---|---|---|
| 后端核心实现 | 4 | app/service/agent/implementations/customer_service.py(748 行主逻辑)、app/service/agent/customer_service_routing.py(一期路由)、app/core/customer_service_rules.py(二期安全路由)、app/service/customer_service_session_memory_service.py(Redis 短期记忆) |
| 前端挂件 | 3 | app/static/portal/common/customer-service-widget/widget.js、widget.css、app/static/index.html(客服测试页) |
| 运维/发布脚本 | 8 | tools/ask_customer_service.py、customer_service_check.py、grant_customer_service_phase2_permissions.py、publish_customer_service_config.py、publish_customer_service_knowledge.py、verify_customer_service_phase1.py、publish_chitchat_prompt.py、publish_profile_tool_whitelist.py |
| 测试 | 9 | tests/unit/api/test_customer_service_test_page.py、tests/unit/core/test_customer_service_rules.py、tests/unit/service/test_customer_service_{agent,chitchat_metadata,search_query,session_memory_service,suitability,topic_matrix}.py、tests/unit/tools/test_publish_customer_service_knowledge.py |
| 文档 | 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-{工作报告,交接文档}-客服Agent与RAG收尾.md、docs/evidence/20260910-customer-service-knowledge-preflight.json |
| 过期字节码 | 6 | tools/__pycache__/ 下 5 个已删脚本 + 其余已删模块的 .pyc(源码已不存在者一律清除) |
完整路径清单:_cs_delete_list.txt(工作区根)。回退副本:_cs_purge_backup/(34/34 个文件,已核对)。
三、已修改(17 个共享文件,逐处说明)
| # | 文件 | 改了什么 | 为什么必须改 |
|---|---|---|---|
| 1 | app/main.py |
删掉 /customer-service-test 静态挂载 |
挂载目录已删,留着 = 启动即 404/异常 |
| 2 | app/service/agent/bootstrap.py |
删 CustomerServiceAgent import + factory.register(...) |
不删 = 整个 Agent 注册入口 import 失败,全部 7 个 Agent 一起挂 |
| 3 | app/service/agent_run_application_service.py |
删 5 处客服 import、CustomerServicePriorContext、_read_customer_service_short_context/_load_mysql_prior_context/_load_customer_service_prior_context、session_memory 构造参数;accept() 改为直接用 request.message;build_outbox_metadata() 退化为纯序列化 |
客服专属方法寄居在全 Agent 共用的受理链路里 |
| 4 | app/worker/runtime.py |
删客服 session_memory import/字段/构造参数、should_request_memory_extraction 的客服短路、should_request_profile_candidate 的 agent_type != "customer_service"、_append_customer_service_session_memory();新增 PROFILE_CANDIDATE_AGENT_TYPES(见 §六) |
Worker 分发全部 Agent |
| 5 | app/static/portal/common/layout/app-shell.js |
删 widget import + 挂载/样式注入块 | app-shell.js 是全 Portal 外壳 → 不删 = 所有页面 import 报错白屏 |
| 6 | app/static/portal/common/visitor-token.js |
更新注释(不再指向已删的 widget 路径) | 悬空路径引用 |
| 7 | app/service/agent/governance.py |
2 处注释:热线同步说明改写;CUSTOMER_FACING_AGENT_TYPES 加「客服仍在名单内」的理由 |
原文引用已删模块 customer_service_rules.CONTACT_PHONE |
| 8 | app/service/auth_service.py |
docstring 里 CustomerServiceAgent → 「面向客户的 Agent」 |
引用已删类名 |
| 9 | tools/check_rbac_seed_consistency.py |
GRANT_SCRIPTS 移除客服二期条目 |
该条目指向已删脚本 → 一致性校验脚本会 RuntimeError |
| 10 | tools/seed_demo_data.py |
STEPS 移除「客服配置白名单」「客服闲聊提示词」两步 |
两步指向已删脚本 |
| 11 | tools/api_console.py |
移除 /customer-service-test 路径分组项 |
与 #1 同因 |
| 12 | tests/unit/service/test_knowledge_granularity.py |
删 import + 4 条 CustomerServiceAgent._prefer_section 用例 |
import 已删模块 |
| 13 | tests/unit/service/test_agent_governance.py |
删 import + test_authenticated_customer_service_does_not_recall_customer_memory |
同上 |
| 14 | tests/unit/service/test_knowledge_keyword_recall.py |
test_gate_value_matches_agent_high_score 改为锁定 VECTOR_CONFIDENT_SCORE == 0.75 |
原用例比较的 HIGH_SCORE 只存在于已删模块 |
| 15 | tests/unit/worker/test_runtime_worker_dispatch.py |
删 CustomerServiceSessionTurn import + 3 条客服用例;2 条访客用例的 agent_type 改为存活 Agent |
已删模块 import / 已删方法调用 |
| 16 | tests/unit/tools/test_foundation_migration_preflight.py |
替身 Git 输出里的 customer-service-rag / customer_service_agent.py 改为中性路径 |
纯命名残留 |
| 17 | docs/customer-service-routing-legacy-keywords.md |
顶部加「已被形态A推翻」告示块 | 该文档原写「chitchat_streak() 保留未删」,现整个文件已删除 |
四、有意保留(不是漏删,逐条给理由)
| 保留项 | 理由 |
|---|---|
app/api/controllers/admin.py 的 7 个 /api/v1/admin/customer-service/handover-tickets* 端点 |
员工端工单队列。删除即改变既有接口面(违反 A-09),且 svc_handover_ticket 是平台核心表 |
app/service/customer_service_handover_{context,action,admin}_service.py |
同上;customer_service_handover_context 还被共享的 agent_persistence_service.py:15 导入 |
svc_handover_ticket / agent_run / request_idempotency / domain_event_outbox / outbox_delivery / agent_negative_word |
平台核心表,服务全部 Agent |
app/core/conversation_privacy.py::sanitize_customer_service_message |
公共隐私函数,还被 memory_extraction_worker + 2 个画像投影 + public_platform_service 使用 |
app/service/public_platform_service.py 的访客转人工写单 |
公共平台链路(访客入口),非客服模块私有 |
app/service/customer_profile_candidate_service.py 的 customer_service_preferences 快照键 |
画像快照已落库字段名,改名 = 数据迁移 |
app/service/agent/governance.py::CUSTOMER_FACING_AGENT_TYPES 中的 "customer_service" |
合规门禁 F5(面向客户输出必须附免责声明)。留着 → 重建后自动继承;摘掉 → 重建后出现合规缺口 |
docs/客服Agent一期_合规红队与业务评测集_v1.md、docs/customer-service-routing-legacy-keywords.md |
重建的验收基线 / 词表唯一副本(见 §六) |
五、验证结果(本机可做的上限)
| 项 | 结果 |
|---|---|
py_compile 全量语法校验 |
610 个 .py,0 错误 |
| AST 静态扫描:指向不存在文件的 import | 0 条 |
__pycache__ 过期字节码 |
已清(仅保留源码仍在的 570 个) |
| 文本残留 | 68 个 .py / 215 处(全部为数据值、共享表名、保留模块名、历史注释,见下) |
| pytest / ruff / mypy / 集成测试 | ❌ 跑不了:本机无项目依赖(pytest/fastapi/sqlalchemy/pydantic/redis/pymilvus/alembic 全部 ModuleNotFoundError),仓库内无 venv |
验证脚本:_purge_verify.py;原始报告:_purge_verify_out.json。
(alembic.* 是第三方包,首轮扫描把它误判成悬空 import,已在脚本里修正口径。)
残留分类(68 个文件):
app/(15 个):全部为有意保留项(handover 三件套 + 工单端点 + 公共隐私函数 + 核心表名 + 历史注释)。tests/(28 个):agent_type="customer_service"/customer_service:faq等测试夹具与配置键的字符串值;acceptance_registry夹具自己注册替身 Agent,故这些用例仍然自洽。tools/(11 个):见 §六.3。alembic/(1 个):基线迁移里的表注释。
六、需要你拍板 / 重建时必须补齐(6 项)
6.1 已随模块消失的安全能力(最重要)
删除的不只是"客服话术",还包括三套拦截能力,现在在生效路径上不存在:
| 能力 | 原位置 | 现状 |
|---|---|---|
| 提示词注入拦截(8 条词) | 先期迁入 customer_service_rules.py |
随模块删除 → 红队 RT-009/010 必然失败 |
凭据披露拦截(_SECURITY_DISCLOSURE_PHRASES) |
同上 | 同上 |
安全关键词路由 + 零容忍词(11 条,与库内 agent_negative_word 镜像) |
route_message() / ZERO_TOLERANCE_WORDS |
同上 |
词表唯一副本已存于 docs/customer-service-routing-legacy-keywords.md(我已在该文档顶部加了告示块)。
重建时按它的迁移对照表恢复,否则这批词会彻底丢失。
6.2 PROFILE_CANDIDATE_AGENT_TYPES 目前为空集合(需确认)
app/worker/runtime.py 新增该常量,frozenset()。行为与删除前完全等价(此前也只有客服命中)。
我故意没有把它改成"任何非访客 Agent 都可产出候选"——因为候选里含 preference:risk_level,
放开会让投顾对话也能产出风险等级候选,触碰 MVP 红线①「风险等级唯一来源是问卷测评」。
重建客服 Agent 后,把它的 agent_type 填回该集合即可接通候选链路。
6.3 11 个开发脚本仍指向已注销的 agent_type="customer_service"
tools/:smoke_check.py(7)、e2e_smoke_test.py(4)、acceptance_check.py(3)、portal.py(3)、
portal_api_check.py(2)、memory_demo_chain.py(2)、chat_console.py(1)、drop_table_header_vectors.py(1)、
publish_risk_agent_config.py(1)、seed_compliance_baseline.py(1)、seed_knowledge_r1r5_faq.py(1)。
这些脚本不是构建依赖(app/ 不 import 它们),但连上服务后会因为 Agent 未注册而失败。
替换成哪个存活 Agent(advisor?fund_query_demo?)会改变脚本演示的语义,我不替你做这个决定。
请给一个口径,我一次改完。
6.4 文档层残留(约 30 处,在 docs/ 站内)
分两类,处理方式不同:
- 历史记录(交付说明、评审回复、合并记录、验收报告等):按其写作日期引用当时的文件,建议原文不动(改历史=伪造记录)。
- 在用运行手册(
AGENTS.md:163、docs/05-接口文档.md(10)、docs/09-底座使用文档.md(9)、docs/32-平台侧交接与联调准备.md(3)、docs/11/14/15-接入说明书):命令/脚本已不存在,建议回写。要我做就说一声。
6.5 Advisory:AGENTS.md:163 引用了已删的发布脚本
AGENTS.md 是项目的规则文件(Rule Priority 载体)。它把「同 key 继承项必须被覆盖」这条教训
挂在 tools/publish_customer_service_config.py 上,而该脚本已删 → 教训的载体消失。
我没有擅自改 AGENTS.md(规范性文件),请你决定是改引用还是换载体。
6.6 重建时必须带回的测试(我已在原位留注释)
tests/unit/service/test_agent_governance.py:客服不得触发通用长期/画像记忆读取。tests/unit/service/test_knowledge_granularity.py:整节块 vs 行级子块的取舍(_prefer_section)。tests/unit/service/test_knowledge_keyword_recall.py:检索层门槛与客服高置信门槛的跨模块对齐。
七、回退方式
# git 写入被本机沙箱拦截(git branch 返回 0 但分支未创建),故用文件级备份:
# D:\桌面\金融\_cs_purge_backup\ 34/34 个被删文件的副本(保持原目录结构)
# 恢复:按原相对路径复制回 group_fqcd_jr\ 即可;
# 17 个被改文件请用 git diff 逐处回退(改动都是"删引用",无逻辑重写)。