AI 助手概述与能力
VTJ.PRO 中的 AI 助手是一个复杂的多模态智能副驾驶,它将自然语言处理、计算机视觉和自动代码生成无缝集成到视觉设计工作流中。这个全面的助手作为人类意图与机器执行之间的智能桥梁,使开发者能够通过对话界面、视觉输入和结构化数据来创建、修改和增强低代码应用程序。
核心架构与设计理念
AI 助手运行在分布式 Agent 架构上,该架构协调多个专门的子系统以提供连贯的智能体验。其基础是连接外部 LLM 服务的 OpenAPI 集成层,而 Agent 系统 处理解析、工具执行和状态管理。该架构强调模块化,允许每个组件独立演进,同时在整个平台中保持一致的接口。
架构设计遵循几个关键原则:状态隔离 确保 AI 操作不会干扰设计器的核心状态,流式响应 在生成过程中提供实时反馈,工具调用 使 AI 能够直接与设计器的功能交互。系统通过主题和聊天的分层结构维护对话上下文,允许具有持久状态的多轮对话 useAI.ts。
核心能力概览
AI 助手提供四种基本交互模式,每种模式都针对低代码开发生命周期中的特定用例进行了优化:
| 能力 | 输入模式 | 主要用例 | 输出格式 |
|---|---|---|---|
| 自然语言生成 | 文本提示词 | 创建组件、修改布局、实现逻辑 | Vue SFC 代码 + DSL |
| 设计元数据解析 | 图像文件 | 将 Figma/MasterGo 设计转换为代码 | 组件结构 + 样式 |
| 结构化数据导入 | JSON 文件 | 导入模式定义、API 规范 | 组件模型 + 绑定 |
| 对话式迭代 | 多轮对话 | 完善输出、修复错误、探索替代方案 | 增量更新 |
助手支持 自动应用模式,该模式自动将成功的生成应用到当前页面,显著加快迭代周期。可以根据用户偏好和工作流要求切换此模式。
自然语言到组件生成
基于文本的生成系统接受自然语言描述,并通过复杂的管道将其转换为生产就绪的 Vue 组件。当用户提交提示词时,系统首先捕获当前项目上下文——包括项目 DSL、当前块模式和生成的 Vue 源代码——然后将此上下文与提示词以及可用的工具描述一起打包给 LLM useAI.ts。
生成过程支持两种不同的输出模式:
- 完整生成模式:AI 生成标记为 ````vue` 代码块的完整 Vue 单文件组件 (SFC)。系统在转换为 DSL 之前验证输出是否为有效的 Vue SFC 格式 useAgent.ts。
- 增量更新模式:AI 生成标记为 ````diff
块的统一差异格式更改。系统使用codeIncrementalUpdater` 将这些补丁应用于现有源代码,从而在不重新生成整个组件的情况下实现精确修改 useAgent.ts。
工具调用与页面操作
助手实现了一个复杂的 工具调用系统,使 AI 能够直接与设计器的功能交互。当 AI 识别到用户请求需要特定操作(例如添加组件、修改属性或配置数据绑定)时,它会生成 JSON 格式的工具调用,系统通过工具注册表验证并执行这些调用 useAgent.ts。
工具注册表维护可用操作的目录,包括组件操作、属性配置、数据源管理和模式操作。每个工具都注册了其参数、描述和处理函数,使 AI 能够适当地理解和使用它们 useAgent.ts。
多模态输入处理
基于图像的设计解析
助手通过图像上传功能支持 视觉输入,使开发者能够将设计工件直接转换为代码。当用户上传图像(通常来自 Figma 或 MasterGo 等设计工具)时,系统将图像文件与当前项目上下文打包,并将其发送给专门的视觉模型 useAI.ts。
图像处理工作流从视觉输入中提取布局信息、组件层次结构、样式属性和交互元素。然后,系统将这些元数据转换为 VTJ 的 DSL 格式,创建的组件能够保持原始设计的视觉保真度和功能意图 useAI.ts。
JSON 数据集成
对于结构化数据输入,助手提供了 JSON 导入功能,用于处理模式定义、API 规范和配置数据。当用户上传 JSON 文件时,系统解析结构并自动生成相应的组件模型、数据源和属性绑定 useAI.ts。
此功能特别适用于:
- API 响应模式集成
- 数据库表结构导入
- 组件属性类型定义
- 开发用的模拟数据生成
对话管理与状态
AI 助手实现了 分层对话模型,将交互组织为主题和单独的聊天消息。每个主题代表一个连贯的讨论线程,专注于特定任务或目标,而聊天则捕获该线程内的单独交流 useAI.ts。
主题与聊天结构
interface AITopic {
id: string;
model: string;
prompt: string;
type?: 'text' | 'image' | 'json';
image?: string;
json?: string;
createdAt: string;
}
interface AIChat {
id: string;
topicId: string;
content: string;
reasoning: string;
status: 'Pending' | 'Success' | 'Failed' | 'Canceled';
vue?: string;
dsl?: any;
toolCallId?: string;
toolContent?: string;
message?: string;
tokens?: number;
thinking?: number;
}
系统在整个生成过程中维护 流式状态,允许用户实时查看 AI 的推理过程。这既包括最终输出内容,也包括支持推理跟踪的模型产生的任何思维链推理 useAI.ts。
自动继续逻辑
复杂的 shouldNext 评估根据当前输出确定助手何时应自动继续对话。系统在以下情况下自动触发后续操作:
- 工具调用已执行并返回结果
- 发生需要解决的错误
- AI 表示它需要额外的信息或步骤 useAgent.ts
这种智能继续创建了流畅的工作流,助手可以主动处理多步操作,而无需为每个步骤进行手动干预。
与设计器组件的集成
AI 助手与 设计器组件系统 深度集成,为交互提供了全面的 UI。位于 packages/designer/src/components/widgets/ai/ 的主组件包含多个专门组件,用于 AI 体验的不同方面:
| 组件 | 目的 | 主要功能 |
|---|---|---|
| index.vue | 主容器 | 主题管理、聊天显示 |
| chat-input.vue | 文本输入 | 多行支持、模型选择 |
| image-input.vue | 图像上传 | 拖放、预览 |
| json-input.vue | JSON 上传 | 验证、预览 |
| bubble.vue | 消息显示 | 流式内容、语法高亮 |
| stream-markdown.vue | Markdown 渲染 | 代码高亮、推理显示 |
| records.vue | 历史记录管理 | 主题列表、搜索、过滤 |
组件系统利用 useAI hook 提供与助手交互的所有必要方法,包括主题创建、聊天管理、内容应用和错误处理 useAI.ts。
AI 组件维护一个 代码可见性切换开关,允许用户隐藏或显示生成的代码块,从而在需要时能够专注于对话流程。此首选项在会话之间保留在本地存储中。
流式传输与实时反馈
助手为所有生成操作实施 实时流式传输,在生成内容时提供即时视觉反馈。流式处理程序处理来自 LLM 的传入块,增量更新聊天内容,并处理推理内容和完成信号的特殊标记 useAI.ts。
流式过程包括:
- 内容累积:逐块构建响应
- 推理跟踪:在可用时捕获思维链
- 令牌计数:监控使用情况以进行成本跟踪
- 状态更新:从待定到成功/失败的转换
- 自动滚动:在生成期间保持对话可见
- 错误处理:网络故障时的优雅降级
系统还支持取消进行中的操作,允许用户在输出不符合预期时停止生成 useAI.ts。
错误处理与恢复
AI 助手在多个层面实施全面的 错误处理 以确保稳健运行:
- 网络错误:检测并显示用户友好的消息
- 解析错误:检测并报告无效的 Vue SFC 或差异格式
- 工具执行错误:捕获并格式化以反馈给 AI
- DSL 转换错误:收集并呈现为可操作的消息
- 生成失败:状态跟踪并具有重试功能
当发生错误时,系统提供多种 恢复途径:
- 瞬态故障时自动重试
- 通过刷新功能手动重新生成
- 为后续提示词预填充错误消息
- 用于调试的详细错误信息 useAI.ts
错误消息设计为 AI 可消费,允许助手了解出了什么问题并在后续交互中尝试更正 useAgent.ts。
配置与设置
助手的行为通过从 OpenAPI 服务检索的 设置系统 控制。设置包括:
interface Settings {
mode: number; // 1: Normal, 2: Invite-only
invited?: boolean; // User invitation status
llm?: LLM; // Default model configuration
// Additional platform-specific settings
}
设置决定 访问控制(正常模式与仅邀请模式)和模型选择的默认配置。系统根据这些设置动态启用或禁用输入,确保正确执行访问控制 useAI.ts。
自然语言到组件的生成
VTJ 的自然语言转组件生成系统通过先进的 AI 驱动管道,将用户以自然语言表达的意图转化为功能性的 Vue 组件。该功能集成了大型语言模型与设计器的 DSL 架构,使开发者能够通过对话式界面创建页面、组件乃至整个应用程序,同时保持精细控制和优化生成代码各个方面细节的能力。
系统架构
AI 驱动的生成系统通过多层架构运行,协调自然语言理解、代码生成和设计器集成。系统的核心利用三个主要的 hooks 来协调整个工作流:useAI 用于聊天管理和 API 交互,useAgent 用于输出解析和工具执行,以及 Tool Registry 用于管理 LLM 可以调用的可用能力。
架构始于 AI Widget 界面,用户在此通过文本、图像或设计元数据输入请求。useAI hook 管理对话状态、上下文准备以及与后端服务的 API 通信。当 LLM 响应到达时,useAgent hook 根据预定义格式解析输出,执行任何工具调用,并将生成的 Vue 代码转换回 DSL 格式以集成到设计器引擎中。Tool Registry 提供了一组全面的操作,LLM 可以调用这些操作来操作页面、组件、API 和项目设置。
对话管理与状态
AI 对话系统通过基于主题的架构保持持久状态,其中每个用户请求都会启动一个新的主题,包含初始提示词、项目上下文以及所有后续交换。useAI hook 协调此生命周期,管理主题创建、聊天历史记录、流式响应以及与设计器引擎的状态同步。
主题充当 AI 交互的容器,存储模型选择、用户提示词、创建时的项目 DSL 以及聊天消息集合。每次聊天代表用户与 AI 之间的单次交换,支持不同的内容类型,包括文本响应、Vue 代码块、diff 更新、工具调用结果和推理内容。系统通过几种状态跟踪状态:Pending(等待响应)、Success(成功完成)、Failed(网络或处理错误)、Error(验证失败)和 Canceled(用户中断)。
系统利用 Vue 的响应式系统为聊天消息实现了响应式状态管理,使得当流式 LLM 响应到达时,UI 能够实时更新。这允许用户实时查看 AI 的推理和代码生成进度,而无需等待完整响应。
// Key state structures from useAI hook
export interface AIChat {
id: string;
content: string;
createdAt: string;
dsl: any;
message: string;
source?: string;
prompt: string;
reasoning: string;
status: 'Pending' | 'Success' | 'Failed' | 'Error' | 'Canceled';
tokens: number;
topicId: string;
userId: string;
userName: string;
thinking: number;
vue: string;
collapsed?: boolean;
image?: string;
json?: string;
type?: TopicType;
dataType?: TopicDataType;
toolCallId?: string;
toolContent?: string;
}
上下文准备与主题创建
在向 LLM 发送提示词之前,系统会准备全面的上下文,使模型能够理解当前项目状态、可用材料和用户需求。createTopicDto 函数通过从设计器引擎中提取当前项目 DSL、活动块的 schema 以及生成的 Vue 源代码来收集这些信息。
上下文准备包括几个关键组件:包含整个应用程序结构和依赖项的项目 DSL,代表正在编辑的页面或组件的当前块 DSL,为代码理解而从 DSL 生成的 Vue 源代码,包括路由配置的项目选项,以及告知 LLM 其可以执行可用操作的工具描述。这种丰富的上下文使 AI 能够生成与现有项目结构无缝集成并遵循既定模式的上下文适当的代码。
async function createTopicDto(
data: AISendData,
engine: UseAIOptions['engine']
) {
const { model, prompt = '', llm } = data;
const { projectDsl, dsl, source, options } = await createCommonDto(engine);
const tools = engine.toolRegistry.generateToolDescriptions();
const dto: TopicDto = {
model,
prompt,
options,
dsl: JSON.stringify(dsl),
project: JSON.stringify(projectDsl),
source,
llm: llm ? JSON.stringify(llm) : '',
tools: tools ? JSON.stringify(tools) : ''
};
return dto;
}
由 ToolRegistry 生成的工具描述尤为重要,因为它们为 LLM 提供了对可用操作的结构化理解。每个工具包括其名称、人类可读的描述和参数 schema,使 LLM 能够选择合适的工具并在需要时生成格式正确的工具调用。
输出解析与代码块检测
Agent 系统采用复杂的解析逻辑来识别和提取 LLM 响应中的不同类型内容。useAgent 中的 parseOutput 函数分析响应内容以检测用 markdown 代码围栏格式化的代码块,支持三种主要格式:用于完整组件生成的 Vue SFC,用于增量更新的 diff 块,以及用于工具调用的 JSON 块。
解析过程遵循优先级规则系统,其中每个规则定义了正则模式、验证函数和可选的解析逻辑。对于 Vue 块,系统验证内容是否包含所有三个必需的部分:template、script 和 style 标签。Diff 块根据需要 SEARCH/REPLACE 标记的特定模式进行验证。JSON 块被解析和验证,以确保它们代表具有 action 和 parameters 字段的有效工具调用。
const PARSE_RULES: readonly ParseRule[] = [
{
type: 'vue',
label: '全量生成',
regex: PARSER_REGEX.VUE,
validate: isValidVueSFC
},
{
type: 'diff',
label: '增量更新',
regex: PARSER_REGEX.DIFF,
validate: isValidDiffFormat
},
{
type: 'json',
label: '工具调用',
regex: PARSER_REGEX.JSON,
parse: (content: string) => JSON.parse(content)
}
] as const;
解析系统通过在应用昂贵的正则操作之前检查代码块标记来实现早期优化。如果响应不包含
vue、diff或json标记,系统将完全跳过正则匹配,从而提高纯文本响应的性能。
当检测到有效的代码块时,系统提取 markdown 围栏之间的内容并应用适当的验证。对于 Vue 块,这确保了在尝试转换之前 SFC 结构是有效的。对于 diff 块,它验证 SEARCH/REPLACE 格式以确保增量更新的正确应用。对于 JSON 块,它解析内容并验证其代表有效的工具调用结构。
工具系统与可用操作
工具系统为 LLM 提供了一个结构化接口来操作项目资源,支持超越简单代码生成的操作。工具在 ToolRegistry 中注册,并通过标准化的 schema 向 LLM 描述,其中包括工具名称、人类可读的描述和参数定义。当 LLM 需要执行操作(例如创建页面或更新 API)时,它会生成一个 JSON 工具调用,系统自动执行该调用。
内置工具
| 工具名称 | 描述 | 参数 |
|---|---|---|
getPages | 检索当前项目中的所有页面 | 无 |
createPage | 创建具有指定属性的新页面 | 页面对象(name, title, icon, dir, layout),parentId(可选) |
updatePage | 更新现有页面元数据 | 页面对象(id, name, title, icon 必需) |
removePage | 删除页面或目录 | id(字符串) |
getBlocks | 检索项目中的所有块组件 | 无 |
createBlock | 创建新的块组件 | 块对象(name, title) |
updateBlock | 更新块组件元数据 | 块对象(id, name, title) |
removeBlock | 删除块组件 | id(字符串) |
active | 在设计器中打开特定文件 | id(字符串) |
getCurrentFile | 获取当前打开文件的元数据 | 无 |
getCurrentFileContent | 获取当前打开文件的源代码 | 无 |
refresh | 刷新运行时以检查错误 | 无 |
setApi | 添加或更新项目 API | api 对象(name, url, method, label) |
getApis | 获取可用 API 列表 | 无 |
removeApi | 删除 API | name(字符串) |
setHomepage | 设置应用程序主页 | id(字符串) |
setGlobalCss | 设置应用程序全局 CSS | css(字符串) |
getSkills | 检索技能文档 | ids(字符串数组) |
getMenus | 获取项目菜单树结构 | 无 |
工具执行流程在解析器检测到 LLM 响应中的 JSON 代码块时开始。系统验证 JSON 是否代表具有 action 字段和可选 parameters 数组的有效工具调用。然后,它在 ToolRegistry 中定位相应的工具并使用提供的参数执行它。工具返回结果,结果被格式化并作为后续操作的上下文反馈给 LLM,从而实现复杂的多步骤工作流,AI 可以在其中规划和执行操作序列。
const callTool = async (tool: ToolCall) => {
let error: any = null;
const result = await engine.toolRegistry
.execute(tool.action, tool.parameters)
.catch((e) => {
error = e;
});
if (error) {
const msg = error?.message
? `错误信息:${createResultContent(error.message || '未知错误')}`
: '';
return `O: 工具调用执行失败!${msg}`;
}
const res = result ? `结果:${createResultContent(result)}` : '';
return `O: 工具调用执行成功。${res}`;
};
代码生成格式
系统支持三种不同的代码生成格式,每种格式都针对不同的用例进行了优化。完整的 Vue SFC 生成生成包含 template、script 和 style 部分的完整单文件组件,适用于创建新组件或页面。基于 diff 的增量更新通过 SEARCH/REPLACE 块提供对现有代码的有针对性修改,从而无需重新生成即可进行精确编辑。工具调用触发操作结构和元数据而不是代码内容的项目操作。
Vue SFC 生成
当 LLM 使用 vue 代码块响应时,触发完整的 Vue SFC 生成。系统验证内容是否包含所有三个必需的 SFC 部分:template、script 和 style 标签。验证通过后,Vue 代码使用解析器服务转换为 DSL 格式并应用于设计器,在项目结构中创建或更新组件。
<!-- Example generated Vue SFC -->
<template>
<div class="user-list">
<el-table :data="users" stripe>
<el-table-column prop="name" label="Name" />
<el-table-column prop="email" label="Email" />
<el-table-column prop="role" label="Role" />
</el-table>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { getUserList } from './api';
const users = ref([]);
onMounted(async () => {
users.value = await getUserList();
});
</script>
<style scoped>
.user-list {
padding: 20px;
}
</style>
Diff 增量更新
基于 Diff 的更新使用 SEARCH/REPLACE 格式,能够对现有代码进行精确修改。系统识别用 vue 代码围栏标记的块,然后将 diff 更新应用于当前源代码。这种方法特别适用于对组件进行特定更改,而无需 LLM 重新生成整个文件。
------- SEARCH
const users = ref([]);
onMounted(async () => {
users.value = await getUserList();
});
=======
const users = ref([]);
const loading = ref(false);
const fetchUsers = async () => {
loading.value = true;
users.value = await getUserList();
loading.value = false;
};
onMounted(() => {
fetchUsers();
});
+++++++ REPLACE
Diff 应用过程包括解析当前 Vue 源代码、识别 SEARCH 块并将其替换为相应的 REPLACE 块。系统验证 diff 格式以确保结构正确,并以原子方式应用更新,如果应用过程中发生错误则回滚。
Vue 转 DSL 转换
系统生成或修改 Vue 代码后,必须将 SFC 转换回 DSL 格式以便与设计器集成。convertVueToDsl 函数通过使用项目 DSL 和 Vue 源代码调用解析器服务来协调此过程。解析器分析 SFC,提取组件结构、绑定、事件和样式,并生成设计器引擎可以应用的相应 DSL schema。
转换过程处理几个复杂的转换:template 结构到节点树,script setup 组合到数据模型和方法,style 提取到样式定义,以及框架特定语法到 DSL 等效项。解析过程中的错误被捕获并连同具体的诊断信息一起报告给用户,从而可以通过 AI 对话进行迭代优化。
const convertVueToDsl = async (chat: AIChat) => {
if (!currentTopic.value) return;
const projectDsl = project.value?.toDsl() as ProjectSchema;
const { name = '', id = '' } = engine.current.value || {};
const source = chat.vue;
if (!source) return;
return await service.parseVue(projectDsl, {
id,
name,
source
});
};
成功转换后,DSL 通过引擎上的 applyAI 方法应用于设计器。这会用新的 schema 更新活动块,触发模拟器中的重新渲染,并更新页面结构。结果立即可见地显示在设计器中,允许用户通过可视化工具或继续 AI 对话来查看、编辑或优化生成的组件。
流式响应处理
系统实现了 LLM 响应的实时流式传输,以提供即时反馈并减少感知延迟。useAI 中的 completions 函数管理流式过程,接收生成的内容块并增量更新聊天状态。这使用户能够在完成之前看到 AI 的推理过程、代码生成进度和中间结果。
流式响应通过回调机制处理,该回调机制接收包含内容和推理字段增量更新的完成块。系统累积这些增量,更新响应式聊天对象,并跟踪令牌使用情况以进行监控和成本跟踪。流完成后,最终输出通过 agent 的解析管道处理,完整的聊天将保存到后端以进行持久化。
const completions = async (
chat: AIChat,
complete?: (chat: AIChat) => void
) => {
engine.state.streaming = true;
promptText.value = '';
chat.content = '';
chat.reasoning = '';
chat.status = 'Pending';
let thinking: number = 0;
const now = Date.now();
__currentCompletions = await chatCompletions(
chat.topicId,
chat.id,
async (data, done) => {
const choice = data?.choices?.[0];
const delta = choice?.delta;
if (delta) {
const content = delta.content || '';
const reasoning = delta.reasoning_content || '';
if (content) {
chat.content += content;
}
if (reasoning) {
chat.reasoning += reasoning;
thinking += Date.now() - now;
}
}
if (done) {
chat.status = 'Success';
chat.thinking = Math.ceil(thinking / 1000);
const output = await processOutput(chat);
await saveChat(chat);
complete && complete(output);
engine.state.streaming = false;
}
}
);
};
流式接口还支持取消,允许用户中断长时间运行的生成。取消后,系统停止流,将聊天状态更新为 Canceled,并清理资源。这提供了对 AI 交互的更好控制,并能够从不良的生成方向中恢复。
多模态输入支持
除了文本提示词外,系统还支持多种输入模态以适应不同的工作流程。图像输入支持设计到代码的工作流程,用户可以在其中上传截图、设计模型或 UI 线框图进行分析和组件生成。JSON 输入支持允许处理来自 Figma、MasterGo 或 Sketch 等设计工具的结构化设计元数据,以用于组件生成。
图像输入
图像输入通过 onPostImageTopic 函数处理,该函数准备包含图像文件以及项目上下文的主题 DTO。图像被上传到后端服务进行分析,LLM 接收图像和文本提示词以生成相应的组件。这使用户能够描述 UI 概念并提供视觉参考,从而实现更准确的生成。
const onPostJsonTopic = async (data: AISendJsonData) => {
loading.value = true;
const dto = await createImageTopicDto(data, engine);
const res = await postJsonTopic(dto);
// ... similar processing to image input
};
JSON 元数据输入
JSON 元数据输入支持来自外部工具的结构化设计数据。onPostJsonTopic 函数处理包含设计规范、组件层次结构或样式定义的 JSON 文件。这使得与设计系统和自动化管道集成成为可能,其中设计元数据以结构化格式可用。
const onPostJsonTopic = async (data: AISendJsonData) => { loading.value = true; const dto = await createImageTopicDto(data, engine); const res = await postJsonTopic(dto); // ... similar processing to image input};
多模态输入通过与文本输入相同的流式和解析管道处理,确保所有输入类型的行为和用户体验一致。系统在主题和聊天记录中保留输入类型,实现基于模态的不同处理逻辑,同时保持统一的对话管理。
错误处理与自动更正
系统在整个 AI 生成管道中实现了强大的错误处理,具有检测、报告和自动更正机制。错误可能发生在多个阶段:与 LLM 服务的网络通信、代码解析和验证、DSL 转换以及工具执行。每种错误类型都通过适当的恢复策略进行处理。
当 LLM 生成无法通过验证的无效代码时,系统会捕获错误详细信息,并在后续提示词中将其反馈给 LLM,其中包含错误消息和更正请求。此自动更正循环继续进行,直到生成有效代码或用户干预。错误消息格式清晰,描述了出了什么问题以及 LLM 应该修复什么,从而实现有效的自我更正。
const collectErrorMessage = (msg: any) => {
let message = '';
if (Array.isArray(msg)) {
message += '页面存在以下错误,请检查并修复:\n';
message += msg.join(';\n');
}
return message
? message
: '请检查代码是否有错误,是否符合模版和规则要求,并改正';
};
shouldNext 函数通过检查响应是否包含失败指示符或错误消息来确定是否继续自动更正循环。如果检测到错误,系统会自动生成包含错误信息的后续提示词,请求 LLM 修复问题。此迭代过程一直持续到成功生成或达到最大重试限制。
UI 集成与用户体验
AI 生成系统通过专用 Widget 集成到设计器中,该 Widget 提供用于与 AI 交互的对话式界面。该 Widget 在 packages/designer/src/components/widgets/ai/index.vue 中实现,具有聊天界面、消息历史记录、代码预览面板以及用于应用、刷新或取消生成的操作按钮。
Widget 功能
| 功能 | 描述 |
|---|---|
| Chat History | 浏览以前的对话并在主题之间切换 |
| Code Preview | 查看生成的 Vue 代码并带有语法高亮 |
| Auto-Apply | 自动将成功的生成应用于设计器 |
| Refresh | 重新生成以前提示词的内容 |
| Cancel | 中止正在进行的生成 |
| Expand/Collapse | 控制代码预览可见性以提高可读性 |
Widget 根据对话状态支持不同的输入模式:创建带有模型选择的新主题、提示词输入以及图像和 JSON 的文件上传选项。在活动对话期间,Widget 显示消息流,并带有关于工具执行状态的用户消息、AI 响应和系统通知的视觉指示器。
Widget 为聊天消息实现了响应式状态管理,使得当流式响应到达时能够实时更新。随着代码的生成,用户可以看到代码增量出现,并通过 markdown 渲染组件应用语法高亮。
实施示例
下面是一个完整的示例,演示了自然语言转组件生成工作流程:
此示例显示用户通过自然语言请求用户列表页面。系统使用项目信息和可用工具准备上下文,将请求发送到 LLM,并处理流式响应。当 LLM 生成 Vue 代码时,它被解析为 DSL 并应用于设计器,使组件立即可见和可编辑。
最佳实践与配置
为了最大化自然语言转组件生成的有效性,请考虑以下最佳实践和配置选项:
提示词工程
提供清晰、具体的提示词,包括组件要求、数据结构和行为预期。在适当的时候包含有关现有项目结构和模式的上下文。尽可能使用示例并引用特定的 UI 组件或框架。
模型选择
根据任务复杂性选择合适的 LLM 模型。简单的组件生成可能适用于较小的模型,而具有多种工具的复杂页面创建则受益于具有更好推理能力的更强大的模型。
工具配置
在 ToolRegistry 中注册自定义工具,以将 LLM 的能力扩展到内置操作之外。工具应具有清晰的描述和定义良好的参数 schema,以实现有效的 LLM 使用。
错误恢复
监控自动更正循环,如果系统陷入错误循环则进行干预。当重复发生故障时,提供更清晰的错误消息或重构提示词。
性能优化
启用流式传输以获得更好的用户体验。对重复操作使用缓存。尽可能批量处理工具调用以减少 API 往返。为生产部署实施速率限制。
设计元数据解析(Figma、MasterGo)
VTJ 基于人工智能的设计元数据解析系统,能够将专业设计工具(Figma、MasterGo、Sketch)的设计文件无缝转换为可执行的 Vue 组件代码。通过利用 AI 理解并将设计规范直接转换为组件实现,这座连接设计与开发的桥梁加速了前端开发工作流程。
架构概览
设计元数据解析系统作为一个复杂的管道运行,负责摄取结构化设计数据,验证格式兼容性,将其传输至 AI 服务进行分析,并将生成的代码应用于当前项目。该架构通过专用的元数据输入工作流与 VTJ 的设计器框架集成。
支持的设计工具和格式
目前,系统通过各平台相应的导出插件支持三大主要设计平台,每个平台均提供捕获组件层次结构、样式和属性的结构化 JSON 元数据。
| 设计工具 | 文件格式 | 检测关键字 | 导出插件 |
|---|---|---|---|
| Figma | .json | type: 'figma' | Figma Plugin (JSON Export) |
| MasterGo | .json | type: 'mastergo', type: 'group', type: 'frame' | MasterGo Plugin (元数据导出) |
| Sketch | .json | type: 'sketch' | Sketch Plugin (JSON Export) |
核心数据结构
设计元数据系统采用类型安全架构,使用特定接口处理不同的输入模式和数据类型。
主题数据类型枚举
export type TopicDataType = 'sketch' | 'figma' | 'mastergo' | 'unknown';
AI 主题接口
AITopic 接口封装了从设计到代码转换会话的完整上下文:
export interface AITopic {
id: string;
appId: string;
createAt: string;
fileId: string;
isHot: boolean;
model: string;
platform: string;
projectId: string;
title: string;
prompt: string;
dependencies: string;
dsl: any;
image?: string;
json?: string;
type?: TopicType; // 'text' | 'image' | 'json'
dataType?: TopicDataType; // 'sketch' | 'figma' | 'mastergo' | 'unknown'
}
AI 聊天接口
表示元数据解析会话中的单次对话交互:
export interface AIChat {
id: string;
content: string;
createdAt: string;
dsl: any;
message: string;
source?: string;
prompt: string;
reasoning: string;
status: 'Pending' | 'Success' | 'Failed' | 'Error' | 'Canceled';
tokens: number;
topicId: string;
userId: string;
userName: string;
thinking: number;
vue: string;
collapsed?: boolean;
image?: string;
json?: string;
type?: TopicType;
dataType?: TopicDataType;
toolCallId?: string;
toolContent?: string;
}
元数据输入组件
json-input.vue 组件提供了一个全面的界面,用于导入设计元数据文件,支持双重输入模式和视觉反馈。
组件特性
- 双重输入模式:文件上传(拖放)和文本粘贴
- 格式检测:自动识别设计工具来源
- 视觉预览:特定平台的图标(Figma、MasterGo、Sketch Logo)
- 自动应用开关:选择是否将生成的代码自动应用到当前页面
- 错误处理:验证并显示用户友好的错误消息
<template>
<div class="v-ai-widget-image-input v-ai-widget-json-input">
<!-- 文本模式:直接粘贴 JSON -->
<div v-if="textMode" class="v-ai-widget-json-input-text">
<ElInput
type="textarea"
:rows="8"
placeholder="请粘贴JSON格式元数据"
v-model="textContent">
</ElInput>
<div class="v-ai-widget-json-input-text__footer">
<ElButton @click="() => changeMode(false)">文件上传</ElButton>
<ElButton type="primary" round @click="onSubmitText">确定</ElButton>
</div>
</div>
<!-- 文件上传模式 -->
<ElUpload
v-else
drag
:auto-upload="false"
accept=".json"
:on-change="onChange">
<XIcon :icon="UploadFilled" :size="60"></XIcon>
<div class="el-upload__text">
拖放 Sketch / Figma / MasterGo 元数据文件
</div>
<div class="or">或</div>
<ElButton>选择文件</ElButton>
<ElButton @click.stop="() => changeMode(true)">粘贴数据</ElButton>
<ElLink
type="primary"
href="https://vtj.pro/guide/meta.html"
target="_blank"
@click.stop>
如何获得元数据文件?
</ElLink>
</ElUpload>
<!-- 预览面板 -->
<div v-if="fileName" class="v-ai-widget-image-input__preview">
<ElImage :src="cover" fit="cover"></ElImage>
<div class="json-name">{{ fileName }}</div>
<ElButton
type="danger"
:icon="CloseBold"
circle
@click="onRemove">
</ElButton>
<div class="v-ai-widget-input__footer">
<ElCheckbox v-model="engine.state.autoApply">自动</ElCheckbox>
<ElButton type="primary" round @click="onSend">发送</ElButton>
</div>
</div>
</div>
</template>
平台图标映射
const cover = computed(() => {
const map: Record<string, string> = {
figma,
sketch,
other,
mastergo,
group: mastergo,
frame: mastergo
};
if (fileType.value) {
return map[fileType.value.toLowerCase()] || other;
}
return other;
});
文件验证逻辑
const onChange = async (file: UploadFile) => {
if (file.status === 'ready' && file.raw) {
const json = await readJsonFile(file.raw);
if (json && json.type) {
fileType.value = json.type;
fileName.value = file.raw.name;
content.value = json;
} else {
await alert(
'无法识别文件, 只支持Sketch/Figma/MasterGo插件导出数据文件',
{ type: 'warning' }
);
fileType.value = null;
fileName.value = null;
content.value = null;
uploadRef.value.clearFiles();
}
}
};
OpenAPI 集成
OpenApi 抽象类提供了与处理设计元数据 AI 处理的后端服务进行通信的契约。
元数据主题提交
export abstract class OpenApi {
/**
* 发送元数据AI话题
*/
public abstract postJsonTopic?: (
dto: TopicDto
) => Promise<ResponseWrapper<{ topic: AITopic; chat: AIChat }>>;
}
主题 DTO 结构
export interface TopicDto {
model: string;
llm?: string;
project: string;
dsl: string;
source: string;
prompt?: string;
file?: File;
options?: string;
tools?: string;
}
工作流集成
元数据解析系统与 VTJ 的 AI Agent 工作流无缝集成,支持自动和手动应用生成的代码。
AI 组件集成
主要的 AI 组件通过协调事件处理来编排元数据解析工作流:
<template>
<NewTopic
v-if="isNewChat"
:models="models"
:loading="loading"
@send="onPostTopic"
@image-send="onPostImageTopic"
@json-send="onPostJsonTopic">
</NewTopic>
<div v-if="!isNewChat" ref="listRef" class="v-ai-widget__bubble-list">
<template v-for="chat of chats" :key="chat.id">
<Bubble type="user" :data="chat"></Bubble>
<Bubble
type="ai"
:data="chat"
:code="!isHideCode"
@view="onView(chat)"
@refresh="onRefresh(chat)"
@apply="onApply(chat, true)"
@fix="onFix(chat)"
@cancel="onCancelChat(chat)">
</Bubble>
</template>
</div>
</template>
引擎状态管理
设计器引擎维护自动应用功能的状态:
watch(
() => engine.state.autoApply,
(v) => {
ElMessage.success({
message: v
? '已开启自动应用到页面功能'
: '已经关闭自动应用到页面功能'
});
}
);
使用工作流
将设计元数据转换为 Vue 组件的完整工作流程遵循以下步骤:
分步流程
-
导出元数据:使用设计工具(Figma/MasterGo/Sketch)中的导出插件生成包含组件结构、样式和属性的 JSON 元数据文件
-
输入方式:选择将 JSON 文件拖放到上传区域,或将 JSON 内容直接粘贴到文本区域
-
验证:系统自动验证文件格式,并根据 JSON 结构中的
type字段检测原始设计工具 -
预览审查:提交前,视觉反馈会显示检测到的平台图标和文件名
-
配置:切换“自动”复选框以启用/禁用生成代码的自动应用
-
提交:点击“发送”按钮将元数据传输到 AI 服务进行处理
-
AI 处理:AI 分析设计元数据,理解组件层次结构、样式和属性,然后生成相应的 Vue DSL
-
代码应用:
- 自动模式:生成的代码会自动应用到当前页面
- 手动模式:在 AI 聊天气泡中查看生成的代码,然后点击“应用”来实施它
错误处理和验证
系统实施了全面的验证和错误处理机制,以确保流畅的用户体验。
文件格式验证
if (json && json.type) {
fileType.value = json.type;
fileName.value = file.raw.name;
content.value = json;
} else {
await alert(
'无法识别文件, 只支持Sketch/Figma/MasterGo插件导出数据文件',
{ type: 'warning' }
);
fileType.value = null;
fileName.value = null;
content.value = null;
uploadRef.value.clearFiles();
}
支持的文件类型
- 接受:仅接受
.json文件 - 检测:验证是否存在与支持的平台匹配的
type字段 - 回退:对于无法识别的格式显示通用的 JSON 图标
与 VTJ 设计器框架的集成
元数据解析系统利用 VTJ 设计器框架的基础设施实现无缝集成。
引擎上下文访问
const engine = useEngine();
状态管理
engine.state.autoApply:控制自动代码应用行为- 实时状态更新触发用户通知
- 状态在元数据解析会话之间保持持久化
工具函数
系统使用工具函数进行文件操作:
import { readJsonFile, alert } from '../../../utils';
最佳实践
设计文件准备
- 组织组件:在导出之前,使用清晰的命名约定和逻辑层次结构来组织设计组件
- 移除未使用的元素:清理未使用的图层和组,以降低元数据复杂性
- 使用标准属性:利用能很好地映射到 CSS/Vue 属性的标准设计属性
- 导出单个组件:为了获得最佳结果,导出单个组件而不是整个页面
元数据工作流优化
- 从简单组件开始:在处理复杂设计之前,先从简单组件开始以验证工作流
- 审查生成的代码:在手动模式下,在应用之前始终审查生成的代码以确保质量
- 迭代优化:使用 AI 聊天上下文请求对生成的代码进行修改和优化
- 利用自动应用进行快速原型制作:在原型设计阶段使用自动应用模式进行快速迭代
自动应用功能通过跳过手动代码审查显著加速了开发,但在生产工作流中应谨慎使用。对于关键组件,请始终在手动模式下验证生成的代码。
用于页面操作的 AI Agent
VTJ 中的页面操作 AI Agent 代表了将人工智能能力集成到可视化页面设计工作流中的复杂系统,支持通过自然语言交互进行组件生成、代码转换和智能页面操作。
架构概览
AI Agent 架构采用基于工具的执行模型,通过结构化的工具调用增强 LLM 能力,这些工具可以直接操作页面 DSL、组件和项目元数据。该架构架起了自然语言指令与精确页面操作之间的桥梁。
核心组件
ToolRegistry 系统
ToolRegistry 是 AI Agent 能力的基础,提供集中式机制来注册、发现和执行 AI 可调用的工具。每个工具都包含元数据,使 LLM 能够理解何时以及如何使用它们。
注册表支持:
- 工具注册:使用名称、描述、参数和处理函数注册工具
- 动态执行:异步工具执行,包含错误处理和日志记录
- Schema 生成:自动生成供 LLM 使用的工具描述
- 参数验证:带类型检查的结构化参数定义
Agent 配置
AgentConfig 接口定义了 AI Agent 的操作参数,包括技能管理和主题跟踪。
配置选项包括:
| 参数 | 类型 | 描述 |
|---|---|---|
getSkills | Function | 根据 ID 检索技能定义的异步函数 |
activeDelayMs | Number | 激活 Agent 响应前的延迟 |
currentTopic | Ref | 活跃对话主题的响应式引用 |
工具上下文系统
ToolContext 为所有工具处理程序提供执行上下文,授予对完整设计环境的访问权限。
上下文包括:
engine:用于页面操作的 Designer Engine 实例project:表示当前项目状态的 ProjectModelservice:用于后端交互的服务层toolRegistry:工具注册表的引用,用于递归工具调用config:Agent 配置实例
工具系统与扩展性
工具定义结构
工具使用 ToolConfig 接口定义,该接口指定了工具的 API 及其实现。
interface ToolConfig {
name: string;
description: string;
parameters: ToolParameter[];
createHandler: (context: ToolContext) => (...args: any[]) => Promise<any>;
}
createHandler 函数模式使工具具有上下文感知能力,在创建时接收完整的工具上下文,而不是在每次执行时传递。
参数定义系统
工具参数使用丰富的 Schema 定义系统,支持嵌套对象和数组。
| 参数类型 | 描述 | 示例用法 |
|---|---|---|
string | 带可选枚举的文本值 | 组件名称、节点 ID |
number | 数值 | 位置坐标、尺寸 |
boolean | 真/假标志 | 可见性、启用状态 |
object | 嵌套参数对象 | 复杂配置对象 |
array | 类型化项列表 | 组件属性列表 |
内置工具类别
框架提供了几类内置工具:
- 组件操作:在页面上添加、删除、修改组件
- 节点操作:更新节点属性、位置和样式
- 项目管理:更新项目元数据、依赖项和配置
- 代码生成:从 DSL 描述生成 Vue 代码
- 数据操作:操作数据源和绑定
AI 聊天系统
AIChat 接口跟踪对话状态和执行结果。
关键属性包括:
| 属性 | 类型 | 描述 |
|---|---|---|
status | String | 执行状态(Pending、Success、Failed、Error、Canceled) |
content | String | 主要响应内容 |
reasoning | String | AI 推理过程(用于推理模型) |
tokens | Number | Token 使用统计 |
dsl | Any | 生成的 DSL 结构 |
vue | String | 生成的 Vue 代码 |
toolCallId | String | 关联的工具执行标识符 |
toolContent | String | 工具执行结果内容 |
内容解析系统
ParseResult 和 ParseRule 接口支持从 AI 响应中智能提取结构化数据。
支持的解析类型:
| 类型 | 描述 | 验证方法 |
|---|---|---|
vue | Vue SFC 模板代码 | 正则模式匹配 + 验证 |
diff | 代码差异/补丁格式 | 正则模式匹配 + 验证 |
json | JSON 结构化数据 | 带错误处理的 JSON 解析 |
实现示例:用户列表生成
以下示例演示了 AI Agent 如何从自然语言指令生成完整的用户列表组件。
生成的组件结构
AI 生成的组件包括:
- 查询表单:包含用户名、性别和电话筛选器的表单
- 数据表格:显示格式化列的用户信息
- 分页:可配置的页面大小和导航
- 事件处理:查询和重置功能
<template>
<div>
<el-form :model="state.queryForm" inline>
<el-form-item label="用户名">
<el-input v-model="state.queryForm.username" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">查询</el-button>
</el-form-item>
</el-form>
<el-table :data="state.tableData" border stripe>
<el-table-column prop="id" label="用户ID" />
<el-table-column prop="username" label="用户名" />
<!-- Additional columns -->
</el-table>
<el-pagination @current-change="handleQuery" />
</div>
</template>
AI 响应处理
系统通过多阶段管道处理 AI 响应:
- 初始接收:从 DeepSeek API 接收结构化响应
- 内容提取:从
choices[0].message.content提取生成的 Vue 代码 - 推理捕获:从
reasoning_content字段存储推理过程 - Token 跟踪:监控 prompt 和补全 token 使用量
- 结果显示:在编辑器中渲染代码以供审查和应用
Agent 工作流集成
Agent 通过几个关键交互点与 Designer 工作流无缝集成。
配置与扩展
自定义工具注册
开发者可以通过注册自定义工具来扩展 AI Agent。
// 示例工具注册
const customTool = {
name: 'customAction',
description: '执行自定义页面操作',
parameters: [
{ name: 'pageId', type: 'string', required: true },
{ name: 'options', type: 'object', required: false }
],
handler: async (context: ToolContext, pageId: string, options: any) => {
// 自定义实现
const page = context.project.getPage(pageId);
// 执行操作
return { success: true, data: page };
}
};
toolRegistry.register(customTool);
技能管理
getSkills 函数支持根据项目需求动态加载技能。
const config: AgentConfig = {
async getSkills(ids: string[]) {
// 从远程或本地源加载技能定义
return skills.filter(s => ids.includes(s.id));
},
activeDelayMs: 500,
currentTopic: ref(null)
};
AI Agent 使用与 Designer 内部操作相同的 ToolRegistry 系统,确保手动操作和 AI 驱动的页面修改之间的一致性。工具可以递归调用其他工具,从而实现复杂的多步骤操作。
与解析器系统集成
AI Agent 与 VTJ 的解析器系统集成,以处理双向代码转换。
const onParser = async () => {
const result = await parseVue({
id: 'test',
name: 'test',
source: content.value
});
console.log(result);
};
这使 Agent 能够:
- 将自然语言转换为 Vue 代码
- 将现有 Vue 代码解析为 DSL 格式
- 应用 DSL 转换
- 从修改后的 DSL 生成更新的 Vue 代码
AI 助手代表了低代码开发的重大进步,在弥合人类创造力与机器精度之间差距的同时,保持了开发者所需的灵活性和控制力。
参考资料:
-
VTJ.PRO官网:vtj.pro/
-
在线应用开发平台:app.vtj.pro/
-
开源代码仓库: gitee.com/newgateway/…