Gemini generateContent
MarkdownFormat asli Google Gemini: untuk Gemini CLI, Google GenAI SDK, dan klien REST.
Panduan lengkap
https://api.ailoot.ai/v1beta/models/{model}:generateContentcurl "https://api.ailoot.ai/v1beta/models/gemini-3.8-flash:generateContent" \
-H "x-goog-api-key: $AILOOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{"role": "user", "parts": [{"text": "Buat tiga nama untuk kedai kopi."}]}
]
}' from google import genai
from google.genai import types
import os
client = genai.Client(
api_key=os.environ["AILOOT_API_KEY"],
http_options=types.HttpOptions(base_url="https://api.ailoot.ai"), # tanpa /v1beta
)
resp = client.models.generate_content(
model="gemini-3.8-flash",
contents="Buat tiga nama untuk kedai kopi.",
)
print(resp.text)import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({
apiKey: process.env.AILOOT_API_KEY,
httpOptions: { baseUrl: "https://api.ailoot.ai" }, // tanpa /v1beta
});
const resp = await ai.models.generateContent({
model: "gemini-3.8-flash",
contents: "Buat tiga nama untuk kedai kopi.",
});
console.log(resp.text);{
"candidates": [
{
"content": {
"role": "model",
"parts": [{ "text": "1. «Biji dan Uap» 2. «Gilingan Pagi» 3. «Kedai Kopi di Sudut»" }]
},
"finishReason": "STOP"
}
],
"usageMetadata": {
"promptTokenCount": 9,
"candidatesTokenCount": 27,
"totalTokenCount": 36
},
"modelVersion": "gemini-3.8-flash"
}Autentikasi
- x-goog-api-keyheaderwajib
Kunci
sk-…. Dapat juga menggunakanAuthorization: Bearerataux-api-key. Untuk kompatibilitas dengan Google, juga diterima?key=dalam alamat — dengan prioritas terendah;?api_key=ditolak dengan 400. Kami menyarankan header agar kunci tidak masuk ke log.
Jalur
- modelstringwajib
ID model dengan format Gemini, misalnya
gemini-3.8-flashataugemini-3.1-pro. Total 27.
https://api.ailoot.ai/v1beta/models/{model}:streamGenerateContent?alt=ssehttps://api.ailoot.ai/v1beta/modelsIsi permintaan
- contentsarraywajib
Pesan dengan
role(user/model) danparts: text, inlineData/fileData, functionCall/functionResponse. Lampiran harus sesuai dengan jenis input yang diterima model. - systemInstructionobjectopsional
Instruksi sistem berupa teks:
{"parts": [{"text": "…"}]}. - generationConfigobjectopsional
generationConfigmenerimatemperature,topP,topK,maxOutputTokens,thinkingConfig,responseMimeType(text/plainatauapplication/json),responseSchemaatauresponseJsonSchema(objek JSON),stopSequences(array string),candidateCount: 1, bilangan bulatseed, nilai numerikpresencePenaltydanfrequencyPenalty. Rentang yang diizinkan dan fitur bergantung pada model yang tepat; untuk respons JSON, pilih satu bentuk skema yang didukung danapplication/json. Untuk model teksresponseModalities— hanya["TEXT"]. - safetySettingsarrayopsional
Objek dengan kolom wajib
categorydanthreshold, kolom opsionalmethod. Nilainya harus didukung oleh model yang tepat. - toolsarrayopsional
Deklarasi fungsi klien
functionDeclarationsdijalankan oleh aplikasi Anda. Model teks juga menerima{"googleSearch": {}}dan{"urlContext": {}}: secara terpisah atau bersama-sama dalam arraytools. Google Search maupun URL context tidak dapat digabungkan denganfunctionDeclarationsdalam satu permintaan. Untuk output gambar, hanya fungsi klien yang tersedia. Alat bawaan lainnya dan explicit cache tidak didukung. Search/URL context dapat memerlukan saldo yang ditahan berdasarkan batas input penuh; nilai aktualtoolUsePromptTokenCountdihitung sebagai token input. - toolConfigobjectopsional
functionCallingConfig: mode (AUTO/ANY/NONE/VALIDATED/MODE_UNSPECIFIED), allowedFunctionNames.
Jika model tidak mendukung kolom, lampiran, atau kombinasi alat, permintaan ditolak sebelum dana ditahan — tidak ada pendebitan. Respons berupa HTTP 400 dengan status INVALID_ARGUMENT dan kelas invalid_request (di ErrorInfo.reason — INVALID_REQUEST). JSON yang tidak valid, kesalahan parameter jalur, dan kegagalan validasi lainnya juga mengembalikan 400; baca pesan kesalahan dan Request ID. Fitur bergantung pada model: periksa format dan inputnya di katalog.
PDF, audio, video, dan tautan
Untuk model Gemini yang mendukung jenis input tersebut, parts[].inlineData berisi mimeType dan data base64 yang tidak kosong; PDF harus berupa file PDF yang valid. fileData berisi alamat publik httpsdi fileUri dan MIME jenis file. Untuk YouTube, MIME boleh tidak diisi. http, alamat privat, gs:// dan objek Google Files API tidak didukung, begitu pula unggahan melalui Google Files API. Untuk video, Anda dapat menambahkan videoMetadata: startOffset/endOffset sebagai string dalam detik (misalnya, 1.5s) dan fps lebih dari 0 dan tidak lebih dari 24. Ukuran isi permintaan, konteks, input yang diizinkan, dan batas respons diperiksa berdasarkan model dan format.
| Input | MIME yang didukung |
|---|---|
| Gambar inline | image/png, image/jpeg, image/webp |
| Dokumen | application/pdf; text/plain, text/html, text/css, text/csv, text/xml, text/rtf, text/markdown, text/javascript, application/x-javascript, text/x-python, application/x-python |
| Audio | audio/wav, audio/mp3, audio/mpeg, audio/aiff, audio/aac, audio/ogg, audio/flac |
| Video | video/mp4, video/mpeg, video/mov, video/quicktime, video/avi, video/x-flv, video/mpg, video/webm, video/wmv, video/3gpp |
import json, os, urllib.request
def generate(model, payload):
req = urllib.request.Request(
"https://api.ailoot.ai/v1beta/models/" + model + ":generateContent",
data=json.dumps(payload).encode(),
headers={"x-goog-api-key": os.environ["AILOOT_API_KEY"],
"Content-Type": "application/json"},
)
# Kirim sekali saja. Jika batas waktu terlampaui, periksa Request ID di riwayat penggunaan sebelum mencoba lagi.
with urllib.request.urlopen(req, timeout=300) as response:
print("Request ID:", response.headers.get("X-Request-ID"))
return json.load(response)
import base64, pathlib, sys
# Sediakan berkas PDF, audio, atau video lokal yang nyata beserta jenis MIME yang didukung.
path, mime = pathlib.Path(sys.argv[1]), sys.argv[2]
payload = {"contents": [{"role": "user", "parts": [
{"text": "Jelaskan isi berkas secara singkat."},
{"inlineData": {"mimeType": mime,
"data": base64.b64encode(path.read_bytes()).decode()}},
]}]}
print(generate("gemini-3.8-flash", payload))
# Lampiran alternatif: {"fileData": {"mimeType": mime, "fileUri": public_https_url}}
# Untuk URL YouTube yang nyata: {"fileData": {"fileUri": youtube_url}}Search dan URL context
Deklarasi fungsi klien functionDeclarations dijalankan oleh aplikasi Anda. Model teks juga menerima {"googleSearch": {}} dan {"urlContext": {}}: secara terpisah atau bersama-sama dalam array tools. Google Search maupun URL context tidak dapat digabungkan dengan functionDeclarations dalam satu permintaan. Untuk output gambar, hanya fungsi klien yang tersedia. Alat bawaan lainnya dan explicit cache tidak didukung. Search/URL context dapat memerlukan saldo yang ditahan berdasarkan batas input penuh; nilai aktual toolUsePromptTokenCount dihitung sebagai token input.
{"tools": [{"googleSearch": {}}, {"urlContext": {}}]}Output gambar
Output gambar dalam respons berformat Gemini hanya didukung oleh gemini-3.1-flash-image. Fitur ini terpisah dari /v1/images/generations: model gambar lain tidak berfungsi di sini. Model ini memiliki batas input hingga 131072 token dan respons hingga 32768; biaya penuh respons terpanjang ditahan di awal.
responseModalities — himpunan TEXT/IMAGE yang tidak kosong dan tanpa duplikat. imageConfig.imageSize: 1K/2K/4K; aspectRatio: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9, 1:4, 4:1, 1:8, 8:1. Input model ini berupa teks dan PNG/JPEG/WebP inline; PDF/audio/video/fileData serta Search/URL context bawaan tidak diterima di sini. Ketersediaan dan harga untuk kunci Anda dapat dilihat di katalog dan GET /v1/models.
import json, os, urllib.request
def generate(model, payload):
req = urllib.request.Request(
"https://api.ailoot.ai/v1beta/models/" + model + ":generateContent",
data=json.dumps(payload).encode(),
headers={"x-goog-api-key": os.environ["AILOOT_API_KEY"],
"Content-Type": "application/json"},
)
# Kirim sekali saja. Jika batas waktu terlampaui, periksa Request ID di riwayat penggunaan sebelum mencoba lagi.
with urllib.request.urlopen(req, timeout=300) as response:
print("Request ID:", response.headers.get("X-Request-ID"))
return json.load(response)
import base64, pathlib
reply = generate("gemini-3.1-flash-image", {
"contents": [{"role": "user", "parts": [{"text": "Lukisan cat air: mercusuar saat fajar"}]}],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"},
},
})
index = 0
for candidate in reply.get("candidates", []):
for part in candidate.get("content", {}).get("parts", []):
if "text" in part:
print(part["text"])
blob = part.get("inlineData", {})
if blob.get("mimeType", "").startswith("image/") and blob.get("data"):
index += 1
extension = {"image/png": "png", "image/jpeg": "jpg",
"image/webp": "webp"}.get(blob["mimeType"], "bin")
pathlib.Path(f"gemini-image-v{index}.{extension}").write_bytes(
base64.b64decode(blob["data"]))
print("All returned images:", index)Siklus lengkap pemanggilan fungsi
Fungsi dijalankan oleh klien. Kembalikan seluruh content asli model beserta thoughtSignature tanpa perubahan, lalu functionResponse dengan name dan id yang sama jika id terdapat dalam functionCall.
import json, os, urllib.request
def generate(model, payload):
req = urllib.request.Request(
"https://api.ailoot.ai/v1beta/models/" + model + ":generateContent",
data=json.dumps(payload).encode(),
headers={"x-goog-api-key": os.environ["AILOOT_API_KEY"],
"Content-Type": "application/json"},
)
# Kirim sekali saja. Jika batas waktu terlampaui, periksa Request ID di riwayat penggunaan sebelum mencoba lagi.
with urllib.request.urlopen(req, timeout=300) as response:
print("Request ID:", response.headers.get("X-Request-ID"))
return json.load(response)
tools = [{"functionDeclarations": [{
"name": "multiply", "description": "Mengalikan dua bilangan",
"parameters": {"type": "object", "properties": {
"a": {"type": "number"}, "b": {"type": "number"}},
"required": ["a", "b"]},
}]}]
contents = [{"role": "user", "parts": [{"text": "Kalikan 7 dengan 8 menggunakan fungsi"}]}]
for turn in range(4): # Batasi pengulangan pemanggilan alat; jangan kirim ulang permintaan yang hasilnya belum jelas.
reply = generate("gemini-3.8-flash", {"contents": contents, "tools": tools})
content = reply["candidates"][0]["content"]
contents.append(content) # Pertahankan semua (ALL) bagian asli dan thoughtSignature tanpa perubahan.
results = []
for part in content.get("parts", []):
call = part.get("functionCall")
if not call:
continue
if call["name"] != "multiply":
raise ValueError("Unexpected function")
args = call["args"]
result = {"name": call["name"], "response": {"value": args["a"] * args["b"]}}
if "id" in call:
result["id"] = call["id"]
results.append({"functionResponse": result})
if not results:
print(content)
break
contents.append({"role": "user", "parts": results})
else:
raise RuntimeError("Tool loop limit reached")Respons
- candidates[].content.partsarray
Respons model.
- usageMetadataobject
promptTokenCount,candidatesTokenCount,totalTokenCount.