diff --git a/pipeline_llm/inference.py b/pipeline_llm/inference.py index 2c2fcab..b287139 100644 --- a/pipeline_llm/inference.py +++ b/pipeline_llm/inference.py @@ -318,12 +318,16 @@ async def _call_upstream_chat(ctx, payload): return data except (asyncio.TimeoutError, aiohttp.ClientError) as e: last = e + # TimeoutError 的 str() 是空串,用 repr 保证消息真实可行动 + detail = repr(e) or type(e).__name__ + # print 确保进应用日志(模块 logger 未接应用日志管道,2026-09-04 实测) + print("[inference] 上游瞬时错误重试 %d/%d: %s (url=%s)" % ( + attempt + 1, _MAX_ATTEMPTS, detail, url.split('?')[0])) if attempt < _MAX_ATTEMPTS - 1: - logger.warning("inference: 瞬时错误重试 %d/%d: %s", - attempt + 1, _MAX_ATTEMPTS, e) await asyncio.sleep(2 * (attempt + 1)) continue - raise ValueError('上游调用失败(重试 %d 次仍失败): %s' % (_MAX_ATTEMPTS, e)) + raise ValueError('上游调用失败(重试 %d 次仍失败,%s): %s' % ( + _MAX_ATTEMPTS, type(e).__name__, detail)) raise last if last else ValueError('上游调用失败') @@ -346,12 +350,16 @@ async def chat_inference(org_id, user_id, payload, model_name='', task_ref=''): # 用途标记(辅助任务走辅助模型链):取出后从 payload 剥离,不透传给上游 purpose = (payload.pop('_purpose', '') or '') + # 单次调用超时覆盖(长文本提取等慢任务):剥离不透传,上限 900 秒 + req_timeout = int(_fnum(payload.pop('_timeout', 0)) or 0) est = max(_texts_len(payload.get('messages')) // EST_TOKENS_PER_CHAR, 200) db, dbname = _get_db() async with db.sqlorContext(dbname) as sor: ctx = await _resolve_call( sor, org_id, user_id or '', model_name, 't2t', est, task_ref, purpose) + if req_timeout > 0: + ctx['timeout'] = min(req_timeout, 900) try: data = await _call_upstream_chat(ctx, payload) except Exception as e: