什么是 Action?

Widget 不仅用于信息展示,同时也支持用户的交互行为。

Action 用于描述当用户在 Widget 中完成某项交互操作(例如点击、选择、填写表单)后,系统应执行的具体行为。通过 Action,Widget 能够将用户操作结果及相关数据返回给智能体,触发后续流程。在 Widget 中,onClickAction、onSubmitAction 和 onChangeAction 均属于 Action 类型。

Widget 是否支持交互取决于是否包含支持 Action 配置的组件,您可以通过组件属性的配置声明对应的 Action 的类型及参数。Action 通常包含以下两个核心字段:

字段 类型 描述
type "sys.chat" | "sys.go_to_url" | "sys.download" 用于定义用户交互后执行的具体行为类型。
payload object 提供指定 Action 类型所需的数据内容。

注意:

不支持在 Widget 模板(Template)中直接编写 Action 的具体实现逻辑。支持声明 Action 的 type 和 payload,当前仅支持使用官方预置的 Action 类型,暂不支持自定义。

官方预置 Action

ADP 官方提供了三种预置 Action 类型,可直接用于 Widget 交互配置。

sys.chat

定义

type: "sys.chat"

功能说明

sys.chat 用于向智能体发送一条对话消息,当用户在 Widget 中触发该 Action 时,系统会将指定内容作为新的用户输入进入当前对话的上下文,参与后续的推理、判断与流程决策。

适用场景

适用于信息收集、补充说明等需要 Agent 感知并继续决策的交互流程。

示例说明

Template 示例:

用户单击重新选择 Button 后,向 Agent 发送“重新选择方案”的对话信息。

<Button   
    label="重新选择"  
     onClickAction={{     
     type: "sys.chat",    
     payload: { query: "重新选择方案" }   }} /> 

代码说明:

  • type 指定为 sys.chat,表示触发对话输入。

  • payload 用于提供 Agent 可理解的文本内容,即直接发送的对话消息。

注意:

  • payload 字段名称支持自定义,可以根据具体场景设置字段名和对应值。
  • 在此示例中,query 是自定义字段,表示用户的操作或选择。

sys.go_to_url

定义

type: "sys.go_to_url"

功能说明

sys.go_to_url 支持触发页面跳转,由前端直接执行。该 Action 不经过模型推理,也不会写入对话上下文。

适用场景

适用于跳转到详情页、打开外部链接等不需要智能体感知用户意图或参与决策的操作。

示例说明

用户单击查看详情 Button 后,执行页面跳转到目标网址。

Template 示例:

<Button   
label="查看详情"   
onClickAction={{     
    type: "sys.go_to_url",     
    payload: {url: "https://adp.tencent.com/"}   }} 
/> 

代码说明:

  • type 为 sys.go_to_url,表示执行页面跳转行为。

  • payload 用于指定目标地址,支持通过变量进行动态配置。

  • 跳转行为由前端直接完成,不影响当前对话与 Agent 状态。

注意:

sys.go_to_url 对应的 payload 必须严格为 url,不支持自定义其他字段。

如果您需要传递其他参数,考虑使用 sys.chat 代替。

sys.download

定义

type: "sys.download"

功能说明

sys.download 用于触发文件下载行为,当用户在 Widget 中触发该 Action 时,系统会根据配置的 URL 地址发起文件下载。该 Action 不经过模型推理,也不会写入对话上下文。

适用场景

适用于向用户提供结果文件下载的场景,例如下载图片、音频、文档等生成内容。

示例说明

用户单击下载图片 Button 后,将下载指定地址对应的文件。

Template 示例:

<Button
  label="下载图片"
  onClickAction={{
    type: 'sys.download',
    payload: {
      url: 'https://cdn.xiaowei.qq.com/static/adp/app-default-avatar.png',
    },
  }}
  style="primary"
  block
/>

代码说明:

  • type 为 sys.download,表示触发文件下载行为。

  • payload 用于指定待下载文件的资源地址(url)。

  • 下载行为由前端直接完成,不影响当前对话与 Agent 状态。

注意:

sys.download 对应的 payload 中的 url 为必填字段,用于指定下载资源地址,否则无法进行文件下载;filename字段为选填字段,用于自定义下载文件名,若未配置,系统将默认使用 URL 路径中最后一级内容作为文件名。

其他类型的 Action 目前暂未支持,后续将支持自定义。

