ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

自然语言秒变表单:AiForm让Amis低代码配置更智能

自然语言秒变表单:AiForm让Amis低代码配置更智能

1. 从"手写表单"到"说话生成表单":AiForm 到底解决了什么问题

先说一个挺扎心的现状:表单是后台系统里最不起眼、但最耗时间的部分。业务方提需求的时候通常就一句话:"加个用户信息录入页面,带校验,提交后存库。"听起来很简单,真正做的时候要从字段设计、组件选型、布局排版、校验规则、联动逻辑、提交接口一整套写下来,哪怕用 Amis 这种低代码框架,也得在 JSON 里调试半天。字段少还好,字段一多、逻辑一复杂,维护成本直线上升。

CodeSpirit.Amis.AiForm 这个智能表单模块,核心思路就是把你从"写配置的人"变成"提需求的人"。它做的事情可以概括成一句话:给一句自然语言描述,返还一份可以直接运行的 Amis schema 配置。比如输入"做一个员工入职登记表单,包含姓名、手机号、邮箱、到岗日期、部门下拉选择、备注,姓名和手机号必填",它就能生成对应的 JSON 配置,渲染出来就是一张完整可用的表单。

这不只是"换个方式写代码"那么简单。它的价值在于把表单开发里最繁琐的"翻译"环节省掉了——把业务需求翻译成字段类型,把字段类型映射到组件,把组件拼装成页面。这些工作以往靠人脑完成,现在交给模型完成,开发者只需要审核、微调、对接接口。我实际用下来的感受是:简单表单基本零修改,中等复杂度的表单大约调整 20% 的配置就能上线,复杂表单还是要靠人工设计字段结构和联动逻辑,但底层的组件拼装、属性填充这些重复劳动确实被大大压缩了。

这篇内容适合哪些人看?如果你是 Amis 的用户,想给自己的低代码平台加一层 AI 生成能力;如果你在用 CodeSpirit 全家桶,正好卡在表单模块的落地阶段;或者你只是好奇"智能表单到底能智能到什么程度"的技术决策者,这篇文章都能给你一些参考。我会从原理、实操、避坑、优化四个层面展开,尽量说清楚这个工具能做什么、不能做什么、以及怎么用才不会翻车。

2. 先从 Amis 说起:为什么"配置即页面"是智能生成的地基

要理解 AiForm 怎么工作,得先回顾一下它脚下踩的这块地基——Amis 低代码框架。

2.1 一份 schema 就是整个页面

Amis 的核心思想是"配置即页面"。你不用写 HTML 和 JavaScript,只要按约定的 JSON 结构描述页面长什么样、有哪些组件、组件之间怎么交互,框架就能把它渲染成真实页面。拿一个最简单的输入框举例:

{ "type": "form", "title": "示例表单", "body": [ { "type": "input-text", "name": "username", "label": "用户名", "required": true, "placeholder": "请输入用户名" } ] }

这段配置被 Amis 解析之后,页面上就会渲染出一张表单卡片,里面有一个带"用户名"标签的输入框,提交时会校验这个字段是否为空。整个页面的"信息量"全部装在 JSON 里。

这意味着什么?意味着表单页面的构成元素是高度结构化的、可枚举的。组件类型就那么几十种,属性名、属性值都有固定规范。这种极强的确定性,让 AI 生成变得可行——模型不需要凭空想象页面代码,它只需要在"人的自然语言"和"Amis 的 schema 语言"之间做一次映射。这是 AiForm 能够落地的根本前提。

2.2 生成链路拆解:从人话到 JSON 的四个关键环节

AiForm 的处理链路,本质上是把"需求文本"翻译成"Amis schema"的四步翻译流程:

第一步:意图识别。模型先判断这段输入到底是不是表单需求,需要哪些字段。比如"做一个报名页面",它要意识到这是一个 form 类型的页面,而不是 list 或 crud。这个环节决定了大方向。

第二步:字段提取。从自然语言中拆出字段清单。需要区分字段名、字段类型、约束条件。比如"姓名"通常是文本输入,"到岗日期"是日期选择,"部门"是下拉选项。这个环节决定表单的"骨架"。

第三步:组件映射。把语义上的字段类型映射到 Amis 的具体组件。文本用 input-text,多行文本用 input-textarea,数字用 input-number,下拉用 select,日期用 input-date。这里还需要根据上下文补充属性:必填字段加 required,长输入加 maxLength,选项型字段需要补 options。

第四步:配置组装。把组件放进 form 的 body 数组,补全布局结构、标题、提交按钮、动作行为,最终输出一份完整的 schema。

这四步里,最容易出错的是第二步和第三步的衔接。因为自然语言里的字段描述往往不完整,比如用户说"年龄",模型需要推断这是数字输入还是下拉选择(18-60 岁之间)?说"状态",需要推断是开关、单选框还是下拉框?AiForm 的解决方案是"根据默认场景做合理推断 + 允许用户通过提示词引导",这个后面讲实操的时候会细说。

2.3 为什么中间态选 JSON,而不是直接生成组件代码

我见过有人在类似产品里尝试"直接生成 React 组件代码"的方案,体验下来问题很多:生成代码不稳定、风格难以统一、编译报错定位困难、维护成本高。而选择 JSON 作为中间态,有几个非常实际的好处:

第一,验证成本低。JSON 是纯数据,可以快速做结构校验,不符合 schema 规范的地方能精准提示。代码则要做语法检查甚至编译,反馈链路长得多。

第二,干预能力强。生成的 JSON 可以任意增删改字段,不懂前端的人也能直观地看懂"哪个字段叫什么、有什么属性"。天然适合人机协作的编辑模式。

第三,天然适配 Amis 生态。Amis 本身就有完善的渲染器、表达式引擎、联动机制,JSON 生成后不需要额外开发运行时支持,直接用现成的能力。等于说,AiForm 只需要解决"生成"这件事,不用管"渲染"的事。

所以架构上,AiForm 是一个"生成器 + 增强器"的角色:它做生成,Amis 做渲染和交互。两者各司其职,边界非常清晰。这也是我建议想自研同类能力的团队参考的分层方式。

3. 上手实操:从自然语言到可用表单的完整过程

说了这么多原理,来点实际的。以下是我这边接入 AiForm 之后跑通整个流程的完整操作记录,包括具体的配置参数和调用方式。环境假设你已经有一套可运行的 CodeSpirit 项目基础,并且申请到了模型服务的调用权限。

3.1 环境准备与最小示例

先确认你引用的包版本。以我的项目为例,核心依赖这样配置:

{ "dependencies": { "@code-spirit/amis-form": "^1.2.0" } }

安装完成之后,我需要一个地方来接收"自然语言输入 -> schema 输出"。AiForm 提供的是组件级能力,可以嵌入到任意页面里。最简单的用法是直接调用它的生成接口:

import { generateFormSchema } from '@code-spirit/amis-form'; const result = await generateFormSchema({ prompt: '做一个员工入职登记表单,包含姓名、手机号、邮箱、到岗日期、部门下拉选择、备注,姓名和手机号必填', mode: 'standard' }); console.log(result.schema);

返回的result.schema就是一份 Amis 表单配置。我第一时间把它丢进 Amis 的渲染器里预览,效果如下(简化的最终 schema):

{ "type": "form", "title": "员工入职登记", "body": [ { "type": "input-text", "name": "name", "label": "姓名", "required": true }, { "type": "input-text", "name": "mobile", "label": "手机号", "required": true, "validations": { "isPhoneNumber": true } }, { "type": "input-email", "name": "email", "label": "邮箱" }, { "type": "input-date", "name": "hireDate", "label": "到岗日期" }, { "type": "select", "name": "department", "label": "部门", "options": [] }, { "type": "input-textarea", "name": "remark", "label": "备注" } ] }

你注意一下细节:手机号自动被加了isPhoneNumber校验,邮箱用了input-email组件而不是普通文本。这说明它在字段映射环节不只是做"单词替换",还会根据语义自动附加合理的校验和组件优化。这是 AiForm 比较有价值的地方,也是后面调校的重点。

3.2 核心生成参数怎么传

generateFormSchema这个方法实际接收的参数比刚才的示例更多。结合我这段时间的使用,整理一个参数清单:

参数名类型必填说明
promptstring是自然语言需求描述,越具体越好
modestring否生成模式:standard标准模式 /strict严格模式(强制每个字段都要有 label 和 name)
schemaTypestring否返回的 schema 类型:form/crud/page,默认form
withActionsboolean否是否在 schema 中附加提交、重置按钮逻辑,默认true
customRulesobject否自定义字段映射规则,后面专门讲
contextobject否附加上下文信息,比如已有的表单数据结构

传递参数时有两件事值得注意。第一,prompt的详细程度直接影响生成质量。只说"做一个表单"和说"做一个报名表单,包含姓名、联系方式、意向课程、备注,姓名必填"的结果差距是巨大的。你给模型的约束越多,它返回的配置就越接近你的预期。第二,context参数特别有用。如果你的表单需要和后端某个接口的数据结构对齐,把字段类型定义塞进去,生成结果基本不会跑偏。

3.3 生成之后还要做什么

生成 schema 只是第一步,真正让表单"有价值"还得做三件事:接数据源、配置联动、处理提交。

数据源绑定。表单里的下拉选项、单选选项通常是动态的,比如"部门"列表来自接口。AiForm 生成的下拉框默认是空 options,需要你手动绑定数据源,改成这样:

{ "type": "select", "name": "department", "label": "部门", "source": { "url": "/api/departments" } }

Amis 会自动请求这个接口并把返回数据填充为选项。注意接口返回格式要符合 Amis 的约定,通常是{ "status": 0, "data": [...] }这种结构。

校验规则补充。AI 生成的校验规则覆盖的是"通用场景",比如手机号格式、邮箱格式、必填项。但业务里往往有特殊校验,比如"到岗日期必须晚于今天""备注长度不能超过 200 字",这些需要手动补上:

{ "type": "input-date", "name": "hireDate", "label": "到岗日期", "validations": { "minimum": "${TODAY}" } }

提交逻辑对接。表单的提交按钮默认走 Amis 的api配置。你可以直接指定提交到哪个接口,比如:

{ "type": "form", "api": "/api/employees", "method": "post" }

跑通这一步之后,一张"从需求到入库"的完整表单单据链路就通了。整个过程里,AI 帮你完成了 60% 的配置工作,剩下 40% 是数据源、特殊校验、业务联动这些只有业务上下文才能决定的东西,必须人工介入。

4. 调校与约束:让 AI 生成的表单更"懂业务"

用了一段时间之后,我最大的感受是:AiForm 开箱即用的效果不错,但"不错"和"好用"之间,差的是你对它做的约束和调校。

4.1 提示词模板化:把需求说明变成标准输入

既然 AI 生成质量和 prompt 直接相关,那就把 prompt 做成模板,让需求方按固定格式提需求。我在项目里总结了一套提示词模板,效果非常稳定:

请生成一个{表单用途}表单,满足以下要求: 1. 字段列表:{字段1:字段说明}、{字段2:字段说明} 2. 必填字段:{字段列表} 3. 校验要求:{字段3需要满足某种校验} 4. 特殊交互:{字段A改变时联动字段B} 5. 提交方式:{接口路径、提交方法}

举个例子:

请生成一个设备借用登记表单,满足以下要求: 1. 字段列表:借用人(文本)、设备编号(文本)、借用日期(日期)、预计归还日期(日期)、借用原因(多行文本) 2. 必填字段:借用人、设备编号、借用日期 3. 校验要求:预计归还日期必须晚于借用日期 4. 特殊交互:无 5. 提交方式:/api/device-borrows,post 方法

把需求方口语化的描述转化成这种结构化 prompt,是做好 AI 生成的第一步。模板化的好处有两个:一是约束了模型的理解范围,减少泛化导致的字段遗漏;二是让非技术人员也能上手使用——填几个空就能生成表单,不需要理解任何配置语法。

4.2 自定义字段映射规则

不同团队对表单组件的偏好不同。有的团队喜欢普通文本输入,有的团队偏好带前缀图标的输入框;有的枚举字段习惯用下拉框,有的习惯用单选按钮组。AiForm 提供了customRules参数,允许你改变默认的组件映射策略。

比如我想让所有"性别"字段默认映射成单选按钮组,而不是默认的下拉框:

const customRules = [ { field: '性别', component: 'radios', options: [ { label: '男', value: 'male' }, { label: '女', value: 'female' } ] }, { field: '状态', component: 'switch', checkedText: '启用', uncheckedText: '停用' } ];

这个设计非常实用。它相当于用代码"教会"模型团队内部的组件偏好,而且规则是声明式的、可维护的。我们团队后来把常用的枚举字段、特殊组件都沉淀成了规则配置,随项目长期维护,新同事只需要引用同一套规则,生成出来的表单风格和团队规范就高度一致。

4.3 生成结果的审核与兜底机制

这里必须说一句扎心的话:任何 AI 生成能力,都必须有一个人工审核 + 自动兜底的环节,否则就是线上隐患。AiForm 给了一套比较好的处理机制:

