feat: 新增归档中心页面并完善知识库与报销查询能力
新增前端归档中心视图及相关工具函数,扩充知识库文档分类和 提取器支持多种格式,增强编排器报销查询的多维度检索,优 化本体规则和用户代理审核消息,前端完善报销创建和审批详 情交互细节,补充单元测试覆盖。
This commit is contained in:
@@ -0,0 +1,896 @@
|
||||
<!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 {
|
||||
--green-900: #064e3b;
|
||||
--green-700: #047857;
|
||||
--green-600: #10b981;
|
||||
--green-100: #dff8ec;
|
||||
--green-50: #effcf6;
|
||||
--blue-700: #1d4ed8;
|
||||
--blue-50: #eff6ff;
|
||||
--amber-600: #d97706;
|
||||
--amber-50: #fffbeb;
|
||||
--red-600: #dc2626;
|
||||
--red-50: #fef2f2;
|
||||
--ink-900: #071124;
|
||||
--ink-700: #24324a;
|
||||
--ink-600: #58677f;
|
||||
--ink-500: #728098;
|
||||
--line: #dbe5ef;
|
||||
--line-strong: #c6d4e2;
|
||||
--surface: #ffffff;
|
||||
--surface-soft: #f7fafc;
|
||||
--shadow: 0 10px 26px rgba(15, 23, 42, 0.08);
|
||||
--radius: 8px;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(239, 252, 246, 0.78), rgba(247, 250, 252, 0.96) 360px),
|
||||
var(--surface-soft);
|
||||
color: var(--ink-900);
|
||||
font-family: "IBM Plex Sans", "Microsoft YaHei UI", "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
line-height: 1.62;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 2px 6px;
|
||||
border-radius: 6px;
|
||||
background: rgba(15, 23, 42, 0.06);
|
||||
color: var(--ink-700);
|
||||
font-family: "JetBrains Mono", "Cascadia Code", Consolas, monospace;
|
||||
font-size: 0.92em;
|
||||
}
|
||||
|
||||
.shell {
|
||||
display: grid;
|
||||
grid-template-columns: 276px minmax(0, 1fr);
|
||||
min-height: 100dvh;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
align-self: start;
|
||||
height: 100dvh;
|
||||
padding: 28px 22px;
|
||||
border-right: 1px solid var(--line);
|
||||
background: rgba(255, 255, 255, 0.86);
|
||||
backdrop-filter: blur(18px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.brand {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.logo-mark {
|
||||
display: grid;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
place-items: center;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(145deg, var(--green-700), var(--green-600));
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
box-shadow: 0 10px 18px rgba(16, 185, 129, 0.26);
|
||||
}
|
||||
|
||||
.brand-title {
|
||||
font-size: 15px;
|
||||
font-weight: 800;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.brand-subtitle {
|
||||
margin-top: 4px;
|
||||
color: var(--ink-500);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.nav-label {
|
||||
margin: 22px 0 8px;
|
||||
color: var(--ink-500);
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.nav a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 38px;
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
color: var(--ink-700);
|
||||
font-size: 13px;
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.nav a:hover {
|
||||
background: var(--green-50);
|
||||
color: var(--green-900);
|
||||
}
|
||||
|
||||
.nav-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
margin-right: 10px;
|
||||
border-radius: 999px;
|
||||
background: var(--line-strong);
|
||||
}
|
||||
|
||||
main {
|
||||
min-width: 0;
|
||||
padding: 34px 42px 56px;
|
||||
}
|
||||
|
||||
.hero {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.14fr) minmax(300px, 0.86fr);
|
||||
gap: 24px;
|
||||
align-items: stretch;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.hero-panel,
|
||||
.metric-panel,
|
||||
section,
|
||||
.card {
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius);
|
||||
background: var(--surface);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.hero-panel {
|
||||
padding: 30px;
|
||||
border-color: rgba(16, 185, 129, 0.28);
|
||||
background:
|
||||
linear-gradient(135deg, rgba(255, 255, 255, 0.96), rgba(239, 252, 246, 0.9)),
|
||||
var(--surface);
|
||||
}
|
||||
|
||||
.kicker {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 28px;
|
||||
padding: 4px 10px;
|
||||
border: 1px solid rgba(16, 185, 129, 0.24);
|
||||
border-radius: 999px;
|
||||
background: rgba(16, 185, 129, 0.1);
|
||||
color: var(--green-900);
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
h1 {
|
||||
max-width: 780px;
|
||||
margin: 16px 0 14px;
|
||||
font-size: 34px;
|
||||
line-height: 1.18;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.hero-copy,
|
||||
.section-desc,
|
||||
.card p,
|
||||
.phase span,
|
||||
.footnote {
|
||||
color: var(--ink-600);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.hero-copy {
|
||||
max-width: 800px;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-top: 22px;
|
||||
}
|
||||
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 32px;
|
||||
padding: 6px 11px;
|
||||
border-radius: 999px;
|
||||
background: #fff;
|
||||
border: 1px solid var(--line);
|
||||
color: var(--ink-700);
|
||||
font-size: 12px;
|
||||
font-weight: 750;
|
||||
}
|
||||
|
||||
.pill.primary {
|
||||
background: var(--green-700);
|
||||
border-color: var(--green-700);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.metric-panel {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.metric {
|
||||
padding: 14px;
|
||||
border-radius: 8px;
|
||||
background: var(--surface-soft);
|
||||
border: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
color: var(--ink-500);
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.metric-value {
|
||||
margin-top: 5px;
|
||||
font-size: 18px;
|
||||
line-height: 1.28;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
section {
|
||||
margin-top: 18px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
gap: 18px;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
margin: 0 0 8px;
|
||||
font-size: 22px;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.section-desc {
|
||||
max-width: 920px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tag {
|
||||
flex: 0 0 auto;
|
||||
min-height: 28px;
|
||||
padding: 4px 10px;
|
||||
border-radius: 999px;
|
||||
background: var(--green-50);
|
||||
color: var(--green-900);
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
border: 1px solid rgba(16, 185, 129, 0.22);
|
||||
}
|
||||
|
||||
.grid-2,
|
||||
.grid-3,
|
||||
.grid-4 {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.grid-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.grid-3 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.grid-4 {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 17px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
margin: 0 0 10px;
|
||||
font-size: 16px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.card p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card ul,
|
||||
.card ol {
|
||||
margin: 0;
|
||||
padding-left: 18px;
|
||||
color: var(--ink-600);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.card li + li {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.tone-green {
|
||||
background: var(--green-50);
|
||||
border-color: rgba(16, 185, 129, 0.26);
|
||||
}
|
||||
|
||||
.tone-blue {
|
||||
background: var(--blue-50);
|
||||
border-color: rgba(37, 99, 235, 0.18);
|
||||
}
|
||||
|
||||
.tone-amber {
|
||||
background: var(--amber-50);
|
||||
border-color: rgba(217, 119, 6, 0.2);
|
||||
}
|
||||
|
||||
.tone-red {
|
||||
background: var(--red-50);
|
||||
border-color: rgba(220, 38, 38, 0.16);
|
||||
}
|
||||
|
||||
.flow {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.flow-row {
|
||||
display: grid;
|
||||
grid-template-columns: 132px minmax(0, 1fr);
|
||||
gap: 12px;
|
||||
align-items: start;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: var(--surface-soft);
|
||||
}
|
||||
|
||||
.flow-key {
|
||||
color: var(--green-900);
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.flow-body {
|
||||
color: var(--ink-600);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.diagram {
|
||||
padding: 16px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: #0f172a;
|
||||
color: #e5eef8;
|
||||
overflow-x: auto;
|
||||
font-family: "JetBrains Mono", "Cascadia Code", Consolas, monospace;
|
||||
font-size: 13px;
|
||||
line-height: 1.65;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.timeline {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.phase {
|
||||
display: grid;
|
||||
grid-template-columns: 150px minmax(0, 1fr);
|
||||
gap: 14px;
|
||||
padding: 14px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: var(--surface-soft);
|
||||
}
|
||||
|
||||
.phase-key {
|
||||
color: var(--green-900);
|
||||
font-size: 13px;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.phase-body strong {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
color: var(--ink-900);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.checklist {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.check {
|
||||
position: relative;
|
||||
padding: 12px 12px 12px 34px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: var(--surface-soft);
|
||||
color: var(--ink-700);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.check::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 13px;
|
||||
top: 17px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 999px;
|
||||
background: var(--green-600);
|
||||
}
|
||||
|
||||
.link-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.link-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 30px;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 999px;
|
||||
background: #fff;
|
||||
color: var(--ink-700);
|
||||
font-size: 12px;
|
||||
font-weight: 750;
|
||||
}
|
||||
|
||||
.link-chip:hover {
|
||||
border-color: rgba(16, 185, 129, 0.5);
|
||||
color: var(--green-900);
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 22px;
|
||||
color: var(--ink-500);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (max-width: 1080px) {
|
||||
.shell {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: static;
|
||||
height: auto;
|
||||
border-right: 0;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.hero,
|
||||
.grid-2,
|
||||
.grid-3,
|
||||
.grid-4 {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 24px 18px 42px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 680px) {
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.section-head,
|
||||
.phase,
|
||||
.flow-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: grid;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="shell">
|
||||
<aside class="sidebar">
|
||||
<div class="brand">
|
||||
<div class="logo-mark">KB</div>
|
||||
<div>
|
||||
<div class="brand-title">轻量知识库归集</div>
|
||||
<div class="brand-subtitle">LightRAG + Hermes 优化方案</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nav-label">文档导航</div>
|
||||
<nav class="nav">
|
||||
<a href="#position"><span class="nav-dot"></span>定位与边界</a>
|
||||
<a href="#architecture"><span class="nav-dot"></span>轻量架构</a>
|
||||
<a href="#borrow"><span class="nav-dot"></span>Yuxi 借鉴点</a>
|
||||
<a href="#modules"><span class="nav-dot"></span>模块设计</a>
|
||||
<a href="#retrieval"><span class="nav-dot"></span>召回与回答</a>
|
||||
<a href="#delivery"><span class="nav-dot"></span>实施路线</a>
|
||||
<a href="#quality"><span class="nav-dot"></span>验收标准</a>
|
||||
</nav>
|
||||
|
||||
<div class="nav-label">硬约束</div>
|
||||
<div class="nav">
|
||||
<a href="#quality"><span class="nav-dot"></span>不做重平台</a>
|
||||
<a href="#quality"><span class="nav-dot"></span>证据优先回答</a>
|
||||
<a href="#quality"><span class="nav-dot"></span>增量任务可追踪</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main>
|
||||
<div class="hero">
|
||||
<div class="hero-panel">
|
||||
<span class="kicker">开发文档 · 先定边界再实现</span>
|
||||
<h1>X-Financial 轻量知识库归集与问答优化方案</h1>
|
||||
<p class="hero-copy">
|
||||
本方案不把 X-Financial 改造成专业知识库平台,而是在现有
|
||||
<code>LightRAG</code>、<code>Hermes</code>、<code>AgentRun</code>
|
||||
和知识库 UI 上补齐最薄弱的归集、分块、召回和证据回答能力。
|
||||
Yuxi 只作为成熟设计参考,借鉴其统一解析、分块预设和评估思想。
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<span class="pill primary">保留现有 LightRAG</span>
|
||||
<span class="pill">轻量 Parser</span>
|
||||
<span class="pill">条款级分块</span>
|
||||
<span class="pill">混合召回</span>
|
||||
<span class="pill">证据化回答</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="metric-panel">
|
||||
<div class="metric">
|
||||
<div class="metric-label">核心目标</div>
|
||||
<div class="metric-value">准、快、可解释</div>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<div class="metric-label">改造范围</div>
|
||||
<div class="metric-value">归集与召回链路,不重做平台</div>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<div class="metric-label">并发预期</div>
|
||||
<div class="metric-value">5-10 用户查询可降级、有上限</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section id="position">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2 class="section-title">定位与边界</h2>
|
||||
<p class="section-desc">
|
||||
知识库在 X-Financial 中是业务辅助能力,不是独立知识管理产品。
|
||||
因此实现必须克制:不引入重型多租户平台,不替换现有业务数据模型,
|
||||
不把知识库 UI 做成复杂后台,只补齐影响问答质量的关键薄层。
|
||||
</p>
|
||||
</div>
|
||||
<span class="tag">轻量优先</span>
|
||||
</div>
|
||||
|
||||
<div class="grid-3">
|
||||
<div class="card tone-green">
|
||||
<h3>要解决的问题</h3>
|
||||
<ul>
|
||||
<li>Word、PDF、Excel 等文件进入 RAG 前缺少统一结构。</li>
|
||||
<li>制度类文档如果按普通 chunk 切分,条款容易被切散。</li>
|
||||
<li>问答质量依赖向量召回,缺少关键词、标题、条款补召回。</li>
|
||||
<li>效果优化缺少固定评测集,容易靠体感判断。</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card tone-blue">
|
||||
<h3>保留的现有能力</h3>
|
||||
<ul>
|
||||
<li><code>KnowledgeService</code> 继续负责文件库和状态入口。</li>
|
||||
<li><code>KnowledgeRagService</code> 继续封装 LightRAG 查询和入库。</li>
|
||||
<li><code>KnowledgeIndexTaskManager</code> 继续承接 Hermes 增量任务。</li>
|
||||
<li>前端知识管理继续保持简单文件夹与文件列表形态。</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card tone-amber">
|
||||
<h3>明确不做</h3>
|
||||
<ul>
|
||||
<li>不整体引入 Yuxi 平台。</li>
|
||||
<li>不把存储改成 Milvus + Neo4j。</li>
|
||||
<li>不一次性接入全量 OCR 引擎。</li>
|
||||
<li>不新增复杂多租户知识库后台。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="architecture">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2 class="section-title">轻量架构</h2>
|
||||
<p class="section-desc">
|
||||
新增能力只放在 LightRAG 前后两侧:前侧负责把文件变成稳定 Markdown 和业务友好 chunk,
|
||||
后侧负责混合召回、证据重排和可靠回答。LightRAG 仍是主召回核心。
|
||||
</p>
|
||||
</div>
|
||||
<span class="tag">薄层增强</span>
|
||||
</div>
|
||||
|
||||
<div class="diagram">原始文件
|
||||
├── docx / pdf / xlsx / pptx / csv / txt
|
||||
↓
|
||||
轻量 Parser
|
||||
├── 统一 Markdown
|
||||
├── 表格上下文
|
||||
└── 页码 / sheet / 条款路径
|
||||
↓
|
||||
Chunk Preset
|
||||
├── laws:制度条款
|
||||
├── qa:常见问答
|
||||
└── table:表格行组
|
||||
↓
|
||||
现有 LightRAG / Qdrant
|
||||
↓
|
||||
混合召回
|
||||
├── LightRAG 语义召回
|
||||
├── 标题与条款关键词召回
|
||||
└── 轻量重排 top 3-5
|
||||
↓
|
||||
证据化回答
|
||||
├── 命中证据
|
||||
├── 直接结论
|
||||
└── 缺失信息说明</div>
|
||||
</section>
|
||||
|
||||
<section id="borrow">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2 class="section-title">Yuxi 借鉴点</h2>
|
||||
<p class="section-desc">
|
||||
Yuxi 的价值不在于整套平台,而在于成熟的归集分层思想:
|
||||
文件先解析成 Markdown,再按场景分块,再索引,再评估。
|
||||
这些思想可以小规模落地到现有服务内。
|
||||
</p>
|
||||
</div>
|
||||
<span class="tag">借鉴而非搬运</span>
|
||||
</div>
|
||||
|
||||
<div class="grid-4">
|
||||
<div class="card">
|
||||
<h3>统一 Parser</h3>
|
||||
<p>学习 Yuxi 把多格式文件统一转 Markdown 的入口设计,但只实现 X-Financial 当前需要的格式。</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>分块 Preset</h3>
|
||||
<p>借鉴 RAGFlow-like preset。先做 <code>laws</code>、<code>qa</code>、<code>table</code> 三类。</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>两阶段状态</h3>
|
||||
<p>内部区分解析和索引。UI 仍可显示简单归纳状态,后台记录真实失败点。</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>轻量评测</h3>
|
||||
<p>不做评估平台,只维护 JSON 用例和脚本,持续检查召回与回答质量。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="link-list">
|
||||
<a class="link-chip" href="https://github.com/xerrors/Yuxi">Yuxi README</a>
|
||||
<a class="link-chip" href="https://github.com/xerrors/Yuxi/blob/main/backend/package/yuxi/plugins/parser/unified.py">Yuxi unified parser</a>
|
||||
<a class="link-chip" href="https://github.com/xerrors/Yuxi/blob/main/backend/package/yuxi/knowledge/chunking/ragflow_like/presets.py">Yuxi chunk presets</a>
|
||||
<a class="link-chip" href="https://github.com/xerrors/Yuxi/blob/main/backend/package/yuxi/knowledge/chunking/ragflow_like/parsers/laws.py">Yuxi laws parser</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="modules">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2 class="section-title">模块设计</h2>
|
||||
<p class="section-desc">
|
||||
新增模块必须小而清楚,避免把逻辑继续堆进单个 Service。
|
||||
单个核心文件控制在 800 行以内,优先按解析、分块、召回、评测拆分。
|
||||
</p>
|
||||
</div>
|
||||
<span class="tag">职责拆分</span>
|
||||
</div>
|
||||
|
||||
<div class="flow">
|
||||
<div class="flow-row">
|
||||
<div class="flow-key">knowledge_parser.py</div>
|
||||
<div class="flow-body">
|
||||
负责把 docx、pdf、xlsx、csv、txt 等文件转成 Markdown。
|
||||
输出正文、标题路径、页码、sheet、表头、解析告警。
|
||||
</div>
|
||||
</div>
|
||||
<div class="flow-row">
|
||||
<div class="flow-key">knowledge_chunking.py</div>
|
||||
<div class="flow-body">
|
||||
根据文件夹、文件类型和文档特征选择分块策略。
|
||||
第一批只实现制度、问答、表格三类。
|
||||
</div>
|
||||
</div>
|
||||
<div class="flow-row">
|
||||
<div class="flow-key">knowledge_retrieval.py</div>
|
||||
<div class="flow-body">
|
||||
在 LightRAG 命中结果外补充关键词、条款标题和文件名召回。
|
||||
最终输出小而准的证据块。
|
||||
</div>
|
||||
</div>
|
||||
<div class="flow-row">
|
||||
<div class="flow-key">knowledge_eval.py</div>
|
||||
<div class="flow-body">
|
||||
读取轻量评测用例,检查 expected 文件、关键词、证据和答案约束。
|
||||
用于每次调整参数后的回归验证。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="retrieval">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2 class="section-title">召回与回答策略</h2>
|
||||
<p class="section-desc">
|
||||
目标不是让模型更会猜,而是让系统给模型更可靠的证据。
|
||||
制度问题优先命中条款,表格问题保留表头与行上下文,回答必须暴露依据和缺失信息。
|
||||
</p>
|
||||
</div>
|
||||
<span class="tag">证据优先</span>
|
||||
</div>
|
||||
|
||||
<div class="grid-3">
|
||||
<div class="card tone-green">
|
||||
<h3>召回层</h3>
|
||||
<ul>
|
||||
<li>LightRAG 继续提供语义召回。</li>
|
||||
<li>条款号、标题、文件名、关键词做补召回。</li>
|
||||
<li>召回候选数量有上限,避免并发下无限扩张。</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card tone-blue">
|
||||
<h3>重排层</h3>
|
||||
<ul>
|
||||
<li>优先保留含问题关键词、标题路径和条款语义的块。</li>
|
||||
<li>制度类按条款完整度加权。</li>
|
||||
<li>最终给回答链路 3-5 条高质量证据。</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card tone-amber">
|
||||
<h3>回答层</h3>
|
||||
<ul>
|
||||
<li>能直接基于证据回答时,不强制二次模型整理。</li>
|
||||
<li>模型只做压缩表达,不凭空补事实。</li>
|
||||
<li>证据不足时明确说明缺什么。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="delivery">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2 class="section-title">实施路线</h2>
|
||||
<p class="section-desc">
|
||||
分四步小步交付。每一步都能单独验证,不把解析、索引、召回和评测揉成一次大改。
|
||||
</p>
|
||||
</div>
|
||||
<span class="tag">渐进落地</span>
|
||||
</div>
|
||||
|
||||
<div class="timeline">
|
||||
<div class="phase">
|
||||
<div class="phase-key">P0 / 文档落地</div>
|
||||
<div class="phase-body">
|
||||
<strong>先明确轻量边界</strong>
|
||||
<span>完成本文档,确认不做重平台、不替换存储、不一次性引入复杂 OCR。</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="phase">
|
||||
<div class="phase-key">P1 / 统一解析</div>
|
||||
<div class="phase-body">
|
||||
<strong>补齐文件归集质量</strong>
|
||||
<span>新增 Parser,把 Word、PDF、Excel、CSV、TXT 稳定转为 Markdown,并保存解析产物供索引复用。</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="phase">
|
||||
<div class="phase-key">P2 / 场景分块</div>
|
||||
<div class="phase-body">
|
||||
<strong>提升制度与表格命中率</strong>
|
||||
<span>实现 laws、qa、table 三类分块。制度按章、节、条、款保留完整语义,表格保留 sheet、表头和行上下文。</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="phase">
|
||||
<div class="phase-key">P3 / 混合召回</div>
|
||||
<div class="phase-body">
|
||||
<strong>减少答偏和漏召回</strong>
|
||||
<span>在 LightRAG 命中外补充关键词、条款标题、文件名召回,输出可控数量的证据块。</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="phase">
|
||||
<div class="phase-key">P4 / 轻量评测</div>
|
||||
<div class="phase-body">
|
||||
<strong>把效果优化变成可回归</strong>
|
||||
<span>建设 30-50 条远光软件制度风格问答用例,覆盖报销、差旅、发票、预算、税务等高频问题。</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="quality">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2 class="section-title">验收标准</h2>
|
||||
<p class="section-desc">
|
||||
验收不只看页面状态,而要看文件是否真实入库、召回是否命中文档依据、
|
||||
回答是否引用证据,以及并发访问时是否能稳定降级。
|
||||
</p>
|
||||
</div>
|
||||
<span class="tag">真实验证</span>
|
||||
</div>
|
||||
|
||||
<div class="checklist">
|
||||
<div class="check">Word、PDF、Excel、CSV、TXT 文件能生成可读 Markdown,且解析产物可复用。</div>
|
||||
<div class="check">制度类文件能按章、节、条、款形成相对完整的证据块。</div>
|
||||
<div class="check">Excel 表格问答能保留 sheet、表头、关键列和业务行上下文。</div>
|
||||
<div class="check">Hermes 增量任务能区分解析失败、索引失败和归纳失败。</div>
|
||||
<div class="check">常见制度问答优先返回证据化直接答案,模型超时时仍有可读降级答案。</div>
|
||||
<div class="check">5-10 个用户同时访问时,查询候选数、重排数、模型调用数都有明确上限。</div>
|
||||
<div class="check">轻量评测集覆盖至少 30 条问题,并记录命中文件、关键词和答案约束。</div>
|
||||
<div class="check">不引入 Yuxi 平台级依赖,不改变现有知识库 UI 的主体交互。</div>
|
||||
</div>
|
||||
|
||||
<p class="footnote">
|
||||
后续实现时,优先在现有定向测试基础上补充 Parser、Chunking、Retrieval 和 Knowledge Eval 的小测试。
|
||||
后端验证优先在 Docker 容器 <code>x-financial-main</code> 中运行。
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
X-Financial 轻量知识库归集与问答优化开发文档 · 放置位置:document/development/knowledge-answers/lightweight-knowledge-ingestion-design.html
|
||||
</footer>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user