Files
sundynix-agentix/production_readiness.md
Blizzard 218fba559c feat(observability): slog 日志带 trace_id,与链路双向互跳
新增 sundynix-shared/otelx/slog.go:traceHandler 包装 slog.Handler,凡 ctx 有
活跃 span 的 slog.InfoContext(ctx,...) 自动注入 trace_id/span_id;SetupSlog(服务名)
装全局 JSON slog(service 标签 + LOG_LEVEL 控级)并设默认;TraceID(ctx) 辅助取 hex。

- 三个服务 main 启动调 otelx.SetupSlog。
- gateway 访问日志 Observe() 改用 slog.InfoContext(c.Request.Context(),...)(删旧
  accessLogger)→ 每条 HTTP 日志带 trace_id。
- dispatcher orchestrator.Handle 的 received/done/error 改 ctx-aware slog → 任务
  执行日志带 trace_id。
- otelx 单测 5 例(注入/无 span 不注入/With() 后仍生效/级别解析)。
- production_readiness.md 1.1:可观测性三件套(metrics+logs带trace_id+traces)闭环。

验证:dispatcher「task done」日志 trace_id 拿去 Jaeger /api/traces/<id> 命中同一条
11 span/3 服务链路;gateway 访问日志亦带同一 trace_id。四模块 build+vet+test 全绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 12:41:33 +08:00

