Ooder UI LLM Deep 匹配模式深度解析

0 阅读12分钟

一、背景与概述

1.1 行业困境

随着大语言模型能力的指数级跃升,AI 生成用户界面(UI)代码已从概念验证走向工程化落地。然而,当前主流方案普遍面临三大核心困境:

困境表现影响
生成质量不可控LLM 自由生成的 UI 代码混用内联样式、原生 DOM 操作与框架特定 API样式污染、事件泄漏、行为失控,难以纳入组件化体系
运行时存在盲区传统生成链路止于静态代码输出,LLM 无法感知浏览器真实渲染效果错误配置反复出现,缺乏自修正能力
能力边界模糊LLM 对组件语义、样式变量体系、事件回调规范理解碎片化需要大量 prompt 工程,维护成本高且通用性差

1.2 Ooder UI 的演进方向

上述问题本质上指向同一个需求:让 LLM 从"代码生成器"升级为具备工程审计闭环与运行时感知能力的**"智能 UI 工程师"**。

Ooder UI 正是在这一背景下诞生的——一个注解驱动、四分离合规、支持 LLM-Browser 双向观察的智能 UI 组件生成框架。

更重要的是,Ooder UI 正在逐步向 A2UI 原生的 AI UI 能力靠近

  • 从代码生成到组件原生:不再生成独立的 JavaScript 代码文件,而是直接操作 A2UI 框架的原生组件实例
  • 从静态输出到运行时融合:LLM 输出直接映射为组件的 Properties/Styles/Events/Behaviors 配置,与框架运行时无缝集成
  • 从单向生成到双向闭环:通过 LLM-Browser 双向观察接口,实现"生成 → 审计 → 运行 → 反馈 → 修正"的完整闭环
  • 从 Prompt 工程到注解驱动:通过 @A2uiSkill@NlpDescription 等注解声明式定义组件能力,减少 prompt 维护成本

1.3 核心设计理念

  • 声明式组件定义:通过 @A2uiSkill 注解定义组件能力元数据
  • 场景化路由:多场景智能匹配,自动选择最佳处理路径
  • 四分离合规:Properties / Styles / Events / Behaviors 维度审计
  • 闭环迭代:LLM 生成 → 审计 → 反馈修正 → 运行时验证 → 再生成

1.4 技术栈概览

层级技术组件职责
路由层StudioChatRouter场景匹配与分发
场景层ChatScene 实现类业务逻辑处理
执行层FunctionCallingLoopExecutor多轮工具调用循环
审计层NlpModuleAuditor四分离合规审计
观察层DebugAgent.js + DebugContextManagerLLM-Browser 双向观察
知识层SkillMdLoader知识文件加载与工具注册

二、系统架构

下图展示了 Ooder UI LLM Deep 匹配模式的整体架构,从用户输入到最终输出合规代码的完整链路:

请在此添加图片描述

2.1 核心组件说明

StudioChatRouter(场景路由器)

文件路径: net\ooder\studio\chat\router\StudioChatRouter.java

负责根据用户输入计算各场景的匹配分数,选择最佳场景处理请求:

public ChatResponse route(ChatRequest request, ChatContext context) {
    ChatScene bestScene = null;
    double bestScore = -1;

    for (ChatScene scene : scenes) {
        if (scene.canHandle(request.getContent(), context)) {
            double score = scene.matchScore(request.getContent(), context);
            if (score > bestScore) {
                bestScore = score;
                bestScene = scene;
            }
        }
    }

    if (bestScene != null) {
        return bestScene.handle(request, context);
    }
    return null;
}

FunctionCallingLoopExecutor(核心执行引擎)

文件路径: \net\ooder\studio\chat\engine\FunctionCallingLoopExecutor.java

实现多轮 Function Calling 循环,支持结构化和文本模式工具调用解析:

public static class LoopConfig {
    private int maxRounds = 5;           // 最大循环轮数
    private boolean supportsTextMode = true; // 支持文本模式工具调用解析
    private long toolTimeoutMs = 30000;   // 单工具超时 30s
    private long llmTimeoutMs = 120000;   // LLM 调用超时 120s
    private long totalTimeoutMs = 180000; // 总超时 180s
}

三、场景体系(ChatScene)

Ooder UI 定义了多种 ChatScene 实现,每种场景针对特定类型的任务进行优化:

场景类场景ID核心能力匹配关键词
RadChatSceneradRAD 快速构建,NLP 组件生成表单、表格、图表、页面
DeepDesignChatScenedeep-design深度设计,四分离审计闭环深度设计、复杂布局
SVGDeepDesignChatScenesvg-deep-designSVG 矢量设计,图形验证流程图、架构图、拓扑图
BpmChatScenebpmBPM 流程设计,节点编排流程、节点、审批
SkillsChatSceneskills技能管理,插件扩展技能、插件、安装

3.1 RadChatScene 实现解析

文件路径: net\ooder\studio\chat\scene\impl\RadChatScene.java

RadChatScene 是最常用的场景,支持通过自然语言快速构建 UI 组件:

@Override
public double matchScore(String input, ChatContext context) {
    if (context != null && "rad".equals(context.getSceneId())) {
        return 10.0;  // 已锁定场景
    }

    String lower = input.toLowerCase();
    double score = 0;

    // UI 上下文关键词
    String[] uiContextKeywords = {"组件", "表单", "表格", "树", "图表", "页面", ...};
    for (String kw : uiContextKeywords) {
        if (lower.contains(kw)) score += 3.0;
    }

    // 动作关键词
    String[] actionKeywords = {"生成", "创建", "构建", "做一个", ...};
    for (String kw : actionKeywords) {
        if (lower.contains(kw)) score += 2.0;
    }

    return score;
}

3.2 DeepDesignChatScene 双阶段闭环

DeepDesignChatScene 实现了双阶段闭环流程

  1. 阶段1(自由构建):LLM 自由发挥生成完整的 ood.Class 模块代码
  2. 阶段2(合规修正):根据四分离审计结果逐项修正,迭代最多 3 轮直到评分 ≥ 80

四、Function Calling 循环机制

FunctionCallingLoopExecutor 是整个 LLM Agent 的核心执行引擎,实现了完整的 Function Calling 多轮循环机制:

请在此添加图片描述

4.1 双模式工具调用解析

当 LLM 未返回结构化 tool_calls 时,系统会从文本内容中解析三种格式的工具调用:

模式格式示例解析方式
XML 格式toolName{...}正则提取
JSON 代码块json {"function":"...", "arguments":{...}} JSON 解析
自然语言调用: toolName,参数: {...}模式匹配

4.2 上下文压缩机制

当估算 token 数超过 200,000 时,自动压缩中间消息:

private List<Map<String, Object>> compressMessages(List<Map<String, Object>> messages) {
    int estimatedTokens = estimateTokens(messages);
    if (estimatedTokens <= 200000) return messages;

    // 保留首尾,中间截断为摘要
    List<Map<String, Object>> compressed = new ArrayList<>();
    compressed.add(messages.get(0));  // system prompt

    // 中间消息压缩为摘要
    String summary = buildSummary(messages.subList(1, messages.size() - 1));
    compressed.add(Map.of("role", "system", "content", "[历史摘要] " + summary));

    compressed.add(messages.get(messages.size() - 1));  // 最新消息
    return compressed;
}

4.3 可用工具列表

RadChatScene 提供了丰富的工具供 LLM 调用:

工具名功能参数
nlp_build_component通过自然语言生成 UI 组件description (组件描述)
update_component更新组件属性alias, properties
get_component_template获取组件四分离模板componentType
get_style_template获取样式模板templateId, componentType, theme
get_event_template获取事件模板templateId, componentType
get_advanced_knowledge获取高级知识topic (event/action/style/annotation)

五、四分离合规审计系统

NlpModuleAuditor 是 Ooder 框架的四分离合规审计引擎,负责对 LLM 生成的代码进行结构化分析和合规评分:

请在此添加图片描述

5.1 四分离维度定义

维度英文标识检查内容禁止 API
属性 (Properties)propertiesScore声明式构建、setHost 绑定setHtml, innerHTML
样式 (Styles)stylesScoresetCustomStyle、CSS 变量体系内联 style 属性
事件 (Events)eventsScore生命周期钩子、组件事件绑定addEventListener
行为 (Behaviors)behaviorsScoredataUrl 数据驱动setTimeout, 手动 DOM