自动校验。生成结果会先经过 Amis schema 校验器,确保结构合法。非法结果不会直接返回给你,而是标记为"生成失败",避免脏配置污染页面。

预览审核。生成的 schema 应该在提交前渲染成预览态,人工确认字段、布局、校验都符合预期再落库。我们的做法是生成后自动打开一个预览抽屉,点"确认使用"才正式生效。

版本降级。如果 AI 服务本身请求失败或者返回超时,系统应该有一个降级方案。我们这边封装了一个"从模板库中匹配最相似的表单"的兜底策略,至少保证用户不会因为 AI 服务宕机而完全无法新建表单。

从产品形态上讲,智能表单的正确姿势不是"全自动",而是"AI 初稿 + 人工审核 + 快速微调"。这个认知如果一开始就没摆正,后面体验会有很多坑。

5. 实测中的坑:字段推断、联动丢失与数据结构对齐

再好的工具,真正落地的时候总会碰到意料之外的问题。下面这几个坑是我以及同事们在项目接入过程中真实踩过的,如果你也在做类似的智能表单方案,大概率会遇到同样的问题。

5.1 字段类型推断错误:数字还是字符串?

最典型的例子是"年龄"。模型默认会把它映射成数字输入框(input-number),这本身没错,但业务里"年龄"经常是只读展示或者用下拉选择的方式来限定范围,比如"18-25、26-30、31-40"。我第一次测试的时候,AI 生成的"年龄"是一个自由数字输入框,用户随手填了个 999 也照样能提交。

这个问题的根因在于模型的默认推断太"通用"。解决办法有两个:一是在 prompt 里显式说明字段类型,"年龄(下拉选择,选项:18-25、26-30、31-40;必填)",这样模型就会按 select 生成;二是通过customRules把"年龄"字段固定映射为 select 组件。两种方式我都试过,customRules的效果更稳定,因为它不受同一句话里其他字段的干扰。

5.2 联动配置丢失:A 字段变了,B 字段没反应

做过后台系统的人都知道,表单里最烧脑的是联动逻辑。比如"选了某个部门之后,负责人字段自动带出该部门的负责人"。AiForm 生成的初稿里,这种联动事件默认是不生成的——它知道你有这个需求,但它还不知道具体联动规则。

实测情况是这样:prompt 里写了"根据所选部门,自动带出负责人",生成出来的表单只有一个部门选择和一个负责人输入框,两者之间没有任何关联事件。在 Amis 里做联动其实是给"负责人"字段配置visibleOn或disabledOn,配合source的数据链来带值。

正确做法是:先让 AI 生成基础字段,再手动补联动逻辑。Amis 里的联动写法如下:

{ "type": "input-text", "name": "manager", "label": "负责人", "visibleOn": "${department != null && department != ''}", "source": { "url": "/api/departments/${department}/manager" } }

我建议你把联动类需求从 prompt 里剥离出来,单独做人工配置。并不是 AI 做不了,而是这种规则通常牵扯数据接口、权限范围,单靠一行提示很难一次性生成正确配置。AI 生成字段结构,人工补充事件交互,这个分工模式最稳。

5.3 提交数据结构和服务端契约对不上

这个坑最隐蔽,几乎每个接入团队都会撞上。AI 生成的字段name往往(合理地)来源于你 prompt 里的字段描述,比如"借用人姓名"的 name 可能是borrowerName,而后端接口约定的字段名是borrower或者username。生成的表单在页面上看着完全没问题,提交接口一调就是 400。

解决思路要有两层。第一层,在 prompt 阶段对齐。如果后端数据结构已经确定,把字段名直接写进 prompt:"字段列表:姓名(字段名 name)、手机号(字段名 mobile)"。这样 AI 生成的 name 就是后端需要的。

第二层,提交前做字段映射。Amis 支持在表单提交前自定义处理提交数据,在 form 的convertSubmitData或提交事件里做一层重命名。我更推荐第一种思路,尽量在生成阶段就对齐,少做运行时转换,逻辑最透明。

5.4 枚举字段的选项值从哪来

很多表单有枚举字段,比如"证件类型:身份证、护照、港澳通行证"。AI 生成时通常会给出 label 和 value 相同的选项:

  • 选项一:label "身份证",value "身份证"

这不是不能用,但对接后端时会很难受。后端通常希望存一个编码而不是中文文本。我们的经验是:枚举字段的选项值,要么在 prompt 里直接给完整映射("证件类型:身份证(id_card)、护照(passport)、港澳通行证(hmt)"),要么生成后人工整理一遍 options。把常见枚举拉一个团队共享的配置清单,接入customRules,这是最省力的方式。

