首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Ooder UI LLM Deep 匹配模式深度解析

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

原创
作者头像
OneCode
发布2026-05-16 18:54:42
发布2026-05-16 18:54:42
1320
举报
文章被收录于专栏:ooderAgentooderAgent

一、背景与概述

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 + DebugContextManager

LLM-Browser 双向观察

知识层

SkillMdLoader

知识文件加载与工具注册

二、系统架构

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

2.1 核心组件说明

StudioChatRouter(场景路由器)

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

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

代码语言:javascript
复制
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 循环,支持结构化和文本模式工具调用解析:

代码语言:javascript
复制
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

核心能力

匹配关键词

RadChatScene

rad

RAD 快速构建,NLP 组件生成

表单、表格、图表、页面

DeepDesignChatScene

deep-design

深度设计,四分离审计闭环

深度设计、复杂布局

SVGDeepDesignChatScene

svg-deep-design

SVG 矢量设计,图形验证

流程图、架构图、拓扑图

BpmChatScene

bpm

BPM 流程设计,节点编排

流程、节点、审批

SkillsChatScene

skills

技能管理,插件扩展

技能、插件、安装

3.1 RadChatScene 实现解析

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

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

代码语言:javascript
复制
@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 格式

<name>toolName</name><arguments>{...}</arguments>

正则提取

JSON 代码块

```json {"function":"...", "arguments":{...}} ```

JSON 解析

自然语言

调用: toolName,参数: {...}

模式匹配

4.2 上下文压缩机制

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

代码语言:javascript
复制
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)

stylesScore

setCustomStyle、CSS 变量体系

内联 style 属性

事件 (Events)

eventsScore

生命周期钩子、组件事件绑定

addEventListener

行为 (Behaviors)

behaviorsScore

dataUrl 数据驱动

setTimeout, 手动 DOM

5.2 分级约束体系

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

代码语言:javascript
复制
public enum ConstraintLevel {
    MANDATORY,    // 架构红线,必须修正 (扣25分)
    RECOMMENDED,  // 推荐修正 (扣15分)
    ENHANCED      // 增强优化 (扣5分)
}

5.3 意图感知权重

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

代码语言:javascript
复制
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 返回示例
代码语言:javascript
复制
{
  "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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
@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

代码语言:javascript
复制
@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

代码语言:javascript
复制
@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

代码语言:javascript
复制
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 文件中加载、解析和注册整个技能体系:

代码语言:javascript
复制
// 知识分为两级
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\

代码语言:javascript
复制
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 双向观察接口设计。通过这些机制,实现了从代码生成到运行时验证的完整闭环。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、背景与概述
    • 1.1 行业困境
    • 1.2 Ooder UI 的演进方向
    • 1.3 核心设计理念
    • 1.4 技术栈概览
  • 二、系统架构
    • 2.1 核心组件说明
      • StudioChatRouter(场景路由器)
      • FunctionCallingLoopExecutor(核心执行引擎)
  • 三、场景体系(ChatScene)
    • 3.1 RadChatScene 实现解析
    • 3.2 DeepDesignChatScene 双阶段闭环
  • 四、Function Calling 循环机制
    • 4.1 双模式工具调用解析
    • 4.2 上下文压缩机制
    • 4.3 可用工具列表
  • 五、四分离合规审计系统
    • 5.1 四分离维度定义
    • 5.2 分级约束体系
    • 5.3 意图感知权重
    • 5.4 遗忘与降级机制
  • 六、LLM-Browser 双向观察接口
    • 6.1 现状痛点
    • 6.2 两条反向路径
    • 6.3 架构总览
    • 6.4 设计期观察接口(路径1)
      • observe_four_separation 返回示例
    • 6.5 运行期调试接口(路径2)
    • 6.6 浏览器端 DebugAgent.js
    • 6.7 完整闭环流程
    • 6.8 调试上下文注入 LLM
    • 6.9 与现有架构的集成
  • 七、Skill 注解驱动体系
    • 7.1 核心注解定义
      • @A2uiSkill 注解
      • @NlpDescription 注解
    • 7.2 Skill 实现示例
      • TreeGridSkill(表格组件)
    • 7.3 元数据类
      • NlpComponentDesc(组件描述元类)
  • 八、知识注入与 Prompt 工程
    • 8.1 SkillMdLoader 知识加载
    • 8.2 Prompt 文件结构
    • 8.3 deep-design.md 提示词结构
  • 九、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档