手搓 Skill 之使用硅基流动 API 免费生图
SKILL 是什么
SKILL 在我看来就是可以让大模型随时看到的说明文档。文档说明了这个 SKILL 可以干什么,有什么工具可以用,应该怎么做。
开始做 SKILL
所以 Skill 的文件结构就必然有 Skill 说明(SKILL.md)以及 Skill 相关代码(Scripts)

至于 references,其实就是一个简易化的 RAG,至于什么是 RAG,问 AI 就行。
然后先编写 SKILL.md 骨架,结构化数据 name 和 description 是描述SKILL。然后后面就可以附加这套 SKILL 怎么做,有什么约束,比如参数格式和失败处理。
---
name: siliconflow-image-generation
description: 通过 SiliconFlow API 、调用 Kwai-Kolors/Kolors 模型生成图片,另外可调整分辨率、步数、数量。
---
# SiliconFlow 生图
## 概述
## 生成图片
## 参数格式
## 结果与失败处理
编写概述
概述的话和 description 不一样,要具体说明。比如
通过 SiliconFlow 生成 1 至 4 张图片,并返回 API 响应或将图片保存到本地。具体通过
uv运行附带脚本,并从环境变量SILICONFLOW_API_KEY读取密钥,避免将密钥写入命令行参数。
但是我建议直接在脚本里指定从 SILICONFLOW_API_KEY 环境变量读取,没必要再 SKILL.md 里说明,除非你有很多 KEY 要逐个使用。所以我的最终版是
通过 SiliconFlow 生成 1 至 4 张图片,并返回 API 响应或将图片保存到本地。。
生成图片说明
直接告诉大模型怎么做就可以了,比如:
通过
uv运行脚本uv run scripts/generate_image.py --prompt "一只坐在阳光图书馆里的电影感橘猫" --size 1024x1024 --steps 20 --count 1 --output-dir .\generated-images编写清晰的生图提示词:主体、环境、构图、光线、媒介或风格,以及质量要求。如果这些因子会影响生图效果,请先确认用户期望的画面比例、风格、图片中的文字和不希望出现的元素。
编写参数说明
说明脚本的每个参数代表什么,其实这个主要是生图 API 支持什么参数,比如:
prompt: 提示词
size:控制参数的图像分辨率,API请求时候,可以自定义多种分辨率。
steps:控制图像生成的步长。
count:一次生成图像的个数,默认值是1,最大值可以设置为 4
output-dir:指定图片存储路径./相对路径会存放到 SKILL 目录下
seed:如果想要每次都生成固定的图片,可以把seed设置为固定值。
编写结果与失败处理
示例嘛,我就不写了,当然比如说遇到429可以等待1分钟后重试。
编写脚本
把 API 说明文档丢给 AI。
# /// script
# requires-python = ">=3.10"
# dependencies = ["openai>=1.0.0"]
# ///
"""Generate images with SiliconFlow's OpenAI-compatible API."""
from __future__ import annotations
import argparse
import base64
import os
import sys
from pathlib import Path
from urllib.request import urlopen
from openai import APIError, OpenAI
DEFAULT_BASE_URL = "https://api.siliconflow.cn/v1"
DEFAULT_MODEL = "Kwai-Kolors/Kolors"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Generate images with SiliconFlow's OpenAI-compatible API."
)
parser.add_argument("--prompt", required=True, help="Description of the desired image.")
parser.add_argument("--model", default=DEFAULT_MODEL, help="SiliconFlow model ID.")
parser.add_argument("--size", default="1024x1024", help="Image resolution, such as 1024x1024.")
parser.add_argument("--steps", type=int, default=20, help="Inference steps.")
parser.add_argument("--count", type=int, default=1, choices=range(1, 5), help="Number of images (1-4).")
parser.add_argument("--negative-prompt", help="Elements to exclude from the image.")
parser.add_argument("--seed", type=int, help="Seed for reproducible output when supported.")
parser.add_argument(
"--parameter-format",
choices=("openai", "model"),
default="openai",
help="Use OpenAI-compatible names or native model parameter names.",
)
parser.add_argument("--base-url", default=DEFAULT_BASE_URL, help="API base URL.")
parser.add_argument("--output-dir", type=Path, help="Directory for downloaded or base64 images.")
return parser.parse_args()
def build_extra_body(args: argparse.Namespace) -> dict[str, object]:
if args.parameter_format == "openai":
parameters: dict[str, object] = {"step": args.steps}
else:
parameters = {
"image_size": args.size,
"num_inference_steps": args.steps,
"batch_size": args.count,
}
if args.negative_prompt:
parameters["negative_prompt"] = args.negative_prompt
if args.seed is not None:
parameters["seed"] = args.seed
return parameters
def save_images(response: object, output_dir: Path) -> None:
output_dir.mkdir(parents=True, exist_ok=True)
images = getattr(response, "data", [])
for index, image in enumerate(images, start=1):
target_path = output_dir / f"image-{index}.png"
encoded_image = getattr(image, "b64_json", None)
image_url = getattr(image, "url", None)
if encoded_image:
target_path.write_bytes(base64.b64decode(encoded_image))
elif image_url:
with urlopen(image_url, timeout=60) as download_response:
target_path.write_bytes(download_response.read())
else:
print(f"Image {index} has no URL or base64 payload; not saved.", file=sys.stderr)
continue
print(f"Saved {target_path}")
def main() -> int:
args = parse_args()
api_key = os.environ.get("SILICONFLOW_API_KEY")
if not api_key:
print("Set SILICONFLOW_API_KEY before generating images.", file=sys.stderr)
return 2
client = OpenAI(api_key=api_key, base_url=args.base_url)
request: dict[str, object] = {
"model": args.model,
"prompt": args.prompt,
"extra_body": build_extra_body(args),
}
if args.parameter_format == "openai":
request["size"] = args.size
request["n"] = args.count
try:
response = client.images.generate(**request)
except APIError as error:
print(f"SiliconFlow image generation failed: {error}", file=sys.stderr)
return 1
print(response.model_dump_json(indent=2))
if args.output_dir:
save_images(response, args.output_dir)
return 0
if __name__ == "__main__":
raise SystemExit(main())
编写元数据
元数据固定路径 agents/openai.yaml。照着改就行。
interface:
display_name: "SiliconFlow 生图"
short_description: "使用 SiliconFlow OpenAI 兼容接口生成图片并调整关键参数"
default_prompt: "使用 $siliconflow-image-generation 通过 SiliconFlow 创建一张图片。"
前边实际不用管
现在大模型都很好用了,你直接丢给他 API 文档,然后编写技能就可以了,比如把下面在 AGENT 丢进去,等一会就写好了。
client = OpenAI(api_key="Your-api_key", base_url="https://api.siliconflow.cn/v1")
response = client.images.generate(
model="Kwai-Kolors/Kolors",
prompt="a cat",
size="1024x1024",
n=1,
extra_body={
"step": 20
}
)
print(response)
重点参数介绍
image_size:控制参数的图像分辨率,API请求时候,可以自定义多种分辨率。
num_inference_steps:控制图像生成的步长。
batch_size:一次生成图像的个数,默认值是1,最大值可以设置为4
negative_prompt:这里可以输入图像中不想出现的某些元素,消除一些影响影响因素。
seed:如果想要每次都生成固定的图片,可以把seed设置为固定值。
根据这个创建一个生图技能

浙公网安备 33010602011771号