Google har lagt ut ett nytt lager med sin API-uppdatering i september 2026: Gemini 3.8 Flash är nu standardmodellen för utvecklare som bygger AI-agenter, och den kommer med ett kontextfönster på en miljon token och inbyggt stöd för function calling. Om du har velat bygga en riktig AI-agent som kan slå upp data, anropa ett väder-API eller boka något åt en användare, men aldrig kommit förbi “hello world”-exemplen, är den här guiden för dig. Vi bygger en komplett agent från grunden, i Python, med verktyg (tools), felhantering och produktionsnära mönster som du faktiskt kan använda i ett riktigt projekt.
Till skillnad från de flesta tutorials som stannar vid ett enda API-anrop går vi igenom hela flödet: autentisering, function calling med flera verktyg, strömmande svar, felkoder du kommer stöta på i produktion, samt hur du håller kostnaden nere när agenten börjar göra hundratals anrop per dag. All kod är testad mot den officiella Python-SDK:n google-genai och modellen gemini-3.8-flash.
Vad är Gemini API och varför Gemini 3.8 Flash just nu
Gemini API är Googles gränssnitt för att bygga applikationer ovanpå Gemini-modellfamiljen, samma teknik som driver Gemini-appen och stora delar av Googles sökprodukter. För utvecklare är poängen att man slipper hantera egen GPU-infrastruktur och istället betalar per token för att skicka text, bilder, ljud eller video till modellen och få tillbaka ett svar, eventuellt med ett verktygsanrop inbakat.
I september 2026 är Gemini 3.8 Flash (modell-id gemini-3.8-flash) den modell Google själva beskriver som sin mest kapabla Flash-modell, byggd för långa agentflöden, autonom kodning och komplexa arbetsflöden i företag. Den har ett kontextfönster på 1 miljon token och stöder upp till 64 000 utdatatoken per svar, vilket räcker för att mata in hela kodbaser eller långa dokumentsamlingar i en enda förfrågan. Modellen har tre inställbara “thinking levels” (low, medium, high) som styr hur mycket intern resonemangstid modellen får innan den svarar, vilket är särskilt relevant när du bygger agenter som ska fatta flerstegsbeslut.
Priset ligger på 0,75 dollar per miljon inmatade token och 3,75 dollar per miljon utmatade token, ett introduktionspris som enligt Googles egen dokumentation gäller till den 31 december 2026. Det är samma prisnivå som föregångaren Gemini 3.7 Flash, vilket betyder att Google höjt kapaciteten utan att höja priset, ett ovanligt drag i en bransch där nya modellgenerationer oftast kostar mer. Kontext-caching, där du återanvänder delar av en tidigare skickad kontext utan att betala fullt pris igen, kostar 0,075 dollar per miljon token under samma period.
Den här guiden fokuserar på function calling (verktygsanrop), funktionen som gör att en språkmodell kan gå från att bara chatta till att faktiskt göra saker: slå upp aktuell data, anropa interna API:er, skriva till en databas eller trigga en process i ditt system. Det är kärnan i varje AI-agent som är mer än en chattbot.
Förkunskaper och verktyg du behöver
Innan du börjar, se till att du har följande på plats. Listan är kort med flit, du ska kunna komma igång på under tio minuter.
- Python 3.10 eller senare (testat med 3.12)
- Ett Google-konto och tillgång till Google AI Studio för att skapa en API-nyckel
- Paketet
google-genai, den aktuella officiella Python-SDK:n, som ersätter det äldregoogle-generativeai-paketet - Paketet
python-dotenvför att hålla API-nyckeln utanför källkoden - Grundläggande kunskap om Python-funktioner och JSON
- En terminal och en kodeditor (VS Code, PyCharm eller motsvarande)
- Ett betalkort kopplat till ett Google Cloud-projekt om du vill gå förbi gratisnivåns begränsningar (valfritt för denna guide)
Du behöver inte något Google Cloud-projekt för att komma igång, en nyckel från AI Studio räcker för utveckling och test. Vill du senare skala upp till produktion är det värt att koppla nyckeln till ett riktigt projekt så att du får tillgång till högre kvoter och separata miljöer för dev, stage och produktion, något Google själva rekommenderar i sin driftsdokumentation.
Steg 1: Skaffa en API-nyckel i Google AI Studio
Gå till Google AI Studio och logga in med ditt Google-konto. Under menyn för API-nycklar klickar du på “Skapa API-nyckel” och väljer antingen ett befintligt Google Cloud-projekt eller låter Google skapa ett åt dig automatiskt. Nyckeln du får är en lång sträng som börjar med AIza. Spara den direkt, den visas bara en gång i klartext i gränssnittet (du kan alltid generera en ny om du tappar bort den).
Lägg aldrig nyckeln direkt i koden. Skapa istället en .env-fil i projektmappen:
GEMINI_API_KEY=AIzaSyDIN_DIN_NYCKEL_HAR_1234567890
Lägg till .env i din .gitignore-fil så att nyckeln aldrig hamnar i versionshanteringen. Det här är ett av de vanligaste säkerhetsmisstagen nya utvecklare gör. En nyckel som läcker till ett publikt GitHub-repo hittas ofta inom minuter av automatiska skannrar och kan missbrukas för att generera fakturor i ditt namn.
Steg 2: Installera SDK:n och sätt upp projektet
Skapa en projektmapp och en virtuell miljö innan du installerar något. Det håller beroenden isolerade från resten av systemet.
mkdir gemini-agent && cd gemini-agent
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install google-genai python-dotenv
Paketet heter google-genai, inte google-generativeai. Det äldre paketet finns kvar av bakåtkompatibilitetsskäl i gamla exempel du hittar på nätet, men Google har flyttat allt aktivt utvecklingsarbete till google-genai, och det är den SDK:n som stöder de senaste funktionerna som thinking levels och den nyare tool-arkitekturen. Skriver du ny kod idag, använd google-genai.
Verifiera installationen:
python3 -c "import google.genai; print('OK, SDK installerad')"
Steg 3: Ditt första API-anrop
Innan vi bygger agenten, testa att grundflödet fungerar. Skapa en fil test_basic.py:
import os
from dotenv import load_dotenv
from google import genai
load_dotenv()
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Förklara vad function calling är för en junior-utvecklare, max 3 meningar."
)
print(response.text)
Kör filen med python3 test_basic.py. Om allt är korrekt uppsatt får du ett textsvar tillbaka inom någon sekund. Ett typiskt utdataexempel:
Function calling låter en språkmodell begära att en specifik funktion i din kod
körs, istället för att bara svara med text. Modellen läser en beskrivning av
vilka funktioner som finns och vilka parametrar de tar, och väljer själv när
den ska anropa dem baserat på användarens fråga. Resultatet från funktionen
skickas sedan tillbaka till modellen, som formulerar ett slutgiltigt svar.
Fungerar inte detta steg är det nästan alltid ett problem med API-nyckeln eller miljövariabeln, inte med koden. Gå till felsökningsavsnittet längre ner om du fastnar här.
Steg 4: Definiera ditt första verktyg (tool)
Nu till det som gör en agent till en agent. Ett verktyg är en vanlig Python-funktion, men med en tydlig docstring och typade parametrar. SDK:n google-genai kan läsa av Python-funktioner direkt och bygga verktygsschemat automatiskt, du behöver inte skriva JSON-schema för hand som i äldre exempel.
def hamta_vader(stad: str) -> dict:
"""Hämtar aktuellt väder för en given stad.
Args:
stad: Namnet på staden, t.ex. "Stockholm" eller "Malmö".
Returns:
Ett dictionary med temperatur och väderbeskrivning.
"""
# I en riktig applikation: anropa ett riktigt väder-API här
fejkdata = {
"stockholm": {"temp": 14, "beskrivning": "molnigt"},
"malmö": {"temp": 17, "beskrivning": "sol"},
"göteborg": {"temp": 13, "beskrivning": "regn"},
}
return fejkdata.get(stad.lower(), {"temp": None, "beskrivning": "okänd stad"})
Docstringen är inte kosmetisk här, den är en del av API-kontraktet. Modellen läser texten i Args för att förstå vad varje parameter förväntar sig, så en otydlig docstring ger sämre träffsäkerhet på när och hur verktyget anropas. Det är en av de vanligaste orsakerna till att en agent “inte fattar” att den ska använda ett visst verktyg.
Steg 5: Koppla verktyget till modellen
Skapa agent_v1.py och skicka in funktionen som ett verktyg i konfigurationen:
import os
from dotenv import load_dotenv
from google import genai
from google.genai import types
load_dotenv()
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
def hamta_vader(stad: str) -> dict:
"""Hämtar aktuellt väder för en given stad."""
fejkdata = {
"stockholm": {"temp": 14, "beskrivning": "molnigt"},
"malmö": {"temp": 17, "beskrivning": "sol"},
}
return fejkdata.get(stad.lower(), {"temp": None, "beskrivning": "okänd stad"})
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Vad är det för väder i Malmö just nu?",
config=types.GenerateContentConfig(
tools=[hamta_vader],
),
)
print(response.text)
När du kör detta hanterar SDK:n hela loopen automatiskt: modellen ser frågan, bestämmer att den behöver anropa hamta_vader("Malmö"), SDK:n kör funktionen lokalt i din process, skickar tillbaka resultatet till modellen, och modellen formulerar ett svar på naturligt språk. Ett typiskt svar:
Just nu är det sol i Malmö med en temperatur på 17 grader.
Steg 6: Bygg en agent med flera verktyg
En riktig agent behöver oftast fler än ett verktyg, och modellen ska själv avgöra vilket eller vilka som krävs för att svara. Utöka exemplet med ett till verktyg för att räkna ut restid:
def berakna_restid(fran_stad: str, till_stad: str) -> dict:
"""Beräknar ungefärlig restid med bil mellan två svenska städer.
Args:
fran_stad: Startstad.
till_stad: Slutstad.
Returns:
Dictionary med restid i minuter och avstånd i kilometer.
"""
ruttdata = {
("stockholm", "malmö"): {"minuter": 360, "km": 615},
("stockholm", "göteborg"): {"minuter": 270, "km": 470},
("malmö", "göteborg"): {"minuter": 150, "km": 270},
}
nyckel = (fran_stad.lower(), till_stad.lower())
return ruttdata.get(nyckel, {"minuter": None, "km": None})
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Jag är i Stockholm och vill åka till Malmö. Hur är vädret där och hur lång är resan?",
config=types.GenerateContentConfig(
tools=[hamta_vader, berakna_restid],
),
)
print(response.text)
Modellen delar upp frågan i två deluppgifter, anropar båda verktygen (i valfri ordning eller parallellt beroende på beslut) och slår ihop resultaten till ett sammanhängande svar. Det här mönstret, flera verktyg i samma konfiguration, är grunden i praktiskt taget alla produktionsagenter, oavsett om de bokar möten, slår upp lagerstatus eller sammanställer rapporter.
Steg 7: Strukturerad utdata med JSON-schema
Ibland vill du inte ha fritext tillbaka utan ett förutsägbart JSON-objekt du kan mata in i en databas eller ett annat system. Det gör du genom att ange ett svarsschema:
from pydantic import BaseModel
class ResRekommendation(BaseModel):
destination: str
temperatur: int
rekommenderas: bool
motivering: str
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Baserat på vädret, är Malmö en bra resa just nu?",
config=types.GenerateContentConfig(
tools=[hamta_vader],
response_mime_type="application/json",
response_schema=ResRekommendation,
),
)
resultat = ResRekommendation.model_validate_json(response.text)
print(resultat.destination, resultat.temperatur, resultat.rekommenderas)
Genom att kombinera Pydantic-modeller med response_schema slipper du skriva egen validering och parsning för hand, en vanlig källa till buggar i tidiga AI-agent-prototyper som aldrig kommer förbi demo-stadiet.
Steg 8: Strömma svar för bättre användarupplevelse
Om agenten är kopplad till ett chattgränssnitt vill du oftast inte att användaren stirrar på en tom skärm i flera sekunder. Strömning (streaming) skickar tokens allt eftersom de genereras:
for chunk in client.models.generate_content_stream(
model="gemini-3.8-flash",
contents="Skriv en kort sammanfattning av varför function calling är användbart.",
):
print(chunk.text, end="", flush=True)
Kombinerat med verktygsanrop blir strömning lite mer komplex eftersom modellen kan behöva pausa mitt i en generering för att vänta på ett funktionsresultat. För de flesta chattgränssnitt är det värt komplexiteten, upplevd svarstid sjunker märkbart jämfört med att vänta på hela svaret.
Steg 9: Håll koll på tokens och kostnad
Varje svarsobjekt innehåller metadata om hur många token som använts. Logga det här från dag ett, inte efter att fakturan kommer som en överraskning:
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Sammanfatta de tre viktigaste punkterna om Gemini API.",
)
anvandning = response.usage_metadata
print(f"Indata-tokens: {anvandning.prompt_token_count}")
print(f"Utdata-tokens: {anvandning.candidates_token_count}")
print(f"Totalt: {anvandning.total_token_count}")
kostnad_usd = (anvandning.prompt_token_count / 1_000_000 * 0.75) + \
(anvandning.candidates_token_count / 1_000_000 * 3.75)
print(f"Ungefärlig kostnad: ${kostnad_usd:.6f}")
Med priset 0,75 dollar per miljon indata-token och 3,75 dollar per miljon utdata-token för Gemini 3.8 Flash blir varje enskilt anrop billigt, men en agent som gör hundratals anrop per timme i en produktionsloop kan snabbt bygga upp en kostnad du inte räknat med, särskilt om du av misstag skickar in hela konversationshistoriken vid varje anrop istället för att trimma den. Ett vanligt tips från produktionsguider är att spåra kostnad per genomförd uppgift, inte bara kostnad per API-anrop, eftersom en agent-loop med flera verktygsanrop kan multiplicera kostnaden för en enda användarförfrågan.
Steg 10: Felhantering och robusta återförsök
Ett API-anrop som fungerar i utveckling kommer förr eller senare att misslyckas i produktion: nätverksfel, tillfällig överbelastning eller att du träffar en kvotgräns. Bygg in återförsök med exponentiell backoff från start:
import time
from google.genai.errors import APIError
def anropa_med_reforsok(prompt, max_forsok=3):
for forsok in range(max_forsok):
try:
return client.models.generate_content(
model="gemini-3.8-flash",
contents=prompt,
)
except APIError as e:
if e.code == 429:
vantetid = 2 ** forsok
print(f"Kvotgräns nådd, väntar {vantetid}s...")
time.sleep(vantetid)
elif e.code in (400, 403):
# Klientfel ska INTE göras om, roten till felet ligger i anropet
raise
else:
if forsok == max_forsok - 1:
raise
time.sleep(1)
raise RuntimeError("Alla återförsök misslyckades")
Notera raden om koder 400 och 403: Googles egen felsökningsdokumentation är tydlig med att klientfel som ogiltig nyckel eller felaktig syntax inte ska göras om automatiskt, det löser aldrig sig själv och slösar bara tid och kvot. Bara serverfel och kvotfel (429) är värda att köa upp för återförsök.
Steg 11: Sätt ihop en komplett agent
Nu sätter vi ihop allt vi byggt till en sammanhängande fil, en liten men fungerande reseassistent-agent som kan svara på väder- och restidsfrågor, hantera fel och logga sin egen kostnad:
import os
import time
from dotenv import load_dotenv
from google import genai
from google.genai import types
from google.genai.errors import APIError
load_dotenv()
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
MODELL = "gemini-3.8-flash"
def hamta_vader(stad: str) -> dict:
"""Hämtar aktuellt väder för en svensk stad."""
data = {
"stockholm": {"temp": 14, "beskrivning": "molnigt"},
"malmö": {"temp": 17, "beskrivning": "sol"},
"göteborg": {"temp": 13, "beskrivning": "regn"},
}
return data.get(stad.lower(), {"temp": None, "beskrivning": "okänd stad"})
def berakna_restid(fran_stad: str, till_stad: str) -> dict:
"""Beräknar ungefärlig restid mellan två svenska städer."""
rutter = {
("stockholm", "malmö"): {"minuter": 360, "km": 615},
("stockholm", "göteborg"): {"minuter": 270, "km": 470},
}
return rutter.get((fran_stad.lower(), till_stad.lower()), {"minuter": None, "km": None})
def kor_agent(fraga: str, max_forsok: int = 3) -> str:
for forsok in range(max_forsok):
try:
svar = client.models.generate_content(
model=MODELL,
contents=fraga,
config=types.GenerateContentConfig(
tools=[hamta_vader, berakna_restid],
),
)
anv = svar.usage_metadata
kostnad = (anv.prompt_token_count / 1_000_000 * 0.75) + \
(anv.candidates_token_count / 1_000_000 * 3.75)
print(f"[debug] tokens in/ut: {anv.prompt_token_count}/{anv.candidates_token_count}, "
f"kostnad: ${kostnad:.6f}")
return svar.text
except APIError as e:
if e.code == 429 and forsok < max_forsok - 1:
time.sleep(2 ** forsok)
continue
raise
if __name__ == "__main__":
fraga = "Jag funderar på att åka från Stockholm till Göteborg imorgon. Hur blir vädret och hur lång är resan?"
print(kor_agent(fraga))
Kör filen och du bör få ett svar i stil med:
[debug] tokens in/ut: 412/86, kostnad: $0.000631
I Göteborg imorgon kan du vänta dig regn och 13 grader. Resan från Stockholm
tar cirka 4,5 timmar (270 minuter) och sträckan är ungefär 47 mil.
Det här är grundstommen. Från här kan du bygga vidare med riktiga API-integrationer istället för fejkdata, ett minne som sparar konversationshistorik mellan sessioner, och ett gränssnitt (till exempel en enkel Flask- eller FastAPI-server) som exponerar agenten som en tjänst.
Gemini API jämfört med OpenAI och Claude för agentbygge
Valet av modellleverantör beror mest på vilken typ av agent du bygger och var din data behöver ligga. Tredjepartsjämförelser som cirkulerat under 2026 beskriver genomgående Gemini som starkast för multimodala uppgifter och långa kontextfönster, medan OpenAI ofta lyfts fram för sitt mogna utvecklarekosystem och Claude för agentiska kodningsuppgifter och resonemang i textcentrerade flöden. Ingen av leverantörerna är objektivt bäst för alla scenarier, det handlar om vilken arbetsuppgift agenten ska lösa.
| Egenskap | Gemini 3.8 Flash | Typiskt för konkurrenter (2026) |
|---|---|---|
| Kontextfönster | 1 miljon token | Ofta 200 000–400 000 token hos flera konkurrerande API:er |
| Max utdata per svar | 64 000 token | Varierar, ofta lägre hos motsvarande "flash"/"mini"-modeller |
| Pris indata (per miljon token) | 0,75 dollar | Varierar kraftigt beroende på modelltier |
| Pris utdata (per miljon token) | 3,75 dollar | Varierar kraftigt beroende på modelltier |
| Thinking levels | Low / medium / high, justerbart per anrop | Finns hos vissa konkurrenter i annan form |
| Inbyggd grounding mot webben | URL Context-verktyg, allmänt tillgängligt | Finns hos flera leverantörer i olika utföranden |
Om din agent framför allt jobbar med stora mängder text eller behöver kombinera bild, ljud och text i samma anrop är Gemini ofta ett naturligt förstahandsval tack vare kontextfönstret. Behöver du istället en agent centrerad kring komplex kodgenerering över många steg kan det vara värt att jämföra resultat med Claude eller OpenAI:s modeller innan du låser dig, till exempel med hjälp av vår guide till att komma igång med Claude API. Priset skiljer sig också mellan modelltiers och bör alltid räknas på din egen förväntade volym snarare än på listpris allena.
Vanliga nybörjarmisstag att undvika
Här är de fällor som oftast dyker upp när utvecklare bygger sin första Gemini-agent, samlade från vanliga mönster i produktionsguider och Googles egen felsökningsdokumentation.
- Otydliga docstrings på verktygsfunktioner. Modellen väljer verktyg baserat på texten du skrivit. En vag beskrivning ger felaktiga eller uteblivna anrop.
- Att skicka hela konversationshistoriken varje gång. Det driver upp kostnaden i onödan och kan trigga tidsgränser vid för stora kontexter.
- Att göra om klientfel automatiskt. Fel som 400 och 403 löser sig aldrig av sig själva, felet ligger i anropet, inte i nätverket.
- Att hårdkoda API-nyckeln i källkoden. Använd alltid miljövariabler och håll nyckeln utanför versionshanteringen.
- Att inte separera dev, stage och produktion. Utan separata kvoter kan ett testskript i utveckling äta upp produktionens kvot.
- Att lita blint på verktygets utdata utan validering. Om ett verktyg returnerar felaktig eller manipulerad data och agenten agerar på den utan kontroll uppstår säkerhetsrisker, särskilt om verktyget har skrivrättigheter i ett riktigt system.
- Att glömma bort thinking levels vid komplexa uppgifter. Om agenten fattar dåliga flerstegsbeslut, testa att höja thinking level innan du byter modell helt.
Felsökning: vanliga fel och hur du löser dem
Nedan är de felkoder du med störst sannolikhet stöter på, hämtade från Googles officiella felkodsdokumentation för Gemini API, tillsammans med hur du åtgärdar varje enskilt problem.
| Felkod | Vad det betyder | Lösning |
|---|---|---|
| 400 INVALID_ARGUMENT | Förfrågan är felformaterad, ofta ett stavfel eller ett saknat obligatoriskt fält | Jämför anropet mot API-referensen, kontrollera att alla fält har rätt namn och typ |
| 400 FAILED_PRECONDITION | Ett förvillkor är inte uppfyllt, ofta kopplat till fakturering eller regional tillgänglighet | Kontrollera att projektet har fakturering aktiverad om det krävs för modellen/funktionen |
| 401 / autentiseringsfel | API-nyckeln saknas, är ogiltig eller har gått ut | Skapa en ny nyckel i AI Studio och verifiera att miljövariabeln laddas korrekt |
| 403 PERMISSION_DENIED | Nyckeln saknar rättigheter för den resurs du försöker använda | Kontrollera nyckelns behörigheter, eller skapa en ny nyckel med rätt scope |
| 404 NOT_FOUND | Angiven resurs, fil eller sökväg finns inte | Dubbelkolla modellnamnet och eventuella filreferenser i anropet |
| 429 RESOURCE_EXHAUSTED | Du har överskridit en kvotgräns (per minut, per dag eller kostnadsbaserad) | Implementera backoff och återförsök, eller uppgradera till en högre kvottier |
| 499 CANCELLED | Klienten kopplade från eller avbröt förfrågan innan svar kom | Kontrollera timeout-inställningar i din klientkod |
| 500 INTERNAL | Ett internt serverfel hos Google | Vänta kort och gör om anropet, om felet kvarstår kontrollera Googles statussida |
| 504 DEADLINE_EXCEEDED | Förfrågan tog för lång tid, ofta för att kontexten är för stor eller timeout för kort | Korta ner kontexten eller höj klientens timeout-värde |
Utöver dessa officiella felkoder är det värt att känna till några vanliga praktiska problem som inte alltid syns som ett tydligt felmeddelande:
- Modellen anropar inte verktyget alls. Skriv om docstringen tydligare, eller lägg till ett exempel i din prompt på när verktyget ska användas.
- Svaret kommer på engelska trots svensk prompt. Var explicit i systeminstruktionen, "Svara alltid på svenska" fungerar oftast direkt.
- Höga kostnader utan uppenbar orsak. Logga
usage_metadatapå varje anrop och leta efter onödigt lång konversationshistorik som skickas med varje gång. - Applikationen hänger sig vid stora kontexter. Sätt en explicit timeout i klientkoden och överväg att korta ner indata innan du skickar den.
- SDK:n hittar inte miljövariabeln. Kontrollera att
.env-filen ligger i samma mapp som skriptet och attload_dotenv()faktiskt körs innan klienten skapas.
Avancerade tips för produktion
När din agent ska gå från prototyp till något som faktiskt körs i produktion är det några saker som gör störst skillnad i praktiken.
Lås modellversionen explicit. Använd alltid det fullständiga modell-id:t, till exempel gemini-3.8-flash, istället för generiska aliasnamn. Det ger dig kontroll över exakt när du uppgraderar, snarare än att bli tvingad till en ny version utan förvarning.
Bygg in en circuit breaker. Om Gemini API skulle vara nere eller din kvot ta slut mitt i en hög trafiktopp, låt agenten falla tillbaka på en enklare regelbaserad logik eller en kö istället för att krascha hela flödet.
Använd context caching för repetitiva prompts. Om din agent skickar samma långa systeminstruktion eller kunskapsbas i varje anrop, cacha den delen av kontexten. Med priset 0,135 dollar per miljon token för cachad kontext (introduktionspris till slutet av 2026) blir besparingen påtaglig vid hög volym.
Begränsa och rotera nycklar. Skapa separata API-nycklar för dev, stage och produktion, begränsa varje nyckel till bara de modeller och funktioner den behöver, och rotera dem regelbundet. Om en nyckel läcker ska den kunna spärras utan att påverka resten av systemet.
Validera verktygens utdata innan agenten agerar på den. Särskilt om ett verktyg har skriv- eller betalningsrättigheter i ett riktigt system bör du lägga in ett explicit valideringssteg mellan verktygets svar och nästa handling agenten tar, snarare än att låta modellen agera helt fritt på rådata.
Skala upp: rate limits och kvottiers
Gemini API använder ett tiersystem för kvoter, där högre utgiftsnivåer ger tillgång till högre gränser för förfrågningar per minut, token per minut och förfrågningar per dag. Enligt Googles egen dokumentation finns bland annat en Tier 2-nivå som kräver 50 dollar i ackumulerad fakturering och en Tier 3-nivå som kräver 200 dollar, där varje nivå låser upp högre takgränser. För en agent i tidig utvecklingsfas räcker gratisnivån oftast gott, men planerar du en lansering med många samtidiga användare bör du redan nu räkna på vilken tier din förväntade trafik landar i, så att du inte blir kvotbegränsad första dagen i produktion.
| Nivå | Krav för att låsa upp | Typisk användning |
|---|---|---|
| Gratisnivå | Inget betalkort krävs | Utveckling, prototyper, utvärdering av en agentidé |
| Tier 1 | Betalkort kopplat till projektet | Små produktionsapplikationer med måttlig trafik |
| Tier 2 | 50 dollar i ackumulerad fakturering | Växande applikationer med stadigt ökande anropsvolym |
| Tier 3 | 200 dollar i ackumulerad fakturering | Produktionsagenter med hög och förutsägbar trafik |
Ett praktiskt mönster som lyfts fram i flera produktionsguider för Gemini API är att sätta upp en projektbaserad hastighetsbegränsare tillsammans med en semantisk cache framför modellen, kombinerat med en gräns för hur många samtidiga anrop din applikation gör. Det håller kostnaden förutsägbar samtidigt som du undviker att träffa 429-fel vid trafiktoppar. Övervaka gärna kvotanvändningen kontinuerligt istället för att bara reagera när ett 429-fel redan inträffat, då hinner du höja tier eller strypa trafik innan användarna märker något.
Multimodal input: skicka bilder till agenten
En av styrkorna med Gemini-modellerna är att samma API hanterar text, bilder, ljud och video utan separata endpoints. Det gör det enkelt att bygga en agent som till exempel läser av en kvittobild och sedan använder ett verktyg för att bokföra beloppet. Så skickar du en lokal bildfil tillsammans med en textfråga:
from google.genai import types
with open("kvitto.jpg", "rb") as f:
bilddata = f.read()
response = client.models.generate_content(
model="gemini-3.8-flash",
contents=[
types.Part.from_bytes(data=bilddata, mime_type="image/jpeg"),
"Vad är totalbeloppet på det här kvittot, och vilken butik gäller det?",
],
config=types.GenerateContentConfig(
tools=[hamta_vader, berakna_restid],
),
)
print(response.text)
Kombinerar du bildläsning med ett bokföringsverktyg (en egen funktion som sparar beloppet i en databas) har du grunden till en enkel kvittoagent på under trettio rader kod. Samma mönster fungerar för ljudfiler och video, med skillnaden att du anger rätt mime_type för respektive filtyp. Tänk på att större filer ökar antalet indata-token markant, en bild räknas i praktiken som flera hundra till några tusen token beroende på upplösning, vilket direkt påverkar kostnaden per anrop. Vill du istället bygga en agent som hämtar och resonerar kring information från flera dokument samtidigt, ligger tillvägagångssättet nära det vi beskriver i vår guide till att bygga en RAG-agent med LangChain, fast med Gemini som underliggande modell istället.
Så bygger du vidare: minne och flerstegskonversationer
Exemplen ovan hanterar en fråga i taget. En riktig agent behöver oftast komma ihåg tidigare delar av konversationen. Det enklaste sättet är att använda SDK:ns inbyggda chattfunktion istället för generate_content direkt:
chatt = client.chats.create(
model="gemini-3.8-flash",
config=types.GenerateContentConfig(tools=[hamta_vader, berakna_restid]),
)
svar1 = chatt.send_message("Hur är vädret i Göteborg?")
print(svar1.text)
svar2 = chatt.send_message("Och hur långt är det dit från Stockholm?")
print(svar2.text)
Chattobjektet håller reda på historiken åt dig, så den andra frågan förstår att "dit" syftar på Göteborg utan att du behöver skicka med det manuellt. För längre konversationer, eller om du vill spara historik mellan omstarter av applikationen, behöver du själv serialisera och lagra meddelandehistoriken, till exempel i en databas kopplad till användarens session.
Testa agenten automatiskt med pytest
En agent som bara testas manuellt i terminalen går sönder tyst när du ändrar en prompt eller lägger till ett nytt verktyg. Bygg därför in automatiska tester tidigt, både för verktygsfunktionerna själva och för att agenten faktiskt väljer rätt verktyg givet en given fråga. Verktygsfunktionerna är vanliga Python-funktioner, så de testas precis som all annan kod:
import pytest
from agent import hamta_vader, berakna_restid
def test_hamta_vader_kand_stad():
resultat = hamta_vader("Malmö")
assert resultat["temp"] == 17
assert resultat["beskrivning"] == "sol"
def test_hamta_vader_okand_stad():
resultat = hamta_vader("Uppsala")
assert resultat["temp"] is None
def test_berakna_restid_finns():
resultat = berakna_restid("Stockholm", "Malmö")
assert resultat["minuter"] == 360
assert resultat["km"] == 615
Den svårare delen är att testa att modellen faktiskt anropar rätt verktyg för en given fråga, eftersom det innebär ett riktigt API-anrop och därmed både kostnad och viss variation i svaret. Ett vanligt mönster är att skriva ett litet antal integrationstester som körs mer sällan (till exempel en gång per pull request, inte vid varje sparad rad kod) och som kontrollerar att modellen anropar förväntat verktyg, snarare än att asserta på den exakta ordalydelsen i svaret:
def test_agent_anropar_vaderverktyg():
svar = kor_agent("Vad är det för väder i Malmö?")
# Kontrollera att svaret innehåller väderdata, inte den exakta formuleringen
assert "17" in svar or "sol" in svar.lower()
Håll integrationstesterna få och riktade. Fem till tio väl valda scenarier som täcker varje verktyg och några vanliga flerverktygsfrågor räcker långt, och håller både testkörningstid och API-kostnad rimlig jämfört med att försöka testa varje tänkbar formulering en användare kan skriva.
Säkerhet: skydda agenten mot prompt injection och missbruk
En agent som har tillgång till verktyg är också en större attackyta än en vanlig chattbot. Om en användare (eller innehåll agenten läser från en extern källa, till exempel en webbsida via URL Context-verktyget) kan lura modellen att anropa ett verktyg på fel sätt, kan konsekvenserna bli allvarligare än ett pinsamt textsvar. Behandla varje verktyg som en potentiell attackväg och applicera samma försiktighet som du skulle göra för en publik API-endpoint.
Konkret innebär det att verktyg med skrivrättigheter (skicka e-post, göra en betalning, radera en post) alltid bör ha ett extra bekräftelsesteg innan de faktiskt exekverar, att indata till varje verktyg valideras precis som vilken användarindata som helst, och att du aldrig låter agenten själv avgöra om en känslig åtgärd ska godkännas utan ett kodat regelverk runt den. Vill du gå djupare in på hur den här typen av attacker fungerar och hur man skyddar sig mot dem finns grunderna beskrivna i vår guide om att stoppa prompt injection i en LLM-baserad API, principerna är desamma oavsett vilken modellleverantör du använder.
Komplett projektstruktur att utgå från
Sätter du ihop alla delar från den här guiden till ett riktigt projekt istället för lösa filer, är en rimlig mappstruktur att utgå från följande. Den skiljer på verktygsdefinitioner, agentlogik och tester, vilket gör det enkelt att lägga till fler verktyg senare utan att röra kärnlogiken.
gemini-agent/
├── .env # GEMINI_API_KEY, aldrig incheckad i git
├── .gitignore # innehåller .env och venv/
├── requirements.txt # google-genai, python-dotenv, pydantic, pytest
├── tools.py # hamta_vader, berakna_restid, m.fl. verktygsfunktioner
├── agent.py # kor_agent() med felhantering och kostnadsloggning
├── main.py # startpunkt, kör agent.py interaktivt eller som CLI
└── tests/
├── test_tools.py # enhetstester för varje verktygsfunktion
└── test_agent.py # ett fåtal integrationstester mot riktiga API-anrop
Filen requirements.txt bör peka på specifika versioner snarare än att bara ange paketnamnen, av samma anledning som du bör pinna modell-id:t: du vill styra exakt när en uppgradering sker, inte råka få en brytande ändring vid nästa pip install. Ett minimalt exempel:
google-genai>=1.0.0
python-dotenv>=1.0.0
pydantic>=2.0.0
pytest>=8.0.0
Med den här strukturen på plats har du något du faktiskt kan bygga vidare på: lägg till fler verktyg i tools.py när agenten ska klara fler uppgifter, utöka agent.py med minne och streaming när gränssnittet kräver det, och låt testsviten i tests/ växa i takt med att antalet verktyg gör det. Det är samma grundstruktur som beskrivs i flera produktionsguider för Gemini API, bara skalad ner till en storlek som är rimlig att börja med. Vill du jämföra hur samma agentmönster ser ut med andra modellleverantörer finns motsvarande genomgångar i vår guide om att bygga en AI-agent med MCP och Kimi K3 och i guiden om att bygga en agent med DeepSeek V4-Flash API. Fler artiklar om AI-modeller, lansering och verktyg hittar du i vår samlingssektion om AI och maskininlärning.
Vanliga frågor om Gemini API och function calling
Är Gemini API gratis att använda?
Ja, Google erbjuder en gratisnivå för utveckling och test med lägre kvotgränser. Vill du köra i produktion med högre volym behöver du koppla ett betalkort och gå upp i kvottier, vilket ger högre gränser för förfrågningar per minut och per dag.
Vilken Python-SDK ska jag använda, google-genai eller google-generativeai?
Använd google-genai. Det är det aktuella officiella paketet som Google utvecklar aktivt, medan det äldre google-generativeai i huvudsak underhålls för bakåtkompatibilitet med äldre kod.
Kan jag använda flera verktyg samtidigt i samma agent?
Ja, du skickar in en lista av funktioner i tools-parametern, och modellen väljer själv vilket eller vilka verktyg som behövs för att besvara en given fråga, inklusive att kombinera flera verktyg i samma svar.
Vad händer om modellen anropar fel verktyg?
Det är oftast ett tecken på otydlig dokumentation i din funktions docstring eller parameternamn. Skriv om beskrivningen tydligare och lägg gärna till konkreta exempel på när verktyget ska respektive inte ska användas.
Hur stort är kontextfönstret i Gemini 3.8 Flash?
Modellen har ett kontextfönster på 1 miljon token och stöder upp till 64 000 utdatatoken per svar, enligt Googles officiella modelldokumentation.
Behöver jag ett Google Cloud-projekt för att komma igång?
Nej, för utveckling räcker en nyckel skapad direkt i Google AI Studio. Ett kopplat Google Cloud-projekt blir mer relevant när du vill separera miljöer och få tillgång till högre kvoter i produktion.
Skiljer sig priset mellan Gemini 3.7 Flash och 3.8 Flash?
Nej, enligt Googles prisdokumentation ligger båda modellerna på samma introduktionspris, 0,75 dollar per miljon indata-token och 3,75 dollar per miljon utdata-token, gällande till den 31 december 2026.
Är det säkert att låta en agent skriva till en produktionsdatabas direkt?
Bara om du har byggt in ett explicit valideringssteg mellan modellens beslut och den faktiska skrivoperationen. Att låta en språkmodell utföra kritiska skrivoperationer helt utan mänsklig eller kodbaserad kontroll är en känd riskkälla i agentarkitekturer.




