AI 分身消息卡片
该教程文档说明,适用于 AI 分身流式对话中使用卡片样式与用户进行交互的场景。
说明
如果用户所使用的抖音客户端版本过低,分身卡片可能会无法渲染。
Android 版本需要 32.1.0 及以上,iOS 版本需要 32.8.0 及以上。
使用限制
- •该能力需要开发者提前进行卡片的创编,详见以下卡片创编接口。
卡片名称 | API | 描述 |
小程序卡片 | ||
查询小程序卡片模板 | ||
删除小程序卡片模板 | ||
上传图片得到的 media_id 用于创建/更新小程序卡片模板 | ||
自定义用户信息收集卡 | 当系统提供的公共组件(姓名、城市、手机号)不能满足收集诉求时,可调用此接口创建满足诉求的交互组件,目前支持单行/多行文本输入框,滚轮/级联/分项选择器(选择器组件审核通过后才可使用) | |
查询对话卡片交互组件 | ||
删除对话卡片交互组件 | ||
创建自定义用户信息收集卡模板,components 可选系统提供的公共组件和开发者自行创建的卡片交互组件 | ||
查询自定义用户信息收集卡模板 | ||
删除自定义用户信息收集卡模板 | ||
查询用户已提交的信息,返回值是一个 KV 对的 json 串。其中,key 表示交互组件的 input_key,value 表示用户真实提交的值,例如:{"name":"test","phone_num":"123456"} |
- •若开发者需要使用 AI 分身消息卡片能力(小程序卡片、自定义用户信息收集卡),需提供分身应用 AppID 至对接运营同学加白,平台加白后即可开始对接。
- •当前开放用户范围:所有接入开放平台的 AI 分身应用。
使用场景
- 1.该能力需要在分身服务的流式对话接口中使用。
- 2.在需 要出卡的场景下,在流式对话的返回 chunk 包中,需要设置回包的
content.type = 2
,content.content
则为指定卡片协议的 JSON 字符串,具体对应的卡片样式和协议在文档后方。- 3.代码中使用的卡片需要经过前期卡片的创编,并通过卡片信息查询接口获取卡片id进行使用。
- 4.当业务判断需要出卡的时候,卡片消息需要是一个独立的 seg,所以上一条消息的
seg_finish
需要先设置为true
,卡片消息自身的 seg_finish
也需要设置为 true
。例如,其中一个 chunk 的协议如下:
{ "data": { "content": { "type": 2, // 枚举值,参考content.type,0-纯文本;2-卡片; "content": "{\"msg_type\": 10,\"applet_card\":{\"card_template_id\": \"@4F9T1avCDMhjO3LyYo04GKep1GeGPPuGOZF2nD+TGmSw1Z\",\"app_id\":\"tt3ergjdge84gdwksb\", \"path\":\"api/apiPage/apiPage\", \"query\":\"{\\\"text\\\":\\\"nihao\\\"}\"}}", // 卡片协议的字符串 "role": 0, // 枚举值,参考content.role; 1-system, 2-user, 3-role "seg_finish": true, // 当前分段是否回答完成;针对每个seg,客户端会分开展示 "seg_type": 0, // 参考枚举值:seg_type }, "trace_info": { "trace_info": "4038savAxJ" // 仅在debug场景使用的调试信息,可选填充 } }, "err_no": 0, "err_msg": "success", "log_id": "xxxxxxxxxxxx" }
代码样例:
// 定义一个总的IM卡片类 @NoArgsConstructor @AllArgsConstructor @Data @JsonInclude(JsonInclude.Include.NON_NULL) public class ImContentCard { @JsonProperty("msg_type") private Integer msgType; @JsonProperty("applet_card") private MicroAppCard microAppCard; @JsonProperty("retain_information_card") private RetainInformationCard retainInformationCard; }
// 创建卡片类数据 public String CreateCardData() { ImContentCard imContentCard = new ImContentCard(); imContentCard.setMsgType(203); RetainInformationCard retainInformationCard = new RetainInformationCard(); retainInformationCard.setCardId("140795904442423414"); imContentCard.setRetainInformationCard(retainInformationCard); String dataString = JSON.toJSONString(imContentCard); return dataString } public void SendCardData(String cardData, HttpServletResponse resp) { //组装卡片的信息 ChatStreamResponseDTO chatStreamResponseDTO = new ChatStreamResponseDTO(); chatStreamResponseDTO.setStreamFinish(false); chatStreamResponseDTO.setBaseResp(new BaseResp()); CopilotContent copilotContent = new CopilotContent(); copilotContent.setSegType(SegTypeEnum.ANSWER); copilotContent.setContent(cardData); copilotContent.setRoleEnum(RoleEnum.Assistant); copilotContent.setSegFinish(true); copilotContent.setContentType(ContentTypeEnum.CARD); chatStreamResponseDTO.setCopilotContent(copilotContent); try { // 发送卡片 this.chunkSendWriter.Send(resp, HttpResponse.SuccessResponse(chatStreamResponseDTO)); } catch (Exception e) { logger.error("[SendCardData] happen Exception, err={}", e.getMessage(), e); } }
场景一:小程序引导卡
卡片样式
接入协议
"content": { "msg_type": 10, // 固定msg_type=10 "applet_card": { // 可通过卡片查询信息接口获取卡片id进行使用 "card_template_id": "@9VwNxuKKBZ03MXG7M8ooWM771FjUAMW/BqhMlDebEmyyzJD7cZENrR868oDbX9xx", "path": "api/apiPage/apiPage", "query": "{\"key1\":\"val1\",\"key2\":\"val2\"}", "app_id": "tt3ergjdge84gdwksb" } }
场景二:用户信息采集卡
卡片样式
接入协议
"content": { "msg_type": 203, // 固定msg_type=203 "retain_information_card": { // 通过卡片查询信息接口获取卡片id进行使用 "card_id": "102432325325", // 用户信息采集卡预填充功能,仅支持预填充单行/多行文本输入框 // "_key"为组件的input_key,"_value"为预填充的值 "prefill": {"_key": "_value", ...} } }
特殊说明
用户信息获取说明
实时获取:
用户提交的信息,会作为流式对话接口的一个 query 请求,开发者收到数据请求之后,代码需要根据业务逻辑做后续的 response 处理。response 作为一条回复内容,对用户反馈已收到其信息,针对用户个性化诉求给出回应。
(请注意 message.content.type, message.content.content),另外具体是哪个用户提交的信息,可以在 common_context.user_info.open_id 获取到用户的 openId。
离线获取:
{ "message": { "conversation_id": "xb17Mth7hy", // 当前会话ID,上游自动传入,不需要关注 "message_id": "hIPrroEYEF", // 用户输入query的message_id;上游自动传入,不需要关注 "role": 1, // 枚举值content.role system=1,user=2, assistant=3; "content": { "type": 2, // 枚举值content.type 0表示纯文本;2表示卡片,这里的2就代表是用户提交卡片的信息回传。 "content": "{\"name\": \"xxxxx\", \"address\": \"xxxxxx\"}" // 这里的信息就是创编卡片对应的卡片key,以及用户提交的个人信息。 } }, "chat_context": { "message_context": [ // 用户和分身的历史聊天,按照时间顺序传入,最大20轮 { "conversation_id": "y5Zu76IcCk", // 消息所属会话ID,上游自动传入,不需要关注 "message_id": "zPONEU9W4m", // 消息的message_id;上游自动传入,不需要关注 "role": 2, // 枚举值content.role system=1, user=2, assistant=3; "content": { "type": 0, "content": "S1klHSsHmy" }, "created_at": 4904873903809125974 } ] }, "reply_message_id": "fG3yPCUzB7", // 本次请求的回答的message_id,上游自动传入,不需要关注 "biz_context": { "biz_id": "bYPxF7HEAM" // 场景枚举值,可根据此标记,定制分身的差异化逻辑 }, // format、私信、ai搜、官方号 "common_context": { "user_info": { "open_id": "4106557274961385626", // C端发起对话的抖音用户的ID,上游自动传入,不需要关注 }, "avatar_info": { "avatar_app_id": "2186328463960574138" // 分身的开平app_id }, "traffic_source": { // 场景流量来源标记,上游自动传入,下游调用原子能力时,可能需要透传;开发者不关注具体值 "source": "nIpNzvSZY7", "enter_from": "RiPRNnnGTC", "traffic_type": "0spfr3Ravm" } } }