5.2 分级约束体系

文件路径: net\ooder\studio\chat\scene\impl\NlpModuleAuditor.java

public enum ConstraintLevel {
    MANDATORY,    // 架构红线,必须修正 (扣25分)
    RECOMMENDED,  // 推荐修正 (扣15分)
    ENHANCED      // 增强优化 (扣5分)
}

5.3 意图感知权重

根据页面类型动态调整四个维度的权重:

case PORTAL:    return new double[]{0.30, 0.20, 0.20, 0.30}; // 门户:属性和行为权重高
case DASHBOARD: return new double[]{0.20, 0.15, 0.25, 0.40}; // 仪表盘:行为权重最高
case FORM:      return new double[]{0.35, 0.15, 0.35, 0.15}; // 表单:属性和事件权重高
case LANDING:   return new double[]{0.20, 0.35, 0.20, 0.25}; // 落地页:样式权重最高

5.4 遗忘与降级机制

当组件评分过低时,系统会建议遗忘或降级:

  • 遗忘分 < 40:标记为 ABANDON(建议放弃该组件)
  • 遗忘分 40-70:标记为 DOWNGRADE(降级为更简单的组件)

六、LLM-Browser 双向观察接口

当前 Ooder UI 的 LLM 交互能力集中在推理阶段(NLP解析→配置生成→静态审计),但在浏览器真实运行期存在严重盲区。LLM-Browser 双向观察接口设计旨在解决这一问题,实现完整的闭环。

6.1 现状痛点

盲区表现影响
运行时错误不可见LLM生成的组件在浏览器中报错,LLM无法感知错误配置反复生成,无法自修正
虚拟DOM树不可查组件的实际渲染结构LLM无法获取布局/嵌套错误无法定位
四分离数据不可采Properties/Styles/Events/Behaviors运行时实际值LLM无法获取样式偏差/事件失效无法诊断
样式实际展示不可测CSS计算值、布局位置、溢出/遮挡LLM无法感知视觉效果与预期不符
交互行为不可模拟LLM无法模拟点击/输入/拖拽等用户操作交互逻辑无法验证

6.2 两条反向路径

路径1: 设计期 — RAD设计器 → 观察接口 → LLM

在设计器中自动打开组件,通过观察接口获取实际位置/样式/四分离数据,动态返回给LLM供参考和修改

路径2: 运行期 — LLM → 浏览器插件Skills → 单页面调试

允许大模型通过浏览器插件Skills打开单页面调试,进行动作/行为模拟操作,并设计开放接口体系和知识体系给LLM

6.3 架构总览

请在此添加图片描述

6.4 设计期观察接口(路径1)

接口名功能返回数据
observe_component_tree观察组件树结构组件层级、属性、样式、事件、行为
observe_component_layout观察组件布局boundingRect、computedStyle、overflow
observe_four_separation观察四分离数据Properties/Styles/Events/Behaviors 运行时值
observe_style_computed观察样式计算值CSS变量实际值、主题色值、字体大小
observe_errors收集运行时错误JS错误、CSS警告、网络错误、控制台日志

observe_four_separation 返回示例

{
  "type": "four_separation",
  "alias": "mainForm",
  "properties": {
    "caption": "用户信息",
    "columns": 2,
    "dock": "fill",
    "editable": true
  },
  "styles": {
    "MAINFRAME": { "background": "var(--ood-bg)", "padding": "16px" }
  },
  "events": {
    "SAVE": { "eventClass": "FormCallBack", "eventValue": "SAVE", "bound": true }
  },
  "behaviors": {
    "SUBMIT": { "actionClass": "CustomFormAction", "actionValue": "SUBMIT", "enabled": true }
  },
  "discrepancies": [
    { "dimension": "styles", "field": "MAINFRAME.background", "declared": "var(--ood-bg)", "computed": "#ffffff" }
  ]
}

6.5 运行期调试接口(路径2)

