Files
GraphRAGAgent/docs/flow.drawio

418 lines
24 KiB
Plaintext
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.

<mxGraphModel>
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<!-- Title -->
<mxCell id="title" value="GraphRAG Studio — 核心业务流程图" style="text;fontSize=20;fontStyle=1;fillColor=none;strokeColor=none;fontColor=#f0f6fc;align=center;" vertex="1" parent="1">
<mxGeometry x="250" y="5" width="350" height="30" as="geometry"/>
</mxCell>
<!-- ===================================================================== -->
<!-- FLOW 1: 文件上传与索引构建 -->
<!-- ===================================================================== -->
<mxCell id="f1-bg" value="" style="rounded=1;fillColor=#0d1117;strokeColor=#58a6ff;strokeWidth=1;dashed=1;opacity=40;" vertex="1" parent="1">
<mxGeometry x="10" y="40" width="930" height="195" as="geometry"/>
</mxCell>
<mxCell id="f1-label" value="流程一:文件上传与知识图谱构建 (Indexing Pipeline)" style="text;fontSize=13;fontStyle=1;fillColor=none;strokeColor=none;fontColor=#58a6ff;align=left;" vertex="1" parent="1">
<mxGeometry x="20" y="43" width="400" height="20" as="geometry"/>
</mxCell>
<!-- Row 1: Upload steps -->
<mxCell id="f1-start" value="📁 拖拽/选择文件" style="rounded=1;fillColor=#0d2137;strokeColor=#58a6ff;fontColor=#f0f6fc;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="25" y="72" width="110" height="34" as="geometry"/>
</mxCell>
<mxCell id="f1-a1" style="endArrow=classic;strokeColor=#58a6ff;strokeWidth=1.5;exitX=1;exitY=0.5;entryX=0;entryY=0.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="135" y="89" as="sourcePoint"/>
<mxPoint x="155" y="89" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f1-validate" value="客户端校验&#xa;(格式+大小)" style="rounded=1;fillColor=#0d2137;strokeColor=#58a6ff;fontColor=#c9d1d9;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="158" y="72" width="110" height="34" as="geometry"/>
</mxCell>
<mxCell id="f1-a2" style="endArrow=classic;strokeColor=#58a6ff;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="268" y="89" as="sourcePoint"/>
<mxPoint x="288" y="89" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f1-upload" value="POST /upload&#xa;保存至 uploads/" style="rounded=1;fillColor=#0d2137;strokeColor=#58a6ff;fontColor=#c9d1d9;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="291" y="72" width="110" height="34" as="geometry"/>
</mxCell>
<mxCell id="f1-a3" style="endArrow=classic;strokeColor=#58a6ff;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="401" y="89" as="sourcePoint"/>
<mxPoint x="421" y="89" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f1-confirm" value="用户确认索引" style="rounded=1;fillColor=#0d2137;strokeColor=#58a6ff;fontColor=#c9d1d9;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="424" y="72" width="110" height="34" as="geometry"/>
</mxCell>
<mxCell id="f1-a4" style="endArrow=classic;strokeColor=#58a6ff;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="534" y="89" as="sourcePoint"/>
<mxPoint x="554" y="89" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f1-startjob" value="POST /index/start&#xa;启动后台线程" style="rounded=1;fillColor=#0d2137;strokeColor=#58a6ff;fontColor=#c9d1d9;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="557" y="72" width="110" height="34" as="geometry"/>
</mxCell>
<!-- Arrow down to pipeline -->
<mxCell id="f1-down" style="endArrow=classic;strokeColor=#58a6ff;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="612" y="106" as="sourcePoint"/>
<mxPoint x="612" y="128" as="targetPoint"/>
</mxGeometry>
</mxCell>
<!-- Row 2: Pipeline stages (3 stages) -->
<mxCell id="f1-stage1" value="Stage 1: MinerU 解析&#xa;PDF → content_list.json&#xa;(subprocess 调用)" style="rounded=1;fillColor=#1a2332;strokeColor=#ffa657;fontColor=#ffa657;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="25" y="135" width="170" height="50" as="geometry"/>
</mxCell>
<mxCell id="f1-pa1" style="endArrow=classic;strokeColor=#ffa657;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="195" y="160" as="sourcePoint"/>
<mxPoint x="225" y="160" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f1-stage2" value="Stage 2: LangExtract + DeepSeek&#xa;page → 实体抽取&#xa;(每页调用 LLM)" style="rounded=1;fillColor=#1a2332;strokeColor=#bc8cff;fontColor=#bc8cff;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="228" y="135" width="180" height="50" as="geometry"/>
</mxCell>
<mxCell id="f1-pa2" style="endArrow=classic;strokeColor=#bc8cff;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="408" y="160" as="sourcePoint"/>
<mxPoint x="438" y="160" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f1-stage3" value="Stage 3: kg_builder&#xa;实体去重 + CO_OCCURS_IN 建边&#xa;→ kg_nodes.json + kg_edges.json" style="rounded=1;fillColor=#1a2332;strokeColor=#3fb950;fontColor=#3fb950;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="441" y="135" width="195" height="50" as="geometry"/>
</mxCell>
<mxCell id="f1-pa3" style="endArrow=classic;strokeColor=#3fb950;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="636" y="160" as="sourcePoint"/>
<mxPoint x="666" y="160" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f1-merge" value="合并全局 KG&#xa;merge_kg()" style="rounded=1;fillColor=#1a2332;strokeColor=#3fb950;fontColor=#3fb950;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="669" y="135" width="120" height="50" as="geometry"/>
</mxCell>
<!-- Decision: result -->
<mxCell id="f1-decision" value="结果?" style="rhombus;fillColor=#1a2332;strokeColor=#d29922;fontColor=#d29922;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="809" y="133" width="60" height="54" as="geometry"/>
</mxCell>
<mxCell id="f1-pa4" style="endArrow=classic;strokeColor=#3fb950;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="789" y="160" as="sourcePoint"/>
<mxPoint x="809" y="160" as="targetPoint"/>
</mxGeometry>
</mxCell>
<!-- Success path -->
<mxCell id="f1-success" value="✅ done&#xa;status→indexed" style="rounded=1;fillColor=#1a3a22;strokeColor=#3fb950;fontColor=#3fb950;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="890" y="108" width="105" height="34" as="geometry"/>
</mxCell>
<mxCell id="f1-pa5" style="endArrow=classic;strokeColor=#3fb950;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="839" y="140" as="sourcePoint"/>
<mxPoint x="887" y="125" as="targetPoint"/>
</mxGeometry>
</mxCell>
<!-- Fail path -->
<mxCell id="f1-fail" value="❌ failed&#xa;显示错误+重试" style="rounded=1;fillColor=#3b1a1a;strokeColor=#f85149;fontColor=#f85149;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="890" y="160" width="105" height="34" as="geometry"/>
</mxCell>
<mxCell id="f1-pa6" style="endArrow=classic;strokeColor=#f85149;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="839" y="180" as="sourcePoint"/>
<mxPoint x="887" y="177" as="targetPoint"/>
</mxGeometry>
</mxCell>
<!-- Polling note -->
<mxCell id="f1-poll" value="⏱ 前端每3s轮询 GET /index/status/{job_id}" style="text;fontSize=9;fillColor=none;strokeColor=none;fontColor=#8b949e;align=left;" vertex="1" parent="1">
<mxGeometry x="25" y="195" width="280" height="14" as="geometry"/>
</mxCell>
<mxCell id="f1-cancel" value="✕ 支持取消: DELETE /index/jobs/{job_id}" style="text;fontSize=9;fillColor=none;strokeColor=none;fontColor=#8b949e;align=left;" vertex="1" parent="1">
<mxGeometry x="310" y="195" width="260" height="14" as="geometry"/>
</mxCell>
<mxCell id="f1-note" value="后台线程执行,支持 cancel flag 中断" style="text;fontSize=9;fillColor=none;strokeColor=none;fontColor=#8b949e;align=left;" vertex="1" parent="1">
<mxGeometry x="580" y="195" width="250" height="14" as="geometry"/>
</mxCell>
<!-- ===================================================================== -->
<!-- FLOW 2: Agentic-RAG 智能问答 -->
<!-- ===================================================================== -->
<mxCell id="f2-bg" value="" style="rounded=1;fillColor=#0d1117;strokeColor=#3fb950;strokeWidth=1;dashed=1;opacity=40;" vertex="1" parent="1">
<mxGeometry x="10" y="245" width="930" height="200" as="geometry"/>
</mxCell>
<mxCell id="f2-label" value="流程二Agentic-RAG 智能问答 (ReAct Agent)" style="text;fontSize=13;fontStyle=1;fillColor=none;strokeColor=none;fontColor=#3fb950;align=left;" vertex="1" parent="1">
<mxGeometry x="20" y="248" width="400" height="20" as="geometry"/>
</mxCell>
<!-- Row 1: Input -->
<mxCell id="f2-q" value="💬 用户输入问题&#xa;(+ 对话历史)" style="rounded=1;fillColor=#0d3320;strokeColor=#3fb950;fontColor=#f0f6fc;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="25" y="278" width="125" height="38" as="geometry"/>
</mxCell>
<mxCell id="f2-a1" style="endArrow=classic;strokeColor=#3fb950;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="150" y="297" as="sourcePoint"/>
<mxPoint x="175" y="297" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f2-post" value="POST /api/v1/query&#xa;{question, history}" style="rounded=1;fillColor=#0d3320;strokeColor=#3fb950;fontColor=#c9d1d9;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="178" y="278" width="135" height="38" as="geometry"/>
</mxCell>
<mxCell id="f2-a2" style="endArrow=classic;strokeColor=#3fb950;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="313" y="297" as="sourcePoint"/>
<mxPoint x="338" y="297" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f2-build" value="加载全局 KG&#xa;→ NetworkX Graph" style="rounded=1;fillColor=#0d3320;strokeColor=#3fb950;fontColor=#c9d1d9;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="341" y="278" width="130" height="38" as="geometry"/>
</mxCell>
<mxCell id="f2-a3" style="endArrow=classic;strokeColor=#3fb950;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="471" y="297" as="sourcePoint"/>
<mxPoint x="496" y="297" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f2-agent" value="创建 ReAct Agent&#xa;ChatOpenAI(deepseek-chat)&#xa;+ 4 个 @tool" style="rounded=1;fillColor=#0d3320;strokeColor=#3fb950;fontColor=#c9d1d9;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="499" y="278" width="145" height="38" as="geometry"/>
</mxCell>
<!-- Arrow down to ReAct loop -->
<mxCell id="f2-down" style="endArrow=classic;strokeColor=#3fb950;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="571" y="316" as="sourcePoint"/>
<mxPoint x="571" y="345" as="targetPoint"/>
</mxGeometry>
</mxCell>
<!-- ReAct Loop (centerpiece) -->
<mxCell id="f2-react" value="" style="rounded=1;fillColor=#161b22;strokeColor=#d29922;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="310" y="348" width="340" height="85" as="geometry"/>
</mxCell>
<mxCell id="f2-react-label" value="🔄 ReAct 推理循环" style="text;fontSize=11;fontStyle=1;fillColor=none;strokeColor=none;fontColor=#d29922;align=center;" vertex="1" parent="1">
<mxGeometry x="400" y="350" width="160" height="18" as="geometry"/>
</mxCell>
<mxCell id="f2-think" value="Think&#xa;(LLM 推理决策)" style="rounded=1;fillColor=#2d2a16;strokeColor=#d29922;fontColor=#d29922;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="325" y="373" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="f2-ra1" style="endArrow=classic;strokeColor=#d29922;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="425" y="393" as="sourcePoint"/>
<mxPoint x="455" y="393" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f2-toolcall" value="Tool Call&#xa;(执行工具函数)" style="rounded=1;fillColor=#2d2a16;strokeColor=#d29922;fontColor=#d29922;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="458" y="373" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="f2-ra2" style="endArrow=classic;strokeColor=#d29922;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="558" y="393" as="sourcePoint"/>
<mxPoint x="588" y="393" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f2-observe" value="Observe&#xa;(分析工具结果)" style="rounded=1;fillColor=#2d2a16;strokeColor=#d29922;fontColor=#d29922;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="591" y="373" width="100" height="40" as="geometry"/>
</mxCell>
<!-- Loop back arrow -->
<mxCell id="f2-loop" style="endArrow=classic;strokeColor=#d29922;strokeWidth=1;dashed=1;curved=1;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="641" y="413" as="sourcePoint"/>
<mxPoint x="375" y="413" as="targetPoint"/>
<Array as="points">
<mxPoint x="641" y="430"/>
<mxPoint x="375" y="430"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="f2-loop-label" value="需要更多信息则继续循环" style="text;fontSize=8;fillColor=none;strokeColor=none;fontColor=#8b949e;align=center;" vertex="1" parent="1">
<mxGeometry x="415" y="425" width="140" height="12" as="geometry"/>
</mxCell>
<!-- 4 Tools box -->
<mxCell id="f2-tools" value="" style="rounded=1;fillColor=#161b22;strokeColor=#8957e5;strokeWidth=1;dashed=1;" vertex="1" parent="1">
<mxGeometry x="680" y="278" width="250" height="120" as="geometry"/>
</mxCell>
<mxCell id="f2-tools-label" value="4 个 KG 检索工具" style="text;fontSize=11;fontStyle=1;fillColor=none;strokeColor=none;fontColor=#8957e5;align=center;" vertex="1" parent="1">
<mxGeometry x="730" y="282" width="150" height="16" as="geometry"/>
</mxCell>
<mxCell id="f2-t1" value="🔍 search_entities" style="rounded=1;fillColor=#21262d;strokeColor=#8957e5;fontColor=#bc8cff;fontSize=9;" vertex="1" parent="1">
<mxGeometry x="695" y="303" width="105" height="22" as="geometry"/>
</mxCell>
<mxCell id="f2-t2" value="🔗 get_neighbors" style="rounded=1;fillColor=#21262d;strokeColor=#8957e5;fontColor=#bc8cff;fontSize=9;" vertex="1" parent="1">
<mxGeometry x="810" y="303" width="105" height="22" as="geometry"/>
</mxCell>
<mxCell id="f2-t3" value="📋 get_entities_by_type" style="rounded=1;fillColor=#21262d;strokeColor=#8957e5;fontColor=#bc8cff;fontSize=9;" vertex="1" parent="1">
<mxGeometry x="695" y="332" width="105" height="22" as="geometry"/>
</mxCell>
<mxCell id="f2-t4" value="📊 describe_graph" style="rounded=1;fillColor=#21262d;strokeColor=#8957e5;fontColor=#bc8cff;fontSize=9;" vertex="1" parent="1">
<mxGeometry x="810" y="332" width="105" height="22" as="geometry"/>
</mxCell>
<mxCell id="f2-tools-note" value="基于 NetworkX 本地计算,无 API 调用" style="text;fontSize=8;fillColor=none;strokeColor=none;fontColor=#484f58;align=center;" vertex="1" parent="1">
<mxGeometry x="695" y="360" width="220" height="12" as="geometry"/>
</mxCell>
<!-- Final output row -->
<mxCell id="f2-down2" style="endArrow=classic;strokeColor=#3fb950;strokeWidth=2;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="480" y="433" as="sourcePoint"/>
<mxPoint x="480" y="438" as="targetPoint"/>
<mxPoint as="array"/>
</mxGeometry>
</mxCell>
<mxCell id="f2-out" value="提取最终答案 + 工具调用链 + 引用节点" style="rounded=1;fillColor=#0d3320;strokeColor=#3fb950;fontColor=#c9d1d9;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="330" y="440" width="220" height="30" as="geometry"/>
</mxCell>
<mxCell id="f2-a4" style="endArrow=classic;strokeColor=#3fb950;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="550" y="455" as="sourcePoint"/>
<mxPoint x="690" y="455" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f2-render" value="前端渲染&#xa;Markdown 答案&#xa;+ ToolCall 面板&#xa;+ Cited Node 标签" style="rounded=1;fillColor=#0d3320;strokeColor=#3fb950;fontColor=#f0f6fc;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="693" y="438" width="130" height="50" as="geometry"/>
</mxCell>
<!-- Save history note -->
<mxCell id="f2-save" value="💾 保存到 query_history.jsonl" style="text;fontSize=9;fillColor=none;strokeColor=none;fontColor=#8b949e;align=left;" vertex="1" parent="1">
<mxGeometry x="26" y="345" width="200" height="14" as="geometry"/>
</mxCell>
<!-- ===================================================================== -->
<!-- FLOW 3: 多模式搜索 -->
<!-- ===================================================================== -->
<mxCell id="f3-bg" value="" style="rounded=1;fillColor=#0d1117;strokeColor=#8957e5;strokeWidth=1;dashed=1;opacity=40;" vertex="1" parent="1">
<mxGeometry x="10" y="455" width="930" height="165" as="geometry"/>
</mxCell>
<mxCell id="f3-label" value="流程三:多模式实体搜索" style="text;fontSize=13;fontStyle=1;fillColor=none;strokeColor=none;fontColor=#8957e5;align=left;" vertex="1" parent="1">
<mxGeometry x="20" y="458" width="250" height="20" as="geometry"/>
</mxCell>
<!-- Search input -->
<mxCell id="f3-input" value="🔎 用户输入搜索" style="rounded=1;fillColor=#1c1830;strokeColor=#8957e5;fontColor=#f0f6fc;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="25" y="488" width="120" height="34" as="geometry"/>
</mxCell>
<mxCell id="f3-sel" value="选择搜索模式" style="rhombus;fillColor=#1c1830;strokeColor=#8957e5;fontColor=#bc8cff;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="165" y="480" width="80" height="50" as="geometry"/>
</mxCell>
<mxCell id="f3-a0" style="endArrow=classic;strokeColor=#8957e5;strokeWidth=1.5;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="145" y="505" as="sourcePoint"/>
<mxPoint x="162" y="505" as="targetPoint"/>
</mxGeometry>
</mxCell>
<!-- Mode 1: Entity Search -->
<mxCell id="f3-m1" value="Entity Search&#xa;GET /search/entities" style="rounded=1;fillColor=#1c1830;strokeColor=#58a6ff;fontColor=#58a6ff;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="270" y="488" width="135" height="34" as="geometry"/>
</mxCell>
<mxCell id="f3-a1" style="endArrow=classic;strokeColor=#8957e5;strokeWidth=1.5;exitX=0.8;exitY=0.2;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="229" y="488" as="sourcePoint"/>
<mxPoint x="267" y="495" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="f3-m1r" value="实体列表 +&#xa;1-hop 预览图" style="rounded=1;fillColor=#1c1830;strokeColor=#58a6ff;fontColor=#c9d1d9;fontSize=9;" vertex="1" parent="1">
<mxGeometry x="270" y="535" width="135" height="30" as="geometry"/>
</mxCell>
<mxCell id="f3-ma1" style="endArrow=classic;strokeColor=#58a6ff;strokeWidth=1;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="337" y="522" as="sourcePoint"/>
<mxPoint x="337" y="532" as="targetPoint"/>
</mxGeometry>
</mxCell>
<!-- Mode 2: Path Search -->
<mxCell id="f3-m2" value="Path Search&#xa;GET /search/path" style="rounded=1;fillColor=#1c1830;strokeColor=#3fb950;fontColor=#3fb950;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="425" y="488" width="135" height="34" as="geometry"/>
</mxCell>
<mxCell id="f3-a2" style="endArrow=classic;strokeColor=#8957e5;strokeWidth=1.5;exitX=0.5;exitY=0.2;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="205" y="488" as="sourcePoint"/>
<mxPoint x="422" y="495" as="targetPoint"/>
<Array as="points">
<mxPoint x="422" y="488"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="f3-m2r" value="路径链可视&#xa;+ 文字描述" style="rounded=1;fillColor=#1c1830;strokeColor=#3fb950;fontColor=#c9d1d9;fontSize=9;" vertex="1" parent="1">
<mxGeometry x="425" y="535" width="135" height="30" as="geometry"/>
</mxCell>
<mxCell id="f3-ma2" style="endArrow=classic;strokeColor=#3fb950;strokeWidth=1;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="492" y="522" as="sourcePoint"/>
<mxPoint x="492" y="532" as="targetPoint"/>
</mxGeometry>
</mxCell>
<!-- Mode 3: Graph Search -->
<mxCell id="f3-m3" value="Graph Search&#xa;GET /search/graph" style="rounded=1;fillColor=#1c1830;strokeColor=#ff7b72;fontColor=#ff7b72;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="580" y="488" width="135" height="34" as="geometry"/>
</mxCell>
<mxCell id="f3-a3" style="endArrow=classic;strokeColor=#8957e5;strokeWidth=1.5;exitX=1;exitY=0.8;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="245" y="520" as="sourcePoint"/>
<mxPoint x="577" y="505" as="targetPoint"/>
<Array as="points">
<mxPoint x="577" y="520"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="f3-m3r" value="D3 子图渲染&#xa;+ 匹配节点列表" style="rounded=1;fillColor=#1c1830;strokeColor=#ff7b72;fontColor=#c9d1d9;fontSize=9;" vertex="1" parent="1">
<mxGeometry x="580" y="535" width="135" height="30" as="geometry"/>
</mxCell>
<mxCell id="f3-ma3" style="endArrow=classic;strokeColor=#ff7b72;strokeWidth=1;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="647" y="522" as="sourcePoint"/>
<mxPoint x="647" y="532" as="targetPoint"/>
</mxGeometry>
</mxCell>
<!-- Cross-page navigation -->
<mxCell id="f3-nav" value="跨页面联动" style="rounded=1;fillColor=#2d2a16;strokeColor=#d29922;fontColor=#f0f6fc;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="760" y="488" width="120" height="34" as="geometry"/>
</mxCell>
<mxCell id="f3-nav-detail" value="[View KG] → #/graph?node=id&#xa;[Chat] → #/chat?q=xxx" style="rounded=1;fillColor=#2d2a16;strokeColor=#d29922;fontColor=#c9d1d9;fontSize=9;" vertex="1" parent="1">
<mxGeometry x="740" y="535" width="160" height="30" as="geometry"/>
</mxCell>
<mxCell id="f3-nav-a" style="endArrow=classic;strokeColor=#d29922;strokeWidth=1;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="820" y="522" as="sourcePoint"/>
<mxPoint x="820" y="532" as="targetPoint"/>
</mxGeometry>
</mxCell>
<!-- Global search note -->
<mxCell id="f3-global" value="🔍 Header 全局搜索框 (debounce 300ms) → GET /search/entities → 实时建议下拉 → 跳转" style="text;fontSize=9;fillColor=none;strokeColor=none;fontColor=#8b949e;align=left;" vertex="1" parent="1">
<mxGeometry x="25" y="578" width="450" height="14" as="geometry"/>
</mxCell>
<!-- Tech stack footer -->
<mxCell id="flow-footer" value="3 条核心流程 | 25 个 REST API 端点 | 后台线程异步索引 | ReAct Agent 多步推理 | 前端轮询 3s/10s | 跨页面 Hash 路由联动" style="text;fontSize=9;fillColor=none;strokeColor=none;fontColor=#484f58;align=center;" vertex="1" parent="1">
<mxGeometry x="60" y="605" width="700" height="16" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>