Files
group_xinghuo_jinrong/docs/项目框架设计/数据分析Agent架构说明书.md
zhanghongyu_0626 793c0307f8 feat(risk): Enhance risk management functionality and access control
- Updated `RiskListAccess` and `ThresholdWriteAccess` to enforce access control in the risk repository and threshold repository, ensuring only authorized roles can perform sensitive operations.
- Introduced new methods in `RiskRepository` for counting pending alerts and listing alerts with access checks, improving data security and compliance.
- Enhanced the `chat.py` and `deps.py` files to integrate compliance roles into the risk management matrix, allowing for more granular access control.
- Updated documentation to reflect the new testing baseline of 825 passed tests, indicating improved stability and functionality across the application.

This update significantly strengthens the risk management capabilities, ensuring robust access control and compliance with organizational policies.
2026-09-11 17:07:22 +08:00

33 KiB
Raw Permalink Blame History

数据分析 Agent 架构说明书

版本:v1.1 · 状态:评审稿(开发期随落地细化) 上游需求:《数据分析 Agent 需求规格(答辩版 v1.2)》docs/需求拆解/01-数据分析Agent需求规格.md 对齐约束:docs/memory/FRAMEWORK.md(分层/选型)、docs/项目框架设计/表设计/(16 表 + Redis Key)、docs/项目框架设计/技术选型和版本/02-JWT-RBAC鉴权手册.md、docs/项目框架设计/Core模拟底座/ 范围声明:本文只描述数据分析 Agent;其余 Agent 仅作为「共用底座 / 数据供给方」出现,不在本文范围。


0. 文档说明

0.1 目的

把需求规格(D-01D-12、N-01N-08)翻译成可实现的技术架构:说清楚数据分析 Agent 由哪些模块组成、数据怎么流、权限怎么兜、SQL 怎么被约束、结果怎么被校验、资产怎么被沉淀,以及每一块落在仓库的哪个目录、哪张表、哪个 Key。

0.2 读者

读者 关注章节
开发(Wave 1 分析组) §4 核心链路、§5 模块划分、§6 LangGraph 编排、§7 数据与存储、§13 接口
平台/底座组 §8 权限与安全、§7.1 复用底座、§13 接口
产品/项目经理 §1 原则、§2 总体架构、§15 落地顺序、§16 验收对照
合规/答辩 §8 五层隔离、§10 数字护栏、§16 验收对照

0.3 需求 ID 对照速查

需求 含义 架构落点
D-01~D-04 客户/产品/预警查数 + 留痕边界 §4 主链路、§8 权限
D-05 复杂交叉问数 §4 多表只读聚合
D-06 查询缓存 §9 双层缓存
D-07 口径统一 §7.2 口径字典、§4 元数据注入
D-08 兜底与拒答 §4 失败分支、§6 节点
D-09 多轮追问 §6 Constrained Edit、§9 短期记忆
D-10 数字护栏 §10
D-11 养 Agent 闭环 §11
D-12 智能看数板 §12
N-01~N-08 消歧/空零/溯源/配额/复用/质量/转人工/可观测 §4/§6/§7/§13 对应小节

1. 架构定位与设计原则

1.1 定位(一句话)

数据分析 Agent = 把「会写 SQL 的人」的生产力变成所有人都能自助调用的只读查数服务:自然语言进、安全 SQL 出、人话解读回、全程可审计、好查询沉淀为资产。

1.2 设计原则

# 原则 说明 对应需求
P1 只读兜底 数据库只读账号 + AST 白名单双保险,任何写操作在生成与执行两层都被拦截 D-04、§5 安全
P2 权限硬约束,不靠提示词自觉 归属注入是系统行为,模型产出的 SQL 必须再被 AST 二次校验 §2.2 五层隔离
P3 数字不赌不猜 解读中的数字必须与 SQL 结果逐字比对,对不上就重生成或降级 D-10
P4 一问一义 指标先经口径字典消歧,多义先反问再生成 D-07、N-01
P5 全链路留痕 trace_id 串联 问题→SQL→结果→判定,审计只 INSERT D-04、F-02
P6 资产可沉淀可回滚 好查询 → 分析师确认 → 版本化发布 → 可灰度可回退 D-11
P7 成本可控 双层缓存 + 配额限流,成本可计量 D-06、N-04
P8 可降级 LLM 超时/报错/校验失败 → 说明性拒答或转人工,不拖垮只读库 N-07、§5 可用性

