基于TinyEngine低代码引擎的AI Agent开发完整指南
基于TinyEngine低代码引擎的AI Agent开发完整指南
TinyEngine在2026年4月30日通过PR #1800正式集成了画布节点级AI助手能力,提供了可扩展的AI Agent框架。本文将从架构原理、环境配置、基础开发、高级扩展四个维度,详细讲解如何基于TinyEngine构建自定义AI Agent,并提供可直接运行的代码示例。
一、TinyEngine AI Agent 整体架构
TinyEngine采用**“低代码画布+大语言模型+工具调用”**的混合架构,AI Agent直接与画布节点交互,实现"自然语言描述→节点自动修改/生成→实时预览"的闭环。
核心架构分层
┌─────────────────────────────────────────┐ │ 用户交互层 (Canvas UI) │ │ - 节点右键AI助手入口 │ │ - 对话面板与结果预览 │ └───────────────────┬─────────────────────┘ │ ┌───────────────────▼─────────────────────┐ │ AI Agent 核心层 │ │ - 提示词模板系统 (Prompt Templates) │ │ - 节点上下文提取器 │ │ - JSON结果解析与验证器 │ │ - 工具调用管理器 │ └───────────────────┬─────────────────────┘ │ ┌───────────────────▼─────────────────────┐ │ 大模型适配层 │ │ - OpenAI/GPT-4o │ │ - Claude 3 Opus │ │ - 本地开源模型 (Qwen/Llama) │ └───────────────────┬─────────────────────┘ │ ┌───────────────────▼─────────────────────┐ │ 画布操作层 (Canvas API) │ │ - 节点属性修改 │ │ - 节点创建/删除/移动 │ │ - 事件与逻辑绑定 │ └─────────────────────────────────────────┘关键设计特点
- 节点级上下文感知:AI Agent自动获取当前选中节点的完整DSL描述
- 结构化输出强制:通过提示词和JSON Schema强制大模型返回可直接执行的操作指令
- 可插拔工具系统:支持注册自定义工具扩展AI能力
- 安全沙箱:所有AI生成的代码和操作都经过验证后才会执行
二、环境准备与基础配置
1. 克隆并启动最新版TinyEngine
# 克隆主仓库gitclone https://atomgit.com/opentiny/tiny-engine.gitcdtiny-engine# 安装依赖pnpminstall# 启动本地开发服务器pnpmdev2. 配置大模型API密钥
TinyEngine默认支持OpenAI和Claude,在.env.local文件中添加以下配置:
# OpenAI 配置 VITE_OPENAI_API_KEY=your-openai-api-key VITE_OPENAI_BASE_URL=https://api.openai.com/v1 # Claude 配置 (可选) VITE_CLAUDE_API_KEY=your-claude-api-key VITE_CLAUDE_BASE_URL=https://api.anthropic.com/v1 # 选择默认模型 VITE_DEFAULT_AI_MODEL=gpt-4o3. 验证AI助手功能
启动项目后,访问http://localhost:8080,拖拽任意组件到画布,右键点击节点,会看到"AI助手"选项,点击即可打开对话面板。
三、基础AI Agent开发:扩展节点修改能力
1. 理解内置AI助手的工作流程
内置AI助手的核心逻辑位于packages/designer/src/composables/useAIHelper.ts,工作流程如下:
- 用户右键点击节点,选择"AI助手"
- 系统提取当前节点的完整DSL(包括属性、样式、事件)
- 将DSL和用户指令一起发送给大模型
- 大模型返回JSON格式的修改指令
- 系统验证JSON并应用到画布节点
2. 自定义提示词模板
创建packages/designer/src/ai/prompts/nodeModifyPrompt.ts:
exportconstnodeModifyPrompt=`你是一个专业的低代码平台AI助手,负责根据用户的自然语言描述修改画布节点。 当前节点信息: {{nodeDSL}} 请根据用户的指令,返回一个JSON对象,包含以下字段: - action: 操作类型,只能是"modify"、"create"、"delete" - target: 目标节点ID - changes: 要修改的属性对象 - description: 对修改内容的简要说明 示例: { "action": "modify", "target": "button-123", "changes": { "props": { "text": "提交订单", "type": "primary" }, "style": { "width": "120px", "height": "40px" } }, "description": "将按钮文字改为'提交订单',设置为主按钮样式,调整尺寸为120x40px" } 注意: 1. 只返回JSON,不要添加任何其他文字 2. 严格按照示例格式返回 3. 不要修改节点ID和类型 4. 如果用户指令不明确,返回description说明需要的信息`;3. 注册自定义提示词
修改packages/designer/src/ai/aiService.ts:
import{nodeModifyPrompt}from'./prompts/nodeModifyPrompt';classAIService{privateasyncsendRequest(prompt:string,nodeDSL:any){constfullPrompt=nodeModifyPrompt.replace('{{nodeDSL}}',JSON.stringify(nodeDSL,null,2));constresponse=awaitfetch(`${import.meta.env.VITE_OPENAI_BASE_URL}/chat/completions`,{method:'POST',headers:{'Content-Type':'application/json','Authorization':`Bearer${import.meta.env.VITE_OPENAI_API_KEY}`},body:JSON.stringify({model:import.meta.env.VITE_DEFAULT_AI_MODEL,messages:[{role:'system',content:fullPrompt},{role:'user',content:prompt}],temperature:0.1,response_format:{type:'json_object'}})});constdata=awaitresponse.json();returnJSON.parse(data.choices[0].message.content);}asyncmodifyNode(nodeId:string,prompt:string){constnodeDSL=this.canvasService.getNodeDSL(nodeId);constresult=awaitthis.sendRequest(prompt,nodeDSL);// 验证结果if(result.action==='modify'&&result.target===nodeId){this.canvasService.applyChanges(nodeId,result.changes);returnresult.description;}thrownewError('AI返回结果无效');}}exportconstaiService=newAIService();四、高级AI Agent开发:添加工具调用能力
1. 实现工具调用框架
创建packages/designer/src/ai/tools/toolManager.ts:
interfaceTool{name:string;description:string;parameters:any;execute:(args:any)=>Promise<any>;}classToolManager{privatetools:Map<string,Tool>=newMap();registerTool(tool:Tool){this.tools.set(tool.name,tool);}getTool(name:string):Tool|undefined{returnthis.tools.get(name);}getToolsDescription():string{returnArray.from(this.tools.values()).map(tool=>`-${tool.name}:${tool.description}参数:${JSON.stringify(tool.parameters)}`).join('\n');}asyncexecuteTool(name:string,args:any):Promise<any>{consttool=this.getTool(name);if(!tool){thrownewError(`工具${name}不存在`);}returnawaittool.execute(args);}}exportconsttoolManager=newToolManager();2. 实现一个"接口数据生成"工具
创建packages/designer/src/ai/tools/generateMockDataTool.ts:
import{toolManager}from'./toolManager';constgenerateMockDataTool={name:'generate_mock_data',description:'根据用户描述生成模拟接口数据',parameters:{type:'object',properties:{description:{type:'string',description:'接口数据的描述'},count:{type:'number',description:'生成的数据条数',default:10}},required:['description']},execute:async(args:{description:string;count:number})=>{constresponse=awaitfetch(`${import.meta.env.VITE_OPENAI_BASE_URL}/chat/completions`,{method:'POST',headers:{'Content-Type':'application/json','Authorization':`Bearer${import.meta.env.VITE_OPENAI_API_KEY}`},body:JSON.stringify({model:'gpt-4o',messages:[{role:'system',content:'你是一个模拟数据生成器,只返回JSON格式的模拟数据'},{role:'user',content:`生成${args.count}条${args.description}的模拟数据`}],response_format:{type:'json_object'}})});constdata=awaitresponse.json();returnJSON.parse(data.choices[0].message.content);}};toolManager.registerTool(generateMockDataTool);3. 修改AI服务支持工具调用
更新packages/designer/src/ai/aiService.ts:
import{toolManager}from'./tools/toolManager';classAIService{privateasyncsendRequestWithTools(prompt:string,nodeDSL:any){constsystemPrompt=`你是一个专业的低代码平台AI助手,可以使用以下工具来完成任务:${toolManager.getToolsDescription()}当需要使用工具时,返回以下格式的JSON: { "type": "tool_call", "tool_name": "工具名称", "tool_args": { "参数名": "参数值" } } 当不需要使用工具时,返回以下格式的JSON: { "type": "final_response", "content": { "action": "modify", "target": "节点ID", "changes": {}, "description": "" } } 当前节点信息: {{nodeDSL}}`;letresponse=awaitthis.sendRawRequest(systemPrompt.replace('{{nodeDSL}}',JSON.stringify(nodeDSL,null,2)),prompt);// 处理工具调用while(response.type==='tool_call'){consttoolResult=awaittoolManager.executeTool(response.tool_name,response.tool_args);// 将工具结果返回给大模型response=awaitthis.sendRawRequest(systemPrompt.replace('{{nodeDSL}}',JSON.stringify(nodeDSL,null,2)),`工具执行结果:${JSON.stringify(toolResult)}\n请根据这个结果继续完成任务`);}returnresponse.content;}privateasyncsendRawRequest(systemPrompt:string,userPrompt:string){constresponse=awaitfetch(`${import.meta.env.VITE_OPENAI_BASE_URL}/chat/completions`,{method:'POST',headers:{'Content-Type':'application/json','Authorization':`Bearer${import.meta.env.VITE_OPENAI_API_KEY}`},body:JSON.stringify({model:import.meta.env.VITE_DEFAULT_AI_MODEL,messages:[{role:'system',content:systemPrompt},{role:'user',content:userPrompt}],temperature:0.1,response_format:{type:'json_object'}})});constdata=awaitresponse.json();returnJSON.parse(data.choices[0].message.content);}asyncmodifyNodeWithTools(nodeId:string,prompt:string){constnodeDSL=this.canvasService.getNodeDSL(nodeId);constresult=awaitthis.sendRequestWithTools(prompt,nodeDSL);if(result.action==='modify'&&result.target===nodeId){this.canvasService.applyChanges(nodeId,result.changes);returnresult.description;}thrownewError('AI返回结果无效');}}五、实战案例:实现一个"智能表单生成"AI Agent
1. 需求分析
用户输入"生成一个用户注册表单,包含姓名、邮箱、手机号、密码和确认密码",AI Agent自动:
- 创建表单组件
- 添加对应的表单项
- 设置表单验证规则
- 绑定提交事件
2. 实现代码
创建packages/designer/src/ai/agents/formGeneratorAgent.ts:
import{aiService}from'../aiService';import{canvasService}from'../../services/canvasService';classFormGeneratorAgent{asyncgenerateForm(description:string){// 1. 创建表单容器constformId=canvasService.createNode('Form',{props:{labelWidth:'100px',labelPosition:'left'},style:{width:'500px',margin:'20px auto'}});// 2. 让AI生成表单项constprompt=`根据以下描述生成一个表单的表单项配置:${description}返回JSON格式,包含以下字段: { "items": [ { "type": "Input", "label": "字段标签", "name": "字段名", "required": true/false, "placeholder": "占位符", "rules": [ { "type": "email", "message": "请输入正确的邮箱格式" } ] } ] }`;constresult=awaitaiService.sendRawRequest('你是一个专业的表单设计器,只返回JSON格式的表单项配置',prompt);// 3. 应用表单项到表单for(constitemofresult.items){constitemId=canvasService.createNode(item.type,{props:{label:item.label,name:item.name,placeholder:item.placeholder,rules:item.rules},parentId:formId});}// 4. 添加提交按钮canvasService.createNode('Button',{props:{text:'提交',type:'primary',onClick:'handleSubmit'},style:{marginTop:'20px'},parentId:formId});return`已成功生成表单,包含${result.items.length}个表单项`;}}exportconstformGeneratorAgent=newFormGeneratorAgent();3. 注册到AI助手入口
修改packages/designer/src/components/NodeContextMenu.vue:
<template> <el-dropdown-menu> <el-dropdown-item @click="openAIHelper">AI助手</el-dropdown-item> <el-dropdown-item @click="generateForm">智能生成表单</el-dropdown-item> </el-dropdown-menu> </template> <script setup lang="ts"> import { formGeneratorAgent } from '../ai/agents/formGeneratorAgent'; const generateForm = async () => { const description = await ElInput.prompt('请描述您需要的表单:'); if (description) { const result = await formGeneratorAgent.generateForm(description); ElMessage.success(result); } }; </script>六、部署与集成
1. 构建包含AI Agent的低代码平台
pnpmbuild:prod2. 部署到Nginx
将dist目录上传到服务器,配置Nginx:
server { listen 80; server_name shturl.cc/dZc3q; location / { root /path/to/dist; index index.html; try_files $uri $uri/ /index.html; } # 代理大模型API请求(避免跨域) location /v1/ { proxy_pass https://api.openai.com/v1/; proxy_set_header Authorization $http_authorization; } }七、最佳实践与注意事项
- 提示词工程:使用明确的指令和示例,强制JSON输出格式,降低大模型幻觉
- 结果验证:始终验证AI返回的结果,避免执行恶意代码
- 错误处理:添加完善的错误处理和用户提示
- 性能优化:缓存常用的AI响应,减少API调用次数
- 安全考虑:在生产环境中,不要将API密钥暴露在前端,应该通过后端代理
