# 开发日志 - 2026-03-06 ## 修复:深度思考内容不显示 ### 问题描述 启用深度思考后,后端日志显示已启用深度思考功能,但前端没有显示深度思考内容。 ### 根本原因 前端 `src/services/api.ts` 中的 `streamChat` 方法只处理了普通 `content`,完全忽略了后端返回的 `reasoning_content`(深度思考内容)。 ### 解决方案 #### 1. 前端 `src/services/api.ts` 添加 `StreamChunk` 接口,区分内容类型: ```typescript // 流式响应块类型 export interface StreamChunk { type: "content" | "reasoning"; text: string; } ``` 修改 `streamChat` 方法同时处理两种内容: ```typescript const delta = data.choices?.[0]?.delta; // 处理深度思考内容(reasoning_content) const reasoningContent = delta?.reasoning_content; if (reasoningContent) { yield { type: "reasoning", text: reasoningContent }; } // 处理普通内容 const content = delta?.content; if (content) { yield { type: "content", text: content }; } ``` #### 2. 前端 `src/components/chat/ChatMain.vue` 修改流式处理逻辑,将 `reasoning` 类型内容包装成 `` 标签: ```typescript let isInReasoning = false; for await (const chunk of stream) { if (chunk.type === "reasoning") { if (!isInReasoning) { isInReasoning = true; fullText += "\n"; } fullText += chunk.text; } else { if (isInReasoning) { isInReasoning = false; fullText += "\n\n"; } fullText += chunk.text; } } // 如果最后还在深度思考块中,关闭它 if (isInReasoning) { fullText += "\n"; } ``` `` 标签会被 `markstream-vue` 库识别,并由 `ThinkingNode` 组件渲染。 --- ## 功能:图片/文件附件自动切换模型 ### 需求 当用户上传图片或文件(PDF、DOCX等)时,无论前端选择了什么模型,后端都应强制使用 `glm-4.6v` 模型(支持多模态)。 ### 解决方案 #### 后端 `server/adapters/glm_adapter.py` **修改 `_build_messages` 方法**: 返回值从 `(messages, has_vision)` 改为 `(messages, has_vision, has_files)`: ```python def _build_messages( self, request: ChatCompletionRequest ) -> tuple[List[Dict], bool, bool]: """ 构建 GLM 格式的消息 返回:(消息列表, 是否包含图片, 是否包含文件附件) """ messages = [] has_vision = False has_files = bool(request.files) # 检查是否有文件附件 # ... 处理消息 ... return messages, has_vision, has_files ``` **修改 `_resolve_model` 方法**: ```python def _resolve_model(self, model: str, has_vision: bool, has_files: bool = False) -> str: """解析实际使用的模型""" model_lower = model.lower() # 如果有图片或文件附件,强制使用 glm-4.6v(支持多模态) if (has_vision or has_files) and model_lower not in VISION_MODELS: logger.info( f"[GLM] 检测到图片或文件附件,强制切换模型: {model} -> glm-4.6v" ) return "glm-4.6v" return model ``` **修改 `chat` 方法调用**: ```python glm_messages, has_vision, has_files = self._build_messages(request) actual_model = self._resolve_model(request.model, has_vision, has_files) ``` --- ## 功能:DeepSeek 深度思考支持 ### 需求 为 DeepSeek 的 `deepseek-reasoner` 模型添加深度思考支持,通过 `extra_body` 参数启用。 ### 解决方案 #### 后端 `server/adapters/openai_adapter.py` **添加支持深度思考的模型列表**: ```python # DeepSeek 支持深度思考的模型 DEEPSEEK_THINKING_MODELS = {"deepseek-reasoner"} ``` **修改 `chat` 方法**: ```python # DeepSeek 深度思考支持 extra_body = None if self._provider_type == "deepseek" and request.deep_thinking: if self._supports_thinking(request.model): extra_body = {"thinking": {"type": "enabled"}} kwargs["extra_body"] = extra_body logger.info(f"[{provider_name}] 深度思考已启用: extra_body = {extra_body}") ``` **添加 `_supports_thinking` 方法**: ```python def _supports_thinking(self, model: str) -> bool: """检查模型是否支持深度思考""" return model.lower() in DEEPSEEK_THINKING_MODELS ``` **修改 `_stream_chat` 和 `_sync_chat` 方法**: - 添加 `extra_body` 参数 - 增强 `reasoning_content` 日志输出 --- ## 功能:模型列表从后端动态获取 ### 需求 前端模型选择器中的模型列表改为从后端 API 获取,而非硬编码。 ### 解决方案 #### 前端 `src/services/api.ts` 修改 `getModels` 方法,调用后端 API: ```typescript async getModels(): Promise { try { const response = await fetch(`${this.baseUrl}${API_ENDPOINTS.MODELS}`, { method: "GET", headers: { "Content-Type": "application/json", }, }); if (!response.ok) { throw new Error(`获取模型列表失败: HTTP ${response.status}`); } const data = await response.json(); // 后端返回格式: { object: "list", data: [...] } return data.data || []; } catch (error) { console.error("获取模型列表失败:", error); // 返回默认模型列表作为降级 return [...]; } } ``` #### 后端 `server/main.py` 已有 `/api/chat-ui/models` 端点: ```python @app.get("/api/chat-ui/models") async def get_models(): """模型列表(聚合所有可用平台的模型)""" from adapters import get_all_adapters all_models = [] for provider, adapter in get_all_adapters().items(): if adapter.is_available(): models = adapter.list_models() all_models.extend([m.to_dict() for m in models]) return {"object": "list", "data": all_models} ``` #### 特点 - **动态聚合**:自动聚合所有已配置 API Key 的平台模型 - **按需显示**:只有配置了 API Key 的平台才会显示模型 - **降级处理**:API 获取失败时返回默认模型列表 --- ## 涉及文件 | 文件 | 修改类型 | |------|----------| | `src/services/api.ts` | 新增 `StreamChunk` 接口,修改 `streamChat` 方法,修改 `getModels` 方法 | | `src/components/chat/ChatMain.vue` | 修改流式处理逻辑,支持 `reasoning` 类型 | | `server/adapters/glm_adapter.py` | 修改 `_build_messages` 和 `_resolve_model` 方法 | | `server/adapters/openai_adapter.py` | 添加 DeepSeek 深度思考支持 | --- ## 测试建议 1. **GLM 深度思考测试**: - 选择支持深度思考的模型(如 glm-4.6v) - 开启深度思考开关 - 发送问题,确认前端显示深度思考内容块 2. **DeepSeek 深度思考测试**: - 选择 `deepseek-reasoner` 模型 - 开启深度思考开关 - 发送问题,确认后端日志显示 `extra_body = {'thinking': {'type': 'enabled'}}` - 确认前端显示深度思考内容块 3. **模型自动切换测试**: - 选择非多模态模型(如 glm-4-flash) - 上传图片或 PDF 文件 - 确认后端日志显示模型切换为 glm-4.6v - 确认多模态内容正确处理 4. **模型列表动态获取测试**: - 检查前端控制台,确认调用了 `/api/chat-ui/models` - 确认模型选择器显示后端返回的模型列表 - 停止后端服务,确认降级模型列表正常显示