Google AI Studio怎么用?从创建API密钥到调用Gemini生成结构化结果
本文从首次使用场景出发,介绍如何进入Google AI Studio、创建并管理Gemini API密钥,在测试区提交提示词并检查模型输出,同时演示如何把会议文本整理为JSON。文中还说明结构化输出、参数调试、密钥保护、额度、地区和计费等需
ARTICLE DETAIL
本文以一个明确的SSE事件协议为例,展示浏览器如何读取后端转发的流式响应,处理跨网络分块的中文文本、结束信号和错误事件,并说明取消请求、连接断开、部分结果保留以及服务端密钥保护等实践要点。
样式 7 内容详情排版
流式输出和一次性返回的区别,在于客户端是否能在完整答案生成前收到增量数据。一次性请求通常要等服务端完成后才得到完整JSON;流式请求则会连续发送多个事件,界面可以先显示已生成的内容。需要区分两个时间:首段响应时间是从发起请求到收到第一段可显示内容的时间,总生成时间则是到结束事件到达的时间。流式传输不必然降低总耗时或费用,但能改善等待过程中的反馈。
不同API的字段和事件名称可能不同。下面只演示一套由业务后端约定的协议,不把它当成所有厂商的通用格式。客户端请求后端的/api/answer,请求体包含message和stream:true。后端返回Content-Type: text/event-stream,每个事件之间用空行分隔,事件只包含一行data::
{"type":"text_delta","text":"你好"}{"type":"tool_delta","name":"search","arguments":"{..."},参数可能跨多个事件,需要继续拼接。{"type":"done"}{"type":"error","message":"..."}真实项目应以所接入API的协议文档为准,不要把其他服务的字段直接套进来。
API密钥应只放在服务端,由后端调用模型服务并转发结果。浏览器只访问自己的业务接口。下面的代码使用Fetch读取响应体,并用TextDecoder处理可能被拆开的UTF-8中文字符:
const controller = new AbortController();
const output = document.querySelector('#output');
let buffer = '';
let;
async function start(message) {
const res = await fetch('/api/answer', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({message, stream: true}),
signal: controller.signal
});
if (!res.ok || !res.body) throw new Error('流式请求失败');
const reader = res.body.getReader();
const decoder = new TextDecoder();
while (true) {
const {value, done} = await reader.read();
buffer += decoder.decode(value || new Uint8Array(), {stream: !done});
const events = buffer.split('\n\n');
buffer = events.pop() || '';
for (const event of events) {
const line = event.split('\n').find(x => x.startsWith('data:'));
if (!line) continue;
const item = JSON.parse(line.slice(5).trim());
if (item.type === 'text_delta') {
text += item.text;
output.textContent = text;
} else if (item.type === 'error') {
throw new Error(item.message);
} else if (item.type === 'done') {
output.dataset.complete = 'true';
}
}
if (done) break;
}
}
这里的关键不是把每次read()当作一个完整事件。网络层可能把一个事件拆成多个数据块,也可能一次读到多个事件,所以必须保留未完成的buffer,按协议分隔符拆分。TextDecoder的stream:true也不能省略,否则多字节中文恰好跨块时可能出现乱码。
文本增量可以直接追加到回答区域;工具调用增量则应单独缓存,等参数完整后再校验JSON并执行,不能把工具参数当作用户可见文本。收到done后再把回答标记为完成。错误事件需要展示可理解的提示,同时保留已经收到的文本,便于用户复制或重试。若协议允许注释行或多行data,解析器还应按该协议合并多行字段,而不是只取第一行。
用户点击“停止”时调用controller.abort(),前端应把当前结果标记为“未完成”,而不是伪装成正常结束。服务端也要监听客户端断开,尽早取消对上游模型的读取,避免无意义地继续生成。网络断开时同样保留已显示内容,但不要默认重试能够接续原输出:除非服务端协议提供可恢复的请求ID、游标或明确的续传机制,重试通常只是一次新的生成。
示例为便于理解在每个文本事件后刷新界面,生产环境可以把增量先放入队列,每隔约几十毫秒批量更新一次,减少布局和渲染开销。服务端还应设置合理的读取超时、错误日志和请求取消逻辑,并严格校验事件JSON。这样既能让用户尽早看到首段响应,也能在异常发生时准确区分“未开始”“部分完成”和“正常完成”。