快速开始
这是基于 Google Flow 的私有图片生成 API,完全兼容 OpenAI 的 POST /v1/images/generations 协议,可以直接用 OpenAI 官方 SDK / 任何 OpenAI 兼容的客户端工具来调用,无需改代码。
- 从管理员那里拿到一个邀请链接(形如
https://flow.aizyk.cn/invite/xxxxxx) - 点开链接,输入你的名字 → 自动获得一个
ak_开头的 API key - 把 key 收藏好(只显示一次),下面就用它替换示例里的
YOUR_API_KEY - API Base URL 是
认证方式
所有请求需要在 HTTP Header 里带上:
Authorization: Bearer YOUR_API_KEY
如果 key 错了 / 被禁用了 / 不带这个 header,会返回 401 或 403。
OpenAI 兼容接口
这是推荐用法:跟 OpenAI 的 image 接口几乎一样,同步阻塞等待图片生成完,直接返回图片 URL(或 base64)。
请求
POST /v1/images/generations
{
"prompt": "黑神话悟空 写实风格 4K电影",
"model": "Nano Banana Pro",
"n": 2,
"size": "1792x1024",
"response_format": "url"
}参数
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
prompt | string | 必填 | 提示词,最长 4000 字 |
model | string | Nano Banana Pro | 见支持的模型 |
n | int | 1 | 生成数量,1~4 |
size | string | 1024x1024 | 见支持的尺寸 |
response_format | string | url | url / b64_json |
user | string | - | OpenAI 字段,会被忽略但不会报错 |
响应
{
"created": 1714112345,
"data": [
{
"url": "https://flow.aizyk.cn/files/abc.../image-1.jpg?e=...&s=...",
"revised_prompt": "..."
}
]
}- 返回的 URL 带签名,浏览器 / 任何工具直接打开就能看图,无需鉴权
- URL 默认有效期 30 天
- 用
response_format: "b64_json",返回的是 base64 编码的图片字节,直接 decode 就是 jpg
支持的模型
| 显示名 | 说明 | 别名(都识别) |
|---|---|---|
Nano Banana Pro | 最强模型(默认) | nano-banana-pro / pro / dall-e-3 / gpt-image-1 |
Nano Banana 2 | 次一档,速度快 | nano-banana-2 / dall-e-2 |
Imagen 4 | Google 经典 Imagen | imagen-4 / imagen4 |
model 默认用 Nano Banana Pro。支持的尺寸
| size | 实际比例 | 用途 |
|---|---|---|
1024x1024 / 1:1 | 方形 1:1 | 头像、icon、缩略图 |
1792x1024 / 16:9 | 横屏 16:9 | 电影截图、桌面壁纸、横版海报 |
1024x1792 / 9:16 | 竖屏 9:16 | 抖音/小红书封面、手机壁纸 |
SDK 示例
因为完全兼容 OpenAI,可以直接用官方 SDK,只需要改两个参数:api_key 和 base_url。
Python(OpenAI 官方 SDK)
装包:
pip install openai代码:
下载图片到本地:
import httpx
url = resp.data[0].url
img_bytes = httpx.get(url).content
with open("output.jpg", "wb") as f:
f.write(img_bytes)或者直接拿 base64(不走 URL):
import base64
resp = client.images.generate(prompt="cat", response_format="b64_json")
img_bytes = base64.b64decode(resp.data[0].b64_json)
open("cat.jpg", "wb").write(img_bytes)Node.js / TypeScript(OpenAI 官方 SDK)
装包:
npm install openai代码:
curl / PowerShell
curl(Linux / macOS / Windows 11+):
PowerShell:
第三方工具接入
任何"自定义 OpenAI 接口"的工具都能用。在工具里配置:
| 字段 | 填什么 |
|---|---|
| API Type | OpenAI / OpenAI 兼容 |
| API Base URL / Endpoint | |
| API Key | 你的 ak_xxxxx |
| 模型名 | Nano Banana Pro 或 dall-e-3 |
常见工具
- Cherry Studio:设置 → 模型服务 → 添加 → 类型选 OpenAI → Base URL 填上面的
- NextChat / ChatGPT-Next-Web:自定义接口 → 接入点 = Base URL
- Lobe Chat:设置 → 语言模型 → OpenAI → API Proxy Address
- One-API / New-API(中转站):渠道 → 添加 → 类型 OpenAI → Base URL 填上面的,模型映射
dall-e-3 → Nano Banana Pro - ComfyUI / SD WebUI:装 OpenAI image 插件后填 Base URL 即可
原生异步接口(高级)
需要"先快速把任务塞进队列、稍后再来取结果"(比如批量生图、不想阻塞)时用。
查询自己的信息
GET /v1/me
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://flow.aizyk.cn/v1/me提交任务(异步)
POST /v1/images/generate — 立即返回 task_id,需要轮询查状态。
curl -X POST https://flow.aizyk.cn/v1/images/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"a cat","count":2,"model":"Nano Banana Pro"}'
# 返回:{"task_id":"abc...","status":"queued"}轮询:GET /v1/tasks/<task_id>
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://flow.aizyk.cn/v1/tasks/abc...
# {
# "task_id": "abc...",
# "status": "completed", // queued / running / completed / failed
# "images": ["https://flow.aizyk.cn/files/abc.../image-1.jpg?e=...&s=..."],
# "error": null
# }列出自己最近任务:GET /v1/tasks?limit=50
错误码
| HTTP | 含义 | 怎么办 |
|---|---|---|
401 | 没带 Authorization 头 | 加 Authorization: Bearer ak_xxx |
403 | API key 错了 / 被禁用 | 找管理员重发邀请链接 |
404 | task_id / 文件不存在 | 检查路径或 task_id |
422 | 请求参数格式错 | 看 detail 字段提示 |
429 | 超出每日配额 | 明天再来 / 找管理员加配额 |
502 | Flow 生图失败 | 看 detail;偶发可重试 |
504 | OpenAI 接口同步等超时 | 用 detail 里的 task_id 走异步轮询 |
常见问题
每天配额怎么算?
每提交一次任务(不论成功失败)算一次。每天 UTC 0 点重置。当前你的配额可以在用户面板看到。
图片 URL 多久过期?
默认 30 天。建议拿到 URL 立刻下载本地长期保存。
支持图生图 / inpaint / 上传参考图吗?
暂时不支持,仅文本 → 图。后续看需求加。
速度多快?
单张图 10~30 秒。多账号并行,但每账号串行。同时提多个任务会排队。
失败了怎么办?
看 error 字段。常见原因:账号被风控 / Google 服务波动 / 提示词触发安全策略。
Key 丢了 / 想换?
找管理员把旧 key 禁用,重发一个邀请链接给你。
有 SLA / 服务保证吗?
团队内部工具,没有正式 SLA。有事在群里 @ 管理员。
架构概览
整个系统跑在一台日本 Linux 服务器(Vultr,CentOS Stream 9)上。技术栈分四层:
- Chrome 容器层:每个 Google 账号一个独立 Chrome 实例(
--user-data-dir隔离),跑在 Xvfb 虚拟显示器里。每个 Chrome 监听不同的 CDP 端口(9222 / 9223 / ...) - Hook 注入层:用 Playwright 通过 CDP 接入每个 Chrome,往登录后的 Flow 页面注入 JavaScript。Hook 拦截 fetch/XHR,捕获 OAuth token + reCAPTCHA 模板
- 调度层:每账号一个 worker 协程,从全局队列抢任务;账号间并行、账号内串行;带配额 / 限速 / 失败冷却 / 自动下线
- API 层:FastAPI 提供 OpenAI 兼容接口(
/v1/images/generations)+ Web 面板 + 邀请链接
关键路径上的几个文件:
| 路径 | 说明 |
|---|---|
/opt/flow-api/ | 项目根目录 |
/opt/flow-api/.env | 所有配置(admin key / 端口 / 风控参数等) |
/opt/flow-api/data/ | 运行时数据(user keys / 账号 / 状态 / 邀请) |
/opt/flow-api/profiles/<acct_id>/ | 每账号的 chrome user-data-dir(登录态在这里持久化) |
/opt/flow-api/outputs/<task_id>/ | 生成的图片落盘位置 |
/etc/systemd/system/flow-*.service | 5 个 systemd 服务 |
⭐ 添加 Google 账号
这是最常用的运维操作。新账号 5 分钟搞定,分 4 步:
第 1 步:在服务器拉起新 chrome 实例
SSH 进服务器,跑:
# 参数:账号 id CDP 端口 [代理 URL,可选]
bash /opt/flow-api/deploy/shell/launch-chrome.sh acct2 9223
# 如要走代理:
# bash launch-chrome.sh acct2 9223 socks5://127.0.0.1:1080
systemctl status flow-chrome@acct2 --no-pager看到 active (running) 即可。chrome 在 Xvfb 里跑起来了,绑定 CDP 端口 9223。
acct1, acct2, acct3, ... 端口 9222 → 9223 → 9224 ...第 2 步:SSH 端口转发到本机看 noVNC
在你 Windows 本机 PowerShell(或 Mac terminal)新开一个窗口跑:
ssh -L 6080:127.0.0.1:6080 root@45.32.57.38输密码后这个窗口别关,然后浏览器打开:
http://127.0.0.1:6080/vnc.html?autoconnect=1&resize=remote能看到一个黑桌面 + 多个 Chrome 窗口(每个账号一个),认准你刚启动的那个。
第 3 步:在 noVNC 里登录 Google + 触发模板
- 在新 Chrome 窗口里访问
https://accounts.google.com/ - 登录新 Google 账号(可能要过手机短信 / 备用邮箱验证)
- 登录后访问
https://labs.google/fx/zh/tools/flow - 输入任意 prompt(
abc都行)→ 点"生成" → 等图出来
第 4 步:写 accounts.json + 热加载
SSH 服务器:
# 编辑账号配置
nano /opt/flow-api/data/accounts.jsonJSON 里加一项(注意逗号):
{
"id": "acct2",
"name": "新账号 (描述用)",
"cdp_url": "http://127.0.0.1:9223",
"proxy": "",
"daily_quota": 80,
"min_interval_seconds": 8,
"enabled": true,
"note": ""
}保存后,不需要重启 flow-api,去管理面板点一下"账号 → 从磁盘热加载",新账号就上线了。
idle,开始自动接任务。开机自启
chrome 实例默认会开机自启(launch-chrome.sh 里 systemctl enable 了)。但建议手动确认一次:
systemctl enable flow-chrome@acct2账号日常管理
禁用 / 删除账号
临时禁用
编辑 data/accounts.json,把 "enabled": true 改成 false,然后管理面板"从磁盘热加载"。worker 立刻停掉,chrome 容器还在(保留登录态)。
彻底删除
# 1. 停 chrome 容器
systemctl disable --now flow-chrome@acct2
# 2. 删账号配置
nano /opt/flow-api/data/accounts.json # 删掉对应那一段
# 3. 删 chrome profile(可选,如果不想留登录态)
rm -rf /opt/flow-api/profiles/acct2
# 4. 删账号运行时状态(可选)
nano /opt/flow-api/data/account_state.json # 删对应 id
# 5. 管理面板"从磁盘热加载"
systemctl restart flow-api解除自动下线 / 解除冷却
账号连续失败 6 次会被自动下线(auto_disabled = true),失败 2~3 次会进 cooldown 冷却。两种情况都可以在管理面板 → 账号对应行点 reset 立刻恢复。
命令行版:
curl -X POST -H "Authorization: Bearer $FLOW_ADMIN_KEY" \
https://flow.aizyk.cn/v1/admin/accounts/acct1/reset重启某账号的 worker
如果 worker 协程"看着活着但不干活",去管理面板 → 账号 → restart worker。
用户 / Key 管理
所有操作都在管理面板里点:
创建 user key
有两种方式:
- 邀请链接(推荐):管理面板 → 邀请 → "+ 新邀请" → 配额 → 生成链接 → 复制 → 通过 IM 发给团队成员。他们点开输名字自己拿 key。优势:你不用经手 key 本体
- 直接创建:管理面板 → Keys → "+ 新建 key" → 输入名字和配额 → 创建后弹窗一次性显示完整 key(务必当场复制发给本人)
禁用 / 启用 / 删除 key
管理面板 → Keys → 对应行的"禁用 / 启用 / 删除"按钮。
- 禁用:保留 key 信息和用量历史,仅暂停使用
- 删除:完全清掉,相同 key 字符串以后再也不能用
调整配额
管理面板暂时不支持改配额,需要 SSH:
curl -X PATCH -H "Authorization: Bearer $FLOW_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"daily_quota": 200}' \
https://flow.aizyk.cn/v1/admin/keys/<key_id>远程进 noVNC
noVNC 是给管理员"远程操作服务器上的 Chrome"用的。绝对不要把 6080 端口直接暴露公网,永远走 SSH 端口转发。
每次需要进的时候:
# 本机新开 PowerShell / Terminal
ssh -L 6080:127.0.0.1:6080 root@45.32.57.38
# 然后浏览器打开
# http://127.0.0.1:6080/vnc.html?autoconnect=1&resize=remote用完关掉那个 SSH 窗口,转发就断。
故障排查
任务一直 queued,不动
看管理面板"账号" tab:
- 没有任何账号 → 还没添加,按上面"添加 Google 账号"流程
- 所有账号都
cooldown/disabled→ 看"上次错误",按下面对应症状处理 - 账号
idle但任务不动 → 重启 flow-api:systemctl restart flow-api
错误:"No batchGenerateImages request captured"
意思:浏览器侧 hook 没录到 Flow 真实请求模板。原因:
- flow-api 启动后 / chrome 重启后,没人在 Flow 页面真正点过"生成"
- Flow 页面被关掉了 / 切到别的页面去了
修复:进 noVNC,确认 Chrome 当前在 https://labs.google/fx/zh/tools/flow/... 页面,输任意 prompt 点一次"生成",等图出来。
错误:"Flow HTTP 401" 或 "token expired"
OAuth token 过期了。同上:进 noVNC 在 Flow 页面点一次生成,新 token 自动被 hook 抓到,下一个任务就成功。
长期解决:keep-alive 代码已经在跑(每 25 分钟主动调一次 Google API 续期),只要 hook 录到了 keep-alive URL 就再也不会过期。
错误:"reCAPTCHA evaluation failed"
这是 Google 的风控。可能原因:
- 同账号短时间提交太多任务 → 等几分钟,调高
account_min_interval_seconds - 账号被风控 → 进 noVNC 用人工方式点几次生成("温水煮青蛙"恢复信誉),过几小时再试
- IP 被风控 → 给账号配独立代理(accounts.json 的
proxy字段)
chrome 容器挂了
# 看状态
systemctl status flow-chrome@acct1 --no-pager
# 看日志
journalctl -u flow-chrome@acct1 --no-pager -n 50
# 重启
systemctl restart flow-chrome@acct1整个系统不响应
# 一键全栈状态检查
systemctl status flow-xvfb flow-x11vnc flow-novnc flow-api 'flow-chrome@*' --no-pager | grep -E '(●|Active:)'
# 一键全栈重启
systemctl restart flow-xvfb flow-x11vnc flow-novnc flow-api 'flow-chrome@*'服务管理速查
| 服务 | 作用 |
|---|---|
flow-xvfb | 虚拟显示器 :99 |
flow-x11vnc | 把 :99 暴露成 VNC 端口 5900 |
flow-novnc | noVNC web 客户端,6080 端口 |
flow-chrome@<acct> | 每个账号一个 chrome 实例(如 flow-chrome@acct1) |
flow-api | FastAPI 主进程,8787 端口 |
常用命令
# 启动 / 停止 / 重启
systemctl start flow-api
systemctl stop flow-api
systemctl restart flow-api
# 看状态
systemctl status flow-api --no-pager
# 看实时日志
journalctl -u flow-api -f
# 看最近 N 条
journalctl -u flow-api --no-pager -n 100
# 看某时间段
journalctl -u flow-api --since '1 hour ago' --no-pager
# 开机自启
systemctl enable flow-api
systemctl disable flow-api配置文件 .env
位置:/opt/flow-api/.env。改完执行 systemctl restart flow-api 才生效。
| 字段 | 说明 | 默认 |
|---|---|---|
FLOW_ADMIN_KEY | 管理面板 / admin 接口的密钥 | 必改 |
FLOW_PROVIDER | 必须 cdp | cdp |
FLOW_HOST | flow-api 监听 IP,正式环境用 127.0.0.1 走 nginx | 127.0.0.1 |
FLOW_PORT | 监听端口 | 8787 |
PUBLIC_BASE_URL | 对外 URL(图片签名链接的前缀) | https://flow.aizyk.cn |
IMAGE_URL_TTL_SECONDS | 图片签名 URL 有效期 | 2592000 (30 天) |
ACCOUNT_DAILY_QUOTA | 每个 chrome 账号每日上限 | 80 |
ACCOUNT_MIN_INTERVAL_SECONDS | 账号两次任务最小间隔 | 8 |
ACCOUNT_JITTER_SECONDS | 间隔上叠加的随机抖动上限 | 6 |
TASK_MAX_RETRIES | 任务失败后自动重试次数 | 2 |
ACCOUNT_DISABLE_AFTER_FAILURES | 账号连续失败多少次自动下线 | 6 |
CDP_KEEPALIVE_INTERVAL_SECONDS | OAuth 续期心跳间隔 | 1500 (25 分钟) |
LOG_LEVEL | INFO / DEBUG / WARNING | INFO |
备份 / 恢复
系统自动每天凌晨 4 点备份 data/ 目录到 /root/flow-backup-YYYY-MM-DD.tgz,保留 14 天(部署时已经设了 cron)。
手动备份
tar -czf /root/flow-backup-manual-$(date +%F).tgz /opt/flow-api/data
ls -lh /root/flow-backup-*.tgz从备份恢复
systemctl stop flow-api
tar -xzf /root/flow-backup-2026-04-26.tgz -C /
chown -R flow:flow /opt/flow-api/data
systemctl start flow-apiprofiles/)和生成的图片(outputs/)默认不在备份里。账号 profile 丢了的代价是要重新登录所有 Google 账号。如要备份它们:tar -czf chrome-profiles.tgz /opt/flow-api/profiles代码升级
开发者打包好新版 zip 后:
- 宝塔 → 文件 →
/opt/flow-api/→ 上传 zip → 解压(覆盖app/和/或web/) - SSH 跑:
chown -R flow:flow /opt/flow-api/app /opt/flow-api/web
systemctl restart flow-api
journalctl -u flow-api --no-pager -n 20看到 account worker started + hook installed on N labs page(s) 就成功了。
安全建议
- FLOW_ADMIN_KEY:用
python3 -c "import secrets;print(secrets.token_urlsafe(32))"生成的强随机串,**绝对不要分享给任何团队成员** - noVNC 6080 端口:永远不要直接暴露公网,只走 SSH 端口转发。已经在 nginx 配置里默认不映射
- SSH:fail2ban 已经装上,5 次失败封 1 小时。建议改 SSH 端口(默认 22 经常被扫):编辑
/etc/ssh/sshd_config改Port 12022,宝塔安全里同步修改 - HTTPS 证书:宝塔 Let's Encrypt 自动续签,无需手动维护
- Google 账号:最好专门为这个用途新注册,不要用你日常用的账号;账号被风控后影响小
- 定期审计:管理面板"任务流水"看下有没有异常 prompt(团队成员是否在用作不当用途)
- image URL 泄露:URL 自带签名 + 30 天过期,单 URL 泄露仅那一张图被陌生人下载,不影响其他。真担心可以缩短
IMAGE_URL_TTL_SECONDS - 紧急 kill switch:如果某 user key 被恶意滥用,管理面板"Keys" tab 一键禁用即可
- 整个签名失效:极端情况下(admin key 被泄露),rotate
FLOW_ADMIN_KEY+ 重启 flow-api,所有签名 URL 立刻失效(包括正在用的)