For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt, and this page is available as Markdown at /recipes/form-assist.md.
外观 ◐
让站点跟随你的 ChatKit打开主题工作台 →

对话辅助填表

用户在左侧说“申请两台云服务器,地域选北京”,右侧表单自动填入数量和地域。用户可以继续对话,也可以直接修改表单,检查后再确认提交。

这项功能不依赖 OpenAI,也不限定某一种 Agent。 ChatKit 显示对话,业务应用负责表单,Agent 提出修改。需要接通的是“修改请求”和“执行结果”的往返。

先点击 Demo 的第一条推荐问题,看右侧字段发生什么变化。本例用本地规则模拟 Agent,没有连接真实模型或业务后端;“确认提交(本地)”不会创建真实资源。

对话辅助填表:Agent 更新草稿,用户修改后确认Mock 演示全屏 ↗
正在加载真实示例…

窄屏下对话与表单上下排列,可在预览中滚动;也可以打开全屏。完整源码与预览一致,下载工程时同时下载旁边的本地 SDK。

先看一遍完整流程

对话辅助填表的业务流程

查看业务流程大图。

  1. 用户说需求:“两台服务器,地域选北京。”
  2. Agent 提出修改:让应用把数量改为 2,地域改为北京。
  3. 应用执行:检查字段和当前表单版本,更新草稿,右侧显示新值。
  4. 应用告知结果:把“填写成功”或“未能填写及原因”返回给 Agent。
  5. Agent 继续:成功时说明已填哪些内容;失败时解释原因或让用户补充信息。

第 4 步不可省略。 右侧界面变了,只能说明应用里的表单状态变了;Agent 收到执行结果后,才知道这次修改是否成功。填写草稿成功和提交业务单据成功也要分别告知。

谁负责什么

角色责任
Agent理解需求,提出修改,读取执行结果后决定下一步
业务应用管理右侧表单,执行校验和修改,回传真实结果
ChatKit显示对话、工具过程和修改回执,提供接入这些交互的公开入口

功能、工具和协议是什么关系

这三个词说的是不同的事情:

名称在这个场景中的含义例子
功能用户能完成什么通过对话填写右侧表单
工具Agent 可以请求应用做什么动作“更新表单草稿”,本例命名为 update_form_draft
协议请求和结果按什么格式、通过什么通道传递应用如何收到“数量改为 2”,又如何把执行结果传回 Agent

协议不决定用户的表单长什么样,也不等于这项功能。 同一套填表功能可以接不同 Agent,但接入代码需要适配它们传请求、收结果的方式。就像同一个表单能连接不同的业务接口,页面功能相同,请求参数和返回格式可能不同。

前面提到 OpenAI,只是因为当前仓库有一个现成适配器支持“在浏览器执行工具并回传结果”。它是可选接法,不是填表功能的前提。业务已经有 Agent 后端时,直接对接该后端提供的工具调用或人工交互接口,无需为了这个功能换模型或后端。

Agent 如何知道该调用前端

应用先把可用动作的名称、用途和允许的参数告诉 Agent。Agent 返回工具名称和参数后,应用根据名称找到执行函数。这个函数可以在前端更新表单,也可以调用后端接口;执行位置由应用决定,Agent 不需要查找 DOM 或 React 组件。

在本例中,“更新表单草稿”对应的是 store.apply(...)。正文里的“已填好”只是解释;表单的实际变化来自这个执行函数。

调用闭环:前端工具与 HITL

HITL(Human-in-the-loop)就是流程中需要人来决定或补充信息。它与自动工具的共同点是:Agent 发出请求,等待结果,收到结果后继续。

体验什么时候回传结果是否必须等用户
自动填写草稿应用检查并更新字段后立即回传不需要
先让用户确认用户确认、修改或拒绝后回传需要,这就是人工介入

例如,“Agent 建议买两台,用户可以改成三台,再点确认”,回传的应是用户最终确认的三台,而不是 Agent 原先建议的两台。取消、拒绝或填写失败也要明确回传,让 Agent 知道该怎样继续。

当前 Demo 做到了哪一步

已经可以体验尚未连接真实服务
本地规则提出修改、右侧草稿更新、手动编辑、版本冲突拒绝、聊天回执和本地确认提交真实 Agent 决策、把执行结果送回 Agent、Agent 等待人工确认后继续、刷新后的业务数据恢复

当前 Demo 的“确认提交(本地)”没有让真实 Agent 等待或继续。 它只是改变页面内存状态。生产如果要求点确认后 Agent 继续,就需要把该按钮的处理结果接到 Agent 的结果接收接口。

接入 SOP

1. 由应用管理右侧表单

把聊天区和表单放在同一个业务页面,表单只保存一份草稿。用户手动编辑和 Agent 修改都更新这份草稿。

本例 form-assist.tsx 负责布局和表单组件,form-assist-store.ts 保存字段与版本。每次修改递增版本,避免较早的 Agent 结果覆盖用户的新修改。

2. 发送时告诉 Agent 当前表单内容

onSend 读取最新草稿,合并到输入的 metadata。本例的业务数据结构为:

{
  "formContext": {
    "formId": "compute-request",
    "expectedVersion": 1,
    "values": { "quantity": 1, "region": "上海", "purpose": "" }
  }
}

