Files
X-Financial/document/development/risk-rule-explainable-flow/CONCEPT.md
caoxiaozhu 92444e7eae feat: 扩展风险规则体系、审批动态路由与预算中心列表化改造
- 新增 25+ 条风险规则(预算/报销/申请/通用类),完善风险规则模拟与反馈发布机制
- 引入费用审批动态路由、平台风险分级、预审与风险阶段管理
- 预算中心列表化改造,优化票据夹仪表盘与数字员工工作看板
- 新增 Hermes 风险线索收集器、Agent 链路追踪中心
- 扩展数字员工能力库(18 个领域 Skill)与交通费用自动预估
- 完善报销申请快速预览、权限控制与前端测试覆盖
2026-06-01 17:07:14 +08:00

582 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 风险规则可解释流程判断改造方案
## 功能一句话
把风险规则从“自然语言生成一段 JSON”升级为“自然语言、字段本体、可执行 JSON DSL、流程判断图、测试命中路径、版本修改”一致闭环让业务用户能看懂规则怎么判断让系统按同一套逻辑执行。
## 背景与问题
当前风险规则已经具备自然语言创建、JSON 风险规则、风险评分、详情页流程图、仿真测试和上线启用能力,但仍有几个关键缺口:
- 规则解释不够稳定。用户输入复杂业务规则后,系统可能把“城市是否一致、日期是否越界、是否存在合理说明”解释成“是否出现关键词”,这会导致业务语义失真。
- 流程图容易变成展示装饰。如果流程图不严格从可执行 JSON DSL 派生,就会出现“页面看起来是 A后端实际执行是 B”的问题。
- 测试结果缺少路径解释。用户上传票据和输入意图后,需要知道系统识别到了哪些字段、走过哪些判断节点、为什么命中或未命中。
- 规则修改缺少版本化闭环。已上线规则不能直接覆盖,应创建修订版本,旧版本继续生效,新版本测试通过后再替换。
- 常见费控规则需要模板化扩展。预算、票据、差旅、招待、采购/AP、企业卡等规则应进入规则模板库但仍必须走同一套解释和执行链路。
## 目标与非目标
### 目标
- [G1] 自然语言规则经过 Hermes 语义理解后,生成结构稳定、可校验、可执行的 JSON DSL。
- [G2] 流程判断图必须由 JSON DSL 派生,不能直接由自然语言单独生成。
- [G3] 详情页展示“文字流程解释 + 流程图 + 使用字段 + 风险分数 + 规则状态”,让业务用户能确认系统理解是否正确。
- [G4] 测试规则时展示本次样例或票据仿真的字段识别结果、判断路径、命中节点和最终结论。
- [G5] 用户觉得规则不合理时,通过“创建修订版本”修改,线上版本保持稳定。
- [G6] 常见费控规则模板库可以复用同一套 DSL、流程图和测试机制。
### 非目标
- [NG1] 本期不做流程图编辑器,不允许拖拽、改节点、缩放编辑或在线画图。
- [NG2] 本期不让大模型作为风险命中裁判。Hermes 只负责理解、生成、解释和辅助解析,最终命中由规则执行器决定。
- [NG3] 本期不把所有复杂政策一次性建成完整专家系统,先保证规则表达、解释和执行一致。
- [NG4] 本期不直接覆盖已上线规则,所有线上修改都走修订版本。
## 用户与场景
- 财务规则制定者:创建风险规则,查看系统理解是否正确,修改草稿规则。
- 高级财务人员 / admin审核、上线、下线、启用、停用、删除未发布规则。
- 普通报销用户:在真实业务命中风险时看到简明原因,可反馈误判或漏判。
- 系统执行链路:报销、费用申请、预算占用、票据识别、采购/AP 等场景只加载已上线且已启用的规则。
核心场景:
1. 新建规则:输入规则标题、费用业务环节、费用领域、是否需要附件、自然语言规则。
2. 生成规则Hermes 结合字段本体输出 JSON DSL、业务说明、风险评分、流程模型和 SVG。
3. 查看详情:用户确认“系统理解的字段、判断条件、例外说明、命中动作”是否正确。
4. 仿真测试:用户上传附件并输入测试意图,系统统一识别字段,再由执行器判断当前规则。
5. 修改规则:未上线规则直接编辑;已上线规则创建修订版本,测试通过后发布替换。
## 功能能力
### C1. 自然语言输入能力
新建风险规则表单应包含:
- 规则标题。
- 业务环节:费用申请、报销、预算控制、付款/采购等。
- 费用领域:差旅、住宿、交通、招待、办公、培训、会议、软件服务、通讯、福利、预算、发票、采购/AP、通用。
- 是否需要附件:需要时测试弹窗开放附件上传;不需要时隐藏上传入口。
- 自然语言规则描述。
风险等级不允许用户手动选择,由评分模型输出风险分数和等级。
### C2. 语义理解与字段本体映射
Hermes 需要输出一份中间语义计划,而不是直接写死 JSON
- 规则意图:判断什么业务风险。
- 适用范围:业务环节、费用领域、费用科目、单据类型。
- 所需字段:中文解释、英文字段名、来源、是否必填。
- 票据字段OCR 或文档智能识别得到的城市、日期、金额、销售方、发票号等。
- 判断步骤:按顺序表达条件、分支、例外说明和命中动作。
- 例外条件:例如延期、改签、跨城办事、临时任务等说明。
- 风险动作:提醒、人工复核、要求补充说明、退回修改、禁止提交。
字段展示统一为:
```text
申报目的地[claim.destination_city]
明细发生地点[item.location_city]
交通票行程城市[receipt.transport_route_cities]
住宿发票城市[receipt.hotel_city]
出差开始日期[trip.start_date]
出差结束日期[trip.end_date]
报销事由[claim.reason]
```
### C3. 可执行 JSON DSL
JSON DSL 应表达规则执行逻辑,而不是保存自然语言摘要。建议基本结构:
```json
{
"rule_id": "risk.travel.city_mismatch",
"version": "v1",
"scope": {
"business_stage": "reimbursement",
"expense_types": ["travel", "lodging"]
},
"required_fields": [
{
"label": "申报目的地",
"field": "claim.destination_city",
"source": "claim",
"required": true
}
],
"conditions": {
"all": [
{
"op": "in_scope",
"field": "expense.type",
"values": ["travel", "lodging"]
},
{
"op": "any_present",
"fields": [
"receipt.transport_route_cities",
"receipt.hotel_city",
"item.location_city"
]
},
{
"op": "none_match",
"left_fields": [
"receipt.transport_route_cities",
"receipt.hotel_city"
],
"right_fields": [
"claim.destination_city",
"item.location_city",
"trip.route_cities"
],
"matcher": "city_equivalent"
},
{
"op": "not_contains_any",
"field": "claim.reason",
"values": ["延期", "改签", "跨城办事", "临时任务", "绕行"]
}
]
},
"action": {
"risk_level": "high",
"risk_score": 76,
"decision": "review_required",
"message": "票据城市与申报目的地或行程城市不一致,且未说明合理原因。"
}
}
```
核心要求:
- 城市、日期、金额、人员、供应商等字段必须使用专门比较算子,不能退化成“关键词出现”。
- 复杂规则允许多层条件组合:`all``any``not``branch``exists``range``compare``semantic_contains`
- 例外说明可以使用语义包含,但只能影响“是否进入复核/降级/豁免”,不能替代结构化字段判断。
- DSL 生成后必须通过 schema 校验和执行器 dry-run。
### C4. 流程判断图
流程图不是编辑器,也不是自然语言插图。流程图必须由 JSON DSL 转换成 `flow_model`,再生成 SVG。
建议 `flow_model`
```json
{
"nodes": [
{
"id": "start",
"type": "start",
"title": "开始",
"description": "进入差旅住宿报销风险检查"
},
{
"id": "scope",
"type": "decision",
"title": "是否属于差旅住宿报销",
"fields": ["expense.type", "claim.business_stage"]
},
{
"id": "city_match",
"type": "decision",
"title": "票据城市是否匹配申报或行程城市",
"fields": [
"receipt.hotel_city",
"receipt.transport_route_cities",
"claim.destination_city",
"trip.route_cities"
]
},
{
"id": "hit",
"type": "risk",
"title": "命中高风险",
"description": "要求补充行程说明或退回修改"
}
],
"edges": [
{ "from": "start", "to": "scope", "label": "开始检查" },
{ "from": "scope", "to": "end_pass", "label": "否" },
{ "from": "scope", "to": "city_match", "label": "是" },
{ "from": "city_match", "to": "end_pass", "label": "是" },
{ "from": "city_match", "to": "hit", "label": "否" }
]
}
```
流程图展示要求:
- 详情页左侧为文字流程解释,右侧为“流程图”。
- 判断分支用“是 / 否 / 通过 / 不通过 / 缺失 / 存在”等明确标签。
- 风险命中框使用风险等级颜色:低风险蓝色,中风险橙色,高风险红色,极高风险深红色。
- 普通节点保持 SaaS 白底、细边框、低饱和样式,不能整张图都染成风险色。
- 图只做展示,不响应拖拽、编辑、缩放和节点点击。
- 节点数量超过 8 个时,需要自动压缩文字、合并说明节点或分页展示,避免图过大。
### C5. 测试命中路径
测试规则弹窗应展示三类信息:
1. 输入与识别结果
- 用户自然语言测试意图。
- 上传附件清单。
- OCR / 文档智能识别字段。
- Hermes 辅助规范化后的结构化字段。
2. 规则执行结果
- 是否进入适用范围。
- 每个判断节点的输入值、比较方式、判断结果。
- 命中的风险动作。
- 未命中的原因。
3. 流程图路径高亮
- 使用同一个 `flow_model`
- 本次执行走过的节点和边由执行器输出 `trace`
- 前端按 `trace` 高亮路径。
执行 trace 示例:
```json
{
"trace_id": "run_001",
"matched": true,
"risk_level": "high",
"risk_score": 76,
"steps": [
{
"node_id": "scope",
"result": true,
"inputs": {
"expense.type": "住宿费",
"claim.business_stage": "reimbursement"
}
},
{
"node_id": "city_match",
"result": false,
"inputs": {
"receipt.hotel_city": "北京",
"claim.destination_city": "上海",
"trip.route_cities": ["武汉", "上海"]
}
}
]
}
```
### C6. 规则修改与版本化
规则修改分三种:
- 未上线规则:允许创建者或 admin 直接编辑,保存后重新生成 DSL、流程图、评分和说明。
- 已上线规则:不允许直接覆盖,必须点击“创建修订版本”。
- 业务用户反馈:只能提交误判/漏判反馈,由管理员决定是否创建修订版本。
已上线规则修改流程:
```text
线上版本 active
创建修订版本 draft_revision
编辑自然语言 / 参数 / 附件要求
重新生成 JSON DSL + 流程图 + 评分
仿真测试通过
发布新版本
旧版本归档,新版本 active
```
版本记录必须包含:
- 修改人。
- 修改原因。
- 修改前后自然语言差异。
- 修改前后 DSL 差异。
- 测试报告。
- 发布时间。
- 是否替换线上版本。
## 方案设计
### 总体链路
```text
自然语言规则
字段本体召回与业务域约束
Hermes 生成语义计划 semantic_plan
语义计划校验与补全
生成 JSON DSL
Schema 校验 + 执行器 dry-run
风险评分 risk_score / risk_level
DSL 转 flow_model
flow_model 转 flow_diagram_svg
详情展示 + 仿真测试 + 上线执行
```
### 前端设计
涉及入口:
- `AuditRuleDialogs.vue`:新建风险规则表单,后续增加修订版本编辑入口。
- `AuditJsonRiskRuleDetail.vue`:详情页展示基本信息、测试状态、流程解释、流程图、操作按钮。
- `RiskRuleFlowDiagram.vue`:只负责展示 SVG 或由 `flow_model` 派生的静态图,不做编辑。
- `RiskRuleTestDialog.vue`:仿真测试窗口,展示输入识别、执行路径、测试报告。
- `auditViewRiskRuleModel.js` / `auditViewModel.js`:规则详情视图模型、列表字段和状态映射。
详情页建议结构:
```text
Topbar规则标题、状态、风险分数、风险等级、上线/启用状态
基本信息:费用领域、业务环节、附件要求、创建人、上线时间、最后操作、测试状态
判断流程:
左侧:文字流程解释
右侧:流程图
测试与版本:
最近测试报告
修订版本 / 历史版本
操作按钮
```
修改规则界面建议采用左右布局:
- 左侧:自然语言规则编辑、规则标题、费用领域、附件要求。
- 右侧:系统解释预览,包括字段、本体映射、流程解释、风险分数。
- 底部:重新生成、保存草稿、测试规则、提交上线。
### 后端设计
已有相关模块应优先复用:
- `risk_rule_generation.py`:规则生成主流程。
- `risk_rule_generation_prompt.py`Hermes 提示词。
- `risk_rule_generation_ontology.py`:字段本体和费用领域约束。
- `risk_rule_generation_semantics.py`:自然语言语义解释。
- `risk_rule_generation_interpreter.py`:解释结果到 DSL。
- `risk_rule_scoring.py`:风险评分。
- `risk_rule_flow_diagram.py`:流程图 SVG 生成。
- `risk_rule_manifest_normalizer.py`:规则 manifest 规范化。
- `risk_rule_template_executor.py`:规则执行器。
- `agent_asset_risk_rule_testing.py`:规则测试、删除、发布、启用。
- `agent_asset_risk_rule_simulation.py`:仿真测试对话。
后端需要补齐的能力:
- 生成 `semantic_plan` 并持久化到 `config_json` 或版本内容中。
- 生成并持久化 `flow_model`,再生成 `flow_diagram_svg`
- 执行器输出 `trace`,用于测试解释和流程图高亮。
- 支持创建修订版本,避免直接覆盖 active 版本。
- 支持从常见模板创建规则,模板也走同一套生成和校验链路。
### 接口设计
建议新增或调整:
```text
POST /agent-assets/risk-rules/generate
根据自然语言创建生成任务,返回生成中资产。
POST /agent-assets/{asset_id}/risk-rules/regenerate
对草稿或修订版本重新生成 DSL、评分和流程图。
POST /agent-assets/{asset_id}/risk-rules/revisions
基于已上线规则创建修订版本。
PATCH /agent-assets/{asset_id}/risk-rules/draft
保存未上线规则或修订版本的编辑内容。
POST /agent-assets/{asset_id}/risk-rule-tests/simulate
独立仿真测试返回字段识别、执行结果、trace。
GET /agent-assets/{asset_id}/risk-rule-tests/latest
返回最近测试摘要。
POST /agent-assets/{asset_id}/publish
发布通过测试的规则版本。
```
### 数据设计
建议在风险规则版本内容或 `config_json` 中保留:
```json
{
"source_text": "用户输入的自然语言规则",
"semantic_plan": {},
"dsl": {},
"flow_model": {},
"flow_diagram_svg": "<svg>...</svg>",
"flow_explanation": [],
"risk_score": 76,
"risk_level": "high",
"required_attachment": true,
"required_fields": [],
"last_operation": {
"action": "publish",
"actor": "admin",
"at": "2026-05-30T10:00:00+08:00"
}
}
```
测试记录保留:
```json
{
"test_type": "simulation",
"input_text": "我去北京出差 3 天,上传武汉到上海车票",
"attachments": [],
"recognized_fields": {},
"normalized_fields": {},
"execution_result": {},
"trace": {},
"passed": true,
"tester": "admin",
"tested_at": "2026-05-30T10:10:00+08:00"
}
```
## 算法与公式
### 风险评分
风险评分由模型辅助判断,但必须结构化输出。建议使用可解释加权模型:
$$
score = \min(100, base + \sum_{i=1}^{n} w_i x_i + c + e)
$$
变量说明:
- $base$:业务领域基础风险分。预算、发票、付款类通常高于普通提示类。
- $x_i$:风险因子是否存在或强度,例如金额影响、附件缺失、字段冲突、越权、历史重复。
- $w_i$:风险因子权重。
- $c$:复杂度修正,例如多字段交叉、跨单据、跨时间窗口、跨附件识别。
- $e$:例外说明修正。存在合理说明时可降低,但不能直接清零。
等级映射:
- 0-30低风险。
- 31-60中风险。
- 61-80高风险。
- 81-100极高风险。
### 流程复杂度控制
为了避免流程图过大,建议定义流程复杂度:
$$
complexity = node_count + 0.5 \times edge_count + branch_count
$$
处理规则:
- `complexity <= 12`:单图展示。
- `12 < complexity <= 20`:合并说明节点,保留关键判断。
- `complexity > 20`:详情页展示主流程,测试弹窗展示完整 trace。
## 测试方案
### 单元测试
- 语义计划生成:复杂差旅城市规则不能退化为关键词判断。
- DSL schema 校验:缺字段、非法算子、空 action 必须失败。
- 执行器:城市匹配、日期范围、金额阈值、附件缺失、例外说明。
- 流程转换:同一 DSL 生成稳定的 `flow_model` 和 SVG。
- 风险评分:低/中/高/极高边界分数。
### 接口测试
- 新建规则返回生成中资产。
- 生成完成后包含 `dsl``flow_model``flow_diagram_svg``risk_score`
- 仿真测试返回 `recognized_fields``normalized_fields``trace`
- 未测试通过的规则不能发布。
- 已上线规则创建修订版本,不覆盖线上版本。
### 前端测试
- 新建弹窗不再选择风险等级。
- 详情页展示风险分数、流程解释、流程图。
- 流程图不可点击、不可拖拽、无工具栏。
- 测试弹窗显示字段识别结果和判断路径。
- 已上线规则只能创建修订版本修改。
### 容器验证
后续开发验证默认在 Docker 容器内执行:
```bash
docker exec x-financial-main sh -lc "cd /app/server && pytest <target> --timeout=60"
docker exec x-financial-main sh -lc "cd /app/web && npm run build"
```
### 本轮落地结果
已落地接口:
- `GET /agent-assets/risk-rules/templates`:返回预算、票据、差旅、招待、采购/AP、企业卡、通用模板分组包含默认自然语言、字段清单、附件要求和 DSL 样例。
- `PATCH /agent-assets/{asset_id}/risk-rules/draft`:编辑未上线风险规则草稿。
- `POST /agent-assets/{asset_id}/risk-rules/revisions`:为已上线规则创建修订草稿。
- `POST /agent-assets/{asset_id}/risk-rules/regenerate`:重新生成 DSL、流程图、风险评分和业务说明。
- `POST /agent-assets/{asset_id}/risk-rules/feedback``GET /agent-assets/{asset_id}/risk-rules/feedback`:记录和查看误判/漏判反馈。
关键文件:
- 后端模板库与契约:`risk_rule_template_catalog.py``agent_asset.py``agent_asset_risk_rules.py`
- 后端生成、修订、发布、反馈、仿真:`risk_rule_generation*``agent_asset_risk_rule_revision.py``agent_asset_risk_rule_regeneration.py``agent_asset_risk_rule_publish.py``agent_asset_risk_rule_feedback.py``agent_asset_risk_rule_simulation.py`
- 前端新建、详情、测试:`AuditRuleDialogs.vue``AuditJsonRiskRuleDetail.vue``RiskRuleFlowDiagram.vue``RiskRuleTestDialog.vue``auditViewDetailTopBar.js``useAuditRiskRuleActions.js``useAuditAssetData.js`
- 测试:`test_risk_rule_template_catalog.py``test_risk_rule_feedback.py``test_risk_rule_revision_endpoints.py``test_risk_rule_explainability.py``risk-rule-detail-experience.test.mjs`
已执行验证命令:
```bash
docker exec x-financial-main bash -lc "cd /app/server && timeout 60 /tmp/x-financial-server-venv/bin/python -m pytest tests/test_risk_rule_template_catalog.py tests/test_openapi_schema.py -q"
docker exec x-financial-main bash -lc "cd /app/server && timeout 60 /tmp/x-financial-server-venv/bin/python -m pytest tests/test_risk_rule_feedback.py tests/test_risk_rule_revision_endpoints.py tests/test_openapi_schema.py -q"
docker exec x-financial-main bash -lc "cd /app/web && timeout 60 node --test tests/risk-rule-detail-experience.test.mjs"
docker exec x-financial-main bash -lc "cd /app/web && timeout 60 npm run build"
```
## 指标与验收
- [A1] 新建复杂差旅规则后,详情页流程解释不能出现“检查是否包含风险关键词”这类错误表达。
- [A2] 详情页流程图与 JSON DSL 条件数量、分支方向、命中动作一致。
- [A3] 仿真测试能显示票据识别字段,并说明为什么命中或未命中。
- [A4] 同一条测试样例的执行 trace 可以高亮流程图路径。
- [A5] 已上线规则修改时不会改变当前线上执行结果,只有发布修订版本后才替换。
- [A6] 低、中、高、极高风险都能由评分模型产出,不应默认集中在中高风险。
- [A7] 前端构建通过,后端定向测试 60s 内完成。
## 风险与开放问题
- LLM 语义理解仍可能出错,因此必须有 schema 校验、执行器 dry-run、详情解释和仿真测试兜底。
- 字段本体不完整会限制规则表达,需要持续扩展费用、票据、预算、采购/AP 字段。
- 复杂规则可能产生过大的流程图,需要主流程和完整 trace 分层展示。
- 老规则没有 `semantic_plan``flow_model`,需要兼容展示并允许重新生成。
- 常见规则模板要避免写成定制逻辑。模板只能提供默认文本、字段和 DSL 样例,最终仍走通用生成链路。
当前仍需持续演进的点:
- 企业卡、采购/AP、预算场景的字段本体还偏少后续应补充企业卡交易流水、供应商、采购订单、合同、预算期间等字段。
- 复杂规则的准确性仍依赖 Hermes 语义计划质量,执行前必须继续保留 DSL validator、执行器 dry-run 和仿真测试。
- 模板库只作为规则编写入口的业务参考,不作为规则执行捷径;新增模板时必须同时提供 DSL 样例和 validator 测试。
## 实现确认
当前实现仍围绕“解释图和执行逻辑一致”推进:自然语言先经字段本体和语义计划形成受控 JSON DSL详情页流程图、文字流程解释、测试 trace、上线版本均围绕同一份 DSL 展示和执行,没有新增流程图编辑器或绕过规则执行器的判断链路。