11. 生图插件配置
目标
让 QQ 机器人可以通过 LangBot 插件调用 OpenAI 兼容的生图接口。
本次实际使用的是中转站接口:
https://image.codesonline.dev/v1/images/generations接口返回格式为:
{
"data": [
{
"url": "https://free.codesonline.dev/p/img/..."
}
]
}因此 LangBot 插件只需要拿到 data[0].url,再把图片或图片链接返回 QQ。
路线选择
一开始尝试过 Dify 工作流:
QQ -> LangBot -> Dify workflow -> 生图中转站 -> image_urlDify 工作流本身能跑通,curl 调用 Dify API 也能返回:
{
"data": {
"outputs": {
"image_url": "https://free.codesonline.dev/p/img/..."
}
}
}但 LangBot 内置 Dify runner 在 workflow streaming/chunked 场景下出现过:
httpx.RemoteProtocolError: peer closed connection without sending complete message body所以生图最终不走 Dify,改为:
QQ -> LangBot 插件 -> OpenAI 兼容图片接口这条链路更短,也更容易排错。
官方插件
LangBot 官方 demo 里有一个可用插件:
AIImagePlugin仓库:
https://github.com/langbot-app/langbot-plugin-demo/tree/main/AIImagePlugin插件结构:
AIImagePlugin
├── main.py
├── manifest.yaml
├── requirements.txt
├── assets
├── components
│ └── commands
│ ├── draw.py
│ └── draw.yaml
└── readme默认命令:
!draw prompt例如:
!draw a cute cat如果群聊流水线要求 @ 机器人,则使用:
@机器人 !draw a cute cat安装插件
在服务器执行:
cd /tmp
rm -rf langbot-plugin-demo
git clone https://github.com/langbot-app/langbot-plugin-demo.git如果没有 git,可以用压缩包:
cd /tmp
rm -rf langbot-plugin-demo langbot-plugin-demo.tar.gz langbot-plugin-demo-main
curl -L https://github.com/langbot-app/langbot-plugin-demo/archive/refs/heads/main.tar.gz -o langbot-plugin-demo.tar.gz
tar -xzf langbot-plugin-demo.tar.gz
mv langbot-plugin-demo-main langbot-plugin-demo复制插件:
cp -r /tmp/langbot-plugin-demo/AIImagePlugin /root/qq-bot/data/langbot/plugins/确认:
ls -lah /root/qq-bot/data/langbot/plugins/AIImagePlugin修改 manifest
插件配置在:
/root/qq-bot/data/langbot/plugins/AIImagePlugin/manifest.yaml先备份:
cd /root/qq-bot/data/langbot/plugins/AIImagePlugin
cp manifest.yaml manifest.yaml.bak.$(date +%F-%H%M%S)把默认 API 地址改为:
default: https://image.codesonline.dev/v1可以用命令:
sed -i 's#default: https://api.qhaigc.net/v1#default: https://image.codesonline.dev/v1#' manifest.yaml如果要把模型选项改成 gpt-image-2,需要在 model_name 的 options 下加:
- name: gpt-image-2
label:
en_US: gpt-image-2
zh_Hans: gpt-image-2并把默认值改成:
default: gpt-image-2如果要加 16:9,需要在 image_size 的 options 下加:
- name: 16:9
label:
en_US: 16:9
zh_Hans: 16:9并把默认值改成:
default: 16:9注意 YAML 缩进。正确结构是:
- name: gpt-image-2
label:
en_US: gpt-image-2
zh_Hans: gpt-image-2错误结构会导致插件消失或加载失败:
- name: gpt-image-2
label:
en_US: gpt-image-2检查 YAML 关键行:
nl -ba manifest.yaml | sed -n '70,100p'
nl -ba manifest.yaml | sed -n '120,145p'如果日志出现:
Failed to load component manifest manifest.yaml优先检查缩进。
数据库配置
LangBot 插件配置保存在 SQLite:
/root/qq-bot/data/langbot/langbot.db表名:
plugin_settings查看表结构:
sqlite3 /root/qq-bot/data/langbot/langbot.db "PRAGMA table_info(plugin_settings);"查看 AIImagePlugin 配置:
sqlite3 /root/qq-bot/data/langbot/langbot.db \
"SELECT plugin_author, plugin_name, enabled, config FROM plugin_settings WHERE plugin_author='langbot-team' AND plugin_name='AIImagePlugin';"示例配置结构:
{
"api_base_url": "https://image.codesonline.dev/v1",
"openai_api_key": "不要写真实 key 到笔记",
"model_name": "gpt-image-2",
"image_size": "1024x1024"
}如果后台保存后插件暂时从列表消失,可以绕过后台,直接改数据库后重启:
sqlite3 /root/qq-bot/data/langbot/langbot.db \
"UPDATE plugin_settings
SET config = json_set(
config,
'$.api_base_url', 'https://image.codesonline.dev/v1',
'$.model_name', 'gpt-image-2',
'$.image_size', '1024x1024'
)
WHERE plugin_author='langbot-team' AND plugin_name='AIImagePlugin';"然后重启:
cd /root/qq-bot
docker restart qqbot-langbot langbot_plugin_runtime
sleep 15本次实际观察到:
后台点击保存配置 -> 插件可能暂时从列表消失
重启 LangBot 和 plugin runtime -> 插件重新出现所以调试阶段可以先不反复点插件页的保存按钮。
日志检查
查看插件运行时日志:
docker logs --tail 200 langbot_plugin_runtime | grep -iE "AIImage|plugin|插件|error|traceback|openai|image|Failed to load"查看 LangBot 主容器日志:
docker logs --tail 300 qqbot-langbot | grep -iE "AIImage|AI Image|绘图|draw|plugin|插件|Failed|error|traceback"完整搜索 AIImage:
docker logs langbot_plugin_runtime 2>&1 | grep -i "AIImage" | tail -80
docker logs qqbot-langbot 2>&1 | grep -i "AIImage" | tail -80如果看到类似:
GET /api/v1/plugins/langbot-team/AIImagePlugin
GET /api/v1/plugins/langbot-team/AIImagePlugin/config
PUT /api/v1/plugins/langbot-team/AIImagePlugin/config说明后台已经识别并访问了插件。
QQ 流水线调用
插件能在调试里跑通后,要在 QQ 里调用,需要两层匹配:
第一层:LangBot 流水线触发条件命中 QQ 消息
第二层:AIImagePlugin 的 Command 组件识别 !draw主流水线可以直接启用插件,然后测试:
@机器人 !draw a cute cat如果流水线允许前缀触发,可以配置 ! 前缀,之后群里直接发:
!draw a cute cat官方 demo 默认命令是 draw,因此不是:
/draw prompt
!画图 prompt而是:
!draw prompt如果 QQ 里没反应,先看主容器日志是否有:
Processing request from group_xxx
No pipeline_uuid for query如果没有进入流水线,检查:
- 机器人是否绑定流水线。
- 群聊是否要求 @。
- 流水线是否配置了
!前缀。 - 插件是否在这条流水线可用。
常见问题
保存配置后插件消失
现象:
后台保存 AIImagePlugin 配置后,插件列表里暂时看不到它。
重启后又出现。判断:
插件目录和数据库配置通常没坏,可能是保存后的热重载/刷新阶段异常。处理:
cd /root/qq-bot
docker restart qqbot-langbot langbot_plugin_runtime
sleep 15必要时直接改 plugin_settings.config,不要反复在后台保存。
YAML 缩进错误
日志:
Failed to load component manifest manifest.yaml
mapping values are not allowed here
expected <block end>, but found '-'处理:
nl -ba /root/qq-bot/data/langbot/plugins/AIImagePlugin/manifest.yaml | sed -n '70,100p'
nl -ba /root/qq-bot/data/langbot/plugins/AIImagePlugin/manifest.yaml | sed -n '120,145p'检查新增 model_name 或 image_size 选项的缩进。
KeyError: owner
日志里可能看到:
KeyError: 'owner'本次观察中,这个错误不是 AIImagePlugin 独有,之前其他插件也出现过。若机器人主功能正常,可先作为插件存储相关噪声处理。
API Key 安全
不要把中转站 API Key 写入笔记或公开日志。
如果 key 已经在聊天、截图或公开文本中暴露,应到中转站后台重置新 key。
后续优化
官方 demo 使用 openai.AsyncOpenAI:
response = await self.plugin.openai_client.images.generate(
model=model,
prompt=description,
size=size,
n=1,
)如果官方插件对 16:9、quality、style、background 等参数支持不好,可以基于官方插件改一个极简版:
不用 OpenAI SDK
直接 httpx.post("/images/generations")
传 model / prompt / n / size / quality / style / background
读取 data[0].url
返回 image_url这样更贴近中转站文档,也更容易兼容其他 OpenAI 格式图片接口。