Claude Opus 5.5 è disponibile su SeedRouter

Nano Banana Pro in Claude Code: uno skill che genera e modifica immagini

Dai a Claude Code uno skill Nano Banana Pro: un piccolo script che invia la richiesta, esegue il polling dell'attività e salva l'immagine, più un file SKILL.md.

Leggi in Markdown

Claude Code può generare e modificare immagini con Nano Banana Pro tramite uno skill: una cartella con un file SKILL.md e un breve script che chiama l'API di SeedRouter. Digiti /nano-banana-pro e descrivi l'immagine; Claude scrive il prompt ed esegue lo script, che invia la richiesta, esegue il polling dell'attività e salva l'immagine nel tuo progetto. La stessa cartella funziona anche in OpenAI Codex. SeedRouter non fornisce uno skill ufficiale né un server MCP, quindi questa guida te ne dà uno da copiare. Il formato dello skill segue la documentazione di Anthropic e OpenAI, verificata il 29 settembre 2026.

Come fa Claude Code a creare immagini con Nano Banana Pro?

Claude Code non disegna immagini da solo. Esegue comandi, quindi può eseguire uno script che chiama un'API per immagini. Con uno skill installato, una richiesta si svolge così:

  1. Richiami lo skill e descrivi l'immagine, per esempio /nano-banana-pro a hero image for the pricing page.
  2. Claude trasforma la tua descrizione in un prompt per Nano Banana Pro e sceglie dimensione e proporzioni.
  3. Esegue lo script. Lo script invia la richiesta a POST https://api.seedrouter.ai/v1/images/generations e riceve un ID attività.
  4. Lo script interroga GET /v1/tasks/{id} ogni pochi secondi finché l'immagine non è pronta, poi la scarica in una cartella images/.
  5. Claude ti indica il percorso del file e può poi usare l'immagine nel tuo codice.

Uno script, invece di sole istruzioni, mantiene esatte le chiamate all'API: il corpo della richiesta, il ciclo di polling e il salvataggio del file sono sempre gli stessi, qualunque prompt scriva Claude.

Cosa ti serve prima di iniziare?

  • Una chiave API di SeedRouter, esportata nel terminale da cui avvii Claude Code:
export SEEDROUTER_API_KEY="your-key"
  • Crediti. Ogni esecuzione è una richiesta a pagamento. I nuovi account partono con un piccolo saldo gratuito e le richieste non riuscite non vengono addebitate.
  • Python 3. Lo script usa solo la libreria standard, quindi non c'è niente da installare.

Lo script: invio, polling e salvataggio

Salva questo come scripts/nano_banana_pro.py nella cartella dello skill:

#!/usr/bin/env python3
import argparse
import json
import os
import pathlib
import sys
import time
import urllib.error
import urllib.request

API = "https://api.seedrouter.ai/v1"
AGENT = "nano-banana-pro-skill/1.0"
MIME = {
    ".jpg": "image/jpeg",
    ".jpeg": "image/jpeg",
    ".png": "image/png",
    ".webp": "image/webp",
    ".heic": "image/heic",
    ".heif": "image/heif",
}
RATIOS = ["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9"]


def call(method, path, body=None):
    request = urllib.request.Request(
        API + path,
        data=None if body is None else json.dumps(body).encode(),
        method=method,
        headers={
            "Authorization": "Bearer " + os.environ["SEEDROUTER_API_KEY"],
            "Content-Type": "application/json",
            "User-Agent": AGENT,
        },
    )
    try:
        with urllib.request.urlopen(request, timeout=60) as response:
            return json.load(response)
    except urllib.error.HTTPError as error:
        sys.exit(f"HTTP {error.code}: {error.read().decode()}")


def submit(args):
    parts = [{"text": args.prompt}]
    for url in args.ref:
        suffix = pathlib.PurePosixPath(url.split("?")[0]).suffix.lower()
        if suffix not in MIME:
            sys.exit(f"Cannot tell the image type of {url}; use a .jpg, .png, .webp, .heic or .heif URL.")
        parts.append({"fileData": {"mimeType": MIME[suffix], "fileUri": url}})
    image_config = {}
    if args.ratio:
        image_config["aspectRatio"] = args.ratio
    if args.size:
        image_config["imageSize"] = args.size
    generation_config = {"responseModalities": ["IMAGE"]}
    if image_config:
        generation_config["imageConfig"] = image_config
    body = {
        "model": args.model,
        "contents": [{"role": "user", "parts": parts}],
        "generationConfig": generation_config,
    }
    return call("POST", "/images/generations", body)["id"]