当引用 Widget 时,如果该 Widget 配置了 Action,在 Multi-Agent 模式中,相关配置会自动回显到 Widget 设置和预览页;在工作流画布中,相关配置会自动回显到 Widget 节点详情页。对于平台暂不支持配置的交互操作,操作栏内容将以红色高亮提示。

Multi-Agent 模式正确配置 Action 的回显 Multi-Agent 模式错误配置 Action 的回显
Multi-Agent 模式正确配置 Action 的回显 Multi-Agent 模式错误配置 Action 的回显
Widget 节点详情正确配置 Action 的回显 Widget 节点详情错误配置 Action 的回显
Widget 节点详情正确配置 Action 的回显 Widget 节点详情错误配置 Action 的回显

Action 的执行流程

完整的 Action 触发流程如下:

  1. 用户在 Widget 中执行交互操作:例如点击按钮、提交选择或填写表单。

  2. 前端触发 Action 回调:前端根据组件中配置的 Action,将对应的 type 与 payload 发送至系统进行处理。

  3. 系统根据 Action 类型执行对应行为:

  • sys.go_to_url:由前端直接执行页面跳转至指定地址。

  • sys.chat:将 payload 中的内容作为新的对话输入,提交给智能体,继续参与后续推理与流程决策。

  • sys.download:根据 payload 中配置的资源地址进行文件下载。

支持 Action 的组件

以下组件支持在配置中声明 Action。

Component Action 属性 说明
Button onClickAction 点击触发
Form onSubmitAction 表单提交
DatePicker onChangeAction 日期变化
Select 选择变化
Checkbox 勾选变化
RadioGroup 单选变化

说明:

超链接可直接在 中使用,无需额外定义 Action:

<Markdown value={"点击 [这里](https://example.com) 查看更多"} />

表单类 Widget 参数提交机制

信息收集类组件

以下组件可以采集用户输入,并在 Action 触发时输出字段:

  • Input

  • Textarea

  • Select

  • Checkbox

  • RadioGroup

  • DatePicker

    上述组件需要配置name字段,用于标识提交参数的字段名。

Widget 提交参数

Widget 在 Action 触发后,向后端发送完整的参数集合,包括:

  1. Action 中声明的 payload。

  2. 表单中所有信息收集组件的用户输入值。

    提交规则:

  • 点击 / 选择类 Action(onClickAction):仅提交 Action 中声明的 payload,不会自动收集表单字段。

  • 表单提交(onSubmitAction):自动合并表单内所有信息收集组件并以各组件的name作为字段名提交对应值。

Widget 示例

Template 示例:

<Card size="sm">
  <Form
    onSubmitAction={{
      type: 'sys.chat',
      payload: { result: 'submit' },
    }}
  >
    <Col gap={3}>
      <Title value="医院与科室信息收集表" size="sm" />
      <Col gap={3}>
        <Col gap={2}>
          <Label value="医院名称" />
          <Input name="hospital" placeholder="请输入医院名称"  />
        </Col>
        <Col gap={2}>
          <Label value="科室" />
          <Input name="department" placeholder="请输入科室名称" />
        </Col>
      </Col>
      <Row>
        <Spacer />
        <Button submit label="确定" style="primary" />
        <Button
          label="取消"
          variant="outline"
          onClickAction={{
            type: 'sys.chat',
            payload: { query: '取消填写' },
          }}
        />
      </Row>
    </Col>
  </Form>
</Card>

效果展示如下:

当用户在输入框中填写:

  • 医院名称:北京301医院。

  • 科室名称:心内科。

    单击确定后,最终发送给智能体的 payload 内容为:

    {
      "result": "submit",
      "hospital": "北京301医院",
      "department": "心内科"
    }
    

常见问题

为什么我在 Widget 里进行了交互操作,但智能体没有拿到结果?

通常可以从两个方面进行排查:

一是确认是否真正触发了 Action。只有当用户在组件上完成了明确的交互操作(如点击按钮、提交表单),且该组件配置了可触发的 Action(如 onClickAction、onSubmitAction),交互结果才会被发送给智能体;如果 Widget 仅用于内容展示,或只包含输入组件但没有对应的提交动作,智能体是无法感知用户操作的。

