02-architecture.md 7.1 KB

02 总体架构

1. 架构总览

 业务平台 A/B/C (Vue)            管理后台 (Vue, 同源静态托管)
   │ @agent-server/client           │
   │ REST + SSE  (/v1)              │ REST + SSE (/v1 + /admin/v1)
┌──▼────────────────────────────────▼──────────────────────────────┐
│ HTTP 层 (Fastify):鉴权(API Key/AdminSession) · 校验(Zod) · 限流    │
├──────────────────────────────────────────────────────────────────┤
│ Session Service   Run Manager     Interaction Service             │
│ Workspace Service Profile Service Settings Service                │
│ Access Policy     Knowledge Service  Usage/Audit  Event Store/Bus │
├──────────────────────────────────────────────────────────────────┤
│ Provider Adapter 层(统一 AgentEvent)                             │
│  ├─ ClaudeAdapter  ── @anthropic-ai/claude-agent-sdk ──► claude CLI 子进程(每会话)│
│  └─ CodexAdapter   ── JSON-RPC(stdio) ──► codex app-server 常驻进程(单个)        │
├──────────────────────────────────────────────────────────────────┤
│ MCP Gateway (/mcp):web_fetch · 资料库检索 ·(预留)内部平台连接器      │
├──────────────────────────────────────────────────────────────────┤
│ SQLite (Drizzle)     文件系统:/srv/agent-server/{workspaces,knowledge,skills,runtime}│
│                      CLI 登录态:~/.claude、~/.codex(本人终端登录)          │
└──────────────────────────────────────────────────────────────────┘

2. 工程结构(pnpm monorepo)

apps/
  server/            Node 22 + TS + Fastify
    src/
      http/          路由:v1/、admin/v1/、mcp/
      services/      session, run, interaction, workspace, profile, settings, access-policy, knowledge, usage, audit
      providers/
        types.ts     AgentProvider 接口、AgentEvent 定义(从 shared 引入)
        claude/      Agent SDK 适配、消息→事件映射、canUseTool 桥接
        codex/       app-server 进程管理、JSON-RPC 客户端、通知→事件映射、审批桥接
      mcp-gateway/   MCP Server 实现、内置工具(web_fetch、kb_*)
      connectors/    (预留)内部平台连接器
      db/            Drizzle schema、迁移
  admin/             Vue 3 + TS + UnoCSS + Vite + Vue Router + Pinia
packages/
  shared/            AgentEvent、API DTO、Zod schema(前后端共享类型)
  client/            TS 客户端 SDK(会话、SSE 订阅、断线续传、交互回复、上传)
  chat-ui/           Vue 对话组件(消息时间线、工具卡片、交互卡片、输入框),Playground 与业务平台共用
  ui-tokens/         UnoCSS preset:VS Code 风格设计令牌(亮/暗)
docs/

3. 核心抽象

3.1 Provider 接口

interface AgentProvider {
  readonly id: 'claude' | 'codex'
  capabilities(): ProviderCapabilities           // 模型列表、是否支持图片/思考/提问等
  health(): Promise<ProviderHealth> // 登录状态、限额
  startRun(ctx: RunContext): RunHandle
}

interface RunContext {
  session: SessionRecord          // 含 providerSessionId(用于 resume)
  input: UserInput                // 文本 + 图片 + 附件引用
  profile: ResolvedProfile        // 已合并的模型、提示词、权限、工具、连接器
  workspaceDir: string
  access: ResolvedAccessPolicy    // 合并后的文件访问策略(06 §4)
  interact: (req: InteractionRequest) => Promise<InteractionResponse> // 挂起等待人工
  signal: AbortSignal
}

interface RunHandle {
  events: AsyncIterable<AgentEvent>
  interrupt(): Promise<void>
}

interact 是两个引擎交互能力的统一出口:Claude 的 canUseTool 回调、Codex 的审批请求、MCP Gateway 的写操作审批,最终都调用它,由 Interaction Service 发出 interaction.required 事件,并挂起 Promise 等待前端回复。

3.2 Run 生命周期

queued ──► running ──► completed
   │          │  ├──► failed
   │          │  └──► interrupted   (用户中断 / 服务重启 / 超时)
   │          └──► waiting_input ──► running   (有未决交互时)
   └──► cancelled
  • 一个会话同一时刻只允许一个活动 Run,新消息在 Run 进行中提交时返回 409(后续可改为排队)。
  • waiting_input 状态不计入并发配额以外的超时;交互超时(默认 10 分钟,可配)按"拒绝"处理。

3.3 事件管道

Adapter 产出 AgentEvent
   → Run Manager 分配 seq(会话内单调递增)
   → Event Store 写入 SQLite(events 表)
   → Event Bus 广播(进程内 EventEmitter)
   → SSE 连接按 sessionId / runId 过滤推送

先落库、再推送;SSE 重连时依据 Last-Event-ID(= seq)从库中补发。message.delta 这类高频事件在落库时按 100ms 窗口合并,推送不合并。

4. 进程模型

引擎 进程 说明
Claude 每个活动 Run 一个 claude 子进程(由 SDK 拉起),Run 结束退出 会话状态由 CLI 自身持久化到 ~/.claude/projects/,下次用 resume 继续
Codex 一个常驻 codex app-server,内部管理多个 thread 进程异常退出自动重启,并把关联的活动 Run 标记 interrupted

并发控制:全局上限(默认 4)+ 每引擎上限(默认 2),使用进程内队列(p-queue),上限在后台设定。注意服务与你在终端中的使用共享同一份订阅额度。

5. 技术栈

层 选型 理由
运行时 Node.js 22 LTS + TypeScript 两个引擎的官方集成以 TS 生态最完善(ADR-0001)
Web 框架 Fastify 性能好、原生 schema 校验、插件体系成熟
校验 Zod(经 fastify-type-provider-zod) 类型与 schema 一处定义,前后端共享
存储 SQLite(better-sqlite3)+ Drizzle ORM 单机足够;WAL 模式支撑并发读写
队列 p-queue(进程内) 单实例无需 Redis
MCP @modelcontextprotocol/sdk(Streamable HTTP) 两个引擎都支持 HTTP MCP
前端 Vue 3 + TS + UnoCSS + Vite + Pinia + Vue Router 与业务平台一致(ADR-0007)
图标 @vscode/codicons 与 VS Code 视觉一致,开源许可
Markdown markdown-it + Shiki 代码高亮主题可跟随亮/暗
日志 pino Fastify 内置,结构化 JSON