接口名功能参数
debug_open_page打开调试页面pageUrl, breakOnErrors, collectMetrics
debug_simulate_action模拟用户操作action (click/input/hover/scroll), target, params
debug_inspect_dom检查DOM状态target, depth, includeStyles, includeEvents
debug_collect_errors收集运行时错误debugSessionId
debug_screenshot截图捕获target, format (base64/description)

6.6 浏览器端 DebugAgent.js

规划文件路径: ood\js\OODDebugAgent.js

ood.Class('OOD.DebugAgent', 'ood.Module', {
    Instance: {
        startCollect: function () {
            var self = this;
            window.onerror = function (msg, url, line, col, error) {
                self.reportError('javascript', {
                    message: msg, source: url, line: line, column: col,
                    stack: error ? error.stack : ''
                });
            };
            // ... 更多错误采集
        },
        collectFourSeparation: function (alias) {
            var widget = designer.getByAlias(alias, true);
            return {
                alias: alias,
                properties: widget.properties,
                styles: widget.CS,
                events: widget.events,
                behaviors: widget.actions,
                discrepancies: this._findDiscrepancies(widget)
            };
        },
        simulateAction: function (action, target, params) {
            var widget = SPA.getWidgetByAlias(target);
            switch (action) {
                case 'click': widget.$dom.click(); break;
                case 'input': widget.setValue(params.value); break;
                // ... 更多操作
            }
            return { success: true, action: action, target: target };
        }
    }
});

6.7 完整闭环流程

请在此添加图片描述

6.8 调试上下文注入 LLM

规划文件路径:debug\service\DebugContextManager.java

public String buildLlmContextSummary(String sessionId) {
    DebugContext ctx = contexts.get(sessionId);
    StringBuilder sb = new StringBuilder();
    sb.append("## 调试上下文\n");
    sb.append("阶段: ").append(ctx.phase).append("\n");
    sb.append("页面: ").append(ctx.pageUrl).append("\n");

    if (!ctx.errorHistory.isEmpty()) {
        sb.append("### 运行时错误\n");
        for (RuntimeErrorReport report : ctx.errorHistory) {
            sb.append("- [").append(report.getSeverity()).append("] ")
              .append(report.getMessage()).append("\n");
        }
    }

    if (ctx.lastTreeSnapshot != null) {
        sb.append("### 组件树概要\n");
        sb.append("组件总数: ").append(ctx.lastTreeSnapshot.getTotalCount()).append("\n");
    }
    return sb.toString();
}

6.9 与现有架构的集成

集成点集成方式
StudioChatRouter在合规审计阶段自动添加观察工具
NlpChatInline处理调试工具结果,展示组件树/四分离面板
LlmFallbackStep注入调试上下文到回退提示
ClsAuditStep审计失败时自动触发设计期观察

七、Skill 注解驱动体系

Ooder UI 采用注解驱动的方式定义组件能力元数据,实现声明式的组件注册与发现:

请在此添加图片描述

7.1 核心注解定义

@A2uiSkill 注解

文件路径: net\ooder\annotation\skill\A2uiSkill.java

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface A2uiSkill {
    String id();
    String name() default "";
    String description() default "";
    String category() default "data-display";
    String[] capabilities() default {};
    ModuleViewType moduleViewType() default ModuleViewType.NONE;
    ComponentType componentType() default ComponentType.MODULE;
    int priority() default 100;
}

@NlpDescription 注解

文件路径: net\ooder\engine\llm\annotation\NlpDescription.java

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NlpDescription {
    String value();           // 自然语言描述
    String[] examples() default {};  // 描述示例
    String[] synonyms() default {};  // 同义词
    int priority() default 0;        // 优先级
}

7.2 Skill 实现示例

TreeGridSkill(表格组件)

文件路径: net\ooder\a2ui\nlp\skill\TreeGridSkill.java

@Component
@A2uiSkill(
    id = "treegrid",
    name = "表格",
    description = "表格/树表组件,用于展示结构化数据,支持编辑、排序、多级树形结构",
    category = "data-display",
    capabilities = {"data-display", "crud", "pagination", "tree"},
    moduleViewType = ModuleViewType.GRIDCONFIG,
    componentType = ComponentType.TREEGRID,
    priority = 10
)
public class TreeGridSkill extends AbstractA2uiSkill {
    @Override
    public List<String> getKeywords() {
        return Arrays.asList("表格", "列表", "树表", "数据表", "grid", "table");
    }

