Files
group_fqcd_jr/docs/客服Agent接入底座扩展说明_v1.md
T
张胜宇 9aaacc242f chore: 清理违反底座规则的死代码并修正接口文档编号
- 删除生产死代码 app/service/knowledge_tool_service.py 与
  app/infrastructure/milvus_knowledge_adapter.py:后者硬编码 Milvus 字段名,
  违反 AGENTS.md §E,且仅被前者引用;生产检索链路实际走
  knowledge_search_tool -> KnowledgeSearchService -> knowledge_schema 运行时探测。
- 删除上述两模块的单测,以及依赖 legacy 位置参数构造的
  tests/unit/service/test_knowledge_retrieval.py。
- app/service/knowledge_retrieval_service.py 整文件回退底座版本,
  移除 legacy 双构造与重复检索实现。
- docs/05-接口文档.md:客服画像候选改登记为 §8.5,恢复 §8.2 解析知识引用;
  既有 §8.1-§8.4 编号全部保持,修复此前出现两个 8.3 的问题。
- app/model/profile.py:current_customer_id 改为普通可空列映射,与
  alembic/baseline_generated.sql 及真实库一致;原 Computed 声明会让 ORM 把该列
  从 INSERT 中排除,与「必须显式写入」的实际 schema 不符。
- 新增 docs/客服Agent接入底座扩展说明_v1.md,供集成分支评审逐项确认。

验证:pytest tests/unit tests/contract -> 1275 passed, 2 skipped, 0 failed;
ruff check app tests tools alembic 通过;mypy app 通过(244 个源文件)。
2026-09-12 11:15:24 +08:00

11 KiB
Raw Blame History

客服 Agent 接入底座扩展说明(v1)

用途:提交 qyqy_develop(集成分支)评审时使用。 本文档逐项列出「客服 Agent + RAG」能力为接入底座而触碰的既有文件、改动性质、合规依据, 以及明确未改动的底座边界,便于架构师逐条确认。

依据:AGENTS.md、docs/00、docs/01、docs/05、docs/09、docs/14、docs/20。


一、总体口径

  • 本次接入遵循 AGENTS.md 规则 7:客服 Agent 继承公共 BaseAgent、由 AgentFactory 创建, 不绕过公共鉴权、记忆、模型路由、工具、合规、审计与事件流程。
  • 数据库侧未做任何基线改动:没有新增/重命名/删除表,没有改字段类型、可空性或业务含义, 没有新增迁移脚本。
  • 底座中所有「既有 Agent 默认行为」均通过带默认值的声明位扩展,默认值等于改动前行为, 其他 Agent(FundQueryDemoAgent、RiskAgent、PlatformProbeAgent)路径不受影响。

二、A 类:纯新增,不影响既有代码

文件 说明
app/core/conversation_privacy.py 客服会话落库前的凭据最小化(密码/验证码/证件号/银行卡/手机号 → 占位符)
app/api/controllers/visitor_tokens.py、app/api/schemas/visitor_tokens.py 访客短时令牌签发接口
app/service/agent/customer_service_routing.py 客服确定性意图路由(安全/账户/人工/合规/闲聊/公开知识)
app/service/customer_service_session_memory_service.py 客服 Redis 短期会话记忆(30 分钟滑动 TTL、24 小时绝对上限、16 条/约 4096 Token 截断)
app/service/customer_service_handover_context.py、customer_service_handover_admin_service.py 转人工上下文构造与管理员只读工单服务
app/service/customer_profile_candidate_service.py 画像候选(Phase 2,异步、需用户确认 + 管理员审核)
app/service/knowledge_authority.py、knowledge_config.py、knowledge_publication_service.py 知识权威回查、运行期配置、受控发布工具所依赖的服务
app/infrastructure/milvus_profile_projection.py、neo4j_profile_projection.py 画像投影适配器(异步派生写入)
app/worker/memory_sync_outbox_worker.py、customer_profile_candidate_worker.py 画像投影 Outbox 消费者、候选画像 Worker
app/static/index.html 客服联调测试页(/customer-service-test)
tools/publish_customer_service_knowledge.py、verify_customer_service_phase1.py、knowledge_import_preflight.py 受控发布、只读门禁、导入预检