2. 总体架构

2.1 分层图

┌─────────────────────────────────────────────────────────────────────┐
│                          客户端(内部工作台)                            │
│     聊天窗 · 智能看数板卡片 · 资产沉淀台 · 运营指标面板                  │
└──────────────────────────────┬──────────────────────────────────────┘
                               │ HTTPS + Bearer JWT
                               │ X-Agent-Type: analyst · X-Trace-Id
┌──────────────────────────────▼──────────────────────────────────────┐
│                     Agent Gateway / Auth SDK(共用底座)               │
│   验签 → 角色准入 → 注入 AuthContext → 越权 401/403 写审计             │
└──────────────────────────────┬──────────────────────────────────────┘
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    app/api/analyst.py(薄路由)                        │
│   /chat · /dashboard · /assets · /sample · /escalate · /ops          │
└──────────────────────────────┬──────────────────────────────────────┘
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│             app/service/analyst_agent.py(LangGraph StateGraph)       │
│                                                                      │
│  input_guard → scope_resolve → ambiguity_check → context_retrieve    │
│  → sql_generate → sql_validate → execute → guardrail_check           │
│  → answer_compose → audit_persist ──(analyst)──> asset_candidate     │
│                                                                      │
│  组件:sql_guard(五层) · guardrail(数字护栏) · dict_service(口径)      │
│        cache_service(双层缓存) · analytics_repo(资产/留痕)            │
└──────┬───────────────┬───────────────┬───────────────┬──────────────┘
       ▼               ▼               ▼               ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│  Core RO     │ │  agent 库    │ │  Redis       │ │  LLM          │
│ 只读 Repository│ │ 只读/只增/资产│ │ 会话/缓存/限流│ │ DeepSeek      │
│ (jinrong_core)│ │ (jinrong_agent)│ │              │ │ NL2SQL+解读   │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘

2.2 与四 Agent 共享底座的关系

数据分析 Agent 不建第二套账号/JWT/RBAC,也不自建 Core 副本:

  • 身份/角色/归属 → 复用 Gateway + customer_advisor_rel(Core 同步)。
  • 事实数据 → CoreReadOnlyRepository 只读 jinrong_core。
  • 会话/消息/审计 → 复用 agent_session / agent_message / agent_tool_call / audit_log / input_guard_log。
  • 画像/预警 → 只读 customer_profile_l1/l2/l3、risk_alert(做统计,不可处置)。
  • 专属数据 → analytics_query_log(已定)+ §7.2 新增口径/示例/模板表。

3. 技术栈(引用既有选型,不新增)

层 选型 说明
服务 Python 3.13 + FastAPI 薄路由,不含业务
编排 LangGraph 1.2.x StateGraph + DeepSeek API 状态机图,Tool 节点化
关系库 MySQL 8(jinrong_agent + jinrong_core 双库) 权威落盘 + Core 只读
缓存 Redis 8 会话短期记忆 + 结果/模板缓存 + 限流
SQL 安全 sqlglot(AST 解析白名单) + 只读账号 已确认新增,登记于技术选型文档
图库/向量库 Neo4j / Milvus(一期分析 Agent 不依赖) 预留;关系与 RAG 归其他 Agent

一期数据分析 Agent 强依赖:MySQL 双库 + Redis + DeepSeek + sqlglot;Neo4j/Milvus 不阻塞。


4. 核心链路:NL → SQL → 解读

4.1 全流程(一次问答)

用户提问(自然语言)
   │
   ▼
① 输入防护     guard:rate 限流 → 注入/超长拦截 → input_guard_log
   ▼
② 权限上下文   解析 AuthContext;顾问/风控/运营的归属白名单/数据域
   scope_resolve(顾问白名单实时取 core_customer_advisor active)
   ▼
③ 指标消歧     命中口径字典的多义指标 → 反问候选口径(N-01)
   ambiguity_check   (有歧义则暂停,本轮不生成 SQL)
   ▼
④ 上下文组装   短期记忆(Redis 会话) + 口径字典条目 + schema 元数据 + few-shot
   context_retrieve
   ▼
⑤ SQL 生成     LLM 生成只读 SELECT(多表只读聚合 D-05)
   sql_generate
   ▼
⑥ SQL 校验     五层:白名单/归属注入/AST 越权/列级脱敏/粒度 → 不通过 403
   sql_validate
   ▼
⑦ 执行        查结果缓存(命中标 cache_hit)→ 未命中执行 → 写缓存
   execute       行数上限 1000 / 超时 10s;空结果三态区分(N-02)
   ▼
⑧ 数字护栏     四道校验:数字/单位/时间窗/抽样复核 → 重生成1次 → 降级(D-10)
   guardrail_check
   ▼
⑨ 组装输出     answer + table + sql + meta(data_as_of/cost/cache_hit) + disclaimer
   answer_compose
   ▼
⑩ 留痕         analytics_query_log + agent_tool_call + audit_log(同 trace_id)
   audit_persist
   ▼
⑪ 资产候选     (仅 analyst)半自动提炼 few-shot/模板候选 → 分析师确认发布(D-11)
   asset_candidate

4.2 失败与降级分支

场景 处理 留痕
越权(顾问查他人客户/运营下钻客户维度) 403 + 说明性拒答 + 可查范围引导 analytics_query_log(blocked) + audit_log
SQL 生成失败 / LLM 超时 / 查不到表 说明性拒答 + 一键转人工(N-07) analytics_query_log(error) + audit_log
数字护栏仍不一致(重试 1 次后) 降级输出:只给表格 +「以数据为准」 result_summary 标 guardrail_failed
空结果 区分 zero / no_data / not_match(N-02) 写入解读 + result_summary
缓存命中 直接返回,标 cache_hit=true + data_as_of analytics_query_log

5. 模块划分(app/)

遵守 FRAMEWORK §3 分层:api → service → tool / repository / model / config,api 不写业务,tool 不写流程。

app/
├─ api/
│  └─ analyst.py                 # 路由:/chat /dashboard /assets /sample /escalate /ops   【待实现】
├─ service/
│  ├─ analyst_agent.py           # LangGraph StateGraph 编排 + 各节点                    【待实现】
│  ├─ sql_guard.py               # 只读白名单 / AST 校验 / 归属注入 / 粒度               【待实现】
│  ├─ guardrail.py               # 数字护栏四道校验                                      【待实现】
│  ├─ dict_service.py            # 口径字典读写 + 消歧                                    【待实现】
│  ├─ cache_service.py           # 结果缓存 / 模板缓存 / data_as_of                      【待实现】
│  └─ analytics_repo.py          # analytics_* 表读写(留痕/资产),不写 Core            【待实现】
├─ tool/
│  ├─ core_ro_tool.py            # 包装 CoreReadOnlyRepository 为 Tool 节点              【待实现】
│  └─ sql_tool.py                # 只读执行 + 行数/超时控制 + 空态标记                    【待实现】
├─ repository/
│  └─ core_ro.py                 # Core 只读 SELECT(jinrong_core)                      【已实现】
├─ model/
│  ├─ schemas/analyst.py         # 请求/响应/输出四件套 Pydantic                          【占位】
│  └─ entities/analytics.py      # analytics_* ORM                                          【占位】
├─ config/                       # settings / database(双库连接)                        【settings 已实现】
└─ utils/                        # response / exceptions / logger / trace                【占位】

