☰
AppPlatform 智能表单自定义组件开发指南:从零开发、调试到打包上传的完整实战
2026/10/14 3:15:34 网站建设 项目流程
  • 人工智能
  • 大模型
  • AI 应用
  • 低代码
  • 后端
  • 前端
  • 流程编排
  • RAG

【免费下载链接】app-platform

AppPlatform 是一个前沿的大模型应用工程,旨在通过集成的声明式编程和低代码配置工具,简化和优化大模型的训练与推理应用的开发过程。本工程为软件工程师和产品经理提供一个强大的、可扩展的环境,以支持从概念到部署的全流程 AI 应用开发。

项目地址:https://gitcode.com/ModelEngine/app-platform
点击查看免费下载

导读

智能表单是 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的动态表单构建思路。

两个工程的目录结构一致,可直接作为自定义表单的脚手架拷贝使用。

三、组件包约束条件

上传到平台的组件包需要满足以下硬性约束:

  1. 必须是 zip 压缩包,解压后总大小不能超过 5M;
  2. 压缩包包含且只能包含三个部分:
    • 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 start

npm 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,≤1Mform.png
上传发布将 build、config.json、form.png 打成 zip(≤5M,命名合规)在表单选择抽屉中上传并选用

十、常见问题与避坑要点

  1. 接口用错节点:终止对话、继续对话接口只能在智能表单节点使用;重新对话接口只能在结束节点使用,混用会报错;在智能表单节点调用重新对话接口前必须先终止流程。
  2. data 与 config.json 不一致:表单初始化拿到的data结构必须与 config.json 入参配置完全一致,否则字段取不到值。
  3. zip 包结构与命名违规:缺少config.json、build/index.js、build/index.html,或缺少form.png/jpg/jpeg,或总大小超过 5M、预览图超过 1M,上传均会被平台拦截。
  4. 外部接口跨域:表单运行在 iframe 中,调用非平台内置接口必须确认目标接口允许跨域。
  5. 图片路径:图片须放在/src/assets/images下,并使用./src/assets/images/xxx形式的相对路径,否则打包后资源无法加载。
  6. 调试端口与 origin:本地模拟数据时origin应填写当前调试窗口的 origin(默认http://127.0.0.1:3350),确保消息能正确回传。
  • 人工智能
  • 大模型
  • AI 应用
  • 低代码
  • 后端
  • 前端
  • 流程编排
  • RAG

【免费下载链接】app-platform

AppPlatform 是一个前沿的大模型应用工程,旨在通过集成的声明式编程和低代码配置工具,简化和优化大模型的训练与推理应用的开发过程。本工程为软件工程师和产品经理提供一个强大的、可扩展的环境,以支持从概念到部署的全流程 AI 应用开发。

项目地址:https://gitcode.com/ModelEngine/app-platform
点击查看免费下载

相关推荐

上一篇:Hugo 分支页面实战:用 Ananke 主题的 `_index.md` 构建 About 等列表页面
下一篇:opencodex Provider 移植调研:五大未路由上游的线协议、认证体系与流式兼容性全景

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询