AI 回复
用户和 AI 机器人单聊时,机器人的回复是一条 type 为 ai 的消息,内容边生成边推送过来。UniApp SDK 的 client.ai 与 Web SDK 相同:按顺序拼接实时内容、断线后续传、重新上线时补发,回复结束后以消息正文为准。接口、字段和事件的完整说明见 Web SDK 的 AI 回复,本页说明在 uni-app 页面中如何显示。机器人和回复由你的服务端创建,见 AI 对话。
版本
AI 回复从 @deeprespond/im-uniapp@1.0.6 起提供(依赖 @deeprespond/im-web@1.0.6),安装见接入与下载。
整理成视图
小程序和 App 端不能直接渲染 Markdown。@deeprespond/im-web/render(随 @deeprespond/im-uniapp 安装)的 aiView(message, live) 把一条 AI 消息整理成模板可以直接使用的视图,正文转成 rich-text 的节点数组(只生成节点,不生成 HTML 字符串;链接只保留文字)。视图的字段见小程序 SDK 的 AI 回复。
vue
<template>
<view class="ai-msg" :data-status="view.status">
<text v-if="view.reasoning">{{ view.thinking ? '思考中…' : '已深度思考' }}</text>
<text v-for="tool in view.tools" :key="tool.id">{{ tool.title }}({{ tool.state }})</text>
<view v-for="(block, index) in view.blocks" :key="index">
<view v-if="block.kind === 'text'">
<rich-text :nodes="block.nodes" selectable />
<text v-if="view.streaming && block.last">▍</text>
</view>
<image v-else-if="block.kind === 'image'" :src="block.url" mode="widthFix" />
<text v-else-if="block.kind === 'file'">{{ block.name }} {{ block.size }}</text>
</view>
<text v-if="view.status === 'stopped'">已停止生成</text>
<text v-if="view.status === 'failed'">生成中断:{{ view.error }}</text>
<text v-if="view.streaming" @click="stop">停止生成</text>
</view>
</template>
<script>
import { aiView } from '@deeprespond/im-web/render';
export default {
props: { item: Object, client: Object },
data: () => ({ live: null, offs: [] }),
computed: {
streamId() { return this.item.body?.stream_id; },
// 生成中取实时内容,结束后取消息正文
view() { return aiView(this.item, this.item.body?.status === 'streaming' ? this.live : null); },
},
mounted() {
this.live = this.client.ai.state(this.streamId);
const mine = (fn) => (s) => { if (s.stream_id === this.streamId) fn(s); };
this.offs = [
this.client.on('ai.streamStarted', mine((s) => (this.live = s))),
this.client.on('ai.streamUpdated', mine((s) => (this.live = s))),
this.client.on('ai.streamEnded', mine(() => (this.live = null))),
];
},
beforeUnmount() { this.offs.forEach((off) => off()); },
methods: {
stop() { this.client.ai.stop(this.streamId); },
},
};
</script>ai.streamUpdated的parts是当前完整内容,按它整体重画这一条消息即可;推送合并为每 50 毫秒或 2 KB 一次。- 回复结束后消息列表会以最终内容更新,
client.ai.state()返回null。 - 停止生成:只有接收回复的用户可以停止,已结束的回复返回当前状态,不报错。
- 重新生成:再发一次被回复的问题,机器人的服务端会开始一条新的回复。
- 会话列表的预览可以使用 SDK 的
summarize(已支持 AI 消息)或消息正文的text。
H5 端可以直接渲染 HTML 时,也可以只取 aiView 的结构,自己把 nodes 转为 DOM。
Demo
三个 Demo 都已显示 AI 回复,可以作为参考:
| Demo | 位置 |
|---|---|
| H5 Demo | demo/src/features/ai.ts(原生 DOM) |
| App Demo | demo-app/components/ai-reply.vue |
| 小程序 Demo | demo-miniprogram/components/ai-reply.vue |