def wait(task_id, out_dir, timeout):
    deadline = time.monotonic() + timeout
    while time.monotonic() < deadline:
        task = call("GET", "/tasks/" + task_id)
        if task["status"] == "completed":
            out_dir.mkdir(parents=True, exist_ok=True)
            extension = "jpg" if task["output"]["output_format"] == "jpeg" else task["output"]["output_format"]
            for index, image in enumerate(task["output"]["data"]):
                path = out_dir / f"{task_id}-{index}.{extension}"
                download = urllib.request.Request(image["url"], headers={"User-Agent": AGENT})
                with urllib.request.urlopen(download, timeout=120) as response:
                    path.write_bytes(response.read())
                print(path)
            return
        if task["status"] == "failed":
            sys.exit(f"Task {task_id} failed: {task['error']['message']}")
        time.sleep(3)
    sys.exit(f"Task {task_id} is still processing. Resume with --resume {task_id}")


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--prompt")
    parser.add_argument("--ref", action="append", default=[])
    parser.add_argument("--ratio", choices=RATIOS)
    parser.add_argument("--size", choices=["1K", "2K", "4K"])
    parser.add_argument("--model", default="gemini-3-pro-image",
                        choices=["gemini-3-pro-image", "gemini-3-pro-image-official"])
    parser.add_argument("--out", default="images")
    parser.add_argument("--timeout", type=int, default=600)
    parser.add_argument("--resume")
    args = parser.parse_args()
    if args.resume:
        task_id = args.resume
    elif args.prompt:
        task_id = submit(args)
        print(f"task {task_id}", file=sys.stderr)
    else:
        parser.error("--prompt or --resume is required")
    wait(task_id, pathlib.Path(args.out), args.timeout)


if __name__ == "__main__":
    main()

Cosa fa:

  • Invia una volta sola. --prompt è il testo, --ref aggiunge l'URL di un'immagine di riferimento (ripetilo per aggiungerne altre) e --ratio e --size impostano imageConfig. Il corpo della richiesta è il formato generateContent di Google con un campo model, come definito nel riferimento dell'API di Nano Banana Pro.
  • Stampa l'ID attività appena l'attività viene creata, prima di mettersi in attesa.
  • Esegue il polling, poi salva. Quando l'attività è completata, scarica ogni immagine in images/ e stampa ogni percorso. Quando l'attività non riesce, stampa il motivo.
  • Riprende invece di reinviare. Se l'attesa scade, --resume <task id> controlla di nuovo la stessa attività. Un secondo invio sarebbe una seconda richiesta a pagamento.
  • Invia un'intestazione User-Agent. Tieni quella riga: alcuni server rifiutano quella predefinita di Python e, senza, il download può fallire con un errore 403.

Puoi provarlo da solo prima che lo usi Claude:

python3 scripts/nano_banana_pro.py --prompt "A ceramic teapot on a linen tablecloth, soft window light" --ratio 16:9 --size 2K

Lo skill: cosa va in SKILL.md?

La documentazione di Claude Code descrive uno skill come una directory con un file SKILL.md: «un frontmatter YAML tra marcatori --- che dice a Claude quando usare lo skill, e un contenuto markdown con le istruzioni che Claude segue quando lo skill viene eseguito». I file di supporto, come una cartella scripts/, stanno accanto.

Salva questo come SKILL.md nella stessa cartella:

---
name: nano-banana-pro
description: Generate or edit an image with Nano Banana Pro (gemini-3-pro-image) through the SeedRouter API and save it into the project. Use when the user asks for an image, illustration, icon, poster or edit of an existing image.
argument-hint: "[what the image should show]"
disable-model-invocation: true
---

Create an image for this request: $ARGUMENTS

1. Write one prompt in full sentences: subject, framing, action, setting and style. Put any text that must appear in the image in double quotes and say where it goes. For an edit, say what changes and what must stay the same.
2. Choose --ratio from 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9 and --size from 1K, 2K, 4K (4K only for print).
3. Reference images must be public HTTPS URLs ending in .jpg, .png, .webp, .heic or .heif, passed with --ref. If the user points to a local file, ask for a public URL instead. Never send base64.
4. Show the user the prompt and options, and wait for approval. Each run is a paid request.
5. Run: python3 ${CLAUDE_SKILL_DIR}/scripts/nano_banana_pro.py --prompt "..." [--ratio R] [--size S] [--ref URL]
6. If it stops with "still processing", run it again with --resume and the same task ID. Never submit the same request twice.
7. Report the saved file paths. If the task failed, explain the reason and suggest a change to the prompt.

Qui contano due campi:

  • disable-model-invocation: true significa che solo tu puoi avviare lo skill. La documentazione di Claude Code lo consiglia per i «flussi di lavoro con effetti collaterali o di cui vuoi controllare il momento». Ogni esecuzione costa denaro, quindi Claude non dovrebbe decidere da solo di generare un'immagine.
  • ${CLAUDE_SKILL_DIR} viene sostituito con la cartella dello skill, così lo script funziona ovunque tu abbia installato lo skill.

Dove si mette lo skill e come si esegue?

Claude Code carica gli skill da due posizioni principali:

PosizionePercorsoDisponibile in
Personale~/.claude/skills/nano-banana-pro/tutti i tuoi progetti su questo computer
Progetto.claude/skills/nano-banana-pro/questo repository; fai commit per condividerlo con il team

La cartella finita ha questo aspetto:

