算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
vertex-banana【设计与创意】Use when the user asks to create, generate, make, draw, design, or edit any image or visual content — blog featured images, YouTube thumbnails, icons, diagrams, patterns, illustrations, photos, visual assets, graphics, artwork, pictures. REQUIRED for all image generation requests — PRIMARY image skill (direct Google Vertex AI / Gemini image API via V…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Generate and edit images using Google Vertex AI Gemini models. Supports two methods: Python SDK (preferred) and curl (fallback).
Use when the user asks to generate or edit images via Google Vertex AI / Gemini image models:
[ -n "$VERTEX_API_KEY" ] && echo "API key configured" || echo "Missing VERTEX_API_KEY"
VERTEX_API_KEY is the Vertex AI API key (53 chars). The script temporarily clears conflicting SDK env vars (GOOGLE_API_KEY, GEMINI_API_KEY, GOOGLE_GENAI_USE_VERTEXAI) during execution to prevent auth conflicts.
pip install --upgrade google-genai
The Python script lives in the skill folder and is accessible from any project:
~/.claude/skills/vertex-banana/vertex_banana.py
Always reference it with the full path: $HOME/.claude/skills/vertex-banana/vertex_banana.py
Uses the google-genai Python package. Handles streaming, image saving, and error handling automatically.
python3 $HOME/.claude/skills/vertex-banana/vertex_banana.py "a cat wearing sunglasses on a beach"
python3 $HOME/.claude/skills/vertex-banana/vertex_banana.py "make the sky purple and add stars" -i input.png
python3 $HOME/.claude/skills/vertex-banana/vertex_banana.py \
"professional product photo of sneakers" \
-m flash-image \
--aspect-ratio 16:9 \
--image-size 2K \
-o ./my-output \
-f product_shot
| Flag | Default | Description |
|---|---|---|
prompt | (required) | Image generation or editing prompt |
-o, --output-dir | ./vertex-banana-output | Output directory |
-m, --model | flash-image | Model shorthand or full ID |
-i, --input-image | — | Input image for editing |
-f, --filename | auto-timestamped | Output filename (no extension) |
--aspect-ratio | auto | auto, 1:1, 16:9, 9:16, 4:3, 3:4 |
--image-size | 1K | 1K or 2K |
--mime-type | image/png | image/png or image/jpeg |
--person-generation | ALLOW_ALL | ALLOW_ALL, ALLOW_ADULT, DONT_ALLOW |
--thinking-level | HIGH | NONE, LOW, MEDIUM, HIGH |
--temperature | 1.0 | Generation temperature |
--top-p | 0.95 | Top P sampling |
--curl | — | Use curl method instead of Python SDK |
--vertex | — | Use Vertex AI endpoint instead of standard Gemini API |
--endpoint | aiplatform.googleapis.com | Custom API endpoint |
Use when the google-genai package is not installed. The same Python script handles this with the --curl flag.
python3 $HOME/.claude/skills/vertex-banana/vertex_banana.py "a sunset over mountains" --curl
Build the request JSON, send via curl, and parse the response:
Step 1: Create request.json
VB_WORK=$(mktemp -d /tmp/vb-XXXXXXXXXX)
cat << 'EOF' > "$VB_WORK/request.json"
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "YOUR PROMPT HERE"
}
]
}
],
"generationConfig": {
"temperature": 1,
"maxOutputTokens": 32768,
"responseModalities": ["TEXT", "IMAGE"],
"topP": 0.95,
"imageConfig": {
"aspectRatio": "auto",
"imageSize": "1K",
"imageOutputOptions": {
"mimeType": "image/png"
},
"personGeneration": "ALLOW_ALL"
},
"thinkingConfig": {
"thinkingLevel": "HIGH"
}
},
"safetySettings": [
{"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "OFF"},
{"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "OFF"},
{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "OFF"},
{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "OFF"}
]
}
EOF
Step 2: Send request
MODEL_ID="gemini-3.1-flash-image"
curl -s -X POST \
-H "Content-Type: application/json" \
"https://aiplatform.googleapis.com/v1/publishers/google/models/${MODEL_ID}:streamGenerateContent?key=${VERTEX_API_KEY}" \
-d @"$VB_WORK/request.json" -o "$VB_WORK/response.json"
Step 3: Extract and save image
python3 -c "
import json, base64, os
os.makedirs('vertex-banana-output', exist_ok=True)
with open('$VB_WORK/response.json') as f:
data = json.load(f)
chunks = data if isinstance(data, list) else [data]
n = 0
for chunk in chunks:
for c in chunk.get('candidates', []):
for p in c.get('content', {}).get('parts', []):
if 'inlineData' in p:
n += 1
img = base64.b64decode(p['inlineData']['data'])
path = f'vertex-banana-output/image_{n}.png'
open(path, 'wb').write(img)
print(f'Saved: {path}')
elif 'text' in p:
print(p['text'])
print(f'{n} image(s) generated' if n else 'No images in response')
"
Note: All model IDs below verified LIVE against the API on 2026-06-10 (
client.models.list()). They may still change as Google rotates previews.
| Shorthand | Model ID | Description |
|---|---|---|
flash-image | gemini-3.1-flash-image | Default. STABLE channel — image gen & editing, high quality, low latency |
flash-image-preview | gemini-3.1-flash-image-preview | Preview channel of the default |
pro-image | gemini-3-pro-image | Pro-tier image model (stable) |
pro | gemini-3.1-pro-preview | Best quality, complex agentic workloads |
flash-lite | gemini-3.1-flash-lite-preview | Most affordable, high-volume agents & large-scale data |
flash | gemini-3-flash-preview | Enhanced multimodal & coding capabilities |
pro-3 | gemini-3-pro-preview | Previous gen pro (still served as of 2026-06-10) |
Thinking level: valid API values are MINIMAL | LOW | MEDIUM | HIGH (default HIGH). NONE is rejected by the API with 400 INVALID_ARGUMENT — the script maps the legacy NONE choice to MINIMAL.
| Use Case | Aspect Ratio | Image Size | Notes |
|---|---|---|---|
| General / auto-detect | auto | 1K | Default — model picks best ratio |
| YouTube thumbnail | 16:9 | 2K | 1280x720 equivalent |
| Blog featured image | 16:9 | 1K | Social preview friendly |
| Square social | 1:1 | 1K | Instagram, LinkedIn |
| Vertical story | 9:16 | 1K | Mobile stories |
| Product photo | 4:3 | 2K | Standard product layout |
Images are saved to ./vertex-banana-output/ in the current working directory by default. Override with -o /path/to/dir.
After generation completes:
./vertex-banana-output/ for the generated file(s)This is the ONLY image-generation skill — there is no alternative and no fallback.
It calls the Vertex AI / Gemini image API directly (Python SDK or curl) with
VERTEX_API_KEY, and depends on no CLI.
| Problem | Solution |
|---|---|
VERTEX_API_KEY not set | export VERTEX_API_KEY="your-key" |
google-genai not installed | pip install --upgrade google-genai (verified working on 2.8.0, 2026-06-10; 1.x also works) |
| 429 RESOURCE_EXHAUSTED | Rate limit — wait and retry, or check quota in Cloud Console |
| 400 INVALID_ARGUMENT | Try simplifying options or check model name |
| 400 Multi-modal output not supported | Use flash-image model — only one supporting image output |
| 401 UNAUTHENTICATED | Wrong key type. Ensure VERTEX_API_KEY is the Vertex AI key (53 chars) |
| SDK uses wrong key | Remove GOOGLE_API_KEY, GOOGLE_GENAI_USE_VERTEXAI from env — they override explicit config |
person_generation TypeError | SDK version too old — script auto-falls back without it |
| No images generated | Check prompt for policy violations, simplify request |
| Curl JSON parse error | Verify API key is valid, check response for error messages |
| Model not found | Check model list above, model IDs change with previews |
| Anti-Pattern | Why It Fails | Correct Approach |
|---|---|---|
| Using Vertex AI image generation for text-heavy images | AI models render text poorly; misspellings and distorted characters are common | Generate the image without text; add text overlays using proper design tools or CSS afterward |
| Not specifying aspect ratio for target platform | Default output may not match blog header (16:9), social media (1:1), or thumbnail (4:3) requirements | Always specify aspect ratio and dimensions matching the deployment target in the generation request |
| Sending requests without error handling for quota limits | Vertex AI has per-minute and per-day quotas; unhandled 429 errors crash the workflow | Implement exponential backoff retry; catch 429 responses; fall back to vertex-banana or queue for later |
| Using high-resolution output for web thumbnails | Unnecessarily large images waste bandwidth, slow page loads, and consume more API quota | Request appropriate resolution for the use case; downscale large outputs before serving on web |
| Not validating prompt against content policy before submission | Policy violations return errors after consuming API quota; repeated violations may restrict account | Review prompts for policy compliance (no violent, explicit, or deceptive content); handle policy errors gracefully |