把 Nano Banana 2 接入生产环境:超时、报错、重试和降级方案

把 Nano Banana 2 接入生产环境:超时、报错、重试和降级方案

Nano Banana 2 的 API 标注着 "Preview"。这两个字意味着:它可以用,但不保证稳定。

如果你只是在 AI Studio 里玩一玩,偶尔超时刷新一下就行了。但如果你要把它接入一个面向用户的生图服务——比如电商的自动海报生成、社交 App 的头像制作——你得提前想好出错时怎么办。

这篇文章整理了 Gemini 3.1 Flash Image Preview 在实际 API 调用中已知的稳定性问题,以及对应的工程化解决方案。

已知的稳定性问题

根据 GitHub issues 和开发者论坛的反馈,目前主要有这几类问题:

1. 偶发超时(约 5% 的请求)

Google 论坛上有开发者反馈,大约 5% 的请求会遇到 "fetch failed sending request" 错误。多数出现在复杂请求(长 Prompt、多模态输入、带参考图)时。

症状:请求发出后长时间无响应,最终返回超时错误。

原因推测:Preview 版本的后端资源分配不如 GA 版本稳定,高峰期可能出现队列拥堵。

2. SSL/TLS 连接错误

Gemini CLI 的用户报告过偶发的 ssl/tls alert bad record mac 错误,大约每小时出现一次。这类错误和请求内容无关,更像是网络层的问题。

3. 流式 + 工具调用组合不稳定

使用 gemini-3-flash-preview 模型时,如果同时开启了 Streaming 和 Tools,LLM 的响应可能返回空白。这是 ADK(AI Development Kit)里的一个已知 bug。

4. 安全过滤误伤

Google 的安全过滤比较保守。一些正常的商业场景描述(比如泳装产品图、医学图示)可能被标记为 FinishReason.SAFETY 而拒绝生成。

5. Rate Limit

Preview 版本的并发限制比较严。具体数值没有公开文档,但多个开发者反馈在 10 QPS 左右就开始被限流。

重试策略

对于超时和网络错误,重试是最直接的解决方案。但不能无脑重试。

指数退避 + 抖动

import time
import random

def generate_with_retry(model, prompt, config, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = model.generate_content(
                contents=[prompt],
                generation_config=config,
                request_options={"timeout": 60}
            )
            if response.parts:
                return response
        except Exception as e:
            if attempt == max_retries - 1:
                raise e
            wait = (2 ** attempt) + random.uniform(0, 1)
            print(f"Attempt {attempt + 1} failed: {e}. Retrying in {wait:.1f}s")
            time.sleep(wait)
    return None

要点:

  • 超时设置为 60 秒(默认可能太短,特别是 4K 图片)
  • 指数退避:第一次等 1-2 秒,第二次等 2-3 秒,第三次等 4-5 秒
  • 加随机抖动(jitter),避免多个客户端同时重试导致"重试风暴"
  • 最多重试 3 次。超过 3 次还失败,说明不是偶发问题

区分可重试和不可重试的错误

不是所有错误都应该重试:

错误类型 是否重试 处理方式
超时 指数退避重试
网络/SSL 错误 指数退避重试
Rate Limit (429) 等待更长时间后重试(按 Retry-After 头)
安全过滤 (SAFETY) 修改 Prompt 或调整 safety_settings
参数错误 (400) 修复请求参数
认证失败 (401/403) 检查 API Key

降级方案

重试解决的是偶发故障。如果模型整体不可用(比如大规模故障或被限流),需要降级方案。

方案一:分辨率降级

4K 生成失败时,自动降到 2K;2K 也失败,降到 1K。低分辨率的请求对后端压力更小,成功率更高。

sizes = ["4K", "2K", "1K", "512"]

def generate_with_fallback_size(model, prompt, sizes):
    for size in sizes:
        try:
            response = generate_with_retry(model, prompt, {"size": size})
            if response:
                print(f"Generated at {size}")
                return response
        except Exception:
            continue
    return None

方案二:模型降级

Nano Banana 2 失败时,切换到其他模型。比如用 Imagen 4 做兜底,或者用 DALL-E 3 做备选。

models = [
    ("gemini-3.1-flash-image-preview", "Nano Banana 2"),
    ("imagen-4.0-generate-001", "Imagen 4"),
]

def generate_with_fallback_model(prompt, config):
    for model_id, name in models:
        try:
            model = genai.GenerativeModel(model_id)
            response = generate_with_retry(model, prompt, config)
            if response:
                print(f"Generated with {name}")
                return response
        except Exception:
            continue
    return None

方案三:异步队列化

如果你的业务场景允许延迟返回(比如用户下单后 5 分钟内收到商品图),可以把生图请求放到消息队列里,后台 Worker 异步处理。

好处是:

  • 失败后可以自动重试,用户无感知
  • 可以控制并发数,避免触发 Rate Limit
  • 可以做优先级排序(VIP 用户的请求优先处理)

技术选型:Redis Queue、RabbitMQ、或者云厂商的消息服务(阿里云 MNS、AWS SQS)都可以。

可观测性

上线后你需要能实时看到系统状态。建议监控以下指标:

  • 成功率:过去 5 分钟的生图成功率,低于 90% 时告警
  • P99 延迟:正常情况下应该在 15 秒以内,超过 30 秒说明有问题
  • 错误分布:按错误类型分类统计(超时 / 限流 / 安全过滤 / 其他)
  • 降级触发次数:如果降级频繁触发,说明主模型不稳定,需要评估是否切换
  • 成本:每日/每周的 API 调用费用

用 Prometheus + Grafana 或者云厂商的监控服务(阿里云 ARMS、AWS CloudWatch)都能实现。

什么时候可以上生产?

Preview 模型上生产不是不行,但要做好几个准备:

  1. 重试 + 降级 + 队列化的完整链路
  2. 可观测性到位,能在问题扩大前发现
  3. 用户侧有"生成中"的等待状态,而不是直接卡死
  4. 有明确的 SLA 预期(比如:95% 的请求在 30 秒内返回结果,剩下 5% 可能需要 1-2 分钟)
  5. 和 Google 确认你的配额是否足够(Preview 版本的默认 QPS 较低,可能需要申请提升)

满足这些条件,Preview 模型就可以用于生产环境。模型本身的生成质量没问题,需要工程上补的是稳定性这一课。


参考链接

  1. GitHub Issue - Gemini CLI frequent API errors
  2. GitHub Issue - Streaming + Tools empty output
  3. Google AI Forum - Fetch failed sending request
  4. Gemini API Docs
  5. Google 官方博客 - Nano Banana 2
← 返回博客列表