From 692d348a26e475e6f6f040749077cf273324f9f7 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 1 Apr 2026 01:56:03 +0800 Subject: [PATCH 1/3] fix: support both Bailian Rerank API formats based on URL endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 阿里云百炼有两个不同的 rerank API 端点: - /compatible-api/v1/reranks: 使用扁平请求格式 {model, query, documents} - /api/v1/services/rerank/...: 需要 input 包装 {model, input: {...}} 之前代码只根据模型名判断格式,导致 qwen3-rerank + compatible-api 组合失败。 修复内容: - _build_payload(): 根据 URL 是否含 'compatible-api' 决定请求格式 - _parse_results(): 根据 URL 判断响应中 results 的位置 Fixes #7161 --- .../provider/sources/bailian_rerank_source.py | 64 ++++++++++++------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/astrbot/core/provider/sources/bailian_rerank_source.py b/astrbot/core/provider/sources/bailian_rerank_source.py index a515d2b9d2..aa15e714c6 100644 --- a/astrbot/core/provider/sources/bailian_rerank_source.py +++ b/astrbot/core/provider/sources/bailian_rerank_source.py @@ -88,9 +88,8 @@ def _build_payload( normalized_model = self.model.strip().lower() normalized_top_n = top_n if top_n is not None and top_n > 0 else None - # qwen3-rerank follows a model-specific payload: - # query/documents/top_n/instruct should be at the top level. - if normalized_model == self.QWEN3_RERANK_MODEL: + is_compatible_api = "compatible-api" in self.base_url + if normalized_model == self.QWEN3_RERANK_MODEL and is_compatible_api: payload = { "model": self.model, "query": query, @@ -107,16 +106,33 @@ def _build_payload( ) return payload - base = {"model": self.model, "input": {"query": query, "documents": documents}} - - params = { - k: v - for k, v in [ - ("top_n", normalized_top_n), - ("return_documents", True if self.return_documents else None), - ] - if v is not None - } + if is_compatible_api: + base = { + "model": self.model, + "query": query, + "documents": documents, + } + params = { + k: v + for k, v in [ + ("top_n", normalized_top_n), + ("return_documents", True if self.return_documents else None), + ] + if v is not None + } + else: + base = { + "model": self.model, + "input": {"query": query, "documents": documents}, + } + params = { + k: v + for k, v in [ + ("top_n", normalized_top_n), + ("return_documents", True if self.return_documents else None), + ] + if v is not None + } if params: base["parameters"] = params @@ -136,16 +152,20 @@ def _parse_results(self, data: dict) -> list[RerankResult]: BailianAPIError: API返回错误 KeyError: 结果缺少必要字段 """ - # 检查响应状态 - if data.get("code", "200") != "200": - raise BailianAPIError( - f"百炼 API 错误: {data.get('code')} – {data.get('message', '')}" - ) + is_compatible_api = "compatible-api" in self.base_url - results = data.get("output", {}).get("results", []) - if not results: - logger.warning(f"百炼 Rerank 返回空结果: {data}") - return [] + if is_compatible_api: + if data.get("code"): + raise BailianAPIError( + f"百炼 API 错误: {data.get('code')} – {data.get('message', '')}" + ) + results = data.get("results", []) + else: + if data.get("code", "200") != "200": + raise BailianAPIError( + f"百炼 API 错误: {data.get('code')} – {data.get('message', '')}" + ) + results = data.get("output", {}).get("results", []) # 转换为RerankResult对象,使用.get()避免KeyError rerank_results = [] From 12b2b9ea127b8641322051bdd1906e6127ecf819 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 1 Apr 2026 02:00:49 +0800 Subject: [PATCH 2/3] refactor: reduce duplication in bailian rerank payload and results handling - Extract params building outside the if-else branch - Add back empty results warning log - Simplify error handling variable assignment --- .../provider/sources/bailian_rerank_source.py | 56 ++++++++----------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/astrbot/core/provider/sources/bailian_rerank_source.py b/astrbot/core/provider/sources/bailian_rerank_source.py index aa15e714c6..d80606afb1 100644 --- a/astrbot/core/provider/sources/bailian_rerank_source.py +++ b/astrbot/core/provider/sources/bailian_rerank_source.py @@ -89,6 +89,7 @@ def _build_payload( normalized_top_n = top_n if top_n is not None and top_n > 0 else None is_compatible_api = "compatible-api" in self.base_url + if normalized_model == self.QWEN3_RERANK_MODEL and is_compatible_api: payload = { "model": self.model, @@ -106,36 +107,21 @@ def _build_payload( ) return payload + params = { + k: v + for k, v in [ + ("top_n", normalized_top_n), + ("return_documents", True if self.return_documents else None), + ] + if v is not None + } + if is_compatible_api: - base = { - "model": self.model, - "query": query, - "documents": documents, - } - params = { - k: v - for k, v in [ - ("top_n", normalized_top_n), - ("return_documents", True if self.return_documents else None), - ] - if v is not None - } + base = {"model": self.model, "query": query, "documents": documents} else: - base = { - "model": self.model, - "input": {"query": query, "documents": documents}, - } - params = { - k: v - for k, v in [ - ("top_n", normalized_top_n), - ("return_documents", True if self.return_documents else None), - ] - if v is not None - } - - if params: - base["parameters"] = params + base = {"model": self.model, "input": {"query": query, "documents": documents}} + if params: + base["parameters"] = params return base @@ -155,18 +141,24 @@ def _parse_results(self, data: dict) -> list[RerankResult]: is_compatible_api = "compatible-api" in self.base_url if is_compatible_api: - if data.get("code"): + code = data.get("code") + if code: raise BailianAPIError( - f"百炼 API 错误: {data.get('code')} – {data.get('message', '')}" + f"百炼 API 错误: {code} – {data.get('message', '')}" ) results = data.get("results", []) else: - if data.get("code", "200") != "200": + code = data.get("code", "200") + if code != "200": raise BailianAPIError( - f"百炼 API 错误: {data.get('code')} – {data.get('message', '')}" + f"百炼 API 错误: {code} – {data.get('message', '')}" ) results = data.get("output", {}).get("results", []) + if not results: + logger.warning(f"百炼 Rerank 返回空结果: {data}") + return [] + # 转换为RerankResult对象,使用.get()避免KeyError rerank_results = [] for idx, result in enumerate(results): From 5a2d242ee4dacc493ec4d2925af7352fa6101efb Mon Sep 17 00:00:00 2001 From: Fix Bot Date: Fri, 3 Apr 2026 18:26:03 +0800 Subject: [PATCH 3/3] fix: simplify bailian rerank payload to use model-based logic only qwen3-rerank always uses flat format regardless of API endpoint. Other models (gte-rerank-v2, etc.) use input wrapper format. This simplifies the logic and correctly handles all model/URL combinations. Tested: qwen3-rerank accepts both formats, gte-rerank-v2 only supports input wrapper. --- .../provider/sources/bailian_rerank_source.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/astrbot/core/provider/sources/bailian_rerank_source.py b/astrbot/core/provider/sources/bailian_rerank_source.py index d80606afb1..65356e100b 100644 --- a/astrbot/core/provider/sources/bailian_rerank_source.py +++ b/astrbot/core/provider/sources/bailian_rerank_source.py @@ -1,4 +1,5 @@ import os +from typing import Any import aiohttp @@ -88,9 +89,7 @@ def _build_payload( normalized_model = self.model.strip().lower() normalized_top_n = top_n if top_n is not None and top_n > 0 else None - is_compatible_api = "compatible-api" in self.base_url - - if normalized_model == self.QWEN3_RERANK_MODEL and is_compatible_api: + if normalized_model == self.QWEN3_RERANK_MODEL: payload = { "model": self.model, "query": query, @@ -107,6 +106,7 @@ def _build_payload( ) return payload + payload_input = {"query": query, "documents": documents} params = { k: v for k, v in [ @@ -116,12 +116,9 @@ def _build_payload( if v is not None } - if is_compatible_api: - base = {"model": self.model, "query": query, "documents": documents} - else: - base = {"model": self.model, "input": {"query": query, "documents": documents}} - if params: - base["parameters"] = params + base: dict[str, Any] = {"model": self.model, "input": payload_input} + if params: + base["parameters"] = params return base