生图插件与配置教程

DSH · 插件教程 · 配置导出

生图工具:插件与配置教程

把当前这台 DSH Web 上的生图能力拆开讲清楚:它是哪个插件、接到谁、每个配置项管什么、怎么改、出问题怎么查。内容按机器上的实际配置导出,可以直接当交接材料。

dsh-studio-image-gen 0.2.0 api-key 模式 gpt-image-2.5 hfsy NewAPI 网关 DSH 0.2.1-rc.2

导出时间 2026-10-21 15:22(Asia/Shanghai)。依据 dsh --profile web --dump-config 的组合结果、凭据库中的键名、以及 dsh.service 的运行状态。文中不含任何密钥值。

三句话版本
1. 现在走的是 API Key 模式 + hfsy NewAPI 网关 + gpt-image-2.5,配置已经在跑。
2. 换模型只改 cordis.patch.yml 里的 model(仅 API Key 模式有效),然后重载服务。
3. 换供应商要同时改 baseUrl 和 apiKeyEnv,对方必须提供 OpenAI 兼容的 /images/generations。

这套东西是什么

image_gen 是一个注册给模型调用的工具。用户在对话里说“生成一张……”,模型决定调用它,参数经过 Host 侧插件校验后发到 OpenAI 兼容网关;回来的图片写进 DSH 附件仓,界面渲染成有预览和下载的卡片,会话重载后还能回放同一张。

插件本体是 dsh-studio-image-gen(dsh-image-gen 的 Studio 分支:每张图有稳定的 IMG- 编号,预览卡片浮在对话上方)。它同时提供 Host 半(注册工具、鉴权、HTTP 取图)和浏览器半(工具卡、灯箱、下载)。

一个容易被忽略的设计
模型只拿到一行纯文本(模型名、尺寸、耗时、IMG- 编号),图片字节留在界面元数据里。这样即使当前对话切到不支持视觉的文本模型,历史也不会因为图片块而卡住。

生成链路

对话中的指令prompt
→
模型调用 image_gentool call
→
Host 插件鉴权 · 校验 · 重试 · 并发
→
hfsy /images/generationshttps 网关
→
DSH 附件仓不可变附件
→
工具卡显影 → 成图 → 预览/下载

旁路两条:卡片通过 Host 私有路由按 sessionId + callId 取图;归属索引写进 $DSH_HOME/image-gen-index/,会话删掉后由后台清扫。

现网快照

插件包
dsh-studio-image-gen 0.2.0
link: /home/ubuntu/dsh/plugins/dsh-studio-image-gen
Host 配置项
image-gen
profile web · bundles 已含本插件
宿主版本
DSH 0.2.1-rc.2
Node v22.23.0 · web profile
服务
dsh.service
127.0.0.1:13080 · 用户级 systemd
认证模式
api-key
不走 Codex 订阅
凭据引用
HFSY_API_KEY
已在 ~/.dsh/.credentials.yaml 中
默认模型
gpt-image-2.5
可被单次调用覆盖
网关
hfsyapi.cn/v1
https://www.hfsyapi.cn/v1
超时 / 并发 / 重试
120s / 2 / 2 次
默认值,未被覆盖
取图路由
/api/dsh-image-gen/image
GET/HEAD · 需会话归属
成图存储
~/.dsh/attachments
约 102 MB(全仓)
归属索引
$DSH_HOME/image-gen-index
当前 0 条 · 启动 90s 后清扫,之后每 6h
与运行时的一致性
服务在 11:00:54 启动;此后 cordis.patch.yml 只在 15:19 改过主题偏好(dark → light),image-gen 段落自 14:27 的快照以来逐字节相同。所以上面的值就是进程正在用的值,而不是“下次重启才生效”的值。

配置放在哪

路径作用改它会发生什么
~/.dsh/profiles/web/package.json 依赖声明 + dsh.profile.bundles 列表 决定插件是否被装进 profile、是否随启动加载
~/.dsh/profiles/web/cordis.patch.yml 本机覆盖层,id: image-gen 的 config 改完必须重载服务;只覆盖写出来的字段
/home/ubuntu/dsh/plugins/dsh-studio-image-gen/cordis.patch.yml 插件自带 bundle patch,只负责 insert 一行 image-gen 一般不动;升级插件时会被覆盖
~/.dsh/.credentials.yaml 凭据仓库,refs 下是按名字索引的密钥 写入后由凭据服务热发布,无需重启

合并顺序是 插件 schema 默认值 → bundle patch → profile patch。profile patch 里没写的键一律落回默认值,所以覆盖层可以只保留真正要改的 4 行:

~/.dsh/profiles/web/cordis.patch.yml(当前生效片段)
# 生图插件:使用 hfsy NewAPI 网关(OpenAI 兼容 images/generations)
- id: image-gen
  config:
    authMode: api-key
    apiKeyEnv: HFSY_API_KEY
    baseUrl: https://www.hfsyapi.cn/v1
    model: gpt-image-2.5
两条硬规矩
密钥只能存在 .credentials.yaml(或凭据页)里,不要写进 patch——patch 会进截图、进 Git、进备份。另外别直接改插件目录里的 cordis.patch.yml,升级会被覆盖,而且与 profile 层的意图混在一起。

配置项全表

“现网”列取自组合后的实际配置;标 已改 的 4 项是相对默认值的覆盖,其余均为 schema 默认。

字段默认现网说明
接入
authMode已改 auto api-key auto:先试 Codex 订阅,非取消类失败再回落到 Key;api-key:只用 Key;codex-subscription:禁止回落
apiKeyEnv已改 OPENAI_API_KEY HFSY_API_KEY 凭据引用名,必须与 .credentials.yaml 的 refs 键完全一致
baseUrl已改 api.openai.com/v1 hfsyapi.cn/v1 网关根地址,插件拼成 <baseUrl>/images/generations;非回环必须是 https,且不能带 query/fragment/账号密码
model已改 gpt-image-2 gpt-image-2.5 部署默认模型,仅 API Key 模式生效;单次调用可用 model 参数覆盖
默认出图参数
defaultSize auto auto 未指定尺寸时的出图尺寸;取值规则见「工具参数」一节
defaultQuality auto auto auto / low / medium / high
defaultOutputFormat png png png / jpeg / webp;Codex 订阅模式只收 PNG
defaultOutputCompression 90 90 0–100,只对 JPEG/WebP 生效;对 PNG 指定压缩会被直接拒绝
defaultBackground auto auto auto 或 opaque;GPT Image 2 不支持透明背景
传输与稳健性
moderation auto auto auto / low,透传给上游审核强度
partialImages 3 3 0–3;API Key 模式下最多展示几张服务端真实局部图(Codex 模式强制 0)
requestTimeoutMs 120000 120000 整次操作超时,允许 10 000–300 000 ms
maxRetries 2 2 0–5;总尝试次数 = maxRetries + 1,只重试 429/5xx/网络类故障
retryBaseMs 1000 1000 100–30 000 ms,指数退避起点(有上限)
maxConcurrent 2 2 1–8;达到上限立刻报错,不排队

凭据与认证模式

模式凭据来源模型接口地址格式 / 渐进图
api-key 当前 apiKeyEnv 指向的 DSH 凭据(现为 HFSY_API_KEY) 配置的 model,可按次覆盖 baseUrl PNG/JPEG/WebP · 最多 3 张真实局部图
codex-subscription dsh-codex-connect 管理的 ChatGPT OAuth 写死 gpt-image-2 固定 chatgpt.com/backend-api/codex 仅 PNG · 无局部图(显影动画代替)
auto 先订阅、失败再回落 Key 随实际走通的通道 随通道 随通道

凭据解析的优先级是:~/.dsh/.credentials.yaml → 进程环境变量 → 启动目录 .env → ~/.dsh/.env。管理库优先,所以凭据页里存过 Key,就不会被 shell 里残留的旧变量顶掉。

为什么这台机器选 api-key
本机没有安装 dsh-codex-connect,也没有 ChatGPT 订阅登录态;加上供应商已经换成 hfsy 网关,只有 API Key 模式能让 baseUrl / model 生效。当前 refs 里已有 HFSY_API_KEY,所以不必在启动环境里再 export 一次。

安装与启用

1

把插件放进 profile

两种等价做法:在凭据齐全的机器上一条命令装进去,或手工保证 package.json 的 dependencies 与 dsh.profile.bundles 都包含它。这是本机现在的做法——依赖指向本地源码目录,方便改。

install
# 本地 link 安装(当前方式)
dsh plugin --profile web add link:/home/ubuntu/dsh/plugins/dsh-studio-image-gen

# package.json 里对应两处:
#   "dependencies":        "dsh-studio-image-gen": "link:/home/ubuntu/dsh/plugins/dsh-studio-image-gen"
#   "dsh.profile.bundles": "dsh-studio-image-gen"
2

存好凭据

在 DSH 的凭据设置里新增一条,名字必须等于 apiKeyEnv(这里是 HFSY_API_KEY)。文件形式就是 ~/.dsh/.credentials.yaml 的 refs 段:

~/.dsh/.credentials.yaml(结构示意,值已省略)
refs:
  HFSY_API_KEY: <你的 hfsy 密钥>
  # 同文件还存有 DEEPSEEK_API_KEY、OPENCODE_GO_API_KEY

凭据服务会热加载这个文件,新增/改名后不用重启;但改了 patch 里的 apiKeyEnv 仍要重载。

3

写覆盖配置

把上面那段 4 行的 image-gen 配置贴进 profile patch。想调默认尺寸、质量、超时,就在同一段里补键,值照抄「配置项全表」的默认列。

4

重载并验证

apply & verify
# 组合结果里看这一段是否生效
dsh --profile web --dump-config | sed -n "/id: image-gen/,/^# ==/p"

# 重载(重启 + 30 次探测 + 失败自动回滚)
~/.dsh/reload-dsh.sh

# 起来了吗
systemctl --user is-active dsh.service
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:13080/

最后在对话里生成一张 1024×1024 的测试图;卡片出现成图、能预览下载,就算链路通了。

怎么调用

不需要写命令,直接描述需求即可;模型会自己拼参数。想控制结果,就把尺寸、画幅、质量、格式写进需求里。

对话示例
# 基础
生成一张电影感 16:9 产品摄影:半透明机械键盘放在深色玻璃桌面上,
紫色轮廓光,浅景深,不要文字。

# 指定尺寸与质量
用 1536x1024、high 质量,画一张海边日落的扁平插画。

# 指定格式(要更小的文件)
生成一张 1024x1024 的贴纸风图标,输出 webp、压缩 80。

# 单次换模型(仅 api-key 模式有效)
用 gpt-image-2pro 生成一张 2048x2048 的科幻城市全景。
工具返回长什么样
正文是一行文本:Generated an image with gpt-image-2.5 (1024×1024, PNG, 18.4s). Image id: IMG-XXXXXX. 之后用户提到这个编号,指的就是这张图。

工具参数

参数取值缺省约束
prompt字符串必填1–32 000 字符,且不超过 64 000 UTF-8 字节
model字符串配置的 model仅 API Key 模式;如 gpt-image-2.5、gpt-image-2pro
sizeauto 或 宽x高defaultSize边长可被 16 整除、单边 ≤ 3840、宽高比 1:3–3:1、总像素 655 360–8 294 400
qualityauto / low / medium / highdefaultQuality—
output_formatpng / jpeg / webpdefaultOutputFormatCodex 订阅模式只接受 PNG
output_compression整数 0–100defaultOutputCompression只对 JPEG/WebP;PNG 传了会报错
backgroundauto / opaquedefaultBackground不支持透明背景
合法尺寸怎么算(几个能直接用的值)

需要同时满足:两边都是 16 的倍数、单边 ≤ 3840、总像素在 655 360–8 294 400 之间、宽高比在 1:3 到 3:1 之间。

可直接用:1024x1024(1:1)、1536x1024(3:2)、1024x1536(2:3)、2048x2048(1:1 高清)、1920x1080(16:9)、1080x1920(竖屏)、3840x2160(4K 上限,正好 8 294 400 像素)。

反例:1000x1000(不是 16 的倍数)、4096x4096(超边且超像素)、3840x480(比例 8:1)。

卡片与图片编号

用途参数说明
缩略图variant=thumb列表/卡片内的小图,WebP,写进 $DSH_HOME/image-gen-cache
预览variant=display默认值,灯箱用
原图variant=orig原始附件字节
下载download=1附上 content-disposition,文件名取提示词前 48 字符

路由形如 /api/dsh-image-gen/image?sessionId=…&callId=…&variant=display。附件是内容寻址的,响应标了 immutable 长缓存,同一 URL 永远对应同一份字节。

改配置与重载

插件配置在启动时组合成快照,改文件不会热生效。改 cordis.patch.yml 之后必须重载。

reload
# 推荐:带健康探测和自动回滚
~/.dsh/reload-dsh.sh

# 脚本做的事:
#   1. 把改动后的文件复制成 cordis.patch.yml.applied
#   2. systemctl --user restart dsh.service
#   3. 每 2 秒探测 13080,最多 30 次
#   4. 起不来就用 cordis.patch.yml.rollback 回滚再重启

# 手动等价(不保留回滚)
systemctl --user restart dsh.service

回滚材料就在 profile 目录:cordis.patch.yml.rollback、.bak.20261021-015536、以及 backups/ 下按时间戳存的副本。

如果通过插件管理界面改
界面会重写整份 cordis.patch.yml,可能把注释和手工排版一起抹掉。习惯手写注释的话,优先直接编辑文件,改完跑重载脚本。

避坑清单

01Codex 模式下 model 被写死

走订阅时请求模型固定为 gpt-image-2,改 patch 里的 model 没用。要换模型,必须让 authMode 落在 api-key(或 auto 实际回落到 key)。

02订阅通道只回 PNG

订阅模式传 output_format 非 png、或传 output_compression,会直接报错,而不是忽略。

03没有透明背景

GPT Image 2 拒绝透明。background 只有 auto 和 opaque,要“抠图效果”请在提示词里写明背景颜色。

04自定义网关的门槛

baseUrl 除回环外必须 https,不能带 query、fragment、账号密码;对方的 /images/generations 要能返回 data[0].b64_json,或发 image_generation.partial_image / completed 的 SSE 事件。

05并发满了直接失败

maxConcurrent 是 2:同时第三张图不会排队等待,而是立刻报“Too many image generations are already running”。批量出图请串行。

06只重试“可恢复”的错

429、5xx、网络/协议类故障会退避重试;内容审核拒绝和参数错误一次就停,重复调用只是浪费额度。

07启动报 webServer 注入错误

插件 inject 必须包含 webServer,否则 0.2.x 下注册 RPC 通道时抛 cannot get property "webServer" without inject,表现为插件静默不激活。

08反代要原样透传 Host

取图路由沿用浏览器的鉴权与同源校验。反向代理若把 Host(含端口)改掉,会出现页面能开、图片 403 的怪现象;nginx 用 $http_host 而不是 $host。

排错对照

症状大概率原因处理
No credential is configured for HFSY_API_KEY refs 里没有这个名字,或大小写/拼写不一致 在凭据页补一条同名凭据,或把 apiKeyEnv 改成已存在的键名后重载
上游返回 401 / 403 Key 失效、额度耗尽,或反代的同源校验没过 先换浏览器直连 13080 复现;再查网关后台的 Key 状态与余额
模型不存在 / model not found 网关没有该模型,或名字拼错 换回 gpt-image-2.5,或对照网关模型列表改 model
404 image not authorized by this session URL 里的 callId 不属于该会话(旧链接、串了会话) 回到原会话从卡片重新打开;别手工拼 URL
请求超时 大尺寸 + high 质量,120s 不够 调大 requestTimeoutMs(≤300 000),或降质量、改 JPEG/WebP
尺寸报错 不是 16 的倍数、超边、比例或像素越界 用「工具参数」里列出的合法值
卡片一直停在显影 上游慢;或反向代理开了缓冲,SSE 局部图不落地 反代关掉 proxy_buffering;订阅模式本来就是非流式,等成图即可
工具在会话里根本不存在 profile 的 bundles 没加插件,或改完没重载 dsh --profile web --dump-config | grep image-gen 确认后重载
图片能生成,刷新后看不见 附件仓不可用,或卡片依赖的浏览器模块没加载 看 Host 日志里的 [image-gen] 记录;确认 ~/.dsh/attachments 可读、页面已刷新到最新 bundle

文件与数据

路径内容
/home/ubuntu/dsh/plugins/dsh-studio-image-gen/src/index.tsHost 入口:配置 schema、工具注册、取图路由、归属索引与清扫
…/src/openai.tsOpenAI 兼容传输:端点拼接、尺寸校验、SSE/JSON 解析、重试
…/src/codex.ts订阅模式:读 dsh-codex-connect 的 OAuth,刷新与固定端点
…/src/client/index.tsx浏览器半:显影动画、局部图淡入、完成卡片、灯箱
…/lib/index.js · lib/client.js构建产物(实际被加载的是这两份)
~/.dsh/profiles/web/cordis.patch.yml本机覆盖配置
~/.dsh/.credentials.yaml凭据仓库(refs)
$DSH_HOME/image-gen-index/*.json每张成图的归属记录:attachmentId、sessionId、hostPath、创建时间
$DSH_HOME/image-gen-cache/缩略图/预览图的 WebP 缓存(尽力而为,可删)
~/.dsh/attachments/v1/不可变成图附件本体(全仓约 102 MB)
~/.dsh/reload-dsh.sh重载脚本:重启 + 探测 + 回滚

会话被删掉后,后台会按索引逐条 stat 对应会话,清掉孤儿图片;启动 90 秒后跑第一次,之后每 6 小时一次,1 小时内新建的条目跳过。所以删会话不会马上腾空间,最多等一轮清扫。

这份文档导出了什么、没导出什么
包含:插件与版本、profile 组合结果、15 个配置项及其现网值、凭据键名、网关地址、取图路由、文件布局与排错路径。
不包含:任何 Key 的值、OAuth token、聊天内容、成图字节。凭据只以名字出现。
生图插件与配置教程 · 导出时间 2026-10-21 15:22(Asia/Shanghai)
依据:dsh --profile web --dump-config(15:21)、~/.dsh/.credentials.yaml 键名、systemctl --user 服务状态、插件源码 0.2.0(git HEAD 68290ee)。
本页为静态文档,可离线保存;部署位置 /var/www/dsh-image-gen-doc/,访问前缀 /image-gen-doc/。