第一条 Gemini API 请求
Gemini API 首请求是 interactions.create(model, input),结果取 output_text,密钥走环境变量 GEMINI_API_KEY。(核验 2026-11-05,F9、F68)
一、第一条 Gemini API 请求:问题不是拿到一句回答,而是知道发了什么、该看哪
大部分人跑通第一条请求就过去了:装包、贴 key、print 出一句话,收工。然后到第二步就卡住——想加多轮,不知道历史放哪;想知道花了多少 token,不知道响应里哪个字段是钱。
所以这一节不看「能不能出字」,看两件事:请求里到底有哪几个字段,响应里到底该盯哪几个字段。
官方给的最小调用只有两个参数(F9):
client.interactions.create(model=..., input=...)
返回值上用 .output_text 直接取文本(F9)。密钥不写在代码里,官方推荐用环境变量 GEMINI_API_KEY(也接受 GOOGLE_API_KEY)(F68)。
三版最小调用长这样,需要你自己的密钥,本机不执行,所以放在不参与自动运行的块里:
## Python
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="用一句话解释 AI 是怎么工作的",
)
print(interaction.output_text)
## JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const interaction = await ai.interactions.create({
model: "gemini-3.8-flash",
input: "用一句话解释 AI 是怎么工作的",
});
console.log(interaction.output_text);
## REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-H "Api-Revision: 2026-05-20" \
-d '{"model": "gemini-3.8-flash", "input": "用一句话解释 AI 是怎么工作的"}'
REST 那版有个细节值得单独记住:官方所有 REST 示例都带 Api-Revision: 2026-05-20 这个请求头(F64),但文档正文从没解释它是干什么的,也没说能不能省略。所以照抄最安全;「能不能不带」属于待核(F65),本教程不替你下结论。
二、Gemini API 响应校验:最小可运行示例
真实调用要密钥,本机跑不了;但「响应长什么样、该断言什么」可以离线练。下面用官方 REST 响应样例的字段结构做一份 mock,校验成功的判据。
## EXPECT: 请求 model=gemini-3.8-flash input=1 段 | 响应 status=completed | output_text 非空 | usage total=197 in=8 out=12 | 差额=有(197 与 in+out 不相等,说明还有未计入 output_text 的 token)
REQUEST = {"model": "gemini-3.8-flash", "input": "用一句话解释 AI 是怎么工作的"}
RESPONSE = {
"id": "v1_demo",
"status": "completed",
"output_text": "AI 通过大量文本学习规律,再用这些规律生成新内容。",
"usage": {"total_tokens": 197, "total_input_tokens": 8, "total_output_tokens": 12},
}
def check(req, resp):
u = resp["usage"]
assert resp["status"] == "completed"
assert resp["output_text"].strip()
gap = u["total_tokens"] - (u["total_input_tokens"] + u["total_output_tokens"])
assert gap >= 0, f"total 小于 in+out,先查字段映射:{u}"
return (f"请求 model={req['model']} input={1} 段 | 响应 status={resp['status']} | "
f"output_text 非空 | usage total={u['total_tokens']} in={u['total_input_tokens']} "
f"out={u['total_output_tokens']} | 差额={'有' if gap else '无'}"
f"(197 与 in+out 不相等,说明还有未计入 output_text 的 token)")
print(check(REQUEST, RESPONSE))
三、解释与边界:三个字段、一个坑、一条边界
三个字段。 model 决定你调谁,input 是本轮输入,密钥走环境变量而不是参数。这三样之外的东西——温度、思考强度、结构化格式——都属于「后面章节的事」,第一条请求先不碰。
一个坑:usage 里三个数对不上是正常的。 官方响应样例是 total_tokens 197、total_input_tokens 8、total_output_tokens 12(F66),加起来只有 20。差额不是文档写错,而是还有你没在 output_text 里看到的部分(思考步骤)。所以做成本核算时不要拿 in + out 当 total,直接读 total_tokens;差额怎么计价,见 10.1。上面的 check 把差额算成了变量 gap,并只对「差额为负」报错——那一定是你字段读错了,不是计费异常。
边界:本节不教流式、不教多轮、不教错误重试策略。 流式见 11.3,多轮见 4.1,重试策略见 11.1。第一节请求只需要成功一次,并且你能读懂它的响应。
还有一条容易被忽略:output_text 是 SDK 的便利属性。REST 原始返回里没有这个字段名,它是从 steps 里拼出来的。所以「Python 里有 .output_text、curl 里找不到 output_text」不是版本问题,是抽象层不同。
四、预期输出与异常分支
真跑输出:
请求 model=gemini-3.8-flash input=1 段 | 响应 status=completed | output_text 非空 | usage total=197 in=8 out=12 | 差额=有(197 与 in+out 不相等,说明还有未计入 output_text 的 token)
首请求失败,基本落在四类里,处理顺序不要乱。密钥缺失或无效:本地报的是环境变量为空,服务端回 401 UNAUTHENTICATED,先查 echo $GEMINI_API_KEY 和进程是否重启过。权限或区域问题:403 PERMISSION_DENIED,回到见 1.2 查区域清单,不要在这里改代码。模型名写错:404 NOT_FOUND 且报错里会带模型名,去见 3.1 用 models.list 查,别猜。配额或频率:429 RESOURCE_EXHAUSTED,退避重试,分流规则见 11.1。
一个反常识的点:status 为 completed 不代表内容一定有用。它只说明这一轮交互正常结束了;内容是否被安全策略截断,要看别的字段(见 11.2)。
五、判据卡:首请求失败的排查顺序
| 该这么做 | 不该这么做 |
|---|---|
| 先确认环境变量有值,再怀疑代码 | 把密钥硬编码进脚本「先跑通」 |
| 403 先查区域与权限,不改代码 | 见到失败就加 try/except 吞掉 |
404 用 models.list 确认真实模型名 |
照着博客里的模型 ID 反复试 |
成本核算读 total_tokens |
用 in + out 自己加 |
REST 照抄官方示例的 Api-Revision 头 |
凭感觉删掉看不懂的请求头 |
六、来源与核验
https://aistudio.google.com/docs/get-started.md(核验 2026-11-05,F9、F64、F66)https://aistudio.google.com/docs/api-key.md(核验 2026-11-05,F68)https://aistudio.google.com/api-reference/api-versions.md(核验 2026-11-05,F8)https://aistudio.google.com/docs/api-errors.md(核验 2026-11-05,F69)
Api-Revision 请求头的作用与必要性属于待核(F65):官方示例一律带它,但文档没有散文说明,正文因此只写「照抄」,不写「必须」或「可省」。REST 路径的 v1 与 v1beta 写法差异同样存在,见 2.3。
七、动手试
- 把
RESPONSE里的status改成"incomplete",重跑。预期会抛AssertionError;验收标准是你说清「为什么校验status比校验文本长度更可靠」。 - 把
usage里的total_tokens改成10,重跑。预期抛AssertionError: total 小于 in+out,先查字段映射;验收标准是你能说清「total小于in + out只可能是字段映射或响应解析出错,不可能是计费异常」——所以这个断言查的是解析,不是钱。 - 用你自己的密钥发一次真实请求(三版任选),把完整响应存成 JSON,找出
output_text对应的原始字段。验收标准:写下一行「Python 拿到的.output_text来自 REST 的哪个字段」,写不出来说明这条链路还没通。

TRAE-AI编程


更多建议: