dokumentaatio
API

Gemini generateContent

Markdown

Google Geminin oma muoto: Gemini CLI:lle, Google GenAI SDK:lle ja REST-asiakkaille.

Koko opas
POSThttps://api.ailoot.ai/v1beta/models/{model}:generateContent
Gemini generateContent
curl "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": "Keksi kolme nimeä kahvilalle."}]}
    ]
  }' 
200 OK
{
  "candidates": [
    {
      "content": {
        "role": "model",
        "parts": [{ "text": "1. ”Papu ja höyry” 2. ”Aamujauhatus” 3. ”Kulmakahvila”" }]
      },
      "finishReason": "STOP"
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 9,
    "candidatesTokenCount": 27,
    "totalTokenCount": 36
  },
  "modelVersion": "gemini-3.8-flash"
}

Todennus

  • x-goog-api-keyheaderpakollinen

    Avain sk-…. Myös nämä käyvät: Authorization: Bearer tai x-api-key. Google-yhteensopivuuden vuoksi hyväksytään myös ?key= osoitteessa — alimmalla prioriteetilla; ?api_key= hylätään koodilla 400. Suosittelemme otsaketta, jotta avain ei päädy lokeihin.

Polku

  • modelstringpakollinen

    Gemini-muotoa tukevan mallin ID, esimerkiksi gemini-3.8-flash tai gemini-3.1-pro. Yhteensä 27.

POSThttps://api.ailoot.ai/v1beta/models/{model}:streamGenerateContent?alt=sse
GEThttps://api.ailoot.ai/v1beta/models

Pyynnön runko

  • contentsarraypakollinen

    Viestit, joissa on role (user/model) ja parts: text, inlineData/fileData, functionCall/functionResponse. Liitteiden on oltava sellaisia, jotka malli hyväksyy syötteenä.

  • systemInstructionobjectvalinnainen

    Tekstimuotoinen järjestelmäohje: {"parts": [{"text": "…"}]}.

  • generationConfigobjectvalinnainen

    generationConfig hyväksyy temperature, topP, topK, maxOutputTokens, thinkingConfig, responseMimeType (text/plain tai application/json), responseSchema tai responseJsonSchema (JSON-objekti), stopSequences (merkkijonotaulukko), candidateCount: 1, kokonaislukuarvo seed, numeeriset arvot presencePenalty ja frequencyPenalty. Sallitut vaihteluvälit ja ominaisuudet riippuvat kyseisestä mallista; valitse JSON-vastaukseen yksi tuettu skeemamuoto ja application/json. Tekstimalleilla responseModalities on vain ["TEXT"].

  • safetySettingsarrayvalinnainen

    Objektit, joissa on pakolliset category ja threshold, valinnainen method. Kyseisen mallin on tuettava arvoja.

  • toolsarrayvalinnainen

    Asiakkaan functionDeclarations suorittaa oma sovelluksesi. Tekstimalleilla hyväksytään myös {"googleSearch": {}} ja {"urlContext": {}}: erikseen tai yhdessä taulukossa tools. Google Searchia tai URL contextia ei voi yhdistää kenttään nimeltä functionDeclarations samassa pyynnössä. Kuvatulosteille ovat saatavilla vain asiakkaan funktiot. Muita sisäänrakennettuja työkaluja tai eksplisiittistä välimuistia ei tueta. Search/URL context voivat vaatia varauksen koko syöterajan mukaan; toteutunut toolUsePromptTokenCount lasketaan syötetokeneiksi.

  • toolConfigobjectvalinnainen

    functionCallingConfig: mode (AUTO/ANY/NONE/VALIDATED/MODE_UNSPECIFIED), allowedFunctionNames.

Jos malli ei tue kenttää, liitettä tai työkaluyhdistelmää, pyyntö hylätään ennen varausta — mitään ei veloiteta. HTTP-statuskoodi on 400 ja vastauksessa on status INVALID_ARGUMENT ja virheluokka invalid_request (kentässä ErrorInfo.reason — INVALID_REQUEST). Virheellinen JSON, polkuparametrien virheet ja muut tarkistusvirheet palauttavat myös 400; lue virheteksti ja Request ID. Ominaisuudet riippuvat mallista: tarkista sen muodot ja syötteet luettelosta.

PDF, ääni, video ja linkit

Gemini-malleilla, jotka tukevat kyseistä syötettä, parts[].inlineData sisältää mimeType ja ei-tyhjät base64-tiedot; PDF:n on oltava aito PDF. fileData sisältää julkisen https-osoitteen kentässä fileUri ja tiedoston MIME-tyypin. YouTubessa MIME voidaan jättää määrittämättä. http, yksityisiä osoitteita, gs:// ja Google Files API -objekteja ei tueta, eikä myöskään lataamista Google Files API:n kautta. Videoon voi lisätä videoMetadata: startOffset/endOffset merkkijonona sekunteina (esimerkiksi 1.5s) ja fps arvolla, joka on suurempi kuin 0 ja enintään 24. Pyynnön rungon koko, konteksti, sallittu syöte ja vastausraja tarkistetaan mallin ja muodon perusteella.

SyöteTuetut MIME-tyypit
Inline-kuvatimage/png, image/jpeg, image/webp
Asiakirjatapplication/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
Ääniaudio/wav, audio/mp3, audio/mpeg, audio/aiff, audio/aac, audio/ogg, audio/flac
Videovideo/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"},
    )
    # Lähetä vain kerran. Tarkista aikakatkaisun jälkeen Request ID käyttöhistoriastasi ennen kuin yrität uudelleen.
    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

