# MCP Client Vue - 架构文档 > 本文档描述了 MCP Client Vue 项目的整体架构设计、技术栈、数据流和关键设计决策。 **更新时间**: 2025-10-16 **版本**: v2.0(重构后) --- ## 📋 目录 1. [项目概述](#项目概述) 2. [技术栈](#技术栈) 3. [目录结构](#目录结构) 4. [架构设计](#架构设计) 5. [数据流](#数据流) 6. [核心服务](#核心服务) 7. [关键设计决策](#关键设计决策) 8. [扩展指南](#扩展指南) --- ## 项目概述 MCP Client Vue 是一个基于 Vue 3 + TypeScript 的 MCP (Model Context Protocol) 客户端应用,支持: - 多模型服务管理(阿里通义、火山方舟等) - 流式对话交互 - MCP 工具调用与编排 - 对话历史持久化 - 主题与显示设置 --- ## 技术栈 ### 前端框架 - **Vue 3.4.15** - 使用 Composition API - **TypeScript 5.3.3** - 类型安全 - **Vite 5.x** - 构建工具 - **Pinia** - 状态管理 ### UI 组件库 - **Naive UI 2.43.1** - 企业级 Vue 3 组件库 ### 数据持久化 - **localStorage** - 当前话题、对话历史、配置 - **IndexedDB (未来)** - 大量数据存储 ### 后端集成 - **MCP Protocol** - 工具调用协议 - **OpenAI-Compatible API** - 统一模型接口 --- ## 目录结构 ``` mcp-client-vue/ ├── web/ # 前端应用 │ ├── src/ │ │ ├── components/ # UI 组件 │ │ │ ├── Chat/ # 聊天相关组件 │ │ │ ├── Settings/ # 设置相关组件 │ │ │ └── Common/ # 通用组件 │ │ ├── services/ # 业务服务层 │ │ │ ├── chat/ # 聊天服务(重构后) │ │ │ │ ├── MessageService.ts │ │ │ │ ├── ConversationService.ts │ │ │ │ ├── StreamProcessor.ts │ │ │ │ ├── ToolExecutor.ts │ │ │ │ ├── ChatOrchestrator.ts │ │ │ │ └── index.ts │ │ │ ├── modelServiceManager.ts │ │ │ └── MCPClientService.ts │ │ ├── stores/ # Pinia 状态管理 │ │ │ ├── chatStore.ts │ │ │ ├── modelStore.ts │ │ │ └── mcpStore.ts │ │ ├── types/ # TypeScript 类型定义 │ │ │ ├── chat.ts │ │ │ ├── model.ts │ │ │ └── mcp.ts │ │ ├── utils/ # 工具函数 │ │ │ ├── logger.ts # 统一日志系统 │ │ │ ├── error.ts # 错误处理体系 │ │ │ └── index.ts │ │ ├── views/ # 页面视图 │ │ ├── App.vue # 根组件 │ │ └── main.ts # 入口文件 │ ├── public/ # 静态资源 │ └── package.json ├── src/ # 后端服务(Node.js) │ ├── server/ │ │ ├── index.ts │ │ ├── LLMService.ts │ │ └── MCPManager.ts │ └── types/ ├── docs/ # 文档 │ ├── ARCHITECTURE.md # 本文档 │ ├── CHAT_V2.1_QUICKSTART.md │ └── ... ├── README.md └── package.json ``` --- ## 架构设计 ### 整体架构 ``` ┌─────────────────────────────────────────────────────────┐ │ 用户界面层 (UI) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 聊天视图 │ │ 设置视图 │ │ 模型管理 │ │ MCP管理 │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────┘ ↓ ↑ ┌─────────────────────────────────────────────────────────┐ │ 状态管理层 (Pinia Stores) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │chatStore │ │modelStore│ │ mcpStore │ │ │ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────┘ ↓ ↑ ┌─────────────────────────────────────────────────────────┐ │ 业务服务层 (Services) │ │ ┌─────────────────────────────────────────────────────┐│ │ │ ChatOrchestrator (协调器) ││ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ││ │ │ │ Message │ │Conversation│ │ Stream │ ││ │ │ │ Service │ │ Service │ │ Processor │ ││ │ │ └────────────┘ └────────────┘ └────────────┘ ││ │ │ ┌────────────┐ ││ │ │ │ Tool │ ││ │ │ │ Executor │ ││ │ │ └────────────┘ ││ │ └─────────────────────────────────────────────────────┘│ │ ┌──────────────┐ ┌──────────────┐ │ │ │ModelService │ │MCPClientSvc │ │ │ │ Manager │ │ │ │ │ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────┘ ↓ ↑ ┌─────────────────────────────────────────────────────────┐ │ 工具层 (Utils) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Logger │ │ Error │ │Validation│ │ │ │ │ │ Handler │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────┘ ↓ ↑ ┌─────────────────────────────────────────────────────────┐ │ 数据持久化层 (Storage) │ │ ┌──────────┐ ┌──────────┐ │ │ │localStorage│ │IndexedDB │ (未来) │ │ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────┘ ↓ ↑ ┌─────────────────────────────────────────────────────────┐ │ 后端服务 (Node.js) │ │ ┌──────────┐ ┌──────────┐ │ │ │LLMService│ │MCPManager│ │ │ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────┘ ↓ ↑ ┌─────────────────────────────────────────────────────────┐ │ 外部服务 (External APIs) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │阿里通义 │ │ 火山方舟 │ │MCP Servers│ │ │ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────┘ ``` --- ## 数据流 ### 发送消息流程 ``` 用户输入消息 ↓ ChatLayout 组件触发事件 ↓ chatStore.sendMessage() ↓ ChatOrchestrator.sendMessageStream() ↓ 1. MessageService 创建用户消息 2. 更新话题信息 3. 持久化到 localStorage ↓ 4. MessageService 创建助手消息占位符 ↓ 5. StreamProcessor.processStream() ├─ 准备工具列表(如有 MCP) ├─ 准备上下文消息(限制 20 条) ├─ 选择服务和模型 └─ 执行流式请求 ↓ 6. 流式响应 onChunk 回调 └─ MessageService.appendMessageContent() └─ 触发 UI 更新 ↓ 7. 检查是否有工具调用 └─ 是: ToolExecutor.executeToolCalls() ├─ 执行每个工具 ├─ 收集工具结果 └─ 发送结果给 AI(递归) └─ 否: 完成 ↓ 8. 更新消息状态为 'success' 9. 更新话题最后消息 10. 持久化 ↓ UI 展示最终消息 ``` --- ## 核心服务 ### 1. ChatOrchestrator(聊天协调器) **职责**: - 统一对外接口 - 协调各服务完成业务流程 - 管理话题和对话 - 处理持久化 **核心方法**: ```typescript class ChatOrchestrator { // 话题管理 createTopic(name: string, options?: CreateTopicOptions): Topic getTopics(filter?: TopicFilter): Topic[] updateTopic(topicId: string, updates: Partial): boolean deleteTopic(topicId: string): boolean // 消息管理 getMessages(topicId: string): Message[] deleteMessage(topicId: string, messageId: string): boolean // 发送消息 sendMessageStream( options: SendMessageOptions, onChunk: (event: StreamEvent) => void, mcpServerId?: string, signal?: AbortSignal ): Promise // 重新生成 regenerateMessage(topicId: string, messageId: string): Promise // 持久化 private saveTopics(): void private loadTopics(): void private saveConversations(): void private loadConversations(): void } ``` --- ### 2. MessageService(消息服务) **职责**: - 消息 CRUD - 消息状态管理 - 消息查询和过滤 **核心方法**: ```typescript class MessageService { createMessage(conversationId: string, options: CreateMessageOptions): Message getMessages(conversationId: string): Message[] getMessagesByTopicId(topicId: string): Message[] updateMessage(conversationId: string, messageId: string, options: UpdateMessageOptions): boolean updateMessageStatus(conversationId: string, messageId: string, status: MessageStatus): boolean appendMessageContent(conversationId: string, messageId: string, content: string): boolean deleteMessage(conversationId: string, messageId: string): boolean deleteMessagesAfter(conversationId: string, messageId: string): boolean getSuccessMessages(conversationId: string): Message[] getRecentSuccessMessages(conversationId: string, limit: number): Message[] } ``` --- ### 3. ConversationService(对话服务) **职责**: - 对话创建、读取、删除 - 对话元数据管理 - 对话与话题的关联 **核心方法**: ```typescript class ConversationService { createConversation(options: CreateConversationOptions): Conversation getConversation(conversationId: string): Conversation | undefined getConversationByTopicId(topicId: string): Conversation | undefined deleteConversation(conversationId: string): boolean deleteConversationByTopicId(topicId: string): boolean updateMetadata(conversationId: string, metadata: Partial): boolean clearMessages(conversationId: string): boolean } ``` --- ### 4. StreamProcessor(流式处理器) **职责**: - 处理流式响应 - 性能监控 - 批量输出 - 工具集成 **核心方法**: ```typescript class StreamProcessor { async processStream(options: StreamOptions): Promise private prepareTools(mcpServerId?: string): Promise<{ tools: any[], mcpServerName: string }> private prepareMessages(conversation: Conversation, tools: any[], mcpServerName: string): any[] private selectServiceAndModel(requestedModel?: string): { service: any, selectedModel: string } private executeStream(...): Promise } ``` **特性**: - 上下文限制:最近 20 条消息 - 批量输出:每 3 个字符一次(增强流式效果) - 性能监控:首字延迟、总耗时、chunk 数 - 工具集成:自动注入系统提示词 --- ### 5. ToolExecutor(工具执行器) **职责**: - 解析工具调用请求 - 执行 MCP 工具 - 处理工具结果 - 支持递归工具链 **核心方法**: ```typescript class ToolExecutor { async executeToolCalls(options: ToolCallOptions): Promise private executeTools(toolCalls: any[], mcpServerId: string, onChunk: Function): Promise private executeSingleTool(toolCall: any, mcpServerId: string, onChunk: Function): Promise private sendToolResultsToAI(...): Promise private buildMessagesWithToolResults(...): any[] } ``` **特性**: - 递归工具链:AI 可以连续调用多个工具 - 错误恢复:单个工具失败不影响其他工具 - 用户反馈:实时显示工具执行状态 --- ## 关键设计决策 ### 1. 为什么拆分 chatService? **原因**: - 原 `chatService.ts` 1147 行,职责过多(消息、对话、流式、工具、持久化) - 难以测试和维护 - 修改一处可能影响多处 **收益**: - 单一职责,每个服务 < 300 行 - 可独立测试 - 易于扩展和复用 --- ### 2. 为什么使用 localStorage 而不是 IndexedDB? **当前选择**:localStorage **原因**: - 数据量小(< 10MB) - 实现简单 - 同步 API,无需处理异步 **未来计划**: - 当对话历史 > 1000 条时,迁移到 IndexedDB - 支持全文搜索 - 支持分页加载 --- ### 3. 为什么限制上下文为 20 条消息? **原因**: - 模型 token 限制(Qwen-plus 30K tokens) - 减少网络传输 - 提高响应速度 **计算**: - 平均每条消息 500 tokens - 20 条 = 10K tokens - 留出 20K tokens 用于响应和工具调用 --- ### 4. 为什么使用批量输出(BATCH_SIZE = 3)? **原因**: - 减少 UI 更新频率 - 增强流式效果(视觉上更流畅) - 降低性能开销 **效果**: - 每 3 个字符触发一次 UI 更新 - 减少 60%+ 的重渲染 --- ### 5. 为什么工具调用使用递归? **原因**: - AI 可能需要多次工具调用才能完成任务 - 例如:查询天气 → 发现位置错误 → 查询正确位置 → 返回天气 **实现**: ```typescript async executeToolCalls() { // 1. 执行当前工具 const results = await this.executeTools() // 2. 发送结果给 AI const response = await this.sendToAI(results) // 3. 检查是否有新的工具调用 if (response.toolCalls) { // 递归调用 await this.executeToolCalls({ ...options, toolCalls: response.toolCalls }) } } ``` --- ### 6. 统一日志和错误处理 **Logger**: ```typescript // 开发环境:显示所有日志 // 生产环境:只显示 WARN 和 ERROR const log = logger.namespace('ChatService') log.debug('详细调试信息') // 开发环境可见 log.info('普通信息') // 开发环境可见 log.warn('警告') // 生产环境可见 log.error('错误', error) // 生产环境可见 ``` **AppError**: ```typescript // 统一错误类型 throw new ValidationError('消息内容不能为空') throw new ServiceError('流式请求失败', ErrorCode.STREAMING_ERROR) throw new NetworkError('网络连接失败') // 统一错误处理 try { await operation() } catch (error) { const appError = handleError(error) log.error(appError.message, appError) notification.error({ title: '操作失败', description: appError.message }) } ``` --- ## 扩展指南 ### 添加新的模型服务 1. 在 `modelServiceManager.ts` 中注册服务 2. 实现 OpenAI-compatible API 接口 3. 配置 API Key 和 Base URL ### 添加新的 MCP 服务器 1. 配置 MCP 服务器信息(地址、认证) 2. 在 `MCPClientService.ts` 中连接 3. 工具会自动注入到 AI 上下文 ### 添加新的聊天功能 1. 在对应的 Service 中实现逻辑 2. 在 ChatOrchestrator 中暴露接口 3. 在 chatStore 中调用 4. 在 UI 组件中使用 ### 性能优化建议 1. **虚拟滚动**:长对话使用 `vue-virtual-scroller` 2. **消息分页**:一次只加载最近 50 条 3. **数据库索引**:IndexedDB 添加 `topicId + timestamp` 复合索引 4. **请求缓存**:模型信息缓存 5 分钟 ### 测试建议 1. **单元测试**:每个 Service 独立测试 2. **集成测试**:测试 ChatOrchestrator 的完整流程 3. **E2E 测试**:使用 Playwright 测试关键用户路径 --- ## 参考资料 - [Vue 3 官方文档](https://vuejs.org/) - [Pinia 状态管理](https://pinia.vuejs.org/) - [Naive UI 组件库](https://www.naiveui.com/) - [MCP Protocol](https://modelcontextprotocol.io/) - [OpenAI API Reference](https://platform.openai.com/docs/api-reference) --- ## 更新日志 ### 2025-10-16 - v2.0(重构版) - ✅ 拆分 chatService 为 5 个独立服务 - ✅ 添加统一日志系统(Logger) - ✅ 添加错误处理体系(AppError) - ✅ 优化流式处理性能 - ✅ 支持递归工具调用链 ### 2024-XX-XX - v1.0 - 初始版本 - 基本的聊天功能 - MCP 工具调用支持 --- **维护者**: Gavin **最后更新**: 2025-10-16