# sundynix-agentix · 架构设计文档
> 版本:2026-07-26
> 定位:**事件驱动的多租户 AI Agent 平台**。以 NATS 为统一总线,服务经契约解耦,Eino 为编排核心,控制面热切换;桌面端 JARVIS 既是语音入口,也是能操作用户电脑的中枢。
>
> **本文以代码为单一事实源。** `PROGRESS.md`(停更于 2026-06-19)与 `DEPTH_ROADMAP.md` 的汇总表已与代码脱节(详见 §9.14),仅作历史参考。
>
> 配套文档:`ARCHITECTURE_REVIEW.md`(架构评审)、`DEPTH_ROADMAP.md`(路线图)、`EINO_ADOPTION.md`(Eino 采纳)、`SAAS_DESIGN.md` / `SAAS_P2_DESIGN.md`(多租户与计量)、`SPACE_DESIGN.md`(共享工作区)、`PAYMENT_DESIGN.md`(支付)、`VOICE_DESIGN.md`(语音)、`JARVIS_BRAIN_DESIGN.md`(JARVIS 中枢)、`LOCAL_AGENT_DESIGN.md`(本地执行)、`DEPLOY.md`(部署)。
---
## 1. 系统概述
用户在桌面端搭一张编排图(或直接说话),任务经网关落库并发到 NATS;调度集群把 DSL 编译成 Eino compose 图执行,过程中自主调用工具(检索/联网/计算/操作用户电脑),Token 与执行轨迹实时流回界面;全程带计量计费、护栏、评测与链路追踪。
### 1.1 Monorepo 结构
```
sundynix-agentix/
├── sundynix-shared/ 共享库:NATS 总线 / 契约 / 对象存储 / 密钥 / OTel / prompts
├── sundynix-gateway/ 第 2 层 业务网关(HTTP + WS + 平台工具 + 后台常驻)
├── sundynix-dispatcher/ 第 4 层 Agent 编排调度集群(无对外端口)
├── sundynix-mcp-go/ 第 5 层 Go I/O 型工具服务(RAG / 记忆 / 报告 / 图表)
├── sundynix-mcp-py/ 第 5 层 Python 算法型工具服务(沙箱执行 / 文档解析)
├── sundynix-desktop/ 桌面端(Wails v3 + React 19)——主产品面
├── sundynix-admin/ 官网 + 运维控制台(同一 SPA,go:embed 进 gateway)
├── sundynix-web/ 薄 Web 面(租户自助:注册/组织/团队/账单)
├── deploy/ 三机部署配置 + NATS 集群配置
└── scripts/ 备份/恢复/RAG 评测
```
`go.work` 只纳入 4 个后端模块(shared / gateway / dispatcher / mcp-go)。
**`sundynix-desktop` 刻意不入 workspace**(它是客户端,独立依赖),因此在该目录下跑 Go 命令必须 `GOWORK=off`。
### 1.2 代码规模(实测)
| 部分 | 源码 | 测试 |
|---|---|---|
| Go · gateway | 14,395 | 2,775 |
| Go · dispatcher | 5,265 | 2,974 |
| Go · mcp-go | 3,844 | 1,319 |
| Go · shared | 2,173 | 681 |
| Go · desktop | 697 | 271 |
| TypeScript · desktop 前端 | 8,980 | 11 个前端测试文件 |
| TypeScript · admin | 9,360 | (同上) |
| TypeScript · web | 2,030 | (同上) |
| Python · mcp-py | 520 | |
---
## 2. 分层架构总览
```mermaid
flowchart TB
subgraph CLIENT["客户端层"]
DESK["sundynix-desktop
Wails v3 + React 19
编排画布 · JARVIS · 本地 runner"]
ADMIN["sundynix-admin
官网 / + 控制台 /admin"]
WEB["sundynix-web
租户自助柜台"]
end
subgraph GW["第 2 层 · gateway(唯一对外入口)"]
HTTP["HTTP API + SSE(gin)"]
WS["WebSocket
语音 /voice/stream
本地执行器 /local/runner"]
PLAT["平台工具提供方
platform_* / local_*"]
BG["后台常驻
配置控制面 · 持久消费者
入库 worker 池 · 3 个 ticker"]
end
BUS{{"NATS + JetStream
统一总线(8MB payload)"}}
subgraph WORK["执行层"]
DISP["第 4 层 · dispatcher
Eino compose 编排
LLM 双池 + failover + 熔断
harness 治理"]
MGO["第 5 层 · mcp-go
RAG 三路 / 记忆 / 报告 / 图表"]
MPY["第 5 层 · mcp-py
Docker 沙箱 / 文档解析"]
end
subgraph STORE["存储层"]
PG[("PostgreSQL 16
29 张表")]
RDS[("Redis 7")]
MLV[("Milvus 2.4.13")]
BLV[("Bleve 全文")]
NEO[("Neo4j 5")]
OSS[("MinIO")]
end
LLM["LLM Provider
OpenAI 兼容 · DeepSeek"]
VOLC["火山引擎
ASR / TTS"]
DESK --> HTTP
ADMIN --> HTTP
WEB --> HTTP
DESK <--> WS
HTTP --> BUS
WS --> VOLC
BG <--> BUS
PLAT <--> BUS
BUS <--> DISP
BUS <--> MGO
BUS <--> MPY
DISP --> LLM
HTTP --> PG
HTTP --> RDS
HTTP --> OSS
MGO --> MLV
MGO --> BLV
MGO --> NEO
MGO --> OSS
DISP --> BUS
```
### 2.1 分层职责
| 层 | 组件 | 职责 | 对外端口 |
|---|---|---|---|
| 1 客户端 | desktop / admin / web | 交互与呈现 | — |
| 2 接入 | **gateway** | 鉴权、租户/空间上下文、限流、护栏、审计、任务落库与发射、SSE/WS 回流、平台工具、后台常驻 | **8080**(生产 3000) |
| 3 总线 | **NATS + JetStream** | 任务队列、回流、工具 RPC、控制面广播、KV checkpoint | 4222 |
| 4 编排 | **dispatcher** | DSL→compose 图执行、ReAct 自主工具、多智能体、HITL 中断、评测纠偏 | 无(仅探针 8091) |
| 5 工具 | **mcp-go / mcp-py** | I/O 型与算法型能力,队列组水平扩 | 无(仅探针 8092) |
**关键设计**:dispatcher 与 mcp-\* 都**没有对外端口**,只通过 NATS 通信 —— 攻击面收敛到 gateway 一个进程。
---
## 3. 服务详解
### 3.1 gateway —— 业务网关 / 统一接入层
`github.com/sundynix/sundynix-gateway` · Go 1.25.8 · 入口 `cmd/server/main.go`
| internal 包 | 职责 |
|---|---|
| `router` | Gin 装配:路由 + 中间件链 + CORS + admin SPA 回退 |
| `handler` | 30+ 文件:task/agent/kb/report/space/tenant/billing/payment/voice/jarvis/prompt/admin/wechat/local_runner/platform_tools |
| `middleware` | RequestID · Observe · Auth 系列 · TenantContext · SpaceContext · RateLimit · Guardrail · Audit · Require\*Role |
| `store` | Postgres(GORM) + Redis 全部访问;迁移、租户作用域插件、leader 选主 |
| `auth` | 无状态 JWT 签发/校验 + bcrypt |
| `dsl` | 前端 JSON DSL → `contract.Task` 解析组装 + 拓扑校验 |
| `guardrail` | 输入护栏 Tier1(归一化 + 注入正则 + env 黑名单) |
| `payment` | 渠道抽象 + manager + 微信支付 |
| `wechat` | 公众号带参二维码扫码登录 + 事件回调 |
| `voice` | 火山 V3 流式 ASR/TTS 客户端 + 二进制帧协议 + 攒句器 |
| `webui` | `go:embed` admin 产物打进二进制 |
| `nats` | shared/bus 薄封装 |
**技术栈**
| 用途 | 库 | 版本 |
|---|---|---|
| Web 框架 | `gin-gonic/gin` | v1.12.0 |
| SSE | `gin-contrib/sse` | v1.1.1 |
| ORM | `gorm.io/gorm` + `driver/postgres` | v1.31.1 / v1.6.0 |
| 缓存 | `redis/go-redis/v9` | v9.20.0 |
| 鉴权 | `golang-jwt/jwt/v5` + `x/crypto`(bcrypt) | v5.3.1 / v0.53.0 |
| ID | `bwmarrin/snowflake` | v0.3.0 |
| WebSocket | `gorilla/websocket` | v1.5.3 |
| 指标 | `prometheus/client_golang` | v1.23.2 |
| 追踪 | `otelgin` + otel | v0.69.0 / v1.44.0 |
| 支付 | `wechatpay-apiv3/wechatpay-go` | v0.2.21 |
| 测试 DB | `glebarez/sqlite`(纯 Go 无 CGO,仅测试) | v1.11.0 |
**后台常驻组件**
| 组件 | 作用 |
|---|---|
| `ServeConfig` ×3 | 模型配置控制面应答(kind = chat / embedding / voice) |
| `ServePrompts` | 激活 prompt 集下发 |
| `ConsumeTaskStatus` | 任务状态落库 + **报告完成时主动语音播报** |
| `ConsumeEval` / `ConsumeUsage` | 评测结果 upsert / 用量落库计费 |
| `StartIngestWorkers` | JetStream 入库作业 worker 池(有界并发背压) |
| `ServePlatformTools` | gateway 自己作为 MCP 工具提供方(见 §5.4) |
| `StartReconcile` / `StartSubscriptionTicker` / `StartScheduleTicker` | 微信掉单补偿 / 订阅周期发放 / JARVIS 定时任务 |
三个 ticker 均带 **PG advisory lock 选主**(`store/leader.go`),多副本下只有一个实例真正扫。
**辅助 CLI**:`cmd/localsim`(模拟桌面本地执行器)、`cmd/voicesim`(免麦端到端语音链路模拟)、`cmd/voiceconfig`、`cmd/voicecheck`。
### 3.2 dispatcher —— Agent 编排调度集群
`github.com/sundynix/sundynix-dispatcher` · Go 1.25.8 · **无 HTTP 业务端口**
| internal 包 | 职责 |
|---|---|
| `eino` | 编排引擎全部:orchestrator · compose_compiler/graph/callbacks · react_agent · coordinator · checkpoint · memory_extract · report |
| `harness` | 治理五件套:budget · circuitbreaker · eval · jailbreak · output |
| `llm` | pool(热更新) · failover(主备链) · cache(输出缓存) |
| `dsl` | DSL 图 → 对话计划编译 |
| `nats` | shared/bus 薄封装 |
**技术栈**:`cloudwego/eino v0.9.12` + `eino-ext/components/model/openai v0.1.13`(OpenAI 兼容协议)、otel v1.44.0。
另有 `cmd/loadtest`(阶梯并发压测器)。
### 3.3 mcp-go —— Go I/O 型工具服务
core NATS request-reply,订阅 `sundynix.tools.go.>`,队列组 `mcp-go-workers`,探针 `:8092`。
**技术栈**:`blevesearch/bleve/v2 v2.4.2`(CJK 分词)、`milvus-sdk-go/v2 v2.4.1`、`neo4j-go-driver/v5 v5.24.0`、`go-redis/v9`、`gorm.io/gorm`。
> ⚠️ `internal/office/unioffice.go` **名字有误导性**:并不引任何第三方 Office 库,而是用标准库 `archive/zip` + 内联 OOXML/WordprocessingML XML 手工拼 `.docx`。
**工具注册表**(`internal/mcp/gateway.go` 的 `buildRegistry()` 是唯一事实源,dispatcher 经 `list_tools` 动态发现,加工具零改调度代码)
暴露给自主 agent(10 个):`wiki_search`(知识检索) · `memory_get`→`recall_user_memory` · `memory_upsert`→`remember_user_fact` · `history_get` · `web_search` · `web_fetch` · `calculator` · `current_datetime` · `sql_query`(仅 SELECT/WITH) · `chart`(bar/line/pie)
内部/流水线(13 个):`kb_ingest` · `kb_delete` · `kb_search` · `kb_graph` · `report_render` · `report_store` · `report_export` · `external_api`(带 SSRF 校验) · `memory_delete` · `memory_list` · `history_append` · `health` · `echo`
### 3.4 mcp-py —— Python 算法型工具服务
Python 3.11 · hatchling · **无 Web 框架**(纯 asyncio + `nats-py`),订阅 `sundynix.tools.py.>`,队列组 `mcp-py-workers`。
依赖:`nats-py>=2.7.0` · `python-docx` · `openpyxl` · `pypdf` · `docker>=7.1.0`
| 工具 | agent 暴露 | 说明 |
|---|---|---|
| `run_code` | ✅ | Docker 沙箱 256m/10s |
| `secure_sandbox` | ❌ | 更严档 128m/5s |
| `parse_document` | ❌ | txt/md/csv 直读;docx/xlsx/pdf 按扩展名路由 |
| `echo` | ❌ | |
两层防护:`sandbox.py` AST 静态守卫(拒 os/sys/subprocess/socket/ctypes/pickle 与 eval/exec/open)+ `interpreter.py` Docker 真隔离(禁网 / 非 root / 丢能力 / 限资源 / 一次性)。
`mineru.py`(多模态解析)目前为桩。
### 3.5 shared —— 共享库
| 包 | 作用 |
|---|---|
| `bus` | NATS/JetStream 封装:流声明、任务收发、Token/Exec 回流、工具 RPC、5 条持久流、控制面、KV checkpoint;`trace.go` 把 W3C traceparent 塞进 NATS 头实现**跨总线链路串联**;消费侧解密 api_key |
| `contract` | 三方共享契约:subject 常量、Task/ToolCall/ToolResult/各类 Event、入库 claim-check、报告对象键 |
| `blob` | MinIO 封装;`cli==nil` 即降级回退本地盘,不阻断启动 |
| `secrets` | **AES-256-GCM**,密钥由 `SUNDYNIX_SECRET_KEY` 经 SHA-256 派生;密文 `enc:1:`+base64url(nonce‖ct);无前缀原样返回(兼容旧明文) |
| `otelx` | OTel 启动器(W3C 传播器 + OTLP/HTTP → Jaeger)+ 带 trace_id 的结构化 slog |
| `prompts` | 受管提示词注册表(内置默认 + `PROMPTS_FILE` 覆盖 + 控制面热下发) |
| `health` | 给无 HTTP 端口的服务起极小探针服务 |
| `cmd/devnats` | 内嵌 nats-server,本地开发免装 |
---
## 4. NATS 总线契约
### 4.1 任务主链(JetStream 持久)
| 流 / Subject | 值 | 用途 |
|---|---|---|
| `SUNDYNIX_TASKS` | `sundynix.tasks.` | 任务队列,消费者 `dispatchers`(队列组负载均衡) |
### 4.2 回流(core NATS,即时不持久)
| Subject | 用途 |
|---|---|
| `sundynix.streams.` | Token 流,结束用消息头 `X-Stream-End: 1` |
| `sundynix.exec.` | 结构化执行节点事件(seq/node/kind/phase/label/ms) |
| `sundynix.voice.event.` | JARVIS 语音事件(navigate / announce) |
### 4.3 工具调用(request-reply + 队列组)
| Subject | 队列组 | 提供方 |
|---|---|---|
| `sundynix.tools.go.` | `mcp-go-workers` | mcp-go |
| `sundynix.tools.py.` | `mcp-py-workers` | mcp-py |
| `sundynix.tools.platform.` | `platform-tools-workers` | **gateway 自己** |
| `sundynix.local.exec.` | — | 桌面端 runner(无订阅 = 离线,明确报不可用) |
### 4.4 回写(JetStream 持久 + 落库幂等 → at-least-once 重投安全)
| 流 | 消费者 | Subject | 用途 |
|---|---|---|---|
| `SUNDYNIX_STATUS` | `gateway-status` | `sundynix.status.task` | 任务生命周期状态 |
| `SUNDYNIX_USAGE` | `gateway-usage` | `sundynix.usage.task` | token 用量(计费凭据) |
| `SUNDYNIX_EVAL` | `gateway-eval` | `sundynix.eval.task` | 自动评测结果 |
| `SUNDYNIX_APPROVALS` | `approval-resumers` | `sundynix.approval.` | HITL 审批决定(抗离线) |
| `SUNDYNIX_INGEST` | `ingest-workers` | `sundynix.ingest.` | 入库作业队列(claim-check:大文件先落 MinIO,消息只带 StageKey) |
> ⚠️ 状态流 subject **必须在 `sundynix.tasks.>` 之外**,否则会被任务流捕获成「幽灵任务」自我放大。
**KV**:`SUNDYNIX_CHECKPOINTS`(TTL 24h)—— 键 `task_id` 存 compose checkpoint,键 `pending:task_id` 存 resume 记录。
### 4.5 控制面
`sundynix.config..get` / `.updated`(kind = chat / embedding / voice)· `sundynix.prompts.get` / `.updated` · `sundynix.health.dispatcher`(心跳)。网关侧共用队列组 `gateway-workers`。
### 4.6 Task.Meta 约定
`user_id` · `tenant_id` · `session_id` · `safety_check` · `token_budget` · `model_profile`(=`voice`) · `intent`(=`report`) · `topic` · `kb`
状态机:`submitted → running → done|failed|timeout`,HITL 分支 `waiting → running|rejected`。
评测分级:`ok`(≥0.75) / `warn`(0.5~0.75) / `poor`(<0.5)。
---
## 5. 编排引擎
### 5.1 执行路径
`Orchestrator.Handle` → `executeGraph` → `runComposeGraph` → **`execComposeGraph`**(`internal/eino/compose_compiler.go`,唯一引擎):
1. `dsl.Parse` + `dsl.Compile` → 建 `board`(黑板,进 compose 本地状态)
2. 无图/空图 → 退化为 compose 单轮对话
3. 建 `compose.Graph`:**边只传占位信号 `flowSignal`,真实数据全走黑板**(注册 no-op merge 支持 fan-in);DAG 触发让无依赖节点自动并行
4. `branch` 节点走 `AddBranch`;`approval` 节点在有 checkpoint 后端时编译为 `approvalInterruptLambda`(`compose.Interrupt` 落盘并释放 goroutine)
5. 编译失败 → 降级回自研 `graph.go`(已退役,保留作安全网)
### 5.2 节点类型(12 种)
| kind | 作用 |
|---|---|
| `input` | 输入/查询 |
| `memory` | 记忆召回 |
| `retriever` | RAG 检索 |
| `tool` | 显式工具调用 |
| `agent` | LLM 推理;`autonomous: true` → 走 **ReAct 自主工具循环** |
| `coordinator` | 多智能体:agent-as-tool 派给专家 + 并行 fan-out + 综合 |
| `aggregate` | 汇聚 |
| `approval` | **HITL 人工审批**(中断落盘) |
| `render` | 渲染(报告等) |
| `map` | 并行 fan-out |
| `output` | 输出 |
| `branch` | 条件分支(建图阶段单独处理,支持 else/default 兜底) |
### 5.3 ReAct 自主工具
`react_agent.go` 用 Eino `react.NewAgent`,工具集经 `list_tools` 从**三个提供方**动态发现(mcp-go / mcp-py / gateway platform)。
- `MaxStep` 默认 12(`REACT_MAX_STEP` 可调)
- `StreamToolCallChecker` 扫描**整段流**判定工具调用(默认只看首片段,deepseek 等常先吐文本再给 tool call 会漏判)
- `inject` 参数(user_id / session_id / task_id / kb / tenant_id)服务端运行时绑定,**不暴露给模型**
- 工具可自报 `timeout_sec` 突破默认 3s(本地执行类要等用户点确认框)
### 5.4 平台工具族(gateway 提供,11 个)
平台操作的权威(提交关卡、归属校验、计费)都在 gateway,工具就长在权威所在地。
| 工具 | 作用 |
|---|---|
| `platform_recent_tasks` / `platform_task_status` | 查任务列表 / 单任务状态与输出 |
| `platform_gen_report` | 派发报告任务(**走 preflightCore 同一关卡**:预算/暂停/积分硬拦截) |
| `platform_open_view` | 切换客户端界面(navigate 白名单) |
| `platform_schedule_create` / `_list` / `_cancel` | 定时任务增删查 |
| `local_list_dir` / `local_read_file` | 看/读用户电脑(只读) |
| `local_write_file` / `local_exec` | 写文件 / 执行命令(三道闸,见 §8.3) |
**安全铁律**:一律 `inject user_id` + 服务端归属校验(越权查他人任务一律回「不存在」,不泄露存在性);会烧钱的提交必须过 `preflightCore`。
### 5.5 harness 治理层
| 组件 | 作用 |
|---|---|
| `budget.go` | token 预算估算(CJK≈1 tok/字),触顶中止整图 |
| `circuitbreaker.go` | 三态熔断(阈值 3 次连续失败 / 冷却 20s / 半开 1 次探测) |
| `eval.go` | 规则 + LLM-as-judge 评测,异步 off 热路径;低分触发自动纠偏 |
| `jailbreak.go` | Tier2 越狱分类(severity ≥0.7 才拦) |
| `output.go` | 发射层逐片脱敏(sk-\* / AKIA\* / JWT / Bearer),跨分片不漏检 |
---
## 6. LLM 治理
```
cachingModel(输出缓存)
└─ failoverModel(主备链,每模型独立熔断器)
├─ 主模型(active)
└─ 备用模型(其它 enabled chat 模型)
```
- **双池**:工作主力 `pool`(chat) + JARVIS 语音 `voicePool`(voice),语音池空则**透明回落**工作池
- **热更新**:经 NATS 配置控制面(`SubscribeModelConfigUpdated` + 启动时 `FetchModelConfigWithRetry`)
- **接入方式**:`eino-ext/openai`,OpenAI 兼容协议(当前用 DeepSeek 在线 API,不拉本地 Ollama)
- 单次请求超时 120s;`LLM_FORCE_STUB=1` 走降级桩(压测用)
- 暴露 `ModelHealth`(provider/model/role/state/fails)供 admin 展示
- **已知局限**:Stream 仅在建流同步报错时切备,已开始回流 token 的中途失败不切
- **输出缓存**:`respCache` TTL 60s(`LLM_CACHE_TTL_S`,0=关)、容量 512(`LLM_CACHE_MAX`),key = sha256
**Prompt 版本化**:`shared/prompts` 内置默认 → `PROMPTS_FILE` 覆盖 → `sundynix_prompt` 表 + admin 热切换(含 diff 与撤销),不重编译即可改。
Known key:`graph.extract` · `eval.quality` · `eval.refine` · `guard.jailbreak` · `coordinator.lead` · `memory.extract`
---
## 7. 数据存储
### 7.1 中间件职责
| 中间件 | 版本 | 用途 |
|---|---|---|
| NATS + JetStream | 2-alpine(max_payload 8MB) | 统一总线(见 §4) |
| PostgreSQL | 16-alpine | 主业务库,29 张表 |
| Redis | 7-alpine | 会话 / 限流 / 任务输出缓存(TTL 48h) / 扫码 ticket;有内存降级兜底 |
| Milvus | v2.4.13 standalone | RAG 向量路 |
| etcd | v3.5.14 | 仅 Milvus 元数据依赖 |
| MinIO | RELEASE.2023-03-20 | 文档正文 blob、报告源/产物(bucket `sundynix-docs`)+ Milvus 段存储 |
| Neo4j | 5-community | RAG 图谱路(三元组) |
| Jaeger | all-in-one 1.60 | OTLP 收集 + trace UI |
| **Bleve** | 进程内库(非容器) | RAG 全文路,scorch 落盘 `BLEVE_PATH` —— **唯一需要给 mcp-go 挂持久卷的原因** |
### 7.2 数据表全清单(29 张)
命名:`TablePrefix: sundynix_` + `SingularTable: true`。公共基类 `BaseModel` = 雪花字符串 id + created/updated + 软删。
| # | 模型 | 表 | 职责 |
|---|---|---|---|
| 1 | `User` | `sundynix_user` | 平台用户 |
| 2 | `Task` | `sundynix_task` | 一次提交的编排任务(DSL);业务 id `task_xxx` 单列供 NATS subject |
| 3 | `Eval` | `sundynix_eval` | 自动评测结果,按 task_id upsert |
| 4 | `LLMModel` | `sundynix_model` | 模型后端配置,每 kind 同时刻仅一条 Active |
| 5 | `KB` | `sundynix_kb` | 知识库,`(space_id,name)` 唯一,分区键 `space_id/name` |
| 6 | `Doc` | `sundynix_doc` | 入库文档主表(Obsidian 式文库) |
| 7 | `Agent` | `sundynix_agent` | 编排定义,`(space_id,name)` 唯一 |
| 8 | `DocLink` | `sundynix_doc_link` | `[[双链]]` 索引,供反链/关系图 |
| 9 | `Pricing` | `sundynix_pricing` | 模型计价(每 1K token 输入/输出单价) |
| 10 | `Prompt` | `sundynix_prompt` | 受管提示词版本,`(key,version)` 唯一 |
| 11 | `AuditLog` | `sundynix_audit_log` | 敏感操作留痕,只增不改 |
| 12 | `GuardrailEvent` | `sundynix_guardrail_event` | 输入护栏命中事件 |
| 13 | `Tenant` | `sundynix_tenant` | 租户(计费/隔离单位),含物化余额列 |
| 14 | `TenantMember` | `sundynix_tenant_member` | 用户↔租户成员关系 + 角色 |
| 15 | `TenantInvite` | `sundynix_tenant_invite` | 可复用邀请码(扫码入组) |
| 16 | `Space` | `sundynix_space` | 共享工作区(资源容器) |
| 17 | `SpaceMember` | `sundynix_space_member` | 空间成员 + 空间内角色 |
| 18 | `UsageEvent` | `sundynix_usage_event` | 用量明细,task_id 唯一 → 幂等 |
| 19 | `CreditLedger` | `sundynix_credit_ledger` | 积分账本(append-only),余额 = SUM |
| 20 | `UsageRollup` | `sundynix_usage_rollup` | 用量按租户/天聚合快照 |
| 21 | `Setting` | `sundynix_setting` | 平台级键值配置 |
| 22 | `CreditPack` | `sundynix_credit_pack` | 积分包商品 |
| 23 | `PaymentOrder` | `sundynix_payment_order` | 充值订单(兑换码也写一行) |
| 24 | `RedeemCode` | `sundynix_redeem_code` | 兑换码 |
| 25 | `SubscriptionPlan` | `sundynix_sub_plan` | 订阅套餐 |
| 26 | `Subscription` | `sundynix_subscription` | 已购订阅(到期即 expired,不自动续) |
| 27 | `UserJarvis` | `sundynix_user_jarvis` | 每用户 JARVIS(名字/人设/自带火山 key,密文入库) |
| 28 | `Schedule` | `sundynix_schedule` | 定时任务 |
| 29 | `SchemaMigration` | `sundynix_schema_migration` | 已应用的版本化迁移记录 |
### 7.3 迁移机制
整段迁移在 **PG advisory lock**(key `20260721`,60s 超时兜底)内串行:
`legacy(默认关) → AutoMigrate(29 模型) → 版本化 schemaSteps`
只有 AutoMigrate 失败才返回 error;版本化步骤失败只记日志下次重试。
**4 个版本化步骤**:账本 grant/adjust 的**部分唯一索引**(支付入账与退款的幂等闸)· 回填租户物化余额 · 微信 openid 唯一索引。
部分唯一索引不写在 struct tag 里 —— AutoMigrate 早于回填会撞车,必须回填后显式建。
破坏性 legacy 迁移需 `ALLOW_LEGACY_SCHEMA_MIGRATION=1` 显式开启(雪花 id 改造、双链改按 Doc.ID 关联)。
---
## 8. 关键链路
### 8.1 任务提交 → 编排 → 回流
```mermaid
sequenceDiagram
participant C as 桌面端
participant G as gateway
participant N as NATS
participant D as dispatcher
participant M as mcp-go
participant L as LLM
C->>G: POST /tasks (DSL)
G->>G: 鉴权 → 租户/空间上下文 → 限流 → 护栏
G->>G: preflight:预算/暂停/计费租户/积分硬拦截
G->>G: launch:落库 + 起录像器
G->>N: publish sundynix.tasks (JetStream)
G-->>C: 202 task_id
C->>G: GET /tasks/:id/stream (SSE, token 走 query)
N->>D: 消费任务
D->>D: DSL 编译为 compose.Graph
loop ReAct 循环
D->>L: 推理(failover + 熔断 + 缓存)
L-->>D: tool_call
D->>N: request sundynix.tools.go
N->>M: 队列组分发
M-->>D: ToolResult
end
D-->>N: Token 流 sundynix.streams
N-->>G: 订阅回流
G-->>C: SSE 逐字推送
D->>N: status / usage / eval(JetStream 持久)
N->>G: 幂等落库
```
### 8.2 语音 JARVIS 全双工
```mermaid
sequenceDiagram
participant U as 用户
participant C as 桌面端
participant G as gateway
participant V as 火山 ASR/TTS
participant D as dispatcher
U->>C: 按住空格说话(PTT)
C->>G: WS 二进制帧:PCM 16k 上行
G->>V: 流式 ASR(X-Api-Key 鉴权)
V-->>G: 转写(部分/最终)
G-->>C: transcript
U->>C: 松开 → end
G->>G: trySubmit:转写 → 组 DSL → 同一提交关卡
G-->>C: task_id
G->>D: 提交任务(model_profile=voice → 走快模型)
D-->>G: Token 流
G-->>C: reply(打字机,早于音频)
G->>V: 攒句 → 双向流 TTS
V-->>G: PCM 24k
G-->>C: speaking + 音频帧 → tts_end
C->>U: 无缝播放
```
**要点**
- ASR 与 TTS 是**不同帧族**(ASR 简帧无事件号;TTS V3 事件族带 event/session/gzip)
- 下行**先订阅 token 流再建 TTS 会话** —— core NATS 无持久,订阅晚于产出会丢开头
- 客户端播放按 `nextStart` 预约到未来时刻,收到 `tts_end` 时**不能立即停**(合成远快于语速,停了只剩前几个字)
### 8.3 本地执行(JARVIS 操作用户电脑)
```mermaid
sequenceDiagram
participant D as dispatcher
participant G as gateway
participant R as 桌面 Go host
participant U as 用户
Note over R,G: 登录后注册:WS /local/runner
R->>G: 上线(携带授权目录白名单)
G->>G: 队列组订阅 sundynix.local.exec
D->>G: 调 local_exec(timeout_sec=160)
G->>R: WS 转发 tool + args
R->>R: 闸一:独立开关校验
R->>R: 闸二:硬黑名单(14 条正则,命中不弹框直接拒)
R->>U: 闸三:原生确认框(默认按钮=拒绝,60s 无应答即拒)
U-->>R: 允许 / 本次会话都允许
R->>R: 沙箱内执行(cwd 锁授权目录,60s 超时,输出 16KB 截断)
R-->>G: 结果
G-->>D: ToolResult
```
**超时链必须外松内紧**:dispatcher 160s > gateway 150s > runner 转发 140s > 桌面端(审批 60s + 执行 60s)。
任一层比内层短,用户还在看确认框就会被判超时。
---
## 9. 功能实现状态
图例:**✅ 已完成(live 验证)** · **🟡 部分** · **❌ 未做**
### 9.1 多租户 / 空间 / RBAC
| 功能 | 状态 |
|---|---|
| Tenant/TenantMember + 注册自动建默认租户 + 存量回填 | ✅ |
| **gorm 租户隔离插件**(查询/更新/删除自动加 tenant_id,创建自动填) | ✅ |
| 租户角色 RBAC(owner/admin/member/viewer)+ 路由级校验 | ✅ |
| 租户邀请码(二维码扫码入组) | ✅ |
| Space 共享工作区(KB/Agent 按空间共享 + 空间角色 + 全员空间) | ✅ |
| 用户 role 字段 + 角色表(把 `RequireAdmin` 从白名单升级为角色校验) | ❌ |
| 用户管理接口(列举/禁用/改角色) | ❌ |
### 9.2 计量 / 计费 / 支付
| 功能 | 状态 |
|---|---|
| 计价配置 + usage_event 计量 + credit_ledger 账本 + daily rollup | ✅ |
| 余额硬拦截(`CREDIT_ENFORCE`) | ✅ |
| 支付渠道抽象 + 微信 Native(**真环境实测通过**) | ✅ |
| 兑换码 / 人工核销 | ✅ |
| 对账 + 退款(adjust 负分录 + 回退余额 + 审计) | ✅ |
| 订阅套餐(周期发放 + 到期失效) | ✅ |
| 发票 / Stripe | ❌ |
### 9.3 知识库 / RAG
| 功能 | 状态 |
|---|---|
| **三路混合检索**(Bleve 全文 + Milvus 向量 + Neo4j 图谱,RRF k=60 融合 + rerank) | ✅ |
| 中文分词修复(CJK bigram) | ✅ |
| 离线检索评测(recall@k / MRR,hybrid vs 单路) | ✅ |
| 大文件生产化(MinIO 正文 + 并发 embed + 窗口化图谱 + JetStream 持久队列,kill -9 续跑验证) | ✅ |
| KB 级联删事务化(三库 + MinIO 先删、PG 最后)+ MinIO 孤儿 GC | ✅ |
| Obsidian 式文库(Markdown + 双链 + 反链 + 关系图) | ✅ |
| 检索持久化治理 / 列表分页 | 🟡 |
| 多模态解析(MinerU/PaddleOCR) | 🟡 骨架,`mineru.py` 为桩 |
### 9.4 报告
| 功能 | 状态 |
|---|---|
| 报告编排(规划 → 分章并行 → 汇聚 → 存源) | ✅ |
| Word(.docx) 渲染(自建零依赖 OOXML) | ✅ |
| Markdown 导出 | ✅ |
| PDF 导出 | 🟡 走 webview 打印;后端原生 PDF 未做 |
| 分章 map 错误传播与汇总 | ✅ |
### 9.5 记忆
| 功能 | 状态 |
|---|---|
| memory CRUD + Profile 表 | ✅ |
| P1 异步攒批 Consolidate(每 3 轮 LLM 对账 ADD/UPDATE/DELETE/NOOP + 软删) | ✅ |
| P2 Score(Recency + Importance) 排序 + 衰减 + top30 截断 | ✅ |
| P3 Relevance(语义相关性) | ✅ |
| 会话历史 history_get/append | ✅ |
### 9.6 编排引擎
| 功能 | 状态 |
|---|---|
| Eino Phase A/B/C/D 全部(组件 → ReAct → compose 全图 → FSM) | ✅ |
| compose 为唯一引擎(`graph.go` 已退役作降级网) | ✅ |
| HITL 人工审批中断(checkpoint 落盘 + NATS 决定回传 + 抗离线) | ✅ |
| 多智能体 coordinator(agent-as-tool + 定制 brief + 并行 fan-out + 专家超时) | ✅ |
| Branch else/default 兜底 · DSL 拓扑校验 · 工具动态发现 | ✅ |
| handoff / adk 可中断多智能体 | ❌ |
| 编译图缓存 | ❌ 判定为 premature(实测编译 ~13µs) |
| 审批 checkpoint 落盘失败重试(现只 log → 任务永卡 waiting) | ❌ |
### 9.7 模型治理
| 功能 | 状态 |
|---|---|
| 模型路由 + Fallback + 每模型三态熔断 | ✅ |
| 模型健康/熔断态 surface 到 admin | ✅ |
| 输出缓存 | ✅ |
| Prompt 版本化 v1(注册表)+ v2(DB 热切换 + diff + 撤销) | ✅ |
| 工作模型与 JARVIS 语音模型分离 + 用量按实际模型计量 | ✅ |
| Prompt 灰度 % A/B | ❌ |
### 9.8 评测 / 护栏
| 功能 | 状态 |
|---|---|
| 自动化评测(规则 + LLM 裁判,异步 off 热路径) | ✅ |
| 裁判校准 + 低分自动纠偏闭环(live 真触发) | ✅ |
| 输入护栏(注入检测 + 归一化 + 超大体拦截)+ 事件落库 | ✅ |
| 输出护栏(跨分片密钥脱敏) | ✅ |
| HITL 审批决定明细(理由)落库 | ❌ 现仅 who/when/status |
| 前端评测质量面板 | ❌ 后端 `/tasks/:id/eval` 已有 |
### 9.9 语音 / JARVIS 中枢
| 功能 | 状态 |
|---|---|
| 火山 ASR + 双向流 TTS 全双工(新版 API Key 鉴权) | ✅ |
| 语音触发任务(复用同一提交关卡) | ✅ |
| PTT 按住说话 + 打断 + 连续对话 + 打字机文本流 | ✅ |
| 每用户 JARVIS(名字/人设/自带豆包配置回落,语音不串主记忆) | ✅ |
| 全屏钢铁侠 HUD(接真实音频电平) | ✅ |
| **P1 平台工具族**(查任务/派报告,含越权拒绝与积分硬拦截验证) | ✅ |
| **P2 动作通道**(语音让界面切页,三层白名单) | ✅ |
| **P3 主动播报**(任务终态主动开口,正朗读则排队不抢麦) | ✅ |
| 声纹 / 唤醒词 / 音色克隆 / 多语种 / ASR-TTS failover | ❌ 本期不做 |
| P5 常驻 companion session | ❌ 暂缓(现靠 session history 串联已够用) |
### 9.10 本地执行
| 功能 | 状态 |
|---|---|
| **只读**:`local_list_dir` / `local_read_file` + runner 注册 + 沙箱(逃逸单测全拦) | ✅ |
| **能动的手**:`local_write_file` / `local_exec` + 三道闸(独立开关 + 14 条黑名单 + 原生审批框) | ✅ |
| 多目录白名单沙箱 + 空 path 自发现授权目录 | ✅ |
| 离线优雅降级(runner 不在线明确报不可用,不挂起) | ✅ |
| ToolPolicy 服务端策略下推 | 🟡 已有审批框 + 黑名单,下推未做 |
| **档 B**:agent 循环下沉客户端(内环不过网) | ❌ 有决策门,未做 |
| gateway LLM 代理端点(档 B 的地基) | ❌ |
### 9.11 定时任务
| 功能 | 状态 |
|---|---|
| `sundynix_schedule` + leader 锁 ticker(30s) + create/list/cancel 工具 | ✅ |
| 存自然语言指令,到点走同一关卡执行 + 主动播报 | ✅ |
| 先推进后提交防重复烧钱;停机错过的**不补跑** | ✅ |
### 9.12 可观测 / 运维
| 功能 | 状态 |
|---|---|
| Prometheus `/metrics`(路由模板低基数)+ 结构化日志 + X-Request-ID | ✅ |
| `/healthz` `/readyz` 探针 + 依赖聚合健康 | ✅ |
| **OTel 全链路**(otelgin + 跨 NATS traceparent 传播 → Jaeger) | ✅ |
| admin 观测面(overview/status/tasks/spaces/usage/evals/datasources/orders/审计/护栏) | ✅ |
| 检索试验台(跨租户 + 单路 mode 对比) | ✅ |
| panic 进 trace span · TTFT/token-s 指标 | ❌ |
| K8s / DB HA / TLS / DR 演练 | ❌(**例外:NATS 集群已落地**) |
### 9.13 客户端
| 端 | 状态 |
|---|---|
| desktop(编排画布 · ⌘K · SSE 轨迹 · 文库 · 知识图谱 · 记忆面板 · JARVIS HUD · 本地 runner · 服务器地址运行时可配) | ✅ |
| admin(官网 + 控制台,go:embed 进 gateway) | ✅ |
| web(租户自助:注册/组织/团队/账单) | ✅ |
| 前端测试 | 🟡 11 个测试文件,集中在 lib 纯函数;视图层基本不测 |
### 9.14 ⚠️ 已知的文档记账偏差
以下 4 处**文档与代码不符,一律以代码为准**:
1. `PROGRESS.md` 停在 2026-06-19,其中「计费未做」「多租户未做」「Relevance 待 P3」均已被后续代码推翻。
2. `DEPTH_ROADMAP.md` 进度表写「T4 后端做实 0/6 组」,但正文里 T4.A/B/E 大量条目已勾 ✅。
3. `DEPTH_ROADMAP.md` Tier 3 写「NATS 集群未做」,实际三节点集群已在 128 落地。
4. `PAYMENT_DESIGN.md` 标题写「不做订阅」,但订阅套餐全套(表 + ticker + admin 页)已实现。
---
## 10. 安全与治理
### 10.1 中间件链(顺序有意义)
```
Recovery → otelgin → RequestID → Observe → cors → Auth → TenantContext → SpaceContext → RateLimit → Guardrail
```
**Auth 必须前置于 RateLimit** —— 否则无法按用户限流(企业网多人共享出口 IP 会互相拖累)。
### 10.2 鉴权
- **JWT 无状态**(`internal/auth`),owner = 雪花 user.id;生产默认密钥 fail-fast
- `Auth()` 非阻断解析 → `RequireAuth()` / `RequireAdmin()`(当前为 `ADMIN_USER_IDS` 白名单)
- **`AuthFromHeaderOrQuery()`**:WS 与 SSE 带不了 Bearer 头,走 `?token=` —— 用于 `/tasks/:id/stream`、`/tasks/:id/exec`、`/kb/ingest/:id/stream`、`/reports/:id/export`、`/voice/stream`、`/local/runner`
- 注册/登录各带 10/min 限流;微信公众号扫码登录独立通道
- **支付回调例外**:`/billing/callback/:channel` 无 Bearer,渠道验签是唯一的门
### 10.3 密钥加密
`shared/secrets`:**AES-256-GCM**,密钥由 `SUNDYNIX_SECRET_KEY` 经 SHA-256 派生 32 字节;密文格式 `enc:1:` + base64url(nonce‖ciphertext),带版本前缀便于轮换。
**全链路**:gateway 保存时 Encrypt 落 PG → 密文原样过 NATS → dispatcher/mcp-go 在 bus 层 Decrypt。**api_key 在磁盘与线缆上都非明文**,仅构建 LLM 客户端时内存短暂还原。三服务的 `SUNDYNIX_SECRET_KEY` 必须一致。
微信支付商户私钥不落库不进镜像 —— 宿主目录只读挂载。
### 10.4 租户隔离
`store/tenant_scope.go`:`tenantScopedMarker` 空接口(小写方法,只有本包模型能标记)+ 4 个 gorm callback(query/update/delete 前自动加 `tenant_id = ?`,create 前自动填)。
**两个必须记住的旁路**:系统级读(admin 聚合)与跨租户写(对账)都要 `WithoutTenant(ctx)` —— 漏了会出回归或对账崩。
### 10.5 限流与审计
- **限流**:Redis 为主后端 + **进程内固定窗口 fail-safe 兜底**(Redis 挂时不再 fail-open,改宽松本地限流);已认证按 uid、未认证按 IP
- **审计**:`Audit(db)` 只审计变更类(POST/PUT/DELETE/PATCH),best-effort 不拖垮主流程;挂在整个 `/admin` 组、prompt 激活/撤销、HITL 审批、租户成员变更、充值兑换
- **护栏事件**:命中落 `GuardrailEvent`(actor/kind/reason/signals/path/ip)→ admin 审计页
---
## 11. 客户端形态
**三个独立产品面,绝不合并**:
| 端 | 定位 | 技术栈 | dev 端口 | 路由 |
|---|---|---|---|---|
| desktop | **用户工作产品** | Wails v3.0.0-alpha2.117 + React 19 + TS 5.6 + Tailwind 3.4 + React Flow 12 | 9245 (wails3) / 5173 (纯 vite) | 无路由,`useState` |
| admin | 官网(`/`) + 平台超管控制塔(`/admin`) | React 19 + react-router-dom 7 | 5174 | **BrowserRouter** |
| web | 租户客户自助柜台 | React 19 + react-router-dom 7 | 5175 | **HashRouter**(纯静态托管即可深链) |
**desktop 页面**(`ViewKey`):`home` 工作台 · `studio` 编排 · `kb` 知识库 · `runs` 运行 · `report` 报告 · `memory` 记忆 · `usage` 用量
**admin 页面**(17 条路由):仪表盘 / 服务状态 / 任务观测 / 自动评测 / 审计安全 / 模型配置 / 登录设置 / 语音设置 / 数据源RAG / 提示词 / 支付(配置·订阅·订单对账) / 租户用户 / 微信用户 / 空间 / 安全护栏
三端共用**自建 UI 组件**(`src/ui/`:Badge/Button/Card/Dialog/Input/Table/Tabs/Toast + cn),**未引任何组件库**。
测试统一 Vitest 4 + jsdom + Testing Library。
---
## 12. 部署拓扑
### 12.1 三机内网生产
```mermaid
flowchart LR
USER["用户桌面端"]
FRP["frp 映射"]
subgraph M132["192.168.100.132 · 应用机"]
GW["gateway 3000→8080
内嵌 admin UI"]
DP["dispatcher"]
MG["mcp-go"]
MP["mcp-py"]
end
subgraph M128["192.168.100.128 · 基建机 + CI runner"]
N1["NATS 三节点集群
4222/4223/4224
REPLICAS=3"]
PG2[("PostgreSQL")]
RD[("Redis")]
ML[("Milvus + etcd")]
NJ[("Neo4j")]
JG["Jaeger"]
end
M126[("192.168.100.126
业务 MinIO
bucket sundynix-docs")]
TX["162.14.122.200
微信 token 中控
静态 IP"]
USER --> FRP
FRP --> GW
GW --> N1
DP --> N1
MG --> N1
MP --> N1
GW --> PG2
GW --> RD
GW --> M126
MG --> ML
MG --> NJ
MG --> M126
GW --> JG
DP --> JG
GW --> TX
```
**要点**
- **对外只暴露 132:3000**(gateway:API + admin UI + 语音 WS + 本地 runner WS),其余全部内网
- NATS 三节点 `cluster.name: sundynix-cluster`,routes 互指 6222;`NATS_STREAM_REPLICAS=3` 走 Raft quorum;三节点 `max_payload: 8MB` 必须一致
- 128 上的 Redis/Milvus/NATS **无认证**,靠防火墙只放行 132/126 网段
- 132 只读挂载两个宿主目录:微信支付商户私钥、微信域名校验文件(不进镜像、不进 git)
- 备份 `scripts/backup.sh`(PG/Neo4j/Milvus/MinIO 卷),建议 cron 每日异机存档
### 12.2 单机一体化
`docker-compose.prod.yml` 一条命令拉起应用 4 服务 + 全套基建(要求 Docker 24+/Compose v2、~8GB 内存)。
基建端口**一律不对宿主暴露**,只留 gateway 与可选 Jaeger UI。密钥用 YAML 锚点 `${SUNDYNIX_SECRET_KEY:?}` 强制 .env 必填。
### 12.3 密钥模型
| 类别 | 内容 | 存放 |
|---|---|---|
| 引导密钥 / 基建凭据 | `SUNDYNIX_SECRET_KEY` · `JWT_SECRET` · PG/Neo4j/MinIO 密码 | `.env`,部署时填一次 |
| 业务模型 key | LLM api_key · 语音 key · 支付配置 | **不进 .env**,登录 admin 配,AES 加密存 PG |
丢失主密钥 = 已存业务 key 全部失效。
首次管理员:注册第一个账号 → 取 user id → 填 `ADMIN_USER_IDS` → 重启 gateway。
---
## 13. CI / CD
### 13.1 GitHub Actions(质量门,push main + PR)
| Job | 内容 | 红门 |
|---|---|---|
| `go` | 4 模块 `build + vet + test -race` | ✅ 一票否决 |
| `lint` | golangci-lint × 4 模块,`only-new-issues`(存量约 42 处不拦) | ✅ 仅新问题 |
| `security` | `govulncheck`(advisory 不阻断)+ **`gitleaks` 扫提交历史(命中即失败)** | 部分 |
| `web` | 三前端 `npm ci` + `tsc --noEmit` + `vitest` | ✅ |
| `desktop` | macOS runner,`GOWORK=off`,先出前端产物供 go:embed | ✅ |
| `py` | Python 3.11 pytest(含沙箱守卫测试) | ✅ |
Go 1.25 / Node 20。所有 job 带 `if: !contains(github.server_url, 'sundynix.cn')` 避免内网 Gitea 误跑。
### 13.2 Gitea Actions(内网真实 CD)
push main → 128 runner:**不用 `actions/checkout`**(内网连不上 github.com,改 `git init + fetch --depth 1`)→ 构建 4 镜像 → `docker save | gzip` scp 到 132 → `docker load` + `up -d --no-build` → **健康检查门**(循环 20 次 curl `/healthz`,失败打日志并 exit 1)。
132 上的 `.env` 手工预放、**部署绝不覆盖**。
> ⚠️ **CD 无任何测试门** —— 测试只在 GitHub 侧跑,内网推送直接部署。
### 13.3 Release
tag `v*` → wails3 构建 macOS universal(lipo 合并)+ Windows amd64 → GitHub Release。旧版 App 启动查 `/releases/latest` 提示更新。
---
## 14. 技术栈总表
| 领域 | 选型 |
|---|---|
| 后端语言 | Go 1.25(4 模块 workspace)+ Python 3.11(算法工具) |
| Web 框架 | Gin v1.12.0 |
| 编排引擎 | **CloudWeGo Eino v0.9.12** + eino-ext/openai |
| 消息总线 | NATS 2 + JetStream(持久流 + KV) |
| 主库 | PostgreSQL 16 + GORM v1.31.1(雪花 id + 软删 + 租户插件) |
| 缓存 | Redis 7(+ 进程内降级) |
| 向量 | Milvus v2.4.13 |
| 全文 | Bleve v2.4.2(进程内,CJK bigram) |
| 图谱 | Neo4j 5-community |
| 对象存储 | MinIO(minio-go v7.2.0) |
| LLM | OpenAI 兼容协议(DeepSeek 在线 API) |
| 语音 | 火山引擎豆包 · 流式 ASR + 双向流 TTS v3 |
| 可观测 | Prometheus + OpenTelemetry v1.44 + Jaeger 1.60 |
| 桌面端 | Wails v3.0.0-alpha2.117(Go host + WKWebView) |
| 前端 | React 19 + TypeScript 5.6 + Vite 5 + Tailwind 3.4 + React Flow 12 |
| 前端测试 | Vitest 4 + jsdom + Testing Library |
| 支付 | 微信支付 APIv3(Native 扫码) |
| 密钥 | AES-256-GCM(`enc:1:` 版本化密文) |
---
## 15. 已知缺口
按优先级归类,均为**明确未做**而非遗漏:
**架构演进**
- 本地 agent 档 B(循环下沉客户端,内环不过网)+ 其地基 gateway LLM 代理端点
- ToolPolicy 服务端策略下推
- JARVIS 常驻 companion session(现靠 session history 串联)
**治理补全**
- 用户 role 字段与角色表(`RequireAdmin` 仍是 env 白名单)
- HITL 审批决定理由落库
- 审批 checkpoint 落盘失败重试(现只 log,任务会永卡 waiting)
- 预算硬顶兜底(budget ≤0 即无限)
**生产硬化(Tier 3,等真实流量)**
- DB HA · K8s 编排 · TLS 终止 · DR 演练 · 备份自动化
- panic 进 trace span · TTFT/token-s 细粒度指标
**产品功能**
- 报告后端原生 PDF(现走 webview 打印)
- 多模态文档解析去桩(MinerU/PaddleOCR)
- Prompt 灰度 A/B
- 前端评测质量面板(后端接口已有)
- 语音:唤醒词 / 声纹 / 音色克隆 / ASR-TTS failover
**文档债**
- `architecture.md`(小写)是历史重复文件,内容早于本文,建议删除或改为指向本文的跳转
- `PROGRESS.md` / `DEPTH_ROADMAP.md` 汇总表需按 §9.14 校正