OpenAI ChatKit 组件参考
2026-11-06 16:45 更新
组件(widget)是ChatKit自带的容器与界面单元。可使用预制组件、修改模板或自行设计,定制产品中的ChatKit。

快速设计组件
在ChatKit Studio的Widget Builder尝试卡片布局、列表行与预览组件。满意后复制生成的JSON,放入集成并由后端提供。
上传素材
上传素材可让组件匹配产品风格。消息引用文件或图片前,应先由自己的后端托管上传内容。参考实现见Python SDK上传指南。
组件可以直接在对话中呈现上下文、快捷操作和交互卡片。用户点击按钮后,应用收到自定义动作载荷,由后端响应。
在服务器处理动作
组件动作可绑定到按钮点击等不同节点事件,再由服务器或客户端集成处理。使用WidgetsOption.onAction回调或对应React钩子捕获事件,将动作载荷转发给后端。
来源示例 1(javascript):
// [中文] 示例1:在服务器处理动作。
// [中文] 捕获组件动作,将动作与item.id作为JSON POST给自有/api/widget-action端点。
// [中文] 此片段未实现服务端认证、授权或载荷校验;不能把客户端传入itemId直接视为访问权限。
chatkit.setOptions({
widgets: {
async onAction(action, item) {
await fetch("/api/widget-action", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ action, itemId: item.id }),
});
},
},
});
完整服务端流程见ChatKit Python SDK文档,更多说明见动作指南。
参考
建议先从上述可视化工具入手,下面用于了解组件工作方式与全部选项。
组件以单个容器WidgetRoot为根,内部包含多个WidgetNode。
容器(WidgetRoot)
容器可显示状态指示文字和主要操作。
- Card:带边界的组件容器,支持status、confirm和cancel,用于显示状态及底部操作按钮。
children: list[WidgetNode]size: "sm" | "md" | "lg" | "full" (默认值: "md")padding: float | str | dict[str, float | str] | None (可用键:top,right,bottom,left,x,y)background: str |{ dark: str, light: str }| Nonestatus:{ text: str, favicon?: str }|{ text: str, icon?: str }| Nonecollapsed: bool | NoneasForm: bool | Noneconfirm:{ label: str, action: ActionConfig }| Nonecancel:{ label: str, action: ActionConfig }| Nonetheme: "light" | "dark" | Nonekey: str | None
- ListView:垂直项目列表;根容器的每项为ListViewItem。
children: list[ListViewItem]limit: int | "auto" | Nonestatus:{ text: str, favicon?: str }|{ text: str, icon?: str }| Nonetheme: "light" | "dark" | Nonekey: str | None
组件(WidgetNode)
支持的组件类型如下,也可在Widget Builder的组件编辑器中浏览和交互编辑。字段名称、类型与枚举保留其API写法。
- Badge:用于状态或元数据的小标签。
label: strcolor: "secondary" | "success" | "danger" | "warning" | "info" | "discovery" | Nonevariant: "solid" | "soft" | "outline" | Nonepill: bool | Nonesize: "sm" | "md" | "lg" | Nonekey: str | None
- Box:灵活布局容器,支持方向、间距与样式。
children: list[WidgetNode] | Nonedirection: "row" | "column" | Nonealign: "start" | "center" | "end" | "baseline" | "stretch" | Nonejustify: "start" | "center" | "end" | "stretch" | "between" | "around" | "evenly" | Nonewrap: "nowrap" | "wrap" | "wrap-reverse" | Noneflex: int | str | Noneheight: float | str | Nonewidth: float | str | NoneminHeight: int | str | NoneminWidth: int | str | NonemaxHeight: int | str | NonemaxWidth: int | str | Nonesize: float | str | NoneminSize: int | str | NonemaxSize: int | str | Nonegap: int | str | Nonepadding: float | str | dict[str, float | str] | None (可用键:top,right,bottom,left,x,y)margin: float | str | dict[str, float | str] | None (可用键:top,right,bottom,left,x,y)border: int |dict[str, Any]| None- 单一边框:
{ size: int, color?: str | { dark: str, light: str }, style?: "solid" | "dashed" | "dotted" | "double" | "groove" | "ridge" | "inset" | "outset" } - 逐边配置:
{ top?: int|dict, right?: int|dict, bottom?: int|dict, left?: int|dict, x?: int|dict, y?: int|dict } radius: "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "full" | "100%" | "none" | Nonebackground: str |{ dark: str, light: str }| NoneaspectRatio: float | str | Nonekey: str | None
- Row:横向排列子节点。
children: list[WidgetNode] | Nonegap: int | str | Nonepadding: float | str | dict[str, float | str] | None (可用键:top,right,bottom,left,x,y)align: "start" | "center" | "end" | "baseline" | "stretch" | Nonejustify: "start" | "center" | "end" | "stretch" | "between" | "around" | "evenly" | Noneflex: int | str | Noneheight: float | str | Nonewidth: float | str | NoneminHeight: int | str | NoneminWidth: int | str | NonemaxHeight: int | str | NonemaxWidth: int | str | Nonesize: float | str | NoneminSize: int | str | NonemaxSize: int | str | Nonemargin: float | str | dict[str, float | str] | None (可用键:top,right,bottom,left,x,y)border: int | dict[str, Any] | None- 单一边框:
{ size: int, color?: str | { dark: str, light: str }, style?: "solid" | "dashed" | "dotted" | "double" | "groove" | "ridge" | "inset" | "outset" } - 逐边配置:
{ top?: int|dict, right?: int|dict, bottom?: int|dict, left?: int|dict, x?: int|dict, y?: int|dict } radius: "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "full" | "100%" | "none" | Nonebackground: str |{ dark: str, light: str }| NoneaspectRatio: float | str | Nonekey: str | None
- Col:纵向排列子节点。
children: list[WidgetNode] | Nonegap: int | str | Nonepadding: float | str | dict[str, float | str] | None (可用键:top,right,bottom,left,x,y)align: "start" | "center" | "end" | "baseline" | "stretch" | Nonejustify: "start" | "center" | "end" | "stretch" | "between" | "around" | "evenly" | Nonewrap: "nowrap" | "wrap" | "wrap-reverse" | Noneflex: int | str | Noneheight: float | str | Nonewidth: float | str | NoneminHeight: int | str | NoneminWidth: int | str | NonemaxHeight: int | str | NonemaxWidth: int | str | Nonesize: float | str | NoneminSize: int | str | NonemaxSize: int | str | Nonemargin: float | str | dict[str, float | str] | None (可用键:top,right,bottom,left,x,y)border: int | dict[str, Any] | None- 单一边框:
{ size: int, color?: str | { dark: str, light: str }, style?: "solid" | "dashed" | "dotted" | "double" | "groove" | "ridge" | "inset" | "outset" } - 逐边配置:
{ top?: int|dict, right?: int|dict, bottom?: int|dict, left?: int|dict, x?: int|dict, y?: int|dict } radius: "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "full" | "100%" | "none" | Nonebackground: str |{ dark: str, light: str }| NoneaspectRatio: float | str | Nonekey: str | None
- Button:可灵活配置的动作按钮。
submit: bool | Nonestyle: "primary" | "secondary" | Nonelabel: stronClickAction: ActionConfigiconStart: str | NoneiconEnd: str | Nonecolor: "primary" | "secondary" | "info" | "discovery" | "success" | "caution" | "warning" | "danger" | Nonevariant: "solid" | "soft" | "outline" | "ghost" | Nonesize: "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | Nonepill: bool | Noneblock: bool | Noneuniform: bool | NoneiconSize: "sm" | "md" | "lg" | "xl" | "2xl" | Nonekey: str | None
- Caption:较小的辅助文字。
value: strsize: "sm" | "md" | "lg" | Noneweight: "normal" | "medium" | "semibold" | "bold" | NonetextAlign: "start" | "center" | "end" | Nonecolor: str |{ dark: str, light: str }| Nonetruncate: bool | NonemaxLines: int | Nonekey: str | None
- DatePicker:带下拉日历的日期输入。
onChangeAction: ActionConfig | Nonename: strmin: datetime | Nonemax: datetime | Noneside: "top" | "bottom" | "left" | "right" | Nonealign: "start" | "center" | "end" | Noneplaceholder: str | NonedefaultValue: datetime | Nonevariant: "solid" | "soft" | "outline" | "ghost" | Nonesize: "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | Nonepill: bool | Noneblock: bool | Noneclearable: bool | Nonedisabled: bool | Nonekey: str | None
- Divider:横向或纵向分隔线。
spacing: int | str | Nonecolor: str |{ dark: str, light: str }| Nonesize: int | str | Noneflush: bool | Nonekey: str | None
- Icon:按名称显示图标。
name: strcolor: str |{ dark: str, light: str }| Nonesize: "xs" | "sm" | "md" | "lg" | "xl" | Nonekey: str | None
- Image:显示图像,可配置样式、适配方式与位置。
size: int | str | Noneheight: int | str | Nonewidth: int | str | NoneminHeight: int | str | NoneminWidth: int | str | NonemaxHeight: int | str | NonemaxWidth: int | str | NoneminSize: int | str | NonemaxSize: int | str | Noneradius: "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "full" | "100%" | "none" | Nonebackground: str |{ dark: str, light: str }| Nonemargin: int | str | dict[str, int | str] | None (可用键:top,right,bottom,left,x,y)aspectRatio: float | str | Noneflex: int | str | Nonesrc: stralt: str | Nonefit: "none" | "cover" | "contain" | "fill" | "scale-down" | Noneposition: "center" | "top" | "bottom" | "left" | "right" | "top left" | "top right" | "bottom left" | "bottom right" | Noneframe: bool | Noneflush: bool | Nonekey: str | None
- ListView:垂直项目列表;根容器的每项为ListViewItem。
children: list[ListViewItem] | Nonelimit: int | "auto" | Nonestatus: dict[str, Any] | None (结构:{ text: str, favicon?: str })theme: "light" | "dark" | Nonekey: str | None
- ListViewItem:ListView中的项目,可带操作。
children: list[WidgetNode] | NoneonClickAction: ActionConfig | Nonegap: int | str | Nonealign: "start" | "center" | "end" | "baseline" | "stretch" | Nonekey: str | None
- Markdown:渲染Markdown文字,支持流式更新。
value: strstreaming: bool | Nonekey: str | None
- Select:下拉单选输入。
options: list[dict[str, str]] (每个选项:{ label: str, value: str })onChangeAction: ActionConfig | Nonename: strplaceholder: str | NonedefaultValue: str | Nonevariant: "solid" | "soft" | "outline" | "ghost" | Nonesize: "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | Nonepill: bool | Noneblock: bool | Noneclearable: bool | Nonedisabled: bool | Nonekey: str | None
- Spacer:布局中的弹性空白。
minSize: int | str | Nonekey: str | None
- Text:显示纯文本;Markdown内容使用Markdown组件,支持流式更新。
value: strcolor: str |{ dark: str, light: str }| Nonewidth: float | str | Nonesize: "xs" | "sm" | "md" | "lg" | "xl" | Noneweight: "normal" | "medium" | "semibold" | "bold" | NonetextAlign: "start" | "center" | "end" | Noneitalic: bool | NonelineThrough: bool | Nonetruncate: bool | NoneminLines: int | NonemaxLines: int | Nonestreaming: bool | Noneeditable: bool | dict[str, Any] | None (为字典时:{ name: str, autoComplete?: str, autoFocus?: bool, autoSelect?: bool, allowAutofillExtensions?: bool, required?: bool, placeholder?: str, pattern?: str })key: str | None
- Title:突出的标题文字。
value: strsize: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | Noneweight: "normal" | "medium" | "semibold" | "bold" | NonetextAlign: "start" | "center" | "end" | Nonecolor: str |{ dark: str, light: str }| Nonetruncate: bool | NonemaxLines: int | Nonekey: str | None
- Form:能够提交动作的布局容器。
onSubmitAction: ActionConfigchildren: list[WidgetNode] | Nonealign: "start" | "center" | "end" | "baseline" | "stretch" | Nonejustify: "start" | "center" | "end" | "stretch" | "between" | "around" | "evenly" | Noneflex: int | str | Nonegap: int | str | Noneheight: float | str | Nonewidth: float | str | NoneminHeight: int | str | NoneminWidth: int | str | NonemaxHeight: int | str | NonemaxWidth: int | str | Nonesize: float | str | NoneminSize: int | str | NonemaxSize: int | str | Nonepadding: float | str | dict[str, float | str] | None (可用键:top,right,bottom,left,x,y)margin: float | str | dict[str, float | str] | None (可用键:top,right,bottom,left,x,y)border: int | dict[str, Any] | None- 单一边框:
{ size: int, color?: str | { dark: str, light: str }, style?: "solid" | "dashed" | "dotted" | "double" | "groove" | "ridge" | "inset" | "outset" } - 逐边配置:
{ top?: int|dict, right?: int|dict, bottom?: int|dict, left?: int|dict, x?: int|dict, y?: int|dict } radius: "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "full" | "100%" | "none" | Nonebackground: str |{ dark: str, light: str }| Nonekey: str | None
- Transition:包裹可能带动画的内容。
children: WidgetNode | Nonekey: str | None
以上内容是否对您有帮助:

TRAE-AI编程


更多建议: