26 Feb, 2026
1 commit
-
- **统一并增强 thinking/reasoning 处理的请求参数逻辑(`shopping_agent.py`)** - 新增基础工具函数用于判断不同 provider 类型: - `_normalize_base_url(base_url)`:标准化 `openai_api_base_url`(去空格与尾部 `/`),避免字符串比较不一致。 - `_is_openai_official_base_url(base_url)`:通过 hostname 判断是否为官方 `api.openai.com`,用于选择 Responses API。 - `_is_dashscope_base_url(base_url)`:通过 hostname 中是否包含 `dashscope` 来识别 DashScope 兼容模式。 - 在 `ShoppingAgent.__init__` 中基于 `base_url` 与 `openai_use_reasoning` 做**分支处理**,确保不同 provider 下的思考模式启用方式正确且互不干扰: - **OpenAI 官方(含未显式配置 base_url 的默认情况)**: - 当 `openai_use_reasoning=True` 且 `base_url` 为空或指向 `api.openai.com` 时: - 启用 `llm_kwargs["use_responses_api"] = True`,切换到 OpenAI Responses API。 - 设置 `llm_kwargs["model_kwargs"] = {"reasoning": {"effort": <配置>, "summary": "none"}}`,与官方 reasoning 参数保持一致。 - **DashScope OpenAI 兼容接口**: - 当 `openai_use_reasoning=True` 且 `base_url` 解析为 DashScope 域名时: - 在请求体中合并注入 `extra_body={"enable_thinking": True}`(保留已有 `extra_body` 字段),按照 DashScope 官方建议开启 Qwen3/QwQ 的思考模式。 - 不启用 Responses API,依然使用标准 `/chat/completions` 接口,符合 DashScope 兼容模式要求。 - **其他第三方 OpenAI 兼容服务**: - 当 `openai_use_reasoning=True` 且 `base_url` 既非 OpenAI 官方也非 DashScope 时: - 不再强行附加任何 provider 特定的 thinking 参数,仅记录一条 info 级别日志说明「请求了 reasoning,但当前 base_url 不识别为 OpenAI 或 DashScope,故跳过 provider-specific 参数」,避免潜在 4xx 报错或不可预期行为。 - 根据 provider 选择不同的 LLM 类: - 对于 **OpenAI 官方 endpoint**(包括默认未设置 `base_url` 时)仍使用原始 `ChatOpenAI`。 - 对于 **任何非 OpenAI 官方的 base_url**(包含 DashScope 和其他兼容实现),统一使用扩展后的 `ChatOpenAIWithReasoningContent`,保证即使未来有更多兼容服务返回 `reasoning_content` 字段,也能统一注入 `additional_kwargs`。 - **扩展 LLM 响应中的 thinking/reasoning 提取与日志记录(`shopping_agent.py`)** - 新增 `_coerce_reasoning_text(value)` 辅助函数,对多种结构的 reasoning 返回进行**鲁棒的文本提取**: - 支持 `str`、`dict`、`list` 等多种结构: - 对 `dict` 优先尝试聚合 `content` / `summary` / `text` / `reasoning_content` 字段; - 对 `list` 递归调用自身并按行拼接; - 当无法结构化提取时,兜底使用 `json.dumps(..., ensure_ascii=False)` 或 `str(value)`,避免因结构变更导致完全丢失思考信息。 - 在 `_extract_thinking(msg)` 中统一使用 `_coerce_reasoning_text`,大幅提高对不同模型/接口返回格式的兼容性: - 优先从 `msg.additional_kwargs["reasoning_content"]` 中提取(DashScope/Qwen 官方推荐字段)并返回。 - 其次从 `msg.additional_kwargs["reasoning"]` 中提取(OpenAI Responses API reasoning 对象)。 - 再次遍历 `msg.content` 为 list 的情况,识别 `type` 为 `"reasoning" / "reasoning_content" / "thinking"` 的内容块,并通过 `_coerce_reasoning_text` 提取文本。 - 最后对于纯字符串 content,通过 `_RE_THINK_INNER` 正则匹配 `<think>...</think>` 包裹的思考片段,只返回标签内正文。 - 在 `_message_for_log` 中增加 `include_thinking` 开关: - 当 `include_thinking=True` 时: - 调用 `_extract_thinking(msg)` 获取思考内容,并做长度截断(超过 `_LOG_CONTENT_MAX` 时尾部追加 `[truncated, total N chars]` 标记),然后写入 `out["thinking"]` 字段。 - 日志中区分「正式回复」与「thinking」两个字段,便于后续排查与分析。 - 调整 `_message_for_log` 对「是否需要走 `_extract_formal_reply`」的判断逻辑: - 如 `msg.additional_kwargs` 中存在 `reasoning` 或 `reasoning_content` 字段,则通过 `_extract_formal_reply` 去掉 thinking,只保留正式回复文本; - 否则直接使用 `_extract_message_text` 减少不必要处理。 - 在 LangGraph 的 `agent_node` 中,将 LLM 响应的日志调用更新为: - `response_log = _message_for_log(response, include_thinking=True)` - 确保每条 `LLM_RESPONSE` 日志都尽量带有 `"thinking"` 字段(在模型真实返回思考内容的前提下),方便线上观测与调试。 - **为兼容模式增加 `reasoning_content` 注入支持(`shopping_agent.py`)** - 新增 `ChatOpenAIWithReasoningContent` 子类,继承自 `ChatOpenAI`,重写 `_create_chat_result`: - `super()._create_chat_result(response, generation_info)` 后,通过原始 `response`(`dict` 或包含 `model_dump()` 的对象)提取 `choices[i].message.reasoning_content`。 - 对于每个 choice,如存在 `reasoning_content` 字段,则将其写入对应 `AIMessage` 的 `additional_kwargs["reasoning_content"]` 中。 - 该注入逻辑是幂等的、仅在字段存在时生效,对不返回 reasoning_content 的模型/服务没有副作用。 - 该子类专门用于 DashScope 及未来可能返回 `reasoning_content` 的其他兼容 provider,将 provider 特定逻辑集中在一处,方便维护。 - **补充与修正与 thinking 相关的正则和提取逻辑(`shopping_agent.py`)** - 在原有 `_RE_THINK_TAGS` 基础上新增加 `_RE_THINK_INNER`: - `_RE_THINK_TAGS`:用于从完整回复中移除 `<think>...</think>` 块,供 `_extract_formal_reply` 使用。 - `_RE_THINK_INNER`:用于仅提取 `<think>...</think>` 标签内部正文,供 `_extract_thinking` 使用,避免日志中重复包含标签本身。 - **更新配置注释以匹配新的 reasoning 行为(`config.py`)** - 改写 `openai_use_reasoning` 的注释,使其准确描述在不同 provider 下的启用方式: - OpenAI 官方 endpoint(含 `api.openai.com` base_url):通过 Responses API 的 `reasoning` 参数启用思考模式。 - DashScope 兼容 endpoint:通过 `extra_body.enable_thinking=True` 开启思考模式,由模型返回 `reasoning_content`。 - 将 `openai_use_reasoning` 默认值设置为 `True`,以便在满足条件时自动启用 reasoning,同时由上游配置控制具体是否生效。
21 Feb, 2026
2 commits
18 Feb, 2026
1 commit
-
2. add web sch tools
12 Feb, 2026
3 commits