# 聊天模块 V2.1 优化更新 ## 📅 更新日期 2025年10月14日 ## 🎯 本次优化内容 ### 1. ✅ 右侧对话列表可折叠 **功能描述**:右侧的对话列表现在支持折叠/展开,节省屏幕空间。 **实现细节**: - 在对话头部添加折叠按钮 - 按钮图标根据状态变化(ChevronLeft / ChevronRight) - 按钮文字显示"显示列表" / "隐藏列表" - 使用 CSS transition 实现平滑动画 **代码实现**: ```vue {{ showSidebar ? '隐藏列表' : '显示列表' }} ``` **使用方法**: - 点击对话头部右上角的折叠按钮 - 对话列表会平滑地隐藏/显示 - 响应式设计:小屏幕时自动变为浮动面板 --- ### 2. ✅ AI 模型选择列表动态加载 **功能描述**:模型选择器现在会动态读取"模型服务"中已配置的所有可用模型。 **实现细节**: ```typescript // 从 modelStore 动态读取模型列表 const modelOptions = computed(() => { const services = modelStore.providers const options: any[] = [] services.forEach((service: any) => { if (service.enabled && service.models) { service.models.forEach((model: any) => { options.push({ label: `${service.name} | ${model.name}`, key: `${service.id}:${model.id}`, icon: () => h(NIcon, { component: BrainIcon }) }) }) } }) return options }) // 显示选中的模型名称 const selectedModelName = computed(() => { if (!selectedModel.value) return undefined const [serviceId, modelId] = selectedModel.value.split(':') const service = modelStore.providers.find((s: any) => s.id === serviceId) const model = service?.models?.find((m: any) => m.id === modelId) return model ? `${service?.name} | ${model.name}` : undefined }) ``` **工作流程**: 1. 用户在"模型服务"页面添加服务(如火山引擎、OpenAI) 2. 服务连接成功后,其模型会自动出现在聊天页面的模型选择器中 3. 选择模型后,该模型会被用于当前对话 4. 模型信息格式:`服务名 | 模型名`(如"火山引擎 | doubao-1.5-pro-32k") **特性**: - ✅ 实时同步:添加新服务后立即可用 - ✅ 多服务支持:同时显示所有服务的模型 - ✅ 清晰标识:服务名和模型名分开显示 - ✅ 图标辅助:每个选项都有模型图标 --- ### 3. ✅ MCP 服务支持(基础架构) **功能描述**:聊天对话中现在支持选择和使用 MCP 服务器。 **实现细节**: #### 3.1 MCP 服务器列表动态加载 ```typescript // 从 mcpStore 读取已连接的服务器 const mcpOptions = computed(() => { const options: any[] = [ { label: '不启用 MCP 服务', key: 'none' } ] // 添加已连接的服务器 mcpStore.connectedServers.forEach((server) => { const toolCount = server.capabilities?.tools?.length || 0 options.push({ label: `${server.name} (${toolCount} 个工具)`, key: server.id, icon: () => h(NIcon, { component: PlugIcon }) }) }) return options }) // 显示选中的 MCP 服务器名称 const selectedMCPName = computed(() => { if (!selectedMCP.value || selectedMCP.value === 'none') return '不启用 MCP 服务' const server = mcpStore.servers.find(s => s.id === selectedMCP.value) return server?.name || '未知服务' }) ``` #### 3.2 MCP 服务器传递到聊天服务 ```typescript // ChatLayout.vue - 发送消息时传递 MCP 服务器 ID const handleSendMessage = async () => { const mcpId = selectedMCP.value === 'none' ? undefined : selectedMCP.value await store.sendMessageStream( content, selectedModel.value, mcpId, // 传递 MCP 服务器 ID () => { scrollToBottom() } ) } // chatStore.ts - 转发到 chatService const sendMessageStream = async ( content: string, model?: string, mcpServerId?: string, // 新增参数 onChunk?: (chunk: string) => void ) => { await chatService.sendMessageStream( { topicId, content, model, stream: true }, onChunk, mcpServerId // 传递给 service ) } // chatService.ts - 接收并准备使用 async sendMessageStream( options: SendMessageOptions, onChunk: (event: StreamEvent) => void, mcpServerId?: string // 接收 MCP 服务器 ID ): Promise { // TODO: 在这里实现 MCP 工具调用逻辑 await this.callModelStream(conversation, model, onChunk, mcpServerId) } ``` #### 3.3 自动加载和重连 ```typescript // 初始化时加载 MCP 服务器 onMounted(async () => { store.initialize() scrollToBottom() // 加载 MCP 服务器配置 mcpStore.loadServers() // 尝试自动重连之前已连接的服务器 try { await mcpStore.autoReconnect() } catch (error) { console.warn('自动重连 MCP 服务器失败:', error) } }) ``` **工作流程**: 1. 用户在"MCP 设置"页面添加并连接服务器 2. 服务器连接成功后,自动出现在聊天页面的 MCP 选择器中 3. 选择服务器后,该服务器 ID 会被传递到聊天服务 4. 聊天服务可以使用该服务器的工具(待实现) **当前状态**: - ✅ 基础架构完成:MCP 服务器 ID 可以从 UI 传递到服务层 - ✅ 服务器列表动态加载:实时显示已连接的服务器和工具数量 - ✅ 自动重连:页面刷新后自动重连之前的服务器 - ⏳ 工具调用逻辑:已预留接口,等待实现 **下一步实现**: ```typescript // 在 callModelStream 中检测 AI 的工具调用请求 private async callModelStream( conversation: Conversation, model: string | undefined, onChunk: (chunk: string) => void, mcpServerId?: string ): Promise { if (mcpServerId) { // 1. 获取 MCP 服务器的可用工具列表 const server = mcpStore.servers.find(s => s.id === mcpServerId) const tools = server?.capabilities?.tools || [] // 2. 将工具列表传递给 AI 模型 // 让 AI 知道可以调用哪些工具 // 3. 如果 AI 返回工具调用请求,执行工具 // const toolResult = await mcpStore.callTool(mcpServerId, toolName, params) // 4. 将工具结果返回给 AI,让它生成最终回复 } // 正常的流式响应 // ... } ``` --- ## 📊 完整功能清单 ### 已完成功能 1. ✅ 左侧导航可折叠(V2.0) 2. ✅ 右侧对话列表(V2.0) 3. ✅ **右侧对话列表可折叠(V2.1 新增)** 4. ✅ 工具栏 - MCP 服务选择 5. ✅ **工具栏 - 模型动态加载(V2.1 优化)** 6. ✅ **MCP 服务集成基础架构(V2.1 新增)** 7. ✅ 快捷操作按钮 8. ✅ 消息实时更新 9. ✅ 消息条数正确显示 ### 待实现功能 1. ⏳ MCP 工具调用实际逻辑 2. ⏳ Markdown 渲染 3. ⏳ 代码语法高亮 4. ⏳ 真正的流式响应(SSE) 5. ⏳ 图片和文件消息 --- ## 🎬 使用示例 ### 场景1:使用特定模型对话 1. **添加模型服务** ``` 侧边栏 → 模型服务 → 添加服务 例如:添加"火山引擎"服务 ``` 2. **在聊天中选择模型** ``` 聊天页面 → 工具栏 → 点击"选择模型▼" 选择:火山引擎 | doubao-1.5-pro-32k-character ``` 3. **发送消息** ``` 输入框 → 输入"你好" → Enter AI 使用选中的模型回复 ``` ### 场景2:使用 MCP 服务器扩展能力 1. **添加 MCP 服务器** ``` 侧边栏 → MCP 设置 → 添加服务器 例如:添加"xhs-sse"服务器 URL: http://localhost:3200 ``` 2. **连接服务器** ``` 点击"连接"按钮 等待连接成功,显示可用工具数量 ``` 3. **在聊天中选择 MCP** ``` 聊天页面 → 工具栏 → 点击"不启用 MCP 服务▼" 选择:xhs-sse (5 个工具) ``` 4. **发送消息(准备使用工具)** ``` 输入框 → 输入"搜索最新的 Vue 3 教程" AI 可以调用 MCP 工具进行搜索(功能待实现) ``` ### 场景3:折叠对话列表获得更大空间 1. **隐藏对话列表** ``` 点击右上角"隐藏列表"按钮 对话列表平滑隐藏 主对话区域扩大 ``` 2. **再次显示** ``` 点击"显示列表"按钮 对话列表平滑显示 ``` --- ## 🔧 技术细节 ### 数据流:模型选择 ``` 用户添加服务 ↓ ModelService 连接 ↓ modelStore.providers 更新 ↓ modelOptions 计算属性更新 ↓ 下拉列表自动刷新 ↓ 用户选择模型 ↓ selectedModel = "serviceId:modelId" ↓ 发送消息时使用该模型 ↓ modelServiceManager.sendChatRequest(serviceId, messages, modelId) ``` ### 数据流:MCP 集成 ``` 用户添加 MCP 服务器 ↓ MCPClientService 连接 ↓ mcpStore.servers 更新 ↓ mcpOptions 计算属性更新 ↓ 下拉列表自动刷新 ↓ 用户选择 MCP 服务器 ↓ selectedMCP = serverId ↓ 发送消息时传递 serverId ↓ chatService.sendMessageStream(..., mcpServerId) ↓ callModelStream(..., mcpServerId) ↓ [待实现] mcpStore.callTool(mcpServerId, toolName, params) ``` ### 关键组件关系 ``` ChatLayout.vue ├─ uses chatStore (聊天状态管理) ├─ uses modelStore (模型列表) ├─ uses mcpStore (MCP 服务器列表) └─ calls sendMessageStream(content, model, mcpServerId) chatStore.ts └─ calls chatService.sendMessageStream(options, onChunk, mcpServerId) chatService.ts └─ calls callModelStream(conversation, model, onChunk, mcpServerId) └─ [TODO] 实现 MCP 工具调用逻辑 ``` --- ## 📝 配置示例 ### 模型服务配置示例 ```json { "id": "volcengine-001", "name": "火山引擎", "type": "volcengine", "url": "https://ark.cn-beijing.volces.com/api/v3", "apiKey": "your-api-key", "enabled": true, "models": [ { "id": "doubao-1.5-pro-32k", "name": "豆包-1.5-pro-32k", "type": "chat" }, { "id": "doubao-1.5-pro-32k-character", "name": "豆包-1.5-pro-32k-角色扮演", "type": "chat" } ] } ``` ### MCP 服务器配置示例 ```json { "id": "mcp-xhs-001", "name": "xhs-sse", "url": "http://localhost:3200", "transport": "sse", "status": "connected", "capabilities": { "tools": [ { "name": "search", "description": "搜索互联网内容" }, { "name": "read_file", "description": "读取本地文件" } ] } } ``` --- ## 🎯 下一步开发计划 ### 优先级1:MCP 工具调用实现 ```typescript // 实现 AI 工具调用流程 1. 将 MCP 工具列表格式化为 OpenAI Function Calling 格式 2. 在调用模型时传递工具定义 3. 解析 AI 返回的工具调用请求 4. 执行 MCP 工具 5. 将结果返回给 AI 6. 显示完整的对话过程 ``` ### 优先级2:模型切换优化 ```typescript // 记住每个对话的模型选择 1. 在 Topic 中保存 modelId 2. 切换对话时自动选择对应模型 3. 支持为不同对话设置默认模型 ``` ### 优先级3:UI 优化 ```typescript // 更好的用户体验 1. 工具调用进度显示 2. MCP 工具调用结果可视化 3. 模型和 MCP 状态指示器 4. 更多的快捷键支持 ``` --- ## ⚠️ 注意事项 ### MCP 服务器要求 1. **必须先配置**:在"MCP 设置"中添加并连接服务器 2. **连接状态**:只有已连接的服务器才会出现在选择器中 3. **自动重连**:页面刷新后会自动尝试重连 4. **工具数量**:选择器显示每个服务器的工具数量 ### 模型服务要求 1. **必须先配置**:在"模型服务"中添加服务 2. **启用状态**:只有启用的服务的模型才会出现 3. **连接状态**:建议先测试连接再使用 4. **API Key**:确保 API Key 有效且有足够配额 ### 性能建议 1. **服务器数量**:建议不超过 5 个 MCP 服务器同时连接 2. **模型选择**:根据对话复杂度选择合适的模型 3. **工具调用**:复杂工具可能需要更长时间 --- ## 📖 更新记录 ### V2.1(2025/10/14) - ✅ 右侧对话列表支持折叠 - ✅ 模型选择器动态加载已配置的模型 - ✅ MCP 服务集成基础架构完成 - ✅ 自动重连 MCP 服务器 - ✅ 完善的数据流和状态管理 ### V2.0(2025/10/14) - ✅ 左侧导航可折叠 - ✅ 右侧对话列表布局 - ✅ 完整工具栏 - ✅ 消息实时更新 - ✅ 消息条数修复 --- **优化完成!** 🎉 现在您可以: 1. ✅ 折叠对话列表获得更大空间 2. ✅ 使用已配置的任意模型对话 3. ✅ 选择 MCP 服务器(基础架构就绪) 继续完善 MCP 工具调用功能,敬请期待 V2.2!