2026-09-05 17:09:21 +08:00
|
|
|
|
# JinRong · 金融四 Agent 智能管家
|
|
|
|
|
|
|
2026-09-07 20:55:00 +08:00
|
|
|
|
四个 Agent(客户财富 / 代理人助手 / 数据分析 / **风控监测**)共用统一数据层与合规底座;Agent 之间**不互调 LLM**,跨 Agent 协作走 L1/L2/L3 画像与预警表。
|
2026-09-05 17:09:21 +08:00
|
|
|
|
|
2026-09-08 20:00:39 +08:00
|
|
|
|
> **当前工作分支:`merger`**(2026-09-08 已完成 AL-09 合并接线:风控模块 + 宿主 Wave 0 共存)。历史交付分支 `risk-control-agent` 已冻结;合并记录见《合并注意事项》执行记录一节。
|
2026-09-05 17:09:21 +08:00
|
|
|
|
|
2026-09-07 20:55:00 +08:00
|
|
|
|
## 你是哪种后续人员?
|
|
|
|
|
|
|
|
|
|
|
|
| 角色 | 先读 |
|
2026-09-05 17:09:21 +08:00
|
|
|
|
| --- | --- |
|
2026-09-08 20:00:39 +08:00
|
|
|
|
| 新 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)(§执行记录) |
|
2026-09-07 20:55:00 +08:00
|
|
|
|
| 了解需求 / 做方案评审 | [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 20:00:39 +08:00
|
|
|
|
## 项目状态(截至 2026-09-08)
|
2026-09-07 20:55:00 +08:00
|
|
|
|
|
2026-09-08 21:44:16 +08:00
|
|
|
|
**AL-09 合并接线完成**:JWT 统一 · 模块 chat/agent/memory 恢复 · auth_adapter 接缝 · **530 passed, 0 skipped**(`python -m pytest`)。核心接口实调此前已通过。
|
2026-09-08 20:00:39 +08:00
|
|
|
|
|
|
|
|
|
|
**下一步(统筹 P1):** Core 公共 API v0.1 · 接口契约发群 · 前端 `web/` init。
|
2026-09-07 20:55:00 +08:00
|
|
|
|
|
|
|
|
|
|
| 里程碑 tag | 内容 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| Wave 0 / T-04 / T-03 / T-21 | JWT 鉴权 · 审计中间件 · chat 闭环 · LangGraph+DeepSeek · Core 只读 Tool · 输入防护 · Milvus 知识库 |
|
|
|
|
|
|
| `risk-m1` | 适当性校验(已换核为 C×R 矩阵契约:match_result 五值 + JR-AST/FM 规则编号) |
|
|
|
|
|
|
| `risk-m2` | 事件线全链路(RISK-001~005 规则引擎 / 预警聚合 / L3 / AML / 交易网关 / 4 个 API) |
|
|
|
|
|
|
| `risk-m3` | 对话线闭环(风控四只读 Tool + StateGraph risk 分支) |
|
|
|
|
|
|
| 阶段一 | 对齐 main 基准 AL-01~08(SUIT-001~008 退役 → core_ro.check_suitability 矩阵判定) |
|
|
|
|
|
|
| `risk-m4` | 追加需求:FR-8 集中度预警 RISK-006 / FR-9 处置时效升级 RISK-007 / FR-10 代理人行为链 RISK-008 |
|
|
|
|
|
|
|
2026-09-08 14:29:33 +08:00
|
|
|
|
**前端接入面(2026-09-08 补齐,后端侧已齐)**:方案 B 会话管理三端点(`8328c24`)+ 方案 C SSE 流式对话(`01ec5fc`)。同步端点 `POST /api/chat` 契约不变,前端可任选同步/流式。详见下文「前端接入契约」。
|
|
|
|
|
|
|
2026-09-08 20:00:39 +08:00
|
|
|
|
**架构定位(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)》。
|
2026-09-07 20:55:00 +08:00
|
|
|
|
|
|
|
|
|
|
## 铁律(改码前必记)
|
|
|
|
|
|
|
|
|
|
|
|
- Core 正式 C1~C5 不可被画像覆盖;Core 库只读(仅模拟交易网关可 INSERT core_trade)
|
|
|
|
|
|
- 审计表(audit_log 等)只 INSERT
|
|
|
|
|
|
- 代理人草稿不自动外发客户;风控不自动冻户
|
|
|
|
|
|
- 仅适当性 R-02 可阻断交易
|
|
|
|
|
|
- 四 Agent 不互调 LLM
|
|
|
|
|
|
- 不改表结构(改表需用户确认);新增依赖须用户确认
|
2026-09-05 17:09:21 +08:00
|
|
|
|
|
|
|
|
|
|
## 后端结构
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
app/
|
2026-09-08 20:00:39 +08:00
|
|
|
|
├── api/ # auth、chat(含 sessions/stream)、risk(4 API)、simulate、deps、auth_adapter、audit_middleware
|
2026-09-07 20:55:00 +08:00
|
|
|
|
├── 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)
|
|
|
|
|
|
├── gateway/ # trade_gateway 模拟交易网关(唯一可写 core_trade)
|
|
|
|
|
|
├── model/ # schemas、suitability(21 列契约)、entities(29 表 ORM 参考)
|
|
|
|
|
|
├── repository/ # core_ro(Core 只读,含 check_suitability 矩阵)、risk_repository、session_repository
|
|
|
|
|
|
├── config/ # settings(双库 + risk_* 阈值 + JWT)
|
|
|
|
|
|
└── utils/ # trace、authz、response(统一错误体)、db、exceptions
|
|
|
|
|
|
|
|
|
|
|
|
scripts/ # core 灌库、demo 演示数据、kb 知识库入库、cron 定时扫描、dev 签发 token
|
2026-09-08 21:44:16 +08:00
|
|
|
|
tests/ # 37+ 模块;530 用例 0 skipped;test_module_boundary.py 锁模块边界
|
2026-09-07 20:55:00 +08:00
|
|
|
|
data/kb/ # 6 只种子产品手册(知识库语料)
|
2026-09-05 17:09:21 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 环境要求
|
|
|
|
|
|
|
2026-09-07 20:55:00 +08:00
|
|
|
|
- **Python 3.13**(项目依赖与 pytest 装在系统 Python 3.13.14)
|
|
|
|
|
|
- MySQL 8.0(双库:`jinrong_core` 模拟 Core 只读 / `jinrong_agent` 业务库)、Redis 8
|
|
|
|
|
|
- Neo4j Desktop(全图同步)、Ollama(bge-m3,1024 维,仅做 embedding)
|
|
|
|
|
|
- Windows 原生部署,不使用本地 Docker(见技术选型文档)
|
2026-09-05 17:09:21 +08:00
|
|
|
|
|
|
|
|
|
|
## 快速启动
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-09-07 20:55:00 +08:00
|
|
|
|
cp .env.example .env # 填 MYSQL_PASSWORD / NEO4J_PASSWORD / DEEPSEEK_API_KEY
|
2026-09-05 17:09:21 +08:00
|
|
|
|
pip install -r requirements.txt
|
2026-09-07 20:55:00 +08:00
|
|
|
|
# 首次灌库与同步:见 docs/memory/FLOW.md §0(权威步骤)
|
|
|
|
|
|
uvicorn app.main:app --reload # → GET http://127.0.0.1:8000/health
|
2026-09-08 21:44:16 +08:00
|
|
|
|
python -m pytest # 基线 530 passed, 0 skipped(系统 Python 3.13.14)
|
2026-09-05 17:09:21 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-09-07 20:55:00 +08:00
|
|
|
|
**演示库重灌(走查/集成测试前必做,两步缺一不可)**:
|
|
|
|
|
|
`scripts/core/reset.ps1`(交互式输密码)→ `scripts/demo/prepare_risk_demo.sql`。
|
|
|
|
|
|
⚠️ 只跑第一步不跑第二步 → 33 客户中 27 人风评过期、约 82% 适当性检查返回 risk_expired,这是种子设计不是 bug。
|
|
|
|
|
|
|
|
|
|
|
|
**调接口(JWT 通道)**:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 签发 token(dev)
|
|
|
|
|
|
python scripts/dev/issue_dev_token.py --sub STAFF-90001 --roles risk_officer
|
|
|
|
|
|
# 调用须同时带两个头
|
|
|
|
|
|
curl -X POST http://127.0.0.1:8000/api/risk/suitability/check \
|
|
|
|
|
|
-H "Authorization: Bearer <token>" -H "X-Agent-Type: risk" \
|
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
|
-d '{"customer_id":"CUST-1001","product_id":"PROD-005827"}'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
dev 环境无 Bearer 时可用 `X-Debug-Role` / `X-Debug-Actor` 头兜底(仅 development + 未配 RS256 公钥时生效)。
|
|
|
|
|
|
|
|
|
|
|
|
## 核心接口一览
|
|
|
|
|
|
|
|
|
|
|
|
| 接口 | 说明 | 权限 |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `GET /api/risk/alerts` | 预警台账分页(FR-4) | risk_officer / risk_manager(只读)/ compliance(仅 aml) |
|
|
|
|
|
|
| `POST /api/risk/alerts/{id}/handle` | 人工处置(状态机 + 审计) | risk_officer |
|
|
|
|
|
|
| `POST /api/risk/suitability/check` | 适当性校验(C×R 矩阵,G-01 归属) | customer 本人 / advisor 名下 / risk_officer |
|
|
|
|
|
|
| `POST /api/risk/aml/scan` | 手动全量 AML 扫描(FR-5) | risk_officer |
|
|
|
|
|
|
| `POST /api/simulate/trade` | 模拟交易(适当性阻断 + 规则引擎) | risk_demo 或客户本人 |
|
|
|
|
|
|
| `POST /api/chat` | 对话(X-Agent-Type 分流四 Agent;风控线四只读 Tool) | 按准入矩阵 |
|
2026-09-08 14:29:33 +08:00
|
|
|
|
| `GET /api/chat/sessions` | 会话列表(本人 + 本 Agent 线,分页) | 按准入矩阵 |
|
|
|
|
|
|
| `GET /api/chat/sessions/{id}/messages` | 会话历史消息(seq_no 升序分页) | 仅本人会话 |
|
|
|
|
|
|
| `POST /api/chat/sessions/{id}/close` | 关闭会话(active→closed) | 仅本人会话 |
|
|
|
|
|
|
| `POST /api/chat/stream` | **SSE 流式对话**(OpenAI 兼容 chunk) | 按准入矩阵 |
|
|
|
|
|
|
|
|
|
|
|
|
> 对话线(含上述全部 `/api/chat*`)**仅 risk_officer**:`risk_manager` 放行 HTTP 台账只读(`GET /api/risk/alerts`),进对话线一律 403(PRD 4A.1 冻结口径)。
|
|
|
|
|
|
|
|
|
|
|
|
## 前端接入契约
|
|
|
|
|
|
|
|
|
|
|
|
**1)会话管理(方案 B)**
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl "http://127.0.0.1:8000/api/chat/sessions?limit=20&offset=0" \
|
|
|
|
|
|
-H "Authorization: Bearer <token>" -H "X-Agent-Type: risk"
|
|
|
|
|
|
# → {"items":[{session_id,agent_type,customer_id,title,status,created_at,...}],"total":2,"limit":20,"offset":0}
|
|
|
|
|
|
|
|
|
|
|
|
curl "http://127.0.0.1:8000/api/chat/sessions/<sid>/messages?limit=50&offset=0" ...
|
|
|
|
|
|
# → {"session_id":"...","items":[{seq_no,role,content,has_disclaimer,created_at}],"total":4,...}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**2)流式对话(方案 C,OpenAI 兼容 chunk)**
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
首帧 data: {"id":"<trace_id>","object":"chat.completion.chunk",
|
|
|
|
|
|
"choices":[{"delta":{"role":"assistant"},"finish_reason":null}],
|
|
|
|
|
|
"meta":{"session_id":"sess-…","trace_id":"…","has_disclaimer":true,
|
|
|
|
|
|
"disclaimer":"以上内容由 AI 生成,仅供业务参考,不构成投资建议。"}}
|
|
|
|
|
|
中间 data: {…,"choices":[{"delta":{"content":"文本块"}}]}
|
|
|
|
|
|
结束 data: {…,"choices":[{"delta":{},"finish_reason":"stop"}],"meta":{"has_disclaimer":true}}
|
|
|
|
|
|
data: [DONE]
|
|
|
|
|
|
异常 data: {"error":{"code":"STREAM_FAILED|PERSIST_FAILED","message":"…"}} → data: [DONE]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
前端须知:
|
|
|
|
|
|
- **免责声明由首帧 `meta.disclaimer` 下发,前端需常驻渲染**(customer/risk 线合规要求);落库文本仍按原口径拼在尾部
|
|
|
|
|
|
- `401/403/404/409/429/400` 在流开始前返回**普通 JSON**,只有正常流才是 `text/event-stream`
|
|
|
|
|
|
- 断连/生成异常 = 整轮消息不落库(Tool 留痕仍可审计),前端需提示重试
|
|
|
|
|
|
- 心跳帧未做:长生成空隙靠反代 `proxy_read_timeout` 兜(已知遗留)
|
2026-09-07 20:55:00 +08:00
|
|
|
|
|
|
|
|
|
|
## 文档地图
|
|
|
|
|
|
|
|
|
|
|
|
| 目录 / 文件 | 内容 |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| [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 · 边界标注 · **合并注意事项** |
|
2026-09-08 20:00:39 +08:00
|
|
|
|
| [docs/项目管理/](docs/项目管理/) | 项目计划 · **04 开发方法**(需求→API 主线)· 表设计字典 |
|
2026-09-07 20:55:00 +08:00
|
|
|
|
| [docs/需求拆解/](docs/需求拆解/) | 业务场景优先级、数据交互矩阵、合规约束、四角色用户故事(docx) |
|
|
|
|
|
|
| [docs/业务记忆管理/](docs/业务记忆管理/) | 业务记忆分层手册 |
|
2026-09-05 17:09:21 +08:00
|
|
|
|
|
|
|
|
|
|
## 前端
|
|
|
|
|
|
|
2026-09-07 20:55:00 +08:00
|
|
|
|
React 19 + Vite 7 + TypeScript strict + Ant Design 5 + HashRouter——`web/` 目录尚未 init,为下一主线。
|
2026-09-08 14:29:33 +08:00
|
|
|
|
|
|
|
|
|
|
后端接入面已就绪,前端只需三件事:① `POST /api/chat/stream` 接 SSE(首帧拿 `session_id`/`disclaimer`,逐帧拼 `delta.content`,收到 `[DONE]` 收尾);② 进页面先 `GET /api/chat/sessions` 拉会话列表、选中后 `GET .../messages` 拉历史;③ 结束会话调 `POST .../close`。所有请求带 `Authorization: Bearer` + `X-Agent-Type`。
|