Files
X-Financial/document/development/hermes-risk-graph-algorithm/index.html
caoxiaozhu 7989f3a159 feat: 新增风险图谱算法与系统仪表盘及操作反馈体系
后端新增风险图谱算法模块、风险观察与反馈服务、规则 DSL
校验器和可解释性引擎,完善系统仪表盘和财务仪表盘统计,
优化 agent 运行和编排执行链路,清理旧开发文档,前端新增
系统趋势、负载热力图等多种仪表盘图表组件,完善操作反馈
对话框和工作台日期选择器,优化报销创建和审批详情交互,
补充单元测试覆盖。
2026-05-30 15:46:51 +08:00

1484 lines
48 KiB
HTML
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.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>X-Financial 财务行为图谱风险引擎核心算法说明</title>
<style>
:root {
color-scheme: light;
--bg: #f5f7f8;
--surface: #ffffff;
--surface-soft: #f8fbfc;
--surface-strong: #edf3f5;
--ink: #172126;
--ink-soft: #44525a;
--muted: #6b7a83;
--line: #dce5ea;
--line-strong: #c2d0d8;
--blue: #235a8f;
--blue-deep: #153e66;
--blue-soft: #e8f1f8;
--teal: #16756f;
--teal-soft: #e7f4f2;
--green: #28784a;
--green-soft: #e9f5ed;
--amber: #9a6200;
--amber-soft: #fff4dd;
--red: #b43d32;
--red-soft: #fff0ee;
--violet: #5b4b9a;
--violet-soft: #f0eef9;
--shadow: 0 18px 44px rgba(24, 38, 48, 0.08);
--shadow-soft: 0 10px 26px rgba(24, 38, 48, 0.06);
--radius: 8px;
--font: "Microsoft YaHei UI", "Microsoft YaHei", "PingFang SC", "Segoe UI", sans-serif;
--mono: "Cascadia Code", "JetBrains Mono", Consolas, monospace;
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
background:
linear-gradient(180deg, rgba(232, 241, 248, 0.92), rgba(245, 247, 248, 0.98) 420px),
var(--bg);
color: var(--ink);
font-family: var(--font);
font-size: 14px;
line-height: 1.72;
letter-spacing: 0;
overflow-wrap: anywhere;
}
a {
color: inherit;
text-decoration: none;
}
code {
padding: 2px 6px;
border-radius: 6px;
background: rgba(35, 90, 143, 0.08);
color: var(--blue-deep);
font-family: var(--mono);
font-size: 0.92em;
}
pre {
margin: 0;
padding: 16px;
overflow: auto;
border: 1px solid #20313c;
border-radius: var(--radius);
background: #101920;
color: #eef7fb;
font-family: var(--mono);
font-size: 12.5px;
line-height: 1.72;
white-space: pre;
}
.page {
display: grid;
grid-template-columns: 278px minmax(0, 1fr) 260px;
min-height: 100dvh;
}
.sidebar,
.aside {
position: sticky;
top: 0;
height: 100dvh;
overflow: auto;
background: rgba(255, 255, 255, 0.92);
backdrop-filter: blur(16px);
}
.sidebar {
padding: 24px 18px;
border-right: 1px solid var(--line);
}
.aside {
padding: 24px 18px;
border-left: 1px solid var(--line);
}
main {
min-width: 0;
padding: 34px 42px 64px;
}
.brand {
display: grid;
gap: 12px;
padding-bottom: 20px;
border-bottom: 1px solid var(--line);
}
.brand-row {
display: flex;
align-items: center;
gap: 12px;
}
.brand-mark {
display: grid;
width: 44px;
height: 44px;
place-items: center;
border-radius: 8px;
background: #142c3f;
color: #fff;
font-size: 13px;
font-weight: 900;
box-shadow: 0 14px 28px rgba(20, 44, 63, 0.24);
}
.brand-title {
color: var(--ink);
font-size: 15px;
font-weight: 900;
line-height: 1.28;
}
.brand-subtitle {
color: var(--muted);
font-size: 12px;
line-height: 1.58;
}
.nav-label,
.aside-title {
margin: 22px 0 10px;
color: var(--muted);
font-size: 12px;
font-weight: 850;
}
.nav {
display: grid;
gap: 5px;
}
.nav a,
.mini-link {
display: flex;
align-items: center;
min-height: 34px;
padding: 7px 10px;
border-radius: 8px;
color: var(--ink-soft);
font-size: 13px;
font-weight: 760;
}
.nav a:hover,
.mini-link:hover {
background: var(--blue-soft);
color: var(--blue-deep);
}
.dot {
flex: 0 0 auto;
width: 7px;
height: 7px;
margin-right: 10px;
border-radius: 99px;
background: var(--line-strong);
}
.nav a:hover .dot,
.mini-link:hover .dot {
background: var(--blue);
}
.side-note,
.aside-card {
margin-top: 18px;
padding: 13px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: var(--surface-soft);
color: var(--ink-soft);
font-size: 12px;
line-height: 1.62;
}
.hero {
overflow: hidden;
border: 1px solid var(--line);
border-radius: var(--radius);
background:
linear-gradient(135deg, rgba(255,255,255,0.98), rgba(232,241,248,0.92)),
var(--surface);
box-shadow: var(--shadow);
}
.hero-inner {
padding: 34px;
}
.eyebrow {
display: inline-flex;
align-items: center;
gap: 8px;
margin-bottom: 14px;
padding: 5px 10px;
border: 1px solid rgba(35, 90, 143, 0.18);
border-radius: 999px;
background: var(--blue-soft);
color: var(--blue-deep);
font-size: 12px;
font-weight: 850;
}
h1 {
max-width: 900px;
margin: 0;
color: #101922;
font-size: clamp(30px, 4.5vw, 56px);
line-height: 1.08;
letter-spacing: 0;
}
.hero-lead {
max-width: 920px;
margin: 18px 0 0;
color: var(--ink-soft);
font-size: 16px;
line-height: 1.78;
}
.hero-metrics {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
margin-top: 26px;
}
.metric {
min-height: 104px;
padding: 14px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: rgba(255,255,255,0.88);
}
.metric-value {
color: var(--blue-deep);
font-size: 24px;
font-weight: 950;
line-height: 1.1;
}
.metric-label {
margin-top: 7px;
color: var(--ink);
font-size: 13px;
font-weight: 850;
}
.metric-desc {
margin-top: 5px;
color: var(--muted);
font-size: 12px;
line-height: 1.5;
}
section {
margin-top: 22px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: var(--surface);
box-shadow: var(--shadow-soft);
}
.section-inner {
padding: 26px;
}
.section-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
margin-bottom: 18px;
padding-bottom: 14px;
border-bottom: 1px solid var(--line);
}
h2 {
margin: 0;
color: #101922;
font-size: 24px;
line-height: 1.25;
letter-spacing: 0;
}
h3 {
margin: 0 0 10px;
color: #172126;
font-size: 17px;
line-height: 1.35;
}
h4 {
margin: 0 0 8px;
color: var(--ink);
font-size: 14px;
font-weight: 900;
}
.section-kicker {
margin-top: 8px;
color: var(--muted);
font-size: 13px;
line-height: 1.66;
}
.tag {
display: inline-flex;
align-items: center;
min-height: 26px;
padding: 0 9px;
border-radius: 999px;
background: var(--surface-strong);
color: var(--ink-soft);
font-size: 12px;
font-weight: 850;
white-space: nowrap;
}
.grid {
display: grid;
gap: 14px;
}
.grid.two {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid.three {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.grid.four {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.card {
padding: 16px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: var(--surface-soft);
}
.card.blue { background: var(--blue-soft); border-color: #c8d9e8; }
.card.green { background: var(--green-soft); border-color: #c9dfd0; }
.card.amber { background: var(--amber-soft); border-color: #ead4a9; }
.card.red { background: var(--red-soft); border-color: #edc7c2; }
.card.violet { background: var(--violet-soft); border-color: #d7d1eb; }
.card.teal { background: var(--teal-soft); border-color: #c9dfdc; }
.card p,
.note p {
margin: 0;
color: var(--ink-soft);
}
.list {
display: grid;
gap: 8px;
margin: 0;
padding: 0;
list-style: none;
}
.list li {
position: relative;
padding-left: 18px;
color: var(--ink-soft);
}
.list li::before {
content: "";
position: absolute;
left: 0;
top: 12px;
width: 7px;
height: 7px;
border-radius: 99px;
background: var(--blue);
}
.flow {
display: grid;
gap: 10px;
}
.flow-row {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 10px;
}
.flow-node {
min-height: 84px;
display: grid;
align-content: start;
gap: 6px;
padding: 13px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: #fff;
}
.flow-node strong {
color: var(--ink);
font-size: 13px;
}
.flow-node span {
color: var(--muted);
font-size: 12px;
line-height: 1.45;
}
.arrow {
display: grid;
place-items: center;
min-height: 28px;
color: var(--muted);
font-size: 12px;
font-weight: 850;
}
.pipeline {
display: grid;
gap: 12px;
}
.pipeline-stage {
display: grid;
grid-template-columns: 168px minmax(0, 1fr);
gap: 12px;
align-items: stretch;
}
.stage-label {
display: grid;
place-items: center;
min-height: 92px;
padding: 14px;
border-radius: var(--radius);
background: #132c3e;
color: #fff;
text-align: center;
font-weight: 900;
}
.stage-content {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 10px;
}
.formula {
padding: 18px;
border: 1px solid #bfd2df;
border-radius: var(--radius);
background: #f5f9fc;
}
.formula-main {
padding: 16px;
overflow-x: auto;
border-radius: var(--radius);
background: #102033;
color: #eff8ff;
font-family: var(--mono);
font-size: 14px;
line-height: 1.75;
white-space: nowrap;
}
.formula-note {
margin-top: 10px;
color: var(--ink-soft);
font-size: 13px;
}
.matrix {
overflow: auto;
border: 1px solid var(--line);
border-radius: var(--radius);
}
table {
width: 100%;
min-width: 760px;
border-collapse: collapse;
background: #fff;
}
th,
td {
padding: 12px 13px;
border-bottom: 1px solid var(--line);
color: var(--ink-soft);
text-align: left;
vertical-align: top;
}
th {
background: #f3f7f9;
color: var(--ink);
font-size: 12px;
font-weight: 900;
white-space: nowrap;
}
tr:last-child td {
border-bottom: 0;
}
.asset-map {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 10px;
}
.asset {
min-height: 138px;
padding: 14px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: #fff;
}
.asset-num {
display: inline-grid;
width: 28px;
height: 28px;
place-items: center;
margin-bottom: 10px;
border-radius: 7px;
background: var(--blue);
color: #fff;
font-weight: 900;
}
.evidence-path {
display: grid;
grid-template-columns: repeat(7, minmax(0, 1fr));
gap: 8px;
align-items: stretch;
}
.evidence-item {
min-height: 86px;
padding: 12px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: #fff;
}
.evidence-item strong {
display: block;
color: var(--ink);
font-size: 12px;
}
.evidence-item span {
display: block;
margin-top: 5px;
color: var(--muted);
font-size: 11px;
line-height: 1.45;
}
.split {
display: grid;
grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
gap: 16px;
align-items: start;
}
.callout {
padding: 15px 16px;
border-left: 4px solid var(--blue);
border-radius: var(--radius);
background: #f4f9fc;
color: var(--ink-soft);
}
.callout strong {
color: var(--ink);
}
.step-list {
display: grid;
gap: 12px;
counter-reset: steps;
}
.step {
display: grid;
grid-template-columns: 42px minmax(0, 1fr);
gap: 12px;
padding: 14px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: var(--surface-soft);
}
.step::before {
counter-increment: steps;
content: counter(steps);
display: grid;
width: 34px;
height: 34px;
place-items: center;
border-radius: 8px;
background: #132c3e;
color: #fff;
font-weight: 900;
}
.step strong {
color: var(--ink);
}
.step p {
margin: 4px 0 0;
color: var(--ink-soft);
}
.sources {
display: grid;
gap: 8px;
margin: 0;
padding: 0;
list-style: none;
}
.sources a {
display: block;
padding: 10px 12px;
border: 1px solid var(--line);
border-radius: var(--radius);
background: var(--surface-soft);
color: var(--blue-deep);
font-size: 12px;
font-weight: 760;
}
.sources a:hover {
background: var(--blue-soft);
}
.print-note {
margin-top: 18px;
color: var(--muted);
font-size: 12px;
}
@media (max-width: 1320px) {
.page {
grid-template-columns: 250px minmax(0, 1fr);
}
.aside {
display: none;
}
.hero-metrics,
.grid.four,
.asset-map {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.evidence-path {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
@media (max-width: 980px) {
.page {
display: block;
}
.sidebar {
position: static;
height: auto;
border-right: 0;
border-bottom: 1px solid var(--line);
}
main {
padding: 24px 18px 44px;
}
.hero-inner,
.section-inner {
padding: 20px;
}
.grid.two,
.grid.three,
.grid.four,
.hero-metrics,
.flow-row,
.stage-content,
.asset-map,
.split {
grid-template-columns: 1fr;
}
.pipeline-stage {
grid-template-columns: 1fr;
}
.evidence-path {
grid-template-columns: 1fr;
}
}
@media print {
body {
background: #fff;
}
.page {
display: block;
}
.sidebar,
.aside {
display: none;
}
main {
padding: 0;
}
section,
.hero {
box-shadow: none;
break-inside: avoid;
}
}
</style>
</head>
<body>
<div class="page">
<aside class="sidebar">
<div class="brand">
<div class="brand-row">
<div class="brand-mark">RGE</div>
<div>
<div class="brand-title">财务行为图谱风险引擎</div>
<div class="brand-subtitle">Risk Graph Engine</div>
</div>
</div>
<div class="brand-subtitle">
X-Financial 核心算法说明文档。版本2026-05-29。
</div>
</div>
<div class="nav-label">目录</div>
<nav class="nav" aria-label="文档目录">
<a href="#summary"><span class="dot"></span>核心定义</a>
<a href="#barrier"><span class="dot"></span>不可复制壁垒</a>
<a href="#architecture"><span class="dot"></span>总体架构</a>
<a href="#ontology"><span class="dot"></span>本体桥接</a>
<a href="#observation"><span class="dot"></span>风险观察</a>
<a href="#scoring"><span class="dot"></span>评分公式</a>
<a href="#evidence"><span class="dot"></span>证据链</a>
<a href="#deep"><span class="dot"></span>深度算法层</a>
<a href="#gate"><span class="dot"></span>人机共审门控</a>
<a href="#dashboard"><span class="dot"></span>产品体现</a>
<a href="#roadmap"><span class="dot"></span>实施路线</a>
<a href="#sources"><span class="dot"></span>参考资料</a>
</nav>
<div class="side-note">
本文档是给业务、算法、后端、前端和管理层共同阅读的核心算法介绍。它不替代 `CONCEPT.md` 与 `TODO.md`,而是把核心算法讲成完整方案。
</div>
</aside>
<main>
<article class="hero" id="summary">
<div class="hero-inner">
<div class="eyebrow">核心中的核心算法</div>
<h1>财务行为图谱风险引擎</h1>
<p class="hero-lead">
这套算法不是单一模型,而是把专有本体、对象中心事件日志、财务行为图谱、画像基线、规则命中、人工反馈和可回放评测集组合成一套持续进化的风险控制系统。它的目标不是“给一个风险分”,而是解释清楚谁异常、哪里异常、依据是什么、历史如何处理、现在应该怎么做。
</p>
<div class="hero-metrics">
<div class="metric">
<div class="metric-value">5</div>
<div class="metric-label">不可复制资产</div>
<div class="metric-desc">专有本体、事件日志、反馈池、人机共审、回放评测。</div>
</div>
<div class="metric">
<div class="metric-value">8</div>
<div class="metric-label">第一版风险信号</div>
<div class="metric-desc">重复票据、超标准、预算超额、附件缺失等。</div>
</div>
<div class="metric">
<div class="metric-value">10+</div>
<div class="metric-label">算法模块</div>
<div class="metric-desc">本体、实体解析、过程挖掘、图特征、异常检测。</div>
</div>
<div class="metric">
<div class="metric-value">1</div>
<div class="metric-label">统一产物</div>
<div class="metric-desc">所有风险最终沉淀为 `RiskObservation`。</div>
</div>
</div>
</div>
</article>
<section id="barrier">
<div class="section-inner">
<div class="section-head">
<div>
<h2>不可复制壁垒</h2>
<div class="section-kicker">
复杂算法本身可以被模仿,真正难复制的是长期运行中积累的语义、过程、反馈和评测资产。
</div>
</div>
<span class="tag">Core Barrier</span>
</div>
<div class="asset-map">
<div class="asset">
<span class="asset-num">1</span>
<h3>专有财务语义本体</h3>
<p>把制度条款、费用类型、风险信号、审批场景、预算科目和票据要求归一为公司自己的语义协议。</p>
</div>
<div class="asset">
<span class="asset-num">2</span>
<h3>对象中心事件日志</h3>
<p>把申请、预算、票据、审批、付款、归档、复盘统一沉淀为可回放事件。</p>
</div>
<div class="asset">
<span class="asset-num">3</span>
<h3>风险观察反馈池</h3>
<p>每条风险都有证据路径、规则命中、画像偏离、图谱异常、人工结果和算法版本。</p>
</div>
<div class="asset">
<span class="asset-num">4</span>
<h3>人机共审行为数据</h3>
<p>记录采纳、驳回、补件、退回、升级审批、标记误报和候选规则生成。</p>
</div>
<div class="asset">
<span class="asset-num">5</span>
<h3>可回放评测资产</h3>
<p>用同一批历史单据、本体版本、规则版本、算法版本和反馈标签评估新算法。</p>
</div>
</div>
<div class="callout" style="margin-top: 16px;">
<strong>结论:</strong>别人可以复制页面、名词和公开算法,但复制不了真实审批过程、公司制度语义、历史处理结果和长期回放集。算法壁垒必须从第一天开始沉淀这些资产。
</div>
</div>
</section>
<section id="architecture">
<div class="section-inner">
<div class="section-head">
<div>
<h2>总体架构</h2>
<div class="section-kicker">
整体架构分为语义、事件、图谱、画像、推理、观察、反馈七层。每层只解决一个问题,避免规则中心、图谱引擎和数字员工职责混乱。
</div>
</div>
<span class="tag">Seven Layers</span>
</div>
<div class="pipeline">
<div class="pipeline-stage">
<div class="stage-label">语义层</div>
<div class="stage-content">
<div class="card blue"><h4>本体解析</h4><p>识别场景、意图、费用类型、风险信号、约束条件。</p></div>
<div class="card blue"><h4>制度条款</h4><p>把制度转成可引用、可版本化、可匹配的条款。</p></div>
<div class="card blue"><h4>标准词典</h4><p>统一供应商、费用类型、票据类型和风险信号。</p></div>
</div>
</div>
<div class="pipeline-stage">
<div class="stage-label">事件层</div>
<div class="stage-content">
<div class="card teal"><h4>业务事件</h4><p>申请、提交、上传票据、审批、退回、付款、归档。</p></div>
<div class="card teal"><h4>多对象日志</h4><p>一个事件同时绑定单据、票据、员工、供应商和预算。</p></div>
<div class="card teal"><h4>运行追踪</h4><p>关联 AgentRun、数字员工任务和工具调用结果。</p></div>
</div>
</div>
<div class="pipeline-stage">
<div class="stage-label">图谱层</div>
<div class="stage-content">
<div class="card green"><h4>节点</h4><p>员工、部门、供应商、票据、单据、制度条款、规则。</p></div>
<div class="card green"><h4></h4><p>提交、包含、使用票据、关联供应商、命中规则。</p></div>
<div class="card green"><h4>证据路径</h4><p>形成可展示、可审计、可回放的风险解释链。</p></div>
</div>
</div>
<div class="pipeline-stage">
<div class="stage-label">推理层</div>
<div class="stage-content">
<div class="card amber"><h4>规则命中</h4><p>确定性规则提供强证据,仍由规则中心治理。</p></div>
<div class="card amber"><h4>画像偏离</h4><p>员工、部门、供应商和费用类型的同类基线。</p></div>
<div class="card amber"><h4>图谱异常</h4><p>供应商集中、重复票据、审批链异常、时空冲突。</p></div>
</div>
</div>
<div class="pipeline-stage">
<div class="stage-label">反馈层</div>
<div class="stage-content">
<div class="card violet"><h4>人工确认</h4><p>采纳、误报、忽略、退回、补件、升级审批。</p></div>
<div class="card violet"><h4>离线回放</h4><p>用历史样本评估规则和算法版本。</p></div>
<div class="card violet"><h4>候选优化</h4><p>生成规则候选、制度更新候选和抽审策略调整。</p></div>
</div>
</div>
</div>
</div>
</section>
<section id="ontology">
<div class="section-inner">
<div class="section-head">
<div>
<h2>本体与风险图谱桥接</h2>
<div class="section-kicker">
本体不是一个辅助字段,而是风险图谱的语义骨架。它决定节点类型、边类型、规则适用范围、风险信号口径和看板聚合维度。
</div>
</div>
<span class="tag">Ontology First</span>
</div>
<div class="split">
<div class="card">
<h3>本体输出最小协议</h3>
<pre>ontology_parse_id
ontology_version
domain
scenario
intent
entities
constraints
risk_signals
confidence</pre>
</div>
<div class="card">
<h3>图谱节点标准字段</h3>
<pre>node_type
ontology_type
canonical_key
canonical_id
source_object_type
source_object_id
ontology_parse_id
ontology_version</pre>
</div>
</div>
<div class="matrix" style="margin-top: 16px;">
<table>
<thead>
<tr>
<th>本体实体</th>
<th>图谱节点</th>
<th>作用</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>expense_type</code></td>
<td>费用类型节点</td>
<td>统一规则范围、画像基线和风险看板聚合。</td>
<td><code>hotel</code>, <code>travel</code>, <code>entertainment</code></td>
</tr>
<tr>
<td><code>risk_signal</code></td>
<td>风险信号节点 / 风险观察</td>
<td>把“住宿超标”“酒店超标”等近义说法合并。</td>
<td><code>accommodation_standard_deviation</code></td>
</tr>
<tr>
<td><code>document_type</code></td>
<td>单据、票据、合同、流水</td>
<td>支撑多凭证一致性校验。</td>
<td><code>invoice</code>, <code>payment_record</code></td>
</tr>
<tr>
<td><code>policy_clause</code></td>
<td>制度条款节点</td>
<td>让风险结论能引用制度依据。</td>
<td>差旅住宿标准第 3 条</td>
</tr>
<tr>
<td><code>vendor</code></td>
<td>供应商 / 商户节点</td>
<td>支撑供应商集中、别名归一、关联交易识别。</td>
<td>上海某酒店管理有限公司</td>
</tr>
</tbody>
</table>
</div>
<div class="callout" style="margin-top: 16px;">
<strong>关键约束:</strong>图谱边必须来自白名单,例如 <code>submitted</code><code>uses_invoice</code><code>paid_to_vendor</code><code>matches_policy_clause</code><code>triggered_rule</code>。数字员工不能自由创造运行时边类型。
</div>
</div>
</section>
<section id="observation">
<div class="section-inner">
<div class="section-head">
<div>
<h2>RiskObservation 是唯一风险产物</h2>
<div class="section-kicker">
规则命中、画像偏离、图谱异常、制度条款和人工反馈最终都必须合成风险观察。它是单据详情、工作记录、风险看板和算法回放的统一事实表。
</div>
</div>
<span class="tag">Single Output</span>
</div>
<div class="grid three">
<div class="card blue">
<h3>输入</h3>
<ul class="list">
<li>本体解析结果</li>
<li>规则命中结果</li>
<li>画像基线偏离</li>
<li>图谱关系异常</li>
<li>历史反馈和相似案例</li>
</ul>
</div>
<div class="card green">
<h3>输出</h3>
<ul class="list">
<li>风险分和风险等级</li>
<li>证据链和制度依据</li>
<li>建议动作和自动化模式</li>
<li>算法版本和置信度</li>
<li>人工反馈状态</li>
</ul>
</div>
<div class="card amber">
<h3>用途</h3>
<ul class="list">
<li>单据详情解释风险</li>
<li>工作记录展示任务产出</li>
<li>风险看板聚合态势</li>
<li>规则优化和误报分析</li>
<li>离线回放和算法评测</li>
</ul>
</div>
</div>
<div class="card" style="margin-top: 16px;">
<h3>核心结构</h3>
<pre>RiskObservation
subject_type / subject_id
risk_type / risk_signals_json
severity / score / confidence_score
ontology_parse_id / ontology_version
domain / scenario / intent
evidence_items_json / evidence_path_json
related_policy_clauses_json
comparable_baseline_json
suggested_actions_json
source_type / source_id
automation_mode / control_stage / control_mode
algorithm_version / feedback_status</pre>
</div>
</div>
</section>
<section id="scoring">
<div class="section-inner">
<div class="section-head">
<div>
<h2>风险评分模型</h2>
<div class="section-kicker">
第一版采用可解释加权模型,不用黑盒模型直接给最终结论。复杂模型只提供候选证据,强结论必须能解释。
</div>
</div>
<span class="tag">Explainable Score</span>
</div>
<div class="formula">
<div class="formula-main">
risk_score = clip(
0.35 * S_rule
+ 0.25 * S_anomaly
+ 0.20 * S_graph
+ 0.15 * S_policy
+ 0.05 * S_history,
0, 100
)
</div>
<div class="formula-note">
<strong>S_rule</strong> 来自规则中心命中,<strong>S_anomaly</strong> 来自画像基线偏离,<strong>S_graph</strong> 来自图谱关系异常,<strong>S_policy</strong> 来自制度语义,<strong>S_history</strong> 来自历史反馈。
</div>
</div>
<div class="grid two" style="margin-top: 16px;">
<div class="formula">
<h3>同类基线偏离</h3>
<div class="formula-main">deviation = (x - median(peer)) / max(IQR(peer), epsilon)
S_anomaly = 100 * sigmoid(k * (deviation - tau))</div>
<div class="formula-note">用于金额、频次、天数、退回率等指标。样本不足时必须记录降级口径。</div>
</div>
<div class="formula">
<h3>图谱异常分</h3>
<div class="formula-main">S_graph = min(100, sum(w_i * g_i))</div>
<div class="formula-note">候选信号包括重复票据、供应商集中、审批链异常、时空冲突和相似单据异常。</div>
</div>
</div>
<div class="matrix" style="margin-top: 16px;">
<table>
<thead>
<tr>
<th>分数项</th>
<th>证据来源</th>
<th>可解释依据</th>
<th>是否可单独强拦截</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>S_rule</code></td>
<td>规则中心 / 决策表</td>
<td>规则版本、命中条件、输入快照。</td>
<td>强制度规则可拦截。</td>
</tr>
<tr>
<td><code>S_anomaly</code></td>
<td>画像基线</td>
<td>同部门、同职级、同费用类型分位偏离。</td>
<td>不可单独拦截。</td>
</tr>
<tr>
<td><code>S_graph</code></td>
<td>图谱路径</td>
<td>供应商集中、重复票据、异常审批路径。</td>
<td>高证据覆盖时可复核拦截。</td>
</tr>
<tr>
<td><code>S_policy</code></td>
<td>制度条款</td>
<td>费用说明、票据、制度条款是否一致。</td>
<td>需结合规则和证据。</td>
</tr>
<tr>
<td><code>S_history</code></td>
<td>人工反馈</td>
<td>相似单据退回率、确认率、误报率。</td>
<td>不单独拦截,影响权重和门控。</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section id="evidence">
<div class="section-inner">
<div class="section-head">
<div>
<h2>证据链如何展示</h2>
<div class="section-kicker">
图谱不要默认展示成全量关系网。产品上要展示小范围、场景化、可解释的证据链。
</div>
</div>
<span class="tag">Evidence Path</span>
</div>
<div class="evidence-path">
<div class="evidence-item"><strong>员工</strong><span>张三P8研发中心</span></div>
<div class="evidence-item"><strong>单据</strong><span>差旅报销 4,860 元</span></div>
<div class="evidence-item"><strong>票据</strong><span>酒店发票1,260 元/晚</span></div>
<div class="evidence-item"><strong>供应商</strong><span>上海某酒店</span></div>
<div class="evidence-item"><strong>基线</strong><span>同级别 P90 为 760 元/晚</span></div>
<div class="evidence-item"><strong>制度</strong><span>住宿标准第 3 条</span></div>
<div class="evidence-item"><strong>历史</strong><span>相似 12 笔8 笔退回</span></div>
</div>
<div class="grid three" style="margin-top: 16px;">
<div class="card blue">
<h3>单据详情</h3>
<p>面向审批人,解释当前单据为什么异常、应该怎么处理。</p>
</div>
<div class="card green">
<h3>工作记录详情</h3>
<p>面向管理员,解释数字员工本次任务处理了哪些实体、发现了哪些风险。</p>
</div>
<div class="card amber">
<h3>风险看板</h3>
<p>面向财务和管理层,展示整体风险态势、算法效果和抽审结果。</p>
</div>
</div>
</div>
</section>
<section id="deep">
<div class="section-inner">
<div class="section-head">
<div>
<h2>深度算法层</h2>
<div class="section-kicker">
这些模块构成算法复杂度,但必须全部回到可解释证据和 `RiskObservation`,不能变成不可审计黑盒。
</div>
</div>
<span class="tag">Algorithm Stack</span>
</div>
<div class="grid two">
<div class="card">
<h3>对象中心过程挖掘</h3>
<p>把申请、票据、预算、审批、付款、供应商放入多对象事件日志,识别跳步审批、流程绕行、返工循环和付款前异常。</p>
</div>
<div class="card">
<h3>实体解析与主数据归一</h3>
<p>归一供应商、商户、酒店、银行户名、员工姓名,避免同一主体被拆成多个节点。</p>
</div>
<div class="card">
<h3>异构图与时序图特征</h3>
<p>计算员工、部门、供应商、票据、规则、制度之间的元路径、中心性、邻域风险密度和关系突增。</p>
</div>
<div class="card">
<h3>多模型异常检测组合</h3>
<p>组合稳健统计、孤立森林、局部离群、时间突变和周期偏离,但只作为候选风险证据。</p>
</div>
<div class="card">
<h3>决策建模与策略即代码</h3>
<p>把规则中心的确定性规则拆成决策表、策略运行和决策追踪,保证版本化和可审计。</p>
</div>
<div class="card">
<h3>反事实风险建议</h3>
<p>给出降低风险分的可执行补救动作,例如补充酒店水单、选择协议酒店或增加预算负责人复核。</p>
</div>
<div class="card">
<h3>数据血缘与质量门禁</h3>
<p>记录风险观察使用了哪些表、文档、OCR、AgentRun、规则版本和本体版本低质量数据不触发强风控。</p>
</div>
<div class="card">
<h3>可解释与不确定性控制</h3>
<p>保存特征贡献、置信度、低置信度原因和人工复核要求,让每个结论都能被复查。</p>
</div>
</div>
</div>
</section>
<section id="gate">
<div class="section-inner">
<div class="section-head">
<div>
<h2>人机共审门控</h2>
<div class="section-kicker">
系统不应让 AI 直接通过或驳回单据。自动化必须由置信度、风险等级、证据覆盖、历史误报率和金额影响共同决定。
</div>
</div>
<span class="tag">Human in the Loop</span>
</div>
<div class="formula">
<div class="formula-main">
if confidence >= theta_auto
and severity <= medium
and evidence_coverage >= 2
and false_positive_rate <= alpha:
automation_mode = "auto"
elif confidence >= theta_semi
and evidence_coverage >= 1:
automation_mode = "semi_auto"
else:
automation_mode = "assist"
</div>
<div class="formula-note">
`assist` 只给建议,`semi_auto` 可半自动但保留抽审,`auto` 只允许低风险、高置信、证据充分、历史误报低的场景。
</div>
</div>
<div class="grid four" style="margin-top: 16px;">
<div class="card red"><h3>高风险</h3><p>全量复核,必须展示完整证据链和制度依据。</p></div>
<div class="card amber"><h3>中风险</h3><p>按风险类型、金额和历史误报率进入抽审。</p></div>
<div class="card green"><h3>低风险</h3><p>可进入小比例随机抽审,用于监控漏报。</p></div>
<div class="card blue"><h3>低置信</h3><p>只生成候选观察,不触发强拦截。</p></div>
</div>
</div>
</section>
<section id="dashboard">
<div class="section-inner">
<div class="section-head">
<div>
<h2>产品体现</h2>
<div class="section-kicker">
核心算法不能只存在后端。它必须在用户能理解的地方体现:详情解释单点风险,看板解释整体态势,工作记录解释数字员工产出。
</div>
</div>
<span class="tag">Product Surface</span>
</div>
<div class="flow">
<div class="flow-row">
<div class="flow-node"><strong>单据详情</strong><span>风险证据链、基线对比、制度条款、建议动作。</span></div>
<div class="flow-node"><strong>工作记录详情</strong><span>任务范围、处理数量、风险观察、异常关系。</span></div>
<div class="flow-node"><strong>风险看板</strong><span>总览、分布、趋势、排行、算法效果。</span></div>
<div class="flow-node"><strong>规则中心</strong><span>规则定义、版本、测试、发布、候选规则审核。</span></div>
<div class="flow-node"><strong>画像详情</strong><span>员工、部门、供应商和费用类型长期基线。</span></div>
</div>
</div>
<div class="matrix" style="margin-top: 16px;">
<table>
<thead>
<tr>
<th>页面</th>
<th>用户</th>
<th>回答的问题</th>
<th>数据来源</th>
</tr>
</thead>
<tbody>
<tr>
<td>单据详情</td>
<td>审批人</td>
<td>这张单为什么异常,应该怎么处理。</td>
<td>RiskObservation + evidence_path</td>
</tr>
<tr>
<td>数字员工工作记录</td>
<td>管理员</td>
<td>这次任务处理了什么,产出了什么风险。</td>
<td>AgentRun + RiskObservation</td>
</tr>
<tr>
<td>风险看板</td>
<td>财务 / 管理层</td>
<td>整体风险态势、确认率、误报率、抽审效率。</td>
<td>RiskObservation 聚合</td>
</tr>
<tr>
<td>规则中心</td>
<td>管理员</td>
<td>规则如何定义、测试、发布和回滚。</td>
<td>risk_rules + rule_runs</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section id="roadmap">
<div class="section-inner">
<div class="section-head">
<div>
<h2>实施路线</h2>
<div class="section-kicker">
第一版不要一次引入全部复杂算法。先打通最小闭环,然后逐步增强图谱、过程挖掘和评测体系。
</div>
</div>
<span class="tag">Execution Plan</span>
</div>
<div class="step-list">
<div class="step">
<div>
<strong>建立本体桥接和 RiskObservation</strong>
<p>把本体解析、规则命中、画像偏离、图谱路径和人工反馈统一进风险观察模型。</p>
</div>
</div>
<div class="step">
<div>
<strong>实现第一批 8 个高价值风险信号</strong>
<p>重复票据、金额超标准、预算超额、附件缺失、报销发票金额不一致、申请报销不一致、时间地点不一致、供应商集中异常。</p>
</div>
</div>
<div class="step">
<div>
<strong>落地三个产品入口</strong>
<p>单据详情风险证据链、数字员工工作记录详情、分析看板风险看板。</p>
</div>
</div>
<div class="step">
<div>
<strong>沉淀反馈与回放集</strong>
<p>记录人工采纳、误报、退回、补件和升级审批;建立历史样本回放能力。</p>
</div>
</div>
<div class="step">
<div>
<strong>引入深度算法模块</strong>
<p>逐步加入实体解析、对象中心过程挖掘、异构图特征、异常检测组合和反事实建议。</p>
</div>
</div>
</div>
</div>
</section>
<section id="sources">
<div class="section-inner">
<div class="section-head">
<div>
<h2>参考资料</h2>
<div class="section-kicker">
以下资料用于公开方法论和可借鉴技术来源。内部实现仍以 X-Financial 自有数据、本体、规则和反馈闭环为准。
</div>
</div>
<span class="tag">References</span>
</div>
<ul class="sources">
<li><a href="https://mks.yybip.com/group1/M00/07/EB/CgoRC2JVTMGAPdWmAEdtt5GGOf0756.pdf">用友 YonBIP 财务云智能费控服务白皮书</a></li>
<li><a href="https://mks.yybip.com/group1/M00/0A/29/CgoRC2XvFQuAKvNtACX8GJS9Zgo009.pdf">用友数智化财务资料:商旅费控、事项法会计与 AI 能力</a></li>
<li><a href="https://www.ekuaibao.com/hoseai.html">合思 AI 官网Agent 与财务审核能力</a></li>
<li><a href="https://www.ekuaibao.com/solutionsr/control.html">合思企业内控解决方案</a></li>
<li><a href="https://www.ocel-standard.org/">OCEL 2.0 Object-Centric Event Log</a></li>
<li><a href="https://www.tf-pm.org/resources/manifesto">IEEE Task Force Process Mining Manifesto</a></li>
<li><a href="https://arxiv.org/abs/2006.10637">Temporal Graph Networks</a></li>
<li><a href="https://papers.neurips.cc/paper/6703-inductive-representation-learning-on-large-graphs">GraphSAGE</a></li>
<li><a href="https://www.kdd.org/kdd2017/papers/view/metapath2vec-scalable-representation-learning-for-heterogeneous-networks">metapath2vec</a></li>
<li><a href="https://arxiv.org/abs/1903.07293">Heterogeneous Graph Attention Network</a></li>
<li><a href="https://cs.nju.edu.cn/zhouzh/zhouzh.files/publication/icdm08b.pdf">Isolation Forest</a></li>
<li><a href="https://arxiv.org/abs/1705.07874">SHAP: A Unified Approach to Interpreting Model Predictions</a></li>
<li><a href="https://www.omg.org/dmn/">OMG Decision Model and Notation</a></li>
<li><a href="https://www.openpolicyagent.org/docs/latest">Open Policy Agent Documentation</a></li>
<li><a href="https://openlineage.io/">OpenLineage</a></li>
<li><a href="https://docs.greatexpectations.io/docs/guides/validation/validate_data_overview/">Great Expectations Data Validation</a></li>
</ul>
<div class="print-note">
本页为静态 HTML 文档,可直接浏览或打印为 PDF。
</div>
</div>
</section>
</main>
<aside class="aside">
<div class="aside-title">关键算法模块</div>
<a class="mini-link" href="#ontology"><span class="dot"></span>本体标准化</a>
<a class="mini-link" href="#observation"><span class="dot"></span>风险观察池</a>
<a class="mini-link" href="#scoring"><span class="dot"></span>风险评分</a>
<a class="mini-link" href="#deep"><span class="dot"></span>图谱特征</a>
<a class="mini-link" href="#gate"><span class="dot"></span>人机门控</a>
<div class="aside-card">
<strong>核心公式</strong>
<p style="margin-top: 8px;">风险分由规则、画像、图谱、制度、历史反馈五部分组成,所有分量必须有证据来源。</p>
</div>
<div class="aside-card">
<strong>边界原则</strong>
<p style="margin-top: 8px;">规则中心管规则,图谱引擎管风险观察,数字员工管持续运行,风险看板管整体态势。</p>
</div>
<div class="aside-card">
<strong>第一版优先级</strong>
<p style="margin-top: 8px;">先做本体桥接、RiskObservation、8 个风险信号、详情证据链、工作记录详情、风险看板和反馈回放。</p>
</div>
</aside>
</div>
</body>
</html>