678 lines
30 KiB
Markdown
Raw Permalink 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.
# sundynix-agentix · 工业生产级演进蓝图
> 基于对当前代码库的深度审计(6 个服务模块 + 共享层 + 基础设施),从 8 个维度系统梳理"从高完成度 MVP 到工业生产级"还需引入的能力。
---
## 当前基线评估
在分析差距之前,先盘点**已有的生产级基因**(这些是优势,不需要从零开始):
| ✅ 已有能力 | 现状 |
|---|---|
| Prometheus 指标 | Gateway 已埋 `sundynix_http_requests_total` / `duration` / `in_flight` 三个核心指标 ([observability.go](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/sundynix-gateway/internal/middleware/observability.go)) |
| 结构化访问日志 | Gateway 已用 `slog.JSONHandler` 输出包含 request_id/method/route/status/latency 的 JSON 日志 |
| Request ID 透传 | `X-Request-ID` 生成 + 上下文注入已实现 |
| 熔断降级 | Dispatcher 有完整的三态熔断器(Closed → Open → HalfOpen([circuitbreaker.go](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/sundynix-dispatcher/internal/harness/circuitbreaker.go)) |
| 输入护栏 | 正则检测提示词注入 + 超大请求体拦截 ([guardrail.go](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/sundynix-gateway/internal/guardrail/guardrail.go)) |
| 输出护栏 | 流式脱敏疑似密钥/令牌 ([output.go](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/sundynix-dispatcher/internal/harness/output.go)) |
| LLM 自动评测 | 规则 + LLM-as-judge 双路评分 ([eval.go](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/sundynix-dispatcher/internal/harness/eval.go)) |
| CI/CD 基础 | GitHub Actions CIGo build+vet+test / 前端 tsc / Python sandbox test+ ReleaseWails 跨平台构建)|
| 限流 | Redis 会话级 IP 限流 120/min ([middleware/guardrail.go](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/sundynix-gateway/internal/middleware/guardrail.go#L39-L51)) |
| 安全沙箱 | Python Code Interpreter 有 Docker 隔离(禁网/non-root/丢 cap/限内存 CPU PID/只读根/tmpfs+ AST 静态守卫 |
| 管理员权限 | RequireAdmin 中间件 + 生产模式强制显式配置 `ADMIN_USER_IDS` |
---
## 一、可观测性 (Observability)
> **目标**:任何线上问题在 5 分钟内能定位到根因节点。
### 1.1 分布式链路追踪 (Tracing) — ✅ 已实现
**已落地**OpenTelemetry 全链路追踪,一次任务从 Gateway → NATS → Dispatcher → MCP 工具的调用链在 Jaeger 里呈现为一棵 span 树。
- 启动器 `sundynix-shared/otelx`:各服务 main 调 `otelx.Init(ctx, "服务名")`OTLP/HTTP 导出到 `OTEL_EXPORTER_OTLP_ENDPOINT`(默认 `localhost:4318`docker 里的 Jaeger);`OTEL_SDK_DISABLED=true` 整体关闭导出(仍保留传播器)。Jaeger UI: `http://localhost:16686`
- **HTTP 入口**gateway 挂 `otelgin` 中间件,每个请求一个 server span(链路根 + 提取上游 traceparent)。
- **NATS 跨进程传播**(关键):`sundynix-shared/bus``PublishTask`/`CallTool` 把 W3C traceparent 注入消息头,`ConsumeTasks`/`ServeTool` 抽出续上——这是链路能跨总线连成一棵树的核心。
- **Eino 图埋点**`task.execute` → 每个 `node.<kind>``tool.call`/`tool.serve`(跨服务成对)→ `llm.stream`/`llm.generate`,层级与 ExecEvent 对齐。
- 实测一次「input→retriever→agent」任务出 14 span / 3 服务,瓶颈(kb_search 692ms、llm 1597ms)一眼可见。
- **日志 ↔ 链路互跳**`otelx.SetupSlog(服务名)` 安装链路感知的全局 slogJSON + service 标签),`traceHandler` 让任意 `slog.InfoContext(ctx,...)` 自动带 `trace_id`/`span_id`。gateway 访问日志、dispatcher 任务生命周期日志均已带 trace_id——Jaeger 里拿 trace_id 即可过滤日志,反之从报错日志跳回链路。实测一致命中。
> Prometheusmetrics+ sloglogs,带 trace_id+ OTeltraces)= 可观测性三件套已闭环。下一步可补:mcp-py 接入、采样策略、legacy log.Printf 渐进迁移到 ctx-aware slog。
**实现细节(原规划,已照此落地)**
```
┌─────────────────────────────────────────────────────────────────┐
│ OpenTelemetry Tracing │
│ │
│ Gateway NATS 消息头 Dispatcher MCP Tools │
│ ┌────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐ │
│ │ Span A │───▶│ W3C Ctx │────▶│ Span B │──▶│ Span C │ │
│ │(HTTP) │ │(Header) │ │(图编排) │ │(工具调用)│ │
│ └────────┘ └──────────┘ └────────────┘ └──────────┘ │
│ │
│ → 导出到 Jaeger / Tempo │
└─────────────────────────────────────────────────────────────────┘
```
| 组件 | 方案 | 说明 |
|---|---|---|
| **SDK** | `go.opentelemetry.io/otel` | Go 标准 OTel SDK |
| **Gin 自动埋点** | `otelgin` 中间件 | 替代/补充现有 Observe(),每个 HTTP 请求自动创建 span |
| **NATS 跨进程透传** | 在 NATS 消息 Header 中注入 `traceparent` (W3C TraceContext) | bus.PublishTask / ConsumeTasks 双端抽 inject/extract |
| **Eino 图节点埋点** | 每个节点 (agent/retriever/tool/branch) 创建 child span | 与现有 ExecEvent 对齐,自动关联 |
| **后端** | Jaeger (开发) / Grafana Tempo (生产) | Tempo 对接 Grafana 可视化 |
**关键收益**:一条 trace 覆盖 HTTP 入口 → DSL 解析 → NATS 发布 → Dispatcher 消费 → 记忆召回 → 图节点 1→2→3 → 工具调用 → Token 回流 → SSE 推送,任何环节慢/错一眼可见。
### 1.2 指标体系完善 (Metrics) — ⚠️ 部分
**现状**Gateway 有 3 个 HTTP 指标,Dispatcher/MCP 无指标。
**需补充**
| 新增指标 | 归属 | 说明 |
|---|---|---|
| `sundynix_tasks_total{status}` | Dispatcher | 任务处理计数(submitted/done/failed/timeout|
| `sundynix_task_duration_seconds` | Dispatcher | 任务端到端耗时直方图 |
| `sundynix_llm_requests_total{model,status}` | Dispatcher | LLM 调用计数 |
| `sundynix_llm_tokens_total{model,direction}` | Dispatcher | Token 用量(input/output)— **计费核心** |
| `sundynix_llm_latency_seconds{model}` | Dispatcher | LLM 响应延迟 (TTFT / 总耗时) |
| `sundynix_tool_calls_total{tool,status}` | MCP-Go/Py | 工具调用计数 |
| `sundynix_rag_search_duration_seconds{path}` | MCP-Go | 检索延迟(向量/全文/图谱/融合)|
| `sundynix_circuitbreaker_state` | Dispatcher | 熔断器当前状态 (gauge) |
| `sundynix_nats_msgs_total{subject}` | Shared | NATS 消息流量 |
**推荐栈**Prometheus + Grafana (已有 prometheus client),补 Grafana 仪表盘。
### 1.3 日志标准化 — ⚠️ 部分
**现状**Gateway 用 `slog` ✅,但 Dispatcher / MCP-Go / MCP-Py 仍用 `log.Printf` / `fmt.Printf`
**需引入**
| 变更 | 说明 |
|---|---|
| 全局切换到 `log/slog` (Go 1.21+) | 统一 JSON 格式,所有日志携带 `request_id` / `task_id` / `service` 字段 |
| 日志级别控制 | 生产 INFO,调试 DEBUG,按环境变量切换 |
| 关联 trace_id | 日志注入 `trace_id` + `span_id`Grafana Loki 可跳到对应 trace |
| Python 端 structlog | MCP-Py 引入 structlog,输出 JSON 格式,对齐 Go 端 |
| 日志采集 | Grafana Loki / ELK (Fluentd → Elasticsearch → Kibana) |
### 1.4 全栈观测仪表盘
```
Grafana Dashboard 体系:
├── Overview: 服务健康 / 请求量 / 错误率 / P99 延迟
├── LLM: Token 用量 / 模型延迟 / 成功率 / 成本估算
├── RAG: 入库速率 / 检索延迟 / 命中率 / 图谱规模
├── Tasks: 任务状态分布 / 排队深度 / 处理耗时
├── NATS: 消息吞吐 / 消费者延迟 / 积压深度
└── Alerts: 错误率>5% / P99>3s / 熔断打开 / 任务超时率>10%
```
---
## 二、安全加固 (Security Hardening)
### 2.1 密钥管理 — ⚠️ 部分(API Key 加密已落地)
**已实现**
-**LLM `api_key` 加密存储 + 端到端密文**`sundynix-shared/secrets`AES-256-GCM,密钥由 `SUNDYNIX_SECRET_KEY` 经 SHA-256 派生)。
网关保存时加密落库(`enc:1:` 前缀),密文经 NATS 原样下发,消费方(dispatcher/mcp-go)在 bus 层解密——
**磁盘与线缆上均无明文**,仅在构建 LLM 客户端时于内存短暂还原。历史明文行自动透传,下次保存即升级为密文。
生产模式(`APP_ENV=production` / `GIN_MODE=release`)下未设 `SUNDYNIX_SECRET_KEY` 直接 fatal`secrets.MustHaveKeyInProd`);
**各服务必须配置相同的密钥**
- ✅ JWT 签名密钥:生产强制 `JWT_SECRET`(未设即 fatal)。
**仍待引入**
- 配置文件中明文 DSN(含密码)→ 见下表
| 方案 | 说明 | 推荐 |
|---|---|---|
| **Vault / SOPS** | 进一步把 `SUNDYNIX_SECRET_KEY` 等根密钥托管、支持轮换 | HashiCorp Vault(生产首选)或 Mozilla SOPS(轻量) |
| **K8s Secrets + CSI** | 集群内密钥挂载 | Secrets Store CSI Driver + Vault Provider |
| **NATS TLS** | NATS 客户端↔服务端全链路 TLS,消息传输加密 | 配置 nats-server TLS + 客户端证书 |
| **PG SSL** | 数据库连接启用 `sslmode=require` | 当前 DSN 为 `sslmode=disable` |
| **环境变量注入** | 敏感配置一律不入代码/配置文件 | `.env.production` + Docker secrets |
### 2.2 认证与授权深化 — ⚠️ 部分
**现状**JWT 鉴权 ✅ + RequireAdmin 白名单 ✅,但:
- 无 Token 刷新机制(过期即登出)
- 无 RBAC 角色体系
- SSE/EventSource 无法带 Authorization 头(当前按 task_id 寻址,无鉴权)
**需引入**
| 能力 | 方案 |
|---|---|
| **Refresh Token** | JWT access_token (15min) + refresh_token (7d),静默续期 |
| **RBAC** | 角色模型:`admin / operator / user / viewer`PG 存角色表 |
| **SSE 鉴权** | 连接时带 `?token=xxx` query param → 验证后升级为 SSE(或 WebSocket 时握手带 token|
| **OAuth2 / SSO** | 企业客户需要 OIDC(接 KeyCloak / Auth0 / Azure AD|
| **API Key 鉴权** | 对外开放 API 时,支持 `X-API-Key` 鉴权(与 JWT 并行)|
### 2.3 网络安全 — ⚠️ 缺失
| 能力 | 当前 | 需引入 |
|---|---|---|
| **CORS** | 未见显式配置 | Gin CORS 中间件,生产严格限制 Origin |
| **HTTPS** | 无 TLS 终端 | 前置 Nginx/Caddy/Traefik 做 TLS 终端 + HTTP→HTTPS 重定向 |
| **mTLS** | 无 | NATS 集群间 + 服务间 mTLS(零信任网络)|
| **WAF** | 无 | 前置 Cloudflare / ModSecurity 或 Nginx WAF 规则 |
| **网络隔离** | docker-compose 共享网络 | K8s NetworkPolicy:前端→Gateway→NATS→后端 严格分网段 |
### 2.4 审计日志 — 🔴 缺失
**需引入**
```go
// 关键操作审计(写 PG sundynix_audit_log):
// - 用户登录/登出
// - 模型配置变更
// - 知识库创建/删除/入库
// - 任务提交/执行
// - 管理员操作(改角色/改限额)
type AuditLog struct {
ID string `gorm:"primaryKey;size:24"`
UserID string // 操作者
Action string // login / config_update / kb_ingest / task_submit / ...
Resource string // 操作对象
Detail string // JSON 详情
IP string
CreatedAt time.Time
}
```
---
## 三、高可用与容灾 (HA & Disaster Recovery)
### 3.1 NATS 集群 — 🔴 必须
**现状**:单节点 NATSdocker-compose),是**全局单点故障**。
**需引入**
```yaml
# NATS 3 节点集群 + JetStream Raft
nats-1:
image: nats:2-alpine
command: ["-c", "/etc/nats/cluster.conf", "--name", "nats-1"]
nats-2:
image: nats:2-alpine
command: ["-c", "/etc/nats/cluster.conf", "--name", "nats-2"]
nats-3:
image: nats:2-alpine
command: ["-c", "/etc/nats/cluster.conf", "--name", "nats-3"]
```
- JetStream 自带 Raft 共识,3 节点即可容忍 1 节点故障
- 客户端连接串改为 `nats://nats-1:4222,nats-2:4222,nats-3:4222`
- `bus.ConnectWithRetry` 已支持重连 ✅
### 3.2 数据库高可用
| 组件 | 当前 | 生产方案 |
|---|---|---|
| **PostgreSQL** | 单节点 | Patroni + etcd 主从自动切换;或云 RDS (高可用版) |
| **Redis** | 单节点 | Redis Sentinel (3 节点) 或 Redis Cluster |
| **Milvus** | Standalone | Milvus Cluster 模式(需独立 Pulsar/Kafka + 多 QueryNode|
| **Neo4j** | 单节点 Community | Neo4j Enterprise Causal Cluster3 Core + Read Replicas|
| **MinIO** | 随 Milvus | 独立 MinIO Distributed (4+ 节点 erasure coding) |
### 3.3 服务多副本与负载均衡
| 服务 | 扩容方式 | 注意事项 |
|---|---|---|
| **Gateway** | N 副本 + Nginx/Traefik 负载均衡 | SSE 连接需要 sticky session 或用 NATS 做中转 |
| **Dispatcher** | N 副本 | NATS 队列组(`ConsumerDurable`)已天然支持负载均衡 ✅ |
| **MCP-Go** | N 副本 | NATS `QueueSubscribe` 队列组已天然支持 ✅ |
| **MCP-Py** | N 副本 | 同上 ✅ |
> 项目架构上 Dispatcher/MCP 已经是无状态 + NATS 队列组,天然支持水平扩展,这是很大的优势。
### 3.4 Kubernetes 部署 — 🔴 必须
**现状**:仅 docker-compose(开发环境)。
**需引入**
```
deploy/k8s/
├── charts/
│ └── sundynix/
│ ├── Chart.yaml
│ ├── values.yaml # 统一配置(副本数/资源限制/密钥引用)
│ ├── values.prod.yaml # 生产覆盖
│ └── templates/
│ ├── gateway-deploy.yaml
│ ├── gateway-svc.yaml
│ ├── dispatcher-deploy.yaml
│ ├── mcp-go-deploy.yaml
│ ├── mcp-py-deploy.yaml
│ ├── ingress.yaml
│ ├── hpa.yaml # 水平自动扩缩
│ ├── pdb.yaml # Pod 中断预算
│ └── networkpolicy.yaml
├── kustomize/ # 或 Kustomize base + overlays
└── Dockerfile.* # 各服务容器镜像
```
**必须包含**
| K8s 资源 | 说明 |
|---|---|
| **Deployment** | 每个服务 ≥2 副本,滚动更新 |
| **HPA** | Gateway 按 CPU/请求量自动扩缩;Dispatcher 按 NATS 消费者延迟 |
| **PDB** | `minAvailable: 1`,升级时不中断 |
| **Resource Limits** | 每个 Pod 明确 requests/limitsCPU/内存)|
| **Liveness / Readiness** | Gateway: HTTP /health; Dispatcher: NATS ping; MCP: NATS health |
| **NetworkPolicy** | 前端 → Gateway (8080)Gateway → NATS (4222) / PG / Redis; NATS → Dispatcher / MCP |
| **Ingress** | Nginx Ingress / Traefik + TLS 证书(cert-manager + Let's Encrypt|
| **ConfigMap / Secret** | 配置与密钥分离,Secret 经 Vault CSI 注入 |
### 3.5 备份与恢复
| 数据 | 策略 | RPO / RTO |
|---|---|---|
| **PostgreSQL** | pg_dump 每日全量 + WAL 归档增量 → S3/MinIO | RPO < 1h, RTO < 30min |
| **Milvus** | Milvus backup 工具 → S3 | RPO < 24h |
| **Neo4j** | neo4j-admin dump → S3 | RPO < 24h |
| **NATS JetStream** | 3 副本 Raft 自带持久化 | 天然容灾 |
| **配置** | Git 版本管理 + Vault 快照 | 即时恢复 |
---
## 四、CI/CD 与发布工程 (Release Engineering)
### 4.1 当前 CI 评估
**已有**
- [ci.yml](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/.github/workflows/ci.yml)Go build+vet+test / 前端 tsc / Python sandbox test ✅
- [release.yml](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/.github/workflows/release.yml)Wails 跨平台构建 + GitHub Release ✅
**缺失**
### 4.2 需补充的 CI 流水线
```yaml
# 完整 CI 流水线:
jobs:
lint: # ← 新增
- golangci-lint run # 代码质量门
- eslint + prettier # 前端 lint
- ruff check # Python lint
security: # ← 新增
- govulncheck ./... # Go 依赖漏洞扫描
- npm audit # 前端依赖漏洞
- trivy image scan # 容器镜像漏洞扫描
- gitleaks detect # 代码中泄露的密钥检测
test: # 增强
- go test -race -coverprofile # 竞态检测 + 覆盖率
- vitest run # 前端单元测试(需先引入)
- pytest --cov # Python 覆盖率
build: # ← 新增:后端容器镜像
- docker build -t sundynix-gateway:$SHA
- docker build -t sundynix-dispatcher:$SHA
- docker build -t sundynix-mcp-go:$SHA
- docker build -t sundynix-mcp-py:$SHA
- push to container registry
e2e: # ← 新增:端到端
- docker-compose up → make e2e → 全链路验证
deploy-staging: # ← 新增
- helm upgrade --install -n staging
- 冒烟测试
deploy-prod: # ← 新增
- 人工审批 gate
- helm upgrade --install -n production
- 金丝雀验证
```
### 4.3 容器化 — 🔴 必须
需为每个服务创建 Dockerfile
```dockerfile
# 示例:sundynix-gateway
FROM golang:1.25-alpine AS builder
WORKDIR /src
COPY go.work go.work.sum ./
COPY sundynix-shared/ sundynix-shared/
COPY sundynix-gateway/ sundynix-gateway/
RUN cd sundynix-gateway && CGO_ENABLED=0 go build -o /app ./cmd/server
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app /app
EXPOSE 8080
ENTRYPOINT ["/app"]
```
- 多阶段构建,最终镜像用 distroless(最小攻击面)
- 镜像推到 GitHub Container Registry (ghcr.io) 或私有 Harbor
### 4.4 发布策略
| 策略 | 说明 |
|---|---|
| **语义化版本** | `vMAJOR.MINOR.PATCH`MAJOR 含 breaking change |
| **金丝雀发布** | 新版先切 10% 流量,观测 30min 无异常再全量 |
| **蓝绿部署** | 数据库 schema 变更时用蓝绿(需 schema 向后兼容)|
| **Feature Flags** | 引入 unleash / flagsmith,功能灰度发布 |
| **回滚机制** | `helm rollback` + NATS JetStream 消费者 replay |
---
## 五、数据治理与合规 (Data Governance)
### 5.1 多租户 — ⚠️ 待实现
**现状**:知识库按 `user_id/kb_name` 做 owner 作用域,但无正式租户模型。
**需引入**
| 层次 | 方案 |
|---|---|
| **数据隔离** | 租户 ID → PG Schema / 行级策略 (RLS)Milvus 按租户 partitionNeo4j 按租户 label |
| **资源配额** | 每租户 LLM Token 配额 / 存储配额 / 并发任务上限 |
| **计费** | 按 Token 用量 / 存储用量 / API 调用量 阶梯计费 |
### 5.2 数据生命周期
| 能力 | 说明 |
|---|---|
| **数据保留策略** | 会话历史 90 天过期;审计日志 1 年;JetStream 7 天滚动 |
| **个人数据删除** | GDPR / 个保法 合规:用户注销 → 级联清除 PG + Milvus + Neo4j + Redis 所有个人数据 |
| **数据脱敏** | 生产日志中 PII 字段(用户输入/模型输出)自动脱敏 |
| **数据分类分级** | API Key = L4 机密;用户输入 = L3 敏感;模型输出 = L2 内部 |
### 5.3 合规
| 要求 | 措施 |
|---|---|
| **等保 2.0 三级** | 审计日志 + 访问控制 + 加密存储 + 入侵检测 |
| **GDPR** | 个人数据删除权 + 数据可携权 + 处理记录 |
| **AI 生成标识** | 输出标注"AI 生成"水印或元信息 |
| **内容审查** | 模型输出过滤(敏感内容/政治/暴力/色情)— 需接第三方审查 API 或部署自有模型 |
---
## 六、AI 特有的生产治理
### 6.1 Token 计量与成本控制 — 🔴 必须
**现状**LLM Pool 无 Token 计数。
**需引入**
```go
// Token 计量中间件(包装 Pool.ChatStream / Chat):
type TokenMeter struct {
pool *Pool
counter prometheus.Counter // sundynix_llm_tokens_total
store TokenUsageStore // 写 PG sundynix_token_usage
}
// 每次 LLM 调用记录:
type TokenUsage struct {
TaskID string
UserID string
Model string
InputTokens int
OutputTokens int
LatencyMS int64
Cost float64 // 按 model pricing 计算
CreatedAt time.Time
}
```
- 大部分 OpenAI 兼容 API 在响应中返回 `usage.prompt_tokens` / `usage.completion_tokens`
- Eino `ChatModel.Generate` 的响应 `ChatModelOutput` 包含 `TokenUsage`
### 6.2 模型路由与 Fallback — ⚠️ 缺失
**现状**:单一模型配置,无 fallback。
**需引入**
```
模型路由策略:
├── 主模型: deepseek-chat (成本低/速度快)
├── Fallback 1: gpt-4o-mini (主模型超时/500 时切)
├── Fallback 2: 本地 Ollama (外网不可用时切)
└── 规则路由:
├── 报告生成 → 强模型 (需要长输出+结构化)
├── 普通对话 → 快模型 (低延迟优先)
└── 知识抽取 → 便宜模型 (批量场景控成本)
```
### 6.3 Prompt 版本管理 — ⚠️ 缺失
**现状**:Prompt 硬编码在 Go 代码中。
**需引入**
| 方案 | 说明 |
|---|---|
| **Prompt 模板表** | PG 存 prompt 模板,支持版本控制 + A/B 测试 |
| **变量插值引擎** | `{{.profile}}` / `{{.history}}` / `{{.refs}}` 模板变量 |
| **A/B 测试** | 同一任务按百分比路由到不同 prompt 版本,对比评分 |
| **Prompt 审计** | 记录每次推理的完整 prompt(脱敏后),便于复盘优化 |
### 6.4 模型输出缓存 — ⚠️ 缺失
| 层次 | 方案 |
|---|---|
| **Semantic Cache** | 相似 query 的 RAG 检索结果缓存(Redis / Milvus 相似度匹配)|
| **Exact Cache** | 完全相同的 prompt 直接返回缓存结果(省 LLM 调用) |
| **KB 搜索缓存** | 高频 query 的检索结果缓存(TTL 5min|
### 6.5 安全 AI 特有治理
| 能力 | 说明 |
|---|---|
| **Prompt 注入防御增强** | 当前正则检测 ✅;建议补 LLM-based 注入检测(二段判决:先用小模型判定是否为注入)|
| **幻觉检测** | RAG 场景:比对模型输出与检索到的参考资料,标注无出处的断言 |
| **输出内容审查** | 接第三方内容审核 API 或部署开源模型(如 Llama Guard)做输出过滤 |
| **PII 检测** | 输入/输出流经 PII 检测器(身份证号/手机号/银行卡号),日志自动脱敏 |
---
## 七、前端工程化
### 7.1 状态管理 — ⚠️ 改进
**现状**:纯 `useState` + props drilling,无全局状态。
```typescript
// 推荐引入 Zustand(轻量 + React 生态友好):
import { create } from 'zustand';
interface AppStore {
user: AuthUser | null;
identity: Identity;
currentRun: RunState;
// actions
setUser: (u: AuthUser | null) => void;
submitTask: (dsl: TaskDsl) => Promise<void>;
}
```
### 7.2 路由 — ⚠️ 缺失
**现状**`view` state + 条件渲染,无 URL 路由。
```typescript
// 引入 React Router v7Admin 端已用):
// → 支持 URL 直达、浏览器前进后退、深链接分享
<Route path="/" element={<Home />} />
<Route path="/studio" element={<StudioView />} />
<Route path="/kb" element={<KbView />} />
<Route path="/report" element={<ReportView />} />
<Route path="/runs/:taskId?" element={<RunsView />} />
```
### 7.3 测试 — 🔴 缺失
| 层次 | 工具 | 覆盖 |
|---|---|---|
| **单元测试** | Vitest + React Testing Library | 核心组件(StudioView / KbView / 状态逻辑)|
| **E2E 测试** | Playwright | 关键用户流(登录 → 编排 → 运行 → 查看结果)|
| **Visual Regression** | Chromatic / Percy | UI 回归检测 |
### 7.4 性能优化
| 方案 | 说明 |
|---|---|
| **代码分割** | React.lazy + Suspense,按视图/路由懒加载 |
| **虚拟列表** | 知识库文档列表 / 运行历史 → 用 `react-virtual` |
| **SSE 重连** | EventSource 断连自动重连 + 指数退避 |
| **离线缓存** | Service Worker 缓存静态资源 |
### 7.5 大文件拆分
| 文件 | 大小 | 建议 |
|---|---|---|
| [KbView.tsx](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/sundynix-desktop/frontend/src/views/KbView.tsx) | 31,944 bytes | 拆为 `KbSearchPanel` / `KbDocList` / `KbGraphPanel` / `KbIngestPanel` |
| [StudioView.tsx](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/sundynix-desktop/frontend/src/studio/StudioView.tsx) | 11,966 bytes | 拆为 `Canvas` / `Toolbar` / `PropertiesPanel` |
| [App.tsx](file:///Users/zhangjianmin/sourceCode/GolandProjects/src/sundynix-agentix/sundynix-desktop/frontend/src/App.tsx) | 8,942 bytes | 路由抽离后天然减小 |
---
## 八、运维自动化 (Platform Engineering)
### 8.1 集中配置管理 — ⚠️ 缺失
**现状**:各服务独立 `config.yaml`NATS 热更新仅覆盖模型配置。
**需引入**
| 方案 | 说明 |
|---|---|
| **NATS KV** | NATS 2.8+ 内建 KV Store,已接 NATS 生态,零额外运维 |
| **Consul** | 功能更全(服务发现 + 配置 + 健康检查),但多一个组件 |
| 推荐 NATS KV(现有生态内扩展,无新增依赖):配置变更 → Watch → 各服务热加载 |
### 8.2 优雅停机 — ⚠️ 部分
**需确保**
- 收到 SIGTERM → 停止接收新请求 → 等待在途请求完成 → 关闭 NATS / PG / Redis → 退出
- NATS ConsumeTasks 的 `stop` 函数已有 ✅,需在信号处理中调用
- K8s `preStop` hook + `terminationGracePeriodSeconds: 30`
### 8.3 数据库 Schema 迁移 — ⚠️ 改进
**现状**GORM `AutoMigrate`(开发方便但生产风险高:字段删除不生效、大表加列会锁表)。
**需引入**
| 工具 | 说明 |
|---|---|
| **golang-migrate****Atlas** | 版本化 SQL 迁移文件(up/down),CI 自动校验;生产用 `gh-ost` 做无锁 schema 变更 |
| 保留 AutoMigrate 仅用于开发模式 | `if env == "dev" { db.AutoMigrate(...) }` |
### 8.4 健康检查统一 — ⚠️ 不一致
**现状**Gateway 有 HTTP 端点,Dispatcher 走 NATS pingMCP-Go 走 NATS 队列组。
**需引入**
```go
// 每个服务暴露统一的 /healthz (liveness) 和 /readyz (readiness)
// - liveness: 进程存活(总是 200
// - readiness: 所有依赖就绪
// Gateway: PG connected + Redis connected + NATS connected
// Dispatcher: NATS connected + LLM pool ready
// MCP-Go: NATS connected + Milvus ready + Bleve ready
// MCP-Py: NATS connected + Docker available
```
### 8.5 告警与 On-Call
| 能力 | 方案 |
|---|---|
| **告警规则** | Prometheus Alertmanager + PagerDuty / 飞书 / 钉钉 webhook |
| **关键告警** | 错误率>5% / P99>5s / 熔断打开 / 磁盘>80% / 队列积压>1000 / LLM 成功率<90% |
| **On-Call 轮值** | PagerDuty / OpsGenie 自动轮值 + 升级 |
| **Runbook** | 每个告警对应标准处置流程文档 |
---
## 优先级排序(路线图)
> 按风险/收益排序,分三阶段实施:
### 🔴 Phase 1:安全底线 + 部署能力 (4-6 周)
| # | 事项 | 理由 |
|---|---|---|
| 1 | **密钥加密存储** (Vault/SOPS) | API Key 明文是最大安全风险 |
| 2 | **Dockerfile 容器化** (4 个 Go 服务 + 1 Python) | 生产部署的前提 |
| 3 | **Kubernetes Helm Chart** | 取代 docker-compose 部署 |
| 4 | **NATS 3 节点集群** | 消除全局单点故障 |
| 5 | **PG SSL + NATS TLS** | 传输层加密 |
| 6 | **统一健康检查** (/healthz + /readyz) | K8s 探针就绪 |
| 7 | **优雅停机信号处理** | 滚动更新不丢请求 |
| 8 | **Token 计量基础** | 成本可控的前提 |
### 🟡 Phase 2:可观测性 + 治理能力 (4-6 周)
| # | 事项 | 理由 |
|---|---|---|
| 9 | **OpenTelemetry Tracing** | 分布式链路追踪 |
| 10 | **指标体系补全** | LLM/RAG/Task 指标 |
| 11 | **Grafana 仪表盘** | 统一观测面板 |
| 12 | **日志标准化** (全局 slog + Loki) | 结构化日志 + 集中采集 |
| 13 | **审计日志** | 合规要求 |
| 14 | **模型路由 + Fallback** | 提升可用性 |
| 15 | **PG 主从 + 备份策略** | 数据安全 |
| 16 | **CI 增强** (lint + security scan + coverage) | 代码质量门 |
| 17 | **Schema 迁移工具** (golang-migrate) | 安全 DDL |
### 🟢 Phase 3:规模化 + 精细化 (6-8 周)
| # | 事项 | 理由 |
|---|---|---|
| 18 | **多租户** | 商业化必需 |
| 19 | **RBAC 角色体系** | 企业客户需求 |
| 20 | **前端 React Router + Zustand** | 用户体验 + 可维护性 |
| 21 | **前端测试** (Vitest + Playwright) | 质量保障 |
| 22 | **Prompt 版本管理 + A/B 测试** | AI 质量持续优化 |
| 23 | **Semantic Cache** | 降低 LLM 调用成本 |
| 24 | **内容审查 (Llama Guard)** | 合规 |
| 25 | **金丝雀发布 + Feature Flags** | 安全发布 |
| 26 | **Milvus Cluster + Neo4j Cluster** | 数据层高可用 |
| 27 | **告警体系 + Runbook** | 运维成熟度 |
| 28 | **GDPR / 个保法合规** | 数据合规 |
---
## 技术选型速查表
| 维度 | 推荐工具/组件 | 替代方案 |
|---|---|---|
| 链路追踪 | OpenTelemetry + Grafana Tempo | Jaeger / SkyWalking |
| 指标 | Prometheus + Grafana | VictoriaMetrics |
| 日志 | slog + Grafana Loki | ELK (Elasticsearch + Logstash + Kibana) |
| 密钥管理 | HashiCorp Vault | AWS Secrets Manager / SOPS |
| 容器编排 | Kubernetes + Helm | Docker Swarm (小规模) |
| CI/CD | GitHub Actions + ArgoCD | GitLab CI / Jenkins |
| 镜像仓库 | ghcr.io / Harbor | Docker Hub Private |
| API 网关 | Traefik / Nginx Ingress | Kong / APISIX |
| 配置中心 | NATS KV | Consul / etcd / Apollo |
| Schema 迁移 | golang-migrate / Atlas | goose / Flyway |
| Feature Flags | Unleash | LaunchDarkly / Flagsmith |
| 内容审查 | Llama Guard (自部署) | 阿里绿网 / 腾讯天御 |
| 前端状态 | Zustand | Jotai / Redux Toolkit |
| 前端测试 | Vitest + Playwright | Jest + Cypress |
| 告警 | Alertmanager + 飞书/钉钉 | PagerDuty / OpsGenie |