Formily 是阿里开源的高性能表单解决方案,它的表单设计器能通过 JSON Schema 配置渲染出可交互的表单界面。本来想着让大模型直接根据需求生成符合 Formily 规范的 schema 会很省事,实际用下来却发现不少问题。先说说最开始的 v1 方案 —— 让 LLM 直接生成 JSON 格式的 Formily Schema(参考:juejin.cn/post/739402…),但这有一些坑:
一是生成的 schema 格式经常不准,要么缺必选的 x-designable-id,要么组件属性写错(比如把 Input 的 props 填到了 x-decorator-props 里),调试起来特别麻烦;
二是直接生成大段 JSON 特别耗 token,尤其是复杂表单,成本也高。
核心逻辑
后来看到一篇论文(arxiv.org/pdf/2508.05…)里的思路特别好,就借鉴过来做了 v2 版本 —— 不让 LLM 直接生成 schema,而是先让它生成 “指令”,再用我们的程序把指令转换成符合 Formily 规范的 schema。
v2 的核心思路很简单,全程不让 AI 直接生成 schema :
- AI 把用户的自然语言需求转换成结构化的任务指令;
- 我们的程序按照 Formily 固定规范,把这些指令转换成确定性的 schema。
这么做不仅能保证 schema 格式 100% 符合要求,还能省不少 token;
另外还有个额外好处:不怎么依赖大模型的能力,后续要新增表单组件也特别方便,不用重新调教模型。
指令的设计思路
v1 直接生成大段 JSON 属于 “一口吃成一个胖子” 的思路,模型很容易顾此失彼,要么漏属性要么格式错。所以借鉴 curriculum learning(课程学习) 的思想,也就是让模型从简单任务到复杂任务逐步学习的思路,让模型从简单到复杂一步步生成指令,不用一步到位:
- 布局阶段:先只生成每个组件的基础信息,比如用什么组件(Input/NumberPicker)、放在哪个位置、同级组件的
x-index顺序; - 属性阶段:再根据需求逐步补全组件的专属属性,比如 Input 的 placeholder、NumberPicker 的最大值最小值、Select 的枚举选项;
- 联动阶段:最后再增加 reactions 指令,实现表单字段之间的联动效果(比如选了 “其他” 选项才显示备注输入框)。
这样拆分后,模型只需要专注处理每一步的简单指令,不用同时兼顾 Formily 复杂的 schema 格式规则,生成的内容更可控,我们的程序也能按阶段把指令转换成标准的 schema,既好调试又省成本。
演示
由于有一些业务代码,就不开源了,直接看效果吧: