🧠 Chat 模块核心概念
📖 前言
在深入学习 Chat SDK 的使用方法之前,理解以下核心概念将帮助您:
- ✅ 快速掌握系统架构和设计理念
- ✅ 避免常见的使用误区和错误
- ✅ 更好地理解 API 设计背后的逻辑
- ✅ 编写出更优雅、更高效的代码
1️⃣ 智能体 (Agent)
什么是智能体?
智能体是具有特定能力和知识领域的 AI 助手。每个智能体都有独特的:
- 专业领域(如代码助手、写作助手、数据分析助手)
- 知识库和训练数据
- 工具和技能集
- 对话风格和个性
agentCode 的作用
agentCode 是智能体的唯一标识符,类似于身份证号。
// 示例:不同的智能体有不同的能力
const agents = {
'gpt-4': '通用对话助手',
'code-helper': '代码编程助手',
'writer': '文案创作助手',
'data-analyst': '数据分析助手'
};多智能体切换
在同一个应用中,您可以根据用户需求动态切换智能体:
// 用户询问编程问题 → 切换到代码助手
await scp.chat.setAgentCode('code-helper');
// 用户需要写文章 → 切换到写作助手
await scp.chat.setAgentCode('writer');使用场景:
- 🎯 根据用户意图自动切换专业助手
- 🎯 在不同业务场景使用不同智能体
- 🎯 A/B 测试不同模型的效果
2️⃣ 会话 (Thread)
什么是会话?
会话是一系列连续对话消息的集合,类似于微信聊天窗口。会话保存了:
- 完整的对话历史
- 上下文信息
- 会话元数据(创建时间、标题等)
有会话模式 vs 无会话模式
有会话模式(isThreadRequired: true)
特点:
- ✅ 保存完整对话历史
- ✅ 支持会话列表管理
- ✅ 可以随时切换和恢复会话
- ✅ 上下文连贯性强
适用场景:
// 客服系统、项目管理助手等需要长期跟踪的场景
await scp.chat.init({
agentCode: 'customer-service',
isThreadRequired: true // 需要会话列表
});无会话模式(isThreadRequired: false)
特点:
- ✅ 轻量级,无需维护会话列表
- ✅ 适合一次性对话
- ✅ 后端仍保存历史,但前端不显示会话列表
适用场景:
// AgentOS 3.0 的简化对话场景
await scp.chat.init({
agentCode: 'quick-assistant',
isThreadRequired: false // 不需要会话列表
});threadId 的作用
threadId 是会话的唯一标识符,用于:
- 📌 恢复历史会话
- 📌 在多个会话间切换
- 📌 MQTT 消息订阅(主题:
MQTT/chat/${threadId})
// 加载指定会话
await scp.chat.init({
agentCode: 'agent_code',
threadId: 'existing_thread_id' // 加载历史会话
});
// 创建新会话
await scp.chat.setThreadId(null);3️⃣ 消息 (Message)
消息的基本结构
每条消息包含以下核心信息:
interface Message {
id: string; // 消息唯一ID
role: 'user' | 'assistant'; // 消息角色
content: MessageContent; // 消息内容
timestamp: number; // 时间戳
status: MessageStatus; // 消息状态
}消息角色 (Role)
user: 用户发送的消息assistant: AI 助手的回复
消息内容类型
Chat 模块支持多种消息类型:
1. 文本消息
await scp.chat.send('你好,请帮我分析一下市场趋势');
// 或
await scp.chat.send({
type: 'text',
text: '你好,请帮我分析一下市场趋势'
});2. 文件消息
await scp.chat.send({
type: 'document', // 注意:后端命名,包含图片、文档等
file: {
uri: 'https://example.com/file.pdf',
mimeType: 'application/pdf'
}
});3. 混合消息
await scp.chat.send([
{ type: 'text', text: '请分析这份报告:' },
{ type: 'document', file: { uri: '...' } }
]);消息状态生命周期
pending → sending → sent → generating → completed
↓
errorpending: 消息准备发送sending: 正在发送中sent: 发送成功generating: AI 正在生成回复completed: 回复完成error: 发生错误
4️⃣ 流式响应 (Streaming)
什么是流式响应?
流式响应是指 AI 的回复逐字逐句实时返回,而不是等待全部生成完毕后一次性返回。
为什么需要流式响应?
用户体验对比:
| 非流式响应 | 流式响应 |
|---|---|
| ❌ 等待时间长(10-30秒) | ✅ 立即看到响应 |
| ❌ 用户焦虑,不知道是否在工作 | ✅ 实时反馈,体验流畅 |
| ❌ 长文本一次性出现,阅读困难 | ✅ 逐字显示,易于阅读 |
| ❌ 无法中断生成过程 | ✅ 可随时停止生成 |
流式响应的工作原理
用户发送消息
↓
后端 AI 开始生成
↓
每生成一小段文本 → 立即推送到前端
↓ ↓
继续生成下一段 ← 前端实时显示
↓
生成完成 → 触发完成事件流式接口事件类型详解 ⭐
💡 重要说明:后端聊天接口采用 JSON-RPC 2.0 协议,基于 Server-Sent Events (SSE) 推送流式事件。接口基于 Claude API 并增强了多轮次推理能力。SDK 会将这些事件转换为前端友好的
STREAM_UPDATE事件。
JSONRPC 接口请求格式
{
"jsonrpc": "2.0",
"id": "0199ff5d-a7d4-75ae-a6f2-1d37ff24bbc7",
"method": "agentos.conversation",
"params": {
"session_id": "0199ff5d-a7d4-75ae-a6f2-208c6986156c",
"request_id": "0199ff5d-a7d4-75ae-a6f2-273652f85081",
"message": {
"id": "0199ff5d-a7d4-75ae-a6f2-17a0b0f0144c",
"role": "user",
"parts": [{"type": "text", "text": "你好"}],
"metadata": {},
"timestamp": "2025-10-20 10:05:51"
},
"agent_code": "agent_00000000",
"metadata": {}
}
}后端原始事件类型
后端接口基于 Claude API + 多轮次增强,会推送以下事件:
| 事件类型 | 说明 | 频率 | 数据内容 |
|---|---|---|---|
accepted | 请求已接受 | 每次请求 1 次 | 会话ID、请求ID、时间戳 |
assistant_init | 助理消息初始化 | 每次回复 1 次 | 助理消息元数据(id、parent_id 等) |
message_start | 轮次开始 | 每个轮次 1 次 ⭐ | 消息元数据(id、role、model 等) |
content_block_start | 内容块开始 | 每个内容块 1 次 | 内容块类型(text/tool_use) |
content_block_delta | 内容增量 | 多次(实时推送) | 文本片段或工具调用参数或引用数据 |
content_block_stop | 内容块结束 | 每个内容块 1 次 | 内容块索引 |
message_delta | 元数据更新 | 每个轮次 1 次 | 停止原因、使用统计 |
message_stop | 轮次结束 | 每个轮次 1 次 ⭐ | - |
approval_request | 用户审批请求 | 需要用户确认执行方案时出现 1 次 | 待执行的方案选项 |
finish | 整体完成 | 每次请求 1 次 | 总轮次数、完成时间、状态 |
notification | 通知事件 | 按需推送 | 通知ID、事件类型、通知数据 |
error | 错误事件 | 发生错误时 | 错误类型和详情 |
⚠️ 设计说明:目前后端将错误也归类到
notification事件中(event: "error"),这个设计存在问题,后续待后端优化。开发者需要检查notification.event字段来判断具体的通知类型。
🔄 多轮次机制说明
💡 关于事件命名:目前后端使用
message_start/message_stop来标识每个推理轮次的开始和结束。从语义角度看,使用turn_start/turn_end可能更直观易懂,因为"turn"(轮次)比"message"(消息)更准确地描述了智能体的多轮推理过程。不过当前实现已经稳定运行,且 SDK 已对前端屏蔽了这些细节。
关键特性:后端智能体支持多轮次推理,一次问答可能包含多个推理轮次:
- 每个轮次开始时推送
message_start - 每个轮次结束时推送
message_stop - 一次完整的回复 = 多个轮次的累加
为什么需要多轮次?
- 🧠 复杂推理:将复杂问题分解为多个步骤
- 🔧 工具调用:每次工具调用可能触发新轮次
- 🎯 精准回答:通过多轮推理提升答案质量
完整的事件流示例
场景:用户发送 "你好"
第一步:请求接受
event: accepted
data: {
"jsonrpc": "2.0",
"id": "0199ff5d-a7d4-75ae-a6f2-1d37ff24bbc7",
"result": {
"status": "accepted",
"sessionId": "0199ff5d-a7d4-75ae-a6f2-208c6986156c",
"requestId": "0199ff5d-a7d4-75ae-a6f2-273652f85081",
"timestamp": "2025-10-20T10:05:52.794845"
}
}
第二步:助理消息初始化
event: assistant_init
data: {
"jsonrpc": "2.0",
"result": {
"session_id": "0199ff5d-a7d4-75ae-a6f2-208c6986156c",
"request_id": "0199ff5d-a7d4-75ae-a6f2-273652f85081",
"seq_id": 1,
"type": "assistant_init",
"id": "0199ff5d-ab23-7bde-8307-820eba075c71",
"parent_id": "0199ff5d-a7d4-75ae-a6f2-17a0b0f0144c",
"message": {
"id": "0199ff5d-ab23-7bde-8307-820eba075c71",
"parent_id": "0199ff5d-a7d4-75ae-a6f2-17a0b0f0144c",
"type": "message",
"role": "assistant",
"parts": [],
"timestamp": "2025-10-20 10:05:52"
}
}
}
第三步:轮次 1 开始(可能有多个轮次)
event: message_start
data: { "type": "message_start", "message": {...} }
第四步:内容块开始
event: content_block_start
data: { "type": "content_block_start", "index": 0, "content_block": {"type": "text"} }
第五步:内容逐字推送(多次)
event: content_block_delta
data: { "type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "你"} }
event: content_block_delta
data: { "type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "好"} }
event: content_block_delta
data: { "type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "!"} }
第六步:内容块结束
event: content_block_stop
data: { "type": "content_block_stop", "index": 0 }
第七步:轮次 1 结束
event: message_stop
data: { "type": "message_stop" }
(如果有工具调用或需要进一步推理,会有轮次 2、轮次 3...)
(每个新轮次都会重复 message_start → content_block_* → message_stop 的流程)
第八步:整体完成(所有轮次结束后)
event: finish
data: {
"jsonrpc": "2.0",
"method": "agentos.conversation.finish",
"params": {
"sessionId": "0199ff5d-a7d4-75ae-a6f2-208c6986156c",
"requestId": "0199ff5d-a7d4-75ae-a6f2-273652f85081",
"status": "success",
"result": {
"totalChunks": 2,
"completedAt": "2025-10-20T10:05:52.924990"
}
}
}
特殊情况:通知事件(可能在任何时候推送)
event: notification
data: {
"jsonrpc": "2.0",
"result": {
"session_id": "01997ede-9b82-728c-a318-f3360f327937",
"request_id": "01997ede-9b82-728c-a318-f4c83ca948fb",
"seq_id": 2,
"type": "notification",
"id": "01997ede-a046-70f6-a082-ed5ea10529c8",
"parent_id": "01997ede-9f55-7130-b9b3-6d53230f1f1c",
"notification_id": "error-01997ede-a044-706b-99d8-572c118da1ef",
"event": "error", // ⚠️ 注意:错误也通过 notification 推送
"notification_data": {
"message": "'NoneType' object has no attribute 'name'"
}
},
"id": 1
}📌 关于 notification 事件的说明:
notification事件可能在流式响应的任何阶段推送- 需要检查
event字段来判断通知类型(如"error"、"warning"等) - ⚠️ 当前设计问题:错误信息也通过
notification事件推送,而不是独立的error事件,这个设计待后端优化 - SDK 会自动处理
notification中的错误,并转换为STREAM_UPDATE(type: 'error')
SDK 事件转换机制
SDK 会自动将后端事件转换为简化的 STREAM_UPDATE 事件:
// 后端事件 → SDK 事件映射关系
accepted + assistant_init + message_start → STREAM_UPDATE(type: 'start')
content_block_delta → STREAM_UPDATE(type: 'content')
finish → STREAM_UPDATE(type: 'end')
notification (event: 'error') → STREAM_UPDATE(type: 'error')
error → STREAM_UPDATE(type: 'error')⚠️ 错误处理说明:
- 当前后端将错误信息包装在
notification事件中 - SDK 会检查
notification.event === 'error'并转换为错误事件 - 独立的
error事件也会被正确处理 - 开发者无需关心错误来源,统一通过
STREAM_UPDATE(type: 'error')处理
多轮次处理逻辑:
- SDK 不处理
message_start和message_stop事件,因为前端不关注具体的轮次切换 STREAM_UPDATE(type: 'start')由accepted+assistant_init触发(只在最开始)STREAM_UPDATE(type: 'end')由finish事件触发(表示所有轮次真正完成)- 多轮次对前端完全透明,
content_block_delta会跨轮次持续推送 - 前端只需关注内容的累加,无需关心后端的轮次切换
为什么需要了解后端事件?
虽然 SDK 已经封装了事件转换,但了解底层事件有助于:
- 调试问题:当流式响应异常时,可以查看原始事件日志
- 理解多轮次:知道为什么会出现多个
message_start/message_stop - 高级定制:某些场景需要访问原始事件数据(如 usage 统计、轮次信息)
- 对接后端:与后端开发者沟通时使用统一的术语
- 性能优化:理解事件流,优化前端渲染策略
STREAM_UPDATE 事件详解
前端开发者只需关注 SDK 转换后的 4 个简化阶段:
scp.chat.on(ChatEventType.STREAM_UPDATE, (msgId, content, type) => {
switch (type) {
case 'start':
// 对应 Claude 的 message_start + content_block_start
// AI 开始生成,显示 loading 动画
showLoadingAnimation(msgId);
break;
case 'content':
// 对应 Claude 的 content_block_delta
// 接收到新内容片段,实时追加到界面
appendContent(msgId, content);
break;
case 'end':
// 对应 Claude 的 content_block_stop + message_stop
// 生成完成,隐藏 loading,显示完整消息
hideLoadingAnimation(msgId);
finalizeMessage(msgId, content);
break;
case 'error':
// 对应 Claude 的 error 事件
// 生成出错,显示错误提示
showError(msgId, content);
break;
}
});各阶段的应用场景:
| SDK 阶段 | 后端原始事件 | 作用 | UI 操作示例 |
|---|---|---|---|
start | acceptedassistant_initmessage_start(首次) | 标记生成开始 | 显示"正在思考..." 打字机动画 |
content | content_block_delta(跨所有轮次) | 实时更新内容 | 逐字显示 自动滚动 |
end | finish | 标记生成完成 | 隐藏动画 启用复制按钮 显示使用统计 |
error | error | 处理错误情况 | 显示错误提示 提供重试按钮 |
⚠️ 多轮次注意事项:
- 在多轮次场景下,
content阶段会持续很长时间 - 中间可能会有短暂的停顿(轮次切换),这是正常现象
- 关键:只有
finish事件才表示真正完成,不要在message_stop时就认为生成完成 - SDK 会自动处理所有轮次,前端只需关注
STREAM_UPDATE的 4 个阶段
scp.chat.on(ChatEventType.STREAM_UPDATE, (msgId, content, type) => {
switch (type) {
case 'start':
// AI 开始生成,显示 loading 动画
showLoadingAnimation(msgId);
break;
case 'content':
// 接收到新内容片段,实时追加到界面
appendContent(msgId, content);
break;
case 'end':
// 生成完成,隐藏 loading,显示完整消息
hideLoadingAnimation(msgId);
finalizeMessage(msgId, content);
break;
case 'error':
// 生成出错,显示错误提示
showError(msgId, content);
break;
}
});各阶段的应用场景:
| 阶段 | 作用 | UI 操作示例 |
|---|---|---|
start | 标记生成开始 | 显示"正在思考..."、打字机动画 |
content | 实时更新内容 | 逐字显示、自动滚动 |
end | 标记生成完成 | 隐藏动画、启用复制按钮 |
error | 处理错误情况 | 显示错误提示、提供重试按钮 |
5️⃣ 事件驱动架构
什么是事件驱动?
Chat 模块采用事件驱动架构,即:
- 📡 系统发生变化时,主动发出事件通知
- 👂 开发者监听感兴趣的事件,执行相应操作
- 🔄 实现松耦合的响应式编程
核心事件类型
enum ChatEventType {
MESSAGES_CHANGE = 'messages_change', // 消息列表变化
STREAM_UPDATE = 'stream_update', // 流式内容更新
TOKEN_STATUS_CHANGE = 'tokenStatusChange', // Token状态变化
THREAD_CREATED = 'threadCreated', // 会话创建
THREAD_CHANGED = 'threadChanged', // 会话列表变化
SKILL_COMPLETED = 'skillCompleted', // 技能执行完成
}事件监听最佳实践
✅ 推荐写法:统一监听
// 使用 on 方法监听,返回取消订阅函数
const unsubscribe = scp.chat.on(ChatEventType.MESSAGES_CHANGE, (newMessages) => {
messages.value = newMessages;
});
// 组件销毁时取消订阅
onUnmounted(() => {
unsubscribe();
});✅ 推荐写法:批量订阅
const unsubscribeAll = scp.chat.subscribeEvents({
[ChatEventType.MESSAGES_CHANGE]: handleMessagesChange,
[ChatEventType.STREAM_UPDATE]: handleStreamUpdate,
[ChatEventType.TOKEN_STATUS_CHANGE]: handleTokenChange
});
// 一键取消所有订阅
onUnmounted(() => {
unsubscribeAll();
});❌ 不推荐:忘记清理
// 没有保存取消订阅函数
scp.chat.on(ChatEventType.MESSAGES_CHANGE, handler);
// 组件销毁时没有取消订阅 → 内存泄漏!事件与消息状态的关系
graph LR
A[发送消息] --> B[MESSAGES_CHANGE]
B --> C[STREAM_UPDATE: start]
C --> D[STREAM_UPDATE: content]
D --> D
D --> E[STREAM_UPDATE: end]
E --> F[MESSAGES_CHANGE]6️⃣ 助理/场景 (Assistant)
什么是 Assistant?
Assistant 也称为"场景"或"助理 ID",代表智能体在特定场景下的配置。
assistant_id 的作用
同一个智能体(agentCode)可以有多个场景配置:
// 同一个 GPT-4 智能体的不同场景
const scenes = {
'agent': '通用对话场景',
'code-review': '代码审查场景',
'translation': '翻译场景',
'summarization': '文档总结场景'
};assistant_id vs agentCode
| 概念 | 含义 | 作用域 | 示例 |
|---|---|---|---|
| agentCode | 智能体标识 | 全局唯一 | 'gpt-4', 'claude' |
| assistant_id | 场景配置 | 智能体内部 | 'agent', 'code-review' |
类比理解:
agentCode= 一个人(张三)assistant_id= 这个人的不同角色(老师、朋友、顾问)
场景切换示例
// 初始化时指定场景
await scp.chat.init({
agentCode: 'gpt-4',
assistant_id: 'agent' // 通用对话场景
});
// 切换到代码审查场景
scp.chat.setAssistantId('code-review');
// 现在对话会围绕代码审查进行
await scp.chat.send('请帮我审查这段代码');metadata 配置
通过 metadata 可以进一步定制场景行为:
await scp.chat.init({
agentCode: 'reasoning-agent',
assistant_id: 'agent',
metadata: {
model_id: 'reasoning', // 推理模型
safe_mode: true, // 安全模式
permission_mode: 'plan' // 规划模式
}
});7️⃣ 工具调用 (Tool Calling)
什么是工具?
工具是赋予 AI 执行特定操作的能力,如:
- 📊 查询数据库
- 📁 读写文件
- 🌐 调用 API
- 📧 发送邮件
- 🧮 执行计算
工具的分类
前端工具 vs 后端工具
| 类型 | 执行位置 | 适用场景 | 示例 |
|---|---|---|---|
| 前端工具 | 浏览器/客户端 | 需要访问前端资源 | 文件上传、页面跳转、本地存储 |
| 后端工具 | 服务器 | 需要服务器权限 | 数据库查询、发送邮件、系统操作 |
工具调用流程
用户: "帮我计算 15 * 23 + 7"
↓
AI 分析: 需要使用计算器工具
↓
发起工具调用请求
↓
前端/后端执行工具
↓
返回执行结果: 352
↓
AI 基于结果生成回复: "根据计算,结果是 352"工具定义示例
// 注册一个简单的计算器工具
scp.chat.registerTool({
name: 'calculator',
description: '执行数学计算',
parameters: {
type: 'object',
properties: {
expression: {
type: 'string',
description: '数学表达式,如 "2 + 3 * 4"'
}
},
required: ['expression']
},
handler: async (params) => {
const result = eval(params.expression);
return {
success: true,
result: result
};
}
});详细说明请参考: 工具集成文档
8️⃣ 实时通信机制
MQTT vs Webhook
Chat 模块支持两种实时通信方式:
MQTT(当前版本)
特点:
- 🔌 基于 WebSocket 的持久连接
- ⚡ 实时性强,延迟低
- 📡 双向通信
适用场景:
// 需要实时推送的场景
listenMqttMessage(threadId, (message) => {
// 处理实时消息
handleRealtimeMessage(message);
});Webhook(AgentOS 3.0)
特点:
- 🌐 基于 HTTP 的回调机制
- 🔒 更安全、更可靠
- 🔄 自动重试机制
适用场景:
// 长任务完成通知、断线重连等
scp.chat.webhook.register({
endpoint: 'https://your-app.com/webhook',
events: ['task_completed', 'message_received']
});详细说明请参考: Webhook 文档
🔄 概念关系图
┌─────────────────────────────────────────────────────────┐
│ Chat 系统架构 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌──────────┐ │
│ │ Agent │────────▶│ Assistant│ │
│ │ (智能体) │ │ (场景) │ │
│ └─────────┘ └──────────┘ │
│ │ │ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ Thread (会话) │ │
│ │ ┌────────────────────────────┐ │ │
│ │ │ Message (消息) │ │ │
│ │ │ ┌──────────────────────┐ │ │ │
│ │ │ │ • 文本消息 │ │ │ │
│ │ │ │ • 文件消息 │ │ │ │
│ │ │ │ • 工具调用 │ │ │ │
│ │ │ └──────────────────────┘ │ │ │
│ │ └────────────────────────────┘ │ │
│ └──────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ 事件驱动系统 │ │
│ │ • MESSAGES_CHANGE │ │
│ │ • STREAM_UPDATE │ │
│ │ • THREAD_CREATED │ │
│ └──────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ 实时通信 │ │
│ │ • MQTT (当前) │ │
│ │ • Webhook (3.0) │ │
│ └──────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘🎯 核心概念速查表
| 概念 | 作用 | 关键 API | 文档链接 |
|---|---|---|---|
| Agent | 智能体标识 | setAgentCode() | 基础使用 |
| Thread | 会话管理 | setThreadId() | 基础使用 |
| Message | 消息发送 | send() | 基础使用 |
| Streaming | 流式响应 | STREAM_UPDATE 事件 | 基础使用 |
| Events | 事件监听 | on(), subscribeEvents() | 基础使用 |
| Assistant | 场景配置 | setAssistantId() | 基础使用 |
| Tool | 工具调用 | registerTool() | 工具集成 |
| Webhook | 异步通知 | webhook.register() | Webhook |
💡 常见问题
Q1: Agent 和 Assistant 有什么区别?
A:
- Agent(智能体):不同的 AI 模型或助手,如 GPT-4、Claude
- Assistant(场景):同一个智能体在不同场景下的配置,如通用对话、代码审查
类比:Agent 是"演员",Assistant 是"角色"。
Q2: 什么时候用有会话模式,什么时候用无会话模式?
A:
- 有会话模式 :需要会话列表、长期跟踪对话历史
- 无会话模式:简化场景、一次性对话、不需要会话列表
Q3: 流式响应的 4 个阶段分别用来做什么?
A:
start: 显示 loading 动画、准备 UIcontent: 实时更新内容、自动滚动end: 隐藏 loading、启用交互按钮error: 显示错误提示、提供重试选项
Q4: 如何避免事件监听器内存泄漏?
A:
// ✅ 正确做法
const unsubscribe = scp.chat.on(ChatEventType.MESSAGES_CHANGE, handler);
onUnmounted(() => {
unsubscribe(); // 组件销毁时取消订阅
});
// 或使用批量清理
onUnmounted(() => {
scp.chat.removeAllListeners();
});Q5: 前端工具和后端工具如何选择?
A:
- 前端工具:需要访问浏览器 API、用户交互、本地资源
- 后端工具:需要服务器权限、数据库访问、安全性要求高的操作
📚 学习路径建议
🎯 新手入门(1-2天)
- 阅读核心概念(本文)- 30分钟
- 学习基础使用 - 2小时
- 初始化模块
- 发送消息
- 监听事件
- 实践简单示例 - 4小时
- 创建基础聊天界面
- 实现流式显示
- 添加事件监听
参考文档: 基础使用指南
🚀 进阶开发(3-5天)
工具集成 - 1天
- 理解工具调用机制
- 注册自定义工具
- 处理工具执行结果
Webhook 配置 - 1天
- 配置 Webhook 端点
- 处理异步通知
- 实现断线重连
性能优化 - 1天
- 事件节流
- 虚拟滚动
- 缓存策略
参考文档:
🏆 高级应用(1-2周)
- 多智能体管理
- 复杂工具链设计
- 实时协作功能
- 安全与权限控制
🔗 相关资源
📖 官方文档
🎓 示例项目
- 项目仓库:
http://gitlab.e-tudou.com/tudou-application/agentos/tudou-agent-scp-web - 在线演示:
http://10.0.36.82:5436/chat/2607551164618825742
🛠️ 开发工具
✨ 总结
掌握这些核心概念后,您将能够:
✅ 理解系统架构
- 智能体、会话、消息的关系
- 事件驱动的工作原理
- 流式响应的实现机制
✅ 高效开发应用
- 正确使用 API
- 避免常见错误
- 优化用户体验
✅ 解决实际问题
- 多智能体场景切换
- 长任务状态跟踪
- 断线重连处理
💡 下一步: 建议您继续阅读 基础使用文档,通过实际代码示例加深理解。