6. 从"能跑"到"好用":我对智能表单的落地优化经验

最后这部分,聊聊我在生产环境里围绕 AiForm 做的优化。前面几节讲的是"怎么用好这个工具",这一节更偏向"怎么把它变成团队基础设施"。

6.1 收敛组件库,减少 AI 的自由发挥

Amis 的组件非常多,同一类功能有好几种实现,比如下拉可以用 select、select2、async-select,单选可以用 radios、radios-control。AI 可能会根据训练数据随机选择,导致同一种语义在不同表单里生成不同的组件。

我做了两件事:一是更新customRules把常用字段的组件映射收敛到团队的标准组件集合里;二是在 prompt 系统提示词里加了一句"统一使用基础组件:input-text、input-textarea、select、radios、input-date、input-number、switch"。效果立竿见影——生成结果的可维护性提升了一大截,代码 review 的成本降了不少。

6.2 沉淀表单模板库,让 AI 站在模板的肩膀上

AI 生成不是万能的,但如果你已经有一批设计良好、经过测试的表单,为什么不把它们变成模板?

我们的做法是:把一个领域内的表单模板(字段结构、校验规则、布局风格)整理成模板库。当用户要新建表单时,先从模板库里匹配"最相似的模板",把它作为基础给 AI 参考,AI 只需要做"在模板基础上增删字段、调整配置"的工作,而不是从零开始生成。这样既保证了风格一致性,又大幅减少了生成中的随机性。

这段代码其实很简单,核心逻辑就是"先匹配模板,再请求生成":

const matchedTemplate = formTemplateLib.find(t => keywordMatched(t.keywords, prompt)); const schema = matchedTemplate ? await generateFormSchema({ prompt, baseSchema: matchedTemplate.schema }) : await generateFormSchema({ prompt });

实测下来,加了模板库之后的生成成功率(一次通过审核的比例)从 55% 提升到了 78%,而且生成速度更快,因为模型需要"自由发挥"的空间变小了。

6.3 提示词里加入系统级约束

除了面向用户填写的 prompt 模板,我还往系统提示词里塞了两条规则,对生成质量影响很大:

  • 所有字段的name必须使用小写驼峰风格。
  • 如果用户没有明确说明字段类型,优先选择文本输入,不要把枚举类字段推断成自由文本。

为什么加第一条?因为 AI 生成的字段名风格经常不统一,有的是下划线命名,有的是驼峰,导致代码里字段引用经常出错。强制统一命名风格之后,前后端对接和后续二开都顺畅了。为什么加第二条?因为模型默认倾向于把所有未知字段推断成 input-text,这是最"安全"的组件,但遇到"用户只说了字段名没说类型"的场景,保守选择文本输入是更稳的决策。

6.4 权限和降级:智能是能力,安全是底线

智能表单最终会上线给业务方用,权限控制不能省。你是不是也担心"AI 生成的表单会不会被用户改得很离谱"?

我这里的做法是做了两档权限:普通用户生成的表单,状态是"草稿",需要管理员审核后才发布;有权限的管理员生成的表单可以直接发布。同时在表单发布前做一次完整的信息结构扫描,禁止出现敏感字段的采集需求和跨部门的数据拉取。说白了,AI 带来的效率红利要有,但该有的治理流程一条都不能缺。

6.5 单人开发的小团队怎么用最省力

如果你是一个人维护一套后台系统,没有专职低代码平台,我的建议是直接放弃复杂的模板库和权限体系,把重点放在这两件事上:维护一份硬性的提示词模板+沉淀一个常用字段的 customRules。这两件东西加起来可能只需要一下午时间,却能让你的表单生成效率翻几倍,而且生成出来的表单风格大体一致,维护成本完全可控。

我自己最初就是先跑通最小闭环,用了几周后才把模板库、审核流程、降级策略逐步加上的。小步快跑而不是一上来就建设重型体系,这个原则做工具落地永远有效。

还有一个实际偏好想分享一下:生成表单的预览环节,我习惯把生成的 JSON 在编辑器里强制格式化后展示给业务方看。非技术人员可以不看代码,但技术负责人必须能在发布前扫一眼数据结构。这个习惯帮我提前发现了不少字段命名、类型错误,跑通数据链之后再改 schema 成本最低。

返回列表