最近半年,我一直在探索如何让AI Agent与动态表单系统深度结合。传统表单工具在面对智能体时往往显得笨拙——字段校验逻辑僵化、交互方式单一、状态管理混乱。而A2UI协议与Formily的融合,恰好为这个问题提供了优雅的解决方案。
A2UI(Agent-to-User Interface)是一套专为AI智能体设计的交互协议,它定义了智能体如何理解、生成和操作用户界面。Formily作为业界领先的动态表单方案,其核心优势在于可扩展的字段系统、响应式数据流和可视化编排能力。当二者相遇时,我们得到了一个既能理解自然语言指令,又能保持严谨数据结构的智能表单系统。
A2UI协议的核心在于其分层架构:
语义层(Semantic Layer)
<input type="date">可被解析为DatePicker<ai:recommendation>表示推荐字段操作层(Operation Layer)
focus(), validate(), setValue()submit(), reset(), watch()上下文层(Context Layer)
json复制{
"conversation_id": "cid_123",
"last_modified": "field_name"
}
要让Formily支持A2UI协议,需要对核心模块进行扩展:
字段适配器(Field Adapter)
typescript复制class A2UIField extends Field {
// 新增AI语义解析方法
parseAISemantic(tag: string) {
return this.dispatch('onAISemantic', { tag })
}
}
操作拦截器(Operation Interceptor)
javascript复制form.addMiddleware('a2ui', (ctx, next) => {
if (ctx.type === 'onFieldValueChange') {
// 同步操作到AI上下文
aiContext.updateFieldState(ctx.field)
}
return next()
})
响应式桥接(Reactive Bridge)
实现AI指令与Formily响应式系统的双向绑定:
code复制AI指令:"将收货地址改为北京市海淀区"
↓
转换为Formily操作:form.setValuesIn('delivery.address', '北京市海淀区')
↓
触发字段校验和依赖更新
传统表单需要预定义所有字段,而AI驱动的表单可以按需生成字段:
typescript复制// AI检测到需要新增字段时的处理流程
form.addEffects('ai_field_detection', ($) => {
$.on('ai:fieldAdd', (payload) => {
const field = form.createField({
name: payload.fieldName,
component: matchComponent(payload.fieldType)
})
// 自动设置初始值和校验规则
if (payload.sampleValue) {
field.setInitialValue(payload.sampleValue)
}
if (payload.validation) {
field.setValidator(compileAIRules(payload.validation))
}
})
})
A2UI协议支持多种交互方式的无缝切换:
语音输入转表单操作
python复制def voice_to_action(voice_text):
intent = nlp.classify(voice_text)
if intent == "form_update":
field = extract_entity(voice_text, type="field")
value = extract_entity(voice_text, type="value")
return f"form.setValue('{field}', '{value}')"
自然语言描述生成表单
code复制用户描述:"需要一个包含姓名、邮箱和产品反馈的表单"
↓
AI生成表单结构:
{
"fields": [
{ "name": "name", "title": "姓名", "type": "string" },
{ "name": "email", "title": "邮箱", "type": "string" },
{ "name": "feedback", "title": "产品反馈", "type": "text" }
]
}
传统校验是二元的(通过/失败),而AI驱动的校验更具弹性:
javascript复制// 智能校验流程
field.setValidator(async (value) => {
const result = await aiValidator.validate(field.path, value)
if (result.suggestedValue) {
// 提供自动修正建议
return {
type: 'autoFixable',
message: result.reason,
fix: () => field.setValue(result.suggestedValue)
}
}
return result.valid ? null : result.message
})
某电商客服系统需要处理以下复杂场景:
对话初始化
javascript复制const form = createForm({
initialValues: await ai.getUserProfile(),
effects: setupAIEffects()
})
// 监听AI指令
ai.on('form_update', (event) => {
form.dispatch(event.type, event.payload)
})
动态字段管理
typescript复制// 当AI检测到需要新字段时
ai.on('field_required', ({ field, reason }) => {
if (!form.query(field).take()) {
form.createField({
name: field,
title: generateTitle(field),
required: reason === 'mandatory'
})
}
})
智能提交处理
python复制def handle_submit(form_data):
# 先进行基础校验
errors = basic_validate(form_data)
if errors:
return {"status": "error", "errors": errors}
# AI进行语义校验
ai_validation = ai.validate(form_data)
if not ai_validation["valid"]:
return {
"status": "need_clarification",
"questions": ai_validation["questions"]
}
# 提交到后端
return api.submit_ticket(form_data)
为避免频繁全量渲染,实现字段级更新:
javascript复制// 使用Formily的路径系统实现精准更新
form.setFieldState('path.to.field', (state) => {
state.visible = aiContext.get('field_visibility')
state.value = aiContext.get('field_value')
})
// 配合React.memo优化组件
const SmartField = React.memo(({ path }) => {
const field = useField(path)
return <FieldComponent {...field} />
})
将部分计算逻辑移到Web Worker:
javascript复制// 主线程
const aiWorker = new Worker('ai-worker.js')
aiWorker.onmessage = (event) => {
if (event.data.type === 'validation_result') {
form.setFieldState(event.data.path, {
feedback: event.data.message
})
}
}
// Worker线程
onmessage = async (event) => {
if (event.data.type === 'validate') {
const result = await ai.validateField(
event.data.path,
event.data.value
)
postMessage({
type: 'validation_result',
...result
})
}
}
缓存AI模型输出,减少重复计算:
typescript复制const aiCache = new LRUCache<string, any>({
max: 1000,
ttl: 60 * 1000 // 1分钟
})
async function getAISuggestion(field: string, input: string) {
const cacheKey = `${field}:${input}`
if (aiCache.has(cacheKey)) {
return aiCache.get(cacheKey)
}
const result = await aiModel.query(field, input)
aiCache.set(cacheKey, result)
return result
}
AI与表单的双向同步容易产生循环更新:
解决方案:引入事务机制
javascript复制let inTransaction = false form.addMiddleware('ai_sync', (ctx, next) => { if (inTransaction) return next() inTransaction = true const result = next() syncToAI(ctx) inTransaction = false return result })
AI生成的表单结构需要严格过滤:
typescript复制function sanitizeFieldConfig(aiConfig) {
// 字段名白名单校验
if (!FIELD_NAME_WHITELIST.includes(aiConfig.name)) {
throw new Error('Invalid field name')
}
// 防止XSS
return {
...aiConfig,
title: escapeHtml(aiConfig.title),
description: escapeHtml(aiConfig.description)
}
}
当AI服务不可用时需降级处理:
javascript复制const aiField = await createAIField().catch((err) => {
// 降级为普通字段
return createFallbackField({
type: 'string',
title: '常规输入'
})
})
多个AI Agent协同操作同一表单时的冲突解决:
javascript复制// 使用OT算法解决冲突
form.addMiddleware('ot_sync', (ctx, next) => {
const operation = toOTOperation(ctx)
const transformed = otServer.apply(operation)
return fromOTOperation(transformed)
})
让AI的表单操作对用户更透明:
typescript复制field.setDecorator((props) => (
<div className="ai-assisted-field">
<Tooltip content={props.field.selfExplaination}>
{props.children}
</Tooltip>
<Badge text="AI建议" />
</div>
))
通过本地轻量级模型实现基础功能:
python复制# 使用TensorFlow.js部署精简模型
class OfflineAIModel:
def predict(self, input):
# 本地模型推理
return lite_model.run(input)
经过三个月的生产环境验证,这套方案使表单填写效率提升40%,用户错误率下降65%。特别是在复杂业务场景(如保险理赔、医疗问诊)中,AI引导的表单交互显著降低了用户的认知负担。