关于 stability-ai-image
stability-ai-image 是选择和使用 Stability AI 托管图像 API 或自托管开源权重的技能,帮助开发者按任务选择生成、编辑、控制和放大接口,并记录制作过程。
主要功能
- 01托管 API 与自托管路线指导
- 02文本生成图像与图像转图像
- 03图像编辑与背景移除
- 04草图、结构和风格控制
- 05图像放大
适用场景
- 01为特定图像任务选择 API 接口
- 02通过蒙版或文本指令编辑图像
- 03使用草图或风格参考引导输出
- 04以不同重构程度放大图像
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ calesthio/ generative-media-skills --skill stability-ai-image安装后在 Claude Code 中输入/stability-ai-image确认已加载。
附带文件EVAL.md
详细介绍
Stability AI 图像制作
使用此技能选择正确的 Stability AI 图像接口,发起符合架构的调用,保留制作证据,并避免混淆托管 API 与可自托管权重。
证据图例与时效性
- 已记录表示相关内容由 Stability AI 第一方来源链接或实时第一方 OpenAPI 文档明确说明。
- 推断表示根据已记录的行为得出的结论;若后果重大,请予以验证。
- 生产经验法则表示操作建议,并非提供方的保证。
- 此技能中的易变 API 信息已于 2026-07-09 验证。提交费用或发布长期集成前,请重新检查API 参考、定价和发行说明。
编写提示词前先确定工作路径
- 决定使用托管还是自托管执行。
- 对于托管 Stable Image 服务、编辑、控制、放大器、审核和提供方签署的溯源信息,请使用托管 Platform API。
- 只有在本地数据控制、自定义推理、微调或部署控制足以证明运行模型及履行其许可义务合理时,才使用开源权重。
- 不要暗示 Stable Image Core 或所有 Stable Image 微服务都可下载为权重。可下载的 SD3.5 检查点与托管服务目录仅部分重叠。
- 将任务意图对应到一项操作,不要强行让每项任务都通过生成来完成。
- 确认输出尺寸、输入限制、费用以及同步/异步行为。
- 上传源图前,确认权限、同意、隐私和当前的《可接受使用政策》。
- 批量处理前,先生成少量经批准的样本。记录端点、参数、API 返回的种子、请求 ID、输入哈希、输出哈希、费用估算以及政策/质量保证处理结果。
当前托管接口
**已记录,验证日期为 2026-07-09:**REST v2beta 是主要功能接口。Stability 表示 REST v1、gRPC 和 v2alpha 仍受维护,但不会获得新功能或参数;该公司建议将等效的 v2alpha URL 改为 v2beta。应将旧版 API 视为维护/迁移接口,而非新设计的信息来源。API 参考
生成
| 服务 | 端点 | 适用场景 | 输出 | 当前价格 |
|---|---|---|---|---|
| Stable Image Ultra | POST /v2beta/stable-image/generate/ultra | 最高档托管生成;也接受可选的初始图像 | 1 MP;1:1 时为 1024x1024 | 8 积分 |
| Stable Image Core | POST /v2beta/stable-image/generate/core | 低成本、快速的托管文生图迭代 | 1.5 MP | 3 积分 |
| SD3.5 套件 | POST /v2beta/stable-image/generate/sd3 | 明确选择基础模型和 cfg_scale;支持文生图或图生图 | 1 MP;1:1 时为 1024x1024 | Large 6.5、Large Turbo 4、Medium 3.5、Flash 2.5 积分 |
文档列出的 SD3.5 标识符为 sd3.5-large、sd3.5-large-turbo、sd3.5-medium 和 sd3.5-flash。默认使用 Large。提供方将 Turbo 和 Flash 描述为经过四步蒸馏的变体。**文档不一致:**API 说明和定价列表包含 Flash,但检查时可下载的 OpenAPI model 枚举中未包含 sd3.5-flash。如果需要使用 Flash,请先在目标账户中以一次低成本调用进行验证,然后再批量处理;遇到 400 时应妥善处理,不要在未告知的情况下切换模型。API 参考、定价
编辑
| 操作 | 端点 | 必填字段 | 重要的可选字段 | 输出/价格 |
|---|---|---|---|---|
| 擦除 | /v2beta/stable-image/edit/erase | image;蒙版文件或图像 alpha 通道决定编辑区域 | mask、grow_mask(0-20,默认 5)、seed、output_format | 4 MP/5 点数 |
| 局部重绘 | /v2beta/stable-image/edit/inpaint | image、prompt;蒙版文件或 alpha 通道决定编辑区域 | mask、negative_prompt、grow_mask(0-100,默认 5)、style_preset、seed、output_format | 4 MP/5 点数 |
| 扩图 | /v2beta/stable-image/edit/outpaint | image,以及至少一个非零方向值 | left、right、up、down 均为 0-2000;prompt;creativity(0-1,默认 .5);style_preset、seed、output_format | 4 点数 |
| 搜索并替换 | /v2beta/stable-image/edit/search-and-replace | image、替换用的 prompt、search_prompt | negative_prompt、grow_mask(0-20,默认 3)、style_preset、seed、output_format | 4 MP/5 点数 |
| 搜索并重新着色 | /v2beta/stable-image/edit/search-and-recolor | image、重新着色用的 prompt、select_prompt | negative_prompt、grow_mask(0-20,默认 3)、style_preset、seed、output_format | 输入分辨率/5 点数 |
| 移除背景 | /v2beta/stable-image/edit/remove-background | image | output_format 只能是 png 或 webp | 支持透明效果的输出/5 点数 |
| 替换背景并重新布光 | /v2beta/stable-image/edit/replace-background-and-relight | subject_image,以及 background_prompt 和/或 background_reference | foreground_prompt、negative_prompt、preserve_original_subject(0-1,默认 .6)、original_background_depth(0-1,默认 .5)、keep_original_background、light_source_direction、light_reference、light_source_strength(0-1,默认 .3)、seed、output_format | 异步/8 点数 |
关于蒙版,**文档说明:**黑色表示保留,白色表示以最大强度编辑,灰色表示部分强度。显式指定的 mask 会覆盖图像 alpha 通道。如果未提供显式蒙版,则透明像素会被编辑,非透明像素会被保留。尺寸不同的蒙版会自动调整大小。尽管如此,仍建议使用与图像相同尺寸的蒙版,以便 QA 能准确判断边界。API 参考
**规格缺陷,已于 2026-07-09 验证:**可下载的 OpenAPI 将未声明的 prompt 标记为 Erase 的必填字段,但端点说明和官方示例要求的仅为 image,mask 则为可选。请遵循说明/示例。如果服务返回架构错误,请记录响应中的 id,并重新核对最新参考文档,而不是自行编造提示词。
Control
| 操作 | 端点 | 请求 | 控制语义 | 输出 / 价格 |
|---|---|---|---|---|
| Sketch | /v2beta/stable-image/control/sketch | 必需的 image、prompt;可选的 control_strength、negative prompt、seed、style、format | 轮廓/边缘引导结果;强度范围为 0-1,默认值为 .7 | 输入分辨率 / 5 积分 |
| Structure | /v2beta/stable-image/control/structure | 与 Sketch 相同的架构 | 输入构图/结构引导结果;强度范围为 0-1,默认值为 .7 | 输入分辨率 / 5 积分 |
| Style Guide | /v2beta/stable-image/control/style | 必需的风格 image、prompt;可选的 aspect_ratio、fidelity、negative prompt、seed、preset、format | 参考风格引导全新构图;fidelity 范围为 0-1,默认值为 .5 | 1 MP / 5 积分 |
| Style Transfer | /v2beta/stable-image/control/style-transfer | 必需的 init_image、style_image;可选的 prompt、negative prompt、seed、format | 在保留构图的同时转换现有内容;style_strength 默认值为 1,composition_fidelity 默认值为 .9,change_strength 默认值为 .9 | 按 init 宽高比输出 1 MP / 8 积分 |
线条/边缘意图使用 Sketch,布局/几何结构使用 Structure,使用 Style Guide 按参考美学创作新内容,使用 Style Transfer 为现有内容重新设置风格。不要承诺身份一致性、精确的像素布局、Logo 保真度或确定性的风格复制;请通过视觉检查验证每项要求。
放大
| 操作 | 端点 | 请求和限制 | 行为 | 输出 / 价格 |
|---|---|---|---|---|
| Fast | /v2beta/stable-image/upscale/fast | image;宽度和高度为 32-1536,总像素为 1,024-1,048,576 | 尺寸放大 4 倍,进行轻量增强 | API 参考文档称最高 16 MP / 2 积分 |
| Conservative | /v2beta/stable-image/upscale/conservative | image、prompt;图片每边至少为 64 像素,像素数为 4,096-9,437,184,宽高比为 1:2.5-2.5:1 | 目标是保留而非重新诠释;文档记录的 creativity 基础范围为 .2-.5,默认值为 .35 | 4 MP / 40 积分 |
| Creative | /v2beta/stable-image/upscale/creative | image、prompt;输入每边至少为 64 像素,且像素数不超过 1,048,576 | 对低于 1 MP 的退化输入进行大幅重新创作;creativity 范围为 .1-.5,默认值为 .3 | 异步 / 60 积分 |
当精确的产品几何形状、面部、文字、证据或忠实修复很重要时,不要使用 Creative。**生产环境启发式:**先比较 Fast,再比较 Conservative;只有在可以接受重新诠释时才使用 Creative。目前的定价页面与在线 OpenAPI 对 Creative 的价格均标为 60 积分;较早收录的文档可能仍显示 40,因此审批时请以定价页面为准。
**当前文档冲突:**Fast Upscaler API 参考文档说明输出最高为 16 MP,而当前定价页面标明最高为 4 MP。在目标账户探测并获得当前支持指导确认之前,请将 4 MP 视为保守的预算/交付承诺;记录输入尺寸,并拒绝意外的结果尺寸。
**文档不一致:**Fast 端点参考文档称尺寸可放大 4 倍,最高达 16 MP,而当前定价说明称最高为 4 MP。不要依据营销文案约定最高规格;请用有代表性的尺寸对在线端点进行预检,并在批量处理前验证返回的文件。文档称 Creative 可达到“4K”,但架构并未承诺某一组精确的宽高。Outpaint 和 Relight 的操作摘要同样未公布固定的输出分辨率保证。
精确的传输与响应约定
身份验证和标头
使用基 URL https://api.stability.ai。发送:
Authorization: Bearer <STABILITY_API_KEY>
Accept: image/*
所有图像 POST 请求正文均为 multipart/form-data。让 HTTP 库设置 Content-Type 及其 boundary;不要硬编码 multipart/form-data。可选诊断标头为 stability-client-id、stability-client-user-id 和 stability-client-version,每个最多 256 个字符。对最终用户 ID 进行混淆处理。将密钥存储在密钥管理器或环境变量中,绝不要将密钥打包进浏览器代码。API 密钥指南
文档记录的访问权限和价格依据,已于 2026-07-09 核实: 创建 Platform 账户和密钥;新账户宣传可获得 25 个试用积分,账户最多可持有 10 个有效密钥,目前 1 个积分为 $0.01。价格可能变动。不同环境使用不同密钥,但获取异步生成结果时,必须使用发起该生成任务的同一密钥。审批前请立即检查账户余额和当前价格。API 密钥指南、定价
二进制字节使用 Accept: image/*,base64 JSON 使用 Accept: application/json。同步请求成功时:
- 二进制响应:图像字节;读取
content-type、x-request-id、finish-reason和seed标头。 - JSON 响应:
{ "image": "<base64>", "seed": 343940597, "finish_reason": "SUCCESS" }。 finish-reason/finish_reason的值为SUCCESS或CONTENT_FILTERED。即使 HTTP 状态码为 200,也应将经过过滤的输出视为 QA 未通过。
常见错误的 JSON 格式为 { "id": "...", "name": "...", "errors": ["..."] }。保存响应中的 id 以便支持人员排查,但不要保存密钥或敏感源内容。
常用字段和约束
prompt:在要求填写时为 1-10,000 个字符。某些编辑/控制提示词规定使用(word:weight)格式,权重范围为 0 到 1。negative_prompt:最多 10,000 个字符。seed:0-4,294,967,294。省略该字段或发送0可使用随机种子。保存返回的种子,而不只是请求的值。output_format:png、jpeg或webp;Remove Background 仅支持png或webp。- 生成图像的宽高比:
21:9、16:9、3:2、5:4、1:1、4:5、2:3、9:16、9:21;默认值为1:1。 - 风格预设:
enhance、anime、photographic、digital-art、comic-book、fantasy-art、line-art、analog-film、neon-punk、isometric、low-poly、origami、modeling-compound、cinematic、3d-model、pixel-art、tile-texture。提供方表示此列表可能变更。 - 上传的图像格式为 JPEG、PNG 或 WebP。大多数编辑/控制输入要求每边至少 64 像素,总像素数为 4,096-9,437,184;许多接口还要求宽高比为 1:2.5-2.5:1。Remove Background 的总像素数上限为 4,194,304。请遵循各接口的 schema,不要将其视为通用规则。
- 这些 v2beta 图像调用的请求载荷上限为 10 MiB。
对于 SD3.5 文本生成图像,aspect_ratio 有效;对于图像生成图像,应改为发送 mode=image-to-image、image 和 0-1 的 strength。strength 为 0 时保留输入图像;为 1 时则趋近于无图像条件。cfg_scale 范围为 1-10;文档中 Large/Medium 的默认值为 4,Turbo/Flash 的默认值为 1。Stability 建议 Flash 图像生成图像使用 .94-.97 的 strength。Ultra 接受可选的 image 和 strength,无需 SD3.5 的 mode 字段。根据文档中的 schema,Core 仅支持文本生成图像。
同步与异步
除 Creative Upscale 和 Replace Background and Relight 外,所有列出的调用都会同步返回 HTTP 200 图像响应:
- 发送 POST multipart 请求。
- 解析
{ "id": "<64-character generation id>" }。 - 使用相同的 API key轮询
GET /v2beta/results/{id}。 - 每次轮询至少间隔 10 秒。
202表示正在处理中;200返回结果;404表示 ID 错误、属于另一个密钥,或已过期。 - 立即下载。结果会保留 24 小时,之后删除。
文档将异步启动响应标记为 HTTP 200,尽管一些较早的客户端习惯预期 202。对于图像端点,应接受文档注明的状态码,并要求响应正文包含 id。不要将 Platform 通用输入/输出保留期限视为 24 小时:该期限仅适用于异步结果检索。
完整可执行示例:一个符合生产场景的 Python 客户端
这是一个示例,并非强制架构。它涵盖同步 Core 生成、带蒙版的 Inpaint,以及异步 Creative Upscale。由于 API 文档未说明幂等键,因此不会针对结果不明确的付费 POST 请求自动重试。
import base64
import hashlib
import json
import os
import sys
import time
from contextlib import ExitStack
from datetime import datetime, timezone
from email.utils import parsedate_to_datetime
from pathlib import Path
import requests
from PIL import Image
BASE = "https://api.stability.ai"
KEY = os.environ["STABILITY_API_KEY"]
SESSION = requests.Session()
SESSION.headers.update({
"authorization": f"Bearer {KEY}",
"stability-client-id": "image-pipeline",
"stability-client-version": "1.0.0",
})
class StabilityError(RuntimeError):
pass
def sha256_file(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
for chunk in iter(lambda: stream.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def retry_after_seconds(value: str | None) -> float:
if not value:
return 60.0
try:
return max(60.0, float(value))
except ValueError:
try:
when = parsedate_to_datetime(value)
if when.tzinfo is None:
when = when.replace(tzinfo=timezone.utc)
return max(60.0, (when - datetime.now(timezone.utc)).total_seconds())
except (TypeError, ValueError, OverflowError):
return 60.0
def error_payload(response: requests.Response) -> dict:
try:
body = response.json()
return body if isinstance(body, dict) else {"body": body}
except ValueError:
return {"body": response.text[:1000]}
def fail(response: requests.Response, context: str) -> None:
payload = error_payload(response)
request_id = payload.get("id") or response.headers.get("x-request-id")
raise StabilityError(
f"{context}: HTTP {response.status_code}; request_id={request_id}; "
f"error={json.dumps(payload, ensure_ascii=False)}"
)
def detect_image_type(raw: bytes) -> str:
if raw.startswith(b"\x89PNG\r\n\x1a\n"):
return "image/png"
if raw.startswith(b"\xff\xd8\xff"):
return "image/jpeg"
if len(raw) >= 12 and raw[:4] == b"RIFF" and raw[8:12] == b"WEBP":
return "image/webp"
raise StabilityError("Output does not have a recognized PNG, JPEG, or WebP signature")
def write_image(response: requests.Response, output: Path) -> dict:
transport_type = response.headers.get("content-type", "").split(";", 1)[0].lower()
if transport_type == "application/json":
payload = response.json()
encoded = payload.get("image")
if not isinstance(encoded, str) or not encoded:
raise StabilityError("JSON success response is missing image base64")
try:
raw = base64.b64decode(encoded, validate=True)
except Exception as exc:
raise StabilityError("JSON image field is not valid base64") from exc
seed = payload.get("seed")
finish_reason = payload.get("finish_reason")
elif transport_type.startswith("image/"):
raw = response.content
seed = response.headers.get("seed")
finish_reason = response.headers.get("finish-reason")
else:
raise StabilityError(f"Unexpected success content-type: {transport_type}")
if finish_reason != "SUCCESS":
raise StabilityError(f"Generation finished as {finish_reason}; do not publish")
if len(raw) < 100:
raise StabilityError("Image payload is implausibly small")
image_type = detect_image_type(raw)
if transport_type.startswith("image/") and transport_type != image_type:
raise StabilityError(f"Header says {transport_type}, bytes are {image_type}")
allowed_suffixes = {
"image/png": {".png"},
"image/jpeg": {".jpg", ".jpeg"},
"image/webp": {".webp"},
}
if output.suffix.lower() not in allowed_suffixes[image_type]:
raise StabilityError(f"Output extension {output.suffix} does not match {image_type}")
output.parent.mkdir(parents=True, exist_ok=True)
output.write_bytes(raw)
return {
"path": str(output),
"sha256": hashlib.sha256(raw).hexdigest(),
"seed": seed,
"request_id": response.headers.get("x-request-id"),
"transport_content_type": transport_type,
"image_content_type": image_type,
}
def request_manifest(endpoint: str, data: dict, file_paths: dict, context: dict) -> dict:
return {
"endpoint": endpoint,
"service": context["service"],
"model": context["model"],
"credit_estimate": context["credits"],
"request_fields": dict(data),
"requested_seed": data.get("seed"),
"input_sha256": {name: sha256_file(path) for name, path in file_paths.items()},
"policy_qa_disposition": "pending human review",
}
def multipart_files(stack: ExitStack, file_paths: dict) -> dict:
if not file_paths:
return {"none": ("", b"")} # Force a requests-generated multipart boundary.
return {
name: stack.enter_context(path.open("rb"))
for name, path in file_paths.items()
}
def sync_post(
endpoint: str, *, data: dict, file_paths: dict, output: Path, context: dict
) -> dict:
# A 429 is a documented rate-limit rejection; reopen every stream before retrying.
manifest = request_manifest(endpoint, data, file_paths, context)
for attempt in range(2):
with ExitStack() as stack:
response = SESSION.post(
BASE + endpoint,
data=data,
files=multipart_files(stack, file_paths),
headers={"accept": "image/*"},
timeout=(15, 180),
)
if response.status_code == 429 and attempt == 0:
time.sleep(retry_after_seconds(response.headers.get("retry-after")))
continue
if response.status_code != 200:
fail(response, endpoint)
metadata = write_image(response, output)
metadata.update(manifest)
return metadata
raise AssertionError("unreachable")
def async_post(
endpoint: str, *, data: dict, file_paths: dict, output: Path, context: dict
) -> dict:
manifest = request_manifest(endpoint, data, file_paths, context)
with ExitStack() as stack:
start = SESSION.post(
BASE + endpoint,
data=data,
files=multipart_files(stack, file_paths),
headers={"accept": "application/json"},
timeout=(15, 180),
)
if start.status_code != 200:
fail(start, endpoint)
generation_id = start.json().get("id")
if not isinstance(generation_id, str) or len(generation_id) != 64:
raise StabilityError(f"Missing/invalid async id: {start.text[:500]}")
deadline = time.monotonic() + 15 * 60
while time.monotonic() < deadline:
time.sleep(10)
result = SESSION.get(
f"{BASE}/v2beta/results/{generation_id}",
headers={"accept": "image/*"},
timeout=(15, 180),
)
if result.status_code == 202:
continue
if result.status_code != 200:
fail(result, f"poll {generation_id}")
metadata = write_image(result, output)
metadata["generation_id"] = generation_id
metadata.update(manifest)
return metadata
raise TimeoutError(f"Generation {generation_id} did not finish before local deadline")
def run_core() -> dict:
return sync_post(
"/v2beta/stable-image/generate/core",
file_paths={},
data={
"prompt": (
"Editorial product photograph of a matte cobalt travel mug on pale gray stone, "
"three-quarter view, soft north-window light, restrained shadow, no text"
),
"negative_prompt": "logo, watermark, extra handles, warped rim",
"aspect_ratio": "4:5",
"seed": "18472931",
"output_format": "webp",
},
output=Path("outputs/mug-core.webp"),
context={"service": "Stable Image Core", "model": "managed-core", "credits": 3},
)
def run_inpaint() -> dict:
return sync_post(
"/v2beta/stable-image/edit/inpaint",
file_paths={"image": Path("inputs/room.png"), "mask": Path("inputs/mask.png")},
data={
"prompt": "a low walnut side table matching the room perspective and warm light",
"negative_prompt": "people, text, floating furniture",
"grow_mask": "6",
"seed": "482019",
"output_format": "png",
},
output=Path("outputs/room-inpaint.png"),
context={"service": "Stable Image Inpaint", "model": "managed-edit", "credits": 5},
)
def run_creative_upscale() -> dict:
source = Path("inputs/degraded-portrait.jpg")
if source.stat().st_size > 9 * 1024 * 1024:
raise StabilityError("Creative Upscale input exceeds the conservative 9 MiB file gate")
with Image.open(source) as image:
width, height = image.size
if image.format not in {"JPEG", "PNG", "WEBP"}:
raise StabilityError(f"Unsupported input format: {image.format}")
pixels = width * height
if width < 64 or height < 64 or not 4_096 <= pixels <= 1_048_576:
raise StabilityError(f"Creative Upscale input is outside documented bounds: {width}x{height}")
return async_post(
"/v2beta/stable-image/upscale/creative",
file_paths={"image": source},
data={
"prompt": "natural editorial portrait, realistic skin texture, soft daylight",
"negative_prompt": "plastic skin, altered identity, text, watermark",
"creativity": "0.2",
"seed": "92173",
"output_format": "png",
},
output=Path("outputs/portrait-upscaled.png"),
context={"service": "Creative Upscale", "model": "managed-upscaler", "credits": 60},
)
if __name__ == "__main__":
modes = {"core": run_core, "inpaint": run_inpaint, "creative-upscale": run_creative_upscale}
if len(sys.argv) != 2 or sys.argv[1] not in modes:
raise SystemExit(f"usage: {sys.argv[0]} {'|'.join(modes)}")
print(json.dumps(modes[sys.argv[1]](), indent=2))
运行前:安装 requests 和 Pillow,设置 STABILITY_API_KEY,仅创建所选模式所需的输入文件,查看当前积分,并获得付费生成的批准。Creative 示例使用较低的创造性设置,但仍可能改变身份特征;请勿将其用于身份特征至关重要的修复。
提示词与控制实践
生产启发式方法: 将提示词写成按顺序排列的制作说明:主体与动作;构图/相机;材质与光线;环境;风格/润色;仅在必要时提供准确的可见文字。尽量描述具体关系,而不是堆砌形容词。负面提示词应简短并针对具体缺陷;不要将整段正面提示词复制到负面字段中。
使用种子来比较一项受控变更,而不要将其视为永久可复现的保证。托管模型/服务更新、安全系统以及未公开的后端变更,都可能导致相同请求产生不同输出。请保留输入、请求字段、返回的种子、日期和实际输出。
对于图像中的文字,请用引号标出所需的准确字符串,说明位置和字体排版;如果拼写具有合同约束力,请预留手动排版的空间。对于品牌和产品,仅在权利允许的情况下使用编辑/控制参考,然后以 100% 缩放检查徽标、几何形状、标签和法律标记。不要依赖负面提示词来执行法律或安全政策。
对于外扩图像,在可行时分阶段扩展,每次扩展不超过源图像尺寸;提供商明确建议,出于质量考虑,方向值不要超过源图像尺寸。每个阶段之后都应检查原始边界、透视延续、重复纹理、主体重复和光线偏移。
故障处理
| 状态/条件 | 含义 | 操作 |
|---|---|---|
200 + SUCCESS | 传输成功,可用 | 仍需进行内容和技术 QA |
200 + CONTENT_FILTERED | 输出违反审核规则,已被模糊处理 | 拒绝;不要发布,也不要尝试规避安全措施 |
| 400 | 参数/架构无效 | 不要原样重试;对照特定端点字段和官方参考文档 |
| 401 | 缺少/密钥无效,或身份验证格式错误 | 停止;验证密钥来源和 Bearer 格式;绝不要记录密钥 |
| 403 | 审核/策略标记或权限失败 | 停止;检查策略和权利;不要自动改写以规避过滤 |
| 413 | 请求超过 10 MiB | 调整大小/重新编码,同时遵守端点的像素/宽高比限制 |
| 422 | 格式正确但遭拒,包括文档说明的语言/公众人物相关情形 | 阅读 errors;仅在合法且符合策略时更改方案 |
| 429 | 每 10 秒超过 150 个请求;文档说明会超时 60 秒 | 至少暂停 60 秒,遵守 Retry-After,降低并发,并加入随机抖动 |
| 500 | 内部错误 | 保留响应 ID;仅在获批的成本/幂等性策略范围内重试 |
| POST 后超时/连接中断 | 结果可能不明确 | 不要盲目重复付费 POST;检查账户遥测数据/联系支持,或就可能产生的重复费用取得批准 |
| 异步 202 | 仍在处理中 | 至少等待 10 秒后再轮询 |
| 异步 404 | 密钥/ID 错误或结果已过期 | 验证是否使用同一密钥以及结果时效;仅在获得批准后重新生成 |
公开速率限制为每 10 秒 150 个请求;超出限制会返回 429,并导致 60 秒超时。速率限制和成本是两种不同的控制措施:使用令牌桶控制吞吐量,并为每个任务单独设置额度预算。Stability 表示失败的生成不会收费,但网络结果不明确时,仍应谨慎重试。速率限制指南
生产环境 QA 与验收
生成前先定义验收标准,然后对每个候选结果进行评分:
- **意图:**主体数量、动作、构图、必需/禁止元素、精确文本。
- **解剖结构与几何:**手部、面部、关节、反射、阴影、透视、重复结构、产品轮廓。
- **编辑局部性:**目标区域已更改;受保护区域未更改;没有光晕、接缝、颜色溢出或纹理不连续。
- **参考保真度:**根据所选控制项保留构图、风格或主体;不要混淆这些目标。
- **技术:**尺寸、宽高比、Alpha、格式、色彩表现、损坏情况和文件哈希。
- **安全与权利:**同意、公开权/隐私、商标/版权、未成年人、敏感属性、误导性语境、披露。
- **来源:**在移除元数据的转换前保留提供方的原始输出;如果交付要求提供来源信息,则使用支持 C2PA 的验证器验证凭据。
**生产启发式:**选择模型、强度或控制设置时,对带有随机种子的 A/B 样本进行盲审。每次只更改一个变量。记录拒绝原因,而不是只保留优胜结果;失败分布有助于批次规划。
托管式与开放权重模型的权利
不要混淆以下制度:
- **托管式 Platform API:**受 Stability 当前的服务条款、可接受使用政策、隐私政策和服务定价约束。在用户与 Stability 之间,用户保留对输入内容的权利;Stability 在法律和合规要求允许的范围内转让其对输出内容可能拥有的权利。其他人也可能生成类似输出,用户仍须对内容的合法性和适当性负责。服务条款禁止将 AI 输出称为人工生成的内容。服务条款
- **自托管 Core Models:**以各模型仓库的实际许可证为准。SD3.5 系列列为受 Stability AI Community License 许可。该许可证允许研究、非商业和有限商业用途;商业用户必须注册;当用户及其关联方的年收入超过 USD $1M 时,免费商业许可证将终止,并需申请 Enterprise 许可证。分发、署名和 AUP 义务仍然适用。不要将此门槛用作托管式 API 调用的定价规则。许可证概览,SD3.5 Large 模型卡片/许可证
- **其他检查点:**不要假设 SDXL、较早发布的 SD、微调模型、第三方适配器或社区检查点使用相同的许可证。请检查确切的模型及其包含的每个组件。
这是操作指南,不构成法律意见。对于高价值、受监管、涉及肖像、训练、再分发或模型托管的用途,请咨询法律顾问。
隐私、安全与来源证明
**文档说明:**Stability 可能会使用 Platform 输入和输出改进和开发服务并训练模型,但 Platform API 用户可以在账户概览中将“Training: Improve the Model for Everyone”设为“No”,选择退出。通用隐私政策并未承诺同步图像输入/输出会有统一的短期保留期限。不要基于假定的 24 小时删除期限发送机密信息、不必要的个人数据、生物识别材料或客户机密图像。隐私中心,隐私政策
**文档说明:**托管式 API 会应用提示词/输出安全过滤器;发行说明描述了输入过滤、NSFW 过滤、通过 Thorn 进行已知 CSAM 过滤、C2PA 签名和水印。请保留原件,因为后续转换、重新压缩、截图或编辑可能会移除或使来源证明信号失效。不要声称每个衍生内容都保证带有可见水印或完整的 C2PA 清单。发行说明,安全
要求用户为成年人,并遵守当前的 AUP。该政策禁止侵犯权利/隐私、剥削儿童、露骨色情内容、未经同意的私密影像、规避安全措施、有害/欺骗性用途、错误信息,以及未经同意或合法授权的冒充。对于可识别人物和上传的参考素材,请取得同意并确保拥有合法权利。API 响应成功不代表已获得法律许可。可接受使用政策
迁移与变更控制
- 自 2025-04-17 起,Stable Diffusion 3.0 标识符
sd3-large、sd3-large-turbo和sd3-medium已自动路由到对应的 SD3.5 模型。请将别名替换为明确的 SD3.5 标识符,使日志反映实际意图。 - Stable Diffusion 1.6 API 和 Stable Video Diffusion API 已于 2025-07-24 停止支持。对于旧版图像生成,提供方曾将 SDXL 列为迁移选项;但新项目应根据明确的需求评估 Core、Ultra 或 SD3.5,而不是默认沿用 SDXL。
- 于 2024-10-11 弃用的模型包括
stable-diffusion-512-v2-1、stable-diffusion-xl-beta-v2-2-2、stable-diffusion-xl-1024-v0-9和esrgan-v1-x2plus。新示例中不要使用这些 ID。 - 迁移前,先采集一组有代表性的基准样本;比较提示词遵循度、文本、身份、几何形状、安全结果、延迟、返回分辨率和积分。不要在生产批处理中悄然切换提供方、端点、模型或保真度设置。
- 对可固定的内容进行固定:端点路径、明确的模型、请求字段和客户端版本。请注意,Core/Ultra 等托管服务可能会在稳定名称下持续演进。
官方来源
验证日期:2026-07-09: