feat(merge): 完成 AL-09 合并接线,整合风控模块与宿主 Wave 0

- 合并 `risk-control-agent` 分支至 `merger`,实现 JWT 统一与模块 API 恢复。
- 更新 `auth_service` 和 `auth_adapter`,确保对外登录/token 统一。
- 增强 chat 模块,支持会话管理与流式对话(SSE)。
- 测试基线更新至 502 passed, 1 skipped,确保系统稳定性。

此更新标志着风控模块的成功集成,提升了系统的整体功能与可维护性。
This commit is contained in:
2026-09-08 20:00:39 +08:00
parent 6d780d45c3
commit f87e11f104
12 changed files with 100 additions and 80 deletions
+11 -7
View File
@@ -24,14 +24,18 @@
## 代码入口
```text
app/main.py # FastAPI:路由挂载 + trace/audit 中间件 + lifespan(风控 4 API + /api/simulate + /api/chat 四端点已挂载)
app/api/chat.py # 对话:POST ""(同步)+ GET /sessions + GET /sessions/{id}/messages + POST /sessions/{id}/close(方案 B)+ POST /stream(SSE 流式,方案 C)
app/api/deps.py # 鉴权工厂(T-01 JWT:Bearer 优先,dev debug 头兜底)+ 归属断言
app/service/auth_service.py # Auth SDK:JWT 验签/吊销(T-01);签发 CLI scripts/dev/issue_dev_token.py
app/service/agent_service.py # LangGraph StateGraph 骨架 + DeepSeek(T-07)
app/config/settings.py # 双库 jinrong_agent + jinrong_core + risk_* 阈值 + JWT 配置
app/repository/core_ro.py # Core 只读(已实现)
app/main.py # FastAPI:AL-09 已集成(宿主 TraceMiddleware + 模块 audit/trace + auth/chat/risk/simulate)
app/api/auth.py # Mock 登录;JWT 统一走 auth_service.issue_dev_token
app/api/auth_adapter.py # S2 接缝:module_auth_from_host(宿主 AuthContext → 模块 AuthContext)
app/api/chat.py # 对话:POST "" + sessions 三端点(B)+ POST /stream SSE(C)
app/api/deps.py # 模块鉴权工厂(Bearer 优先,dev debug 头兜底)+ 归属断言
app/gateway/ # 宿主 Wave 0 鉴权四件套(与 deps 双栈并存;模块禁止 import)
app/service/auth_service.py # Auth SDK:JWT 验签/吊销/签发
app/config/settings.py # 双库 + risk_* 阈值 + JWT(issuer/audience 统一)
app/repository/core_ro.py # Core 只读 + check_suitability(R-02)
scripts/core/reset.ps1 # 本地灌 Core 模拟库
```
**当前分支:** `merger` · **测试基线:** `python -m pytest` → 502 passed, 1 skipped
技术选型硬阀门见 MEMORY 第 3、7 节。Cursor 以 `.cursor/rules/project-memory.mdc` 为准。
+13 -10
View File
@@ -2,20 +2,23 @@
四个 Agent(客户财富 / 代理人助手 / 数据分析 / **风控监测**)共用统一数据层与合规底座;Agent 之间**不互调 LLM**,跨 Agent 协作走 L1/L2/L3 画像与预警表。
> **本分支(`risk-control-agent`)= 风控 Agent 模块的交付分支**。模块功能已全部交付(2026-09-07),合并 main 的事宜见《合并注意事项》一文,后续人员请按下表对号入座。
> **当前工作分支:`merger`**(2026-09-08 已完成 AL-09 合并接线:风控模块 + 宿主 Wave 0 共存)。历史交付分支 `risk-control-agent` 已冻结;合并记录见《合并注意事项》执行记录一节。
## 你是哪种后续人员?
| 角色 | 先读 |
| --- | --- |
| 接手模块开发 / 维护 | [交接文档.md](交接文档.md)(本地)→ [docs/memory/MEMORY.md](docs/memory/MEMORY.md) §0 → [docs/memory/TODO.md](docs/memory/TODO.md) |
| 负责把模块并入 main | [docs/项目框架设计/合并注意事项-风控模块并入main.md](docs/项目框架设计/合并注意事项-风控模块并入main.md)(自包含操作手册) |
| 新 Agent / 统筹开发 | [docs/memory/MEMORY.md](docs/memory/MEMORY.md) §0 → [docs/memory/TODO.md](docs/memory/TODO.md) |
| 搭公共 REST API / 前端 | [docs/项目管理/04-从需求到公共API开发方法.md](docs/项目管理/04-从需求到公共API开发方法.md) |
| 查阅 AL-09 合并记录 | [docs/项目框架设计/合并注意事项-风控模块并入main.md](docs/项目框架设计/合并注意事项-风控模块并入main.md)(§执行记录) |
| 了解需求 / 做方案评审 | [docs/PRD/PRD-风控监测Agent.md](docs/PRD/PRD-风控监测Agent.md)(v1.1)+ [附-风控规则表.md](docs/PRD/附-风控规则表.md) |
| 起环境跑演示 | [docs/项目框架设计/演示SOP-风控模块.md](docs/项目框架设计/演示SOP-风控模块.md) + 本页「快速启动」 |
## 模块交付状态(截至 2026-09-08)
## 项目状态(截至 2026-09-08)
**后端功能全部完成,全量 pytest 503 passed 0 failed(sqlite + 真 MySQL 集成),核心接口实调验收通过。**
**AL-09 合并接线完成**:JWT 统一 · 模块 chat/agent/memory 恢复 · auth_adapter 接缝 · **502 passed, 1 skipped**(`python -m pytest`)。核心接口实调此前已通过。
**下一步(统筹 P1):** Core 公共 API v0.1 · 接口契约发群 · 前端 `web/` init。
| 里程碑 tag | 内容 |
| --- | --- |
@@ -28,7 +31,7 @@
**前端接入面(2026-09-08 补齐,后端侧已齐)**:方案 B 会话管理三端点(`8328c24`)+ 方案 C SSE 流式对话(`01ec5fc`)。同步端点 `POST /api/chat` 契约不变,前端可任选同步/流式。详见下文「前端接入契约」。
**架构定位**:风控 Agent 为**独立封装模块**——模块内自带鉴权(`app/api/deps.py` + `app/service/auth_service.py`)、防护、trace、引擎工厂;与宿主的耦合只走 4 个接缝(挂载点 / AuthContext / settings / 引擎工厂),由 `tests/test_module_boundary.py` 防呆锁定。详见《[风控Agent模块边界与合并接缝标注.md](docs/项目框架设计/风控Agent模块边界与合并接缝标注.md)》。
**架构定位(AL-09 后):** 宿主 `app/gateway/` 与模块 `app/api/deps.py` **双栈并存**;对外登录/token **统一**(`/api/auth/login` → `issue_dev_token`);模块 API 禁止 import gateway。接缝 S2 用 `auth_adapter.module_auth_from_host`。详见《[风控Agent模块边界与合并接缝标注.md](docs/项目框架设计/风控Agent模块边界与合并接缝标注.md)》。
## 铁律(改码前必记)
@@ -43,7 +46,7 @@
```text
app/
├── api/ # 路由:chat、risk(4 API)、simulate、deps(JWT 鉴权工厂)、audit_middleware
├── api/ # auth、chat(含 sessions/stream)、risk(4 API)、simulate、deps、auth_adapter、audit_middleware
├── service/ # agent_service(LangGraph StateGraph)、risk/*(rules/engine/alert/aml/L3/C4~C6)、
│ # suitability、tool_service、auth_service、input_guard、RAG 三层
├── tool/ # core_tools(Core 只读 Tool)、kb_tools(知识库检索 Tool)
@@ -54,7 +57,7 @@ app/
└── utils/ # trace、authz、response(统一错误体)、db、exceptions
scripts/ # core 灌库、demo 演示数据、kb 知识库入库、cron 定时扫描、dev 签发 token
tests/ # 30+ 模块;_ddl.py 为 sqlite DDL 单一事实源;test_module_boundary.py 锁模块边界
tests/ # 36+ 模块;502 用例 1 skipped;test_module_boundary.py 锁模块边界
data/kb/ # 6 只种子产品手册(知识库语料)
```
@@ -72,7 +75,7 @@ cp .env.example .env # 填 MYSQL_PASSWORD / NEO4J_PASSWORD / DEEPSEEK_A
pip install -r requirements.txt
# 首次灌库与同步:见 docs/memory/FLOW.md §0(权威步骤)
uvicorn app.main:app --reload # → GET http://127.0.0.1:8000/health
python -m pytest # 基线 503 用例(系统 Python)
python -m pytest # 基线 502 passed, 1 skipped(系统 Python 3.13.14)
```
**演示库重灌(走查/集成测试前必做,两步缺一不可)**:
@@ -149,9 +152,9 @@ curl "http://127.0.0.1:8000/api/chat/sessions/<sid>/messages?limit=50&offset=0"
| [docs/memory/](docs/memory/) | 项目记忆六件套(MEMORY/TODO/REQUIREMENTS/FRAMEWORK/FLOW/ENVIRONMENT),入口为 MEMORY.md §0 |
| [docs/PRD/](docs/PRD/) | 风控 PRD v1.1(§4A = 追加需求)+ 风控规则表 |
| [docs/项目框架设计/](docs/项目框架设计/) | 架构设计 · 开发计划 · 实现方案 C4~C6 · 表设计(SQL 单一事实源)· 技术选型与 JWT 手册 · Core 模拟底座 · 演示 SOP · 边界标注 · **合并注意事项** |
| [docs/项目管理/](docs/项目管理/) | 项目计划 · **04 开发方法**(需求→API 主线)· 表设计字典 |
| [docs/需求拆解/](docs/需求拆解/) | 业务场景优先级、数据交互矩阵、合规约束、四角色用户故事(docx) |
| [docs/业务记忆管理/](docs/业务记忆管理/) | 业务记忆分层手册 |
| [交接文档.md](交接文档.md) | 模块开发交接(本地保留,不入库) |
## 前端
+1 -1
View File
@@ -25,7 +25,7 @@
- **内部分析**:SQL 或 IT 导表。
- **风控**:事后/T+1 发现异常;适当性靠交易前规则;AML 批处理或人工。
Agent **尚未上线**;后端风控事件线 + 对话线 + 知识库已实现(`risk-control-agent` 分支,B1~B9b + 阶段 C + T-03/T-21 + **阶段一对齐 main 基准 AL-01~08**,406 测试绿),其余 Agent 仍为脚手架;无生产接入。
Agent **尚未上线**;后端风控全链路 + Wave 0 共用底座已在 **`merger` 分支**集成(AL-09 完成,502 pytest 绿):事件线 B1~B9b · 对话线 C1~C6 · 知识库 T-21 · chat sessions/stream;客户/代理人/分析 Agent 仍为 chat 骨架,无独立业务 Tool;无生产接入。
------
+5 -3
View File
@@ -33,7 +33,7 @@
⑥ 验证
uvicorn app.main:app --reload
GET http://127.0.0.1:8000/health → {"status":"ok"}
(可选)Python 调 CoreReadOnlyRepository.get_customer_l0("CUST-10001")
python -m pytest → 502 passed 1 skipped(改路由必同步 test_all_routers_mounted)
RBAC 联调账号:scripts/dev/rbac-seed-reference.md
```
@@ -48,9 +48,11 @@ RBAC 联调账号:scripts/dev/rbac-seed-reference.md
Client → Gateway(JWT/RBAC) → api/chat → agent_service(LangGraph) → Tools → 存储 → 响应 + audit_log
```
当前:**风控事件线(B1~B9b)+ Wave 0 共用底座 + 风控阶段 C(C1~C3 对话线,tag risk-m2/risk-m3)+ T-04 Tool 节点 + T-03 输入防护 + T-21 知识库全部完成**(交易网关 → 规则引擎 → 预警/AML/L3 → 4 API,`main.py` 路由挂载 + trace 中间件 + audit 中间件 + lifespan;T-01/T-02/T-06/T-07/T-04/T-03/T-21 均经独立 AI 评审闭环)。**阶段一「对齐 main 基准」AL-01~AL-08 已完成(2026-09-07,406 测试绿;适当性判定换核 core_ro.check_suitability,risk_suitability_log 21 列,Core 表 is_hnw/风评 expires_at 新列,种子 33 客户/14 产品)**。**下一步:阶段一验收门(用户目视确认)→ AL-09 合并 main → 阶段二 C4~C6 编码**(FR-8 集中度/FR-9 时效升级/FR-10 代理人行为链,实现方案《docs/项目框架设计/实现方案-风控追加需求v1.1-C4C6.md》已定稿并经独立 AI 评审修订闭环,含定时任务 scripts/cron/* 与新增对话 Tool;编码未开始)。
当前:**风控全链路 + Wave 0 共用底座 + AL-09 合并接线已完成(2026-09-08,`merger` 分支)**——B1~B9b 事件线 · C1~C6 对话/追加需求(FR-8/9/10)· 前端接入 B/C(sessions/stream)· T-03/T-04/T-21 · JWT 统一 + auth_adapter 接缝。**测试基线:`python -m pytest` → 502 passed 1 skipped**(含 `test_module_boundary` 宿主 D 类文件排除规则)。
**本机已就位状态(2026-09-07 更新 · 已完成上述 ①~⑤,无需重做):** `.env` 已配置(学习项目,`MYSQL_PASSWORD=123456`;NEO4J/DEEPSEEK 留空——DEEPSEEK_API_KEY 空时 chat 走降级回复,不阻塞演示;`.env` 无 JWT 项,签发走默认 `JWT_DEV_SECRET`,**启动时出现默认密钥 warning 属预期**,生产形态须配 `JWT_PUBLIC_KEY_PATH`);`jinrong_core` + `jinrong_agent` 已灌库(**阶段一 AL-01/AL-08 后为 33 客户/14 产品/矩阵 25 行/风评 33** / AML 名单 8 条 / 演示测评 expires_at 新口径已刷新 / 归属同步 33 行);`python -m pytest` **406** 用例全绿(集成测试真连本机 MySQL,未灌库的机器自动 skip 集成模块;pytest 依赖装在系统 Python 3.13.14);**演示库已按阶段一新口径重灌并清理冒烟数据(2026-09-07),全量测试可直接跑,下次演示/走查后再按 SOP §2 重灌**;本机 Redis 服务在跑(`redis://127.0.0.1:6379/0`,B9a 订阅脚本已验证)。
**下一步(统筹 P1):** Core 公共 API v0.1(见 `docs/项目管理/04` Phase A)· 接口契约 v0.1 发群 · 前端 `web/` init · 客户/代理人/分析 Agent 并行。
**本机已就位状态(2026-09-08 · 已完成上述 ①~⑤,无需重做):** `.env` 已配置(学习项目;DEEPSEEK_API_KEY 空时 chat 走降级回复;JWT 未配项时走默认 `JWT_DEV_SECRET`,**启动 warning 属预期**);`jinrong_core` + `jinrong_agent` 已灌库(33 客户/14 产品/矩阵 25 行/风评 33 / AML 8 条 / 归属 33 行);`python -m pytest` **502 绿 1 skipped**(集成测试真连本机 MySQL,未灌库自动 skip;系统 Python 3.13.14);Redis `redis://127.0.0.1:6379/0` 在跑。**演示/走查后按《演示SOP-风控模块.md》§2 重灌**(`reset.ps1` + `prepare_risk_demo.sql` 两步必跑)。
**本机已知坑:** `mysql.exe` 不在 PATH(位于 `C:\Program Files\MySQL\MySQL Server 8.0\bin`);`reset.ps1` 的交互式 `-p` 在自动化执行时会卡死——脚本化重灌用 `MYSQL_PWD` 环境变量传密码(交互执行不受影响,不把密码写进仓库脚本);**`redis` 与 `python-jose[cryptography]` 包均出现过 requirements 有而环境漏装(B9a 补装 redis、Wave 0 补装 jose,2026-09-07),重装环境后先 `python -c "import jose, redis"` 自检**。
+5 -5
View File
@@ -34,11 +34,11 @@
| 模块 | 职责 | 依赖 | 代码状态 |
| --- | --- | --- | --- |
| Agent Gateway / Auth SDK | JWT、RBAC、归属校验 | Redis、MySQL customer_advisor_rel | **已实现(T-01,2026-09-07)**:`service/auth_service.py`(验签/吊销)+ `api/deps.py`(Bearer 全环境优先 + dev debug 头兜底 + AGENT_ACCESS_MATRIX 准入) |
| Agent Gateway / Auth SDK | JWT、RBAC、归属校验 | Redis、MySQL customer_advisor_rel | **已实现(T-01 + AL-09)**:模块 `service/auth_service.py` + `api/deps.py`;宿主 `gateway/` 四件套并存;`/api/auth/login` 统一走 `issue_dev_token`;S2 接缝 `auth_adapter.module_auth_from_host` |
| 客户财富 Agent | L1 画像、事实查询、阈值提醒 | Core RO、Milvus 产品库 | 空壳 service(chat 骨架已通) |
| 代理人助手 Agent | L2 画像、RAG、草稿 | L1 只读、Milvus | 空壳 service(chat 骨架已通) |
| 数据分析 Agent | NL→SQL→解读 | Core RO、画像只读 | 空壳 service(chat 骨架已通) |
| 风控监测 Agent | 预警、L3、R-02 适当性 | 交易事件、AML 名单 | **已实现 B1~B7 + C1~C3(对话线四 Tool + risk 分支 StateGraph,A-6 验收)**;追加 FR-8/9/10(C4~C6:集中度/时效升级/行为链)方案已定稿待编码 |
| 风控监测 Agent | 预警、L3、R-02 适当性 | 交易事件、AML 名单 | **已实现 B1~B9b + C1~C6(FR-1~10)**:事件线 + 对话线 + 集中度/时效升级/代理人行为链;**AL-09 已并入 `merger` 分支** |
| Core 只读层 | L0 事实查询 | `jinrong_core` | **已实现 + 已接对话 Tool(T-04)**:core_ro 经 app/tool/core_tools.py 三只读 Tool(L0/持仓/流水)进 chat;风控扩展查询照旧 |
| 共用底座 | 会话、审计、输入防护 | MySQL 11 表 + Redis | **已接入(2026-09-07)**:会话(T-06 session_repository + memory_service 窗口)、审计中间件(T-02 http_access + input_guard_log 双写)、agent_tool_call Tool 留痕(T-04)、输入防护(T-03 input_guard:注入词表纯函数检测 + oversize + Redis 固定窗口限流,chat 链路 限流→注入/超长→归属) |
| 对话编排 | LangGraph StateGraph + DeepSeek | langgraph/langchain-openai | **已实现(T-07 骨架 + T-04 Tool 节点 + C1 风控四 Tool + C2 risk 分支,2026-09-07)**:tool(分组关键词意图→Tool,customer/advisor/risk)→llm→guard(免责声明);analyst 分支与 LLM intent 待后续 |
@@ -49,7 +49,7 @@
## 3. 后端分层(app/)
```text
api/ → risk / simulate / chat / deps / audit_middleware 已实现;knowledge、admin 空壳 【大部分】
api/ → auth / risk / simulate / chat(含 sessions/stream)/ deps / auth_adapter / audit_middleware 已实现;knowledge、admin 空壳 【大部分】
service/ → risk/*(rules/alert/aml/engine/l3/scoring/locks/redis_gateway/chat_tools)+ suitability +
auth_service(T-01 JWT)+ agent_service(T-07 图 + T-04 tool 节点 + C2 risk 分支)+ memory_service(T-06)+
tool_service(T-04 对话 Tool 编排:意图/归属校验/run_tool 落库)+ input_guard(T-03)+
@@ -63,7 +63,7 @@ gateway/ → 模拟交易网关(trade_gateway + gateway_repository 仅 IN
model/ → schemas(Pydantic)、entities(ORM) 【占位】(风控暂用 dict,收敛待后续)
config/ → settings(双库 + risk_* 阈值 + JWT 配置)、database 【settings 已实现】
utils/ → trace(trace_id+request_id)/ desensitize / db(引擎工厂)/ response(统一错误体)/ exceptions 【基本就绪;logger 占位】
main.py → 路由挂载 + trace 中间件(双 ID 贯通 + 500 兜底)+ audit 中间件 + lifespan(B7/T-02) 【已集成】
main.py → 宿主 TraceMiddleware + 模块 audit/trace 中间件 + 路由挂载 + lifespan(AL-09);trace 对 ApiError 等 re-raise 【已集成】
允许:api → service → tool / repository / model / config
禁止:api 直连 Milvus/MySQL 写复杂逻辑;tool 写业务流程;repository 写 Core
@@ -80,7 +80,7 @@ scripts/demo/ → 演示数据准备(prepare_risk_demo.sql,reset 后
scripts/sync/ → sync_advisor_rel.py、sync_neo4j.py
scripts/dev/ → issue_dev_token.py(JWT 签发)+ rbac-seed-reference.md(联调账号)
scripts/kb/ → build_kb.py(知识库入库,T-21)
scripts/cron/ → (C5/C6 规划)escalation_scan.py / agent_behavior_scan.py 定时任务
scripts/cron/ → escalation_scan.py / agent_behavior_scan.py(C5/C6 定时任务,独立脚本非 lifespan 内嵌)
```
------
+4
View File
@@ -12,3 +12,7 @@
| 2026-09-07 | 《实现方案-风控追加需求v1.1-C4C6.md》定稿:独立 AI 评审 FAIL(P0×1/P1×4/P2×6)→ 修订闭环;C4~C6 编码依据可照抄 | 开发流程第 2 步(另一 AI 验证挑毛病) | 实现方案文档 |
| 2026-09-07 | 全库文档同步:分支口径修正(`feature/risk` → 实况 `risk-control-agent`,与 main 分叉 67/4)+ T-21 评审闭环 / 425 绿 / T-03 / C1~C3 状态落账 + 新建项目根交接文档.md | 文档与实况不一致(用户排查要求) | MEMORY / TODO / REQUIREMENTS / FRAMEWORK / FLOW / ENVIRONMENT / ITERATION / PRD / 架构设计 / 开发计划 / README / 交接文档 |
| 2026-09-07 | **阶段一「对齐 main 基准」AL-01~AL-08 完成**(逐项独立 commit bb244f4~b5fd52e):SUIT-001~008 换核为 core_ro.check_suitability(C×R 矩阵 + match_result 五值 + JR-AST/FM 契约)· risk_suitability_log 重建 21 列 · Core 表 is_hnw/风评 expires_at 七新列 · 种子 33 客户/14 产品 · 全量 **406 passed 0 failed 0 skipped**(425→406,SUIT 测试重写)· uvicorn 冒烟三端点通过 · risk-m1 补打(3c07de6)· 六项拍板全落定 | 阶段一执行(用户拍板 main = 需求唯一基准);基线变更与 SUIT 体系退役需落账 | MEMORY / TODO / REQUIREMENTS / FRAMEWORK / FLOW / ENVIRONMENT / ITERATION / README / 交接文档 |
| 2026-09-07 | **阶段二 C4~C6 完成**(FR-8/9/10):集中度 `fe4801b` · 时效升级 `90d0660` · 代理人行为链 `66ec7eb` · 挂账 #1~#9 核对无违规 · tag `risk-m4` · 482 pytest 绿 | PRD v1.1 追加需求落地 | MEMORY / TODO / REQUIREMENTS / PRD / 开发计划 |
| 2026-09-08 | **前端接入方案 B/C**:chat 拉侧三端点 `8328c24` · SSE 流式 `01ec5fc` · 503→502 测试基线 | 前端联调前置 | MEMORY / TODO / chat / session_repository / agent_service |
| 2026-09-08 | **AL-09 合并接线完成**(`merger` 分支):JWT 统一 · 模块 chat/agent/memory 恢复 · auth_adapter S2 接缝 · trace 中间件 ApiError re-raise · test_module_boundary 绿 · **502 passed 1 skipped** | 风控模块并入宿主 Wave 0 | MEMORY / TODO / FRAMEWORK / FLOW / REQUIREMENTS / ENVIRONMENT / 合并注意事项 |
| 2026-09-08 | **《04-从需求到公共API开发方法》首版**:固化需求→矩阵→存储→Service→API→Agent 主线及 Phase A 分批策略 | 统筹 P1 下一步搭公共 REST API | docs/项目管理/04 / README |
+18 -15
View File
@@ -9,13 +9,18 @@
**项目是什么:** 金融四 Agent(客户财富 / 代理人 / 数据分析 / 风控)共用数据层与合规底座;**不**互调 LLM,跨 Agent 走 L1/L2/L3 画像与预警表。
**当前进度:** 需求与表设计已定 · **风控模块 B1~B9b 全部完成(M2 tag risk-m2),M4 复核已闭环(2026-09-07),风控阶段 B 正式完结** · **Wave 0 已完成(2026-09-07,经独立 AI 评审闭环)**:T-01 JWT 鉴权(auth_service Auth SDK + deps 工厂替换 + X-Agent-Type 准入矩阵)/ T-02 审计中间件(http_access + 独立 request_id + 4xx/500 统一错误体 + input_guard_log 双写)/ T-06 chat 最小闭环(POST /api/chat + 会话落库 + Redis 窗口)/ T-07 LangGraph StateGraph 骨架 + DeepSeek(无 key 降级)· **T-04 Core RO Tool 节点已完成(2026-09-07)**:app/tool/core_tools.py 三只读 Tool + tool_service(意图/归属校验/run_tool)+ 图 tool 节点 + agent_tool_call 落库 + `utils/authz.py` 公共鉴权留痕,**321 测试绿(首评+复审双闭环)**。风控阶段 C 已完成(2026-09-07,345 绿,tag `risk-m3`,A-6 对话线验收通过,独立 AI 评审 PASS P0=0)。T-03 输入防护已完成(2026-09-07,378 绿,独立 AI 评审 PASS with findings P0=0):app/service/input_guard.py 注入词表 42 条纯函数检测 + oversize 4000 + actor 级 Redis 固定窗口限流 30 次/分(fail-open);chat 链路顺序 = 鉴权→准入→空白→限流 429→注入/超长 400→归属→会话,被拒 fail-fast 不建会话,blocked 落 input_guard_log(ENUM 四值已用满)。**阶段一「对齐 main 基准」AL-01~AL-08 已完成(2026-09-07,逐项独立 commit bb244f4~b5fd52e):适当性判定换核为 main 的 core_ro.check_suitability(C×R 矩阵表数据驱动,match_result 五值/JR-AST-012/FM-01/FM-03/JR-AST-PRO 契约,SUIT-001~008 退役);risk_suitability_log 重建 21 列;Core 表加 is_hnw/风评七新列(expires_at);种子 33 客户/14 产品;全量 406 passed 0 failed 0 skipped + uvicorn 冒烟三端点通过;risk-m1 已补打(指向 3c07de6)**。**下一步:阶段一验收门(**合并 main 前的最终交付检查点,非分支开发阻塞**;用户浏览器目视确认 UI)→ AL-09 合并 main → AL-10 PRD v1.2 → AL-11 docx 登记 → 阶段二 C4~C6(**已完成并打 `risk-m4` tag**)/ 前端 React 多 Agent 入口(HashRouter `web/` init)。****开发在分支 `risk-control-agent`(与 origin/main 已分叉:领先 84 提交 / 落后 0,origin/main 为分支祖先;**分支已推送远程,origin/risk-control-agent 同步于 `1d00e53`,本地跟踪已建立**;旧文档中的 `feature/risk` 为过时口径)。**
**当前进度:** 需求与表设计已定 · **风控模块 B1~B9b + 阶段 C(C1~C3)+ C4~C6(FR-8/9/10)+ 前端接入 B/C 全部完成** · **AL-09 合并接线已完成(2026-09-08,`merger` 分支)**:`risk-control-agent` 并入宿主 Wave 0;JWT 统一(`/api/auth/login` → `auth_service.issue_dev_token`,与 risk/chat 共用 `settings.jwt_issuer`);模块版 chat/agent/memory 已恢复(含 sessions/stream);S2 接缝 `auth_adapter.module_auth_from_host` 已接线;**502 passed 1 skipped**(`python -m pytest`)。**下一步:统筹侧 Core 公共 API v0.1 + 前端 `web/`;各 Agent 负责人并行 Tool/编排。**
**工作分支:** 团队开发在 **`merger`**(已 merge 风控模块);历史开发分支 `risk-control-agent` 交付冻结。旧文档中「待 AL-09 合并」口径已过时。
**仓库地图:**
| 路径 | 状态 | 说明 |
| --- | --- | --- |
| `app/main.py` | **已集成** | 路由挂载 + trace 中间件(X-Trace-Id/X-Request-Id 贯通 + 500 兜底错误体)+ audit 中间件(T-02 http_access)+ lifespan(jwt_ready 校验 · Redis 网关注册 · 引擎 dispose) |
| `app/main.py` | **已集成(AL-09)** | 宿主 TraceMiddleware + 模块 audit/trace 中间件 + 路由(auth/chat/risk/simulate)+ lifespan;trace 中间件对 ApiError 等 **原样 re-raise**,仅未捕获异常 → 500 |
| `app/api/auth.py` | **已实现(AL-09)** | Mock 登录;签发走 `auth_service.issue_dev_token`(与模块 API 同一 issuer) |
| `app/api/auth_adapter.py` | **已接线(S2)** | `module_auth_from_host()`:宿主 AuthContext → 模块 AuthContext |
| `app/gateway/` | **宿主 Wave 0(并存)** | jwt_service / auth_deps / rbac / ownership;模块 API 走 `deps.py`,禁止模块 import gateway |
| `app/api/risk.py` `simulate.py` `deps.py` | **已实现** | 风控 4 API + 模拟网关路由 + **JWT 鉴权工厂(T-01:Bearer 全环境优先;debug 头仅 dev+无 RS256 公钥时兜底;AGENT_ACCESS_MATRIX 准入)** |
| `app/api/chat.py` `audit_middleware.py` | **已实现(T-06/T-02 + 前端接入 B/C)** | POST /api/chat(SessionGuard+归属+窗口+落盘)· **前端拉侧三端点**(`GET /sessions` / `GET /sessions/{id}/messages` / `POST /sessions/{id}/close`,方案 B `8328c24`)· **SSE 流式 `POST /api/chat/stream`**(OpenAI 兼容 chunk,方案 C `01ec5fc`);守卫抽 `_guard_request`/`_prepare_turn`/`_guard_session` 同步流式共用 · http_access 访问审计 |
| `app/api/knowledge.py` `admin.py` | 空壳 | 待审计查询台与知识库 API(T-21 拍板一期只做脚本入库,上传/重建端点不做) |
@@ -34,11 +39,12 @@
| `scripts/core/*.sql` + `reset.ps1` | **已实现** | Core 模拟库 DDL + 种子 |
| `scripts/agent/` `scripts/demo/` `scripts/dev/` | **已实现** | AML 名单种子 + 风控演示数据 + subscribe_alerts/rebuild_alerts + issue_dev_token(JWT 签发) |
| `scripts/sync/*.py` | **已实现** | 归属同步 + Neo4j 全图 |
| `tests/` | **已实现** | 36 个测试模块 503 用例(sqlite 隔离;DDL 单一事实源 `_ddl.py`;`test_integration_risk.py` 走真 MySQL + TRD-TEST- 前缀隔离;pytest 依赖装在系统 Python 3.13.14;阶段一基线 425→406,前端接入 B/C 后 **482→503**)。**改路由必同步 `tests/test_main.py::test_all_routers_mounted` 的路径清单,否则必红** |
| `tests/` | **已实现** | 36+ 测试模块 **502 用例 1 skipped**(sqlite 隔离;`test_module_boundary` 宿主 D 类文件不参与跨层扫描)。改路由必同步 `tests/test_main.py::test_all_routers_mounted` |
| `docs/需求拆解/` | 已定 | 场景 P0、矩阵、合规原文 |
| `docs/PRD/PRD-风控监测Agent.md` | **已冻结(v1.1)** | 风控 PRD v1.0 + v1.1 追加 FR-8/9/10(§4A)+ 规则表附录 |
| `docs/项目框架设计/实现方案-风控追加需求v1.1-C4C6.md` | **已定稿** | C4~C6 编码依据(经独立 AI 评审修订闭环);分支/进度速览另见项目根 `交接文档.md` |
| `docs/项目框架设计/合并注意事项-风控模块并入main.md` | **已定稿(2026-09-07)** | **给合并执行人**:基底锁定(本地 main 3995cb4,origin/main 停在 Initial commit)/ 20 冲突裁决指引 / 14 静默并入文件 / 三处硬伤处置 / 合并后必测清单 |
| `docs/项目框架设计/合并注意事项-风控模块并入main.md` | **AL-09 已执行(2026-09-08)** | 合并接线完成;接缝见《风控Agent模块边界与合并接缝标注.md》 |
| `docs/项目管理/04-从需求到公共API开发方法.md` | **已定(2026-09-08)** | 需求→矩阵→存储→Service→API→Agent 主线;Phase A Core API 清单 |
| `docs/项目框架设计/表设计/` | 已定 | Agent 共用 11 表 + agent 专用 SQL |
| `docs/项目框架设计/Core模拟底座/` | 已定 | 无真实 Core 时的 L0 方案 |
| `web/` | **不存在** | 前端 React 待 init |
@@ -54,15 +60,12 @@
5. mysql … < scripts/agent/seed-aml-list.sql # AML 名单种子
(风控演示:scripts/demo/prepare_risk_demo.sql,reset 后重跑)
6. python scripts/sync/sync_advisor_rel.py && python scripts/sync/sync_neo4j.py
7. uvicorn app.main:app --reload → GET /health;python -m pytest(406 用例,系统 Python 3.13.14)
7. uvicorn app.main:app --reload → GET /health;python -m pytest(**502 绿**,系统 Python 3.13.14)
```
> **本机 ①~⑤已执行、`.env` 已配置,勿重做**;本机状态与已知坑(mysql.exe 路径 / reset.ps1 交互式 -p / `redis`、`python-jose` 包漏装已补)见 `FLOW.md` §0 尾注。
> **演示库状态(2026-09-07)**:已按演示 SOP §2 重灌并清理冒烟数据(alerts 0 / AML 8 / 会话 0),pytest 全量可直接跑;**下次演示/走查后再按 SOP §2 重灌**(核查单⑥前置断言会对走查残留显式 fail,属防护行为)。
**AL-09 合并后架构(一句话):** 宿主 `gateway/` + 模块 `deps.py` **双栈并存**;对外登录/token **统一**;chat/risk 均走模块鉴权;接缝 S2 用 `auth_adapter`。
**前端接入面已交付(2026-09-08,503 绿)**:**方案 B** 会话管理三端点(`GET /api/chat/sessions`、`GET /api/chat/sessions/{id}/messages`、`POST /api/chat/sessions/{id}/close`,commit `8328c24`)+ **方案 C** SSE 流式对话 `POST /api/chat/stream`(OpenAI 兼容 chunk:首帧 meta 带 disclaimer → delta → finish_reason=stop → `[DONE]`,commit `01ec5fc`)。三条硬约束:① 守卫全在返回 StreamingResponse 之前(SSE 一开改不了状态码,401/403/404/409/429/400 仍普通 JSON);② 整轮一次性落库(`insert_turn` 同事务),断连/异常不落消息;③ risk_manager 在对话线数据面一律 403(PRD 4A.1)。遗留 P2:无心跳帧、断连留空会话、流式 429 未单测。
**下一步开发(见 TODO):** **模块侧交付完毕(2026-09-07:全量 pytest 482 绿 + 接口实调验收通过——suitability/check 阻断+放行、simulate/trade 阻断、三条鉴权边界 401/403/403 契约零偏差;`risk-m1~m4` tag 齐)。合并 main 已移交合并执行人,操作手册《docs/项目框架设计/合并注意事项-风控模块并入main.md》(含基底锁定/20 冲突裁决/14 静默文件/三硬伤/合并后必测,实测数据编制)。模块侧开放项:chat 链路 risk_suitability_log.actor_id 落 SYSTEM 待评估 / 前端 React 多 Agent 入口(`web/` 未 init,归属待拍板)。**演示走查按 `docs/项目框架设计/演示SOP-风控模块.md`(debug 头通道仍有效;JWT 通道签发用 `scripts/dev/issue_dev_token.py`;演示库已按 AL-08 expires_at 新口径重灌)。知识库入库:`python scripts/kb/build_kb.py`(先启 Ollama;**Milvus 数据路径必须纯英文**——faiss 不支持中文路径,本机 .env 已配 C:/Users/YUAN/.jinrong/milvus/)。
**下一步(见 TODO):** Core 公共 API v0.1(`docs/项目管理/04` Phase A)· 前端 `web/` init · 客户/代理人/分析 Agent 业务并行。
**禁止(改代码前必记):** Core 正式 C1~C5 不可被画像覆盖 · 审计表只 INSERT · 代理人草稿不外发 · 仅 R-02 可阻断交易 · 四 Agent 不互调 LLM。
@@ -81,8 +84,8 @@
## 1. 项目简介
- **名称:** JinRong 金融四 Agent 智能管家
- **当前阶段:** **模块交付完毕(2026-09-07)+ 前端接入面交付(2026-09-08)**——阶段一 AL-01~08 + 阶段二 C4~C6 + 前端接入 B/C 全部完成,**503 绿**,接口实调验收通过(AI 代验),`risk-m1~m4` tag 齐;合并 main 已移交合并执行人(手册:《合并注意事项-风控模块并入main.md》)
- **当前优先级:** 前端 React 入口(`web/` init,后端接入面已就绪)/ 模块侧开放项(actor_id 透传评估);合并进度由合并执行人负责,模块侧不阻塞
- **当前阶段:** **AL-09 合并接线完成(2026-09-08,`merger` 分支)**——风控 + Wave 0 宿主共存;502 测试绿;接口实调此前已通过
- **当前优先级:** Core 公共 API v0.1(统筹 P1)/ 前端 `web/` / 客户·代理人·分析 Agent 并行
------
@@ -145,7 +148,7 @@ Core 模拟:scripts/core/reset.ps1 · 文档 docs/项目框架设计/Core模
种子:scripts/agent/seed-aml-list.sql(AML 名单)· scripts/demo/prepare_risk_demo.sql(reset 后重跑)
依赖:requirements.txt(LangGraph + langchain-core/openai + FastAPI + SQLAlchemy)
启动:uvicorn app.main:app --reload → GET /health
测试:python -m pytest(503 用例;集成测试需本机演示数据,未灌库时自动 skip)
测试:python -m pytest(**502 绿** 1 skipped;集成测试需本机演示数据,未灌库时自动 skip)
运维/演示脚本:scripts/demo/subscribe_alerts.py(订阅推送演示)· rebuild_alerts.py TRD-xxx(引擎异常补偿重放)
JWT 联调:python scripts/dev/issue_dev_token.py --sub STAFF-30001 --roles risk_officer(+ Authorization: Bearer + X-Agent-Type)
配置:.env(见 .env.example)
@@ -171,7 +174,7 @@ RBAC 联调账号:scripts/dev/rbac-seed-reference.md
| `docs/项目框架设计/架构设计-风控模块.md` | 风控模块架构(§3.1 编排 / §5 service 职责) |
| `docs/需求拆解/` | 业务原文(场景、矩阵、合规) |
| `docs/项目框架设计/` | 表结构、JWT 手册、Core 模拟、技术版本 |
| `docs/业务记忆管理/` | Redis 短期 vs MySQL/Milvus/Neo4j 权威记忆 |
| `docs/项目管理/04-从需求到公共API开发方法.md` | 搭公共底座/API 前;新人 onboarding |
缺 `docs/memory/*` 文件:按 project-memory-kit 同名补回,**禁止空模板盖进度**。
@@ -189,6 +192,6 @@ RBAC 联调账号:scripts/dev/rbac-seed-reference.md
2. 改动属于 api / service / tool / repository 哪一层?
3. 是否需 customer_id 归属与 JWT RBAC?
4. Core 是模拟库只读还是 agent 库读写?
5. 如何验证?(`python -m pytest` 全量(当前 **503 绿**)· uvicorn 启动 + /health · SQL / sync 脚本 · 对照 REQUIREMENTS 验收列)
5. 如何验证?(`python -m pytest` 全量(当前 **502 绿**)· uvicorn 启动 + /health · `tests/test_module_boundary.py` 全绿 · SQL / sync 脚本 · 对照 REQUIREMENTS 验收列)
大任务:FRAMEWORK/FLOW 与实现状态不符时先更新 memory 再编码(用户确认跳过除外)。
+5 -3
View File
@@ -13,6 +13,8 @@
------
**合并状态(2026-09-08):** AL-09 接线完成(`merger` 分支)——宿主 Wave 0 与风控模块共存;JWT/login 统一;chat/risk 走模块鉴权;502 pytest 绿。
## Wave 0 · 共用底座
| ID | 需求 | 验收对照 | 状态 | TODO |
@@ -46,9 +48,9 @@
| R-03 | AML 命中通知 | 不自动冻户 | **已实现**(aml_service + scan API + L3 联动;对话线随 C1~C3 完成,A-6 验收通过) | ~~T-32~~ |
| R-04 | 频繁/试探模式预警 | 聚合出单 + 去重 | **已实现**(B1 规则 + B2 聚合去重) | ~~T-30~~ |
| R-05 | L3 画像写入 | 最小写入(最高档合并) | **已实现**(profile_l3 防降级;`risk_score` 一期保持 NULL 归评分模型首写) | ~~T-30~~ |
| FR-8 | 客户资产配置集中度预警(RISK-006) | A-10:R4+R5 占比 ≥ 阈值出单(并入事件类聚合);对话线只读展示 | **待编码**(实现方案已定稿,任务 C4) | C4 |
| FR-9 | 预警单处置时效监控与自动升级(RISK-007) | A-11:超时分级升级(payload 承载不改 status)+ 幂等 + 降噪 | **待编码**(P0 红线;任务 C5,前置 = risk_manager 角色联动) | C5 |
| FR-10 | 代理人异常行为链识别(RISK-008) | A-12:条件 A/B/C 触发 + 代理人维度出单(payload.actor_id)+ 明细仅 officer/manager 可见 | **待编码**(任务 C6,前置 = trade_gateway actor 透传) | C6 |
| FR-8 | 客户资产配置集中度预警(RISK-006) | A-10:R4+R5 占比 ≥ 阈值出单(并入事件类聚合);对话线只读展示 | **已实现**(C4 `fe4801b`,2026-09-07) | ~~C4~~ |
| FR-9 | 预警单处置时效监控与自动升级(RISK-007) | A-11:超时分级升级(payload 承载不改 status)+ 幂等 + 降噪 | **已实现**(C5 `90d0660` + escalation_scan 脚本,2026-09-07) | ~~C5~~ |
| FR-10 | 代理人异常行为链识别(RISK-008) | A-12:条件 A/B/C 触发 + 代理人维度出单(payload.actor_id)+ 明细仅 officer/manager 可见 | **已实现**(C6 `66ec7eb` + agent_behavior_scan 脚本,2026-09-07) | ~~C6~~ |
## Wave 3 · 客户 P0
+10 -27
View File
@@ -5,43 +5,26 @@
## 进行中
**阶段一 AL-01~AL-08 与阶段二 C4~C6 均已完成(2026-09-07)**:全量 pytest **482 passed 0 failed 0 skipped**(真库集成)✓ · uvicorn 冒烟三端点 ✓ · 接口实调验收 ✓(2026-09-07:suitability/check 阻断+放行、simulate/trade 阻断、三条鉴权边界 401/403/403,契约零偏差)· risk-m1~m4 tag 齐。**合并 main 已移交合并执行人**(操作手册:《docs/项目框架设计/合并注意事项-风控模块并入main.md》,随分支上传),后续模块侧待办见下方。
**AL-09 合并接线已完成(2026-09-08,`merger` 分支)**:JWT 统一 · 模块 chat/agent/memory 恢复 · auth_adapter 接线 · trace 中间件修复(应用异常 re-raise)· **502 passed 1 skipped** ✓
## 待办(推荐顺序)
## 待办(统筹 · P1 推荐顺序)
- [x] **【阶段一验收门】接口实调验收** —— **通过(2026-09-07 委托 AI 代验:三接口契约 + 三鉴权边界全部符合;前端 web/ 未 init,验收口径为后端接口验证)**
- [x] **【阶段二】C4~C6 追加需求编码**(实现方案已定稿)—— **全部完成(C4 RISK-006 `fe4801b` / C5 RISK-007 `90d0660` / C6 RISK-008 `66ec7eb`,全量 pytest 482 passed 0 failed);收尾=演示 SOP 补代理人扮演步骤 + 02-redis-keys.md 增补 + tag `risk-m4`(见下条)**
- [x] **【阶段二前置】**`python -m pytest` 全量(系统 Python 3.13.14)确认基线绿 —— **482 passed 0 failed ✓(2026-09-07)**
- [x] **【阶段二】C5 前置联动**(挂账 #6):seed STAFF-31001/31002 + AGENT_ACCESS_MATRIX 增补 risk_manager + chat.py 显式 deny(对话线维持仅 risk_officer)+ risk.py 台账 manager 只读分支 + JWT 手册 §5.3 —— **完成(随 C5 落地,见挂账 #6 核对)**
- [x] **【阶段二】C4 RISK-006 集中度**(FR-8):rules(rule_concentration + RuleHit.alert_subtype)+ core_ro.concentration_profile + engine 接入 + alert_service(锚点排除 agent_behavior 单【评审 P0-1】+ subtype 合并 + alert_type 重算)+ customer_context 扩展 + settings 11 项配置;验收 A-10 —— **完成(commit `fe4801b`)**
- [x] **【阶段二】C5 RISK-007 时效升级**(FR-9):escalation_service + scripts/cron/escalation_scan.py + query_overdue_alerts Tool + conftest 回拨 fixture;验收 A-11 —— **完成(commit `90d0660`)**
- [x] **【阶段二】C6 RISK-008 代理人行为链**(FR-10):trade_gateway actor_id 透传(前置)+ agent_behavior_service + scripts/cron/agent_behavior_scan.py + query_agent_behavior Tool;验收 A-12 —— **完成(commit `66ec7eb`)**
- [x] **【阶段二收尾】**演示 SOP 补代理人扮演步骤(A-12)+ 02-redis-keys.md 增补(C6 联动)+ 挂账 #1~#9 逐项核对 + 打 `risk-m4` tag —— **全部完成(2026-09-07,`risk-m4` 指向 `323d98b`,仅本地未 push)**
**挂账 #1~#9 核对结论(基于 C4~C6 三提交 `fe4801b`/`90d0660`/`66ec7eb` + 文档 `323d98b` 实查):**
| 挂账 | 内容 | 现状 | 判定 |
|---|---|---|---|
| #1 | 持仓汇总 | 收口进 `core_ro.concentration_profile`(持仓画像非流水),C4 `rule_concentration` 直接消费 | ✓ 已收口 |
| #2 | 定时任务内嵌 lifespan | `app/main.py` lifespan 无 cron 调用;`scripts/cron/escalation_scan.py` + `agent_behavior_scan.py` 仍独立 | ✓ 未触碰 |
| #3 | agent_profile_l3 建表 | 终态 entities 无 `agent_profile_l3`(仅有 `customer_profile_l3`,非同一表) | ✓ 未建 |
| #4 | escalated 状态改表 | 升级标记走 `payload.escalation_level/escalated_at`,无 status 列变更、无 ALTER | ✓ 未改表 |
| #5 | alert_type ENUM 扩展 | `alert_type` 仍为 `VARCHAR`,靠 `payload.alert_subtype` 承载子类型 | ✓ 未扩 ENUM |
| #6 | risk_manager 联动 | 随 C5 前置落地:seed STAFF-31001/31002 + AGENT_ACCESS_MATRIX 放行只读 + handle/aml/scan 端点保持 risk_officer only(manager 触碰即 403) | ✓ 已收口(零处置权) |
| #7 | customer_query 事件类型补建 | C6 复用既有 `trade_request`/`authz forbidden` 事件,无新建 `customer_query` 事件类型/枚举 | ✓ 未建 |
| #8 | core_trade actor 字段 | 终态 `core_trade` ORM 无 `actor` 列;actor 透传仅落在 `audit_log`/`agent_*`(`trade_gateway.actor_id` 写入审计,非 core_trade) | ✓ 未加列 |
| #9 | payload JSON 检索性能 | `risk_repository` 仅改 `append/merge/find` 逻辑,无新增索引/查询计划优化 | ✓ 未动 |
**红线复核**:C4~C6 无 DDL/迁移脚本(`scripts/core/02-seed-base.sql` 仅补 seed 行,非改表);审计仅 INSERT;升级标记仅 cron 可写;manager 无处置权;四 Agent 不互调 LLM。挂账清单无一项退化为本期误做。
- [ ] **Core 公共 API v0.1**(见 `docs/项目管理/04` Phase A:customers/products/holdings/trades/suitability-check)
- [ ] **接口契约 v0.1** 发群(login/token/chat + Core 只读 REST)
- [ ] 前端 React 多 Agent 入口(HashRouter,`web/` init)
- [ ] 同步 `MEMORY/REQUIREMENTS/FRAMEWORK` 与各 Agent 负责人联调节奏
## 待办(模块侧开放项)
- [ ] chat 链路 `risk_suitability_log.actor_id` 暂落 SYSTEM(run_tool 统一透传需动 core_tools/kb_tools 冻结 func 契约,发起者留痕已由 agent_tool_call 覆盖)——AL-06 遗留,动 Tool 契约前先出方案
- [x] **【前端接入·方案 B】chat 拉侧三端点**(commit `8328c24`,2026-09-08):`GET /api/chat/sessions`(本人+本 Agent 线分页列表)、`GET /api/chat/sessions/{id}/messages`(历史消息升序分页,closed 仍可读)、`POST /api/chat/sessions/{id}/close`(active→closed,重复/非 active 409);chat.py 抽 `_resolve_agent_type`/`_assert_chat_entry`/`_guard_session` 三守卫供四端点共用,POST "" 行为零回归;risk_manager 在对话线数据面保持 403(PRD 4A.1)。测试 482→**494 绿**;独立评审 P0=0,P1(close 并发 rowcount 静默 200)已修复
- [x] **【前端接入·方案 C】SSE 流式对话**(commit `01ec5fc`,2026-09-08):新增 `POST /api/chat/stream`(OpenAI 兼容 chunk:首帧 meta → delta → finish_reason=stop → `[DONE]`);`agent_service.stream_chat` 生成器 + `needs_disclaimer`;`_guard_request`/`_prepare_turn` 与同步端点共用守卫;`session_repository.insert_turn` user+assistant 同事务落库(修评审 P0/P1)。测试 494→**503 绿**。遗留:无心跳帧、断连留空会话待清理
- [ ] 前端 React 多 Agent 入口(HashRouter,`web/` init)——是否归风控模块由用户拍板
- [ ] 前端 React 多 Agent 入口(HashRouter,`web/` init)——统筹 P1,见上方待办
- [x] 2026-09-05 memory 文件夹更新(新 Agent 交接清单)
> **合并 main 相关(AL-09 / AL-10 / AL-11)已移交合并执行人**——模块侧交付完毕(482 绿 + 接口实调验收通过 2026-09-07),执行手册:《docs/项目框架设计/合并注意事项-风控模块并入main.md》(含基底锁定/20 冲突裁决/14 静默文件/三硬伤/合并后必测清单,实测数据编制)。
> **AL-09 已完成(2026-09-08)**——见 `docs/项目框架设计/合并注意事项-风控模块并入main.md` 执行记录。
- [x] **【AL-09】合并接线**(2026-09-08):JWT 统一 · 模块 chat 恢复 · auth_adapter · test_module_boundary 绿 · **502 pytest 绿**
- [x] T-04 Core RO 封装为 Tool 节点;A-01 归属校验(chat Tool 接入 + agent_tool_call 落库)—— **完成(2026-09-07)**:`app/tool/core_tools.py`(L0/持仓/流水三只读 Tool + TOOL_REGISTRY 白名单)+ `app/service/tool_service.py`(关键词意图仅 customer/advisor;归属校验对齐 deps.assert_customer_access 口径——Tool 层拒绝不抛 403 而 blocked 留痕,纵深防御;run_tool 执行+落库,落库失败降级)+ agent_service 图 tool 节点(START→tool→llm→guard;结果注入 LLM 上下文,降级回复带摘要)+ session_repository.insert_tool_call(message_id 一期 NULL)。**A-01 口径:本任务只做 Tool 层归属校验语义(customer 本人/advisor assigned/risk_officer 全量/其余拒),A-01 完整场景(代理人画像)仍归 T-20**;risk 分支四 Tool 归 C1 复用 run_tool。**评审闭环(2026-09-07):首评 P1×2+P2×3+P3×2 → 修复 `40a9ee2` → 复审 P2×1+P3×4 → 修复 `1216d26`,pytest 321 绿;入参白名单+days 钳制、公共鉴权双写 `utils/authz.py`、list_holdings LIMIT 均落地**
- [x] T-21 Milvus Lite + kb_product_rules 首批入库 —— **完成(2026-09-07,commits e34973f~535c8a0 共 6 个 + 评审闭环 9cc2e59)**:`app/service/embedding.py`(Ollama bge-m3 批量 /api/embed 1024 维,四类失败一律 EmbeddingError 不静默降级)+ `app/service/milvus_service.py`(kb_product_rules 幂等建集合+upsert+search_kb 溯源/effective_date 合规过滤)+ `data/kb/` 6 只种子产品手册(prospectus/fee/rule/risk 四节 24 块)+ `scripts/kb/build_kb.py`(--dry-run/--kb-dir)+ `app/service/rag_service.py` 落地(search_knowledge→chunks+source_refs,异常上抛防 LLM 编造)+ `app/tool/kb_tools.py` 挂注册表第三层(**ToolSpec 新增 skip_access_check**:公开知识无归属语义,advisor 无绑定客户可查;意图层限定 customer/advisor,risk 不开放——用户拍板)+ tool_node 按 spec 白名单注入 query + summarize 溯源口径。**真库验收:24 块入库,search_knowledge("基金申购") Top3 命中申赎规则(score 0.73+),溯源完整**。三坑收口:Milvus Lite 跨进程重开须显式 load / faiss 不支持中文路径(本机 .env 改 C:/Users/YUAN/.jinrong/milvus/)/ build_kb sys.path 引导。知识库 API(上传/重建端点)一期不做(knowledge.py 仍空壳,用户拍板),425 绿
@@ -1,6 +1,24 @@
# 合并注意事项 · 风控 Agent 模块并入 main(AL-09 执行手册)
> 版本:2026-09-07 v1.0(基于 `risk-control-agent` 分支 HEAD `cfbd056` 实测编制)
> **执行状态:AL-09 已完成(2026-09-08,工作分支 `merger`)** — 下文 §0~§7 为合并前手册,保留作审计参照;执行摘要见下节。
---
## ✅ AL-09 执行记录(2026-09-08)
| 项 | 结果 |
| --- | --- |
| 工作分支 | `merger`(已 merge 风控模块 + 宿主 Wave 0) |
| JWT 统一 | `/api/auth/login` → `auth_service.issue_dev_token`;`gateway/jwt_service` issuer/audience 读 `settings` |
| 模块 chat 恢复 | `chat.py` / `agent_service.py` / `memory_service.py`(含 sessions/stream) |
| S2 接缝 | `auth_adapter.module_auth_from_host()` 已接线 |
| trace 中间件 | ApiError / AppError / PermissionDenied / RequestValidationError / StarletteHTTPException **re-raise**;仅未捕获 → 500 |
| 边界测试 | `tests/test_module_boundary.py` 全绿(宿主 D 类文件排除跨层扫描) |
| 测试基线 | **`python -m pytest` → 502 passed, 1 skipped** |
**架构结论:** 宿主 `gateway/` 与模块 `deps.py` **双栈并存**;对外 token 统一;模块 API 禁止 import `app/gateway/`。
> 用途:**给合并执行人**——风控模块开发方已交付(482 用例全绿 + 接口实调验收通过),本文档是该模块并入 main 的全部注意事项。逐项过完再动手,可避开已知的全部坑。
> 裁决依据(冲突逐文件怎么改):**《风控Agent模块边界与合并接缝标注.md》§4 裁决表**——本文档讲"操作顺序与坑",与它配合读。
@@ -36,7 +36,7 @@
| `app/gateway/trade_gateway.py` | 交易网关(C6 需透传 actor_id) |
| `app/model/suitability.py` | 适当性落库行构造(AL-04 引入,与 main 同名 → **冲突时以模块版为准**) |
| `scripts/demo/*`、`scripts/core/*` | 演示与 Core 种子脚本 |
| `tests/`(除 test_module_boundary 外) | 模块测试,406 基线 |
| `tests/`(除 test_module_boundary 外) | 模块测试;**AL-09 后全量基线 502 passed 1 skipped** |
### 1.2 B 类 · 模块私有基建(与宿主同类但模块内自用,**允许与 main 并存**)
@@ -84,7 +84,7 @@ app.include_router(chat_router)
# 模块部分:追加挂载,中间件改为模块内注册(见下)
app.include_router(risk_router)
app.include_router(simulate_router)
setup_risk_module(app) # 待 AL-09 实现:注册 audit + trace 两层 http 中间件
setup_risk_module(app) # AL-09 已完成:注册 audit + trace 两层 http 中间件
```
**注意**:main 用 `add_middleware`,我方用 `@app.middleware("http")`——两种注册方式可共存,但中间件执行顺序需实测确认(trace 必须在 audit 内层,保证 audit 能读到 trace_id)。这列为 AL-09 必测项。
@@ -160,7 +160,7 @@ AL-09 可选优化:让 `config.database` 内部转调 `utils.db.get_engine`,
| 11 | `AGENTS.md` | 文档 | 以我方为准(含 memory 六件套指引),吸收 main 新增条目 |
| 12~18 | `docs/memory/{MEMORY,TODO,REQUIREMENTS,FRAMEWORK,FLOW,ENVIRONMENT,ITERATION}.md` | 文档 | **以我方为准**(六件套是我方进度事实源),逐份吸收 main 新增实质内容 |
| 19 | `scripts/core/02-seed-base.sql` | A 私有 | 手工融合:main 账号(STAFF-10086~50001 等)+ 模块独有 **STAFF-90001**(风控演示账号,main 无!)+ C5 前置 **STAFF-31001/31002** |
| 20 | `tests/conftest.py` | A 私有 | **以模块版为准**(406 用例依赖),再把 main 的 wave0 fixture 增量并入 |
| 20 | `tests/conftest.py` | A 私有 | **以模块版为准**(502 用例依赖),再把 main 的 wave0 fixture 增量并入 |
**另有 13 个 main 独有文件不报冲突、静默并入** → 见 §1.4,全部接纳但模块不得 import。
@@ -170,7 +170,7 @@ AL-09 可选优化:让 `config.database` 内部转调 `utils.db.get_engine`,
| 硬伤 | 原风险 | 自治方案下处置 |
| --- | --- | --- |
| JWT issuer 不一致(`idp.jinrong.internal` vs `.dev`) | 统一后旧 token 全 401 | **不统一**。模块继续认自己的 issuer;跨层调用走 S2 适配器。省掉一次全量 token 重签 |
| JWT issuer 不一致(`idp.jinrong.internal` vs `.dev`) | 统一后旧 token 全 401 | **AL-09 已统一**:`/api/auth/login` → `issue_dev_token`;`gateway/jwt_service` issuer/audience 读 `settings`;旧 dev token 需重签 |
| main 无 STAFF-90001(风控演示账号) | 演示账号变 401 | 模块账号由模块 seed 维护(`02-seed-base.sql` 融合时保留),不走宿主 `DEFAULT_ROLES_BY_ACTOR` |
| main `infer_roles` 未知 actor 默认 `["analyst"]`(fail-open,含 `sql:execute:readonly`) | 越权风险 | 模块鉴权不采用 `infer_roles`;**若宿主侧修复前上线,须在 AL-09 记录为待办 P1**——模块自身为 fail-closed(缺失 X-Agent-Type 即 401) |
@@ -184,14 +184,14 @@ AL-09 可选优化:让 `config.database` 内部转调 `utils.db.get_engine`,
4. 接 S1 挂载点:`main.py` 补 router + 两层中间件,实测中间件顺序(trace 在内层);
5. 处理 S4:确认模块无 `config.database` 导入(防呆测试已覆盖);
6. 融合 `02-seed-base.sql`(保留 STAFF-90001 / 补 STAFF-31001、31002);
7. SOP §2 重灌演示库 → 全量 `pytest` 须回 **406 + 新增边界用例**全绿;
7. SOP §2 重灌演示库 → 全量 `pytest` 须 **502 passed 1 skipped** + 边界用例全绿;
8. uvicorn 冒烟:三端点 + 模块 4 API 逐个验证(注意 JWT 与 debug 头两条通道都要走一遍)。
---
## 7. 待办与遗留
- [ ] AL-09 时实现 `setup_risk_module(app)`(中间件注册函数),当前 main.py 仍为直接装饰器
- [ ] 中间件执行顺序实测(main `add_middleware` vs 模块 `@app.middleware` 双层叠加)
- [ ] 宿主 `infer_roles` fail-open 缺陷:建议在 AL-09 一并提交宿主侧修复(P1,非模块阻塞项)
- [x] AL-09 实现 `setup_risk_module(app)` 与中间件注册(2026-09-08)
- [x] 中间件执行顺序实测;trace 对 ApiError 等 re-raise(2026-09-08)
- [ ] 宿主 `infer_roles` fail-open 缺陷:建议宿主侧修复(P1,非模块阻塞项)
- [ ] 模块代码若未来要彻底隔离,可迁至 `app/modules/risk/`——本次**不做**(属重构,收益 < 风险)
@@ -177,3 +177,4 @@ Agent 对话能力走第 ⑥ 步,**不重复实现 L0 查数逻辑**。
| 日期 | 说明 |
| --- | --- |
| 2026-09-08 | 首版:固化「需求→矩阵→存储→Service→API→Agent」主线及分批策略 |
| 2026-09-08 | AL-09 合并完成:`merger` 分支 502 绿;下一步统筹 Phase A Core REST API v0.1 |