这段数据表达“当前是哪张表、哪个版本、有哪些值”。它由业务定义,不是 SDK 内置的表单类型。接真实后端时,还要让适配器把这些信息放到该后端实际读取的位置;只给前端加 metadata,Agent 不会自动知道。

3. 接收修改请求,校验后执行

应用收到工具名称和字段修改后,调用对应的草稿更新函数。这里负责检查:表单标识是否匹配、字段是否允许修改、数量和地域是否有效、版本是否还是发送时的版本。

本例 form-assist-adapter.ts 用 plan() 的固定规则模拟修改请求:只识别数量、北京/上海/广州和“用途:…”等输入,等待两秒后调用 store.apply(...)。无法识别时给提示,不修改表单。生产用真实 Agent 的请求替换这一步,并在业务服务端执行权限与数据校验。

4. 把执行结果交回 Agent

本例草稿服务返回:

{
  "applied": true,
  "reason": "草稿更新成功",
  "version": 2,
  "fields": ["quantity", "region"]
}

应用应把结果关联到原来的那次修改请求再送回 Agent,不能只画一张“成功”卡片。发生冲突时回传 applied: false、原因和当前版本,保留用户的新值。实际接入可以返回校验后的完整字段,方便 Agent 理解最终表单。

当前本地 Demo 直接用该结果更新聊天回执,并按固定规则生成后续文字;此处没有真实 Agent 的结果回传请求。换成真实服务时,需要补上接收修改请求和返回结果这两个连接点。聊天回执渲染和 onEvent 埋点不能代替这个连接。

5. 如果必须人工确认,就把回传放到确认之后

Agent 提出建议后,应用先展示待确认内容。用户确认或修改后,重新校验当前表单,再回传用户决定和真实执行结果;拒绝、取消和超时也需要结束对应等待。

本地 Demo 的确认按钮只检查必填项并锁定表单。生产中的提交、持久化、等待恢复和重复执行处理由业务服务负责。更新草稿不能自动代表已经创建资源。

验证结果

操作预期结果
点击第一条推荐问题数量为 2、地域为北京、用途为集成测试,字段高亮
手动改用途,再发“把数量改成 5 台,地域改为广州”修改数量和地域,保留手动填写的用途
工具执行的两秒内将数量改为 9提示版本冲突,保留 9,该次整个修改不应用
发送“申请 200 台”显示校验失败,草稿不改变
用途为空时确认提交提示填写用途
字段有效时确认提交显示本地模拟提交成功,字段锁定;没有真实资源创建请求
写入前点击停止不执行这次草稿修改;已完成的写入不会因停止文字输出而回滚
进行中重置表单版本递增,旧结果被拒绝;刷新页面会清空内存数据

常见问题

  • 工具显示成功,表单没变:检查业务执行函数是否真的更新了草稿,以及页面是否订阅正确的表单。聊天展示不会代替业务写入。
  • 表单变了,Agent 不知道:检查是否把执行结果交回对应请求;setState、画回执和更新 metadata 都不会自动发送工具结果。
  • 总提示版本冲突:重新读取最新草稿后再发起,不重试旧补丁。本例整次拒绝,不自动合并字段冲突。
  • 换会话后写错表单:每个请求要绑定正确的会话和表单。本例固定一个会话,不演示多会话目录。
  • 刷新后数据消失:本例只在内存中。生产应恢复草稿和聊天历史,恢复显示时不能重新执行业务写入。
  • 需要动态表单或撤销:字段定义、校验、修改记录和撤销接口由业务应用提供,不属于本例的内置功能。

开发参考:不同后端如何接入

先完成上面的业务流程,再根据自己已经使用的 Agent 后端选择下面的接法。

展开:当前本地适配器的相关能力与调用时序

前端工具与 HITL 的调用闭环

查看技术调用时序大图。实线表示请求,虚线表示结果;等待是 Agent 的逻辑状态,不要求一个 HTTP 请求始终保持连接。

  • 业务后端运行完整 Agent:需要提供向浏览器发工具请求、接收执行结果、恢复任务的通道。应用按工具名称路由到允许执行的函数,并回传原请求标识。仅在聊天流中看到工具片段,不表示这些通道已经接好。
  • 直接接 OpenAI 兼容模型接口:当前 createOpenAiAdapter({ tools }) 可以按名称执行 tools[name].execute,把返回值交回对应工具调用,再请求模型继续。这只是现成实现之一;执行函数、参数校验、业务操作、鉴权和请求代理仍由业务提供。
  • 工具中等待用户确认:浏览器工具循环可以让 execute 返回等待用户操作的 Promise,再用用户决定作为结果。需要处理取消和页面关闭;刷新后仍可恢复的任务需要后端保存等待状态。
  • 使用内置追问或审批卡片:后端给出交互请求、适配器提供 respond 后可以接收用户答复。actions.respond(toolCallId, response) 会作为新的一轮发送,有一轮在运行时不受理。原请求通过 toolCallId 关联,不保证沿用原 UI runId;也不能把它当成任意表单对象的通用回传接口。

详见追问与审批、OpenAI 接入及适配器契约。

完整代码与相关参考

上方切换“代码”可以查看布局、草稿服务、适配器和样式;完整下载包含入口与项目配置。也可以进入示例工作区。

继续阅读发送前处理、业务卡片和 Hooks。