    @Override
    public String buildGenJson(String moduleName, String caption, 
                               List<String> fields, Map<String, Object> options) {
        // 构建组件 JSON 配置
        JSONObject treeGridComponent = new JSONObject();
        treeGridComponent.put("alias", "mainGrid");
        treeGridComponent.put("type", "TreeGrid");
        // ... 配置属性
        return buildModuleFromTemplate(moduleName, properties, children);
    }
}

7.3 元数据类

运行时通过元数据类封装注解信息,支持 Builder 模式构建:

NlpComponentDesc(组件描述元类)

文件路径: net\ooder\engine\llm\meta\NlpComponentDesc.java

public class NlpComponentDesc {
    private String className;
    private String description;
    private String[] intents;
    private List<NlpFieldDesc> fields;
    private List<NlpActionDesc> actions;

    // 构建 LLM 提示词
    public String toPrompt() {
        StringBuilder sb = new StringBuilder();
        sb.append("组件:").append(className).append("\n");
        sb.append("描述:").append(description).append("\n");
        // ... 更多信息
        return sb.toString();
    }
}

八、知识注入与 Prompt 工程

8.1 SkillMdLoader 知识加载

文件路径: net\ooder\studio\chat\engine\SkillMdLoader.java

SkillMdLoader 负责从 SKILL.md 文件中加载、解析和注册整个技能体系:

// 知识分为两级
private static final Set<String> BASIC_KNOWLEDGE_FILES = Set.of(
    "basic.md", "style-quickref.md", "event-quickref.md", "behavior-quickref.md",
    "chart-components.md", "display-components.md", "container-components.md"
);
private static final int MAX_KNOWLEDGE_CHARS = 16000;  // 基础知识总长度限制

8.2 Prompt 文件结构

知识文件路径: skills\rad-component-reader\

skills/
└── rad-component-reader/
    ├── SKILL.md                    # 技能定义
    ├── knowledge/
    │   ├── basic.md               # 基础知识
    │   ├── style-quickref.md      # 样式快速参考
    │   ├── event-quickref.md      # 事件快速参考
    │   └── _four-separation.md    # 高级知识 (以下划线开头)
    └── prompts/
        ├── deep-design.md         # 深度设计提示词
        ├── rad.md                 # RAD 提示词
        └── intent-recognition.md  # 意图识别提示词

8.3 deep-design.md 提示词结构

文件路径:resources\skills\rad-component-reader\prompts\deep-design.md

定义了双阶段闭环流程:

  • 阶段1:自由构建 - LLM 自由发挥生成完整代码
  • 阶段2:合规修正 - 根据审计结果逐项修正
  • ood.Class 模块结构模板
  • 复杂布局组件选择指南(门户/仪表盘/落地页/控制台)
  • CS Key 快速参考表
  • CSS 变量体系参考

九、总结

Ooder UI 的 LLM Deep 匹配模式是一个完整的智能 UI 组件生成解决方案,其核心创新点包括:

  1. 注解驱动的 Skill 体系:通过 @A2uiSkill@NlpDescription 等注解声明式定义组件能力
  2. 多场景智能路由:根据关键词匹配分数自动选择最佳处理场景
  3. Function Calling 循环:支持多轮工具调用,双模式解析,上下文自动压缩
  4. 四分离合规审计:从 Properties/Styles/Events/Behaviors 四个维度确保代码质量
  5. LLM-Browser 双向观察:设计期观察 + 运行期调试,实现完整闭环
  6. 双阶段闭环迭代:自由构建 → 审计反馈 → 合规修正 → 运行时验证
  7. 知识分级注入:基础知识始终加载,高级知识按需获取

本文深入解析了 Ooder UI LLM Deep 匹配模式的核心实现,包括注解驱动的 Skill 体系、四分离合规审计、以及 LLM-Browser 双向观察接口设计。通过这些机制,实现了从代码生成到运行时验证的完整闭环。