评审意见逐条落地(详见文档新增的 §0 对照表): - §1.1/§1.2/§4:确认两台机器连的**不是同一套 MySQL/Milvus**(我方 config_release 总共 4 条、 最高 216;架构师侧 201 + 9 条白名单),据此把"216 已在共享库生效"整体改写为 "**我方环境**已发布,你那台需补发";补发由架构师做(配置属环境数据,不随代码合并) - §1.3:字段映射已改为运行时探测(见上一提交),文档里的 A/B/C 三选一整体替换为探测方案说明 - §1.4:mypy 那条改写——查清主因是**本机缺 SQLAlchemy 2.0 类型信息**(装 sqlalchemy2-stubs 181→43,卸载回 184),明确"本机数字不可作为质量结论、两边不可比";我文件里的 8 个真实错误已修 - §2:明确 docs/26 是**重命名**(原 21,因 21 已被风控迁移清单占用),不是新增、不会并存 - §3.1:审计留痕已补(agent_type + governance_rewrite) - §3.3:5 份文档删除**已撤回**(上一提交) - §5/§7:更新验证数字(1218 passed)、两个环境相关失败的证据、memory_sync_outbox 双环境对照表 另修一处**同事那条线带入的重号**:docs/15-金融NL2SQL工具接入说明.md 与既有 docs/15-Agent组员详细开发与使用手册.md 撞号 → 新那份让号到 docs/27 (依据:手册被 docs/16、docs/17、AGENTS.md 三处引用,改名代价更大)。守卫恢复通过(32 份)。
29 KiB
交付说明 · 客服 Agent + RAG + 画像(NL_develop → qyqy_develop)
收件人:架构师(
qyqy_develop维护者) 来源分支:NL_develop合并目标:qyqy_develop基线:本分支已包含qyqy_develop的3f7c5ca(含你与同事各自的最新推送,落后 0) 一句话:以你已有的客服实现为骨架,把本线独有的画像问答出口、知识库文档管理三端点、 合规语境豁免嫁接进去;按你的评审意见把检索字段名改为运行时探测; 并修掉合并过程中暴露的多个"单测全绿但真机必挂"的问题。📌 本文档是给评审者看的,与给接手开发的
docs/superpowers/handoff/2026-09-11-交接文档-客服Agent与RAG收尾.md定位不同:那份讲"怎么继续开发",这份讲"动了你什么、为什么、要不要你点头"。
0. 第二次修订:评审意见的落实情况(2026-09-11 晚)
你那份《评审意见》里的每一条我都核对过实测证据,除 §3.3 我照你的要求撤回之外,其余全部采纳。
| 你的意见 | 我的处理 | 落地位置 |
|---|---|---|
| §1.1 我说的 active 216 在你那边不存在 | ✅ 你是对的。我这边 config_release 总共只有 4 条(最高 id=216),你那台有 201/198/197… 与 9 条 agent_tools 白名单 —— 两台机器连的不是同一套 MySQL/Milvus。已把"216 已在共享库生效"整体改写为"我方环境已发布,你那台需在合并后补发" |
§4.9 |
§1.2 合并后画像出口会 AGENT_PERMISSION_DENIED |
✅ 采纳。customer_service:faq 必须补 query_customer_profile。你已提出"我这边可以出脚本"——接受,由你来发(config_release 是环境数据,不随代码合并) |
§4.9 |
| §1.3 字段映射不是 A/B/C,应改运行时探测 | ✅ 已按你的方案实现:新增 app/core/knowledge_schema.py,describe_collection 拿真实字段名建映射、按集合缓存;visibility 有才过滤;缺必需字段的集合明确判为不可用。两套 schema 各有单测(任何回退到硬编码都会让其中一侧红) |
§4.2 |
| §1.4 解释器不统一、mypy 数字不可比 | ✅ 你是对的,而且我查到了根因:本机 mypy app 报 181/184 个错的主因是缺 SQLAlchemy 2.0 类型信息(装上 sqlalchemy2-stubs 后 181→43,卸载回 184)。这个数字双方不可比,我不再拿它当结论;我文件里的 8 个真实错误已单独修掉 |
§5 |
§2 docs/26 会和 docs/21 重复 |
⚠️ 核对后是同名重命名而非并存:你那台的 docs/21-JWT密钥管理与轮换.md 与我这台的 docs/26-… 是同一份内容,我这边 21 已被你的《风控业务第二版迁移清单》占用,所以只能让号。合并后是一次 rename(删 21、加 26),不会出现两份同主题文档 |
§2 末 |
§3.1 agent_type 同意,但要写进审计 |
✅ 已加:interaction_audit.detail 增 agent_type + governance_rewrite(不改表结构,detail 是 JSON 列);真机已验证最新审计行含这两个键 |
§4.1 |
| §3.3 驳回删除 5 份文档 | ✅ 撤回,5 份已全部恢复(git show 从你分支取回,逐字节相同)。AGENTS.md 改为"保留但仅作历史参考"并入 D 类 |
§1 第 3 项 |
§4 memory_sync_outbox |
⚠️ 两台的结论不同,我这边更"进一步":我方有生产者(profile_repository.py:142)、表里已有 2 行待处理,但消费端从未被实例化(ProjectionReconciliationService( 全仓无调用点);你说的 GraphProjectionWorker 无实例化点在我这边同样成立。同一类问题:组件写好了、线没接。归属待定,见 §7 |
§7 |
| §5 合并顺序 | ✅ 按你的顺序:先对齐环境口径 → 改字段探测 → 撤回删除项 → 合代码 → 补发配置(你来) | 全文 |
一句话总结这次核对:不是谁配错了,而是两台机器各自有独立的 MySQL + Milvus。 由此推出的第一条纪律:"配置已发布""数据是某 schema"这类结论必须带环境限定, 否则每次合并都要重吵一遍——这正是你 §1.4 想避免的事。
1. 请你重点看的四件事(都在 §4 有逐条说明)
| # | 事项 | 状态 |
|---|---|---|
| 1 | AgentGovernance.review() 新增可选 agent_type |
你已同意;审计留痕已按你要求补上(§4.1) |
| 2 | 检索字段名改为运行时探测 | ✅ 已按你的 §1.3 实现,替换掉原先的硬编码映射(§4.2) |
| 3 | ✅ 已撤回,5 份全部恢复(§3.3 你驳回) | |
| 4 | docs/26-JWT密钥管理与轮换.md |
是重命名(原 21,因 21 被你占用),非新增(§2 末) |
2. 净差异总量(相对 qyqy_develop 的 d2cdbba)
93 项:新增 51 / 修改 35 / 删除 6 / 重命名 1
新增的 51 项里包含本文档自身(
docs/交付说明-NL_develop-给架构师.md); 本说明写作时的数字是 92 项/新增 50,加入本文后为 93/51。
| 类别 | 数量 | 说明 |
|---|---|---|
新增 app/ 模块 |
16 | 画像生成与投影、知识入库/检索/管理、Milvus 读写适配、文档解析与落盘、合规语境 |
新增 tests/ |
17 | 与服务一一对应;另有 1 个 MySQL 集成测试 |
新增 tools/ |
5 | 知识集合建表、种子导入、画像演示数据、合规种子、QA 素材解析 |
| 新增文档 | 14 | 交接文档、工作报告、本交付说明、验收证据(从被 gitignore 的 .superpowers/ 复制)、ARCHIVE 归档、设计 spec |
| 修改 | 35 | 其中 7 个是你的核心文件(见 §4) |
| 删除 | 6 | 5 份编号文档 + 1 份过程产物(见 §1.3) |
未新增任何数据库表、未新增迁移:fin_knowledge_meta 等本就在 docs/00 基线内,本次只补 ORM 映射。
.venv\Scripts\python.exe tools\audit_schema.py → 51 business tables, no missing or unexpected tables。
3. 本线交付了什么(按功能,附真机证据)
3.1 画像问答出口(你的实现里没有这个出口)
- 新增
app/service/customer_profile_service.py:query_customer_profile只读工具。 权限memory:read:self;作用域校验self/own_customers/all;审计memory.profile_read;fields参数拒绝任何 PII 字段;快照缺失/为空失败关闭(不返回空对象假装成功)。 - 新增
app/core/profile_projection.py:画像字段白名单投影,PII 全剔除,assessment_expired重算。 - 新增
app/service/profile_generation_service.py+app/repository/profile_repository.py: 一次 MySQL 事务内 新快照 + 2 条同步事件 + 旧快照is_current置 0(符合docs/00§6.4.6)。 - 修掉
app/service/public_platform_service.py的memory()恒返回{}静默故障 → 现返回投影。 - 在
customer_service.py中新增出口零:is_profile_question()确定性关键词识别(不经意图分类), 命中即查本人权威字段;失败关闭为转人工。
真机证据:
客户 9101(C5)→ succeeded 「您的风险测评等级是 进取型(C5)。」
客户 9001(测评过期)→ succeeded 「…保守型(C1)。注意:您的风险测评已过有效期,需要重新完成测评…」
规则类问题「风险等级怎么划分」→ 未被画像分支截走,走知识检索
跨客户读取 → GenericResourceNotFoundError: 客户不可访问
3.2 知识库文档管理三端点(老师验收标准第 7 条)
app/api/controllers/knowledge_management.py + app/service/knowledge_management_service.py
POST /api/v1/knowledge/upload → 201(切分 → 逐块写 fin_knowledge_meta → 投向量同步事件)
GET /api/v1/knowledge/list → 200(只返 content_preview 前 200 字,不做正文旁路)
DELETE /api/v1/knowledge/{id} → 200(status='expired' + 投向量删除事件;不存在 → 404)
真机证据(含向量的真实进出,不只是返回码):
客户 9001 上传 → 403 ✅ 权限隔离正确
管理员上传 → 201 ids=['369']
消费同步事件 → Milvus 出现 ✅
列表 → 200 命中本次上传 1 项 ✅
删除 → 200 {"status":"expired","vector_delete_event":"knowledge.vector_delete_requested"}
消费删除事件 → Milvus 向量消失(轮询 2s)✅
不存在 id → 404 ✅
📌 路径口径:老师草稿写的是
POST /api/knowledge/upload(无/v1),实现为/api/v1/knowledge/upload。docs/05§8.3 与 §19 目录(K002/K003/K004)均以带/v1的路径为权威。
3.3 合规语境豁免(恢复政策问答)
app/core/compliance_context.py(新增)+ app/service/agent/governance.py(改)
问题:零容忍词库是朴素子串匹配,它分不清"作出承诺"与"禁止承诺/谈论该表述"。 政策原文里含「严禁承诺保本保收益」「禁止使用『保证收益』」时,平台会用自己的规则拦下自己的合规教材 —— 实测「基金销售有哪些合规要求」的回答从 1097 字被替换成 83 字的"该内容需要人工核实"。
修法:按句界限定窗口(12 字符)的否定/元语言线索豁免。第一版没限句界,
把 严禁承诺保本。但这只基金保本 错误豁免了 —— 已收紧为句内才认,并有 17 条单测锁定。
3.4 知识向量链路(入库 → 同步 → 检索)
app/service/document_parser.py(txt/md/docx,512 字符切块 / 64 重叠)app/service/knowledge_ingest_service.py→ 写fin_knowledge_meta+ 投knowledge.vector_sync_requestedapp/worker/knowledge_vector_worker.py→ 消费事件 →MilvusKnowledgeWriter写 Milvusapp/service/knowledge_retrieval_service.py→ 读路径(Milvus 失败降级 MySQL LIKE,并如实标degraded)- 读写物理隔离(写适配器与召回客户端不共用连接)
顺带修掉的 4 个真机静默故障(都是"单测绿、真机挂"):
| # | 位置 | 缺陷 | 原后果 |
|---|---|---|---|
| 1 | milvus_knowledge_writer.py |
写字段名 vector,集合 schema 是 embedding |
所有向量写入失败 |
| 2 | knowledge_vector_worker.py |
Milvus VARCHAR 上限是 UTF-8 字节,未按字节截断 | title 346 字节 > 256 → 整批失败 |
| 3 | 同上 | 乱序到达的旧同步事件会把已删向量复活 | 已删知识又出现在检索结果 |
| 4 | knowledge_tool.py |
async with _session_factory() 少一层调用 |
工具 100% 抛错 |
4. 我对你的代码做的修改(逐文件说明)
4.1 app/service/agent/base.py(+6 −1)⚠️ 公共契约
# 原来
result = await governance.review(result, context, config, memories)
# 现在
result = await governance.review(
result, context, config, memories, agent_type=self.definition.agent_type
)
理由:门禁 F5(面向客户输出 100% 附固定话术)只该对面向客户的 Agent 生效。
你的风控 Agent 输出是字段化摘要(预警编号/级别/建议动作),被追加一句面向投资者的免责声明后,
tests/contract/test_risk_agent_contract.py 直接失败(实测)。agent_type 从定义取最可靠
(不需要查库、与发布配置无关)。
协议同步(governance.py):AgentGovernance.review 与 PlatformGovernance.review 均新增
关键字参数 agent_type: str = "",带默认值,所以旧的调用点不会 TypeError。
判定口径是确认式白名单:只有 CUSTOMER_FACING_AGENT_TYPES = {customer_service, fund_query_demo}
才注入;空串(未声明)不注入——理由见代码注释(测试替身刻意不连库,若默认注入则每个替身测试
都会被塞进话术,用测试噪声换假安全感)。
受影响的测试替身已同步更新(5 处):tests/conftest.py、tests/contract/test_fund_query_demo_agent_contract.py、
tests/contract/test_risk_agent_contract.py、tests/unit/service/test_agent_governance.py
(test_risk_agent_contract.py 里那个 StubGovernance 也补了转发 agent_type)。
4.2 app/service/knowledge_search_service.py(+79 −47)⚠️ 需你裁决
现象:合并后你的 search_knowledge 在我这台环境零召回且整条链路失败 —— Milvus 报
field doc_id not exist / field visibility not exist,三个集合全失败 → degraded=True →
客服对所有知识问题一律"引导人工"(实测连「基金申购后多久确认」都 failed)。
根因:两台机器的集合 schema 不同(这正是你评审 §1.3 指出的核心事实,我实测确认):
我这台(describe_collection 实测) |
你那台(你实测) | |
|---|---|---|
| 标识字段 | knowledge_id |
doc_id(主键) |
| 正文 | snippet |
content |
| 可见性 | 无 | visibility |
| 来源/章节 | 无 | source_file / chapter / section / doc_no |
| 行数 | 106 / 177 / 73 | 125 / 297 / 214 |
所以"改读取侧字段名"这个方向本身是错的 —— 无论改成哪一套,都会把另一套打挂。 采纳你的方案(运行时探测),已实现:
# app/core/knowledge_schema.py(新增)
FIELD_CANDIDATES = { # 逻辑名 → 该字段在各环境里可能的物理名(按优先级)
"doc_id": ("doc_id", "knowledge_id"),
"content": ("content", "snippet"),
"visibility": ("visibility",), # 可选:有就过滤,没有就跳过
"source_file": ("source_file",), # 同上(章节/编号同理)
...
}
REQUIRED_LOGICAL_FIELDS = ("doc_id", "content") # 缺这两个 ⇒ 该集合判为不可用
# app/service/knowledge_search_service.py(改造)
schemas = {c: self._schema_for(client, c) for c in targets} # 逐集合探测,按集合缓存
expression = self._visibility_filter(schemas, include_internal) # 有 visibility 才拼
raw = client.search(..., output_fields=list(schema.output_fields)) # 只请求存在的字段
代价与边界(如实说明):
visibility缺失的集合没有检索层内部资料隔离(我方 356 行均为对外知识,已核对); 你那台有该字段,过滤照常生效——所以这条能力不是被关掉,而是"按环境自动启用"。- 既无
doc_id又无knowledge_id(或既无content又无snippet)的集合会被明确判为 不可用并记degraded=True,不静默零召回——这是刻意的:静默零召回最难定位。
测试:新增 17 个探测单测;并把你那三个关键词召回用例参数化为两套 schema 各跑一遍
(tests/unit/service/test_knowledge_keyword_recall.py 的 SCHEMAS)。
任何回退到硬编码字段名的改动,都会让其中一侧立刻变红。
4.3 app/service/agent/implementations/customer_service.py(+137 −9)⚠️ 你的骨架 + 我的出口
保留你的全部实现(三档置信阈值、适当性裁决、闲聊、话题矩阵、_topic_of/_search_query/
_suitability_text 等方法一字未改——你的 3 个测试文件全绿即为证)。
新增:
- 出口零:画像问答(
handle()最前面加一次is_profile_question()判定); allowed_tools增加query_customer_profile(代码上限);- 删掉 Agent 自己拼的
DISCLAIMER常量及 3 处f"...\n{DISCLAIMER}"—— 见 §4.5。
PROFILE_WHITELIST_INTENT = INTENT_FAQ:画像工具调用复用已发布的faq意图 key。 换新意图码会让allowed_tools_by_intent缺 key → 交集为空 →AGENT_PERMISSION_DENIED。
4.4 app/service/model_gateway.py(+53 −35)⚠️ 我改了你的映射表
你的版本把 intent_classification 映射成同名的 intent_classification;现库没有任何端点声明该能力
(实测 embedding-primary=["embedding"]、chat-primary=["chat"])⇒ 筛选得空集,靠你新加的
"空集 → 回退全部端点"才不至于失败。我改为映射到 chat(意图分类走 /chat/completions)。
同时并入你新增的 5 个风控 task_type,与我的映射合并成同一张表(REQUIRED_CAPABILITY_BY_TASK_TYPE,
TASK_CAPABILITY 保留为别名指向它 —— 两个名字不要各存一份内容,那正是"修复被后续合并悄悄回退"的成因)。
你新加的"未登记 task_type 要告警留痕"我保留了(并补上了被你删掉的 logger 定义)。
4.5 app/service/agent/governance.py(+141 −5)
| 改动 | 说明 |
|---|---|
| 语境豁免 | _first_violation 走 app/core/compliance_context.py,见 §3.3 |
| 客服热线白名单 | CUSTOMER_SERVICE_HOTLINE = "15936583816" 不再被脱敏成 [手机号已脱敏](实测:客户拿不到联系方式) |
| 免责声明限定范围 | agent_type 判定,见 §4.1 |
| 免责声明重复的修复 | 见下 |
免责声明曾出现两条(Agent 自己拼一句 + 治理层追加权威话术):
## 第三章 客户风险等级划分
(以上内容由智能客服依据公司公开资料整理,不构成投资建议) ← Agent 拼的
本内容仅为投资分析参考,不构成任何直接投资建议… ← 治理层追加的
修法:话术只由治理层注入。理由:合规文案属发布配置,改文案不该改代码;
且治理层无法判断"业务是不是已经加过了"(它只认自己追加过的形状)。
副作用:customer_service.py 的 DISCLAIMER 常量被删除 → 你的 test_customer_service_topic_matrix.py
原本 from ...customer_service import DISCLAIMER,已改为从 governance 取 FALLBACK_DISCLAIMER
(该测试只用它拼"治理后"的正文形状,断言对象是 _topic_of,语义不变)。
4.6 app/service/agent/bootstrap.py(+40 −0)
- 补回
get_milvus_knowledge_writer()(知识向量写适配器装配入口;我的 Worker 依赖它, 返回None表示显式降级 —— 语义与你的projection_cleaner一致)。 - 注册
query_customer_profile工具(required_permission="memory:read:self")。
你新增的平台验证探针(PlatformProbeAgent + 两个探针工具)全部保留,与我的改动无交集。
4.7 app/worker/runtime.py(+50 −0)
- 新增知识向量同步的装配:
knowledge_writer/knowledge_embedder/knowledge_endpoint_resolver三个注入点 + 降级告警只打一次。你新增的relationships(图关系服务)保留,两段是并集。
4.8 其他被修改的你的文件(改动很小)
| 文件 | 改动 |
|---|---|
app/core/knowledge_contracts.py |
两条链路的契约并存:你的 KnowledgeSearchInput + 本线的 ALLOWED_COLLECTIONS/VECTOR_DIM/intent_for_qa_id/KnowledgeQuery/KnowledgeHit/KnowledgeSearchResult。合并时一度误删后者,导致 23 个测试模块收集失败,已恢复并在文件头注明"删任何一半前先看两份引用点" |
app/main.py |
挂载知识库管理路由(knowledge_management_router) |
tests/conftest.py |
替身 review 转发 agent_type |
tools/publish_customer_service_config.py |
见 §4.9 |
tests/unit/service/test_knowledge_keyword_recall.py |
替身字段名改成现库 schema(否则测试假绿:业务读到空 snippet 静默丢弃,断言又只查 doc_id) |
4.9 配置发布(这是运行期必须的一步,请留意)
工具白名单是失败关闭的:ToolExecutor 取「代码 allowed_tools ∩ 发布配置
agent_tools/<agent>:<intent>」的交集,缺配置时交集为空 ⇒ 任何工具调用都被拒。
⚠️ 首先纠正我上一版的错误表述:config_release 是环境数据,不随代码合并。
我上一版写"216 已在共享库生效"是错的——你那台根本没有 216(你实测最高 201),
两台机器各自有独立的 config_release 表。下面这张表只描述我方环境:
| 环境 | 生效版本 | customer_service:faq 白名单 |
|---|---|---|
| 我方(我发布的) | id=216(我发的) | [search_knowledge, query_customer_profile] ✅ 画像出口可用 |
| 你方(你维护的) | id=201(你发的) | [search_knowledge] ❌ 缺 query_customer_profile |
⇒ 合并后你那台必须补发一版,把 customer_service:faq 改成
[search_knowledge, query_customer_profile],其余 8 条原样继承
(config_release 是整版本替换,漏带会清空别人的白名单)。
这一步由你来发——你已在评审里提出"我这边可以出脚本",我接受:配置属环境数据,
谁的环境谁发布,代码合并不该携带它。
发布脚本的一个坑(与我方无关,但你会踩到):tools/publish_customer_service_config.py
会把当前生效版本的配置项原样搬进新版本,而同 key 的继承项必须被本次新定义覆盖——
否则旧值(例如已从代码上限移除的 query_knowledge)会被 admin 端的子集校验 422 拦下,
整次发布失败,而报错只有"配置超出 Agent 工具上限",看不出是继承造成的。
我方已改为"同 key 覆盖"并打印被替换的旧值,这个改动随代码合并给你。
⚠️ 顺带:
fund_query_demo:fund_quote这条白名单在我方环境的生效版本里不存在 (我发布时"当前生效版本配置项"只打印出 1 条),而你那边 201 里是有的 —— 这又是两台环境不一致的证据。我方的FundQueryDemoAgent需要补发才能调用工具; 你那台不受影响。
5. 验证证据(均可复现)
# 测试(合并后基线)
.\.venv\Scripts\python.exe -m pytest -q
# → 3 failed, 1218 passed, 2 skipped
# 1 个是既有缺陷(test_fund_readonly_contract 的空集问题,与本线无关)
# 2 个是环境相关(§5.1 已说明:断言方式依赖 JSON 序列化配置,非代码缺陷)
# 结构审计(证明未动 docs/00 基线)
.\.venv\Scripts\python.exe tools\audit_schema.py
# → schema audit passed: 51 business tables, no missing or unexpected tables
# 文档守卫(编号无冲突)
.\.venv\Scripts\python.exe tools\check_authoritative_docs.py
# → checked 32 documents, no number collision
# 顺带修了一处**同事那条线带入的重号**:`docs/15-金融NL2SQL工具接入说明.md` 与既有
# `docs/15-Agent组员详细开发与使用手册.md` 撞号 → 新的那份让号到 `docs/27`(详见 §6)
5.1 两个环境相关失败(不是代码缺陷)
tests/unit/service/test_offsite_document_recognition_adapter.py 的 2 个用例断言
请求体里是中文原文("产品代码".encode() in requests[1].content),
而本机 httpx 把中文序列化成 \uXXXX,字节序列自然不匹配。
判定它既不是代码缺陷、也不是我引入的,有两条硬证据:
① 该测试文件与我合并的分支 origin/qyqy_develop 逐字节相同(git diff 无输出);
② 本机 .pytest_cache 的 lastfailed 里早已记录这两个用例(合并前的运行结果)。
功能无影响(OCR/LLM 请求本身正常)。建议改为断言 json.loads(body) 后的字段值——
比字节级断言稳,也不受序列化配置影响。
5.2 mypy:这个数字不可比,我不拿它当结论(采纳你 §1.4)
你那边 mypy app 是 138 文件 0 错;我这边同一份代码报 184 个错。
根因不是代码质量差异,而是本机缺 SQLAlchemy 2.0 的类型信息:
本机(无存根) mypy app → 184 errors
装 sqlalchemy2-stubs mypy app → 43 errors ← 该类存根是 2.0 之前的旧包,
还会换一批新错(mapped_column/DeclarativeBase 不存在)
卸载后 mypy app → 184 errors
结论:本机 mypy 基线不可作为质量结论,两边也不可比。 但那 184 里有 8 个是我文件里的真实错误,已单独修掉:
| 文件 | 错数 | 处理 |
|---|---|---|
app/service/knowledge_retrieval_service.py |
4 | ✅ 已修 |
app/api/controllers/knowledge_management.py |
3 | ✅ 已修 |
app/service/model_gateway.py |
2 | ⏸ 未动:ModelEndpointConfig 实际具备协议要求的全部字段,属 Mapped[T] 在缺存根时的消解问题,不用 cast 掩盖 |
app/worker/runtime.py |
1 | ⏸ 未动:同类问题 |
| 其余 ~174 | — | 全在 app/model/*.py 与既有文件,属本机缺存根所致 |
若希望两边数字可比,需要固定 mypy 依赖版本或把"缺存根"写进已知限制 —— 属公共约定, 我没有擅自改
pyproject.toml的 mypy 配置。
真机链路(真实 MySQL / Redis / Milvus / DashScope / HTTP,非单测替身):
| 场景 | 结果 |
|---|---|
| 知识问答「基金申购后多久确认」 | succeeded,免责声明仅 1 条 |
| 知识问答「风险等级怎么划分」 | succeeded(政策集合真实命中) |
| 画像问答 9101 / 9001(测评过期) | succeeded,过期被明说 |
| 知识库三端点 | 403 / 201 / 200 / 200+expired / 404 全绿 |
| 跨客户读画像 | 被拒(客户不可访问) |
6. 需要你裁决 / 知晓的事项汇总
AgentGovernance.review()新增agent_type参数 —— 你已同意;审计留痕已按你要求补上 (§4.1)。若你更希望走别的判定途径(例如让 Agent 自己声明customer_facing属性),告诉我,我改。- 检索字段名 —— ✅ 已按你 §1.3 改为运行时探测,不再是"三选一"(§4.2)。
删除 5 份编号文档—— ✅ 已撤回,5 份全部恢复(你 §3.3 驳回)。docs/26-JWT密钥管理与轮换.md—— 是重命名(原docs/21,因21已被你的《风控业务 第二版迁移清单》占用),不是新增、也不会与docs/21并存。config_release是环境数据 —— 我方已发 216 且仅对我方环境有效;你那台需在合并后 补发(把query_customer_profile加进customer_service:faq)。这一步你说你来出脚本,我接受。fund_query_demo:fund_quote白名单 —— 在我方环境缺失(你那边 201 里有)。属环境差异, 我方需补发;你那台不受影响。- 同事那条线带入的文档重号 ——
docs/15-金融NL2SQL工具接入说明.md与既有docs/15-Agent组员详细开发与使用手册.md撞号,我把新的那份让号到docs/27(依据:15-…手册被docs/16/17与AGENTS.md三处引用,改名代价更大)。 若你认为该由旧的那份让号,我改回来。 - 同事那条线带入 11 个 alembic 迁移,我方已执行
alembic upgrade heads建出offsite_*/promotion_*等表(本库此前一张都没有,而alembic_version却已指向 同事的 revision —— 属"版本号跑了但表没建"的状态)。你那台若也这样,合并后需补跑迁移。
7. 已知限制(未做,不是遗漏)
-
画像链路"生产端已接、消费端未接" —— 与你 §4 的发现同源但不同表现,请一起裁决归属:
你那台(你 grep 的结论) 我这台(实测) MemorySyncOutbox生产者无 有: profile_repository.py:142表内数据 空 2 行待处理( MILVUS/NEO4J各 1)消费端 无 有服务定义( ProjectionReconciliationService)但全仓无实例化点GraphProjectionWorker无实例化点(你发现) 同样无实例化点(我复核一致) ⇒ 同一类问题:组件写好了、线没接。 我这台更进一步:事件已经写进表里、没人消费。 建议先定归属再动手(涉及
app/worker/与app/service/profile_*,跨你我两条线), 否则两边各接一根线会更乱。 -
mypy —— 见 §5.2:本机数字不可比(缺 SQLAlchemy 2.0 类型信息);我文件里的 8 个真实错误已修, 其余未动。没有擅自改 mypy 配置。
-
Redis 限流降级:容器以
--requirepass 123456启动而.env无密码 ⇒ 每次请求一条AuthenticationError堆栈、限流形同虚设(不阻断业务)。属本地环境配置,未擅自修改。 -
Docker Desktop 不常驻:它没运行时 Milvus 不可用(
dockerCLI 报连不上守护进程)。 我方已把这条写进AGENTS.md的环境口径。 -
5 份恢复的文档没有内容校对 ——
docs/04/06/10/13/99只做了"恢复",未逐字核对 其正确性(它们此前被判定为内容过期)。已在AGENTS.md的 D 类里标注"仅作历史参考", 但不排除其中仍有会误导读者的内容——若你要用它们,建议先过一遍。
本说明由 2026-09-11 的收尾会话产出;第二次修订在评审意见之后(见 §0)。
若你发现与代码不一致,以代码与 docs/05 为准。