Commit Graph
13 Commits
Author SHA1 Message Date
张胜宇 dc83f4f4a7 docs(W20): 定位「按我的风险等级能买什么」被 PROMOTION_REQUEST_PATTERNS 第4条误拦 + 五条待决登记(D1.6 4.48 / D2.1 v6.35 / D1.1 29) 2026-09-20 18:18:33 +08:00
张胜宇 172806ae36 docs(W19): D2.6 答辩报告同步演示前核验 + D1.6/D2.1 落档;修边界脚本自碰撞
一、D2.6 答辩报告(客服agent\D2.6)
* 新增 §6.4「演示前最后一次全量核验(W19)」:demo.ps1 五项自检全过(退出码 0)/
  pytest 1917 passed / portal_api_check 35 通过 0 失败 / e2e_smoke_test 31/31 /
  http_probe 11/11 / 边界 12/12 / _consistency 失效锚点 0 / check_authoritative_docs 54 无冲突 /
  /internal/health/ready 三依赖全绿;并记两条可当面演示的实证(画像题有数据可依、跨主体会话隔离)。
* §6.3 两行补 W19 复跑值;§9 新增两条教训(误删文件的清理判据、边界用例标识必须每次唯一);
  §10 新增两条已知边界(D-2 重复问句漂移 / D-4 英文落 E5b)并更正 M-2b 口径;
  §12 一页速览的数字更新为 1917;头部新增 W19 状态更新行。

二、脚本修复
* _fe_boundary_http.py:「session_id 恰好 64」原用固定串,第二次跑必然 404
  SESSION_NOT_ACCESSIBLE(访客令牌每次是新主体,会话号与主体绑定)⇒ 改为 64 字且每次唯一;
  该"误撞"同时固化为用例说明(跨主体会话隔离生效)。复跑 12/12。

三、落档
* D1.6 新增 §4.47 的「演示前全量核验」与「画像题真机复验」两行;D2.1 新增 v6.34 第 12/13 条。

四、门禁
* _consistency.py exit 0;tools/check_authoritative_docs.py 54 文档无编号冲突(exit 0)。
2026-09-20 18:00:37 +08:00
张胜宇 fc4351e219 docs(W19): 补登画像题真机复验(fin_customer_profile 6 行,H-03/D-04 由查不到档案变为有数据可依) 2026-09-20 17:54:43 +08:00
张胜宇 d5e813b726 feat(model-gateway)+docs(W19): embedding 端点唯一性配置守卫 + 三份完整版/收敛版索引口径补注 + 门槛口径更正 + D3.7 难例口径统一
一、代码(2 文件 + 2 工具脚本注记)
* app/service/model_gateway.py:DatabaseModelEndpointResolver.resolve() 加配置守卫
  —— required == "embedding" 且 len(matched) > 1 时 logger.warning(只告警、不改行为)。
  多个 embedding 端点会让索引向量与查询向量可能来自不同模型(维度同为 1024、不报错),
  COSINE 相似度整体失真,表现为"越答越差"的哑故障。顺手删掉重复的 return endpoints(死代码)。
* tests/unit/service/test_model_gateway.py:新增 2 条单测(多端点告警且返回顺序不变 / 单端点静默)。
* tools/configure_embedding_endpoint.py:加「已废弃,勿重跑」标注 —— 它写的是
  qwen-embedding / qwen3.7-text-embedding-flash,与现役端点 knowledge-embedding-qwen-v3 /
  text-embedding-v3 不一致,重跑会凭空多出一个 embedding 端点。
* tools/build_knowledge_chunks.py:删掉与新口径冲突的注释「不泄露档位与门槛」,
  改为「registered 的依据是权益明细而非门槛;门槛属公开宣传口径」。

二、文档(8 份;D-1 选乙 + D-3 统一为 18)
* D2.4 v1.6 → v1.7:§4.4 + 附录B 更正「门槛金额不再单独构成 registered 的理由」
  (public 的 FAQ-0014 已完整给出五档门槛、FAQ-0050 含钻石门槛);
  HNW-004—HNW-007 保持 registered,依据收窄为"各层级权益明细";HNW-* 档位不动(分区键)。
* D3.1 v2.5 → v2.6:§5.3 加索引口径落地注(覆盖 §2.5 决策表 / FR-CS-007 / 排期 T4)
  + 补「字段表同属初稿」(实库 18 字段全 NOT NULL、doc_id 主键、无 metadata JSON)。
