Files
group_fqcd_jr/docs/46-投顾Agent需求文档.md
T
Windows 560775156c docs: 新增投顾 Agent 需求文档与功能架构文档
依据仓库既有设计与已落地代码反推整理,内容与当前实现一致(非前瞻设计)。

- docs/46-投顾Agent需求文档.md
  · 背景与三个真实断点(交付无落点 / 文案不可读 / 客户无入口)
  · 目标 G1-G5 与 4 条非目标(不真实下单、不预测收益、不自动投资、不做场外)
  · 角色场景 SC-01~SC-05、两条主链路流程图
  · 功能需求 FR-01~FR-21(含口径、优先级、验收标准)
  · 业务规则:候选池硬约束 fail-closed、5 条合规红线、状态机、FM-03 熔断
  · 非功能需求、异常处理表、权限矩阵、数据需求、验收清单、11 项待确认问题

- docs/47-投顾Agent功能架构文档.md
  · 五层架构总览、后端模块划分与 3 条设计约束、数据模型与关系
  · 接口清单(投顾 8 / 客户 3 / 依赖能力 3 组)
  · 三张时序图(生成推荐、审核发布、申报受理)
  · 外部依赖降级矩阵、前端模块结构与 2 条硬约定、权限灰度、配置清单、已知约束
2026-09-16 18:17:45 +08:00

15 KiB
Raw Blame History

投顾 Agent 需求文档(PRD)