二是确认是否使用了正确的 Action 类型。在当前支持的 Action 中,sys.go_to_url 仅用于页面跳转,不会向智能体传递任何数据,而 sys.chat 会将 payload 作为新的用户输入写入对话上下文,供智能体继续推理与决策。因此,只要希望智能体“看到”并处理用户的操作结果,就必须使用 sys.chat

表单里的 Input 已填写,为什么提交后仍然拿不到对应的值?

这种情况通常由两个原因导致:

其一,Input 未配置 name 字段,没有 name 的输入项不会参与参数提交,例如以下示例中,缺少 name 字段,用户即便填写了内容,也无法提交给智能体。

错误示例(缺少name字段,不会提交):

<Form
  onSubmitAction={{
    type: 'sys.chat',
    payload: { type: 'submit_form' },
  }}
>
  <Input placeholder="医院名称" />
  <Button submit label="提交" />
</Form>

其二,输入组件未通过 Form 表单组件进行提交。Input、Select 等信息收集组件本身不会主动提交数据,必须包裹在 Form 表单组件中,并通过 onSubmitAction 触发表单提交,才能将用户填写的内容统一发送出去。

因此,表单类 Widget 必须满足以下条件:输入组件配置了 name 字段、组件被包裹在 Form 表单组件中,并且通过 onSubmitAction 触发提交。符合规范的示例如下:

<Form
  onSubmitAction={{
    type: 'sys.chat',
    payload: { type: 'submit_form' },
  }}
>
  <Input
    name="hospital_name"
    placeholder="医院名称"
    required
  />

  <Button submit label="提交" style="primary" />
</Form>

或者使用具备表单语义的容器组件:

<Card
  as="form"
  onSubmitAction={{
    type: 'sys.chat',
    payload: { type: 'submit_form' },
  }}
>
  <Input
    name="hospital_name"
    placeholder="医院名称"
    required
  />

  <Button submit label="提交" />
</Card>

如何在 Widget 中实现预填内容,并支持用户修改内容并返回智能体?

在许多交互场景中,Agent 会先向用户展示一个表单或预填信息,用户在此基础上进行修改并提交,希望将修改后的内容重新传回 Agent,用于后续推理或流程决策。这类交互在用户提交个人信息、选择方案或确认内容时尤为常见。

Widget 能够支持这类交互:智能体生成的初始结果可作为 defaultValue 预填到输入组件中,用户修改后,通过 Action 将用户修改后的内容传回智能体。其中 defaultValue 仅用于初始内容展示,作为用户修改的起点,不会直接返回给智能体,真正参与后续推理的内容是用户在输入组件中修改并提交的最终值。

以播客内容生成表单为例,具体流程为:智能体生成 initialObjectinitialScript 的初始默认值作为播客主题及文案的初稿,并通过 defaultValue 预填到输入框中,用户修改后提交表单,智能体最终接收的值是用户确认修改后的播客主题及文案,而非初始默认值。总之,defaultValue 只是展示给用户的初稿,智能体始终接收并处理用户提交的最终结果。

Template 示例:

<Form
  onSubmitAction={{
    type: 'sys.chat',
    payload: { type: 'submit_form' },
  }}
>
  <Title value="播客内容生成" size="sm" />
  <Label value="播客主题" />
  <Input name="object" defaultValue={initialObject} />
  <Label value="播客文案" />
  <Textarea
    name="script"
    defaultValue={initialScript}
    rows={10}
    autoResize
    required
  />
  <Row>
    <Spacer />
    <Button submit label="提交" style="primary" />
  </Row>
</Form>

效果展示:

该播客内容生成表单中的播客主题和播客文案已经通过 defaultValue 预填到输入框,用户可以直接修改并提交,最终内容会传回智能体进行后续处理。

下载按钮希望用户可以反复点击,应该怎么配置?

onClickAction 中将 alwaysEnabled 设置为true,即可允许 Button 多次点击;否则按钮默认只可点击一次并会自动禁用,详情可见 Button 按钮

注意:

该配置适用于下载(sys.download)、跳转(sys.go_to_url)等可重复执行的操作,不建议用于sys.chat类型的 Action,以避免重复触发对话请求。

例如:

<Button
  label="下载图片"
  onClickAction={{
    type: 'sys.download',
    alwaysEnabled: true,
    payload: {
      url: 'https://cdn.xiaowei.qq.com/static/adp/app-default-avatar.png',
    },
  }}
/>