以上均为新增文件,不改变任何既有模块行为。


三、B 类:带默认值、默认行为不变的扩展(对齐底座扩展点,建议直接确认)

文件 改动 默认值是否等于原行为
app/core/contracts.py AgentDefinition 新增 requires_model_intent_classification=True、recalls_customer_memory=True;AgentRequestMetadata 新增 chitchat_streak/clarification_round/session_context;CoreResult 新增 clarification_required 是
app/service/agent/base.py recall_memory() 在声明关闭或访客时置空;classify_intent() 在声明关闭时返回 None 是
app/service/agent/factory.py 仅在 requires_model_intent_classification 为真时绑定意图分类器 是
app/core/config.py 新增 visitor_token_ttl_seconds、milvus_local_uri、knowledge_embedding_endpoint_code、knowledge_embedding_timeout_ms 与 resolved_milvus_uri 属性 是(新增项均有默认值)
app/core/knowledge_contracts.py 新增 ALLOWED_KNOWLEDGE_COLLECTIONS 别名(与 ALLOWED_COLLECTIONS 恒等);KnowledgeHit.answer 可选字段;KnowledgeSearchResult.hits 补默认值 是(三个 fin_*_collection 白名单内容未变)
app/model/knowledge.py 新增 FinKnowledgeMeta = KnowledgeMeta 别名 是
app/model/memory.py __all__ 与 ProfileSnapshot 兼容转出 是
app/service/agent/bootstrap.py 新增注册 query_knowledge 工具,handler 复用 knowledge_search_tool(与 search_knowledge 同一实现),required_permission="knowledge:query" 是(不新增能力面,实际范围仍由 config_release 白名单收口)
app/service/memory_service.py upsert_memory() 新增 status 参数(active/candidate),candidate 不覆盖现有有效记忆 是(默认 active)
app/service/public_platform_service.py 转人工工单 reason_detail 落库前做凭据脱敏 是(安全收紧)
app/main.py 注册 visitor_tokens_router、挂载 /customer-service-test 静态页 是(纯新增装配)
pyproject.toml、requirements.txt 新增 milvus-lite>=3.2,<4 是(可选本地开发依赖)
.gitignore 新增 .worktrees/、data/milvus/ 是

四、C 类:需要架构师确认的底座语义扩展

C1. 访客身份(app/api/dependencies/auth.py + app/core/security.py)

  • security.py:JwtAuthenticator.authenticate() 新增分支——当令牌含 visitor: true 声明时, 返回 roles=("visitor",)、permissions=("agent:run", "knowledge:query")、data_scope="public"。
  • auth.py:build_request_context() 对 visitor 角色跳过 IdentityService().resolve() (访客不在 sys_user 中,无法解析身份)。

合规说明:

  • visitor 角色只可能出自用项目 RS256 私钥签名、且显式带 visitor: true 的令牌,普通用户令牌 无法携带该角色;
  • 访客权限固定为 agent:run + knowledge:query,data_scope="public", 不包含任何账户、持仓、订单、银行卡、投诉进度或画像权限;
  • 该分支只影响访客令牌,非访客令牌仍走完整 IdentityService 身份解析。

请求确认: 是否接受在底座统一鉴权链路中增加这一受控访客身份;如需要,我们可补一份 docs/ 说明或在 docs/05 登记该令牌类型。

C2. 客服 Agent 的角色与安全路由(app/service/agent/implementations/customer_service.py)

  • allowed_roles 由 ("customer",) 扩为 ("visitor", "customer");
  • handle() 首部插入确定性安全路由 route_message()(安全提示、合规拒答、账户入口、人工转接优先于检索);
  • 新增 recalls_customer_memory=False(客服不隐式召回长期/画像记忆);
  • 新增 chitchat_streak == 4 的一次性业务引导;
  • 业务口径:COMPANY 由 南方科技 改为 奶龙基金责任有限公司。

请求确认: 角色扩容与行为契约变更(安全路由前置、闲聊计数);品牌名属业务口径调整。

C3. 画像快照 ORM 声明清理与 current_customer_id 映射更正

