From 7ed0ed9b80317abe854bcc49d03c4cc1faa1d8a5 Mon Sep 17 00:00:00 2001 From: ymq Date: Mon, 17 Aug 2026 18:43:37 +0800 Subject: [PATCH] =?UTF-8?q?fix(llm=5Fbridge):=20=E7=BD=91=E5=85=B3=20200?= =?UTF-8?q?=20=E4=BD=86=E6=97=A0=20choices=20=E7=9A=84=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=87=8D=E8=AF=95=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=20KeyError=20=E6=89=93=E5=B4=A9=E8=A7=92=E8=89=B2agent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit llmage 网关偶发返回 200 但内容无 choices(错误JSON),llm_call_msgs_native 的 data[choices] 直接 KeyError,导致 role_agent 任务失败并报人工介入。_post_chat_completion 对无 choices 的 200 响应视为可重试异常,重试后仍失败则 raise 带网关原始内容的 ValueError。 --- pipeline_service/llm_bridge.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pipeline_service/llm_bridge.py b/pipeline_service/llm_bridge.py index 37124c7..f333856 100644 --- a/pipeline_service/llm_bridge.py +++ b/pipeline_service/llm_bridge.py @@ -110,7 +110,17 @@ async def _post_chat_completion(url: str, headers: dict, payload: dict) -> dict: await asyncio.sleep(2 * (attempt + 1)) continue raise err - return await resp.json() + data = await resp.json() + # 网关偶发返回 200 但内容无 choices(错误 JSON),视为可重试的瞬时异常; + # 不处理会导致上层 llm_call_msgs_native 的 data["choices"] 抛 KeyError。 + if not isinstance(data, dict) or "choices" not in data: + err = ValueError("LLM 响应缺 choices: %s" % json.dumps(data, ensure_ascii=False)[:300]) + if attempt < _LLM_MAX_ATTEMPTS - 1: + last_exc = err + await asyncio.sleep(2 * (attempt + 1)) + continue + raise err + return data except (asyncio.TimeoutError, aiohttp.ClientError) as e: last_exc = e if attempt < _LLM_MAX_ATTEMPTS - 1: