# 架构说明 **MateClaw 是怎么拼起来的,一页讲完。** **用** MateClaw 的人看 [项目介绍](./intro)。**在 MateClaw 上面建东西**的人——加工具、新渠道、自定义记忆 provider、新的 Agent 图节点——看这一页。 --- ## 一张图的产品 ``` ┌─────────────────────────────────────────────────────────────────┐ │ MateClaw │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌─────────────────────┐ │ │ │ Web 控制台 │ │ 桌面端 │ │ IM 渠道 │ │ │ │ Vue 3 SPA │ │ Electron │ │ 钉钉 / 飞书 / │ │ │ │ (src/static) │ │ + 内置 │ │ 企业微信 / Telegram/ │ │ │ │ │ │ JRE 21 │ │ Discord / QQ / ... │ │ │ └──────┬──────┘ └──────┬───────┘ └──────────┬──────────┘ │ │ │ HTTP/SSE │ HTTP/SSE │ SPI │ │ └────────┬────────┴───────────────────────┘ │ │ │ │ │ ┌───────────────▼──────────────────────────────────────────┐ │ │ │ Spring Boot 后端(vip.mate.*) │ │ │ │ │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │ │ │ │ │ auth │ │ channel │ │ agent │ │ │ │ │ │ (JWT) │ │ adapters │ │ (AgentScope │ │ │ │ │ └────────────┘ └─────┬──────┘ │ runtime) │ │ │ │ │ │ │ │ │ │ │ │ ┌────────────┐ │ │ ┌──────────────┐ │ │ │ │ │ │ workspace │ │ │ │ ReasoningN │ │ │ │ │ │ │ isolation │ │ │ │ ActionN │ │ │ │ │ │ └────────────┘ │ │ │ Observation │ │ │ │ │ │ │ │ │ PlanGenN │ │ │ │ │ │ ▼ │ │ StepExecN │ │ │ │ │ │ ┌──────────────┐ │ │ FinalAnsN │ │ │ │ │ │ │ Message │ │ └──────────────┘ │ │ │ │ │ │ Router ├──▶ │ │ │ │ │ │ └──────────────┘ └──────┼─────────────┘ │ │ │ │ │ │ │ │ │ ┌─────────────────────────────────────▼────────────────┐ │ │ │ │ │ Tool Registry │ │ │ │ │ │ │ │ │ │ │ │ 内置 @Tool + MCP client + 技能脚本 │ │ │ │ │ └─────────┬───────────────────────────────────────────┬──┘ │ │ │ │ │ │ │ │ │ │ ▼ ▼ │ │ │ │ ┌──────────────┐ ┌─────────────┐ ┌───────────────────┐ │ │ │ │ │ Tool Guard │ │ 审批 │ │ 审计日志 │ │ │ │ │ │ (规则) │ │ 工作流 │ │ 管道 │ │ │ │ │ └──────────────┘ └─────────────┘ └───────────────────┘ │ │ │ │ │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │ │ │ │ │ memory │ │ wiki │ │ skill │ │ │ │ │ │ 多层 │ │ (分层) │ │ (SKILL.md 运行时) │ │ │ │ │ │ SPI │ │ digester │ │ │ │ │ │ │ └────────────┘ └────────────┘ └────────────────────┘ │ │ │ │ │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ │ │ MyBatis Plus / H2 或 MySQL │ │ │ │ │ │ │ │ │ │ │ │ mate_agent / mate_message / mate_wiki_* / │ │ │ │ │ │ mate_tool_guard_* / mate_workspace / ... │ │ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` **一个 JAR。一个进程。The whole widget。** --- ## 仓库布局 ``` mateclaw/ ├── mateclaw-server/ # Spring Boot 后端(心脏) │ └── src/main/java/vip/mate/ │ ├── MateClawApplication.java │ ├── agent/ # 原生 ReAct、计划策略与状态 │ ├── planning/ # Plan 和 SubPlan 持久化 │ ├── workflow/ # 工作流引擎(1.3.0+):DSL 编译、线性 runtime、payload spill │ ├── trigger/ # 触发器引擎(1.3.0+):6 种 pattern、事件治理、CronDelegationPort │ ├── tool/ # ToolRegistry、@Tool bean、MCP(per-agent 绑定)、guard │ ├── approval/ # 审批工作流(兼任 workflow 的 await_approval 暂停/恢复桥接) │ ├── skill/ # 动态技能包 │ ├── wiki/ # LLM Wiki + Transformations 引擎(1.3.0+) │ ├── memory/ # 记忆层 + SPI │ ├── workspace/ # 工作空间实体 + 会话 + 文档 │ ├── channel/ # 渠道 SPI + 适配器(1.3.0+: WeCom v2、reply queue、leader lease) │ ├── llm/ # LLM provider 配置(1.3.0+: 多模态 sidecar 路由) │ ├── auth/ # Spring Security + JWT │ ├── audit/ # 审计事件管道 │ ├── cron/ # 定时任务引擎(trigger.cron 通过 CronDelegationPort 复用) │ ├── task/ # 异步任务运行时 │ ├── dashboard/ # 指标聚合 │ ├── datasource/ # 外部 DB 连接 │ ├── stt/ # 语音转文字 │ ├── tts/ # 文字转语音 │ ├── system/ # 系统设置、bootstrap、引导 │ ├── config/ # Spring 配置 │ ├── common/ # 共享工具 │ └── exception/ # 全局异常处理器 │ └── src/main/resources/ │ ├── application.yml │ ├── db/migration/ # Flyway 迁移脚本(h2/ + mysql/) │ ├── db/data.sql # 种子数据 │ ├── prompts/ # LLM prompt 模板 │ ├── skills/ # 捆绑的技能包 │ └── static/ # 前端构建产物 ├── mateclaw-ui/ # Vue 3 管理控制台 ├── mateclaw-desktop/ # Electron 桌面壳 ├── mateclaw-webchat/ # 可嵌入的聊天小部件 ├── matevip-sites/ # 营销和文档站点(pnpm workspace) ├── docs/ # 这份文档(VitePress) ├── deploy/ # 生产部署配置 ├── docker-compose.yml └── .env.example ``` 后端是**一个模块化的单体**。其他项目是不和后端共享代码的独立包。 --- ## 原生 ReAct 与显式计划阶段 后端使用 Java 21、Spring Boot 4.1.1、Spring AI 2.0.1 和 AgentScope Java 2.0.4。`NativePolicyDriver` 为每次调用创建独立的原生 `ReActAgent`,由 SDK 管理推理/行动循环。应用策略继续管理提示词、审批、观察、总结与目标预算。 ### 请求与预算归属 AgentScope 2.0.4 管理循环编排,Spring AI/provider 适配器负责实际模型请求准备。`PromptBudget` 在推理预检与压缩模型调用之间共享生效选项的预算估算,不替代供应商请求序列化。工具审批、工作空间保护、Goal 预算和完成验收门仍由应用负责。[预算说明](./models#上下文预算与请求准备-3-0-0) ### 关键文件 - `agent/runtime/agentscope/NativePolicyDriver.java`——原生循环与应用策略回调 - `agent/runtime/agentscope/ApplicationGuardedToolkit.java`——受保护的整批执行入口;SDK 回调只提供 schema - `agent/runtime/plan/ExplicitPlanRuntime.java`——计划生成、步骤推进、总结与目标阶段 - `agent/graph/plan/node/StepExecutionNode.java`——每个计划步骤的内部工具循环使用原生 ReAct - `agent/graph/executor/ToolExecutionExecutor.java`——已有工具保护、审批、执行归因与结果 - `agent/runtime/state/RunState.java` + `RunStep.java`——独立状态与带版本的调用内快照 - `agent/AgentGraphBuilder.java`——按 Agent 配置装配运行时 - `agent/graph/StateGraphReActAgent.java` + `agent/graph/plan/StateGraphPlanExecuteAgent.java`——保留名称的应用封装类;这些名称不代表 Alibaba 图框架依赖 ### 历史与扩展边界 应用会话消息仍是提示词的权威来源和持久化产品记录。SDK 临时历史只用于编排,不单独持久化。原生 pending-tool recovery 已关闭;内部快照成功不代表外部副作用可以安全重放。 业务行为通过已有节点、dispatcher 与 `MateClawStateKeys` 修改,并由 `AgentGraphBuilder` 接入。`ReasoningNode` 每次只执行一轮模型策略;`ActionNode.executeBatch` / `completeBatch` 分离受保护执行与完成策略。`GraphEventPublisher` 与 `NodeStreamingChatHelper` 继续维持应用 SSE 契约。 Spring AI 接口仍是模型/工具插件边界。原生 DashScope 对话和 embedding 适配器替代 Alibaba AI starter,独立的 DashScope SDK 继续支持语音集成。 ### 目标评估节点(1.4.0+) 图(ReAct 和 Plan-Execute 都有)现在在 `FinalAnswerNode` 把最终答案流式输出之后再跑一个 `GoalEvaluationNode`:1.5.0 起它逐条裁决目标的 checklist 准则(bootstrap / verdict 两模式),**全部准则通过才算完成**,并可选地注入一条针对剩余准则的自动跟进消息,把没达成的目标继续推进。 ### 其他 1.4.0 运行时变化 - **渐进式工具/技能披露**——工具披露层把工具分成核心层(core)和扩展层(extension)两档;`enable_tool` / `load_skill` 让员工按需激活扩展工具、按需加载技能,从而把系统提示保持得足够小。 - **多级子员工委派树**——父员工到子员工的委派是递归的、有深度上限的,构成一棵树;子图的事件实时回流到根会话。 - **ChannelToolProvider SPI**——渠道(比如飞书)可以把平台能力直接作为员工工具暴露出来,不需要单独的 MCP 服务器。 - **工作空间 RBAC**——能力(capability)由后端的「角色 → 能力」映射解析,同时门禁 REST 接口和前端路由/菜单。 ### 共享 state key | Key | 用途 | |-----|------| | `USER_MESSAGE` | 当前用户输入 | | `MESSAGES` | 从 `mate_message` 加载的会话消息 | | `OBSERVATION_HISTORY` | 本回合的工具调用结果 | | `CURRENT_ITERATION` | 已经循环过多少次 | | `MAX_ITERATIONS` | 上限 | | `TOOL_CALLS` | 当前工具调用列表 | | `AWAITING_APPROVAL` | 有调用需要人工审批时置 true | | `FINAL_ANSWER` | Agent 的响应 | | `FINISH_REASON` | 图为什么结束 | --- ## 数据流 —— 单次回合 ``` 1. POST /api/v1/chat?agentId={id} (或 POST /api/v1/chat/stream,agentId 在 body 里) ↓ 2. ChatController.sendMessage() ↓ 3. ConversationManager.loadOrCreate(conversationId) ↓ 4. AgentGraphBuilder.build(agentEntity) ← 解析运行时 ↓ 5. runtime.stream(initialState) ← 原生循环 / 应用阶段开始 ↓ ReasoningNode → Dispatcher → ActionNode → ObservationNode →(循环或结束) ↓ 6. 工具调用走: ToolRegistry.resolve() → Tool Guard 规则评估 → (需要审批时)mate_tool_approval 行 + SSE 事件 + AWAITING_APPROVAL=true (内联允许时)ToolExecutionExecutor.execute() → observation ↓ 7. Segment 通过以下方式流到客户端: GraphEventPublisher → NodeStreamingChatHelper → SSE 流 ↓ 8. 结束时: FinalAnswerNode 聚合结果 ConversationManager 把 segment 持久化到 mate_message ConversationCompletedEvent 发出(异步记忆提取启动) ↓ 9. 响应关闭 ``` --- ## 扩展点 这些是你可以在上面建东西的 SPI 和插件点: ### `@Tool` 标注的 Spring bean 写一个带 `@Tool` 方法的 `@Component`。启动时被 `ToolRegistry` 捡起来。每个 `@Tool` 方法都成为一个可调用工具。 ```java @Component public class MyCustomTool { @Tool(description = "LLM 看到的描述") public String doThing(@ToolParam(description = "...") String input) { return "result"; } } ``` ### `ChannelAdapter` SPI 实现 `vip.mate.channel.ChannelAdapter`(或支持流式的 `StreamingChannelAdapter`)。注册成 Spring bean。通过 `ChannelWebhookController` 加 webhook 端点。见 [多渠道接入](./channels)。 ```java public interface ChannelAdapter { void onMessage(ChannelMessage message); void sendMessage(String channelId, String content); String getChannelType(); } ``` ### `MemoryProvider` SPI 实现 `vip.mate.memory.spi.MemoryProvider` 来插入自定义记忆后端(向量、图、外部服务)。**多个 provider 可以在 Agent 上堆叠**。见 [记忆系统](./memory)。 ### MCP 服务 通过 stdio、streamable_http、sse 连接外部工具服务。它们的工具自动出现在工具注册表里——Agent 代码**不知道它们是外部的**。见 [MCP 协议](./mcp)。 ### 技能包 把指令 + 工具 + 可选脚本打包进一个 `SKILL.md`。通过 UI 或 API 上传。Agent 在运行时可以调用它们。见 [技能系统](./skills)。 ### Agent 图节点和边 更深的定制——在 `agent/graph/node/` 加新节点或在 `agent/graph/edge/` 加新 dispatcher。在配置 flag 后面接进 `AgentGraphBuilder`。State 访问走 `MateClawStateAccessor`。 --- ## 持久化 —— 一份 schema,两种数据库 MateClaw 用 **MyBatis Plus**(不是 JPA)做数据库访问。约定: - 所有表前缀 `mate_` - `snake_case` 列、`camelCase` Java 字段、自动映射 - 每张表有 `create_time`、`update_time`、`deleted`(逻辑删除) - **Flyway** 管理 schema 迁移——`db/migration/h2/` 和 `db/migration/mysql/` 各有一套方言脚本,启动时自动选择 - `FlywayRepairConfig` 默认执行开启校验的 `migrate()`;修复历史记录必须显式开启,操作前参阅[数据库恢复说明](./config#数据库-schema-初始化) - 种子数据由 `DatabaseBootstrapRunner` 从 `db/data-*.sql` 加载,幂等执行 ### 表分组 **身份和配置**——`mate_user`、`mate_system_setting`、`mate_model_config`、`mate_model_provider`、`mate_datasource`、`mate_mcp_server` **Agent 和计划**——`mate_agent`、`mate_agent_skill`、`mate_agent_tool`、`mate_plan`、`mate_sub_plan` **会话**——`mate_conversation`、`mate_message`、`mate_channel`、`mate_channel_session` **工具和审批**——`mate_tool`、`mate_tool_approval`、`mate_tool_guard_rule`、`mate_tool_guard_config`、`mate_tool_guard_audit_log` **技能和工作空间**——`mate_skill`、`mate_workspace`、`mate_workspace_member`、`mate_workspace_file` **知识和记忆**——`mate_wiki_knowledge_base`、`mate_wiki_raw_material`、`mate_wiki_page`、`mate_wiki_transformation`、`mate_wiki_transformation_run`(1.3.0+)、`mate_memory_recall` **工作流和触发器(1.3.0+)**——`mate_workflow`、`mate_workflow_revision`、`mate_workflow_run`、`mate_workflow_step_run`、`mate_workflow_payload`、`mate_trigger`、`mate_trigger_event` **运维**——`mate_cron_job`、`mate_cron_job_run`、`mate_async_task`、`mate_usage_daily`、`mate_audit_event`、`mate_doctor_check` --- ## 流式 —— 为什么用 SSE 不用 WebFlux MateClaw 用 **Spring MVC**,不是 Spring WebFlux。**WebFlux 在依赖图里被明确排除。** 为什么:Spring MVC + SSE 足以把 LLM 响应流式到前端。它更容易推理、更容易调试、不强迫整个栈变成响应式。 ::: tip 虚拟线程(JDK 21) `spring.threads.virtual.enabled=true` 已开启。Tomcat 请求线程、`@Scheduled` 任务和 `@Async` 方法全部运行在虚拟线程上。SSE 长连接不再占用平台线程——并发连接数不再受线程池大小约束。 ::: 流式流程: 1. 客户端 `POST /api/v1/chat/stream`,body 里带 `agentId` / `message` / `conversationId`,请求头加 `Accept: text/event-stream` 2. Controller 返回 `SseEmitter` 3. Agent 图在工作线程上运行;节点执行把事件发给 `GraphEventPublisher` 4. 事件序列化成 SSE 格式写进 emitter 5. `ChatStreamTracker` 监视被遗弃的流并清理它们 同样的 SSE 模式被支持流式的渠道适配器复用(钉钉 AI Card、Web)。 --- ## 前端架构 **Vue 3 + TypeScript + Composition API + `