From 3f7df28423fd3c5f028a25efa7440c4646a5846b Mon Sep 17 00:00:00 2001 From: xiaoli-cli bot Date: Tue, 23 Jun 2026 09:59:08 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=80=9A=E7=94=A8=E6=B7=B1=E5=BA=A6?= =?UTF-8?q?=E6=80=9D=E8=80=83=E9=80=82=E9=85=8D=20-=20=E5=8E=9F=E7=94=9FAP?= =?UTF-8?q?I=20+=20=E6=8F=90=E7=A4=BA=E8=AF=8D=E5=85=9C=E5=BA=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原生支持 (API参数): - DeepSeek/MiMo: enable_thinking + reasoning_effort - OpenAI o-series: reasoning.effort - Claude: thinking.type + budget_tokens (按等级分配2k/8k/32k) - Grok: thinking.enabled - Gemini thinking: 模型名自带 不支持原生的模型 (提示词注入): - low: 无额外提示词 - medium: 逐步思考提示 (分析→因素→方案→选择) - high: 工程级深度推理框架 (问题分解→多角度分析→方案设计→验证优化) 所有模型统一 /engine.openai think [on|off|low|medium|high] 控制 --- ai_engines/openai_engine.py | 94 ++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 12 deletions(-) diff --git a/ai_engines/openai_engine.py b/ai_engines/openai_engine.py index 9c50b5d..3a7108d 100644 --- a/ai_engines/openai_engine.py +++ b/ai_engines/openai_engine.py @@ -163,8 +163,19 @@ OpenAI 兼容格式引擎帮助信息 } # ── 深度思考模式 ── + self._inject_thinking_prompt = None # 清除标记 if self.deep_think: body = self._apply_deep_think(body) + # 不支持原生思考的模型,注入提示词 + if self._inject_thinking_prompt: + thinking_hint = self._get_thinking_prompt(self._inject_thinking_prompt) + if thinking_hint and messages: + # 追加到系统提示词末尾 + if messages[0].get("role") == "system": + messages[0]["content"] += thinking_hint + else: + messages.insert(0, {"role": "system", "content": thinking_hint}) + body["messages"] = messages # ── Function Calling: 注入工具定义 ── if tools: @@ -357,32 +368,91 @@ OpenAI 兼容格式引擎帮助信息 def _apply_deep_think(self, body: dict) -> dict: """ - 根据模型类型注入深度思考参数。 - 支持: - - DeepSeek / MiMo: enable_thinking + reasoning_content - - OpenAI o-series: reasoning.effort - - 通用: reasoning_effort + 通用深度思考适配。 + 原生支持的模型用 API 参数,不支持的用提示词模拟。 """ model = (self.model or "").lower() + effort = self.reasoning_effort # low / medium / high - # DeepSeek / MiMo 系列(格式相同) + # ── 原生支持:API 参数 ── + + # DeepSeek / MiMo if "deepseek" in model or "mimo" in model: body["enable_thinking"] = True body.pop("temperature", None) - # reasoning_effort 也支持 - if self.reasoning_effort: - body["reasoning_effort"] = self.reasoning_effort + if effort: + body["reasoning_effort"] = effort return body # OpenAI o-series (o1, o3, o4-mini 等) if model.startswith("o") and (model[1:2].isdigit() or model[1:3] in ("1-", "3-", "4-")): - body["reasoning"] = {"effort": self.reasoning_effort} + body["reasoning"] = {"effort": effort} return body - # 通用 - body["reasoning_effort"] = self.reasoning_effort + # Anthropic Claude (通过 OpenAI 兼容层) + if "claude" in model or "anthropic" in model: + body["thinking"] = {"type": "enabled", "budget_tokens": self._thinking_budget(effort)} + return body + + # Grok + if "grok" in model: + body["thinking"] = {"enabled": True} + return body + + # Gemini thinking 模型 + if "gemini" in model and "thinking" in model: + return body # 模型名自带 thinking,不需要额外参数 + + # ── 不支持原生思考:用提示词模拟 ── + self._inject_thinking_prompt = effort return body + @staticmethod + def _thinking_budget(effort: str) -> int: + """思考 token 预算""" + return {"low": 2048, "medium": 8192, "high": 32768}.get(effort, 8192) + + def _get_thinking_prompt(self, effort: str) -> str: + """根据思考等级生成提示词(注入系统提示词末尾)""" + if effort == "low": + return "" + + if effort == "medium": + return ( + "\n\n【思考模式:中等】\n" + "回答前请先逐步思考:\n" + "1. 分析用户的核心需求\n" + "2. 列出关键因素和约束\n" + "3. 考虑可能的方案\n" + "4. 选择最优方案并解释理由\n" + "然后再给出最终回答。" + ) + + # high + return ( + "\n\n【思考模式:深度推理】\n" + "你必须使用结构化深度推理框架回答问题。严格遵循以下步骤:\n\n" + "## 第一步:问题分解\n" + "- 将问题拆解为子问题\n" + "- 识别关键约束和边界条件\n" + "- 明确输入输出要求\n\n" + "## 第二步:多角度分析\n" + "- 从至少 3 个不同角度分析问题\n" + "- 评估每种方案的优缺点\n" + "- 考虑边界情况和异常场景\n\n" + "## 第三步:方案设计\n" + "- 选择最优方案并详细说明理由\n" + "- 给出具体的实现步骤\n" + "- 预判可能的问题并给出预防措施\n\n" + "## 第四步:验证与优化\n" + "- 检验方案是否满足所有约束\n" + "- 考虑是否有更优解\n" + "- 给出最终答案和注意事项\n\n" + "## 输出格式\n" + "先输出推理过程(用 [思考] 标记),再输出最终答案。\n" + "推理过程要详细但不啰嗦,最终答案要简洁明确。" + ) + def set_model(self, model_name): """设置模型""" self.model = model_name