nano-banana-pro/
├── SKILL.md
└── scripts/
    └── nano_banana_pro.py

Avvia Claude Code in un terminale in cui è impostata SEEDROUTER_API_KEY, poi digita il nome dello skill seguito da ciò che vuoi:

/nano-banana-pro a 16:9 hero image for the pricing page: a calm desk with a laptop, a notebook and a cup of tea, soft morning light, muted green palette, no text

Claude mostra il prompt e le opzioni, tu approvi e l'immagine arriva in images/. A meno che tu non abbia già autorizzato il comando, Claude Code chiede anche il permesso prima di eseguire lo script: un secondo controllo prima che venga addebitato qualcosa.

Per il prompt vero e proprio, la guida ai prompt di Nano Banana Pro approfondisce struttura, testo nell'immagine e riferimenti.

Codex può usare lo stesso skill di Nano Banana Pro?

Sì. Entrambi gli strumenti seguono lo standard aperto Agent Skills. La documentazione di Codex di OpenAI dice che uno skill «è una directory con un file SKILL.md più script e riferimenti facoltativi» e che il file «deve includere name e description», cosa che lo skill qui sopra ha.

Codex cerca gli skill in altre cartelle:

PosizionePercorso
Personale~/.agents/skills/nano-banana-pro/
Repository.agents/skills/nano-banana-pro/

Copia lì la cartella oppure crea un link simbolico che punti a essa; entrambi gli strumenti seguono le cartelle di skill collegate tramite link simbolico. In Codex, esegui /skills o digita $nano-banana-pro per richiamarlo.

Due differenze da conoscere:

  • Il percorso dello script. ${CLAUDE_SKILL_DIR} è una sostituzione di Claude Code. Codex mostra al modello il percorso del file di ogni skill, quindi può trovare scripts/nano_banana_pro.py accanto a SKILL.md; se esegue il percorso sbagliato, digli dove si trova lo script.
  • L'uso automatico. disable-model-invocation è un campo di Claude Code. L'equivalente in Codex è un file agents/openai.yaml nella cartella dello skill con allow_implicit_invocation: false sotto policy, così Codex esegue lo skill solo quando lo richiami tu.

Lo script ha bisogno dell'accesso alla rete per raggiungere api.seedrouter.ai. Se il tuo agente gira in una sandbox senza rete, consenti l'accesso alla rete per quella sessione.

Come si modificano le immagini già presenti nel progetto?

Nano Banana Pro modifica a partire da immagini di riferimento, e l'API le accetta solo come URL pubblici. Un file sul tuo disco deve prima essere ospitato da qualche parte, per esempio nel tuo bucket di storage, e poi passato con --ref.

Le immagini generate sono già ospitate: ogni attività completata restituisce l'immagine come URL. Per perfezionare un risultato, ripassa quell'URL come riferimento insieme alla modifica che vuoi:

/nano-banana-pro edit the last image: keep the desk and the laptop, change the tea cup to a glass of water, and make the light warmer

Claude riutilizza l'URL dell'immagine precedente con --ref e scrive un prompt di modifica che dice cosa deve restare uguale. Per una modifica su più turni che mantenga il contesto del modello tra un turno e l'altro, il riferimento dell'API spiega come rimandare i turni precedenti; lo script qui sopra invia un turno alla volta.

Se usi già GPT Image 2 da un agente di programmazione, GPT Image 2 in Codex e Claude Code descrive quella configurazione, basata su un prompt da incollare nell'agente.

Domande frequenti

Esiste uno skill o un server MCP ufficiale di SeedRouter per Nano Banana Pro?

No. SeedRouter non ne fornisce. Lo skill di questa guida è una semplice cartella che ti appartiene e che puoi modificare, e chiama l'API pubblica con la tua chiave.

Perché lo script esegue il polling invece di aspettare l'immagine?

Su SeedRouter le richieste di Nano Banana Pro sono attività: l'invio restituisce un ID attività e l'immagine arriva quando l'attività è completata. Il polling mantiene brevi le connessioni e, se l'attesa viene interrotta, l'ID attività resta valido.

Posso usare lo stesso skill per Nano Banana 2?

Sì, con piccole modifiche. Cambia il valore predefinito e le scelte di --model nello script in gemini-3.1-flash-image e aggiungi 512 alle scelte di --size, una dimensione che Nano Banana 2 supporta e Pro no. Nano Banana 2 vs Pro vs 2 Lite confronta i modelli.

Caricare lo skill costa qualcosa?

No. Che Claude legga SKILL.md non costa nulla su SeedRouter. Ogni esecuzione dello script è una richiesta, addebitata alla tariffa indicata nella pagina del modello, e un'attività non riuscita non viene addebitata.

Inizia a generare da Claude Code

Crea la cartella, esporta la tua chiave e prova prima /nano-banana-pro con un'immagine piccola. I prezzi attuali sono nella pagina di Nano Banana Pro e tutti i campi della richiesta nel riferimento dell'API.

Guide correlate