三处相关改动(属于修既有缺陷,不是改设计):

  1. app/model/risk_questionnaire.py:原有内联 ProfileSnapshot 声明与 app/model/profile.py 的同表声明重复,两个 declarative 类映射同一张表会让 SQLAlchemy 直接拒绝导入。 现改为从 app.model.profile 转出规范类,保留对既有调用方的兼容导出。
  2. app/model/profile.py:把 current_customer_id 映射为普通可空列。
  3. 依据:该列在真实库中是普通可空列(EXTRA=''、GENERATION_EXPRESSION='',已实测), alembic/baseline_generated.sql 的建表语句也没有 GENERATED 子句, tools/seed_profile_demo.py 明确写着「不是生成列,必须显式写入」。 因此不能声明 Computed(...)——那会让 SQLAlchemy 把它从 INSERT 中排除,反而永远写不进去。
  4. 附带发现(建议底座侧修正): docs/00-新数据库基线设计.md 第 783 行把该列描述为 「生成列」,与 docs/02/alembic 基线 DDL 及真实库不一致。本次未改动 docs/00, 仅在此登记,请底座侧决定以哪一侧为准。

请求确认: 上述三点是否按「修缺陷」接受。

C4. Milvus 双地址与部署约束(app/core/config.py + app/service/health_service.py)

  • 新增 milvus_local_uri(默认空串)与 resolved_milvus_uri = milvus_local_uri or milvus_uri;
  • health_service.py 的健康检查改用 resolved_milvus_uri。

约束(请一并确认并写入环境规范):

  • 团队/生产环境的 .env 必须留空 MILVUS_LOCAL_URI,否则健康检查与部分检索链路会指向 本地 Milvus Lite 文件,出现「健康检查正常、实际查的是另一个库」的隐性偏差;
  • .env 中默认值为空串,默认行为与改动前完全一致。

五、D 类:本次已从 ZSY 侧移除、不进入集成分支的内容

为避免把违反底座规则的内容带进集成分支,以下内容已在本分支删除:

内容 原因
app/service/knowledge_tool_service.py 生产死代码(全仓唯一引用是它自己的单测)。生产路径是 bootstrap.get_knowledge_search_service() → KnowledgeSearchService
app/infrastructure/milvus_knowledge_adapter.py 违反 AGENTS.md §E:硬编码 knowledge_id/snippet/tags 等 Milvus 字段名,会打挂字段名不同的环境。且仅被上面那个死模块引用
tests/unit/service/test_knowledge_tool_service.py、tests/unit/infrastructure/test_milvus_knowledge_adapter.py 上述两模块的单测
tests/unit/service/test_knowledge_retrieval.py 依赖已移除的 legacy 位置参数构造
app/service/knowledge_retrieval_service.py 的 legacy 双构造与 _legacy_search 已整文件回退为底座版本,消除「同一服务两套构造语义 + 两套检索实现」的技术债

检索仍统一走底座既有链路:ToolExecutor → knowledge_search_tool → KnowledgeSearchService → app/core/knowledge_schema.py 的 detect_schema() 运行时字段探测,无任何硬编码字段名。


六、E 类:明确未改动的底座边界

  • docs/00、docs/02 的表结构与字段语义:未改动;
  • alembic/ 迁移脚本:未改动;
  • Milvus 字段名:无硬编码,全部走运行时探测;
  • docs/05-接口文档.md 的既有章节编号:§8.1–§8.4 全部保持原编号,客服二期新增的 「客服画像候选」登记为 §8.5(不占用既有号段),另有 §9.7 追加;原有交叉引用 「§8.3 知识库管理三端点」「§8.4 公共只读工具索引」仍然成立;
  • 其他业务 Agent、场外/推广/风控域:未改动行为契约。

七、F 类:需要业务方在环境侧确认的既有约束(非本次引入)

  1. config_release 是环境数据、不随代码合并:换环境需重新发布客服工具白名单。
  2. Milvus 集合 schema 因环境而异,检索层已运行时探测,任何新增代码都不得硬编码字段名。
  3. 本地 Milvus Lite 仅用于本地开发;团队环境应使用受管 Milvus 并留空 MILVUS_LOCAL_URI。