文档版本:v1.0(2026-09-16) 文档状态:已实现反推稿 —— 本章所记需求均已在本仓库落地并本地验证,非前瞻设计 适用范围:投顾 Agent(投顾工作台 + 客户端「我的投顾方案」+ 客户主动申报) 依据材料(均为仓库内既有文档与代码,非本文件臆造): · 设计:docs/01(通用 Agent 平台)、docs/03(端到端流程)、docs/05(接口文档)、 docs/22(四大 Agent 拆解)、docs/30(投顾迁移 TODO)、docs/31(投顾灰度与回滚)、 docs/43(场内产品手册)、docs/44(演示流程) · 代码:app/service/product_recommendation_service.py、advisor_service_request_service.py、 advisor_reason_service.py、app/api/controllers/recommendations.py、advisor_service_requests.py、 app/static/portal/employee-advisor/dashboard/*、app/static/portal/customer/advisor-plans/*


1. 背景与目标

1.1 问题陈述

投顾业务的真实痛点在于「选品可解释 + 交付可追溯」:

  • 投顾给客户荐品,必须能说清为什么是这几只(适当性匹配、期限/流动性匹配、证据可核查);
  • 方案从生成到到达客户手里,必须留痕、且未经审核不得对客户可见;
  • 客户侧长期是单向接收,缺少「主动提出需求」的入口。

此前系统里推荐能力存在,但存在三处断点:

断点 表现
交付无落点 投顾「发送给客户」只改数据状态,客户端没有任何页面/接口能读到已发布方案
文案不可读 每只产品的「推荐依据」是同一句套话,客户看不出差异
客户无入口 客户只能被动等方案,无法主动申报

1.2 目标(G)

编号 目标 衡量方式
G1 推荐可解释:每只入选产品都能给出基于真实参数的依据 方案里每只产品都有独立依据,且含风险等级/匹配关系
G2 交付可追溯:审核与发布分离,未发布对客户不可见 状态机 + published_at 双条件;客户接口只返回已发布
G3 呈现可感知:客户能看到走势图、指标与组合构成 客户端可展示净值折线图、环形配置图、区间收益与最大回撤
G4 客户能发起:客户可主动申报,投顾后台受理后出方案 申报→受理→生成草稿→审核→发送 全链路打通
G5 合规不越线:不得承诺收益,证据缺失即整只排除 硬约束 fail-closed + 文案合规守卫

1.3 非目标(本期明确不做)

非目标 说明
真实下单 推荐方案不产生交易指令,客户仍需在交易页自行下单
收益预测 不预测未来收益,只呈现历史区间收益与最大回撤
自动投资 无自动调仓、无定投、无代客操作
场外基金 投顾范围限定场内基金,场外走独立模块(见 docs/22)

2. 角色与场景

2.1 角色定义

角色 角色码 入口 核心诉求
投顾 advisor /portal/employee-advisor/dashboard/ 代客出方案、审核发布、处理客户申报
客户 customer /portal/customer/advisor-plans/ 接收方案、主动申报、查看申报进度
管理员 admin / super_admin 管理面 审核、发布、故障处置(不受灰度限制)

2.2 核心场景

编号 场景 触发方
SC-01 投顾选择名下客户 → 生成推荐方案 → 审核通过 → 发送给客户 投顾
SC-02 投顾查看历史方案记录(含草稿)→ 抽查内容详情 投顾
SC-03 客户登录 → 在「我的投顾方案」查看已收到的方案 客户
SC-04 客户提交投顾方案申报 → 投顾受理 → 自动出草稿 客户→投顾
SC-05 投顾受理后审核、发布,客户看到方案变为「已发送方案」 投顾→客户

3. 业务流程

3.1 主链路 A:投顾主动出方案

flowchart LR
    A[投顾选择客户] --> B[合规熔断校验 FM-03]
    B -- 测评失效 --> X[熔断拦截 转人工]
    B -- 通过 --> C[生成推荐方案]
    C --> D{候选池硬约束}
    D -- 某产品缺证据 --> E[整只排除 fail-closed]
    D -- 通过 --> F[排序取 TopN]
    E --> F
    F --> G[LLM 生成推荐依据]
    G --> H[落库 pending_review]
    H --> I[投顾审核通过]
    I --> J[发布给客户]
    J --> K[客户可见]

3.2 主链路 B:客户主动申报

flowchart LR
    A[客户填写申报单] --> B[服务端校验风险测评有效性]
    B -- 未测评/已过期 --> X[拒绝 并提示原因]
    B -- 通过 --> C[落库 pending]
    C --> D[投顾工作台出现待办]
    D --> E{投顾受理 or 驳回}
    E -- 驳回 --> F[填理由 客户可见]
    E -- 受理 --> G[自动跑推荐逻辑 出草稿]
    G --> H[投顾审核 + 发送]
    H --> I[申报单变 已发送方案]

4. 功能需求

优先级:P0 本期必须 / P1 重要 / P2 增强。

4.1 客户与画像

编号 功能 口径 优先级 验收标准
FR-01 投顾查看名下客户 范围 = 本人 + sys_customer_assignment 归属客户 P0 非归属客户不可见,越权返回 403
FR-02 风险测评(客户自助) ONB001 取题 / ONB002 提交;结果落服务端权威画像 P0 测评结果由服务端权威返回,前端不得自行计算风险等级
FR-03 熔断前置校验 测评超过 12 个月或缺失 → FM-03 拦截 P0 前端展示熔断横幅,接口返回 blocked_by_fuse

4.2 组合诊断与配置

编号 功能 口径 优先级 验收标准
FR-04 组合分析 集中度、行业穿透与流动性 P1 返回可展示的诊断结论
FR-05 资产配置 按风评与目标给出配比与偏离 P1 目标缺失时返回 investment_goal_required
FR-06 画像评分 本地演示引擎计算(后端无对应接口,明确标注"规则模拟") P2 结果区必须带演示标识
FR-07 调仓建议 同上,本地引擎 P2 结果区必须带演示标识

FR-06/FR-07 由本地演示引擎计算,前端会明确标注;不得被误认为真实后端结论。

4.3 推荐方案生成(核心)

编号 功能 口径 优先级 验收标准
FR-08 生成推荐方案 POST /api/v1/advisor/recommendations,需 16-128 位 ASCII 幂等键 P0 同键重试返回同一方案,不重复建单
FR-09 候选池硬约束 产品须同时具备:场内可交易 + 销售机构已验证适当性证据 + 基金合同快照;缺任一即整只排除 P0 排除原因可查(前端「排除原因」提示词)
FR-10 排序与入选 按适当性等级、目标期限、目标流动性筛选后综合打分取 TopN(默认 3) P0 返回 selection_summary:候选/入选/排除数
FR-11 推荐依据生成 规则文案兜底;配置大模型时改写为面向客户的说明 P0 文案必须含真实参数;命中收益承诺词即丢弃并回退
FR-12 审核 reviews 接口,decision ∈ {approved, rejected} P0 未审核不得发布
FR-13 发布 publications 接口,置 review_status 与 published_at P0 发布后客户可见;重复发布幂等

4.4 历史记录与交付

编号 功能 口径 优先级 验收标准
FR-14 历史方案记录 本人生成的全部状态方案 P0 状态标签与后端状态一致,不使用枚举兜底文案
FR-15 客户接收方案 GET /api/v1/users/me/advisor-contents:只看本人、已审核且 published_at 非空 P0 未发布的方案对客户不可见
FR-16 方案可视化 净值折线图(带坐标轴/网格)、组合业绩(等权合成 + 最大回撤)、资产配置环形图 P1 数据缺失显示「暂无数据」,不显示 0

4.5 客户主动申报

编号 功能 口径 优先级 验收标准
FR-17 客户提交申报 金额(万元)/ 投资期限 / 风险偏好 / 备注 P0 服务端校验取值与风评有效性
FR-18 我的申报 只看自己的申报单与状态 P0 状态含 待受理/已受理/已发送/已驳回
FR-19 投顾申报队列 本人 + 归属客户的申报,待受理排前 P0 非归属客户的申报不可处理
FR-20 受理并生成方案 受理即调用现有推荐逻辑自动出待审核草稿 P0 生成失败给出人话原因,并保持待受理
FR-21 驳回 需填理由(可选),客户可见 P1 驳回后申报单不可再被受理

5. 业务规则

5.1 候选池硬约束(fail-closed)

产品必须同时满足三项,缺一即排除:

  1. 场内可交易;
  2. 适当性证据:销售机构的已验证适当性证据,带可核查来源链接与 document_sha256;
  3. 合同快照:基金合同快照,同样带来源与摘要。

按目标继续过滤:

维度 规则
风险等级 客户风评等级对应的禁投风险级直接排除
投资期限 短于目标期限下限的产品排除
流动性 不符合目标流动性要求(如 30 日内可用)的产品排除

5.2 合规红线(必须遵守,代码强制)

# 红线
1 不得出现收益承诺与绝对化表述(保本/保证收益/稳赚/无风险/收益承诺…)
2 未审核发布的方案对客户不可见
3 推荐不产生交易指令,仅作分析参考
4 客户不得自行修改风险测评结果(服务端权威)
5 全流程留痕(审核、发布、受理、驳回均记录操作人与时间)

5.3 状态机

推荐方案

stateDiagram-v2
    [*] --> pending_review: 生成方案
    pending_review --> approved: 审核通过
    pending_review --> rejected: 驳回
    approved --> 已发布: 发送给客户
    rejected --> [*]
    已发布 --> [*]

「已发布」不是独立状态字段,而是 review_status ∈ {approved, published} 且 published_at 非空 —— 避免两处状态各写各的而对不上。

客户申报单

stateDiagram-v2
    [*] --> pending: 客户提交
    pending --> accepted: 投顾受理(自动生成方案草稿)
    pending --> rejected: 投顾驳回
    accepted --> 已发送: 关联方案发布后推导

已发送(delivered) 同样不落库,由关联方案的 published_at 推导。

5.4 熔断 FM-03

条件 结果
无风险测评 拦截,提示先完成测评
测评超过 12 个月 拦截(服务端判 valid_until,缺失时按 12 个月兜底)
熔断生效时 客户仅可办理赎回,流程转人工

6. 非功能需求

类别 要求
幂等 写接口必须带 16-128 位 ASCII Idempotency-Key;同键重试返回首次结果
降级 图谱(Neo4j)、大模型、行情任一不可用,业务继续可用并明确标注降级
留痕 审核/发布/受理/驳回写入审计;演示口径留存 ≥ 20 年
限流 按「用户 + 方法 + 路由」计数,超限 429;Redis 不可用时降级放行
灰度 ADVISOR_ROLLOUT_ENABLED 开启后仅白名单客户与管理员可访问投顾业务
前端一致性 同一页面内同一模块的 ?v= 版本号必须一致(否则双实例)

7. 异常处理

场景 返回 前端呈现 可恢复动作
客户无风险测评 profile_required 结果区提示 先做风险测评
无已确认投资目标 investment_goal_required 结果区提示 先录入并确认目标
推荐数量越界 422 RECOMMENDATION_PARAM_INVALID 结果区提示 改为 1-3
权限不足 403 「当前账户暂不可访问 / 权限不足」+ toast 换有权限的账号
未开户(资金类) 404 「客户未开户」 先建模拟账户
行情/净值缺失 503 / 空数据 「暂无净值数据」 跑 tools/sync_nav_history.py
大模型不可用 无异常 依据回退为规则文案 关闭开关或换 key
熔断 blocked_by_fuse 熔断横幅 转人工

8. 权限矩阵

能力 客户 投顾 管理员
提交/查看自己的申报 ✅ advisor-request:write:self / read:self — —
查看自己的已发布方案 ✅ product-recommendation:read:self — —
生成/查看/删除推荐方案 — ✅ ✅
审核 / 发布方案 — ✅(自助) ✅
查看客户申报队列 — ✅ advisor-request:read ✅
受理 / 驳回申报 — ✅ advisor-request:review ✅
灰度限制 — 受白名单限制 不受限

权限码定义源:tools/seed_test_rbac.py;投顾角色的授权工具:tools/grant_advisor_role.py。


9. 数据需求

表 用途 关键字段
client_facing_content 方案与方案书 content_type / customer_id / review_status / published_at / draft_content
advisor_service_request 客户申报单 request_no(唯一) / customer_id / amount_wan / horizon / risk_preference / status / result_content_id
sys_customer_assignment 投顾-客户归属 决定投顾可见范围
fin_product / fin_market_price / fin_nav_history 产品、行情、净值 图表与指标的数据源
api_request_receipt 幂等 user_id / scope_hash / idempotency_key / request_hash
interaction_audit 审计留痕 操作人、动作、明细

10. 验收清单

# 验收项 方法
1 投顾生成方案 → 结果区出现卡片与图表 工作台执行「生成推荐方案」
2 审核通过后发布 → 客户可见 客户页出现该方案
3 未发布方案对客户不可见 客户页不出现草稿
4 同幂等键重试不重复建单 连续两次提交同键
5 客户申报 → 投顾队列出现 → 受理后自动出草稿 两端对照
6 文案命中收益承诺词被丢弃 单测 test_advisor_reason_service.py
7 大模型不可用时回退规则文案 关闭开关后重生成
8 越权客户不可见/不可处理 换非归属客户验证 403

11. 待确认问题

# 问题 影响
Q1 适当性证据与合同快照的真实数据来源何时接入?当前候选为 0(证据缺失 fail-closed) 阻塞:决定演示用真实方案还是本地引擎
Q2 推荐依据是否允许出现历史业绩之外的表述(如基金经理风格)? 影响文案提示词
Q3 客户申报是否需要额度/频率限制(防刷)? 影响 FR-17
Q4 申报单与投资目标的关系:受理后是否自动创建投资目标? 影响 FR-20 之后流程
Q5 灰度白名单的最终放量范围? 影响验收范围