* D3.2 v1.2 → v1.6:§4.1 加同口径注 + 版本位追平(顶栏 v1.1 / doc-meta v1.2 落后于自身记录 v1.5)。
* D2.2 v2.6 → v2.7:§1.4.2 域 B 加注(TopK / 阈值 / 度量 / 集合选择均未变 ⇒ 不影响验收)。
* D3.7:§3 难例口径统一 —— 难例 32 条(改写 8 + 口语 16 + 多轮 4 + 禁忌 4)为定义式总数,
  M-2b 分母 = 其中带期望证据家族的 18 条;并补正 §3 初稿表格条数(以 cases_46.json 为准)。
* D1.1 v1.8 → v1.9:新增 §28;四处版本位同步;顺带修正两处历史遗留
  (D2.4 版本位长期停在 v1.3、D2.2 日期列停在 2026-09-17)。
* D1.6:新增 §4.47(含自我失误留痕)。
* D2.1 v6.33 → v6.34:新增本轮修订要点段。

三、实测门口(本机)
* tests/unit/service/test_model_gateway.py:10 passed
* pytest -q -p no:cacheprovider(全量,跑前已停 Worker):1917 passed / 3 skipped / 0 failed
* tools/check_authoritative_docs.py:54 文档无编号冲突(exit 0)
* _consistency.py:失效锚点 0、交叉引用全 ✅(exit 0)
* _fe_boundary_http.py(重建件):12/12 符合预期
* 服务已重启:/internal/health/ready 三依赖全绿(mysql / redis / milvus)

四、如实留痕(自我失误)
本轮清理临时文件时删除判据过宽,误删 _consistency.py(已原样恢复)、
_legacy_customer_service.py(已按 f72a545 逐字节重建,40,554 字节)、
_fe_boundary_http.py(原件不可恢复,已按既有判据重建并实跑 12/12)与若干历史轮次原始日志。
详见 D1.6 §4.47 五。
2026-09-20 17:53:06 +08:00
张胜宇 44b57a56ce docs(D2.9): 补精确 G 组出口语义(P0/P1/P2 与 E5c)+ 两条判分别名说明 2026-09-20 17:32:16 +08:00
张胜宇 eb1822d802 docs(W18): D2.4 索引口径更正为 AUTOINDEX(v1.6)+ D2.9 手动对话测试用例成文 + 空白消息 500 修复
- D2.4 v1.3 -> v1.6:索引统一 AUTOINDEX(设计初稿 HNSW/IVF_FLAT 未落地,实库直查为据)
  更正 9 处 + 新增 §4.1 索引口径落地注;语料 628 -> 675 块并补 fin_basic_collection 说明
  (三集合仍是唯一默认检索面,basic 并入会使 M-1 100% -> 91.3%)
- 新增 客服agent/D2.9-客服Agent手动对话测试用例-2026-09-20.md:
  46 条金标逐条可问 + 11 条边界 Z 组 + 判分四问 + M-1~M-10 手动汇总 + 真 HTTP 核验配方
  实测登记 3 项缺口:空白消息 500(已修)/ 语料档位口径矛盾(待裁定)/ 重复问句漂移(待裁定)
- 修修复:message 纯空白 500 -> 422 AGENT_INPUT_INVALID(入口补判据 + 回归测试)
- tools/chat_console.py 提示语去掉已下线产品名(季季盈)
- 落档:D1.1 §27(60 -> 61 份 / 客服agent 8 -> 9 份 / 注入校验 56 -> 57)、D2.1 v6.33、D1.6 §4.46
- 门禁:check_authoritative_docs 通过、_consistency.py GATE PASS、pytest 1915 passed / 0 failed
2026-09-20 17:31:40 +08:00
张胜宇 921de2cfc3 docs(W17): 知识库 RAG 全链路与选型说明成文(D2.8)—— 按八阶段讲清解析/切片/检索增强 + 4 张流程图
新增 客服agent\D2.8-客服Agent知识库RAG全链路与选型说明-2026-09-20.md(域 2,D2.x 续号,683 行)。