5.1 关键模块职责边界

模块 做什么 不做什么
sql_guard SELECT 白名单、AST 越权、归属注入、粒度、脱敏列清单 不执行 SQL、不解析业务语义
guardrail 解读数字与结果一致性校验 不生成 SQL
dict_service 指标定义/公式/适用表 + 消歧反问 不直接改口径(仅 analyst 经确认发布)
cache_service 键构造(含权限指纹)、TTL 分层、主动失效 不落 PII 明文
analytics_repo analytics_* 增改查、版本/灰度状态 不写 jinrong_core,不改审计表

6. LangGraph 编排(StateGraph)

6.1 图结构

                 ┌──────────────┐
                 │  input_guard  │
                 └──────┬───────┘
                        │ passed
                 ┌──────▼────────┐
                 │ scope_resolve │
                 └──────┬────────┘
                        │
                 ┌──────▼──────────┐   歧义
                 │ ambiguity_check ├─────────► clarify(反问口径,写会话,结束本轮)
                 └──────┬──────────┘
                        │ 无歧义
                 ┌──────▼──────────┐
                 │ context_retrieve│
                 └──────┬──────────┘
                        │
                 ┌──────▼──────────┐
                 │  sql_generate   │
                 └──────┬──────────┘
                        │
                 ┌──────▼──────────┐   拒绝(403)
                 │  sql_validate   ├─────────► deny(拒答+范围引导+留痕,结束)
                 └──────┬──────────┘
                        │ 通过
                 ┌──────▼──────────┐
                 │     execute     │
                 └──────┬──────────┘
                        │
                 ┌──────▼──────────┐
                 │ guardrail_check │──重试1次──► 回 sql_generate
                 └──────┬──────────┘
                        │ 通过 / 降级
                 ┌──────▼──────────┐
                 │ answer_compose  │
                 └──────┬──────────┘
                        │
                 ┌──────▼──────────┐
                 │  audit_persist  │
                 └──────┬──────────┘
                        │ (analyst 角色)
                 ┌──────▼──────────┐
                 │ asset_candidate │──► 半自动候选(仅提示,不自动生效)
                 └─────────────────┘

6.2 State 概要(Pydantic)

class AnalystState(TypedDict):
    trace_id: str
    session_id: str
    auth: AuthContext              # sub/roles/permissions/agent_type
    nl_question: str               # 本轮问题(追问已带上下文)
    scope: ScopeContext            # 角色数据域 + 归属白名单 customer_id 集合
    ambiguity: Ambiguity | None    # N-01 消歧候选
    context: PromptContext         # schema 元数据 + 口径条目 + few-shot
    sql: str                       # 生成/改写后的 SQL
    validation: ValidationResult   # sql_guard 判定
    result: QueryResult            # rows/columns/空态/data_as_of/cache_hit
    guardrail: GuardrailResult     # 四道校验结果
    answer: AnalystResponse        # 四件套
    status: str                    # success/clarify/deny/degrade/error/escalate

6.3 多轮追问(D-09)—— 与首轮的区别

追问不走结果缓存命中,而是:

  1. 从短期记忆取出上轮 SQL + 上轮口径四件套(指标定义、时间窗、维度、脱敏级别)。
  2. 对 SQL 做受限改写(Constrained Edit):只允许追加/替换分组、过滤、排序,禁止更换事实表。
  3. 改写失败 → 自动降级为全新生成,但必须携带同一口径四件套,保证「同一指标前后一个定义」。
  4. 看板钻取(D-12)复用此链路。

7. 数据与存储

7.1 复用底座(11 表,只读/只增)

表 用途 访问
agent_session / agent_message / agent_tool_call 会话与消息、Tool 调用 读 + 正常业务写
audit_log 审计总账 只 INSERT
input_guard_log 输入防护 只 INSERT
customer_advisor_rel 顾问归属白名单(RBAC 权威) 只读
customer_profile_l1/l2/l3 画像(统计口径可选读) 只读(脱敏/聚合)
risk_alert 预警台账 只读,不可处置
risk_suitability_log 适当性 只读

