diff --git a/backend/python/app/api/chat.py b/backend/python/app/api/chat.py
index 98b78b5..1df62c3 100644
--- a/backend/python/app/api/chat.py
+++ b/backend/python/app/api/chat.py
@@ -239,6 +239,49 @@ async def _optimize_media_prompt(raw_prompt: str, media_type: str, db=None) -> s
return stripped
+def _friendly_media_err(kind: str, raw: str) -> str:
+ """把 AGNES 原始错误转译为对用户友好的中文。
+
+ AGNES 常见错误:429 限频(每分钟1次视频) / Server disconnected(连接重置) /
+ publish_video_queue_failed + context deadline exceeded(队列超时)。这些都不是
+ 平台代码问题,统一给出可操作的提示,不把原始 HTTP/JSON 甩给用户。
+ """
+ r = (raw or "").lower()
+ if "429" in raw or "rate limit" in r:
+ return (f"⚠️ {kind}生成请求过于频繁(AGNES 限制每分钟 1 次),"
+ f"请稍等 1 分钟后再试。")
+ if "server disconnected" in r or "连接" in raw or "reset" in r:
+ return f"⚠️ {kind}生成服务暂时连接失败,请稍后重试。"
+ if "publish_video" in r or "queue" in r or "deadline" in r or "context" in r:
+ return f"⚠️ {kind}生成队列繁忙(AGNES 处理超时),请稍后重试。"
+ return f"⚠️ {kind}生成失败(请稍后重试):{(raw or '')[:120]}"
+
+
+async def _agnes_post_json(api_url: str, headers: dict, payload: dict, timeout) -> tuple:
+ """直连 AGNES 发 POST,对 5xx / 连接中断做指数退避重试。
+
+ AGNES 视频/图像队列极不稳定:经常返回 500 publish_video_queue_failed /
+ context deadline exceeded,或连接被重置(Server disconnected)。这类错误是 AGNES
+ 侧瞬时抖动,重试通常立刻成功。4xx(参数错误)不重试,直接返回。
+ 返回 (resp, err):成功(resp.status_code<500) 时 err=None;耗尽重试时 resp=None。
+ """
+ last_err = None
+ for attempt in range(3):
+ try:
+ async with httpx.AsyncClient(
+ timeout=timeout, proxy=_proxy_for_url(api_url), trust_env=False
+ ) as client:
+ resp = await client.post(api_url, headers=headers, json=payload)
+ if resp.status_code < 500:
+ return resp, None
+ last_err = f"HTTP {resp.status_code}: {resp.text[:200]}"
+ except Exception as e:
+ last_err = str(e)[:200]
+ if attempt < 2:
+ await asyncio.sleep(2 * (attempt + 1))
+ return None, last_err
+
+
async def _generate_media(db, ai_model, prompt: str, user_id: str = None) -> str:
"""图像/视频生成模型统一入口:按 capabilities 调用 AGNES 等媒体生成 API。
返回可直接在 AI 聊天中渲染的富文本(含
/