- Implemented `check_suitability` method in `CoreReadOnlyRepository` for suitability determination based on customer and product risk levels. - Added `build_suitability_log_row` function in `suitability.py` for mapping suitability check results to `risk_suitability_log`. - Updated `AGENTS.md`, `ENVIRONMENT.md`, and `FLOW.md` to reflect changes in suitability assessment processes and documentation. - Revised `FRAMEWORK.md` and `MEMORY.md` to clarify project structure and data flow related to suitability checks. - Expanded `TODO.md` with tasks related to logging and auditing suitability assessments.
11 KiB
11 KiB
Core 模拟底座方案(无真实 Core、无 HTTP API)
状态:已落地(2026-09-05)
详见 01-表结构与种子说明.md
1. 要解决什么问题
| 需求 | 没有 Core 时的问题 | 本方案 |
|---|---|---|
| C-01/A-01 查持仓 | 无数据 | 种子持仓表 |
| R-02 适当性 | 无 C1~C5 / 产品 R 等级 | 种子测评 + 产品风险等级 |
| F-01 代理人只看名下客户 | 无归属 | 种子归属 + 同步到 customer_advisor_rel |
| D-01 分析 Agent 查数 | 无宽表 | Core 库可被只读 SQL 查(同 MySQL 实例) |
| R-01 大额监测 | 无交易流 | 种子交易 + 可选「注入脚本」模拟新交易 |
| Neo4j 关系图 | 无源 | 从 Core 库 同步脚本 灌图 |
不做什么:
- 不模拟真实 TA/清算/报盘
- 不提供 HTTP Core API(以后有真 Core 再换 Adapter,Repository 接口不变)
- 不让 Agent 写 Core 库(无 UPDATE/INSERT 权限或代码层禁止)
2. 推荐架构(方案 A · 首选)
┌─────────────────────────────────────────────────────────┐
│ MySQL 8.0(本机 :3306,同一实例两个库) │
├─────────────────────────┬───────────────────────────────┤
│ jinrong_core │ jinrong_agent │
│ 【模拟 Core · L0 权威】 │ 【Agent 平台 · 已有 16 表】 │
│ 客户/产品/持仓/流水/测评 │ 会话/画像/预警/审计 │
│ ★ Agent 只读 SELECT │ Agent 读写 │
└───────────┬─────────────┴───────────────┬───────────────┘
│ │
│ scripts/sync/*.py │
└──────────► customer_advisor_rel (agent 库)
└──────────► Neo4j (可选 sync_neo4j.py)
┌─────────────────────────────────────────────────────────┐
│ app/repository/core_ro.py │
│ 只读 SQL · 禁止写 · 供 Tool / 分析 Agent 白名单 schema │
└─────────────────────────────────────────────────────────┘
为何不用 API、不用 JSON 文件?
| 方案 | 优点 | 缺点 | 结论 |
|---|---|---|---|
| A. 独立库 jinrong_core + SQL 种子 | 贴近真 Core;D-01 可直接 SELECT;易 reset | 多一套 DDL | 推荐 |
| B. JSON/YAML fixtures | 简单 | 分析 Agent 难 SQL;大数据量慢 | 仅适合单元测试 |
| C. 全塞进 agent 库 | 一张库 | 违反「Core / Agent 分治」;合规演示不清 | 不推荐 |
3. 库与目录规划
scripts/
└── core/
├── 00-create-database.sql # CREATE DATABASE jinrong_core
├── 01-ddl.sql # Core 表结构
├── 02-seed-base.sql # 产品、代理人、风险等级字典
├── 03-seed-customers.sql # 客户 L0 + 测评
├── 04-seed-holdings.sql # 持仓
├── 05-seed-trades.sql # 流水/交易(含 R-01 大额样例)
├── 06-seed-nav.sql # 净值/行情(C-05)
├── reset.ps1 # Windows:drop 数据 + 重跑 seed
└── README.md # 执行顺序
scripts/sync/
├── sync_advisor_rel.py # core → jinrong_agent.customer_advisor_rel
└── sync_neo4j.py # core → Neo4j(P0 可选第二批)
app/
└── repository/
├── __init__.py
└── core_ro.py # 只读查询封装(无 HTTP)
docs/项目框架设计/Core模拟底座/
├── 00-方案总览.md # 本文件
└── 01-表结构与种子说明.md # 确认后补充字段级文档
执行顺序(开发/答辩前):
1. mysql < scripts/core/00-create-database.sql
2. mysql < scripts/core/01-ddl.sql
3. mysql < scripts/core/02~06-seed-*.sql
4. mysql < docs/.../01-mysql-共用底座.sql # agent 库(若未建)
5. python scripts/sync/sync_advisor_rel.py
6. python scripts/sync/sync_neo4j.py # 可选
4. Core 库表设计(P0 最小集)
命名前缀
core_,与 agent 库表 绝不重名。
| 表名 | 对应 L0 能力 | P0 场景 |
|---|---|---|
core_advisor |
理财师/员工 | F-01、A-01 |
core_customer |
客户主档(脱敏字段) | 全 Agent |
core_customer_risk |
正式 C1~C5 + 测评时间 | R-02、C-07 |
core_customer_advisor |
客户-代理人归属 | F-01 → 同步 agent 库 |
core_product |
基金/产品 + R1~R5 | C-02、R-02 |
core_holding |
持仓份额、成本、市值、盈亏% | C-01、A-01、C-04 |
core_trade |
申购/赎回/转换流水 | R-01、D-01 |
core_cash_flow |
资金进出 | C-01 |
core_product_nav |
最新净值/日涨跌 | C-05 |
P1 可加: core_industry、core_dividend、core_aml_list(R-03 名单)
4.1 关键字段约定
- 主键统一字符串:
CUST-xxxx、STAFF-xxxx、PROD-xxxx、TRD-xxxx - 金额
DECIMAL(18,2);份额DECIMAL(18,4);盈亏比例DECIMAL(8,4) - 所有事实表带
as_of DATE或updated_at,展示时必须带「数据截至」 core_customer_risk.is_authoritative = 1表示 L0 正式等级(Agent 不可写此表)
5. 种子数据设计(演示用 personas)
建议 少而全:6 个客户 + 2 代理人 + 8~10 产品,覆盖 P0 验收。
| customer_id | 正式等级 | 代理人 | 用途 |
|---|---|---|---|
CUST-9527 |
C3 | STAFF-10086 | 主 demo:正常持仓、问持仓/净值 |
CUST-1001 |
C1 | STAFF-10086 | R-02:尝试买 R5 应阻断 |
CUST-1002 |
C2 | STAFF-10086 | 亏损接近阈值 C-04 |
CUST-2001 |
C4 | STAFF-10087 | 跨代理人:10086 不能查 |
CUST-3001 |
C3 | STAFF-10086 | R-01:单笔 50 万+ 交易 seed |
CUST-4001 |
C5 | STAFF-10087 | 高龄 + 高风险产品冲突(R-02) |
| advisor_id | 名下客户 |
|---|---|
STAFF-10086 |
9527, 1001, 1002, 3001 |
STAFF-10087 |
2001, 4001 |
| product_id | 风险 | 说明 |
|---|---|---|
PROD-110022 |
R2 | 债基,C1 可买 |
PROD-005827 |
R3 | 混合 |
PROD-161725 |
R4 | 行业主题 |
PROD-XYZ999 |
R5 | 用于适当性拒单 demo |
Milvus 产品文档仍走 data/kb/ + 向量库;Core 的 core_product 只放 结构化字段(代码、名称、R 等级、费率摘要),与 RAG 文档通过 product_id 关联。
6. 应用层:只读 Repository(非 API)
# app/repository/core_ro.py 职责边界
class CoreReadOnlyRepository:
"""仅 SELECT jinrong_core.*;连接只读账号或同一连接但方法内禁止写。"""
def get_customer_l0(customer_id: str) -> CustomerL0
def list_holdings(customer_id: str) -> list[Holding]
def list_trades(customer_id: str, since: date) -> list[Trade]
def get_product(product_id: str) -> Product
def get_latest_nav(product_id: str) -> NavQuote
def list_customers_by_advisor(advisor_id: str) -> list[str] # 归属
- Tool 层(agent_service)只调 Repository,不拼裸 SQL。
- 数据分析 Agent:SQL 网关白名单仅允许
jinrong_core+jinrong_agent指定表;默认禁止 JOIN 跨库写。 - 以后有真 Core:新增
CoreHttpAdapter实现同一接口,种子库保留作集成测试。
7. 同步脚本(模拟「Core → Agent/Neo4j」)
7.1 sync_advisor_rel.py
读 core_customer_advisor (status=active)
→ UPSERT jinrong_agent.customer_advisor_rel
→ 供 JWT 归属校验 / F-01
7.2 sync_neo4j.py(第二批)
core_customer / core_advisor / core_product / core_holding
→ Neo4j Customer/Advisor/Product/HOLDS/ASSIGNED_TO/HAS_RISK_LEVEL/REQUIRES_MIN_RISK
同步频率:开发期手动跑;README 写「改 seed 后必跑 sync」。
7.3 inject_trade.py(可选)
命令行:模拟一笔新交易写入 core_trade
→ 触发风控 Agent 测试 R-01(不必真 API)
8. 权限与安全(开发期)
| 项 | 做法 |
|---|---|
| MySQL 用户 | agent_app:对 jinrong_agent 读写;对 jinrong_core 仅 SELECT |
| 代码 | Repository 内仅 session.execute(text("SELECT ...")) |
| 测试 | 断言无 INSERT/UPDATE/DELETE 指向 jinrong_core |
答辩环境可共用 root;生产模拟仍建议分权限。
9. 与现有文档的用语对齐
| 原说法 | 落地后 |
|---|---|
| Core 只读 API | Core 只读 Repository(查 jinrong_core) |
| Core 同步 | scripts/sync/*.py |
| L0 | jinrong_core 表内正式字段 |
| F-04 | Agent 不写 core 库,只 SELECT |
建议在 业务记忆管理手册.md §8 加一句:「开发期 Core = jinrong_core 模拟库」。
10. 实施分期
| 阶段 | 交付 | 工期估 |
|---|---|---|
| P0-1 | DDL + base/customer/holding seed + sync_advisor_rel | 1~2 天 |
| P0-2 | core_ro.py + 2 个 Tool(持仓/产品)+ C-01/A-01 可 demo | 1~2 天 |
| P0-3 | trade seed + inject_trade + R-01/R-02 联调 | 1 天 |
| P1 | sync_neo4j + nav seed + D-01 跨表 SQL | 1~2 天 |
11. 验收清单
jinrong_core与jinrong_agent同实例不同库,Agent 代码无 core 写操作- 客户 CUST-9527 可查持仓;CUST-2001 代理人 10086 查不到(403)
- CUST-1001(C1)买 PROD-XYZ999(R5)→ R-02 阻断记录
reset.ps1一键清空并重灌 seed,同步 rel 后代理人权限仍正确- 分析 Agent 可对
jinrong_core.core_holding做 COUNT/GROUP BY
12. 待你确认的点
已确认:33 客户 / 14 产品、RBAC 多角色、Neo4j P0、静态净值、KYC/C×R 矩阵对齐客户手册。
13. 关联文档
- 05-多Agent共用底座清单.md §七 Core 只读接口 → 本方案替代实现
- 04-neo4j-model.md
- 业务记忆管理手册.md §8 M4 官方事实
- 业务场景优先级清单.md P0 场景