7.2 专属表

已有(02-mysql-agent专用.sql 已定义):

  • analytics_query_log:NL→SQL→结果留痕,含 sql_hash / exec_status / result_summary。

新增(已定稿 · 独立文件 docs/项目框架设计/表设计/03-mysql-analyst专用.sql):

-- 口径字典:指标名 → 定义/公式/适用表(D-07 / D-11)
CREATE TABLE analytics_metric_dict (
    id                  BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    metric_key          VARCHAR(128)    NOT NULL COMMENT '唯一键,如 holding_scale',
    metric_name         VARCHAR(128)    NOT NULL COMMENT '持仓规模',
    aliases             JSON            NULL COMMENT '同义词:["规模","市值"]',
    definition          TEXT            NOT NULL COMMENT '口径定义',
    formula             TEXT            NULL COMMENT '计算公式',
    applicable_tables   JSON            NULL COMMENT '适用表清单',
    default_time_window VARCHAR(64)     NULL COMMENT '默认时间窗',
    unit                VARCHAR(32)     NULL COMMENT '单位:元/万元/%',
    status              ENUM('draft','published','rolled_back') NOT NULL DEFAULT 'draft',
    version             INT UNSIGNED    NOT NULL DEFAULT 1,
    gray_roles          JSON            NULL COMMENT '灰度:null=全量,["advisor"]=部分角色',
    created_by          VARCHAR(64)     NOT NULL,
    published_by        VARCHAR(64)     NULL,
    created_at          DATETIME(3)     NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    updated_at          DATETIME(3)     NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
    UNIQUE KEY uk_metric (metric_key, version),
    KEY idx_status (status, metric_key)
) ENGINE=InnoDB COMMENT='【分析专用】口径字典(D-07/D-11)';

-- few-shot 示例:问题 → 正确 SQL 对(D-11)
CREATE TABLE analytics_few_shot (
    id                BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    question          TEXT            NOT NULL,
    sql_text          TEXT            NOT NULL,
    tags              JSON            NULL,
    source_session_id VARCHAR(64)     NULL COMMENT '溯源',
    status            ENUM('draft','published','rolled_back') NOT NULL DEFAULT 'draft',
    version           INT UNSIGNED    NOT NULL DEFAULT 1,
    gray_roles        JSON            NULL,
    created_by        VARCHAR(64)     NOT NULL,
    published_by      VARCHAR(64)     NULL,
    created_at        DATETIME(3)     NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    updated_at        DATETIME(3)     NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
    KEY idx_status (status, id)
) ENGINE=InnoDB COMMENT='【分析专用】few-shot 示例(D-11)';

-- 快速模板:参数化 SQL(D-06 模板缓存 / D-11)
CREATE TABLE analytics_query_template (
    id             BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    template_key   VARCHAR(128)    NOT NULL,
    template_sql   TEXT            NOT NULL COMMENT '参数化 SQL,如 WHERE risk_code IN (:risk_codes)',
    params_schema  JSON            NULL COMMENT '参数定义',
    tags           JSON            NULL,
    source_session_id VARCHAR(64)  NULL,
    status         ENUM('draft','published','rolled_back') NOT NULL DEFAULT 'draft',
    version        INT UNSIGNED    NOT NULL DEFAULT 1,
    gray_roles     JSON            NULL,
    created_by     VARCHAR(64)     NOT NULL,
    published_by   VARCHAR(64)     NULL,
    created_at     DATETIME(3)     NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    updated_at     DATETIME(3)     NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
    KEY idx_status (status, template_key)
) ENGINE=InnoDB COMMENT='【分析专用】快速模板(D-06/D-11)';

三表分建(已定);灰度字段 gray_roles 用于「先灰度部分角色验证再全量」。建表 SQL 见 docs/项目框架设计/表设计/03-mysql-analyst专用.sql。