- 按流程逐步:语料与解析 → 切片 → 向量化 → 存储 → 入库七步 → 在线八步 → 检索增强 7 个动作 → 阈值与五出口。
- 4 张 Mermaid 图:端到端全景 / 切片与派生字段 / 检索增强 / 出口决策树。
- 切片写透:叶子标题策略(对照三种真实情况)、表格逐行拆自解释小块(父子块)、表头 bug 与自检守卫。
- 检索增强 7 动作:向量召回 / 字面召回(专有名词,条件触发)/ 父块带回 ×0.9 / doc_id 去重 / 兄弟子块归并 / 整节块保底席位 / 证据包三种形态。
- 阈值取证:0.75/0.55/0.07/0.40/0.5,MIN_GAP 实测标定区间 (0.0649, 0.0759)。
- 选型原因:8 项决策 26 备选,逐项含否决理由与演进触发条件。
- 实测:切片件 675 块,Milvus 四集合 count(*) 150/191/288/46 与切片件逐集合一致,索引全 Finished。
- 新登记 3 项不一致(只登记不修复):① 文档写 HNSW/IVF_FLAT 而实库是 AUTOINDEX;② tools\configure_embedding_endpoint.py 会建出第二个 embedding 端点(重跑可能造成索引与查询不同模型的无声质量崩塌);③ agent_faq_synonym 表检索链路不读(术语归一化未落地)。
- 计数同步:D1.1 v1.6→v1.7,59→60 份(58→59 份编号),客服agent\ 7→8 份;§4.0 总表与 §4.1 明细各新增 D2.8 行;注入校验 55→56 份;新增 §26 轮次段。
- D2.1 标题 v6.31→v6.32;D1.6 新增 §4.45(含一处自我更正:误读旧 JSON 导致"实库缺 family_id/param_class/intent"的错误结论)。
- 本轮不改代码、未跑金标评测;门禁:check_authoritative_docs.py 通过 + _consistency.py GATE PASS。
2026-09-20 16:58:42 +08:00
张胜宇 bcedf71e12 docs(W16): 中长期记忆与画像联动设计成文(D2.7)—— 三问直答 / 五道闸门取证 / INV-M1~M6 / 废弃理由更正
新增 客服agent\D2.7-客服Agent中长期记忆与画像联动设计-2026-09-20.md(域 2,D2.x 续号)。

- 主设计主张:让记忆改变「系统行为」而非「模型输入」——记忆只作确定性信号(检索分区加权 / 澄清候选排序 / E2 计算入参 / 适当性过滤),永不进生成上下文(FR-CS-009 + FR-CS-049)。
- 新增记忆子域不变量 INV-M1~INV-M6(INV-M6:记忆只能收窄、不能放宽)。
- 登记两处过期理由:D2.2 §1.7 第 12 项 + 第 998 行澄清框仍引「投顾已整体清除」,而投顾已于 2026-09-20 恢复(D4.7)。
- 计数同步:D1.1 v1.5→v1.6,58→59 份(57→58 份编号),客服agent\ 6→7 份;§4.0 总表与 §4.1 明细各新增 D2.7 行;注入校验 54→55 份;新增 §25 轮次段。
- D2.1 标题 v6.30→v6.31(新增 v6.31 段);D1.6 新增 §4.44。
- 本轮不改代码、不改行为;门禁:check_authoritative_docs.py 通过(54 份无编号冲突)+ _consistency.py GATE PASS。
2026-09-20 16:31:29 +08:00
张胜宇 e28e1f3900 docs(W16): 落档「Agent 与用户画像关系 / 对话能否更新画像 / 中长期记忆」咨询轮 —— D2.1 v6.30 / D1.6 §4.43 / D1.1 §24 版本位 2026-09-20 16:25:44 +08:00
张胜宇 c3d57fbf3f feat(cs)+docs: 修掉 P1 错分「风险测评结果」—— 画像问答改由受控工具作答(W15)
背景(用户提问触发):
  §1.2.1「客户能看本人的持仓/交易/账户/画像与风评」与 §1.4.5 P1
  「账户与个人数据(含风险测评结果)Agent 无权限读取」读起来互相矛盾。

