📋 Gemini AI 做图 - 项目文档
基于 Google Gemini 的 AI 图片生成服务 · 最后更新: 2026-02-24
🏗️ 系统架构
┌─────────────────────────────────────────────────────────┐
│ 用户浏览器 │
│ gemini.666douyin.cn │
└──────────────────────┬──────────────────────────────────┘
│ HTTP
▼
┌──────────────────────────────────────────────────────────┐
│ 阿里云服务器 8.138.104.108 │
│ ┌────────────┐ ┌──────────────────┐ │
│ │ Nginx │───▶│ 127.0.0.1:3555 │ │
│ │ (反向代理) │ │ (SSH隧道入口) │ │
│ └────────────┘ └────────┬─────────┘ │
└─────────────────────────────┼────────────────────────────┘
│ SSH反向隧道
▼
┌──────────────────────────────────────────────────────────┐
│ 本地 Mac │
│ ┌──────────────────┐ ┌───────────────────────┐ │
│ │ api_server.py │───▶│ worker.py (子进程) │ │
│ │ aiohttp :8800 │ │ gemini_webapi 调用 │ │
│ │ HTTP路由/静态文件 │ │ fast_init_client() │ │
│ └──────────────────┘ └───────────┬───────────┘ │
│ │ HTTPS │
│ ┌──────────────────┐ ▼ │
│ │ tunnel-guard.sh │ ┌───────────────────────┐ │
│ │ launchd 每60秒 │ │ gemini.google.com │ │
│ │ 自动检查+重连 │ │ (Google Gemini API) │ │
│ └──────────────────┘ └───────────────────────┘ │
└──────────────────────────────────────────────────────────┘
为什么这么设计?
- 问题 服务器在国内,无法直接访问 Google
- 方案 API 跑在本地 Mac,通过 SSH 反向隧道暴露到服务器
- 问题 gemini_webapi 库的
get_access_token() 在 Python 3.14 下死锁,阻塞 event loop
- 方案 子进程架构:HTTP 服务器只做路由,每次生图 spawn 独立 Python 进程
- 问题 库的 init 函数内部用
asyncio.Task() 构造方式不兼容 Python 3.14
- 方案 worker.py 自定义
fast_init_client(),手动用 httpx 获取 SNlM0e token 注入 GeminiClient
📁 项目文件
| 文件 | 说明 |
api_server.py | HTTP 服务器 (aiohttp),路由分发 + 子进程调度,272行 |
worker.py | 子进程 worker,fast_init_client + 生图/编辑/状态检查,183行 |
public/index.html | 前端页面:文生图 + 图生图 + 12风格预设 + 画廊 + 灯箱 + 历史 + 编辑 |
public/docs.html | API 接口文档页面 |
public/project.html | 本项目文档(你正在看的) |
auto_login.py | nodriver 自动登录 Google 获取 Cookie(需 python3.13) |
tunnel-guard.sh | 隧道守护脚本,launchd 每60秒调用 |
keep-alive.sh | 旧版保活脚本(已被 tunnel-guard 替代) |
.env | Cookie 存储:GEMINI_SECURE_1PSID + GEMINI_SECURE_1PSIDTS |
output/ | 生成的图片存储目录,按日期分文件夹 |
🔧 核心组件
api_server.py — HTTP 服务器
- 框架:aiohttp,监听
0.0.0.0:8800
- 鉴权:Bearer Token 或 URL 参数
?key=gemini_2026
- 并发控制:
asyncio.Semaphore(2),最多2个并发生图任务
- 子进程调度:
asyncio.create_subprocess_exec 调用 worker.py
- 超时:生图90秒,Cookie验证30秒
worker.py — 生图引擎
fast_init_client():绕过库的死锁 init,手动获取 SNlM0e token
- 每次请求创建新的 GeminiClient,用完即关(无状态)
- 支持三种动作:generate(文生图)、edit(图生图/编辑)、status(Cookie验证)
- 输出目录:
output/YYYY-MM-DD/gen_timestamp_index/
tunnel-guard.sh — 隧道守护
- macOS launchd 每60秒执行
- 检查本地 API → 挂了自动重启
- 检查远端隧道 → 断了自动重建
- SSH 参数:
ControlMaster=no(独立连接,避免被其他SSH带断)
- 日志:
/tmp/tunnel-guard.log
- plist:
~/Library/LaunchAgents/com.gemini.tunnel.guard.plist
🍪 Cookie 管理
重要:Google Cookie 寿命短(几小时~几天),过期后生图会一直 "queueing" 超时。
刷新流程
- 运行
python3.13 auto_login.py(必须用 3.13,3.14 有 SyntaxError)
- nodriver 打开真实 Chrome 窗口(非 headless,Google 会检测)
- 自动输入邮箱 → 密码 → TOTP → 跳过 Passkey → 到达 Gemini
- 提取
__Secure-1PSID 和 __Secure-1PSIDTS,写入 .env
- 重启 api_server.py(或调
POST /api/cookie 热更新)
注意事项
pkill 有时杀不掉旧进程,需 kill -9 <pid> 精确杀
load_dotenv(override=True) 必须加 override
- Google 免费账号有生图配额限制,用多了会限流,需等几小时恢复
🌐 部署信息
| 项 | 值 |
| 域名 | gemini.666douyin.cn |
| 服务器 | 8.138.104.108 (阿里云 Ubuntu) |
| Nginx 配置 | /etc/nginx/sites-available/gemini-api |
| 隧道端口 | 服务器 3555 → 本地 Mac 8800 |
| 本地项目路径 | ~/projects/nano-banana-mcp/ |
| Python 版本 | api_server/worker: 3.14 · auto_login: 3.13 |
| NQF工具箱 | 已集成,id=gemini-gen,全员可见 |
⚡ 功能清单
| 功能 | 状态 | 说明 |
| 文生图 | ✅ | 输入文字描述生成图片,支持中英文 |
| 图生图 | ✅ | 上传图片 + 描述修改,支持拖拽上传 |
| 图片编辑 | ✅ | 对已生成图片进行二次编辑 |
| 风格预设 | ✅ | 12种风格一键应用(赛博朋克、水彩、像素等) |
| 画廊 + 灯箱 | ✅ | 网格展示 + 点击放大 + 下载 |
| 历史记录 | ✅ | localStorage 持久化 |
| 提示词增强 | ✅ | 自动补充画质/光影/构图描述 |
| Cookie 热更新 | ✅ | POST /api/cookie 无需重启 |
| 自动守护 | ✅ | launchd 每60秒检查 API + 隧道 |
| API 文档 | ✅ | /docs 页面,含各语言调用示例 |
🐛 踩坑记录
| 问题 | 原因 | 解决 |
| API 启动后卡死不响应 |
gemini_webapi 的 get_access_token() 在 Python 3.14 下死锁,阻塞 aiohttp event loop |
改为子进程架构,worker.py 自定义 fast_init_client() |
| 编辑图片报 Pydantic ValidationError |
gemini_webapi 的 Image 类不接受 path 参数,只接受 url |
修改库源码 image.py,加 model_validator 映射 path→url |
| 新 Cookie 不生效 |
旧进程 kill 不掉占着端口,新进程启动失败 |
kill -9 <pid> 精确杀 + 等端口释放 |
| 隧道频繁断开 |
SSH ControlMaster 复用连接,其他SSH断开时带走隧道 |
隧道SSH加 ControlMaster=no ControlPath=none + launchd 守护 |
| 隧道端口冲突 |
3550 被 game-portal 占用 |
改用 3555 |
| 生图返回文本而非图片 |
Gemini 有时把短 prompt 当文本对话处理 |
prompt 前加 "Generate an image:" 引导 |
| Google 限流 (queueing) |
免费账号短时间请求过多 |
等几小时恢复,无法绕过 |
📝 更新日志
| 日期 | 更新 |
| 2026-02-24 | 创建项目文档 + 更新API文档 |
| 2026-02-22 | 添加图生图功能(前端上传+拖拽);设置 launchd 隧道守护(60秒间隔);隧道端口 3550→3555 |
| 2026-02-21 | v2 子进程架构重写;自定义 fast_init_client 绕过库死锁;修复编辑功能 Pydantic 错误;自动登录获取 Cookie;前端上线(12风格预设+画廊+灯箱+历史);API文档页面;集成到 NQF 工具箱 |