7.3 Redis Key(分析 Agent 新增部分)

沿用 {domain}:{agent}:{entity}:{id} 规范:

Key 类型 TTL 说明
sess:analyst:{session_id}:ctx Hash 2h 追问上下文 + 上轮 SQL + 口径四件套
sess:analyst:{session_id}:msgs List 2h 最近 N 轮窗口
cache:analyst:result:{perm_fp}:{sql_hash} String(JSON) 分层 结果缓存(键含权限指纹)
cache:analyst:scope:{staff_id} String(JSON) 5m 顾问名下客户白名单(转岗/离职立即失效)
cache:analyst:top:{staff_id} String(JSON) 24h 中期记忆:常用查询 TOP + 偏好口径
guard:rate:{actor_id}:analyst String INCR 1m 限流(复用 F-03)

TTL 分层(D-06): 交易类 5min / 台账类 1h / 基础信息类当日。

7.4 缓存失效(data_as_of 与主动失效)

  • 响应 meta.data_as_of 标明数据截至时间(区分 T+1 / 准实时)。
  • 交易/持仓/归属等事实表变更时主动 DEL 对应缓存键,不等 TTL。
  • 一期模拟库:由 scripts/sync/sync_advisor_rel.py(归属)与 Core reset/更新流程广播失效;生产切换 CDC/binlog 订阅,Agent 层失效接口不变。

8. 权限与安全:五层隔离实现

需求 §2.2 五层 → 实现组件映射:

层 需求 实现组件 校验时机
1 身份 Mock JWT(HS256,24h 续期) Gateway / Auth SDK;payload 含 user_type/employee_role 入口
2 角色 RBAC 数据域 RbacGuard.can(ctx, perm);analyst 角色 → sql:execute:readonly 入口 + Tool
3 行级归属 归属强制注入 + 二次校验 scope_resolve 取白名单 → sql_guard 在生成阶段注入 WHERE customer_id IN (:scope) → AST 校验超范围 403 生成 + 校验
4 列级脱敏 存储层已脱敏 种子已存 mask;API/日志/归档同源;脱敏列清单由 sql_guard 维护 读取
5 粒度控制 聚合 vs 明细 sql_guard 检查是否含客户级下钻;ops 无客户维度 → 拒绝 + 说明 校验

越权处理: 403 + 双留痕(audit_log 总账 + analytics_query_log 记录问题与拒绝原因),可演示「顾问 A 问顾问 B 的客户 → 被拒且留痕可查」。

SQL 安全双保险(D-04 / §5 安全):

  1. 生成侧:sql_guard 用 sqlglot 解析 AST → 仅允许 SELECT(含 WITH/子查询白名单)→ 拦截多语句/写语句/DDL。
  2. 执行侧:数据库连接使用只读账号(jinrong_core 只读;jinrong_agent 业务表按角色授权)。
  3. 资源侧:LIMIT 1000 / 10s 超时。

9. 缓存与记忆(D-06 / §9.1 定稿方案)

9.1 双层缓存

层 命中对象 机制
结果缓存 同形态独立问题 键 = 权限指纹 + sql_hash;直接秒回;命中标 cache_hit=true;PII 不落或脱敏
模板缓存 跨会话同形态问题 命中参数化模板 → 填参执行;资产发布后自动入池(D-11 联动)

追问变体不走缓存命中,走上轮 SQL 受限改写(见 §6.3)。

9.2 三层记忆

层 载体 内容 用途
短期 Redis 会话级 30min 追问上下文、上轮 SQL、口径四件套 D-09 追问 / D-12 钻取 / D-10 重试
中期 Redis 用户级 24h 常用查询 TOP + 偏好口径 调优缓存 TTL、看板排序
长期 MySQL 资产表 few-shot / 字典 / 模板 D-11 资产,喂养模板缓存

10. 数字护栏(D-10 · 亮点)

guardrail_check 对解读执行四道校验,任一失败 → 重生成(默认 1 次)→ 仍失败 → 降级输出(只给表格 +「解读校验未通过,以数据为准」):

  1. 数字比对:提取解读中全部数字/金额,与 SQL 结果逐项比对。
  2. 单位/币种/百分比:元 vs 万元、% vs bp。
  3. 时间窗一致性:「近 30 天」按自然日/交易日解析正确。
  4. 抽样复核:抽 1~2 行回源明细核对(与 N-03 共用链路)。

校验结果(通过/重试/降级)写入 result_summary + audit_log。

答辩台词:「LLM 有幻觉,但我们不赌它不犯——我们校验它。」


11. "养 Agent" 闭环(D-11 · 亮点)

分析师问答 → 已执行 SQL → 半自动提炼候选(few-shot/模板/字典)
        │
        ▼
分析师确认 → 发布(版本化)→ 灰度(gray_roles)→ 生效 → 喂模板缓存
        │
        ▼
出问题 → 一键回滚(status=rolled_back,回到上一版本)
  • 仅 analyst 角色可写;每次沉淀操作审计留痕。
  • 资产三类:few-shot 示例 / 口径字典条目 / 快速模板。
  • 版本化 + 可回滚 + 可灰度;系统从每次已执行 SQL 半自动提炼候选,分析师仅确认。
  • 生效后同类问题命中新资产,analytics_query_log.result_summary 标 source=沉淀资产。

12. 智能看数板(D-12 · 亮点)

  • 定位:预聚合概览 + 钻取入口,不是独立报表系统。
  • 角色化卡片(后端返回结构化 JSON,前端下轮渲染):
    • analyst:客户总数 / 总持仓规模 / 今日交易笔数金额 / 待处理预警数 / 口径字典资产数
    • advisor:名下客户数 / 名下资产规模 / 盈亏分布 / 风险等级分布(仅名下)
    • risk_officer:待处理预警数 / 按类型分布 / 近 7 天新增趋势
    • ops:近 30 天申购赎回金额 / 各产品类型规模 TOP(仅聚合)
  • 卡片钻取 → 复用 D-09 追问链路,指标与对话打通。
  • 边界:同样走只读层 + 角色权限;加载与钻取留痕;准实时/按需,不做实时推送。

13. 接口设计(REST,X-Agent-Type: analyst)

方法 路径 说明 需求
POST /api/analyst/chat 主对话/追问(SSE 可选,首版 JSON) D-01~D-05/D-09
GET /api/analyst/sessions/{id}/messages 会话消息回放 D-04
GET /api/analyst/dashboard 看板数据(按角色) D-12
GET /api/analyst/query/{trace_id}/sample 聚合结果抽样明细(脱敏) N-03
POST /api/analyst/assets/{dict|few_shot|template} 沉淀资产(仅 analyst) D-11
POST /api/analyst/assets/{kind}/{id}/publish 发布/灰度 D-11
POST /api/analyst/assets/{kind}/{id}/rollback 回滚 D-11
POST /api/analyst/query/{trace_id}/save 存为常用(P1) N-05
POST /api/analyst/query/{trace_id}/share 分享(继承接收方权限,P1) N-05
POST /api/analyst/query/{trace_id}/subscribe 订阅刷新(P1) N-05
POST /api/analyst/escalate 一键转人工(写审计) N-07
GET /api/analyst/ops/metrics 运营指标(P1) N-08

统一输出四件套(§3 全局约定):

{
  "answer": "人话解读…",
  "table": { "columns": ["risk_code","cnt"], "rows": [["C1",4]] },
  "sql": "SELECT …",
  "meta": { "exec_ms":45, "row_count":5, "cache_hit":false, "data_as_of":"2026-09-04", "source":"jinrong_core", "cost_est":0.002 },
  "disclaimer": "本内容仅为投资分析参考,不构成任何直接投资建议…"
}

14. 非功能需求落点

