
2026-05-22OODER Architecture Team深度技术 · Agent 架构
想象一下这个场景:你正在用 OODER Studio 设计一个销售占比饼图。你说了一句"创建一个销售占比饼图",AI 迅速生成了代码,点击"编译"——然后整个 Studio 界面卡死了。30秒后,浏览器显示"页面无响应"。你刷新页面,之前的设计全部丢失。
这不是假设,而是我们团队在过去半年中反复遇到的真实问题。
OODER Studio 是一个 AI 驱动的可视化设计平台。用户通过自然语言描述需求,AI 自动生成 UI 组件代码,涉及大量的代码生成(CodeGen)、编译和热部署操作。在当时的实现中,所有这些操作都在 Studio 主进程的同一个 Java 虚拟机(JVM)中完成。
核心矛盾
Studio 的核心职责是稳定地提供 UI 设计、预览和交互能力。而 CodeGen 的本质是频繁试错——生成代码、编译、报错、修复、再编译。这两种截然不同的运行模式被塞进同一个 JVM,就像把化学实验室和总裁办公室放在同一个房间:实验的每一次爆炸都会波及办公区。
具体来说,当 AI 生成了一段有语法错误的 Java 代码,编译器尝试编译时:
这些问题不是"可能出问题",而是必然出问题。随着用户项目越来越多、AI 生成代码越来越复杂,崩溃频率从每周一次变成了每天数次。
更深层的问题在于:我们不是在做一个简单的代码编辑器,而是在构建一个 AI 智能体的生产流水线。用户说的每一句话,都可能触发一条完整的智能体构建链路:代码生成 → 编译构建 → 调试运行 → 打包发布。这条链路如果和 Studio 主进程耦合在一起,不仅稳定性无法保障,更谈不上规模化、自动化和智能化。
这就是 Agent Build 要解决的问题。
Agent Build 是 OODER 平台提出的 AI 智能体构建技术体系。它的核心思想是:将 AI 生成代码的编译、调试、发布等构建过程,从 Studio 主进程中彻底解耦出来,封装为独立的智能体(Agent),通过标准化的能力协议进行编排和调度。
换句话说,Agent Build 不是"在 IDE 里加个编译按钮",而是为 AI 智能体的全生命周期构建一条工业化流水线。这条流水线需要回答三个根本问题:
围绕这三个问题,我们提炼出 Agent Build 的三大技术支柱:

这三大支柱不是三个独立的技术点,而是一个有机整体:独立 JVM 解决"环境隔离"问题,ooderAgent 解决"智能体治理"问题,Skills 规范解决"能力标准化"问题。三者叠加,才构成了完整的 Agent Build 能力。
要理解为什么必须独立 JVM,需要先看看 Studio 的工程化管理模型。
OODER Studio 采用MySpace 工程化管理模型。每个用户在 Studio 中创建的"项目",实际上是一个完整的工程空间,拥有独立的版本空间、用户配置和类配置:
versionspace/项目名/0/ —— 存放所有视图文件(.cls)、SVG 图片等资源userspace/项目名/config/ —— 存放项目的配置信息aggclassconfig/ 和 apiclassconfig/ —— 存放聚合类和 API 类的配置比如一个叫"test"的项目,它的所有文件都存放在 form/myspace/versionspace/test/0/ 目录下。这种"一个项目 = 一个独立工程"的设计,天然适合进程级隔离——每个项目可以拥有自己的独立运行环境,互不干扰。
在旧的实现中,当用户点击"编译"按钮时,Studio 会执行一条全部在主 JVM 内完成的流水线。最致命的一步是将编译产物通过 defineClass 直接注入当前 JVM 的 Metaspace。一旦编译出错,错误会通过共享的类加载器、单例工厂和 API 路由表传导到 Studio 的每一个角落。
风险 | 通俗解释 | 后果 |
|---|---|---|
类无法卸载 | 编译后的类像钉子一样钉在内存里,拔不出来 | Metaspace 持续膨胀,最终 OOM |
编译锁全局阻塞 | 整个 Studio 排队等编译,像单窗口银行 | UI 冻结,用户以为程序挂了 |
JRE 环境崩溃 | 用户电脑只有运行环境,没有编译工具 | 直接抛异常,Studio 启动失败 |
单例状态污染 | 一个项目的错误数据流到其他项目 | A 项目编译错,B 项目也受影响 |
故障域无边界 | 没有防火墙,一处着火全城遭殃 | 无法定位问题,只能重启整个 Studio |
为什么不是"修修补补"就能解决的?
有人可能会想:给编译加个 try-catch、给内存加个限制、给锁加个超时,不就行了吗?问题在于,这些方案都是在同一个 JVM 内做防御,而 JVM 的类加载机制决定了 defineClass 是不可逆的。一旦类被注入,就无法卸载(除非整个 ClassLoader 被回收,而全局 ClassLoader 永远不会被回收)。这不是 bug,这是 JVM 的设计特性。唯一的出路是物理隔离——让编译发生在另一个 JVM 中。
我们的解法是:给每个项目配一个独立的 JVM,专门负责编译和调试。这个独立的 JVM 通过 ooderAgent 能力管理体系与 Studio 主进程通信。
用生活化的比喻来说:以前是一个办公室里所有人共用一台电脑,谁写代码写崩了全办公室都没法工作。现在给每个人配一台独立的工作站,工作站之间通过文件柜交换文件、通过内线电话实时沟通、通过对讲机下达指令。

图 1:Agent Build 架构——Studio 主进程与独立构建 Agent 通过三通道协同工作
在这个架构中,Studio JVM 只负责"稳定面"(UI 渲染、设计器、预览、路由注册),Isolated JVM 承担"试错面"(编译、调试、发布)。两个 JVM 之间通过三条通道协同工作:
通俗解释 VFS
VFS(Virtual File System,虚拟文件系统)是 OODER 平台内置的分布式文件系统。你可以把它理解为一个"共享文件柜":Studio 把源码放进文件柜的 A 抽屉,Isolated JVM 从 A 抽屉取出源码进行编译,然后把编译产物放进 B 抽屉,Studio 再从 B 抽屉取出产物使用。双方不需要直接对话,只需要看文件柜里有没有新文件。
独立的 JVM 只是"硬件",要让这个构建 Agent 真正"智能"地工作,还需要一个治理框架。这就是 ooderAgent 的核心价值。
ooderAgent 是 OODER 平台的 Agent 治理框架。你可以把它理解为一个大楼的物业系统:每个房间(Agent)有自己的门牌号(Agent ID),房间里的设备(Skill)有自己的功能编号(Capability)。当有人需要某个服务时,不需要知道具体房间在哪里,只需要告诉物业"我需要某个服务",物业就会帮你找到对应的房间和设备。
ooderAgent 定义了两类核心角色:
角色 | 职责 | 在 Agent Build 中的定位 |
|---|---|---|
McpAgent | 中心控制节点,负责 Agent 注册、发现、心跳监控和指令下发 | Studio 主进程中的 Agent 管理器 |
EndAgent | 终端代理,负责在终端节点上安装、卸载、调用技能,执行具体任务 | Isolated JVM 中的 CodeGenAgent |
EndAgent 接口定义了终端代理的完整生命周期管理能力:
// EndAgent 核心接口:终端代理的能力契约
public interface EndAgent extends Agent {
String getAgentId(); // 唯一身份标识
String getEndpoint(); // 通信端点地址
void start(); // 启动 Agent
void stop(); // 停止 Agent
boolean isHealthy(); // 健康检查
// 技能生命周期管理
CompletableFuture<Void> installSkill(SkillPackage pkg);
CompletableFuture<Void> uninstallSkill(String skillId);
CompletableFuture<List<String>> listInstalledSkills();
// 技能调用
CompletableFuture<Map<String, Object>> invokeSkill(String skillId,
Map<String, Object> params);
// 心跳与故障转移
CompletableFuture<Void> heartbeat();
CompletableFuture<Void> handleFailover(String sceneGroupId,
String failedMemberId);
}Studio 需要向 Isolated JVM 下达指令:"编译这个项目"、"启动调试"、"停止调试"、"打包发布"。这些指令通过 ooderAgent 的 A2A(Agent-to-Agent)协议传输。
A2A 协议是 ooderAgent 框架定义的 Agent 间通信协议。你可以把它理解为对讲机系统:Studio(McpAgent,中心控制节点)对着对讲机说"请执行编译任务",Isolated JVM 中的 CodeGenAgent(EndAgent,终端代理)收到指令后,将任务分发给对应的 Skill。执行完成后,Skill 通过对讲机回复"编译成功,生成 15 个类文件"。
通俗解释 A2A 协议
A2A(Agent-to-Agent)协议就像对讲机系统。不同 Agent 之间通过对讲机通话,不需要知道对方在哪里,只需要知道对方的"频道号"(Agent ID)。McpAgent 是"总台",负责调度所有对讲机;EndAgent 是"手持机",负责接收指令并执行。
A2A 协议支持心跳检测:Studio 每 5 秒向 Isolated JVM 发送一次心跳,如果连续 3 次没有收到回复,就认为 Isolated JVM 已经崩溃,自动重启一个新的实例。新的实例会从 VFS 拉取最新的源码,继续工作。
故障自愈
如果 Isolated JVM 因为编译错误而崩溃,Studio 会在 30 秒后自动检测到心跳丢失,然后启动一个新的 Isolated JVM 实例。新的实例会从 VFS 拉取最新的源码,继续工作。用户几乎感知不到中断——最多只是 Console 中多了一条"Agent 已重启"的提示。
有了独立的 JVM 和 Agent 治理框架,还需要回答一个问题:构建 Agent 到底能做什么?怎么做? 这就是 ooder Skills 规范的使命。
在 ooderAgent 框架中,Skill(技能)是 Agent 的能力单元。你可以把 Skill 理解为 Agent 的"职业技能证书":一个 Agent 可以拥有多个 Skill,每个 Skill 定义了它能做什么、需要什么参数、返回什么结果。
Skill 的核心定义由 SkillDefinition 描述:
// Skill 定义:一个技能的身份和能力描述
public class SkillDefinition implements Serializable {
private String skillId; // 技能唯一标识
private String skillType; // 技能类型(如 skill-org, skill-vfs)
private String name; // 技能名称
private String description; // 技能描述
private String version; // 版本号
private Map<String, Object> config; // 配置参数
private Map<String, Object> capabilities; // 能力声明
private List<String> supportedOperations; // 支持的操作列表
private int timeout; // 超时时间(毫秒)
private boolean asyncSupported; // 是否支持异步执行
private Map<String, Object> metadata; // 扩展元数据
}每个 Skill 都有一个 SkillManifest(技能清单),相当于技能的"简历"。它采用 Kubernetes 风格的声明式格式,包含 metadata(元信息)、spec(规格)和 capabilities(能力列表):
// SkillManifest:技能的完整简历(Kubernetes 风格)
public class SkillManifest {
private String apiVersion; // API 版本
private String kind; // 资源类型
private Metadata metadata; // 元信息(id, name, version, author...)
private Spec spec; // 规格定义
// 能力声明
private List<Capability> capabilities;
private List<Dependency> dependencies; // 依赖的其他 Skill
// 协作能力(多 Agent 协作时使用)
private List<String> collaborativeCapabilities;
// 自驱入口配置(mainFirst)
private SceneConfig mainFirstScene;
}在 Agent Build 场景中,我们将编译、调试、发布等构建过程封装为四个标准化的 Skill:
技能 | 能力标识 | 通俗解释 | 对应构建阶段 |
|---|---|---|---|
GenJavaSkill | codegen:gen-java | "代码生成员"——把 .cls 视图文件转成 .java 源码 | 代码生成 |
CompileSkill | codegen:compile | "编译员"——调用 Maven 把 .java 编译成 .class | 编译构建 |
DebugSkill | codegen:debug | "调试员"——启动 Spring Boot 应用供预览 | 调试运行 |
DeploySkill | codegen:deploy | "打包员"——执行 mvn package 生成可部署 JAR | 发布部署 |
SkillService 是 ooderAgent 框架中的技能管理服务,相当于"人力资源部":负责技能的发现、安装、卸载、更新和查询。
// SkillService:技能的人力资源管理
public class SkillService {
// 发现技能:在技能市场中搜索
CompletableFuture<SkillPackage> discoverSkill(String skillId);
CompletableFuture<List<SkillPackage>> discoverAllSkills();
// 安装/卸载技能
CompletableFuture<InstallResult> installSkill(String skillId);
CompletableFuture<UninstallResult> uninstallSkill(String skillId);
// 查询已安装技能
CompletableFuture<List<InstalledSkill>> listInstalledSkills();
CompletableFuture<Boolean> isSkillInstalled(String skillId);
// 获取技能详情
CompletableFuture<SkillManifest> getSkillManifest(String skillId);
}通过 SkillService,Agent 可以动态地发现和安装技能。这意味着:构建 Agent 的能力不是写死的,而是可以动态扩展的。未来如果需要支持 Gradle 构建、Node.js 构建,只需要开发新的 Skill 并安装到 Agent 中即可,无需修改 Agent 本身的代码。
Skills 规范的核心价值
ooder Skills 规范解决了三个关键问题:标准化(所有 Skill 遵循统一的定义格式)、可发现(Skill 可以被自动扫描和注册)、可扩展(新 Skill 可以动态安装,无需重启 Agent)。这让 Agent Build 从"固定流水线"升级为"可插拔的能力市场"。
现在我们把三大支柱串起来,看看一个完整的 Agent Build 流程是什么样的。
触发条件:用户在 Studio 中输入自然语言(如"创建一个销售占比饼图"),或手动保存 .cls 文件。
执行流程:
versionspace/test/0/view/VfsWatchService 检测到文件变更GenJavaSkill,调用 D2CGenerator 将 .cls 转换为 .java 源码src/main/java/ 目录用户感知:Console 的 agent 通道显示"检测到文件变更,正在生成 Java 源码..."
触发条件:用户点击"编译"按钮,或 GenJavaSkill 生成完成后自动触发。
执行流程:
invokeSkill("codegen:compile", params)mvn compile用户感知:Console 的 build 通道显示 Maven 编译日志,编译成功后 UI 自动刷新。
触发条件:用户点击"调试"按钮。
执行流程:
invokeSkill("codegen:debug", params)用户感知:Studio 中打开预览窗口,看到实时渲染的 UI 组件。
触发条件:用户点击"发布"按钮。
执行流程:
invokeSkill("codegen:deploy", params)mvn package -DskipTests用户感知:Console 显示"打包成功",项目可以正式访问。
// Studio 侧:用户点击"编译"按钮
@Autowired private CodeGenBridgeService bridgeService;
public void onBuildClick(String projectVersionName) {
// 1. 确保 Isolated JVM 中的 CodeGenAgent 已启动
bridgeService.ensureAgent(projectVersionName);
// 2. 通过 A2A 协议调用 CompileSkill
Map<String, Object> result = bridgeService
.invokeSkill(projectVersionName, "codegen:compile", params)
.get(120, TimeUnit.SECONDS);
// 3. 处理编译结果
if ("success".equals(result.get("status"))) {
// 4. 从 VFS 拉取编译产物
bridgeService.pullCompiledClasses(projectVersionName);
// 5. 注册到 API 路由
bridgeService.registerDeployedArtifact(projectVersionName);
}
}让我们回到文章开头的问题:当 AI 代码生成器把 IDE 搞崩了,怎么办?
OODER 平台的答案是:不要试图在同一个房间里既做实验又办公,给实验配一个独立的工作室,再配一个智能管家和一套标准化的工具规范。这个"工作室"就是独立 JVM,"智能管家"就是 ooderAgent,"工具规范"就是 Skills 规范——三者共同构成了 Agent Build 技术体系。
Agent Build 带来的六大收益
Studio 的 MySpace 工程化管理模型已经为 Agent Build 做好了准备。每个项目的版本空间是天然隔离的,VFS 同步机制已经支持双向文件流转,Console 桥接已经支持多通道日志路由。Agent Build 不是"推翻重来",而是将现有的工程化管理能力从"同一 JVM 内的方法调用"升级为"跨 JVM 的 Agent 协议通信"。
这是 OODER 平台从单体应用向 Agent 集群演进的关键一步。未来,每个项目不仅可以拥有独立的编译 Agent,还可以拥有独立的测试 Agent、部署 Agent、监控 Agent——它们通过 ooderAgent 的 A2A 协议相互发现、相互调用,形成一个真正的分布式 Agent 集群。
而 Agent Build 只是开始。当 AI 不仅能生成代码,还能自主完成编译、调试、测试、部署的全流程时,我们离"AI 自主编程"的愿景就更近了一步。
OODER Architecture Team © 2026 | ooderAgent SDK | Agent Build 技术体系
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。