实测根因(两处):
  1) route_message() 在画像分支之前,且 P1_KEYWORDS 含裸词「风险测评结果」
     ⇒「我的风险等级是多少」走画像作答,
       「我的风险测评结果是什么」被降级成「无法读取本人账户数据」
       —— 同一诉求两种结论,属「能答而不答」(H-03 同类)。
  2) 画像词在前、账户词在后的混问法漏网
     (「我的风险测评结果和持仓一起给我」落 P3 ⇒ 只答画像、静默忽略账户诉求)。

依据(决定性):D2.2 §1.7 第 21 项「画像问答字段直返」;
  D3.1 §0.3 术语表「画像问答属客服能力,与持仓查询严格区分」。

代码:
  - app/core/customer_service_rules.py:P1_KEYWORDS 移除裸词 + 口径说明;
    P1_PATTERNS 新增混问法守卫(第一人称 + 画像词 + 并列连词 + 账户词)。
  - customer_service.py / profile_projection.py:补「投影层白名单 ⊇ 客服对话
    渲染集」口径(total_asset / behavior_score / risk_tags 刻意不陈述,
    渲染它们等于用画像工具绕过 P1)。

守卫:
  - test_customer_service_rules.py:RT-004 → None;新增 RT-004b → P1;
    SAFETY_CASES 由字面区间改显式名单(RT-004b 字母后缀会落区间外被静默漏掉)。
  - test_customer_service_agent.py:画像端到端 3 条 + 混问法反向守卫。

安全不降:答案只来自 query_customer_profile(self 作用域 + 字段白名单 + 工具
  审计),查不到失败关闭、绝不猜等级;P0/P2 未动、P1 其余字面未动;
  混问法仍走 P1;访客问画像仍引导登录。

文档:D2.2 v2.5→v2.6 / D3.1 v2.4→v2.5 / D2.6 更正 / D4.6 追加 §3(不改正文)
  / D1.1 §24 + 版本位 / D1.6 §4.41 修正误记 + §4.42 / D2.1 v6.29。

实测:pytest 1914 passed / 3 skipped / 0 failed(+5);ruff 20(无新债);
  check_authoritative_docs 54 文档无冲突;_consistency GATE PASS;
  http_probe 11/11;定向真机复验 9/9;portal_api_check 35/0/5;
  e2e_smoke 31/31;fe_boundary 12/12;demo.ps1 五项自检全过。
2026-09-20 16:22:02 +08:00
张胜宇 c91bbcbdc1 feat(ops)+docs: 密钥轮换工具 + 两份文档目录审计收口(D1.1 §23 / D2.1 v6.26)
一、密钥轮换(新增工具 + 操作手册)
- 新增 tools/rotate_api_keys.py:--check 体检 + 交互式轮换;getpass 不回显、
  自动备份 .env.bak-<时间戳>(已被 ignore 命中)、校验不过整体不写入、
  三个 Qwen 变量写同一值 / 两个 DeepSeek 变量写同一值。
  实测 --check:Qwen 三变量同值且非空、DeepSeek 两变量同值且非空。
- 新增 开发文档/D3.8-模型密钥轮换与凭据安全操作手册-2026-09-20.md(CS-OPS-2026-023):
  .env 5 个变量与读取方取证、五步流程、3 个坑、复核清单、回退方式、能力边界。
- 口径确认:model_endpoint_config.secret_ref 存变量名 ⇒ 轮换只改 .env,不动 DB;
  但必须重启 API + Worker。

二、门禁修复:docs/ 编号撞车
- tools/check_authoritative_docs.py(D3.4 N-14 登记的验收命令集之一)实测 FAIL:
  我方 docs/46 docs/47(2026-09-20 建)与投顾组 docs/46-投顾Agent需求文档.md
  docs/47-投顾Agent功能架构文档.md(2026-09-16 建)同号。
- 按「后到者让位」改名:docs/48-可改文件白名单.md / docs/49-底座会签申请单-2026-09-19.md,
  同步 8 处引用。修复后:checked 54 documents, no number collision,exit 0。

三、前端品牌残留(W12 合并静默回退)
- employee-advisor/dashboard/index.html 与 customer/advisor-plans/index.html 的
  <title> 仍是 南方财富(投顾组分支带回)→ 按 DEC-27 改为 南方基金。
- HTTP 实测两页标题已正确;全仓 app/ 复查 南方财富 = 0。

