Full-stack application for document-to-knowledge-graph pipeline: - Backend: FastAPI + LangGraph ReAct agent + DeepSeek + MinerU parsing - Frontend: React 19 + Vite + D3.js + shadcn/ui - Pipeline: MinerU parsing → LangExtract entity extraction → KG building Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1443 lines
55 KiB
Markdown
1443 lines
55 KiB
Markdown
# GraphRAG Studio — 产品需求文档(PRD)v1.0
|
||
|
||
> 文档类型:Product Requirements Document
|
||
> 产品名称:GraphRAG Studio
|
||
> 版本:v1.0
|
||
> 日期:2026-03-05
|
||
> 作者:产品设计团队
|
||
> 状态:草稿(Draft)
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
- [一、产品概述](#一产品概述)
|
||
- [1.1 产品背景](#11-产品背景)
|
||
- [1.2 核心目标](#12-核心目标)
|
||
- [1.3 业务痛点](#13-业务痛点)
|
||
- [1.4 核心场景](#14-核心场景)
|
||
- [1.5 用户群体](#15-用户群体)
|
||
- [1.6 产品边界](#16-产品边界)
|
||
- [二、产品流程](#二产品流程)
|
||
- [2.1 整体用户旅程](#21-整体用户旅程)
|
||
- [2.2 核心流程一:文件上传与知识图谱构建](#22-核心流程一文件上传与知识图谱构建)
|
||
- [2.3 核心流程二:知识图谱探索](#23-核心流程二知识图谱探索)
|
||
- [2.4 核心流程三:Agentic 知识问答](#24-核心流程三agentic-知识问答)
|
||
- [2.5 核心流程四:多模式实体搜索](#25-核心流程四多模式实体搜索)
|
||
- [2.6 错误与异常处理流程](#26-错误与异常处理流程)
|
||
- [三、页面与模块清单](#三页面与模块清单)
|
||
- [3.1 全局框架模块](#31-全局框架模块)
|
||
- [3.2 Page 1 — Dashboard(系统总览)](#32-page-1--dashboard系统总览)
|
||
- [3.3 Page 2 — Document Manager(文档管理)](#33-page-2--document-manager文档管理)
|
||
- [3.4 Page 3 — KG Explorer(知识图谱)](#34-page-3--kg-explorer知识图谱)
|
||
- [3.5 Page 4 — QA Chat(智能问答)](#35-page-4--qa-chat智能问答)
|
||
- [3.6 Page 5 — Search(搜索)](#36-page-5--search搜索)
|
||
- [四、核心功能交互逻辑](#四核心功能交互逻辑)
|
||
- [4.1 文件上传与索引任务管理](#41-文件上传与索引任务管理)
|
||
- [4.2 知识图谱可视化交互](#42-知识图谱可视化交互)
|
||
- [4.3 多轮对话与推理链展示](#43-多轮对话与推理链展示)
|
||
- [4.4 跨页面联动导航](#44-跨页面联动导航)
|
||
- [4.5 全局通知与反馈机制](#45-全局通知与反馈机制)
|
||
- [五、UI 设计规范](#五ui-设计规范)
|
||
- [5.1 整体布局结构](#51-整体布局结构)
|
||
- [5.2 配色系统](#52-配色系统)
|
||
- [5.3 字体与排版](#53-字体与排版)
|
||
- [5.4 组件样式规范](#54-组件样式规范)
|
||
- [5.5 响应式断点规范](#55-响应式断点规范)
|
||
- [六、后端接口依赖](#六后端接口依赖)
|
||
- [七、非功能性需求](#七非功能性需求)
|
||
- [八、验收标准](#八验收标准)
|
||
|
||
---
|
||
|
||
## 一、产品概述
|
||
|
||
### 1.1 产品背景
|
||
|
||
在学术研究、企业知识管理、技术调研等场景中,研究人员需要从大量非结构化文档(PDF 论文、DOCX 报告、PPT 演示文稿、图片等)中快速提炼关键知识,理解概念之间的语义关联。
|
||
|
||
传统的 RAG(检索增强生成)系统采用向量检索方式,其结果呈现为零散的文本片段,缺乏实体间的结构化关联。用户无法直观感知"某个概念与哪些技术相关""两个实体之间的路径是什么"等图谱层面的知识。
|
||
|
||
**GraphRAG Studio** 基于知识图谱增强的多模态 RAG 技术,将文档自动解析为结构化知识图谱,并提供图谱可视化、多轮问答、实体搜索等完整工具链,将非结构化文档转化为可交互的知识网络。
|
||
|
||
### 1.2 核心目标
|
||
|
||
| 目标 | 说明 |
|
||
|------|------|
|
||
| **知识结构化** | 将多格式文档(PDF/DOCX/PPTX/PNG 等)自动解析并提取实体与关系,构建知识图谱 |
|
||
| **知识可视化** | 提供交互式力导向图,直观呈现实体及其语义关联,支持筛选、搜索、节点详情 |
|
||
| **知识问答** | 基于 Agentic-RAG(ReAct 框架),对自然语言问题进行多步工具调用推理,给出有据可查的答案 |
|
||
| **知识探索** | 提供实体搜索、路径发现、子图搜索三种探索模式,支持从不同维度切入知识网络 |
|
||
| **工程化管理** | 提供完整的文档上传、索引任务管理、任务进度监控、失败重试等工程化能力 |
|
||
|
||
### 1.3 业务痛点
|
||
|
||
**P1 — 高优先级痛点(必须解决)**
|
||
|
||
| # | 痛点描述 | 影响 |
|
||
|---|---------|------|
|
||
| P1-1 | 文档中知识密度高,人工阅读耗时长,无法快速定位关键概念 | 研究效率低下 |
|
||
| P1-2 | 概念之间的关联关系隐含在文字中,难以可视化梳理 | 知识理解片面 |
|
||
| P1-3 | 传统 RAG 只能返回文本片段,缺乏结构化推理能力 | 问答质量不稳定 |
|
||
| P1-4 | 多份文档的知识无法统一管理和关联查询 | 知识孤岛问题 |
|
||
|
||
**P2 — 中优先级痛点(应当解决)**
|
||
|
||
| # | 痛点描述 | 影响 |
|
||
|---|---------|------|
|
||
| P2-1 | 索引任务耗时长(MinerU 解析 + LLM 抽取),用户无法感知进度 | 操作体验差 |
|
||
| P2-2 | LLM 推理过程黑箱,用户不知道答案从何而来 | 可信度低 |
|
||
| P2-3 | 搜索只能通过全文检索,无法按实体类型或图谱路径搜索 | 搜索精度不足 |
|
||
|
||
**P3 — 低优先级痛点(后续解决)**
|
||
|
||
| # | 痛点描述 |
|
||
|---|---------|
|
||
| P3-1 | 多人协作时知识图谱共享困难 |
|
||
| P3-2 | 知识图谱版本管理缺失 |
|
||
|
||
### 1.4 核心场景
|
||
|
||
**场景一:论文精读与知识提炼**
|
||
|
||
> 研究人员上传一篇 GraphRAG 相关的 PDF 论文,系统自动提取论文中的技术概念(TECHNOLOGY)、研究方法(CONCEPT)、研究机构(ORGANIZATION)及其关联关系,生成知识图谱。研究人员通过图谱可视化快速理解论文核心知识结构,并通过 QA Chat 就具体问题进行深度追问。
|
||
|
||
**场景二:多文档跨文件知识整合**
|
||
|
||
> 用户批量上传多份研究报告,系统对每份文档独立索引后,将所有实体和关系合并至全局知识图谱。用户可在图谱中筛选特定文档的节点,发现跨文档的共同实体,通过路径搜索追溯概念间的传播关系。
|
||
|
||
**场景三:快速技术调研问答**
|
||
|
||
> 产品经理或技术负责人上传若干竞品白皮书,通过 QA Chat 提问"这些文档中提到了哪些核心技术?它们之间的关系是什么?"。系统通过 Agentic-RAG 进行多步工具调用(实体搜索 → 邻居查询 → 描述生成),返回结构化答案并展示推理步骤,Cited Nodes 直接链接到图谱中对应的节点。
|
||
|
||
**场景四:知识图谱演示与汇报**
|
||
|
||
> 教师或讲师上传课程材料,通过 KG Explorer 的全屏图谱视图向学生展示知识体系结构;通过 Demo 模式加载预置数据集,无需实际索引即可演示产品能力。
|
||
|
||
### 1.5 用户群体
|
||
|
||
| 用户角色 | 特征描述 | 核心诉求 | 使用频次 |
|
||
|---------|---------|---------|---------|
|
||
| **研究员 / 学者** | 熟悉 AI/NLP 领域,有文献精读需求 | 快速提取论文概念关联,深度问答 | 高频(每日) |
|
||
| **产品经理 / 分析师** | 非技术背景,有竞品调研需求 | 直观图谱展示,简单问答 | 中频(每周) |
|
||
| **技术工程师** | 熟悉 API,有集成需求 | 完整 API 文档,调试便利 | 中频(按需) |
|
||
| **教师 / 讲师** | 有知识可视化展示需求 | 图谱演示,无需深度操作 | 低频(按需) |
|
||
| **系统管理员** | 负责部署和维护 | 系统健康监控,日志排查 | 低频(运维) |
|
||
|
||
**主要设计对象:** 研究员 / 学者(核心用户)、产品经理 / 分析师(次核心用户)
|
||
|
||
### 1.6 产品边界
|
||
|
||
**In Scope(本版本包含):**
|
||
- 多格式文档上传与管理(PDF/DOCX/PPTX/DOC/PPT/PNG/JPG/HTML)
|
||
- MinerU 文档解析 + LangExtract 实体抽取自动索引链路
|
||
- 全局知识图谱的可视化浏览与交互
|
||
- 基于 Agentic-RAG(DeepSeek + LangChain)的多轮问答
|
||
- 实体搜索、路径搜索、子图搜索
|
||
- 系统健康监控与任务状态看板
|
||
|
||
**Out of Scope(本版本不包含):**
|
||
- 用户账号体系与权限管理
|
||
- 多人协作与知识图谱共享
|
||
- 知识图谱版本历史与回滚
|
||
- 流式(Stream)问答输出
|
||
- 自定义实体类型与关系类型配置
|
||
|
||
---
|
||
|
||
## 二、产品流程
|
||
|
||
### 2.1 整体用户旅程
|
||
|
||
```
|
||
进入系统
|
||
│
|
||
▼
|
||
[Dashboard] ─── 查看系统概览 & 健康状态
|
||
│
|
||
├─── 无文档 → [Documents] 上传文件 → 触发索引 → 等待完成
|
||
│ │
|
||
│ 索引完成 (done)
|
||
│ │
|
||
├─── 有 KG ──────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌──────────────────────────────────────────────┘
|
||
│ │
|
||
├────▼─── [KG Explorer] 图谱可视化浏览
|
||
│ └─── 点击节点 → 查看详情 → [Ask AI] → Chat
|
||
│
|
||
├────────── [QA Chat] 自然语言问答
|
||
│ └─── Cited Nodes → KG Explorer 节点定位
|
||
│
|
||
└────────── [Search] 实体/路径/子图搜索
|
||
└─── View in KG → KG Explorer
|
||
└─── Chat → Chat 预填问题
|
||
```
|
||
|
||
### 2.2 核心流程一:文件上传与知识图谱构建
|
||
|
||
这是系统最核心的数据入口流程,共分为 6 个阶段,涵盖客户端校验、上传、解析、实体抽取、图谱构建、结果呈现。
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────────┐
|
||
│ 文件上传与索引完整流程 │
|
||
└──────────────────────────────────────────────────────────────────┘
|
||
|
||
用户操作:拖拽文件 / 点击"Browse Files"
|
||
│
|
||
▼
|
||
[Stage 0 — 客户端预校验]
|
||
检查文件扩展名(PDF/DOCX/DOC/PPTX/PPT/PNG/JPG/JPEG/HTML)
|
||
检查文件大小(≤ 200MB)
|
||
─── 校验失败 → 文件名标红 + 行内错误说明(不上传)
|
||
─── 校验通过 → 进入 Stage 1
|
||
│
|
||
▼
|
||
[Stage 1 — 文件上传]
|
||
POST /api/v1/documents/upload (multipart/form-data)
|
||
─── 成功 → 返回 doc_id,文档行项目添加到列表(status: uploaded)
|
||
─── 失败 → Toast.error + 终止流程
|
||
│
|
||
▼
|
||
[Stage 1.5 — 用户确认]
|
||
弹出二次确认:
|
||
"Start indexing now? [Yes, Start Indexing] [Later]"
|
||
─── Later → 保持 uploaded 状态,显示 [▶ Index] 按钮,流程结束
|
||
─── Yes → 进入 Stage 2
|
||
│
|
||
▼
|
||
[Stage 2 — 启动索引任务]
|
||
POST /api/v1/index/start { doc_id }
|
||
─── 成功 → 返回 job_id,status 更新为 indexing,显示进度条
|
||
─── 失败 → Toast.error(如"文档已在索引中")
|
||
│
|
||
▼
|
||
[Stage 3 — MinerU 文档解析(parsing)]
|
||
轮询 GET /api/v1/index/status/{job_id}(每 3 秒)
|
||
stage = "parsing"
|
||
进度显示:"Stage: Parsing document pages (2/4)..."
|
||
progress = parsed_pages / total_pages × 33%
|
||
│
|
||
▼
|
||
[Stage 4 — LangExtract 实体抽取(extracting)]
|
||
stage = "extracting"
|
||
进度显示:"Stage: Extracting entities (18 found so far)..."
|
||
progress = 33% + extracted_entities / estimated_total × 33%
|
||
│
|
||
▼
|
||
[Stage 5 — 知识图谱构建(indexing)]
|
||
stage = "indexing"
|
||
进度显示:"Stage: Building knowledge graph..."
|
||
progress ≈ 90%
|
||
│
|
||
▼
|
||
[Stage 6 — 完成(done / failed)]
|
||
─── done:
|
||
GET /api/v1/index/result/{job_id} → 获取结果统计
|
||
更新状态标记为 ● indexed
|
||
展开结果摘要:40 nodes · 780 edges · 4 pages · 45 extractions · 42.1s
|
||
Toast.success("paper.pdf indexed: 40 nodes, 780 edges")
|
||
AppState.kg.loaded = false(触发 KG Explorer 下次进入时重新加载)
|
||
─── failed:
|
||
行内展示错误信息(如 "MinerU failed: timeout after 600s")
|
||
显示 [⟳ Retry] 按钮
|
||
Toast.error("Indexing failed: paper.pdf")
|
||
```
|
||
|
||
**多文件串行处理规则:**
|
||
- 同时拖入多个文件时,依次串行执行上述流程(上传 → 确认 → 索引)
|
||
- 每个文件独立显示进度,互不影响
|
||
- 任一文件失败不阻塞其他文件的处理
|
||
|
||
### 2.3 核心流程二:知识图谱探索
|
||
|
||
```
|
||
进入 KG Explorer (#/graph)
|
||
│
|
||
▼
|
||
[初始化加载]
|
||
优先读取 AppState.kg 缓存(避免重复请求)
|
||
若无缓存 → GET /api/v1/kg/nodes?page_size=200
|
||
GET /api/v1/kg/edges?page_size=500
|
||
─── KG 为空(code 3002)→ 显示空状态引导页面
|
||
─── 加载成功 → D3 力导向图渲染
|
||
│
|
||
▼
|
||
[URL 参数处理]
|
||
解析 hash query:
|
||
?doc_id=xxx → 自动勾选对应文档筛选,其余节点淡化
|
||
?node=xxx → 自动选中节点 + 高亮 + 展开 Detail Panel + 平移居中
|
||
│
|
||
▼
|
||
[用户交互分支]
|
||
│
|
||
├─ 节点悬停 → Tooltip(name / type / page / confidence / degree)
|
||
│
|
||
├─ 节点单击
|
||
│ GET /api/v1/kg/nodes/{node_id}(获取详情)
|
||
│ GET /api/v1/kg/nodes/{node_id}/neighbors?hops=1(获取邻居)
|
||
│ → 右侧 Detail Panel 展开
|
||
│ → 点击节点高亮,其余节点 opacity 0.1,相连边 opacity 0.8
|
||
│
|
||
├─ 节点拖拽 → pin 到固定位置(fx/fy 设置)
|
||
│
|
||
├─ 点击空白处 → 取消选中,Detail Panel 收起,恢复透明度
|
||
│
|
||
├─ Filter Panel 操作
|
||
│ 勾选/取消实体类型 → 实时过滤可见节点
|
||
│ 选择 Source Doc → 筛选对应文档节点
|
||
│ 勾选/取消 Confidence 等级 → 实时过滤
|
||
│
|
||
├─ 工具栏操作
|
||
│ [+ -] → 缩放
|
||
│ [⊡ Fit] → 自适应全部节点
|
||
│ [Search] → GET /api/v1/search/entities?q=...(闪烁高亮 + 居中)
|
||
│ [PNG] → SVG → PNG 下载
|
||
│ [JSON] → GET /api/v1/kg/export → 文件下载
|
||
│
|
||
└─ Detail Panel 操作
|
||
[💬 Ask AI] → #/chat?q=Tell+me+about+{name}
|
||
邻居节点点击 → 切换选中节点
|
||
[All neighbors →] → 展开完整邻居列表
|
||
```
|
||
|
||
### 2.4 核心流程三:Agentic 知识问答
|
||
|
||
```
|
||
进入 Chat (#/chat)
|
||
│
|
||
▼
|
||
[初始化]
|
||
GET /api/v1/query/history?page_size=20 → 渲染左侧历史列表
|
||
若无历史 → 显示欢迎页 + Suggested Prompts
|
||
若有 URL 参数 ?q=... → 预填输入框并自动聚焦
|
||
│
|
||
▼
|
||
[用户输入问题]
|
||
输入框(多行)+ Enter 或 点击 [▶] 按钮
|
||
│
|
||
▼
|
||
[发送请求]
|
||
构建 payload:
|
||
{ question: "...", history: [ {role:"human",...}, {role:"ai",...} ] }
|
||
POST /api/v1/query
|
||
立即显示:
|
||
- 用户消息气泡(右对齐,蓝色背景)
|
||
- "thinking..." 三点跳动动画(左对齐)
|
||
输入框禁用(发送中)
|
||
│
|
||
▼
|
||
[等待 API 响应(超时 60s)]
|
||
─── 超时 → Toast.warning + 三点动画消失 + 输入框恢复
|
||
─── 网络错误 → Toast.error("Network error") + [Retry]
|
||
─── API 成功 → 进入渲染阶段
|
||
│
|
||
▼
|
||
[渲染 AI 回答]
|
||
消除 thinking 动画
|
||
渲染 AI 消息气泡(左对齐,卡片样式):
|
||
│
|
||
├─ answer 文本(marked.js 渲染 Markdown)
|
||
│
|
||
├─ Tool Calls 折叠面板(默认收起)
|
||
│ 显示 "▶ Tool Calls (N steps)"
|
||
│ 展开后逐步显示每个工具调用:
|
||
│ Step 1: search_entities / Input / Output
|
||
│ Step 2: get_neighbors / Input / Output
|
||
│ ...(等宽字体,代码块样式)
|
||
│
|
||
├─ Cited Nodes 标签组
|
||
│ [◉ GraphRAG] [◉ LLMs] [◉ knowledge graphs] ...
|
||
│ 点击任一标签 → #/graph?node={node_id}
|
||
│ hover → 显示 Tooltip(type + page)
|
||
│
|
||
└─ 耗时信息(⏱ 8.4s)
|
||
│
|
||
▼
|
||
[更新状态]
|
||
AppState.chatHistory.push(result)(维护多轮 history)
|
||
输入框清空 + 恢复可用
|
||
左侧历史列表:新会话置顶
|
||
```
|
||
|
||
### 2.5 核心流程四:多模式实体搜索
|
||
|
||
```
|
||
进入 Search (#/search)
|
||
│
|
||
▼
|
||
[初始化]
|
||
解析 URL 参数 ?q=...&type=...&tab=...
|
||
预填搜索框,自动触发搜索
|
||
│
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ 三种搜索模式 │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
│
|
||
├── [Tab 1: Entity Search]
|
||
│ 输入实体名称 + 可选类型过滤(All / TECHNOLOGY / CONCEPT / ...)
|
||
│ 点击 [Search] 或 Enter
|
||
│ GET /api/v1/search/entities?q=...&type=...
|
||
│ ─── 无结果 → 空状态提示 + "Try KG Explorer"
|
||
│ ─── 有结果 → 左侧结果列表(实体卡片)
|
||
│ 点击结果行 → 右侧 Preview Graph 渲染(1-hop 邻居子图)
|
||
│ GET /api/v1/kg/nodes/{id}/neighbors?hops=1
|
||
│ [View KG] → #/graph?node={node_id}
|
||
│ [Chat] → #/chat?q=What+is+{name}
|
||
│
|
||
├── [Tab 2: Path Search]
|
||
│ 选择起点节点(搜索选择器)
|
||
│ 选择终点节点(搜索选择器)
|
||
│ 设置最大跳数(1-5)
|
||
│ 点击 [Find Path]
|
||
│ GET /api/v1/search/path?from={id}&to={id}&max_hops={n}
|
||
│ ─── 无路径 → "No path found between these entities"
|
||
│ ─── 有路径 → 路径可视化(线性节点链)+ 文字描述
|
||
│
|
||
└── [Tab 3: Graph Search]
|
||
输入关键词 + 可选"Include Neighbors"开关
|
||
点击 [Search]
|
||
GET /api/v1/search/graph?q=...&include_neighbors=true
|
||
─── 渲染子图(D3 可视化,仅展示匹配节点及其邻边)
|
||
─── 列表显示匹配节点摘要(name / type / page)
|
||
```
|
||
|
||
### 2.6 错误与异常处理流程
|
||
|
||
```
|
||
API 调用失败(code ≠ 0)
|
||
│
|
||
├─ code 1001/1002/1003(参数/格式/大小校验)
|
||
│ → 行内错误提示(不弹 Toast)
|
||
│
|
||
├─ code 2001(job 不存在)
|
||
│ → Toast.error + 刷新任务列表
|
||
│
|
||
├─ code 3002(KG 为空)
|
||
│ → 不弹 Toast,页面内空状态引导:[Upload & Index →]
|
||
│
|
||
├─ code 4001(QA 失败)
|
||
│ → Toast.error(msg) + 输入框恢复
|
||
│
|
||
├─ code 5000(服务器内部错误)
|
||
│ → Toast.error("Server error, check API logs")
|
||
│
|
||
└─ 网络不可达(fetch 异常)
|
||
→ Toast.error("Network error. Is API server running on :8000?")
|
||
→ 相关操作显示 [Retry] 按钮
|
||
→ Header 右侧健康指示器变红点
|
||
```
|
||
|
||
---
|
||
|
||
## 三、页面与模块清单
|
||
|
||
### 3.1 全局框架模块
|
||
|
||
系统采用 SPA(单页应用)架构,Hash 路由(`#/dashboard`、`#/documents` 等),全局框架由以下四个固定区域构成:
|
||
|
||
#### 3.1.1 Header(顶部导航栏)
|
||
|
||
- **高度:** 56px,`position: sticky; top: 0; z-index: 100`
|
||
- **左区:** 汉堡折叠按钮(`[≡]`)+ 产品 Logo 文字 "GraphRAG Studio"
|
||
- **中区:** 全局搜索框(max-width 400px)
|
||
- 输入 3+ 字符 → 实时调用实体搜索接口(debounce 300ms)
|
||
- 下拉展示最多 5 条建议(名称 + 类型 Badge)
|
||
- 按 Enter → 跳转 `#/search?q={input}`
|
||
- 点击建议项 → 跳转 `#/graph?node={node_id}`
|
||
- **右区:** 系统健康指示器(绿点/红点)+ "API: localhost:8000"
|
||
|
||
#### 3.1.2 Sidebar(左侧导航栏)
|
||
|
||
- **宽度:** 220px(默认),折叠后 72px(仅图标)
|
||
- **导航项列表:**
|
||
|
||
| 图标 | 标签 | 路由 | 右侧 Badge |
|
||
|------|------|------|-----------|
|
||
| ◈ | Dashboard | `#/dashboard` | — |
|
||
| ▤ | Documents | `#/documents` | 文档总数 |
|
||
| ◉ | KG Explorer | `#/graph` | — |
|
||
| ◇ | Chat | `#/chat` | 历史查询数 |
|
||
| ⊕ | Search | `#/search` | — |
|
||
| ☰ | System | — | — |
|
||
|
||
- **激活状态:** 左侧 2px 蓝色竖线 + 背景 `rgba(88,166,255,0.1)` + 文字变蓝
|
||
|
||
#### 3.1.3 Status Bar(底部状态栏)
|
||
|
||
- **高度:** 32px,常驻底部
|
||
- **左区:** 当前活跃 Job 进度(如 "Indexing paper.pdf... 65%"),无 Job 时隐藏
|
||
- **右区:** API 版本号(v1.0.0)+ 健康状态点(常驻)
|
||
|
||
#### 3.1.4 全局状态管理(AppState)
|
||
|
||
前端维护内存级全局状态,页面间共享:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `currentPage` | string | 当前激活页面 |
|
||
| `kg.nodes` | array | 全量 KG 节点缓存(首次加载后复用) |
|
||
| `kg.edges` | array | 全量 KG 边缓存 |
|
||
| `kg.loaded` | boolean | 索引完成后置 false,触发重新加载 |
|
||
| `documents` | array | 文档列表缓存 |
|
||
| `activeJobs` | object | `job_id → polling timer`(轮询管理) |
|
||
| `chatHistory` | array | 当前会话的多轮对话历史 |
|
||
| `health` | object | 最近一次健康检查结果 |
|
||
|
||
---
|
||
|
||
### 3.2 Page 1 — Dashboard(系统总览)
|
||
|
||
**路由:** `#/dashboard`
|
||
**目的:** 系统全局状态一览,快速导航到各功能,最近活动监控。
|
||
|
||
#### 模块组成
|
||
|
||
**A. Overview 指标卡(4 个)**
|
||
|
||
| 指标 | 数据来源 | 颜色 |
|
||
|------|---------|------|
|
||
| KG Nodes(知识节点数) | `GET /api/v1/system/stats` | 蓝色 `#58a6ff` |
|
||
| KG Edges(知识关系数) | `GET /api/v1/system/stats` | 紫色 `#8957e5` |
|
||
| Documents(文档总数) | `GET /api/v1/system/stats` | 绿色 `#3fb950` |
|
||
| Queries(问答次数) | `GET /api/v1/system/stats` | 黄色 `#d29922` |
|
||
|
||
每 10 秒自动轮询刷新,数值变化时平滑过渡动画。
|
||
|
||
**B. System Health 面板**
|
||
|
||
显示 4 个依赖服务的健康状态,数据来源 `GET /api/v1/health`:
|
||
|
||
| 服务 | 状态指示 |
|
||
|------|---------|
|
||
| MinerU venv | ● ok / ● error |
|
||
| LangExtract venv | ● ok / ● error |
|
||
| DeepSeek API | ● ok / ● error |
|
||
| Storage | ● ok / ● error |
|
||
|
||
**C. Recent Documents 列表**
|
||
|
||
显示最近 5 条文档记录,数据来源 `GET /api/v1/documents?page=1&page_size=5`:
|
||
- 文件名、格式、页数、状态 Badge、日期
|
||
- indexed 状态:显示 [KG] 跳转按钮
|
||
- indexing 状态:显示行内进度条 + [✕] 取消按钮
|
||
- uploaded 状态:显示 [▶ Index] 按钮
|
||
- 右上角 [View All →] 跳转 `#/documents`
|
||
|
||
**D. Quick Actions 快捷按钮组**
|
||
|
||
| 按钮 | 操作 |
|
||
|------|------|
|
||
| [◉ Explore KG] | 跳转 `#/graph` |
|
||
| [◇ Start Chat] | 跳转 `#/chat` |
|
||
| [⊕ Search] | 跳转 `#/search` |
|
||
| [⚡ Demo] | 调用 `GET /api/v1/system/demo`,加载演示数据,跳转 `#/graph` |
|
||
|
||
**E. Upload & Index 入口**
|
||
|
||
右上角 `[+ Upload & Index]` 主操作按钮,点击打开 Upload Modal(复用 Documents 页上传区),完成后跳转 `#/documents`。
|
||
|
||
---
|
||
|
||
### 3.3 Page 2 — Document Manager(文档管理)
|
||
|
||
**路由:** `#/documents`
|
||
**目的:** 文件上传、列表管理、触发/监控索引任务、查看索引结果。
|
||
|
||
#### 模块组成
|
||
|
||
**A. 拖拽上传区**
|
||
|
||
- 虚线边框卡片,居中显示上传图标和说明文字
|
||
- 拖拽悬停时:边框变蓝(`#58a6ff`)+ 背景 `rgba(88,166,255,0.05)`
|
||
- 点击 [Browse Files] 触发文件选择器
|
||
- 支持格式说明:`PDF · DOCX · DOC · PPTX · PPT · PNG · JPG · HTML`
|
||
- 文件大小限制:`Max 200MB per file`
|
||
|
||
**B. 文档列表工具栏**
|
||
|
||
- 格式筛选下拉(All / PDF / DOCX / PPTX / PNG / JPG / HTML)
|
||
- 状态筛选下拉(All / indexed / indexing / uploaded / failed)
|
||
- 关键词搜索框(客户端过滤,实时)
|
||
|
||
**C. 文档列表(表格)**
|
||
|
||
每行字段:文件名、格式、页数、状态 Badge、上传日期、操作按钮组
|
||
|
||
| 状态 | 显示内容 | 操作按钮 |
|
||
|------|---------|---------|
|
||
| `uploaded` | ● uploaded(灰) | [▶ Index] [🗑 Delete] |
|
||
| `indexing` | ● indexing(黄,动画点) + 进度条 + stage 说明 | [✕ Cancel] |
|
||
| `indexed` | ● indexed(绿) | [◉ View KG] [🗑 Delete] |
|
||
| `failed` | ● failed(红) + 错误摘要 | [⟳ Retry] [🗑 Delete] |
|
||
|
||
**D. 索引结果展开行**(仅 indexed 状态)
|
||
|
||
点击展开:
|
||
```
|
||
40 nodes · 780 edges · 4 pages · 45 extractions · 42.1s
|
||
TECHNOLOGY(4) CONCEPT(36)
|
||
[◉ View in KG] [≡ Show Extractions]
|
||
```
|
||
|
||
展开 [Show Extractions] 显示抽取记录表:text / type / alignment / page(最多 50 条,可滚动)
|
||
|
||
---
|
||
|
||
### 3.4 Page 3 — KG Explorer(知识图谱)
|
||
|
||
**路由:** `#/graph`
|
||
**目的:** 全屏交互式知识图谱可视化,节点筛选、详情查看、图谱导出。
|
||
|
||
#### 模块组成
|
||
|
||
**A. Filter Panel(左侧筛选栏,280px)**
|
||
|
||
- Source Docs 下拉:按文档筛选图谱节点
|
||
- Entity Types 多选:TECHNOLOGY / CONCEPT / PERSON / ORGANIZATION / LOCATION(每类显示数量)
|
||
- Confidence 等级多选:exact / greater / lesser / fuzzy
|
||
- 图谱导出按钮:[📷 Export PNG] [⬇ Export JSON]
|
||
|
||
**B. D3 力导向图(中央主区,flex: 1)**
|
||
|
||
- SVG 全屏渲染,支持 `d3.zoom`(scaleExtent 0.1 ~ 8)
|
||
- 工具栏(浮于图谱左上角):[+] [-] [⊡ Fit All] [🔍 Search input]
|
||
- 图例(浮于图谱左下角):五种颜色对应五种实体类型
|
||
- 空状态(KG 无数据):居中提示 + [Upload & Index →] 按钮
|
||
|
||
**C. Detail Panel(右侧详情栏,300px,点击节点后出现)**
|
||
|
||
- 节点名称(H1 样式)
|
||
- 实体类型 Badge
|
||
- 属性信息:Page / Confidence / Degree / Centrality
|
||
- 邻居节点列表(最多展示 5 个,[All N →] 查看全部)
|
||
- [💬 Ask AI] 按钮 → 跳转 Chat 预填问题
|
||
- [× Close] 关闭 Detail Panel
|
||
|
||
---
|
||
|
||
### 3.5 Page 4 — QA Chat(智能问答)
|
||
|
||
**路由:** `#/chat`
|
||
**目的:** 多轮知识图谱问答,展示 Agentic-RAG 推理过程,Cited Node 联动跳转。
|
||
|
||
#### 模块组成
|
||
|
||
**A. History Sidebar(左侧历史栏,240px)**
|
||
|
||
- [+ New Chat] 新建会话按钮
|
||
- 历史记录列表(按时间分组:Today / Yesterday / Earlier)
|
||
- 每条显示问题前 30 字符
|
||
- 点击切换历史会话(前端记录,当前版本不持久化多会话)
|
||
- 数据来源:`GET /api/v1/query/history?page_size=20`
|
||
|
||
**B. Chat Area(右侧对话区)**
|
||
|
||
- 欢迎界面(无历史时):产品介绍 + Suggested Prompts(4 个常用问题)
|
||
- 消息时间分隔线
|
||
- 用户消息气泡(右对齐,蓝色背景)
|
||
- AI 消息气泡(左对齐,卡片样式):
|
||
- Markdown 渲染的答案文本
|
||
- Tool Calls 折叠面板(默认收起)
|
||
- Cited Nodes 标签组(可点击跳转)
|
||
- 耗时信息(⏱ N.Ns)
|
||
- Thinking 动画(三点跳动)
|
||
|
||
**C. 输入区**
|
||
|
||
- 多行文本输入框(placeholder: "Ask about the knowledge graph...")
|
||
- [▶ Send] 发送按钮
|
||
- Enter 发送,Shift+Enter 换行
|
||
- 发送中:输入框禁用,按钮 loading 状态
|
||
|
||
---
|
||
|
||
### 3.6 Page 5 — Search(搜索)
|
||
|
||
**路由:** `#/search`
|
||
**目的:** 多模式实体搜索,支持关键词、路径、子图三种搜索范式。
|
||
|
||
#### 模块组成
|
||
|
||
**A. 搜索头区**
|
||
|
||
- 主搜索框(全宽)
|
||
- 类型筛选下拉(All Types / TECHNOLOGY / CONCEPT / PERSON / ORG / LOC)
|
||
- [Search] 搜索按钮
|
||
- 搜索状态与 URL 双向同步:`#/search?q=...&type=...&tab=...`
|
||
|
||
**B. Tab 切换栏**
|
||
|
||
3 个 Tab:Entity Search(默认) / Path Search / Graph Search
|
||
|
||
**C. Entity Search Tab**
|
||
|
||
- 左栏:结果列表(卡片式)
|
||
- 实体名称 + 类型 Badge + 页码 + Degree + Confidence
|
||
- [View KG] + [Chat] 操作按钮
|
||
- 右栏:Preview Graph(D3 迷你图,展示选中实体的 1-hop 邻居子图)
|
||
|
||
**D. Path Search Tab**
|
||
|
||
- From 节点选择器(搜索 + 下拉选择)
|
||
- To 节点选择器
|
||
- Max Hops 下拉(1-5)
|
||
- [Find Path] 按钮
|
||
- 路径结果:线性节点链可视化 + 文字描述
|
||
|
||
**E. Graph Search Tab**
|
||
|
||
- 关键词输入框
|
||
- [Include Neighbors] 开关
|
||
- D3 子图可视化(全宽)
|
||
- 匹配节点列表
|
||
|
||
---
|
||
|
||
## 四、核心功能交互逻辑
|
||
|
||
### 4.1 文件上传与索引任务管理
|
||
|
||
#### 拖拽上传区状态机
|
||
|
||
```
|
||
初始状态(idle)
|
||
│
|
||
├── dragenter → hover 状态(边框蓝,背景浅蓝)
|
||
│ └── dragleave → 回到 idle
|
||
│
|
||
└── drop / browse → uploading 状态
|
||
│
|
||
├── 校验失败 → idle(行内错误)
|
||
└── 校验通过 → 文件加入上传队列
|
||
```
|
||
|
||
#### 进度条渲染规则
|
||
|
||
| 阶段 | 进度计算 | 展示文字 |
|
||
|------|---------|---------|
|
||
| parsing | `parsed_pages / total_pages × 33%` | "Parsing document... (2/4 pages)" |
|
||
| extracting | `33% + extracted_entities / estimated × 33%` | "Extracting entities... (18 found)" |
|
||
| indexing | 固定 80% ~ 95%(indeterminate) | "Building knowledge graph..." |
|
||
| done | 100% | 渐隐,展开结果行 |
|
||
|
||
#### 索引取消逻辑
|
||
|
||
- 点击 [✕ Cancel] → 弹出确认弹窗
|
||
- 确认后 → `DELETE /api/v1/index/jobs/{job_id}`
|
||
- 停止对应 job_id 的轮询 timer
|
||
- 文档状态退回 "uploaded",显示 [▶ Index] 按钮
|
||
|
||
#### 文档删除确认弹窗规范
|
||
|
||
删除 indexed 状态的文档时,弹窗需展示关联数据影响范围:
|
||
|
||
```
|
||
Delete "paper.pdf"?
|
||
|
||
This document and all associated KG data will be permanently deleted.
|
||
· 40 nodes removed from knowledge graph
|
||
· 780 edges removed from knowledge graph
|
||
|
||
This action cannot be undone.
|
||
|
||
[Cancel] [Delete →]
|
||
```
|
||
|
||
- [Delete] 为红色危险按钮
|
||
- 操作完成后 Toast.success("paper.pdf deleted") + 刷新列表
|
||
|
||
### 4.2 知识图谱可视化交互
|
||
|
||
#### 节点视觉映射规则
|
||
|
||
| 视觉属性 | 规则 |
|
||
|---------|------|
|
||
| 颜色 | 实体类型 → 5 色方案(蓝/紫/绿/红/橙) |
|
||
| 半径 | `r = Math.max(4, Math.log(degree + 1) × 4)`(连接越多越大) |
|
||
| 描边 | 正常 1.5px / hover 2.5px 白色 |
|
||
| 透明度 | 正常 0.9;高亮模式下非焦点节点 0.1 |
|
||
|
||
#### 节点高亮逻辑(聚焦模式)
|
||
|
||
```
|
||
点击节点 N:
|
||
所有节点 → opacity 0.1(淡化)
|
||
节点 N 及其直连邻居 → opacity 0.9(保持)
|
||
节点 N → 半径 × 1.5(放大)
|
||
节点 N 相连的边 → opacity 0.8(清晰)
|
||
其余边 → opacity 0.05(几乎隐藏)
|
||
|
||
点击空白区域:
|
||
全部节点恢复 opacity 0.9
|
||
全部边恢复 opacity 0.25
|
||
Detail Panel 收起
|
||
```
|
||
|
||
#### D3 力参数配置
|
||
|
||
| 参数 | 值 | 说明 |
|
||
|------|---|------|
|
||
| `forceLink distance` | 60 | 边长 |
|
||
| `forceLink strength` | 0.3 | 弹力 |
|
||
| `forceManyBody strength` | -120 | 节点斥力 |
|
||
| `forceCollide radius` | `d.r + 4` | 防重叠 |
|
||
| `alphaDecay` | 0.02 | 稳定速度 |
|
||
|
||
#### Tooltip 内容规范
|
||
|
||
鼠标悬停节点时,在鼠标右下方 8px 处显示:
|
||
|
||
```
|
||
┌─────────────────────────┐
|
||
│ GraphRAG [TECH] │
|
||
│ Page: 0 │
|
||
│ Confidence: match_exact │
|
||
│ Degree: 39 │
|
||
└─────────────────────────┘
|
||
```
|
||
|
||
### 4.3 多轮对话与推理链展示
|
||
|
||
#### 多轮 History 维护规则
|
||
|
||
```javascript
|
||
// 每次发送携带完整历史(前端维护)
|
||
const payload = {
|
||
question: inputText,
|
||
history: AppState.chatHistory.flatMap(msg => [
|
||
{ role: 'human', content: msg.question },
|
||
{ role: 'ai', content: msg.answer }
|
||
])
|
||
};
|
||
```
|
||
|
||
- 每次问答后将 QAResult 追加到 `AppState.chatHistory`
|
||
- 历史条数上限:20 轮(超出后丢弃最早的对话)
|
||
|
||
#### Tool Call 折叠面板展示规范
|
||
|
||
- 默认收起(▶ Tool Calls (N steps))
|
||
- 点击展开 → 逐步展示每个 tool step
|
||
- 样式:等宽字体,暗色背景(`--bg-s3`),黄色 tool 名称
|
||
- 输入(Input)/ 输出(Output)用分隔线区分
|
||
|
||
#### Suggested Prompts 展示逻辑
|
||
|
||
| 条件 | Prompts 显示 |
|
||
|------|-------------|
|
||
| KG 非空 + 无对话历史 | 展示 4 个预设问题 |
|
||
| KG 为空 | 提示"先上传文档构建 KG" |
|
||
| 已有对话历史 | 不显示 Prompts |
|
||
|
||
预设问题:
|
||
1. "Give me an overview of the knowledge graph"
|
||
2. "List all TECHNOLOGY entities"
|
||
3. "How does GraphRAG relate to knowledge graphs?"
|
||
4. "What is retrieval-augmented generation?"
|
||
|
||
### 4.4 跨页面联动导航
|
||
|
||
系统各页面通过 Hash 路由参数实现深度联动:
|
||
|
||
| 触发位置 | 触发动作 | 目标页面 | URL 参数 |
|
||
|---------|---------|---------|---------|
|
||
| Dashboard [KG] 按钮 | 点击 | KG Explorer | `#/graph?doc_id={doc_id}` |
|
||
| Dashboard [Explore KG] | 点击 | KG Explorer | `#/graph` |
|
||
| Dashboard [Demo] | 点击 | KG Explorer | 加载 demo → `#/graph` |
|
||
| Dashboard [Start Chat] | 点击 | QA Chat | `#/chat` |
|
||
| Documents [◉ View KG] | 点击 | KG Explorer | `#/graph?doc_id={doc_id}` |
|
||
| Chat Cited Node 标签 | 点击 | KG Explorer | `#/graph?node={node_id}` |
|
||
| KG Detail Panel [💬 Ask AI] | 点击 | QA Chat | `#/chat?q=Tell+me+about+{name}` |
|
||
| Search [View KG] | 点击 | KG Explorer | `#/graph?node={node_id}` |
|
||
| Search [Chat] | 点击 | QA Chat | `#/chat?q=What+is+{name}` |
|
||
| Header 全局搜索框 Enter | 提交 | Search | `#/search?q={input}` |
|
||
| Header 全局搜索框建议项 | 点击 | KG Explorer | `#/graph?node={node_id}` |
|
||
|
||
**URL 参数接收规则(KG Explorer):**
|
||
|
||
```javascript
|
||
// KG Explorer 初始化时解析
|
||
const params = new URLSearchParams(window.location.hash.split('?')[1]);
|
||
const docFilter = params.get('doc_id'); // 按文档筛选
|
||
const nodeHighlight = params.get('node'); // 聚焦并定位节点
|
||
|
||
if (docFilter) {
|
||
// 自动勾选 Filter Panel 中对应文档,其余节点淡化
|
||
}
|
||
if (nodeHighlight) {
|
||
// 找到节点 → 模拟点击(触发 Detail Panel)→ 平移居中 → 高亮
|
||
}
|
||
```
|
||
|
||
### 4.5 全局通知与反馈机制
|
||
|
||
#### Toast 通知系统
|
||
|
||
**位置:** 右上角 `position: fixed; top: 72px; right: 24px`
|
||
**宽度:** 320px
|
||
**堆叠规则:** 最多同时显示 3 条,从上向下排列,间距 8px
|
||
|
||
| 类型 | 背景 | 左边框 | 图标 | 使用场景 |
|
||
|------|------|-------|------|---------|
|
||
| Success | `#1a3a22` | 3px `#3fb950` | ✓ | 索引完成、删除成功 |
|
||
| Warning | `#2d2a16` | 3px `#d29922` | ! | 请求超时、格式警告 |
|
||
| Error | `#3b1a1a` | 3px `#f85149` | ✗ | 上传失败、网络错误 |
|
||
| Info | `#161f2e` | 3px `#58a6ff` | i | 操作提示、加载状态 |
|
||
|
||
**生命周期:**
|
||
- 出现:从右侧 slide-in(200ms ease-out)
|
||
- 停留:4000ms(hover 时暂停计时器)
|
||
- 消失:fade-out(300ms)→ 从 DOM 移除
|
||
|
||
#### Loading 状态层级
|
||
|
||
| 层级 | 样式 | 触发场景 |
|
||
|------|------|---------|
|
||
| Header 进度条 | 2px 高,顶部蓝色横条 | 所有 API 请求期间 |
|
||
| Skeleton Loader | 灰色矩形 shimmer 动画 | 列表首次加载 |
|
||
| 图谱 Loading | SVG 中央文字 + 三点动画 | KG 数据加载 |
|
||
| Chat Thinking | 三点跳动动画(气泡内) | 等待 QA 响应 |
|
||
|
||
#### 空状态引导设计
|
||
|
||
| 页面 | 空状态触发条件 | 引导内容 |
|
||
|------|--------------|---------|
|
||
| KG Explorer | KG 无节点数据 | 图标 + "No knowledge graph yet" + [Upload & Index →] |
|
||
| Chat | 无历史对话 | 欢迎语 + Suggested Prompts(4 个) |
|
||
| Search | 搜索结果为空 | "No entities found for '{query}'" + [Explore KG] |
|
||
| Documents | 无文档记录 | 上传区更突出,拖拽提示放大 |
|
||
|
||
---
|
||
|
||
## 五、UI 设计规范
|
||
|
||
### 5.1 整体布局结构
|
||
|
||
系统采用 CSS Grid 四区布局,高度占满视口(`height: 100vh`):
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────────┐
|
||
│ HEADER 56px (sticky, z-index: 100) │
|
||
├──────────────┬───────────────────────────────────────────────────┤
|
||
│ │ │
|
||
│ SIDEBAR │ MAIN CONTENT AREA │
|
||
│ 220px │ (overflow-y: auto, padding: 24px) │
|
||
│ (fixed) │ │
|
||
│ │ KG Explorer 例外:padding: 0,内部自行布局 │
|
||
│ │ │
|
||
├──────────────┴───────────────────────────────────────────────────┤
|
||
│ STATUS BAR 32px │
|
||
└──────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**CSS Grid 骨架代码:**
|
||
|
||
```css
|
||
.app {
|
||
display: grid;
|
||
grid-template-areas: "header header" "sidebar main" "footer footer";
|
||
grid-template-columns: var(--sidebar-w, 220px) 1fr;
|
||
grid-template-rows: 56px 1fr 32px;
|
||
height: 100vh;
|
||
overflow: hidden;
|
||
}
|
||
```
|
||
|
||
**KG Explorer 三栏内部布局:**
|
||
|
||
```
|
||
┌─────────────┬────────────────────────────────────┬─────────────┐
|
||
│ Filter Panel│ D3 Graph(flex: 1) │ Detail Panel│
|
||
│ 280px │ │ 300px │
|
||
│ │ 全屏 SVG,支持缩放/拖拽/pin │ 点击节点后 │
|
||
│ │ │ 滑入出现 │
|
||
└─────────────┴────────────────────────────────────┴─────────────┘
|
||
```
|
||
|
||
**Chat 双栏内部布局:**
|
||
|
||
```
|
||
┌──────────────┬──────────────────────────────────────────────────┐
|
||
│ History │ Chat Area │
|
||
│ 240px │ (display: flex; flex-direction: column) │
|
||
│ │ 消息列表(flex: 1, overflow-y: auto) │
|
||
│ │ 输入区(固定底部) │
|
||
└──────────────┴──────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 5.2 配色系统
|
||
|
||
采用 GitHub 深色主题(Dark)配色体系,在现有 `index.html` 调色板基础上扩展:
|
||
|
||
#### 背景层级
|
||
|
||
| 变量 | 色值 | 用途 |
|
||
|------|------|------|
|
||
| `--bg-base` | `#0f1117` | 页面底色(body background) |
|
||
| `--bg-s1` | `#161b22` | 主要表面(sidebar / header / card) |
|
||
| `--bg-s2` | `#21262d` | 次级表面(hover 态 / input / tag) |
|
||
| `--bg-s3` | `#1c2128` | 浮层表面(tooltip / popover / 代码块) |
|
||
|
||
#### 边框
|
||
|
||
| 变量 | 色值 | 用途 |
|
||
|------|------|------|
|
||
| `--border` | `#30363d` | 主边框 |
|
||
| `--border-muted` | `#21262d` | 次级分隔线 |
|
||
|
||
#### 文字层级
|
||
|
||
| 变量 | 色值 | 用途 |
|
||
|------|------|------|
|
||
| `--text-1` | `#f0f6fc` | 主标题、强调文字 |
|
||
| `--text-2` | `#c9d1d9` | 正文内容 |
|
||
| `--text-3` | `#8b949e` | 辅助信息、Label |
|
||
| `--text-4` | `#484f58` | Placeholder、极弱文字 |
|
||
|
||
#### 功能色
|
||
|
||
| 变量 | 色值 | 用途 |
|
||
|------|------|------|
|
||
| `--blue` | `#58a6ff` | 链接 / 激活态 / 聚焦 / 进度条 |
|
||
| `--green` | `#3fb950` | 成功状态 / indexed |
|
||
| `--green-btn` | `#238636` | 主操作按钮背景 |
|
||
| `--green-hover` | `#2ea043` | 主操作按钮 hover |
|
||
| `--red` | `#f85149` | 错误 / 危险操作 / failed |
|
||
| `--yellow` | `#d29922` | 警告 / indexing 进行中 |
|
||
| `--purple` | `#8957e5` | 边数指标 / 特殊强调 |
|
||
|
||
#### 实体类型颜色(与 D3 图谱一致)
|
||
|
||
| 实体类型 | 颜色变量 | 色值 | 节点颜色 |
|
||
|---------|---------|------|---------|
|
||
| TECHNOLOGY | `--type-tech` | `#58a6ff` | 蓝色 |
|
||
| CONCEPT | `--type-concept` | `#bc8cff` | 紫色 |
|
||
| PERSON | `--type-person` | `#3fb950` | 绿色 |
|
||
| ORGANIZATION | `--type-org` | `#ff7b72` | 红色 |
|
||
| LOCATION | `--type-loc` | `#ffa657` | 橙色 |
|
||
|
||
#### 状态 Badge 配色
|
||
|
||
| 状态 | 背景 | 文字 |
|
||
|------|------|------|
|
||
| indexed | `#1a3a22` | `#3fb950` |
|
||
| indexing | `#2d2a16` | `#d29922` |
|
||
| uploaded | `#1c2128` | `#8b949e` |
|
||
| failed | `#3b1a1a` | `#f85149` |
|
||
|
||
### 5.3 字体与排版
|
||
|
||
**字体族:**
|
||
|
||
```css
|
||
--font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
--font-mono: 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
|
||
```
|
||
|
||
**字体层级规范:**
|
||
|
||
| 层级 | 大小 | 粗细 | 颜色 | 用途 |
|
||
|------|------|------|------|------|
|
||
| H1(页面标题) | 20px | 600 | `--text-1` | 页面大标题 |
|
||
| H2(区块标题) | 16px | 600 | `--text-1` | 区块标题 |
|
||
| H3(面板子标题) | 13px | 600 uppercase | `--text-3` | 面板分类标题(字母间距 0.5px) |
|
||
| Body(正文) | 14px | 400 | `--text-2` | 列表内容、说明文字 |
|
||
| Small(辅助) | 12px | 400 | `--text-3` | 日期、辅助信息、Tooltip |
|
||
| Badge(标签) | 11px | 600 | — | 状态标记、类型标签 |
|
||
| Mono(代码) | 13px | 400 | `--text-2` | Tool Call 输入输出、文件路径 |
|
||
|
||
**行间距:** 正文 `1.6`,代码块 `1.5`
|
||
|
||
### 5.4 组件样式规范
|
||
|
||
#### 按钮(4 种变体)
|
||
|
||
| 变体 | class | 背景 | 边框 | 文字颜色 | 用途 |
|
||
|------|-------|------|------|---------|------|
|
||
| Primary | `.btn-primary` | `--green-btn` | `--green-btn` | `#ffffff` | 主操作(Upload / Send / Index) |
|
||
| Secondary | `.btn-secondary` | `--bg-s2` | `--border` | `--text-2` | 次要操作(Cancel / Filter) |
|
||
| Ghost | `.btn-ghost` | transparent | none | `--text-3` | 图标按钮(内联操作) |
|
||
| Danger | `.btn-danger` | `--bg-s2` | `--border` | `--red` | 危险操作(Delete) |
|
||
|
||
```css
|
||
.btn {
|
||
padding: 6px 14px;
|
||
border-radius: 6px; /* --r-md */
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: all 150ms ease;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
border: 1px solid transparent;
|
||
}
|
||
.btn-sm { padding: 4px 10px; font-size: 12px; }
|
||
```
|
||
|
||
#### 卡片(Card)
|
||
|
||
```css
|
||
.card {
|
||
background: var(--bg-s1);
|
||
border: 1px solid var(--border);
|
||
border-radius: 8px; /* --r-lg */
|
||
padding: 16px;
|
||
}
|
||
```
|
||
|
||
#### 输入框(Input)
|
||
|
||
```css
|
||
.input {
|
||
background: var(--bg-s2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 6px;
|
||
color: var(--text-1);
|
||
padding: 8px 12px;
|
||
font-size: 14px;
|
||
width: 100%;
|
||
transition: border-color 150ms ease;
|
||
}
|
||
.input:focus {
|
||
outline: none;
|
||
border-color: var(--blue);
|
||
box-shadow: 0 0 0 3px rgba(88,166,255,0.15);
|
||
}
|
||
```
|
||
|
||
#### 进度条
|
||
|
||
```css
|
||
.progress-bar {
|
||
height: 4px;
|
||
background: var(--bg-s2);
|
||
border-radius: 2px;
|
||
overflow: hidden;
|
||
}
|
||
.progress-fill {
|
||
height: 100%;
|
||
background: var(--blue);
|
||
border-radius: 2px;
|
||
transition: width 300ms ease;
|
||
}
|
||
```
|
||
|
||
#### Modal(确认弹窗)
|
||
|
||
```css
|
||
.modal-overlay {
|
||
position: fixed; inset: 0;
|
||
background: rgba(0,0,0,0.6);
|
||
z-index: 1000;
|
||
display: flex; align-items: center; justify-content: center;
|
||
}
|
||
.modal {
|
||
background: var(--bg-s1);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px; /* --r-xl */
|
||
padding: 24px;
|
||
width: 360px;
|
||
box-shadow: 0 8px 32px rgba(0,0,0,0.6);
|
||
}
|
||
```
|
||
|
||
#### Skeleton Loader(骨架屏)
|
||
|
||
```css
|
||
.skeleton {
|
||
background: linear-gradient(90deg, var(--bg-s2) 25%, var(--bg-s1) 50%, var(--bg-s2) 75%);
|
||
background-size: 200% 100%;
|
||
animation: shimmer 1.5s infinite;
|
||
border-radius: 4px;
|
||
}
|
||
@keyframes shimmer {
|
||
0% { background-position: 200% 0; }
|
||
100% { background-position: -200% 0; }
|
||
}
|
||
```
|
||
|
||
#### 阴影规范
|
||
|
||
```css
|
||
--shadow-sm: 0 1px 3px rgba(0,0,0,0.4); /* card 轻阴影 */
|
||
--shadow-md: 0 4px 16px rgba(0,0,0,0.5); /* dropdown / tooltip */
|
||
--shadow-lg: 0 8px 32px rgba(0,0,0,0.6); /* modal / drawer */
|
||
```
|
||
|
||
#### 圆角规范
|
||
|
||
```css
|
||
--r-sm: 4px; /* badge / tag / 小按钮 */
|
||
--r-md: 6px; /* 按钮 / 输入框 / 小卡片 */
|
||
--r-lg: 8px; /* 卡片 / 面板 */
|
||
--r-xl: 12px; /* Modal / 大弹窗 */
|
||
```
|
||
|
||
### 5.5 响应式断点规范
|
||
|
||
系统支持 4 个断点,覆盖从 4K 显示器到移动端的使用场景:
|
||
|
||
| 断点 | 宽度范围 | 目标设备 |
|
||
|------|---------|---------|
|
||
| Desktop | > 1280px | 台式机、宽屏笔记本 |
|
||
| Laptop | 1024 ~ 1280px | 普通 13/14 寸笔记本 |
|
||
| Tablet | 768 ~ 1024px | iPad、竖屏笔记本 |
|
||
| Mobile | < 768px | 手机 |
|
||
|
||
#### 各断点布局变化
|
||
|
||
**Desktop(> 1280px):**
|
||
- 完整三列布局(Sidebar 220px + Main + Detail Panel)
|
||
- 所有功能面板默认展开
|
||
|
||
**Laptop(1024 ~ 1280px):**
|
||
- Sidebar 折叠为图标模式(72px),仅显示图标
|
||
- 导航文字 Label、Badge、Logo 文字隐藏
|
||
- 内容区相应扩展
|
||
|
||
**Tablet(768 ~ 1024px):**
|
||
- Sidebar 完全隐藏(`grid-template-columns: 0 1fr`)
|
||
- 汉堡菜单按钮(`[≡]`)展开/收起 Sidebar Drawer
|
||
- Drawer 覆盖内容区(`position: fixed; z-index: 500`)+ 半透明遮罩
|
||
- KG Explorer:Filter Panel → 浮动侧边 Drawer(FAB 触发)
|
||
- Chat:History Sidebar → 顶部 Drawer
|
||
|
||
**Mobile(< 768px):**
|
||
- 底部 Tab Bar 替代左侧 Sidebar(高度 56px,5 个图标导航)
|
||
- Header 精简(隐藏全局搜索框,仅保留 Logo + 健康状态)
|
||
- Dashboard 指标卡:4 列 → 2 列网格
|
||
- Documents 列表:表格 → 卡片堆叠(隐藏 Pages、Date 列)
|
||
- KG Explorer:三栏 → 图谱全屏,Detail Panel → 底部 Sheet(滑入,高度 60vh)
|
||
- Search:左右双栏 → 上下堆叠(Preview Graph 缩小到 200px)
|
||
|
||
#### CSS 媒体查询关键规则
|
||
|
||
```css
|
||
/* Laptop */
|
||
@media (max-width: 1280px) {
|
||
.app { --sidebar-w: 72px; }
|
||
.nav-label, .nav-badge, .sidebar-logo-text { display: none; }
|
||
}
|
||
|
||
/* Tablet */
|
||
@media (max-width: 1024px) {
|
||
.app { grid-template-columns: 0 1fr; }
|
||
.sidebar {
|
||
position: fixed; left: 0; top: 0; bottom: 0;
|
||
width: 220px; z-index: 500;
|
||
transform: translateX(-220px);
|
||
transition: transform 0.2s ease;
|
||
}
|
||
.sidebar.open { transform: translateX(0); }
|
||
}
|
||
|
||
/* Mobile */
|
||
@media (max-width: 768px) {
|
||
.app { grid-template-rows: 56px 1fr 56px; }
|
||
.sidebar { display: none; }
|
||
.bottom-nav { display: flex; }
|
||
.metrics-grid { grid-template-columns: repeat(2, 1fr); }
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 六、后端接口依赖
|
||
|
||
GraphRAG Studio 前端依赖以下 25 个 FastAPI 后端接口,服务地址 `http://localhost:8000/api/v1`,统一响应格式 `{code, msg, request_id, data}`:
|
||
|
||
### A 组:文档管理
|
||
|
||
| 接口 | 方法 | 路径 | 触发页面 |
|
||
|------|------|------|---------|
|
||
| 上传文档 | POST | `/documents/upload` | Dashboard Modal, Documents |
|
||
| 文档详情 | GET | `/documents/{doc_id}` | Documents |
|
||
| 文档列表 | GET | `/documents` | Dashboard(最近5条),Documents(全部) |
|
||
| 删除文档 | DELETE | `/documents/{doc_id}` | Documents |
|
||
|
||
### B 组:Indexing Pipeline
|
||
|
||
| 接口 | 方法 | 路径 | 触发页面 |
|
||
|------|------|------|---------|
|
||
| 启动索引 | POST | `/index/start` | Dashboard, Documents |
|
||
| 查询任务状态 | GET | `/index/status/{job_id}` | Dashboard(轮询),Documents(轮询) |
|
||
| 获取索引结果 | GET | `/index/result/{job_id}` | Documents(完成后) |
|
||
| 取消任务 | DELETE | `/index/jobs/{job_id}` | Dashboard, Documents |
|
||
|
||
### C 组:知识图谱
|
||
|
||
| 接口 | 方法 | 路径 | 触发页面 |
|
||
|------|------|------|---------|
|
||
| 节点列表 | GET | `/kg/nodes` | KG Explorer(初始化) |
|
||
| 边列表 | GET | `/kg/edges` | KG Explorer(初始化) |
|
||
| 节点详情 | GET | `/kg/nodes/{node_id}` | KG Explorer(点击),Chat(hover),Search |
|
||
| 节点邻居 | GET | `/kg/nodes/{node_id}/neighbors` | KG Explorer(Detail Panel),Search(Preview) |
|
||
| 图谱统计 | GET | `/kg/stats` | KG Explorer |
|
||
| 导出图谱 | GET | `/kg/export` | KG Explorer(工具栏) |
|
||
|
||
### D 组:QA 问答
|
||
|
||
| 接口 | 方法 | 路径 | 触发页面 |
|
||
|------|------|------|---------|
|
||
| 同步问答 | POST | `/query` | Chat(发送消息) |
|
||
| 批量问答 | POST | `/query/batch` | — |
|
||
| 批量状态 | GET | `/query/batch/{batch_id}` | — |
|
||
| 历史查询 | GET | `/query/history` | Chat(历史列表) |
|
||
|
||
### E 组:搜索
|
||
|
||
| 接口 | 方法 | 路径 | 触发页面 |
|
||
|------|------|------|---------|
|
||
| 实体搜索 | GET | `/search/entities` | Header(全局搜索),KG Explorer(工具栏),Search Tab1 |
|
||
| 路径搜索 | GET | `/search/path` | Search Tab2 |
|
||
| 子图搜索 | GET | `/search/graph` | Search Tab3 |
|
||
|
||
### F 组:系统
|
||
|
||
| 接口 | 方法 | 路径 | 触发页面 |
|
||
|------|------|------|---------|
|
||
| 健康检查 | GET | `/health` | Dashboard(Health 面板),Header(健康状态) |
|
||
| 系统统计 | GET | `/system/stats` | Dashboard(指标卡) |
|
||
| 支持格式 | GET | `/system/formats` | Documents(格式说明) |
|
||
| Demo 数据 | GET | `/system/demo` | Dashboard(Demo 按钮) |
|
||
|
||
### 错误码处理规范
|
||
|
||
| code | 含义 | 前端处理 |
|
||
|------|------|---------|
|
||
| 0 | 成功 | 正常渲染数据 |
|
||
| 1001 | 参数校验失败 | 行内表单错误提示 |
|
||
| 1002 | 文件格式不支持 | 文件名标红 + 行内说明 |
|
||
| 1003 | 文件超过大小限制 | 同上 |
|
||
| 1004 | 文件不存在 | Toast.error |
|
||
| 2001 | Job 不存在 | Toast.error + 刷新列表 |
|
||
| 2002 | Job 仍在运行 | Toast.warning(防重复启动) |
|
||
| 2003 | Job 已完成 | Toast.info |
|
||
| 2004 | Job 取消失败 | Toast.error |
|
||
| 3001 | 节点不存在 | Toast.error |
|
||
| 3002 | KG 为空 | 页面空状态引导(不弹 Toast) |
|
||
| 4001 | QA 执行失败 | Toast.error + 输入框恢复 |
|
||
| 5000 | 服务器内部错误 | Toast.error("Server error") |
|
||
|
||
---
|
||
|
||
## 七、非功能性需求
|
||
|
||
### 7.1 性能要求
|
||
|
||
| 指标 | 要求 |
|
||
|------|------|
|
||
| 页面切换(SPA 路由) | < 100ms |
|
||
| D3 图谱初始渲染(40 节点,780 边) | < 500ms |
|
||
| API 请求超时设置 | 普通接口 30s,QA 接口 60s |
|
||
| KG 节点轮询最小间隔 | 3s |
|
||
| Dashboard 刷新间隔 | 10s |
|
||
| 全局搜索建议 debounce | 300ms |
|
||
| D3 图谱性能阈值 | ≤ 500 节点使用 SVG;> 500 节点切换 Canvas 渲染 |
|
||
|
||
### 7.2 兼容性要求
|
||
|
||
| 维度 | 要求 |
|
||
|------|------|
|
||
| 浏览器 | Chrome 90+ / Edge 90+ / Firefox 88+ / Safari 14+ |
|
||
| 屏幕分辨率 | 最低 1024×768,推荐 1440×900 以上 |
|
||
| 屏幕像素比 | 支持 1x / 2x(Retina) |
|
||
| JavaScript | 无构建工具,原生 ES2020+(使用 CDN) |
|
||
|
||
### 7.3 可访问性(Accessibility)
|
||
|
||
- 所有交互元素支持键盘导航(Tab / Enter / Esc)
|
||
- 图标按钮提供 `aria-label` 说明
|
||
- 颜色对比度符合 WCAG 2.1 AA 标准(文字:≥ 4.5:1)
|
||
- Toast 通知区域添加 `aria-live="polite"`
|
||
|
||
### 7.4 安全性
|
||
|
||
- API 请求不包含敏感数据(API Key 存于后端 `.env`,不暴露至前端)
|
||
- 上传文件客户端预校验格式与大小(后端二次校验)
|
||
- XSS 防护:Chat 页 AI 答案通过 marked.js 的 sanitize 选项过滤
|
||
|
||
---
|
||
|
||
## 八、验收标准
|
||
|
||
### 8.1 功能验收
|
||
|
||
| 编号 | 验收项 | 验收标准 |
|
||
|------|-------|---------|
|
||
| F-01 | 文件上传 | 支持 9 种格式,200MB 以内;拖拽和点击均可触发;校验失败行内提示 |
|
||
| F-02 | 索引任务 | 启动后每 3s 更新进度;stage 文字正确反映当前阶段;完成后展示结果摘要 |
|
||
| F-03 | 任务取消 | 点击 [✕] 确认后任务终止,状态回退到 uploaded |
|
||
| F-04 | KG 图谱渲染 | 节点颜色、大小按规则渲染;边透明度 0.25;力模拟稳定 |
|
||
| F-05 | 节点高亮 | 点击节点后非焦点节点 opacity 变 0.1,相连边 opacity 0.8 |
|
||
| F-06 | Detail Panel | 点击节点后出现,显示属性+邻居;点击空白处收起 |
|
||
| F-07 | QA 问答 | 发送问题后 thinking 动画出现;响应后 Markdown 渲染正确 |
|
||
| F-08 | Tool Call 展示 | 默认收起;展开后每步 tool name / input / output 完整显示 |
|
||
| F-09 | Cited Nodes | 显示为可点击标签;点击跳转 `#/graph?node=xxx` |
|
||
| F-10 | 实体搜索 | 输入关键词后返回结果;点击结果行渲染 Preview Graph |
|
||
| F-11 | 路径搜索 | 选择两个节点后返回路径;路径可视化正确 |
|
||
| F-12 | 跨页联动 | 所有 11 条跨页导航路径携带正确 URL 参数且被接收页正确处理 |
|
||
| F-13 | Toast 通知 | 4 种类型正确显示;4s 后自动消失;最多同时显示 3 条 |
|
||
| F-14 | 空状态引导 | KG 无数据时显示引导 UI;文档列表为空时上传区突出 |
|
||
| F-15 | 响应式布局 | 在 1024px 以上显示完整布局;768px 以下切换底部 Tab Bar |
|
||
|
||
### 8.2 性能验收
|
||
|
||
- 页面切换动画流畅(60fps)
|
||
- D3 图谱 40 节点 + 780 边在 500ms 内完成初始渲染
|
||
- 轮询机制不导致内存泄漏(离开页面时清除所有 timer)
|
||
|
||
### 8.3 API 覆盖验收
|
||
|
||
所有 25 个后端 API 端点在前端代码中均有明确的调用时机,且均通过 `api.js` 封装层调用,错误统一由 `APIError` 捕获处理。
|
||
|
||
---
|
||
|
||
## 附录
|
||
|
||
### A. 技术栈汇总
|
||
|
||
| 层次 | 技术 | 版本 | 引入方式 |
|
||
|------|------|------|---------|
|
||
| 前端框架 | 原生 HTML/CSS/JS | ES2020+ | — |
|
||
| 图形渲染 | D3.js | v7 | CDN |
|
||
| Markdown 渲染 | marked.js | v9 | CDN |
|
||
| 后端框架 | FastAPI | 0.104+ | Python venv |
|
||
| ASGI 服务器 | Uvicorn | 0.24+ | Python venv |
|
||
| PDF 解析 | MinerU | 最新稳定版 | subprocess |
|
||
| 实体抽取 | LangExtract + DeepSeek | — | Direct import |
|
||
| 知识问答 | LangChain + DeepSeek | 0.2+ | Direct import |
|
||
| 图计算 | NetworkX | 3.x | Python venv |
|
||
|
||
### B. 文件交付清单
|
||
|
||
| 类型 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| 规范文档 | `docs/backend_service_specification-v1.0.md` | FastAPI 后端 25 个接口规范 |
|
||
| 规范文档 | `docs/frontend_design_specification-v1.0.md` | 前端 SPA 设计规范(5 页面) |
|
||
| 规范文档 | `docs/product_requirements_document-v1.0.md` | 本文档(产品需求文档) |
|
||
| 前端入口 | `graphrag_pipeline/static/app/index.html` | SPA 主入口(待实现) |
|
||
| 前端样式 | `graphrag_pipeline/static/app/css/` | 3 个 CSS 文件(待实现) |
|
||
| 前端逻辑 | `graphrag_pipeline/static/app/js/` | 7 个 JS 文件(待实现) |
|
||
| 后端服务 | `graphrag_pipeline/api_server.py` | FastAPI 主入口(待实现) |
|
||
|
||
### C. 词汇表
|
||
|
||
| 术语 | 说明 |
|
||
|------|------|
|
||
| GraphRAG | 知识图谱增强的 RAG(检索增强生成)系统 |
|
||
| KG | Knowledge Graph,知识图谱 |
|
||
| Entity | 实体,知识图谱中的节点,包含名称、类型、页码、置信度等属性 |
|
||
| Relation | 关系,知识图谱中的边,当前版本固定为 `CO_OCCURS_IN`(共现关系) |
|
||
| MinerU | 文档解析工具,将 PDF/DOCX 等格式解析为结构化文本 |
|
||
| LangExtract | 基于 LLM 的实体抽取框架 |
|
||
| Agentic-RAG | 基于 ReAct 框架的智能问答,LLM 通过多步工具调用推理 |
|
||
| ReAct | Reasoning + Acting,推理与行动交替的 Agent 模式 |
|
||
| Job | 索引任务,一个文档的完整 parsing → extracting → indexing 流程 |
|
||
| SPA | Single Page Application,单页应用 |
|
||
| Hash 路由 | 通过 URL 的 `#` 部分控制页面切换,无需服务端路由 |
|
||
| Cited Nodes | QA 答案中引用的知识图谱节点,可点击跳转至图谱 |
|
||
| Tool Call | Agentic-RAG 中 LLM 调用的工具函数(如 search_entities) |
|