Skip to content

Commit 5168868

Browse files
committed
feat(chatbot): add qa for chatbot
1 parent a13eaa3 commit 5168868

File tree

2 files changed

+124
-6
lines changed

2 files changed

+124
-6
lines changed

packages/pro-components/chat/chatbot/_example/basic.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export default function chatSample() {
119119
onAbort: async () => {},
120120
// 自定义流式数据结构解析
121121
onMessage: (chunk: SSEChunkData): AIMessageContent => {
122+
console.log("====chunk", chunk)
122123
const { type, ...rest } = chunk.data;
123124
switch (type) {
124125
case 'search':

packages/pro-components/chat/chatbot/chatbot.md

Lines changed: 123 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,129 @@ spline: navigation
114114
| isChatEngineReady | boolean | ChatEngine 是否就绪 |
115115
| chatMessageValue | ChatMessagesData[] | 获取当前消息列表的只读副本 |
116116
| chatStatus | ChatStatus | 获取当前聊天状态(空闲/进行中/错误等) |
117-
| senderLoading | boolean | 当前输入框按
118-
钮是否在'输出中' |
117+
| senderLoading | boolean | 当前输入框按钮是否在'输出中' |
119118

120119
## 常见问题
121120

122-
1. 如何构造初始消息?
123-
2. onMessage 返回 null 和不返回有什么区别?
124-
3. 如何处理多种消息类型?
125-
4. 如何实现消息历史加载?
121+
### 如何回填设置消息列表(初始化/加载历史消息)?
122+
123+
组件支持两种方式回填消息:
124+
125+
**1. 初始化时回填**
126+
127+
通过 `defaultMessages` 属性传入静态初始消息列表:
128+
129+
```javascript
130+
const defaultMessages = [
131+
{
132+
id: '1',
133+
role: 'user',
134+
content: [{ type: 'text', data: '你好' }],
135+
datetime: '2025-01-01 10:00:00'
136+
},
137+
{
138+
id: '2',
139+
role: 'assistant',
140+
content: [{ type: 'text', data: '你好!有什么可以帮助你的吗?' }],
141+
datetime: '2025-01-01 10:00:01',
142+
status: 'complete'
143+
}
144+
];
145+
```
146+
147+
148+
**2. 动态加载历史消息**
149+
150+
通过 ref 调用 `setMessages` 方法,支持三种模式:
151+
152+
```javascript
153+
const chatbotRef = useRef(null);
154+
155+
// 替换所有消息(初始化回填)
156+
chatbotRef.current.setMessages(historyMessages, 'replace');
157+
158+
// 在顶部追加历史消息(适用于上拉加载更多)
159+
chatbotRef.current.setMessages(olderMessages, 'prepend');
160+
161+
// 在底部追加消息
162+
chatbotRef.current.setMessages(newMessages, 'append');
163+
```
164+
165+
**3. 消息数据结构说明**
166+
167+
每条消息必须包含以下字段:
168+
- `id`:消息唯一标识
169+
- `role`:消息角色(user/assistant/system)
170+
- `content`:消息内容数组,详见 [ChatMessage 组件文档](/react-aigc/components/chat-message?tab=api)
171+
- `datetime`:消息时间(可选)
172+
- `status`:消息状态(可选),AI 消息建议设置为 'complete'
173+
174+
175+
### 如何处理后端返回的消息数据转换?
176+
177+
后端返回的数据格式通常与组件所需的消息结构不一致,需要在 `onMessage` 回调中进行转换。
178+
179+
**核心概念**
180+
- `onMessage` 的返回值决定了如何更新消息内容
181+
- 返回 `null``undefined` 表示忽略本次数据块,不更新消息
182+
- 返回 `AIMessageContent` 表示要添加/更新单个内容块
183+
- 返回 `AIMessageContent[]` 表示批量更新多个内容块
184+
185+
**场景 1:多种消息类型混合**
186+
187+
```javascript
188+
chatServiceConfig={{
189+
onMessage: (chunk) => {
190+
// chunk为后端实时返回的数据流
191+
// { event: "message", data: { type: "think", title: "思考中...", content: "用户" } }
192+
// { event: "message", data: { type: "text", content: "总结下这个问题" } }
193+
const { type, ...rest } = chunk.data;
194+
195+
// 处理思考过程
196+
if (type === 'think') {
197+
return {
198+
type: 'thinking', // 返回组件内置的消息类型和data结构
199+
data: { text: rest.content, title: rest.title }
200+
};
201+
}
202+
203+
// 处理文本内容
204+
if (type === 'text') {
205+
return {
206+
type: 'markdown',
207+
data: rest.content,
208+
strategy: 'merge'
209+
};
210+
}
211+
212+
return null; // 忽略未知事件
213+
}
214+
}}
215+
```
216+
217+
**场景 2:批量更新多个内容块**
218+
219+
```javascript
220+
chatServiceConfig={{
221+
onMessage: (chunk, message) => {
222+
// message 是当前正在构建的消息对象
223+
const { event, data } = chunk;
224+
// 也可以根据当前消息内容动态决定
225+
if (event === 'complete') {
226+
const currentContent = message?.content || [];
227+
// 移除思考过程,只保留最终答案
228+
return currentContent.filter(c => c.type !== 'thinking');
229+
}
230+
231+
return null;
232+
}
233+
}}
234+
```
235+
236+
**返回值处理逻辑**:
237+
238+
| 返回值类型 | 处理逻辑 | 适用场景 |
239+
|-----------|---------|---------|
240+
| `null` / `undefined` | 忽略本次数据块,不更新消息 | 过滤无关事件、跳过中间状态 |
241+
| `AIMessageContent` | 根据 `strategy` 字段决定:<br>• `merge`(默认):查找相同 type 的最后一个内容块并合并<br>• `append`:追加为新的独立内容块 | 大多数流式响应场景 |
242+
| `AIMessageContent[]` | 遍历数组,根据 `id``type` 匹配已存在的内容块:<br>• 匹配到:更新该内容块<br>• 未匹配:追加到末尾 | 批量更新多个内容块、动态调整内容结构 |

0 commit comments

Comments
 (0)