这次我们来看一个很实用的玩法:用 JSON 提示词来控制 Nano Banana 2 图像生成模型。很多做AI绘画的人可能已经发现,传统自然语言提示词在描述"左边是什么、右边是什么、谁在前谁在后"的时候,经常出现元素错位、数量不对、风格漂移的问题。而 JSON 提示的核心思路,是把画面里的主体、动作、位置、关系、风格、光线、镜头全部结构化,让模型像读配置文件一样理解你的意图。这个思路对 Nano Banana 2 格外有效,因为它的原生多模态理解能力明显强于第一代,复杂指令和图文混合输入的稳定性要好很多。
这篇文章会讲清楚四件事:Nano Banana 2 到底是什么、JSON 提示的结构怎么设计、怎么通过 API 把 JSON 场景描述发给模型、批量生成时 JSON 任务怎么管理。另外会给出文生图、图生图、文字渲染的验证流程,以及常见报错和排查方法。如果你正准备用 Nano Banana 2 做产品概念图、漫画分镜、电商素材或者批量配图,建议直接收藏。
先说明一个前提:Nano Banana 2 是云端 API 模型,不是本地开源模型。它的推理发生在服务端,本机只需要能发 HTTP 请求,不需要 GPU、不需要下载权重。所以这篇文章不涉及显存占用,更关注的是 API 接入、JSON 结构设计和批量任务工程化。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 模型定位 | 多模态图像生成与编辑模型 |
| 代号对应 | 初代 Nano Banana:Gemini 2.5 Flash Image;Nano Banana 2:Gemini 3 系列 Pro Image |
| 主要功能 | 文生图、图生图、多图参考、局部编辑、文字渲染、JSON 结构化场景描述 |
| 运行方式 | 云端 API,不依赖本地显卡 |
| 硬件门槛 | 能运行 Python 并联网的电脑即可,无显存要求 |
| 接入方式 | Gemini API、Google AI Studio、Vertex AI、兼容 OpenAI 协议的第三方平台 |
| 是否支持 API | 支持官方 generateContent 接口 |
| 是否支持批量任务 | 支持,可脚本串行或并发调用,建议配合任务队列 |
| 提示语言 | 中文、英文均可,JSON 字段建议中英结合 |
| 适合场景 | 产品概念图、漫画分镜、电商素材、批量配图、创意自动化流程 |
需要提醒的是,模型 ID、配额和价格会随官方调整而变化,实际接入时以对应文档为准。下面所有示例中的模型名和接口路径,都是演示性质,真实环境需要替换成当前可用的值。
2. 适用场景与使用边界
2.1 这个工具适合谁
如果你是内容创作者、插画师、游戏原画师、电商运营,Nano Banana 2 的 JSON 提示能帮你把复杂画面拆成明确要素,减少反复抽卡的次数。
如果你是开发者,JSON 提示的价值更大。JSON 本身就是程序语言,你可以把场景配置存成文件、写进数据库、通过管理后台动态修改,然后由脚本自动调用 API 生成图片,输出到指定目录。整个流程不需要人工干预。
2.2 能解决什么问题
- 自然语言提示词描述复杂构图时,模型经常漏元素或错位。
- 多物体场景中,"物体之间的关系"难以用一句话稳定表达。
- 批量生成时,提示词散落在文本里,不好管理和复用。
- 需要程序化控制画面参数,比如按商品 ID 动态生成不同颜色、不同背景的素材图。
2.3 不适合什么场景
- 完全离线的图像生成场景。Nano Banana 2 是云服务,不提供可下载的本地权重。
- 对数据出境或服务商有严格合规要求的业务,需要先做评估。
- 需要精确控制输出像素尺寸的场景。图像模型的输出尺寸由服务端决定,长宽比控制范围有限,建议生成后自己裁剪或放大。
2.4 合规与安全边界
这一点必须单独强调。用 Nano Banana 2 生成图片时:
- 不要生成真实人物的肖像,除非你拥有明确的肖像授权。
- 不要生成受版权保护的 IP 角色、品牌 Logo、商标图案。
- 不要用生成结果做伪造、误导、诈骗类内容。
- 商用前要确认模型服务条款允许你的用途。
- 批量生成素材用于内容平台时,建议保留生成记录,方便追溯来源。
涉及人脸、品牌、版权素材的场景,先把授权文件准备好再开工。
3. 环境准备与前置条件
Nano Banana 2 的接入门槛比本地部署低很多,不需要折腾 CUDA、PyTorch 和模型文件。你需要准备的是 API Key、Python 环境和网络访问能力。
3.1 准备清单
- 一个 API 服务账号,并开通图像生成模型的访问权限。
- API Key,用于接口鉴权。
- Python 3.10 或更高版本。
- 网络环境能够访问对应的 API 服务。如果当前网络无法直连官方接口,可以评估你所在网络环境下可访问的兼容 API 平台,使用方式类似,只是 base_url 和模型名不同。
3.2 安装 Python 依赖
官方推荐使用google-genaiSDK,也可以直接用requests。
pip install requests pip install google-genai3.3 配置 API Key
建议通过环境变量管理,不要硬编码在代码里。
Linux / macOS:
export GEMINI_API_KEY="你的_API_Key"Windows PowerShell:
$env:GEMINI_API_KEY="你的_API_Key"配置完成后,可以用下面这段代码验证 Key 是否可用:
import os from google import genai client = genai.Client(api_key=os.environ["GEMINI_API_KEY"]) print("API Key 配置完成")如果能正常打印,说明环境准备完毕。
4. JSON 提示词的结构化设计
4.1 为什么要用 JSON 提示
Nano Banana 2 和传统扩散模型最大的区别,是它对结构化数据有很强的理解能力。传统模型把提示词当作文本序列,模型在语义空间里"猜测"你想要什么;Nano Banana 2 可以把 JSON 当作一张场景图来读,字段名、嵌套结构、数组关系都能被理解。
这样做的好处有三个:
- 稳定性:同样的 JSON 结构,换不同的值,画面风格和构图逻辑保持一致。
- 可控性:物体位置、数量、动作、关系都能用字段明确指定。
- 可编程性:JSON 可以来自数据库、配置文件、Excel 转换脚本,方便批量任务接入。
4.2 通用 JSON 提示结构
一个完整的 JSON 提示可以包含以下模块:
{ "任务": "文生图", "主体": { "类型": "柴犬", "数量": 1, "动作": "坐姿看向镜头", "表情": "开心", "服装": "黄色雨衣、蓝色小帽子" }, "场景": { "地点": "雨后城市街道", "背景": "霓虹灯商店橱窗", "前景": "地面的积水洼地", "氛围": "治愈、温暖、安静" }, "构图": { "布局": "主体偏右", "景别": "中景", "视角": "平视", "留白": "画面左侧留白" }, "风格": { "画风": "半写实插画", "色彩": "暖色调为主,点缀蓝紫色霓虹", "材质": "轻微水彩质感", "光影": "傍晚暖光,霓虹灯补光" }, "镜头": { "焦段": "50mm", "光圈": "f/2.8", "景深": "背景虚化" }, "文字": { "是否需要": false, "内容": "", "位置": "", "字体风格": "" }, "禁止项": ["不要水印", "不要第二只动物", "不要文字", "不要模糊"] }这里的关键是"值用自然语言描述,键保持固定"。比如"动作": "坐姿看向镜头"的值仍然是一段自然语言,但因为它挂在主体下面,模型会把这段描述绑定到这个主体对象上,而不是整个画面。
4.3 用 JSON 表达物体关系
多物体场景最容易出问题。自然语言提示 "一只猫在桌子下面,一只狗在桌子旁边" 可能被模型理解成一只整体场景。JSON 可以明确拆开:
{ "任务": "文生图", "场景": { "地点": "木质书房", "光线": "窗外自然光" }, "物体列表": [ { "名称": "橘猫", "数量": 1, "位置": "桌子下方", "动作": "趴着睡觉", "大小": "画面占比 15%" }, { "名称": "柯基犬", "数量": 1, "位置": "桌子右侧", "动作": "站立抬头看猫", "大小": "画面占比 25%" } ], "物体关系": [ "柯基犬与橘猫之间视线存在联系", "橘猫在桌子下方,柯基犬在桌子右侧" ], "构图": { "视角": "轻微俯视", "景别": "全景" }, "禁止项": ["不要出现其他动物", "不要文字水印"] }物体列表用数组描述每个独立对象,物体关系补充对象之间的空间和互动关系。这种结构比 "一幅图里有一只猫和一只狗" 要准确得多。
4.4 编辑类任务的 JSON
如果要做图生图或局部编辑,需要指定参考图和编辑指令:
{ "任务": "图生图编辑", "参考图": "input.jpg", "编辑指令": { "操作": "替换主体", "原物体": "透明玻璃杯", "新物体": "白色陶瓷马克杯", "保持不变": ["光线方向", "桌面材质", "背景颜色", "构图角度"] }, "输出要求": { "分辨率": "与参考图一致", "画风": "与参考图保持一致" } }编辑类任务的重点是保持不变列表。这个列表能让模型清楚哪些要素不能动,避免修改一个杯子的同时把整张图的色调和构图都改掉。
4.5 编写 JSON 提示的规则
- 键名固定,值用自然语言。不要把所有信息塞进一个字段。
- 数量写清楚,包括物体个数、画面占比。
- 用
禁止项约束负面条件,比堆砌负面提示词更有效。 - 调试时一次只改一个变量,方便定位影响效果的是哪个字段。
- 字段数量控制在 10 到 20 个左右,过多会让模型注意力分散。
5. 功能测试与效果验证
接入 API 后,先用小参数测试,不要直接跑大批量任务。
5.1 文生图测试
测试目的:验证模型能否按 JSON 场景生成符合预期的画面。
输入示例:使用 4.2 中的柴犬雨衣场景 JSON。
操作步骤:
- 把 JSON 转成字符串。
- 在提示词中明确要求模型"严格按 JSON 字段执行"。
- 调用生成接口。
- 保存返回的图片。
判断成功的标准:
- 画面中有且只有一只穿黄色雨衣的柴犬。
- 柴犬位于偏右位置。
- 背景是雨后城市街道,有霓虹灯。
- 没有水印和多余文字。
- 整体风格接近半写实插画。
如果失败,优先检查 JSON 里主体和禁止项是否冲突。
5.2 图生图编辑测试
测试目的:验证局部替换是否只影响目标区域。
输入示例:一张玻璃杯放在木桌上的照片,JSON 要求把玻璃杯换成白色陶瓷马克杯。
预期结果:马克杯准确替换玻璃杯,桌面、光线、背景角度都不变。
如果背景也被修改,说明保持不变列表写得太粗,应该补充更多字段,比如 "桌面的木纹方向""窗外的景色""杯子的阴影方向"。
5.3 文字渲染测试
Nano Banana 2 支持在图中渲染文字,但中文文字渲染依然建议单独测试。
{ "任务": "文生图", "场景": "咖啡店黑板前", "主体": { "类型": "黑板", "位置": "画面中央", "内容": "写着「今日特调:桂花拿铁」" }, "文字": { "是否需要": true, "内容": "今日特调:桂花拿铁", "位置": "黑板中央", "字体风格": "手写体", "颜色": "白色粉笔" }, "禁止项": ["不要出现其他文字", "不要错别字"] }判断标准:文字内容与文字.内容完全一致,没有多字、少字、错字。如果文字渲染不稳定,把文字内容缩短、减少生僻字、把文字位置描述得更具体,效果会好一些。
5.4 输出保存与日志记录
每次生成都建议记录输入 JSON、输出图片路径、请求耗时和状态。后续排查和效果对比都用得到。
import json import time def log_task(task_id, scene, image_path, status, elapsed): entry = { "task_id": task_id, "status": status, "image_path": image_path, "elapsed_seconds": round(elapsed, 2), "scene": scene } with open("generation_log.jsonl", "a", encoding="utf-8") as f: f.write(json.dumps(entry, ensure_ascii=False) + "\n")6. 接口 API 调用示例
6.1 使用官方 SDK 生成图片
下面是使用google-genaiSDK 的完整示例。模型名以你实际可用的为准,示例中使用的是gemini-3-pro-image-preview。
import os import json import base64 from google import genai from google.genai import types client = genai.Client(api_key=os.environ["GEMINI_API_KEY"]) scene = { "任务": "文生图", "主体": { "类型": "柴犬", "数量": 1, "动作": "坐姿看向镜头", "表情": "开心", "服装": "黄色雨衣、蓝色小帽子" }, "场景": { "地点": "雨后城市街道", "背景": "霓虹灯商店橱窗", "氛围": "治愈、温暖" }, "构图": { "布局": "主体偏右", "景别": "中景" }, "风格": { "画风": "半写实插画", "光影": "傍晚暖光,霓虹灯补光" }, "禁止项": ["不要水印", "不要文字", "不要第二只动物"] } prompt = f"请严格根据以下 JSON 场景描述生成一张图片:\n{json.dumps(scene, ensure_ascii=False, indent=2)}" response = client.models.generate_content( model="gemini-3-pro-image-preview", contents=prompt, config=types.GenerateContentConfig( response_modalities=["IMAGE", "TEXT"] ), ) for part in response.candidates[0].content.parts: if part.inline_data is not None: image_bytes = part.inline_data.data with open("output.png", "wb") as f: f.write(image_bytes) print("图像已保存到 output.png") elif part.text is not None: print("模型文字说明:", part.text)6.2 使用 HTTP 接口 + curl
如果不想装 SDK,可以直接用 HTTP 接口。下面是一个 curl 示例:
curl -X POST \ "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-image-preview:generateContent?key=YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "contents": [{ "parts": [{"text": "请根据 JSON 场景生成图片:{\"任务\":\"文生图\",\"主体\":{\"类型\":\"柴犬\"}}"}] }], "generationConfig": { "responseModalities": ["IMAGE", "TEXT"] } }'注意:上面的接口路径是演示用,实际部署时要换成官方文档中当前生效的模型名和路径。
6.3 兼容 OpenAI 协议的调用示例
很多第三方平台提供 OpenAI 兼容接口。接入方式类似,只是base_url、请求头和模型名不同:
import requests import os api_key = os.environ.get("API_KEY") base_url = "https://你的平台地址/v1" # 按实际平台文档替换 model = "google/gemini-3-pro-image" # 按实际平台模型名替换 response = requests.post( f"{base_url}/chat/completions", headers={"Authorization": f"Bearer {api_key}"}, json={ "model": model, "messages": [ {"role": "user", "content": "请根据 JSON 场景生成图片:{...}"} ] }, timeout=300 ) print(response.json())这类平台的请求和返回结构会略有差异,务必以平台文档为准。
7. 批量任务设计
批量生成是 JSON 提示的强项。因为每个任务本身就是一段结构化数据,天然适合写入 JSONL 文件逐行处理。
7.1 JSONL 任务文件格式
{"id": "scene_001", "output": "outputs/scene_001.png", "scene": {"任务": "文生图", "主体": {"类型": "柴犬", "动作": "坐姿"}, "风格": {"画风": "半写实插画"}}} {"id": "scene_002", "output": "outputs/scene_002.png", "scene": {"任务": "文生图", "主体": {"类型": "橘猫", "动作": "跳跃"}, "风格": {"画风": "赛博朋克"}}} {"id": "scene_003", "output": "outputs/scene_003.png", "scene": {"任务": "文生图", "主体": {"类型": "柯基", "动作": "奔跑"}, "风格": {"画风": "水彩"}}}7.2 Python 批量处理脚本
import json import time import os from google import genai from google.genai import types client = genai.Client(api_key=os.environ["GEMINI_API_KEY"]) os.makedirs("outputs", exist_ok=True) with open("tasks.jsonl", "r", encoding="utf-8") as f: tasks = [json.loads(line) for line in f if line.strip()] for task in tasks: start = time.time() try: prompt = ( "请严格根据以下 JSON 场景描述生成一张图片:\n" + json.dumps(task["scene"], ensure_ascii=False, indent=2) ) response = client.models.generate_content( model="gemini-3-pro-image-preview", contents=prompt, config=types.GenerateContentConfig(response_modalities=["IMAGE"]), ) for part in response.candidates[0].content.parts: if part.inline_data is not None: with open(task["output"], "wb") as f: f.write(part.inline_data.data) print(f"完成: {task['id']}, 耗时 {time.time() - start:.2f}s") break else: print(f"未收到图像: {task['id']}") except Exception as exc: print(f"失败: {task['id']}, 错误: {exc}") time.sleep(1) # 简单限速,避免触发频率限制7.3 批量任务的工程化建议
- 任务文件与输出目录分离,任务按批次归档。
- 每次循环捕获异常,失败任务单独记录,不要中断整个批次。
- 增加重试机制,对 429、5xx 类错误做指数退避重试。
- 批量任务之前先跑 3 到 5 个样例任务,确认 JSON 结构和输出路径没有问题。
- 并发调用前先确认 API 配额允许的每分钟请求数,保守一点。
7.4 失败重试模板
import time def call_with_retry(func, max_retries=3, base_delay=2): for attempt in range(max_retries): try: return func() except Exception as exc: if attempt == max_retries - 1: raise delay = base_delay * (2 ** attempt) print(f"第 {attempt + 1} 次失败: {exc}, {delay}s 后重试") time.sleep(delay)8. 资源占用与性能观察
前面说过,Nano Banana 2 是云端 API,本机不计算显存。但仍有几个性能指标值得观察。
8.1 关注哪些指标
- 单张图片耗时:从请求发出到收到完整图片的时间。受网络和模型负载影响,一般需要几十秒到几分钟。
- 输入 token 消耗:JSON 越长,输入 token 越多。简短的 JSON 提示比长段自然语言更省成本。
- 输出图片体积:API 返回 base64 编码的图片,单张可能几 MB,网络传输和磁盘存储都要考虑。
- 配额消耗:每个请求消耗一次图像生成配额,批量任务前计算好总量。
8.2 成本控制
- 先用小 JSON 结构测试,确认效果后再扩大。
- 批量任务设置每日上限,防止脚本失控产生高额费用。
- 相同场景只生成一次,用输出文件缓存,避免重复请求。
- 后台记录每个任务的耗时和配额用量,月底汇总。
8.3 与本机资源的区别
如果你看到网上有人讨论 Nano Banana 跑在 ComfyUI 里,那通常是指通过云 API 节点在 ComfyUI 中编排,本机只负责上传图片、发送请求、接收结果,不做推理。不要误以为可以本地部署。
9. 常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 返回 400 INVALID_ARGUMENT | JSON 格式错误或请求参数不符合接口规范 | 用python -m json.tool校验 JSON,检查接口文档 | 修正 JSON 格式,去掉多余字段 |
| 返回 403 PERMISSION_DENIED | API Key 无权限或未开通该模型 | 检查 Key 是否有效、服务是否开通 | 在服务控制台确认模型访问权限 |
| 返回 429 RESOURCE_EXHAUSTED | 配额不足或请求频率超限 | 查看配额用量和限流策略 | 降低并发,增加延时,申请更高配额 |
| 生成结果不遵循 JSON 结构 | 提示词没有强调执行方式 | 检查提示词里是否要求"严格按字段执行" | 在 prompt 开头加入强制指令,简化 JSON 层级 |
| 元素数量不对 | 主体字段缺少数量约束 | 检查主体.数量和禁止项 | 明确写"数量": 1,禁止项里写"不要出现其他物体" |
| 文字渲染错字 | 文字过长或字体风格描述不清晰 | 单独测试文字字段 | 缩短文字内容,明确字体和位置 |
| 网络请求超时 | 网络不稳定或服务端负载高 | 观察耗时和错误日志 | 增加超时时间,重试,错峰调用 |
| 输出图片与预期风格不一致 | 风格字段描述太抽象 | 对比不同风格值的输出 | 加入参考风格词和色彩代码,缩小风格范围 |
如果多个问题同时出现,建议把输入 JSON 和输出图片放在一起对比,一次性定位是结构问题还是提示词表达问题。
10. 最佳实践与使用建议
10.1 建立 JSON 模板库
把常用场景拆成模板:漫画分镜模板、产品图模板、人物插画模板、文字海报模板。每个模板保留固定键,只改值,能大幅降低调试成本。
10.2 参数化设计
把可变内容抽出来,比如主体类型、颜色、动作、背景,写入配置项。一个模板加上不同参数,就能生成一批风格统一但内容不同的图片。
10.3 先跑小规模验证
任何新场景第一次使用,先手动跑 1 到 3 张,确认输出符合预期,再写成批量脚本。批量任务失败时的排查成本比单张高得多。
10.4 保留完整日志
每个任务记录输入 JSON、输出路径、耗时、状态。效果回归和成本分析都依赖这些数据。日志用 JSONL 格式最方便。
10.5 合规审查前置
所有批量素材在正式使用前做一次人工复核。涉及人脸、品牌、受版权保护的内容,先确认授权材料齐全。商用场景建议保留任务日志作为溯源凭证。
10.6 接口服务化封装
如果团队多人使用,可以把生成图片的 API 封装成内部服务,统一管理 Key、配额和日志,避免 Key 泄露和超额消耗。
最后说一句
JSON 提示的价值不在于"语法正确",而在于把模糊的画面意图变成可复现的结构化配置。Nano Banana 2 对结构化指令的理解能力,是目前图像模型里最适合这个玩法的一档。拿到 API Key 之后,建议先从第 4 节的柴犬场景开始测,跑通一次完整流程,再加上你的实际业务场景,改成自己的模板。最容易踩的坑有三个:模型名写错导致 404、JSON 字段太多导致模型注意力分散、批量任务没有重试导致中途卡死。把这几个点提前处理掉,后面的批量生成会顺畅很多。