四、文档口径校准(12 处事实漂移)
- D1.1:D2.1 版本 v5.3 → v6.26(§4.0 / §4.1 / §1 / §2 四处长期错误);
  §8 四行遗留项闭合(D-5 / D-6 / D-7 / 仓库副本同步)+ 新增 §22 §23 留痕;
  §10.2「本区不在任何 git 仓库内」更正为已入库;新增两编号 ⇒ 计数 56 → 58 全量同步。
- D2.2:顶栏徽标 v2.4 与元数据 v2.5 自相矛盾 → 统一;「投顾已清除」→ 状态更新
  (模块 2026-09-20 已恢复,但客服范围裁定 §1.7 / RK-10 不变)。
- D2.3:徽标 v1.0 · 7 批次 51 项 → v1.1 · 8 批次 57 项;投顾清除后果 + §7.1 头号风险
  + 风险表 + 不触碰行全部加恢复口径。
- D2.4:v1.3 变更说明 ⑦ / §1.4 Out of scope / Q-09 加投顾恢复口径。
- D2.5:advisor_t 自相矛盾口径改写为账号表一行 + 口径更正;五项自检首选改为
  一键脚本 启动演示.bat / demo.ps1;补 D3.8 与未发布 advisor:* 白名单登记。
- D2.6:门禁数字 1856/2 → 1909/3 skipped、ruff 19 → 20、补 portal_api_check 行;
  §10 两项已闭环(密钥轮换已工具化、A-10 组 3/4 已补签);头部加 W12/W13 状态更新。
- D4.5:顶部状态更新补指向 D4.7。
- 新增 开发文档/D4.7-投顾模块恢复记录-2026-09-20.md(CS-PURGE-2026-014):
  时间线、8 项恢复动作、客服线不变的结论、DEC-19 理由更正、遗留 1 项、失误登记。
- _consistency.py(维护侧):§三 改为「投顾状态口径检查」,合法语境扩为
  清除史 / 恢复史 / 不属本 Agent 范围。

五、回归实测(全绿)
- pytest -q:1909 passed / 3 skipped / 0 failed
- ruff check app tools tests:20(与 W12 持平,未引入新债)
- mypy app:2(= 既有基线)
- tools/check_authoritative_docs.py:54 文档无编号冲突(exit 0)
- tools/e2e_smoke_test.py --read-only:31/31
- tools/portal_api_check.py:40 项 通过 35 / 失败 0 / 跳过 5
- _eval_harness/http_probe.py:11/11 succeeded
- _consistency.py:GATE PASS
- demo.ps1 -SkipStart -NoBrowser:五项自检全过、退出码 0
- 权威副本 ↔ 仓库:逐字节一致(客服agent 24 / 开发文档 52)

六、未做(如实登记)
- 投顾 config_release 工具白名单(advisor:*)仍未发布 ⇒ 投顾 Agent 工具调用 fail closed
  (实测 active_agent_tools 仅 customer_service:* 4 项 + risk:* 4 项)。与客服线无关;
  要演投顾线先跑 tools/publish_advisor_demo_config.py --apply。
- 两把 key 的实际轮换需你在控制台建新 key(无法代做),流程见 D3.8。
2026-09-20 15:27:07 +08:00
张胜宇 4306326a56 docs: 落档本轮(演示一键启动 + 权威文档入库 + 回归复跑)
- `开发文档/D1.6` 新增 **§4.38**:本轮指令原文、`demo.ps1`/`启动演示.bat` 的职责与实测结果、
  两个真实问题(PS 5.1 传参吞双引号 ⇒ 改走 stdin;终端乱码经复核是捕获侧假象)、
  **权威文档入库的关键判断**(仓库内是 2026-09-16 前的过期副本 + 旧文件名,少 49 份 ⇒
  按「权威覆盖过期」入库并复核零差异)、入库前密钥扫描结论、回归复跑全表、推送记录。
- `客服agent/D2.1` 升 **v6.25**:同上要点的执行看板口径,并写明「后续同步文档一律按
  权威副本 -> 仓库 单向覆盖」。
- 两份文件的仓库副本与权威副本**逐字节一致**(已复核)。

回归(入库后跑):pytest 1909 passed / 3 skipped / 0 failed;ruff 20;mypy app 2;
e2e_smoke 31/31;portal_api_check 40 项 35/0/5;http_probe 11/11;_consistency GATE PASS。
2026-09-20 15:09:12 +08:00
张胜宇 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