Llm image generation
徐望瀚日常工作中使用和维护的可复用 agent skills。
npx -y skills add black-yt/skills --skill llm-image-generationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
当需要通过 OpenAI-compatible LLM 网关生成图片时使用,尤其是使用 LLM_API_KEY 和 LLM_BASE_URL 调用 gpt-image-2、gpt-image-1、dall-e-3 等图像模型;覆盖环境变量检查、缺失配置提示、模型选择、/images/generations 请求、长等待时间处理、base64/URL 返回保存和排错。
SKILL.md
7.1 KB, as published. Nobody here has run it
LLM Image Generation
使用原则
- 优先从环境变量读取
LLM_API_KEY和LLM_BASE_URL,不要把 key 写进代码、日志、README 或命令输出。 - 如果环境变量缺失,先要求用户配置环境变量,不要猜测 key 或 base URL。
- 图像生成比普通 chat completion 慢很多。请求发出后 60-180 秒没有输出是常见情况;默认等待至少 180 秒,推荐超时设置为 300 秒。不要因为 30-60 秒无输出就判断失败。
- 输出图片保存到用户指定路径或当前项目的明确输出目录。仅测试时可以临时写入
/tmp,但验证后必须删除。 - 只在用户明确要求真实生成图片时调用接口;普通写作、提示词设计或代码生成不需要真的发图像请求。
环境变量
必需:
export LLM_API_KEY="sk-..."
export LLM_BASE_URL="http://host:port/v1"
可选:
export LLM_IMAGE_MODEL="gpt-image-2"
检查当前环境:
python3 - <<'PY'
import os
print("LLM_API_KEY:", "<set>" if os.environ.get("LLM_API_KEY") else "<unset>")
print("LLM_BASE_URL:", os.environ.get("LLM_BASE_URL", "<unset>"))
print("LLM_IMAGE_MODEL:", os.environ.get("LLM_IMAGE_MODEL", "<unset>"))
PY
如果 LLM_API_KEY 或 LLM_BASE_URL 是 <unset>,回复用户:
当前环境缺少 LLM_API_KEY 或 LLM_BASE_URL。请先在 shell 中配置:
export LLM_API_KEY="sk-..."
export LLM_BASE_URL="http://host:port/v1"
如果有指定图像模型,也可以配置:
export LLM_IMAGE_MODEL="gpt-image-2"
模型选择
先查询模型列表,再选择模型:
python3 - <<'PY'
import os, json, urllib.request
base = os.environ["LLM_BASE_URL"].rstrip("/")
key = os.environ["LLM_API_KEY"]
req = urllib.request.Request(
base + "/models",
headers={"Authorization": f"Bearer {key}"},
)
with urllib.request.urlopen(req, timeout=60) as r:
data = json.load(r)
models = [m.get("id", "") for m in data.get("data", [])]
for m in models:
ml = m.lower()
if "image" in ml or "dall" in ml:
print(m)
PY
默认优先级:
LLM_IMAGE_MODEL,如果用户或环境已指定。gpt-image-2,如果模型列表存在。gpt-image-1。gpt-image-1-mini。dall-e-3。dall-e-2。
如果这些都不存在,向用户报告模型列表中没有明确可用的图像生成模型,并询问要使用哪个模型。
生成图片
下面的脚本使用标准库,无需安装 OpenAI SDK。它会:
- 从环境变量读取 key/base/model。
- 请求
/images/generations。 - 等待最多 300 秒。
- 支持
b64_json或url返回。 - 不打印 API key。
python3 - <<'PY'
import base64
import json
import os
import pathlib
import urllib.error
import urllib.request
base = os.environ.get("LLM_BASE_URL", "").rstrip("/")
key = os.environ.get("LLM_API_KEY")
model = os.environ.get("LLM_IMAGE_MODEL", "gpt-image-2")
prompt = "A clean scientific icon of a blue beaker with a small sparkle, white background."
out_path = pathlib.Path("generated_image.png")
if not key or not base:
raise SystemExit(
"Missing LLM_API_KEY or LLM_BASE_URL. Please export both before generating images."
)
payload = {
"model": model,
"prompt": prompt,
"size": "1024x1024",
"n": 1,
}
req = urllib.request.Request(
base + "/images/generations",
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": f"Bearer {key}",
"Content-Type": "application/json",
},
method="POST",
)
print(f"[INFO] Request sent to {base}/images/generations with model={model}.")
print("[INFO] Image generation may take 60-180 seconds; waiting up to 300 seconds.")
try:
with urllib.request.urlopen(req, timeout=300) as r:
data = json.load(r)
except urllib.error.HTTPError as e:
body = e.read().decode("utf-8", errors="replace")
print(f"[ERROR] HTTP {e.code}")
print(body[:2000])
raise SystemExit(1)
except TimeoutError:
print("[ERROR] Timed out after 300 seconds. The request may be slow or the model may be unavailable.")
raise SystemExit(1)
items = data.get("data") or []
if not items:
print("[ERROR] Response has no data field.")
print(json.dumps(data, ensure_ascii=False)[:2000])
raise SystemExit(1)
item = items[0]
if item.get("b64_json"):
image_bytes = base64.b64decode(item["b64_json"])
out_path.write_bytes(image_bytes)
print(f"[INFO] Saved image to {out_path.resolve()} ({len(image_bytes)} bytes).")
elif item.get("url"):
img_req = urllib.request.Request(item["url"])
with urllib.request.urlopen(img_req, timeout=300) as r:
image_bytes = r.read()
out_path.write_bytes(image_bytes)
print(f"[INFO] Downloaded image to {out_path.resolve()} ({len(image_bytes)} bytes).")
else:
print("[ERROR] Response has neither b64_json nor url.")
print(json.dumps(data, ensure_ascii=False)[:2000])
raise SystemExit(1)
PY
如果只是验证接口是否可用,可以把 out_path 指向临时文件,验证 PNG 后立刻删除:
path = pathlib.Path("/tmp/codex_gpt_image_test.png")
path.write_bytes(image_bytes)
print(path.stat().st_size)
path.unlink()
等待时间与状态判断
- 0-30 秒无输出:正常,不要中断。
- 30-90 秒无输出:仍然正常,图像模型经常需要较长生成时间。
- 90-180 秒无输出:继续等待,尤其是
gpt-image-2这类较新模型。 - 超过 300 秒:按超时处理,记录模型名、endpoint、HTTP 状态或错误正文,再考虑换模型或重试。
发起请求后应给用户明确状态说明,例如:
图像生成请求已发出。该接口可能需要 60-180 秒返回;我会等到 300 秒超时后再判断失败。
排错
LLM_API_KEY=<unset>或LLM_BASE_URL=<unset>:要求用户先配置环境变量。- HTTP 401/403:key 无效、权限不足或网关拒绝;不要打印 key。
- HTTP 404:
LLM_BASE_URL不对、网关不支持/images/generations,或模型名不可用。 - HTTP 400:检查
model、size、n、prompt参数。先把请求缩小到n=1和1024x1024。 - 300 秒超时:不要立刻认为代码错。先换
gpt-image-1或dall-e-3对照,再判断是模型慢还是接口不可用。 - 返回没有
b64_json:检查是否返回url;两者都没有时打印不含 key 的响应摘要。 - 生成成功但文件打不开:检查是否正确 base64 decode,确认文件头是否为 PNG/JPEG。
当前环境实测记录
在本环境中,LLM_BASE_URL=http://35.220.164.252:3888/v1 的模型列表包含 gpt-image-2、gpt-image-1、gpt-image-1-mini、dall-e-3 等图像模型。gpt-image-2 调用 /images/generations 可返回 b64_json,解码后是有效 PNG。实际调用时等待时间超过 60 秒属于正常现象。