縮圖建立技能(透過 Gemini)
在 Claude Code 內部擔任圖片生成代理,產生文章和電子報的縮圖候選方案。您不再需要在不同工具間切換、一個一個在 Gemini 的網頁 UI 中輸入提示;這個技能讓 Claude 完成整個循環:閱讀文案、提出構圖、撰寫客製化提示、呼叫 Gemini API、評估輸出結果,並回傳排名後的候選方案與簡短理由。
產出的縮圖候選方案可直接用於您的 CMS、電子報工具或社群媒體排程器。
前置作業
在技能可以開始生成圖片之前,必須先確定以下兩項都已準備就緒:
1. Gemini API 金鑰
從 Google AI Studio 取得免費金鑰。
設定為環境變數:
export GEMINI_API_KEY=<你的金鑰>
若要跨工作階段保留,請新增至您的 shell 設定檔(~/.zshrc 或 ~/.bashrc):
echo 'export GEMINI_API_KEY=<你的金鑰>' >> ~/.zshrc
source ~/.zshrc
確認已設定:
echo $GEMINI_API_KEY
2. generate_image.py 腳本
此腳本必須存在於專案根目錄下的 ./generate_image.py。完整的範本請參閱下方的「腳本範本」章節。Claude 會檢查此檔案,若遺失則會主動提議建立。
Python 相依套件:
pip install google-generativeai Pillow requests
若使用 uv:
uv pip install google-generativeai Pillow requests
必要輸入
若未提供,Claude 會詢問以下資訊:
| 輸入項目 | 必要與否 | 備註 |
|---|---|---|
| 文章內容或 URL | 是 | 貼上完整文章內容,或提供 URL 以供擷取。用來提取主題、鉤子與關鍵主張來進行構圖。 |
| 品牌色彩 | 建議提供 | 十六進制色碼或描述性名稱。例如 #1A1A2E(深藍)、#E94560(珊瑚紅)。若未提供,Claude 會使用乾淨的中性預設值。 |
| 字型 / 字體風格 | 建議提供 | 例如「粗體無襯線字體」、「編輯襯線字體」、「Neue Haas Grotesk」。用於提示中引導文字處理方式。 |
| 風格參考描述 | 建議提供 | 例如「扁平插畫、簡約,像 Stripe 的行銷網站」或「寫實、深色背景、高對比」。也可以提供風格圖片的 URL。 |
| 輸出尺寸 | 否 | 預設為 1792x1024(橫向,標準文章縮圖)。可選:1024x1024(正方形)、1024x1792(直向/行動裝置)。 |
| 候選數量 | 否 | 預設為 4。最少 1,最多 8(API 限制與成本考量)。 |
| 文章標題(若不同於 H1) | 否 | 用作圖片提示中的主要文字元素。 |
| 候選選擇 | 否 | 在提出構圖後,Claude 會詢問要生成哪些。使用者可以回答「全部」或依編號選擇。 |
輸出結構
第一階段 — 構圖提案(文字,在呼叫 API 之前)
Claude 會呈現 3-4 個構圖概念供使用者核准。格式如下:
「[文章標題]」的構圖概念
1. 大膽主張
版面: 滿版深色背景、置中大型白色標題、下方以品牌色彩顯示單一重點數據(例如「3 倍快」)
氛圍: 高度權威、電子報風格
最適合: LinkedIn、Substack 頁首
理由: 文章的核心主張(「X 比 Y 快 3 倍」)夠具體,足以支撐視覺 — 讀者會因為數據而停下。
2. 概念物體
版面: 中央物體插畫(例如,一篇關於浪費時間的文章可以放一個壞掉的時鐘)、標題在上三分之一處、極簡紋理背景
氛圍: 編輯風格、Medium 風格
最適合: 部落格頁首、Medium 封面、電子郵件前導
理由: 給予藝術總監視覺隱喻的靈活性;適用於各種尺寸。
3. 對比分割
版面: 左半部品牌色彩、右半部白色或圖片、標題在色彩側、輔助文字在白色側
氛圍: 整潔、專業、新創品牌感
最適合: 電子報、LinkedIn 輪播第一張
理由: 分割版面在電子報 A/B 測試中表現穩定;小尺寸下文字仍可讀。
4. 純文字編排
版面: 無插畫、超大標題處理、作者姓名以小寫大寫字體置於底部、細線分隔
氛圍: 高質感、自信、編輯風格
最適合: Substack、Ghost、高密度郵件清單
理由: 當品牌有強烈的字體識別時適用。製作速度最快。
您要生成哪些構圖?(請回覆編號,例如「1, 3」或「all」)
第二階段 — 生成的圖片檔案
生成完成後,Claude 會將檔案儲存至 ./thumbnails/[文章縮寫]/:
thumbnails/
└── 依標題產生的文章縮寫/
├── candidate_01_bold_claim.png
├── candidate_02_conceptual_object.png
├── candidate_03_contrast_split.png
├── candidate_04_typographic.png
└── evaluation_report.md
第三階段 — 評估摘要表
Claude 會透過電腦視覺評估每張回傳的圖片,並產出:
縮圖評估 — 「[文章標題]」
生成日期:2026-05-27 | 模型:Gemini Imagen | 尺寸:1792x1024
| # | 候選方案 | 構圖 | 品牌契合度 /10 | 文字可讀性 /10 | 建議 |
|---|---|---|---|---|---|
| 1 | candidate_01_bold_claim.png | 大膽主張 | 9 | 8 | ★ 首選 — 數據錨點強烈、品牌色彩正確、200px 寬度下標題可讀 |
| 2 | candidate_02_conceptual_object.png | 概念物體 | 7 | 9 | 良好的備選 — 可讀性高、乾淨,但插畫風格略微偏離品牌 |
| 3 | candidate_03_contrast_split.png | 對比分割 | 8 | 7 | 全尺寸時表現良好;發布前請先測試縮圖尺寸 — 右側文字較緊湊 |
| 4 | candidate_04_typographic.png | 純文字編排 | 9 | 10 | 最適合電子郵件 — 零品牌偏移風險、完全基於文字 |
推薦用於網頁: candidate_01_bold_claim.png
推薦用於電子郵件/行動裝置:candidate_04_typographic.png
推薦用於社群媒體: candidate_03_contrast_split.png
檔案儲存於:./thumbnails/文章縮寫/
Claude 應如何執行此技能
步驟 1 — 輸入並分析文章
接受以貼上文字或 URL 形式提供的文章內容。
若提供 URL,則擷取頁面並提取:
- H1 標題
- 前 3-5 個段落(鉤子、核心主張與關鍵論點)
- 任何值得注意的統計數據或提及的知名架構
- 作者姓名(用於純文字編排構圖)
若貼上文字,則直接閱讀。重點關注:
- 鉤子: 開頭的主張或張力是什麼?
- 核心論點: 文章論證或教導的一件事是什麼?
- 關鍵細節: 任何能夠作為視覺錨點的數字、知名架構或具體例子
- 語氣: 這是正式/權威、口語/平易近人、還是挑釁/挑戰性?
在提出構圖之前先在內部總結這些發現 —— 提案應針對這篇特定文章量身定制,而非泛泛而談。
步驟 2 — 收集品牌規格
若未提供品牌規格,則詢問使用者:
要產生符合品牌風格的縮圖,我需要以下資訊:
1. 品牌色彩(十六進制色碼或描述)——例如 #1A1A2E、#E94560
2. 字型風格偏好——例如「粗體無襯線字體」、「編輯襯線字體」、「幾何字體」
3. 視覺風格——例如「扁平極簡」、「寫實」、「插畫」、「純文字編排」
4. 任何風格參考——描述一個您想比照其美學的品牌或刊物,或分享圖片 URL
如果您還沒有品牌規格,請說「使用乾淨的預設值」,我將使用專業的深色文字配白色背景的編輯風格。
若使用者說「使用乾淨的預設值」,則套用:
- 背景:
#FFFFFF或#0F0F0F(深色模式預設) - 強調色:
#2563EB(藍色) - 字型風格:粗體幾何無襯線字體
- 風格:極簡扁平、無紋理、高對比
步驟 3 — 提出構圖概念
針對文章的語氣與內容撰寫 3-4 個構圖概念。每個概念必須:
- 有名稱(簡短、好記的標籤)
- 精確描述版面(標題位置、支撐畫面的視覺元素、背景處理方式)
- 註明氛圍及其最適合的使用情境
- 包含一句理由說明,解釋為什麼此構圖適合這篇特定文章
呈現概念後,詢問要生成哪些。在進行任何 API 呼叫之前,等待使用者確認。
步驟 4 — 撰寫 Gemini 圖片生成提示
針對每個選定的構圖,撰寫詳細的圖片生成提示。圖片生成提示的語法與文字提示不同 —— 它們是描述性的,而非指令性的。
提示結構:
[主體/構圖] + [風格] + [色彩調色盤] + [氛圍/燈光] +
[文字處理(若有)] + [應避免的內容]
大膽主張構圖的提示範例:
文章縮圖圖片。大型粗體白色無襯線字體標題顯示「比傳統方法快 3 倍」在深海軍藍背景(#1A1A2E)上置中。下方以珊瑚紅強調色文字(#E94560)顯示副標題。極簡扁平設計,無漸層、無圖庫照片元素、無人物。乾淨專業的編輯風格、高對比、電子報頁首格式、16:9 橫向畫面。構圖為純文字編排 — 文字是主角,不需要插畫。避免:剪貼畫、投影、低對比、擁擠的版面。
提示規則:
- 當提供品牌色彩時,須包含確切的十六進制色碼
- 指定要在圖片中顯示的確切標題文字
- 明確說明風格(「扁平設計」、「編輯風格」、「寫實」)—— Gemini 對風格類別名稱反應良好
- 在結尾加入負面提示(「避免:...」)以減少偏離品牌風格的情況
- 將提示控制在 300 字以下 —— 較長的提示不一定能產生更好的結果
步驟 5 — 檢查前置條件並執行生成腳本
在呼叫 API 之前,請確認:
# 檢查 API 金鑰是否已設定
echo $GEMINI_API_KEY
# 檢查腳本是否存在
ls -la ./generate_image.py
# 檢查相依套件
python3 -c "import google.generativeai, PIL, requests; print('Dependencies OK')"
若腳本遺失,主動提議使用下方「腳本範本」章節中的範本來建立。
為每個提示執行生成腳本:
python3 generate_image.py \
--prompt "您的完整提示" \
--output "./thumbnails/文章縮寫/candidate_01_bold_claim.png" \
--width 1792 \
--height 1024
或將所有提示透過批次設定檔傳入:
python3 generate_image.py --config ./thumbnails/文章縮寫/prompts.json
步驟 6 — 評估生成的圖片
每張圖片儲存後,使用電腦視覺進行檢查。從兩個維度評估:
品牌契合度(分數 /10):
- 品牌色彩是否正確?(各 1-2 分)
- 風格是否符合要求的美感?(2 分)
- 版面是否與構圖簡報一致?(2 分)
- 是否有任何 AI 偽影、扭曲文字或非預期元素?(每項扣 1 分)
文字可讀性(分數 /10):
- 全解析度下標題文字是否可讀?(3 分)
- 圖片縮放至 300px 寬(縮圖尺寸)時,標題文字是否可讀?(3 分)
- 文字與背景之間是否有足夠的對比?(2 分)
- 文字是否位於安全區域內(未被邊緣裁切)?(2 分)
注意:Gemini Imagen 有時會渲染出有拼寫錯誤或字母形狀扭曲的文字。如果發生這種情況,請在評估中註明,並建議使用者在 Canva 或 Figma 中手動加上文字疊加層。
步驟 7 — 產出評估報告
撰寫評估摘要表(格式如「輸出結構」章節所示),並將其儲存為輸出資料夾中的 evaluation_report.md。
包含:
- 每個分數的一行理由說明
- 每個使用情境(網頁、電子郵件/行動裝置、社群媒體)的首選推薦
- 任何製作備註(例如「候選方案 2 的文字渲染不完美 — 請手動疊加文字」)
- 所使用的完整提示,以便使用者可以直接在 AI Studio 中迭代(如有需要)
步驟 8 — 提供迭代選項
交付候選方案後,提供一次迭代循環:
想要我對任何一個進行迭代嗎?
選項:
- 調整特定候選方案的色彩或風格
- 嘗試不同的構圖概念
- 更改標題文字
- 使用不同的 Gemini 參數重新執行(不同的 temperature / seed)
- 為首選生成更多變體
只要告訴我要改什麼即可。
腳本範本
如果 generate_image.py 不存在,Claude 應主動提議寫入此檔案。這是應使用的標準範本。
#!/usr/bin/env python3
"""
generate_image.py — Gemini Imagen wrapper for Thumbnail Creator skill.
Usage:
python3 generate_image.py --prompt "..." --output "./out.png" [--width 1792] [--height 1024]
python3 generate_image.py --config ./prompts.json
Config JSON format:
[
{
"prompt": "...",
"output": "./thumbnails/slug/candidate_01.png",
"width": 1792,
"height": 1024
}
]
Requirements:
pip install google-generativeai Pillow
"""
import os
import sys
import json
import argparse
import base64
from pathlib import Path
try:
import google.generativeai as genai
from google.generativeai import types as genai_types
except ImportError:
print("ERROR: google-generativeai not installed. Run: pip install google-generativeai")
sys.exit(1)
try:
from PIL import Image
import io
except ImportError:
print("ERROR: Pillow not installed. Run: pip install Pillow")
sys.exit(1)
def get_api_key() -> str:
key = os.environ.get("GEMINI_API_KEY", "")
if not key:
print("ERROR: GEMINI_API_KEY environment variable is not set.")
print("Get a key at: https://aistudio.google.com/app/apikey")
print("Then run: export GEMINI_API_KEY=<your-key>")
sys.exit(1)
return key
def generate_image(
prompt: str,
output_path: str,
width: int = 1792,
height: int = 1024,
) -> bool:
"""
Call Gemini Imagen to generate a single image and save it to output_path.
Returns True on success, False on failure.
"""
key = get_api_key()
genai.configure(api_key=key)
output = Path(output_path)
output.parent.mkdir(parents=True, exist_ok=True)
try:
model = genai.GenerativeModel("models/imagen-3.0-generate-001")
response = model.generate_content(
prompt,
generation_config=genai_types.GenerationConfig(
temperature=0.4,
candidate_count=1,
),
safety_settings=[
{
"category": genai_types.HarmCategory.HARM_CATEGORY_HARASSMENT,
"threshold": genai_types.HarmBlockThreshold.BLOCK_NONE,
},
{
"category": genai_types.HarmCategory.HARM_CATEGORY_HATE_SPEECH,
"threshold": genai_types.HarmBlockThreshold.BLOCK_NONE,
},
{
"category": genai_types.HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
"threshold": genai_types.HarmBlockThreshold.BLOCK_NONE,
},
{
"category": genai_types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
"threshold": genai_types.HarmBlockThreshold.BLOCK_NONE,
},
],
)
if not response.candidates:
print(f"ERROR: No candidates returned for prompt: {prompt[:60]}...")
if response.prompt_feedback:
print(f"Block reason: {response.prompt_feedback}")
return False
image_data = None
for part in response.candidates[0].content.parts:
if part.inline_data and part.inline_data.mime_type.startswith("image"):
image_data = part.inline_data.data
break
if not image_data:
print(f"ERROR: No image data in response for prompt: {prompt[:60]}...")
print(f"Response text (if any): {response.text[:200] if hasattr(response, 'text') and response.text else 'N/A'}")
return False
img = Image.open(io.BytesIO(image_data))
img = img.resize((width, height), Image.Resampling.LANCZOS)
img.save(output_path, "PNG")
print(f"OK: {output_path} ({width}x{height})")
return True
except Exception as e:
print(f"ERROR generating image: {e}")
return False
def main():
parser = argparse.ArgumentParser(description="Generate image via Gemini Imagen")
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--prompt", type=str, help="Image generation prompt")
group.add_argument("--config", type=str, help="Path to JSON config file with batch of prompts")
parser.add_argument("--output", type=str, help="Output image path (required with --prompt)")
parser.add_argument("--width", type=int, default=1792, help="Image width (default: 1792)")
parser.add_argument("--height", type=int, default=1024, help="Image height (default: 1024)")
args = parser.parse_args()
if args.config:
config_path = Path(args.config)
if not config_path.exists():
print(f"ERROR: Config file not found: {config_path}")
sys.exit(1)
with open(config_path, "r") as f:
jobs = json.load(f)
success_count = 0
for job in jobs:
if generate_image(
prompt=job["prompt"],
output_path=job["output"],
width=job.get("width", 1792),
height=job.get("height", 1024),
):
success_count += 1
total = len(jobs)
print(f"\nDone: {success_count}/{total} images generated successfully.")
sys.exit(0 if success_count == total else 1)
elif args.prompt:
if not args.output:
print("ERROR: --output is required when using --prompt")
sys.exit(1)
success = generate_image(
prompt=args.prompt,
output_path=args.output,
width=args.width,
height=args.height,
)
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()
常見問題
- Gemini 在縮圖中產生拼寫錯誤的文字。 這是已知的限制。在評估報告中指出,並建議使用者在 Canva 或 Figma 中手動疊加正確文字。
- 生成的圖片完全偏離品牌風格。 為提示加入更明確的負面指示。確認品牌色彩已正確傳入。
- API 金鑰錯誤。 執行
echo $GEMINI_API_KEY確認金鑰已正確設定。若金鑰包含特殊字元,請檢查您的 shell 設定檔中是否有正確的引號。 - 批次中的某些提示失敗。 重新單獨執行失敗的提示。有時 Gemini 基於不明原因會拒絕某個特定提示;修改措辭通常可以解決問題。
限制
- 文字渲染: Gemini Imagen 產生的文字並非 100% 可靠。讀者不應期望產生可發布的文字 —— 將此技能視為構圖產生器,而非最終排版工具。
- 成本: Imagen 是付費 API。
1792x1024尺寸的每次生成會使用固定配額。大量批次可能產生費用。 - 風格一致性: 不同生成之間無法保證完全一致的風格。若需要重現相同外觀,請考慮使用種子值或風格參照圖片。