# Anna oikea paikallinen PDF-, ääni- tai videotiedosto ja sen tuettu MIME-tyyppi.
path, mime = pathlib.Path(sys.argv[1]), sys.argv[2]
payload = {"contents": [{"role": "user", "parts": [
    {"text": "Kuvaile lyhyesti tiedoston sisältö."},
    {"inlineData": {"mimeType": mime,
                    "data": base64.b64encode(path.read_bytes()).decode()}},
]}]}
print(generate("gemini-3.8-flash", payload))
# Vaihtoehtoinen liite: {"fileData": {"mimeType": mime, "fileUri": public_https_url}}
# Oikealle YouTube-URL-osoitteelle: {"fileData": {"fileUri": youtube_url}}

Search ja URL context

Asiakkaan functionDeclarations suorittaa oma sovelluksesi. Tekstimalleilla hyväksytään myös {"googleSearch": {}} ja {"urlContext": {}}: erikseen tai yhdessä taulukossa tools. Google Searchia tai URL contextia ei voi yhdistää kenttään nimeltä functionDeclarations samassa pyynnössä. Kuvatulosteille ovat saatavilla vain asiakkaan funktiot. Muita sisäänrakennettuja työkaluja tai eksplisiittistä välimuistia ei tueta. Search/URL context voivat vaatia varauksen koko syöterajan mukaan; toteutunut toolUsePromptTokenCount lasketaan syötetokeneiksi.

{"tools": [{"googleSearch": {}}, {"urlContext": {}}]}

Kuvatulosteet

Vain gemini-3.1-flash-image voi tuottaa kuvia Gemini-muotoisessa vastauksessa. Tämä on erillinen ominaisuus suhteessa /v1/images/generations: muut kuvamallit eivät toimi tässä. Tällä mallilla syöte on enintään 131072 tokenia ja vastaus enintään 32768; pisimmän mahdollisen vastauksen koko hinta varataan etukäteen.

responseModalities — ei-tyhjä TEXT/IMAGE-joukko ilman toistoja. 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. Tämän mallin syöte on teksti ja inline PNG/JPEG/WebP; PDF/audio/video/fileData ja sisäänrakennetut Search/URL context eivät käy tässä. Tiedot mallien saatavuudesta ja hinnoista omalle avaimellesi löytyvät luettelosta ja 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"},
    )
    # Lähetä vain kerran. Tarkista aikakatkaisun jälkeen Request ID käyttöhistoriastasi ennen kuin yrität uudelleen.
    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": "Akvarelli: majakka aamunkoitteessa"}]}],
    "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)

Funktiokutsujen koko kierros

Asiakas suorittaa funktiot. Palauta mallin koko alkuperäinen content ja thoughtSignature muuttamattomina, sitten functionResponse samalla name-arvolla ja samalla id-arvolla, jos id oli mukana functionCallissa.

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"},
    )
    # Lähetä vain kerran. Tarkista aikakatkaisun jälkeen Request ID käyttöhistoriastasi ennen kuin yrität uudelleen.
    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": "Kerro kaksi lukua keskenään",
    "parameters": {"type": "object", "properties": {
        "a": {"type": "number"}, "b": {"type": "number"}},
        "required": ["a", "b"]},
}]}]
contents = [{"role": "user", "parts": [{"text": "Kerro 7 luvulla 8 funktion avulla"}]}]
for turn in range(4):  # Rajoita työkalusilmukan toistot; älä lähetä uudelleen pyyntöä, jonka tulos on epäselvä.
    reply = generate("gemini-3.8-flash", {"contents": contents, "tools": tools})
    content = reply["candidates"][0]["content"]
    contents.append(content)  # Säilytä KAIKKI alkuperäiset osat ja thoughtSignature muuttumattomina.
    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")

Vastaus

  • candidates[].content.partsarray

    Mallin vastaus.

  • usageMetadataobject

    promptTokenCount, candidatesTokenCount, totalTokenCount.

Onko vielä kysyttävää? Lähetä Request ID ja kuvaus — autamme selvittämään asian.Ota yhteyttä tukeen