269 lines
12 KiB
HTML
269 lines
12 KiB
HTML
<!DOCTYPE html>
|
|||
|
|
<html lang="zh-CN">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8" />
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
|
|
<meta name="api-base" content="http://127.0.0.1:8000" />
|
||
|
|
<title>RAG-cut — 文档切片演示</title>
|
||
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||
|
|
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
||
|
|
<link rel="stylesheet" href="/css/styles.css" />
|
||
|
|
<script src="https://cdn.jsdelivr.net/npm/marked@15.0.12/marked.min.js"></script>
|
||
|
|
<script src="https://cdn.jsdelivr.net/npm/mammoth@1.8.0/mammoth.browser.min.js"></script>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<a class="skip-link" href="#main-content">跳到主要内容</a>
|
||
|
|
|
||
|
|
<header class="app-header">
|
||
|
|
<div class="brand">
|
||
|
|
<svg class="brand-icon" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||
|
|
<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/>
|
||
|
|
<polyline points="14 2 14 8 20 8"/>
|
||
|
|
<line x1="8" y1="13" x2="16" y2="13"/>
|
||
|
|
<line x1="8" y1="17" x2="13" y2="17"/>
|
||
|
|
</svg>
|
||
|
|
<div>
|
||
|
|
<h1>RAG-cut</h1>
|
||
|
|
<p class="brand-sub">AI 知识库 · 文档切片演示</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="header-meta" id="statusBadge" aria-live="polite">
|
||
|
|
<span class="badge badge-idle">等待上传</span>
|
||
|
|
</div>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<div class="app-layout">
|
||
|
|
<aside class="config-panel" aria-label="切分配置">
|
||
|
|
<section class="panel-section">
|
||
|
|
<h2>上传文档</h2>
|
||
|
|
<div
|
||
|
|
class="dropzone"
|
||
|
|
id="dropzone"
|
||
|
|
tabindex="0"
|
||
|
|
role="button"
|
||
|
|
aria-label="点击或拖拽上传文档"
|
||
|
|
>
|
||
|
|
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
|
||
|
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||
|
|
<polyline points="17 8 12 3 7 8"/>
|
||
|
|
<line x1="12" y1="3" x2="12" y2="15"/>
|
||
|
|
</svg>
|
||
|
|
<p class="dropzone-title">拖拽文件到此处</p>
|
||
|
|
<p class="dropzone-hint">或点击选择 · pdf docx ppt pptx xlsx md txt 等</p>
|
||
|
|
<p class="dropzone-file" id="fileName"></p>
|
||
|
|
</div>
|
||
|
|
<input type="file" id="fileInput" class="sr-only" accept=".pdf,.doc,.docx,.ppt,.pptx,.ppsx,.xlsx,.xls,.csv,.md,.txt,.html,.json,.xml,.log,.jpg,.jpeg,.png,.bmp,.gif" />
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="panel-section">
|
||
|
|
<h2>切分设置</h2>
|
||
|
|
<form id="configForm" class="config-form" novalidate>
|
||
|
|
<div class="field">
|
||
|
|
<label for="splitMode">切分模式</label>
|
||
|
|
<select id="splitMode" name="mode">
|
||
|
|
<option value="default" selected>默认切分(结构感知)</option>
|
||
|
|
<option value="delimiter">通用标识符切分</option>
|
||
|
|
<option value="parent_child">父子标识符切分</option>
|
||
|
|
<option value="by_row">按行切分(表格)</option>
|
||
|
|
</select>
|
||
|
|
<p class="helper" id="modeHint">按标题/结构切分,适合 PDF、Word、PPT 等</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="mode-options" id="modeOptionsDefault">
|
||
|
|
<div class="field-row">
|
||
|
|
<div class="field">
|
||
|
|
<label for="maxChunkSize">最大长度</label>
|
||
|
|
<input type="number" id="maxChunkSize" name="max_chunk_size" min="200" max="8000" step="100" value="2200" />
|
||
|
|
</div>
|
||
|
|
<div class="field">
|
||
|
|
<label for="overlap">重叠长度</label>
|
||
|
|
<input type="number" id="overlap" name="overlap" min="0" max="2000" step="10" value="120" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="mode-options hidden" id="modeOptionsDelimiter">
|
||
|
|
<div class="field">
|
||
|
|
<label for="delimiter">标识符</label>
|
||
|
|
<input type="text" id="delimiter" name="delimiter" value="###" placeholder="例如 ### 或 \\n\\n" />
|
||
|
|
<p class="helper">按该标识符切开;标识符本身不会写入切片</p>
|
||
|
|
</div>
|
||
|
|
<div class="field-row">
|
||
|
|
<div class="field">
|
||
|
|
<label for="delimiterMaxSize">最大长度</label>
|
||
|
|
<input type="number" id="delimiterMaxSize" name="delimiter_max_chunk_size" min="200" max="8000" step="100" value="1500" />
|
||
|
|
</div>
|
||
|
|
<div class="field">
|
||
|
|
<label for="delimiterOverlap">重叠长度</label>
|
||
|
|
<input type="number" id="delimiterOverlap" name="delimiter_overlap" min="0" max="2000" step="10" value="150" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="mode-options hidden" id="modeOptionsParentChild">
|
||
|
|
<div class="field">
|
||
|
|
<label for="parentDelimiter">父级标识符</label>
|
||
|
|
<input type="text" id="parentDelimiter" name="parent_delimiter" value="##" placeholder="例如 ##" />
|
||
|
|
</div>
|
||
|
|
<div class="field">
|
||
|
|
<label for="childDelimiter">子级标识符</label>
|
||
|
|
<input type="text" id="childDelimiter" name="child_delimiter" value="###" placeholder="例如 ### 或 \\n\\n" />
|
||
|
|
<p class="helper">先按父标识符切父片,再按子标识符切子片;检索用子片,父片作上下文</p>
|
||
|
|
</div>
|
||
|
|
<div class="field-row">
|
||
|
|
<div class="field">
|
||
|
|
<label for="parentMaxSize">父级最大长度</label>
|
||
|
|
<input type="number" id="parentMaxSize" name="parent_max_chunk_size" min="200" max="8000" step="100" value="2000" />
|
||
|
|
</div>
|
||
|
|
<div class="field">
|
||
|
|
<label for="childMaxSize">子级最大长度</label>
|
||
|
|
<input type="number" id="childMaxSize" name="child_max_size" min="50" max="1500" step="50" value="512" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="field">
|
||
|
|
<label for="parentChildOverlap">重叠长度</label>
|
||
|
|
<input type="number" id="parentChildOverlap" name="parent_child_overlap" min="0" max="2000" step="10" value="80" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="mode-options hidden" id="modeOptionsByRow">
|
||
|
|
<div class="field-row">
|
||
|
|
<div class="field">
|
||
|
|
<label for="headerRowStart">表头起始行</label>
|
||
|
|
<input type="number" id="headerRowStart" name="header_row_start" min="1" value="1" />
|
||
|
|
</div>
|
||
|
|
<div class="field">
|
||
|
|
<label for="headerRowEnd">表头结束行</label>
|
||
|
|
<input type="number" id="headerRowEnd" name="header_row_end" min="1" value="1" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="field-row">
|
||
|
|
<div class="field">
|
||
|
|
<label for="startRow">数据起始行</label>
|
||
|
|
<input type="number" id="startRow" name="start_row" min="1" value="2" />
|
||
|
|
</div>
|
||
|
|
<div class="field">
|
||
|
|
<label for="rowsPerChunk">每片行数</label>
|
||
|
|
<input type="number" id="rowsPerChunk" name="rows_per_chunk" min="1" max="500" value="10" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="auto-policy" id="autoPolicy">
|
||
|
|
<div>
|
||
|
|
<span class="auto-policy-kicker" id="policyKicker">AUTO</span>
|
||
|
|
<p class="auto-policy-title" id="policyTitle">系统根据上传文档自动选择切分参数</p>
|
||
|
|
</div>
|
||
|
|
<dl class="auto-policy-grid" id="autoPolicyGrid">
|
||
|
|
<div><dt>模式</dt><dd>待上传后判断</dd></div>
|
||
|
|
<div><dt>长度</dt><dd>自动</dd></div>
|
||
|
|
<div><dt>重叠</dt><dd>自动</dd></div>
|
||
|
|
<div><dt>策略</dt><dd>自动判断</dd></div>
|
||
|
|
</dl>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<button type="submit" class="btn btn-primary" id="submitBtn" disabled title="请先上传文档">
|
||
|
|
<span class="btn-label">开始切分</span>
|
||
|
|
<span class="btn-spinner hidden" aria-hidden="true"></span>
|
||
|
|
</button>
|
||
|
|
</form>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="panel-section history-section" aria-label="历史切片">
|
||
|
|
<div class="history-header">
|
||
|
|
<h2>历史切片</h2>
|
||
|
|
<button type="button" class="btn btn-ghost btn-sm" id="historyRefreshBtn" title="刷新列表">刷新</button>
|
||
|
|
</div>
|
||
|
|
<p class="history-hint" id="historyHint">加载中…</p>
|
||
|
|
<div class="history-list" id="historyList" role="listbox" aria-label="历史切片列表"></div>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="panel-section stats-section hidden" id="statsSection">
|
||
|
|
<h2>切分概览</h2>
|
||
|
|
<dl class="stats-grid">
|
||
|
|
<div><dt>Blocks</dt><dd id="statBlocks">—</dd></div>
|
||
|
|
<div><dt>Chunks</dt><dd id="statChunks">—</dd></div>
|
||
|
|
<div><dt>模式</dt><dd id="statMode">—</dd></div>
|
||
|
|
<div><dt>Doc ID</dt><dd id="statDocId" class="mono">—</dd></div>
|
||
|
|
</dl>
|
||
|
|
</section>
|
||
|
|
</aside>
|
||
|
|
|
||
|
|
<main class="workspace" id="main-content">
|
||
|
|
<div class="empty-state" id="emptyState">
|
||
|
|
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" aria-hidden="true">
|
||
|
|
<rect x="3" y="3" width="18" height="18" rx="2"/>
|
||
|
|
<path d="M3 9h18M9 21V9"/>
|
||
|
|
</svg>
|
||
|
|
<h2>上传文档查看切片效果</h2>
|
||
|
|
<p>支持 Word / PDF / Excel / Markdown 等格式。左侧原文、中间切片列表、右侧切片预览。</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="workspace-pane hidden" id="workspacePane">
|
||
|
|
<section class="pane pane-original" aria-label="原文预览">
|
||
|
|
<div class="pane-header">
|
||
|
|
<h2>查看原文</h2>
|
||
|
|
<span class="pane-tag" id="originalTag"></span>
|
||
|
|
</div>
|
||
|
|
<div class="pane-body" id="originalPreview">
|
||
|
|
<p class="placeholder">原文加载中…</p>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="pane pane-chunks" aria-label="切片列表">
|
||
|
|
<div class="pane-header">
|
||
|
|
<h2>管理切片</h2>
|
||
|
|
<span class="pane-tag" id="chunkCountTag"></span>
|
||
|
|
</div>
|
||
|
|
<div class="pane-body chunk-list" id="chunkList" role="listbox" aria-label="切片列表"></div>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="pane pane-preview" id="previewPanel" aria-label="选中切片预览">
|
||
|
|
<div class="pane-header">
|
||
|
|
<h2>切片预览</h2>
|
||
|
|
<span class="pane-tag" id="selectedChunkTag">未选择</span>
|
||
|
|
</div>
|
||
|
|
<div class="pane-body markdown-body" id="chunkPreview">
|
||
|
|
<p class="placeholder">点击中间列表中的切片查看 Markdown 渲染结果</p>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<details class="recall-panel hidden" id="recallPanel">
|
||
|
|
<summary>召回测试</summary>
|
||
|
|
<form class="recall-form" id="recallForm">
|
||
|
|
<label class="field recall-query">
|
||
|
|
<span>查询内容</span>
|
||
|
|
<input id="recallQuery" type="search" maxlength="500" placeholder="输入要检索的问题或关键词" required />
|
||
|
|
</label>
|
||
|
|
<label class="field recall-top-k">
|
||
|
|
<span>Top K</span>
|
||
|
|
<input id="recallTopK" type="number" min="1" max="20" value="5" required />
|
||
|
|
</label>
|
||
|
|
<button class="btn btn-primary recall-submit" id="recallSubmit" type="submit">开始召回</button>
|
||
|
|
</form>
|
||
|
|
<p class="recall-hint" id="recallHint">仅检索有语义价值的切片,“仅展示”切片不会进入候选集。</p>
|
||
|
|
<div class="recall-results" id="recallResults"></div>
|
||
|
|
</details>
|
||
|
|
|
||
|
|
<details class="api-panel hidden" id="apiPanel">
|
||
|
|
<summary>API 请求 / 响应</summary>
|
||
|
|
<div class="api-grid">
|
||
|
|
<div>
|
||
|
|
<h3>Request</h3>
|
||
|
|
<pre id="apiRequest" class="code-block"></pre>
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<h3>Response</h3>
|
||
|
|
<pre id="apiResponse" class="code-block"></pre>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</details>
|
||
|
|
</main>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script src="/js/app.js"></script>
|
||
|
|
</body>
|
||
|
|
</html>
|