类别 需求 落点
安全 只读/注入拦截/越权拒绝/脱敏 §8 sql_guard + 只读账号
合规 免责声明/不处置/不推荐/不对客 answer_compose 固定 disclaimer + D-02/D-03 边界
性能 超时与行数上限 1000/10s + 缓存 §4 execute、§9 缓存
审计 trace_id 全链路可还原 §4 audit_persist
可运营 资产可维护、版本化回滚灰度 §11
数据新鲜度 data_as_of + 主动失效 §7.4
成本 成本计量 + 配额限流 meta.cost_est + guard:rate + N-04
可观测 通过率/命中率/拒答率/成本/转人工率 §13 /ops/metrics(N-08)
可用性 超时降级,不拖垮只读库 §4.2 失败分支 + N-07

15. 落地顺序与实现状态

阶段 内容 状态
Wave 0(平台) JWT/RBAC(T-01)、审计贯通(T-02)、agent 库灌库(T-05) 未做(复用,非分析组)
Wave 1-A(P0 闭环) analytics_query_log + sql_guard + analyst_agent 主链路 → D-01~D-04 闭环 未做
Wave 1-B(P0 增强) 口径字典(D-07)、缓存+记忆(D-06)、追问改写(D-09)、数字护栏(D-10) 未做
Wave 1-C(P0 亮点) 养 Agent 资产沉淀(D-11)、智能看数板后端(D-12)、消歧(N-01)、空零(N-02)、溯源(N-03)、转人工(N-07) N-03/N-07 已做;D-12 未做
Wave 2(P1) 配额(N-04)、保存/分享/订阅(N-05)、质量提示(N-06)、运营面板(N-08) 未做

已有实现:CoreReadOnlyRepository(只读 SELECT)、settings 双库、Core 模拟库脚本、customer_advisor_rel 同步脚本。分析 Agent 业务层尚未实现。


16. 验收对照(演示即验收)

需求演示 架构断言
「按产品类型统计总持仓规模」 sql_validate 通过 → execute → 四件套正确
「查 CUST-1004(非名下)持仓」 scope_resolve 白名单不含 → 403 + 双留痕
「当前待处理大额预警占比」 risk_alert 只读统计,处置意图被拒
「近一月申购金额总额」(运营) 粒度控制:仅聚合,无客户明细
同形态问题重复问 结果缓存命中 cache_hit=true
「数字加起来是 123 万吗」 guardrail 四道校验拦截或通过
沉淀 few-shot 后问同类问题 命中沉淀资产,source=沉淀资产
点看板卡片钻取 复用 D-09 改写链路

17. 待定项

# 待定项 当前立场
1 口径字典/few-shot/模板三表是否合一 已定:三表分建,见 03-mysql-analyst专用.sql
2 新增依赖 sqlglot(AST 白名单) 已确认,登记于技术选型文档与 requirements.txt
3 D-12 钻取实现深度 已定做钻取,细节开发期细化
4 看板刷新策略 准实时/按需,不做实时推送
5 结果缓存失效通道(CDC vs 同步脚本) 一期用同步脚本广播,生产切 CDC

18. 决策记录

决策点 结论
编排 LangGraph StateGraph,节点化 Tool
SQL 安全 sqlglot AST 白名单 + 只读账号双保险
权限 五层隔离,行级归属系统注入 + 二次校验
缓存 结果/模板双层 + 短期/中期/长期三层记忆
数字护栏 四道校验,重试 1 次后降级
资产 仅 analyst 可写,版本化/回滚/灰度(gray_roles)
专属表 口径字典/few-shot/模板三表分建,独立 03-mysql-analyst专用.sql
看数板 后端 JSON 接口先行,前端下轮渲染
一期依赖 不依赖 Neo4j/Milvus

变更记录

版本 日期 变更
v1.0 2026-09 初版:基于需求规格 v1.2 生成,对齐 FRAMEWORK/表设计/JWT 手册/Core 模拟
v1.1 2026-09 确认新增 sqlglot;口径字典/few-shot/模板三表分建,DDL 独立为 03-mysql-analyst专用.sql