c7a02c3905
5 层 + 1 条 NATS 零拷贝消息总线的 monorepo(Monolith First → Microservices Morph B)。 纵向主干(任务流 + Token 流回流)已真实跑通,横向各层能力为带注释的桩。 已贯通(real code): - sundynix-shared: 共享契约 + JetStream/core NATS 真实收发(bus) + 内嵌 NATS(devnats) + e2e 测试 - sundynix-gateway: Gin 接入 + DSL 解析组装 + NATS Publish + SSE 流式输出 - sundynix-dispatcher: NATS 消费 + Eino Orchestrator 流式回流 + 熔断器 + LLM Pool 占位流式 - 链路: HTTP POST → DSL → sundynix.tasks.* → Dispatcher → Token 经 sundynix.streams.<id> 回流 → SSE - 基础设施: docker-compose(nats/postgres/redis/neo4j/milvus) + Makefile(make demo/e2e) 待填(桩): - Eino 图编排 compose.NewGraph、LLM Pool 接 vLLM/Ollama - Gateway store 换真实 pgx/redis - sundynix-mcp-go: Bleve+Milvus+Neo4j 混合检索 / UniOffice / 外部 API - sundynix-mcp-py: gVisor 沙箱 / MinerU(PaddleOCR) / Docker 解释器 - sundynix-desktop: React Flow 画布 → DSL 导出 → SSE 展示
287 lines
13 KiB
HTML
287 lines
13 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>sundynix-agentix · 系统架构图</title>
|
||
<style>
|
||
:root{
|
||
--client:#f6d9b0; --client-bg:#fdf2e3; --client-br:#e0a85a;
|
||
--gateway:#f8c9c9; --gateway-stroke:#d96b6b;
|
||
--nats:#cfe8c6; --nats-bg:#e7f4e1; --nats-br:#86c06a;
|
||
--dispatcher:#dcc7ef; --dispatcher-bg:#efe5f8; --dispatcher-br:#a984cf;
|
||
--gotools:#bcdcef; --gotools-bg:#dcecf7; --gotools-br:#5fa9d4;
|
||
--pytools:#f6e6a8; --pytools-bg:#fbf3cf; --pytools-br:#d8bf52;
|
||
--ginserver:#bfe3c4;
|
||
--box:#eef1f4; --box-br:#c4ccd4;
|
||
--ink:#1c2b3a; --muted:#5a6b7b;
|
||
}
|
||
*{box-sizing:border-box;}
|
||
body{
|
||
margin:0; padding:32px;
|
||
font-family:"PingFang SC","Microsoft YaHei","Segoe UI",system-ui,sans-serif;
|
||
background:#f3f5f7; color:var(--ink);
|
||
}
|
||
h1{font-size:22px; margin:0 0 4px;}
|
||
.sub{color:var(--muted); margin:0 0 24px; font-size:13px;}
|
||
|
||
.grid{
|
||
display:grid;
|
||
grid-template-columns: 1.05fr 1.05fr 1.15fr;
|
||
gap:22px;
|
||
align-items:start;
|
||
max-width:1980px;
|
||
}
|
||
|
||
/* ---- generic layer card ---- */
|
||
.layer{
|
||
border-radius:14px; padding:14px;
|
||
border:2px solid transparent;
|
||
}
|
||
.layer > .ltitle{
|
||
font-weight:800; font-size:15px; margin:0 0 12px; letter-spacing:.2px;
|
||
}
|
||
.layer > .ltitle small{display:block; font-weight:600; font-size:11px; color:var(--muted); margin-top:2px;}
|
||
|
||
.panel{
|
||
background:rgba(255,255,255,.65);
|
||
border-radius:11px; padding:12px; margin-bottom:12px;
|
||
}
|
||
.panel:last-child{margin-bottom:0;}
|
||
.panel-title{font-weight:700; font-size:13px; margin:0 0 10px;}
|
||
.panel-title small{font-weight:500; color:var(--muted);}
|
||
|
||
.box{
|
||
background:var(--box); border:1px solid var(--box-br);
|
||
border-radius:8px; padding:9px 11px; margin-bottom:8px;
|
||
font-size:12.5px; line-height:1.35; text-align:center;
|
||
}
|
||
.box:last-child{margin-bottom:0;}
|
||
.box b{display:block; font-weight:700;}
|
||
.box span{display:block; color:var(--muted); font-size:11px; margin-top:2px;}
|
||
.box.hl{background:#fff;}
|
||
|
||
.row2{display:grid; grid-template-columns:1fr 1fr; gap:8px;}
|
||
.row2 .box{margin-bottom:0;}
|
||
|
||
/* ---- layer colors ---- */
|
||
.client { background:var(--client-bg); border-color:var(--client-br); }
|
||
.gateway { background:#e6eef6; border-color:var(--gotools-br); }
|
||
.gateway .panel{background:#cfe0ef;}
|
||
.nats { background:var(--nats-bg); border-color:var(--nats-br); }
|
||
.dispatcher{ background:var(--dispatcher-bg); border-color:var(--dispatcher-br); }
|
||
.toolswrap { background:var(--nats-bg); border-color:var(--nats-br); padding:14px; border-radius:14px; border:2px solid var(--nats-br);}
|
||
.mcp-go { background:#d6e7f3; border:2px solid var(--gotools-br); border-radius:12px; padding:12px; margin-bottom:14px;}
|
||
.mcp-py { background:var(--pytools-bg); border:2px solid var(--pytools-br); border-radius:12px; padding:12px;}
|
||
|
||
.colA{display:flex; flex-direction:column; gap:0;}
|
||
.colB{display:flex; flex-direction:column; gap:18px;}
|
||
|
||
/* connector labels */
|
||
.conn{
|
||
text-align:center; font-size:11px; color:#2a3a49; font-weight:700;
|
||
margin:6px 0; line-height:1.4;
|
||
}
|
||
.conn .arr{font-size:15px; color:#33485c;}
|
||
.conn small{display:block; font-weight:500; color:var(--muted);}
|
||
|
||
.midbar{
|
||
display:flex; align-items:center; justify-content:center; gap:8px;
|
||
font-weight:800; font-size:12px; color:#2a3a49; text-align:center;
|
||
background:#fff; border:1px dashed #9fb0bf; border-radius:8px;
|
||
padding:8px 10px; margin:14px 0;
|
||
}
|
||
|
||
.llmpool{
|
||
background:#e9edf0; border:1px solid #c4ccd4; border-radius:50px/40px;
|
||
padding:14px 16px; text-align:center; font-size:12.5px;
|
||
}
|
||
.llmpool b{display:block;}
|
||
.einolink{text-align:center; font-size:11px; font-weight:700; color:#6a4fa0; margin:8px 0;}
|
||
|
||
/* legend */
|
||
.legend{
|
||
margin-top:26px; display:flex; flex-wrap:wrap; gap:10px 26px;
|
||
align-items:center; background:#fff; border:1px solid var(--box-br);
|
||
border-radius:12px; padding:14px 18px; max-width:1980px;
|
||
}
|
||
.legend b{width:100%; font-size:13px; margin-bottom:2px;}
|
||
.lg{display:flex; align-items:center; gap:8px; font-size:12.5px;}
|
||
.sw{width:20px; height:14px; border-radius:4px; border:1px solid rgba(0,0,0,.15);}
|
||
.sw.client{background:var(--client);} .sw.gateway{background:var(--gateway);}
|
||
.sw.nats{background:var(--nats);} .sw.dispatcher{background:var(--dispatcher);}
|
||
.sw.gotools{background:var(--gotools);} .sw.pytools{background:var(--pytools);}
|
||
.sw.ginserver{background:var(--ginserver);}
|
||
|
||
.flow-note{
|
||
max-width:1980px; margin-top:22px; background:#fff; border:1px solid var(--box-br);
|
||
border-radius:12px; padding:16px 20px; font-size:13px; line-height:1.7;
|
||
}
|
||
.flow-note b{color:#2a3a49;}
|
||
.tag{display:inline-block; background:#eef1f4; border:1px solid var(--box-br);
|
||
border-radius:5px; padding:1px 7px; font-size:11.5px; font-family:ui-monospace,monospace;}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<h1>sundynix-agentix · 系统架构图</h1>
|
||
<p class="sub">分层式 AI Agent 平台 — Client / Gateway / NATS 总线 / Dispatcher / MCP Tools(Monolith First → Microservices Morph B)</p>
|
||
|
||
<div class="grid">
|
||
|
||
<!-- ===================== 列 1:左纵列 (Client → Gateway → NATS → Dispatcher) ===================== -->
|
||
<div class="colA">
|
||
|
||
<!-- 1. CLIENT -->
|
||
<div class="layer client">
|
||
<div class="ltitle">1. CLIENT LAYER <small>Edge Interaction</small></div>
|
||
<div class="panel">
|
||
<div class="panel-title">sundynix-desktop <small>(User Device App)</small></div>
|
||
<div class="box hl"><b>UI Representation Layer</b><span>React 19 + TypeScript</span></div>
|
||
<div class="box"><b>shadcn/ui + Tailwind CSS</b><span>Styles / Components</span></div>
|
||
<div class="row2" style="margin-bottom:8px;">
|
||
<div class="box"><b>React Flow Canvas</b><span>Agent Orchestration</span></div>
|
||
<div class="box"><b>JSON DSL export</b><span> </span></div>
|
||
</div>
|
||
<div class="box"><b>LLM Wiki Management Panel</b></div>
|
||
<div class="box hl" style="background:var(--ginserver);"><b>Wails Local Go Runtime</b></div>
|
||
<div class="row2">
|
||
<div class="box hl" style="background:var(--gotools);"><b>Strong Binding</b><span>TS / Go</span></div>
|
||
<div class="box hl" style="background:var(--gotools);"><b>Local File System I/O</b></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- connector client <-> gateway -->
|
||
<div class="conn">
|
||
<span class="arr">↕</span> 4. PHYSICAL COMMUNICATION<br>
|
||
<small>HTTPS / WebSocket / SSE · <span class="tag">sundynix.streams.task_id</span> Token Stream</small>
|
||
</div>
|
||
|
||
<!-- 2. GATEWAY -->
|
||
<div class="layer gateway">
|
||
<div class="ltitle">2. BUSINESS GATEWAY LAYER</div>
|
||
<div class="panel">
|
||
<div class="panel-title">sundynix-gateway <small>(Gin 微服务 · 集成 Monolith First)</small></div>
|
||
<div class="box hl"><b>Gin 微服务 / 统一接入层</b></div>
|
||
<div class="row2" style="margin-bottom:8px;">
|
||
<div class="box">🗄️ <b>MainDB</b><span>PgSQL: Users, Billing, DSL</span></div>
|
||
<div class="box">🧱 <b>CacheDB</b><span>Session / Rate Limit</span></div>
|
||
</div>
|
||
<div class="row2" style="margin-bottom:8px;">
|
||
<div class="box">🧱 <b>CacheDB</b><span>Redis: Session, Rate Limit</span></div>
|
||
<div class="box"><b>商业化与计费模块</b></div>
|
||
</div>
|
||
<div class="row2">
|
||
<div class="box"><b>Harness</b><span>Input / Output Guardrail</span></div>
|
||
<div class="box"><b>Task DSL Parser & Assembly</b></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- connector gateway <-> nats -->
|
||
<div class="conn">
|
||
<span class="arr">↓</span> 1. Publish Task DSL | 4. Subscribe Stream <span class="arr">↑</span>
|
||
</div>
|
||
|
||
<!-- 3. NATS -->
|
||
<div class="layer nats">
|
||
<div class="ltitle">3. MESSAGE BUS — NATS 零拷贝骨干网</div>
|
||
<div class="panel">
|
||
<div class="panel-title" style="text-align:center;">NATS Server (Go) 🗄️</div>
|
||
<div class="row2">
|
||
<div class="box"><b>NATS Queue</b><span>分布式任务队列<br><span class="tag">sundynix.tasks.*</span></span></div>
|
||
<div class="box"><b>NATS Stream</b><span>零拷贝字节管道<br><span class="tag">sundynix.streams.*</span></span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- connector nats <-> dispatcher -->
|
||
<div class="conn"><span class="arr">↕</span> 4. Subscribe Stream</div>
|
||
|
||
<!-- 4. DISPATCHER -->
|
||
<div class="layer dispatcher">
|
||
<div class="ltitle">4. AI AGENT DISPATCHER LAYER</div>
|
||
<div class="llmpool" style="margin-bottom:10px;">
|
||
<b>LLM Pool</b><span style="color:var(--muted); font-size:11px;">vLLM / Ollama 集群</span>
|
||
</div>
|
||
<div class="einolink">↑ EinoCore · Eino 回调机制 ↓</div>
|
||
<div class="panel">
|
||
<div class="panel-title">sundynix-dispatcher <small>(Go / Eino 集群)</small></div>
|
||
<div class="row2" style="margin-bottom:8px;">
|
||
<div class="box hl"><b>Eino 图编排引擎</b></div>
|
||
<div class="box hl"><b>nats.go client</b></div>
|
||
</div>
|
||
<div class="box"><b>Harness: LLM 自动化评测</b></div>
|
||
<div class="box"><b>Harness: 熔断降级中心</b></div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- ===================== 列 2:留白做视觉间隔 / 物理通信说明 ===================== -->
|
||
<div class="colA" style="justify-content:flex-start;">
|
||
<div class="midbar">⟷ 4. PHYSICAL COMMUNICATION ⟷</div>
|
||
<div class="flow-note" style="margin-top:0;">
|
||
<b>核心数据流(编号对应连线)</b><br>
|
||
<b>1.</b> Gateway 解析 DSL 后 <b>Publish Task DSL</b> → NATS Queue(<span class="tag">sundynix.tasks.*</span>)<br>
|
||
<b>2.</b> Dispatcher 通过 <span class="tag">nats.go</span> 订阅任务,Eino 图编排引擎驱动 LLM Pool 推理<br>
|
||
<b>3.</b> Dispatcher / Gateway 经 NATS 调用第 5 层 MCP 工具(Go I/O 型 + Python 算法型)<br>
|
||
<b>4.</b> 推理结果以 <b>零拷贝 Token Stream</b> 经 <span class="tag">sundynix.streams.task_id</span> 回流 Gateway → 经 SSE/WS 推送给 Client
|
||
</div>
|
||
<div class="midbar" style="margin-top:18px;">⟶ 4. Subscribe Stream ⟶ MCP Tools</div>
|
||
</div>
|
||
|
||
<!-- ===================== 列 3:MCP Tools 层 ===================== -->
|
||
<div class="colB">
|
||
<div class="toolswrap">
|
||
<div style="font-weight:800; font-size:15px; margin-bottom:4px;">5. MICROSERVICE MCP TOOLS LAYER</div>
|
||
<div style="font-size:11px; color:var(--muted); margin-bottom:12px;">Standalone microservices · Morph B</div>
|
||
|
||
<!-- mcp_go -->
|
||
<div class="mcp-go">
|
||
<div class="panel-title">sundynix-mcp-go <small>(Go 微服务 · I/O 型)</small></div>
|
||
<div class="box hl"><b>MCP Protocol Gateway</b></div>
|
||
<div class="box hl"><b>LLM Wiki 搜索引擎</b><span>Hybrid Search: Bleve · Milvus Go SDK · Neo4j Go Driver</span></div>
|
||
<div class="row2" style="margin-bottom:8px;">
|
||
<div class="box">🧊 <b>Milvus</b><span>Vector DB</span></div>
|
||
<div class="box">🔎 <b>Bleve</b><span>Go Search Index</span></div>
|
||
</div>
|
||
<div class="row2" style="margin-bottom:8px;">
|
||
<div class="box">🕸️ <b>Neo4j</b><span>Knowledge Graph</span></div>
|
||
<div class="box">🕸️ <b>Neo4j</b><span>Graph</span></div>
|
||
</div>
|
||
<div class="row2">
|
||
<div class="box">📄 <b>UniOffice</b><span>Word/Doc Rendering</span></div>
|
||
<div class="box"><b>External APIs</b></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- mcp_py -->
|
||
<div class="mcp-py">
|
||
<div class="panel-title">sundynix-mcp-py <small>(Python 微服务 · 算法型)</small></div>
|
||
<div class="box hl"><b>MCP Protocol Gateway</b></div>
|
||
<div class="box"><b>Harness: Secure Code Sandbox</b><span>gVisor / KataVM · Static Code Guard</span></div>
|
||
<div class="box"><b>MinerU</b><span>Multimodal Parser: PaddleOCR</span></div>
|
||
<div class="box"><b>Docker 隔离沙箱</b><span>Code Interpreter</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- ===================== 图例 ===================== -->
|
||
<div class="legend">
|
||
<b>Legend</b>
|
||
<div class="lg"><span class="sw client"></span>Client</div>
|
||
<div class="lg"><span class="sw gateway"></span>Gateway</div>
|
||
<div class="lg"><span class="sw nats"></span>NATS</div>
|
||
<div class="lg"><span class="sw dispatcher"></span>Dispatcher</div>
|
||
<div class="lg"><span class="sw gotools"></span>Go Tools</div>
|
||
<div class="lg"><span class="sw pytools"></span>Python Tools</div>
|
||
<div class="lg"><span class="sw ginserver"></span>GinServer</div>
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|