- 人工智能
- 大模型
- AI 应用
- 低代码
- 后端
- 前端
- 流程编排
- RAG
【免费下载链接】app-platform
AppPlatform 是一个前沿的大模型应用工程,旨在通过集成的声明式编程和低代码配置工具,简化和优化大模型的训练与推理应用的开发过程。本工程为软件工程师和产品经理提供一个强大的、可扩展的环境,以支持从概念到部署的全流程 AI 应用开发。
导读
智能表单是 AppPlatform 大模型应用中让流程在"智能表单节点"或"结束节点"与用户进行人工交互的关键载体。本文以仓库内置的面试确认表单(interview)示例为蓝本,完整讲解自定义表单组件的开发约束、工程搭建、流程数据获取、三大内置对话接口(终止对话 / 继续对话 / 重新对话)的调用方式、本地调试、config.json 出入参配置规范以及最终打包上传的全过程,并辅以平台侧源码印证通信与校验的底层机制。读完本文,你可以从零开发出一个可上传到平台、可在流程中真实运行的自定义表单组件。
一、自定义表单在流程中的定位与运行机制
在 AppPlatform 中,流程编排(agent-flow)通过"智能表单节点"和"结束节点"接入表单。开发者上传的自定义表单会以 iframe 的形式嵌入前端页面,表单与流程之间的数据交换完全基于postMessage跨窗口消息:
- 平台侧在 iframe 加载完成后,通过
contentWindow.postMessage将前序节点的输出数据(即表单初始化入参)推送给表单; - 表单通过
window.parent.postMessage将用户交互结果(出参)回传给平台,或触发终止、继续、重新对话等流程控制动作。
这一机制可以在仓库源码中得到印证:表单渲染组件 监听app-engine-form-terminate、app-engine-form-resuming、app-engine-form-restart、app-engine-form-resize、app-engine-form-ready五类消息并分别处理;而示例组件中的表单入口 app.tsx 则分别以app-engine-form-terminate、app-engine-form-resuming、app-engine-form-restart三类消息与平台通信,并额外通过app-engine-form-resize上报表单高度以驱动 iframe 自适应。
理解这一机制后,后续的接口调用、数据结构和调试方法就都顺理成章了。
二、前提条件与开发环境
开发自定义表单前,请先确认本地环境满足以下要求:
- 开发工具建议使用 VSCode;
- Node.js 版本建议为18 及以上;
- npm 版本建议为10 及以上;
- React 组件建议使用 antd 组件库,模板默认版本为4.24.13(仓库示例 package.json 中即依赖
antd: 4.24.13,并搭配react: ^18.1.0)。
仓库中提供了两个可直接参照的完整示例工程:
- interview 示例:一个"简历文件是否包含信息、是否继续生成面试计划"的人工确认表单,结构精简,是本文讲解的主体;
- smart-form 示例:基于 config.json 的 schema 动态渲染 Input、Radio、Select、Switch、Checkbox、Label 等字段的通用型智能表单,展示了
buildFormSchema的动态表单构建思路。
两个工程的目录结构一致,可直接作为自定义表单的脚手架拷贝使用。
三、组件包约束条件
上传到平台的组件包需要满足以下硬性约束:
- 必须是 zip 压缩包,解压后总大小不能超过 5M;
- 压缩包包含且只能包含三个部分:
build文件夹:表单代码打包后的静态资源;config.json:表单的出入参配置文件;form.jpg/form.png/form.jpeg:表单预览图,大小不能超过 1M。
这些约束与平台侧的上传校验逻辑一一对应。在表单上传组件 upload-form.tsx 中可以确认:平台会校验 zip 中必须存在config.json、build/index.js、build/index.html,且必须存在form.png/form.jpg/form.jpeg中的至少一张预览图;validateAllSize 校验解压后总大小不超过 5M,validateFileSize 校验预览图不超过 1M。
此外,上传时对 zip 包文件名也有要求:支持大小写英文、中文和数字的字符串,可以包含中划线-和下划线_,但不能以中划线或下划线开头或结尾。平台侧使用正则^[a-zA-Z0-9\u4e00-\u9fa5]+([_-][a-zA-Z0-9\u4e00-\u9fa5]+)*$进行校验(见 upload-form.tsx),违反该规则的文件会在beforeUpload阶段被拦截。
四、开发组件代码
4.1 创建组件文件
在工程的/src/components文件夹下创建自己的组件文件,类型为.tsx。仓库示例 interview 的组件位于 form.tsx,其核心代码如下:
import { Button } from 'antd'; import React, { useContext } from 'react'; import { DataContext } from "../context"; import '../styles/form.scss'; const SmartForm: React.FC = () => { const { resumingClick } = useContext(DataContext); // 调用继续会话接口 const onResumeClick = (str: string) => { resumingClick({ params: { isCvFile: str } }); } return ( <div className="form-wrap"> <div className="question-item"> 经过分析,此文件内容可能不包含简历信息,请确认是否继续生成面试计划? </div> <div className="button-group"> <Button onClick={() => onResumeClick('否')}>否</Button> <Button onClick={() => onResumeClick('是')} type="primary">是</Button> </div> </div> ); }; export default SmartForm;4.2 表单获取流程数据
在流程中使用智能表单节点或结束节点选用表单时,可以将前序节点的输出作为表单初始化的数据使用。假设表单需要的数据结构为:
{ "a": "你好", "b": "Demo1" }在表单里使用如下代码获取流程传入的数据:
const { data, terminateClick, resumingClick, restartClick } = useContext(DataContext);其中data就是由流程传输给表单的 JSON 数据(格式为{"a": "", "b": ""}),可以使用它来初始化表单。
注意:data的数据结构与config.json的入参配置保持一致。
DataContext由平台提供的固定模板声明,在示例工程的 context/index.ts 中可以看到其定义:
import { createContext } from 'react'; export const DataContext = createContext({ data: {}, terminateClick: (params) => {}, resumingClick: (params) => {}, restartClick: (params) => {}, });该文件标注了"请勿修改或删除",其 Provider 注入逻辑位于 app.tsx:平台将receiveData与三个回调方法合并后通过<DataContext.Provider>提供给业务表单组件。模板文件 index.tsx 负责挂载 App 到#root。
4.3 表单调用内置接口
平台提供了三个内置接口:继续对话(resumingClick)、重新对话(restartClick)、终止对话(terminateClick)。通过useContext(DataContext)即可像调用普通方法一样使用它们。其底层实现(见 app.tsx)都是通过window.parent.postMessage向平台发送带uniqueId的消息,uniqueId由模板工具函数getQueryParams从 URL 中解析(见 utils/index.ts)。
4.3.1 终止对话接口(terminateClick)
- 适用场景:配置在智能表单节点的表单,用于用户在流程中间过程中想终止本地对话的场景。
- 交互过程:
应用流程进行到智能表单节点,流程暂停 ---> 用户与表单进行交互,触发终止对话接口 ---> 流程终止,对话结束- 使用示例:
// 表单里的触发按钮 <Button onClick={onTerminateClick}>终止对话</Button> // 调用终止对话接口 const onTerminateClick = () => { terminateClick({ content: /* 字符串,终止对话后希望显示的文本 */ }); } // 例如希望点击终止对话后显示文本 "终止对话" terminateClick({ content: "终止会话" });注意:在结束节点使用的表单如果调用终止对话接口,会出现错误。
平台侧收到app-engine-form-terminate消息后,会调用停止实例接口结束流程(见 render.tsx 与 terminateChat),并且当流程状态为ARCHIVED时会给出提示而不执行终止。
4.3.2 继续对话接口(resumingClick)
- 适用场景:配置在智能表单节点的表单,用于在流程中间过程通过表单进行人工交互,交互结束后流程继续。
- 交互过程:
应用流程进行到智能表单节点,流程暂停 ---> 用户与表单进行交互,触发继续对话接口 ---> 流程继续进行到下一个节点- 使用示例:
// 表单里的触发按钮 <Button onClick={onResumeClick}>继续对话</Button> // 调用继续对话接口 const onResumeClick = () => { resumingClick({ params: /* 这里是表单的出参数据 */ }); } // 如果表单的出参有两个,String 类型的 "a",Int 类型的 "b": resumingClick({ params: { a: "hello", b: 1 } });注意:在结束节点使用的表单如果调用继续对话接口,会出现错误。
平台侧收到app-engine-form-resuming消息后,会携带formAppearance、formData(即data.params序列化结果)以及businessData.output(出参)调用继续对话接口(见 render.tsx),流程随即向下一个节点推进。
4.3.3 重新对话接口(restartClick)
- 适用场景:配置在结束节点的表单,用于流程结束后,用户希望使用相同的问题重新发起一次对话。
- 交互过程:
应用流程进行到结束节点,流程结束 ---> 表单展示流程输出,用户与表单进行交互,触发重新对话接口 ---> 再次从头发起一次流程- 使用示例:
// 表单里的触发按钮 <Button onClick={onRestartClick}>重新对话</Button> // 调用重新对话接口 const onRestartClick = () => { restartClick({ params: /* 这里是表单的出参数据 */ }); } // 如果表单的出参有两个,String 类型的 "a",Int 类型的 "b": restartClick({ params: { a: "hello", b: 1 } });注意:在智能表单节点使用的表单如果调用重新对话接口,需要先执行终止对话接口,将流程停止,再执行重新对话接口。
平台侧收到app-engine-form-restart消息后,会校验流程状态——如果状态为RUNNING会给出提示并拒绝执行;否则将data.params作为output调用重新发起对话接口(见 render.tsx)。
4.4 表单调用外部接口
如果想在表单中调用非平台内置的接口,需要保证该接口支持跨域调用(CORS),因为表单运行在 iframe 沙箱环境中(平台 iframe 的sandbox='allow-scripts',见 render.tsx),跨域请求会受到浏览器同源策略限制。
4.5 表单使用图片
- 使用图片文件时,需要将图片放置在
/src/assets/images目录下; - 表单中的路径需要写为
./src/assets/images/图片文件名。
示例:
<img src="./src/assets/images/empty.png" alt="" height="100px" width="100px"/>这是因为模板的 webpack 配置通过CopyWebpackPlugin将src/assets目录整体拷贝到构建产物中(见 webpack.common.js),运行时保持src/assets/images的相对路径结构。
4.6 表单添加样式文件
可以在/src/styles目录下添加样式文件,请使用.scss类型。webpack 配置中已内置sass-loader+postcss-loader+css-loader的完整链式处理(见 webpack.common.js)。仓库示例的样式位于 form.scss,示例代码如下:
.form-wrap { display: flex; justify-content: center; align-items: center; flex-direction: column; .question-item { font-weight: 600; margin: 8px 0; } .button-group { margin: 12px 0; .save-button { border-radius: 10px; width: 60px; height: 32px; margin: 0 40px; } } }五、调试表单
本地调试分两步:先启动表单工程查看样式,再模拟流程数据验证数据交互。
5.1 启动工程
在工程根目录依次执行:
执行 npm install 执行 npm startnpm start实际运行的是webpack serve --host 127.0.0.1 --port 3350(见 package.json),启动后可在浏览器中打开本地页面查看表单样式是否符合预期。开发服务器配置了热更新(hot: true)与历史路由回退(见 webpack.dev.js)。
5.2 模拟数据传输
可以通过设置 app.tsx 文件里的receiveData来模拟流程传输数据给表单。示例:
receiveData: { data: { "a": "你好", "b": "Demo1" }, // 真正的表单需要的输入 uniqueId: 10, // 任意数字即可 origin: http://127.0.0.1:3350, // 当前调试本地窗口origin tenantId: fh47kl // 任意uuid即可 }在生产运行环境中,receiveData由平台通过window.addEventListener('message', ...)接收 iframe 父窗口(即平台页面)推送的消息来填充,模板代码见 app.tsx;平台侧则是在 iframeonLoad时通过postMessage发送{ uniqueId, origin, tenantId, data }(见 render.tsx),两者正好对应。
六、打包表单代码
调试完成后,执行:
执行 npm run build将组件打包在build文件夹里。生产构建使用 webpack.prod.js,入口为./src/index.tsx,输出index.js到build目录,并合并通用配置中的代码分割与资源处理逻辑。打包后请确认build目录下存在index.js和index.html(平台上传校验所必需的两个文件)。
七、表单出入参配置(config.json)
表单的出入参配置文件必须是 JSON 文件,名称为config.json。文件内容表示表单出入参的类型、描述及参数顺序等信息,需符合 JSON Schema 规范。
7.1 配置约束
- parameters 字段是入参,入参第一层必须
type为object; - 必须包含
name,支持中文、英文、数字、空格、中划线、下划线组合; - 可以包含
description,对参数进行描述; - 必须包含
parameters; - 必须包含
required,其内容不可以是properties下参数名之外的参数名; - 可以包含
order:若写,必须为properties下所有参数名的列表;若不写,则默认按照properties下所有参数名的顺序; - 必须包含
return,return字段是出参。
7.2 配置示例
以下是一个出入参均为字段名"a"、"b"、类型String的完整配置示例:
{ "schema": { "parameters": { "type": "object", "required": [ "a", "b" ], "properties": { "a": { "type": "string", "default": "haha" }, "b": { "type": "string", "default": "heihei" } } }, "return": { "type": "object", "properties": { "a": { "type": "string" }, "b": { "type": "string" } } } } }仓库内 interview 示例的实际 config.json 定义了instanceId(string)与isCvFile(string)两个必填入参,出参为isCvFile;smart-form 示例的 config.json 则展示了更复杂的参数结构(含schema动态渲染所需的字段信息),可作为进阶参考。
一致性要求:config.json 的入参结构必须与表单代码中data的使用结构保持一致(文档明确强调"data 的数据结构与 config.json 的入参配置一致"),否则表单初始化拿不到预期数据。
八、表单预览图与最终打包
- 表单预览图的类型支持
.jpg/.png/.jpeg,文件名必须为form,大小不超过 1M。平台在表单选择列表中通过预览图展示表单外观(见 form-select-drawer.tsx)。 - 最终打包:将
build文件夹、config.json、form.png打成 zip 压缩包。压缩包名称支持大小写英文、中文和数字,可以包含中划线-和下划线_,但不能以中划线或下划线开头或结尾。
interview 示例的预览图如下,展示了"是否继续生成面试计划"的按钮型表单外观:
打包完成后,即可在平台"智能表单节点 / 结束节点"的表单选择抽屉中上传该 zip 包(上传入口及校验逻辑见 upload-form.tsx),并在流程编排中选用。
九、完整开发流程速览
| 阶段 | 操作 | 关键产物 / 命令 |
|---|---|---|
| 环境准备 | Node 18+、npm 10+、VSCode、antd 4.24.13 | 参照示例工程脚手架 |
| 组件开发 | 在/src/components编写.tsx组件,useContext(DataContext)取数据、调接口 | form.tsx |
| 样式/图片 | /src/styles/*.scss、/src/assets/images/*,路径以./src/assets/images/开头 | form.scss |
| 本地调试 | npm install→npm start,通过receiveData模拟流程数据 | 端口127.0.0.1:3350 |
| 打包 | npm run build,产物在build目录 | build/index.js、build/index.html |
| 出入参配置 | 编写config.json(parameters + return,符合 JSON Schema) | config.json |
| 预览图 | form.jpg/png/jpeg,≤1M | form.png |
| 上传发布 | 将 build、config.json、form.png 打成 zip(≤5M,命名合规) | 在表单选择抽屉中上传并选用 |
十、常见问题与避坑要点
- 接口用错节点:终止对话、继续对话接口只能在智能表单节点使用;重新对话接口只能在结束节点使用,混用会报错;在智能表单节点调用重新对话接口前必须先终止流程。
- data 与 config.json 不一致:表单初始化拿到的
data结构必须与 config.json 入参配置完全一致,否则字段取不到值。 - zip 包结构与命名违规:缺少
config.json、build/index.js、build/index.html,或缺少form.png/jpg/jpeg,或总大小超过 5M、预览图超过 1M,上传均会被平台拦截。 - 外部接口跨域:表单运行在 iframe 中,调用非平台内置接口必须确认目标接口允许跨域。
- 图片路径:图片须放在
/src/assets/images下,并使用./src/assets/images/xxx形式的相对路径,否则打包后资源无法加载。 - 调试端口与 origin:本地模拟数据时
origin应填写当前调试窗口的 origin(默认http://127.0.0.1:3350),确保消息能正确回传。
- 人工智能
- 大模型
- AI 应用
- 低代码
- 后端
- 前端
- 流程编排
- RAG
【免费下载链接】app-platform
AppPlatform 是一个前沿的大模型应用工程,旨在通过集成的声明式编程和低代码配置工具,简化和优化大模型的训练与推理应用的开发过程。本工程为软件工程师和产品经理提供一个强大的、可扩展的环境,以支持从概念到部署的全流程 AI 应用开发。
相关推荐
AppPlatform 智能表单自定义组件开发指南:从画布组件开发、config.json 出入参规范到打包上传
AppPlatform 智能表单自定义组件开发指南:从画布组件开发、config.json 出入参规范到打包上传 导读 :AppPlatform(ModelEn
人工智能大模型AI 应用低代码后端前端流程编排RAGAppPlatform 智能表单 React 模板开发指南:从零构建可嵌入流程的自定义表单组件
AppPlatform 智能表单 React 模板开发指南:从零构建可嵌入流程的自定义表单组件 智能表单是 AppPlatform(ModelEngine/ap
人工智能大模型AI 应用低代码后端前端流程编排RAGFlowGram 自定义节点开发指南:从 JSON Schema 表单到自定义 UI 的完整实战
FlowGram 自定义节点开发指南:从 JSON Schema 表单到自定义 UI 的完整实战 导读 本文面向需要在 FlowGram 工作流平台中扩展业务能
前端低代码工作流自动化流程编排
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考