跳到主要内容

信息收集卡片 (Info Collection)

当 Agent 需要知道访客是谁——公司、职位、联系方式——它会在对话里放出一张填空卡片;SDK 负责把这张卡片渲染出来,并把用户填的内容回传给平台写进联系人档案。 你不用自己设计表单、不用管字段校验与落库,卡片什么时候出现由 Agent 判断。

前提:Agent 的所有者需先在「联系人」里配置好要收集的字段。字段的名称、类型、是否必填都在那里定义,SDK 侧不需要重复声明。

收集是怎么发生的

  1. 你像平常一样用 SDK 发消息(见 对话 (Chat))。
  2. Agent 判断当前访客缺少某些已配置的字段时,平台向对话流里推一条 info_collection 事件,里面带着这张卡片的数据(标题、说明、待填字段列表)。
  3. 你把卡片渲染给用户,用户填完点提交。
  4. 提交的内容以 info_collection_submit 回传,平台写入该访客的联系人记录;用户选择「稍后填写」则回传 info_collection_skip,只记录这个行为、不写任何字段。

卡片只会问当前缺失的字段。已经填过的不会重复问——判断在平台侧完成,你不需要自己比对。

卡片的数据结构

info_collection 事件里的 InfoCollectPayload

字段类型说明
fieldsInfoCollectField[]待填字段列表
cardTitlestring?卡片标题,如「完善信息,让 Agent 更好地了解你」
cardDescriptionstring?标题下的一句说明,交代为什么要收集

每个 InfoCollectField

字段类型说明
keystring字段标识,回传时作为 key
labelstring展示给用户的中文名,如「公司」
typestring?控件类型,缺省为 text
requiredboolean?是否必填
placeholderstring?输入框占位提示
optionsstring[]?select 的候选项

type 与控件的对应关系:

type渲染为
text单行输入框
email输入框,唤起邮箱键盘并做格式校验
phone输入框,唤起电话键盘
select下拉框,选项取自 options
textarea多行输入框

select 若没有配 options,会降级成文本输入框而不是渲染一个选不了的空下拉框;未知的 type 同样降级为文本框。这样即使字段配置有疏漏,用户也总能作答。

在原生 JS / TS 里处理

用事件工具从流里识别卡片:

import { OpenhexClient, extractInfoCollect, isInfoCollect } from '@openhex-ai/agent-sdk';

const client = new OpenhexClient({ apiKey, agentId });

for await (const record of client.runTurn('我想了解你们的服务')) {
const card = extractInfoCollect(record);
if (card) {
renderForm(card); // 你的渲染:遍历 card.fields
}
}

用户填完后,把结果作为工具动作回传:

import { infoCollectSubmitMetadata, infoCollectSkipMetadata } from '@openhex-ai/agent-sdk';

// 提交
await client.chat.send({
conversationId,
message: '',
toolAction: true,
metadata: infoCollectSubmitMetadata({ company: '蓝色光标', role: '运营总监' }),
});

// 或者稍后填写
await client.chat.send({
conversationId,
message: '',
toolAction: true,
metadata: infoCollectSkipMetadata(),
});

也可以用 isInfoCollect(record) 只做布尔判断。

在 React 里处理

React 集成把这套都封装好了:卡片自动挂到对应消息上,<ChatBox> / <ChatWidget> 直接渲染,提交与跳过也已接好。

import { ChatBox } from '@openhex-ai/agent-sdk/react';

export function SupportChat({ token }: { token: string }) {
return <ChatBox agentId="ce9382ad-…" token={token} />;
}

不需要任何额外配置——平台推卡片时它自己出现。

自定义文案

卡片上所有面向用户的文字都可以覆盖。默认是中文,与平台自有界面一致:

<ChatBox
agentId="ce9382ad-…"
token={token}
infoCollectLabels={{
title: '请补充以下信息',
submit: '提交',
skip: '稍后填写',
submitted: '信息已收到,感谢填写',
skipped: '已跳过,稍后可在对话中补充',
optional: '选填',
selectPlaceholder: '请选择',
}}
/>

自己渲染转录

如果你用 useOpenhexChat 自己画对话界面,卡片会以 infoCollect 挂在消息上。可以直接用内置卡片组件,也可以基于载荷自己实现:

import { InfoCollectCard, useInjectStyles, useOpenhexChat } from '@openhex-ai/agent-sdk/react';

function Transcript({ token }: { token: string }) {
useInjectStyles(true); // 页面上没有 ChatBox 时必须调用,否则卡片没有样式
const { messages, submitInfoCollect, skipInfoCollect } = useOpenhexChat({
agentId: 'ce9382ad-…',
token,
});

return (
<>
{messages.map(m =>
m.infoCollect ? (
<InfoCollectCard
key={m.id}
payload={m.infoCollect}
onSubmit={submitInfoCollect}
onSkip={skipInfoCollect}
/>
) : (
<MyBubble key={m.id} message={m} />
)
)}
</>
);
}

⚠️ onSubmit / onSkip 必须如实反映发送结果。 只有返回的 Promise resolve,卡片才会翻成完成态;reject 时保持可编辑,让用户能重试。发送失败却显示「已收到」,用户会以为信息存下了。

让卡片和网页端长得一样

SDK 的默认配色刻意保持中性——它嵌入的是你自己的站点,套用我们的品牌色未必合适。卡片的版式(圆角、内边距、最大宽度、纵向间距)默认就与网页端一致,差异只在配色。

想让嵌入效果与 OpenHex 网页端完全一致,套用内置预设:

import { ChatBox, PLATFORM_TOKENS } from '@openhex-ai/agent-sdk/react';

<ChatBox agentId="ce9382ad-…" token={token} tokens={PLATFORM_TOKENS} />;

tokens 开放的是全部设计变量,可以在预设基础上只改一项,也可以完全按自己的品牌来:

<ChatBox tokens={{ ...PLATFORM_TOKENS, accent: '#0f766e' }} />
<ChatBox tokens={{ bg: '#fff', fg: '#1a1a1a', border: 'rgba(0,0,0,0.08)' }} />

自己画转录时用 tokenStyle(),把变量设在任意外层元素上,内部卡片会继承:

import { tokenStyle, PLATFORM_TOKENS, InfoCollectCard } from '@openhex-ai/agent-sdk/react';

<div style={tokenStyle(PLATFORM_TOKENS)}>
<InfoCollectCard payload={payload} onSubmit={onSubmit} onSkip={onSkip} />
</div>;

字体是个例外:网页端用的中英文字体是站点自身加载的,嵌入方引用不到。预设里给的是同一套回退字体,字形可能仍有细微差别。需要完全一致的话,自行加载那两款字体并排在前面即可。

下一步