guides

Pydantic AI: Produksjonsguiden (Hinsides Hello World)

Skrevet av Mert Batur
Apr 1, 2026
9 lesing
Pydantic AI: Produksjonsguiden (Hinsides Hello World)

Pydantic AI: Produksjonsguiden (Hinsides Hello World)

Rå LLM-utdata ødelegger applikasjoner. Du ber om JSON, du får markdown. Du ber om et tall mellom 1 og 10, du får "Visst! Her er et tall: syv." Hvis du har bygget noe reelt med LLM-API-er, har du skrevet defensiv parsekode som får deg til å stille spørsmål ved dine karrierevalg. Pydantic AI fikser dette -- det er det typesikre agent-rammeverket bygget av det samme teamet bak Pydantic og FastAPI. Tenk på det som "FastAPI for AI-agenter": du definerer hva du vil ha med Python-typeantydninger, og rammeverket håndterer validering, nye forsøk og verktøyanrop.

Denne Pydantic AI-guiden er for utviklere som allerede har gjort sitt første LLM-anrop og ønsker produksjonsmønstre: strukturerte utdata som ikke går i stykker, dependency injection for testbare agenter og virkelige verktøy utover værhentings-API-er. På slutten har du fungerende agenter med verktøy, DI, strømming og tester.

<!-- IMAGE: Pydantic AI-agentarkitektur -- Agent mottar prompt, kaller verktøy via RunContext, validerer utdata gjennom Pydantic-modellen -->

Pydantic AI i Korthet

AttributtDetaljer
Hva det erTypesikkert AI-agent-rammeverk for Python
Bygget avPydantic-teamet (Samuel Colvin mfl.)
Filosofi"FastAPI for AI-agenter" -- typeantydninger driver alt
LisensMIT (åpen kildekode)
Gjeldende Versjonv1.74.0 (Mars 2026)
Python-versjon3.9+
Støttede ModellerOpenAI, Anthropic, Google Gemini, Groq, Mistral, Ollama og mer
NøkkelfunksjonerStrukturerte utdata, verktøyanrop, dependency injection, strømming, TestModel
GitHub-stjerner16 000+
ProduksjonsklarJa -- v1.0 utgitt september 2025
ObserverbarhetInnebygd Logfire-integrasjon (OpenTelemetry-basert)
LæringskurveLav om du kjenner Pydantic/FastAPI; moderat ellers

De fremtredende funksjonene er strukturerte utdata (validert med Pydantic-modeller), dependency injection (som FastAPI:s Depends) og TestModel (mock-LLM for testing uten API-anrop). Hvis du kommer fra LangChain og lurer på "finnes det noe renere?", er dette sannsynligvis svaret.

Installasjon og Første Agent

bash
# Installer med OpenAI-støtte (bytt ut openai med anthropic, google osv.)
pip install "pydantic-ai[openai]"

# Sett din API-nøkkel
export OPENAI_API_KEY="sk-..."

Din første agent på 5 linjer:

python
from pydantic_ai import Agent

agent = Agent("openai:gpt-4o", system_prompt="You are a helpful assistant.")

result = agent.run_sync("What's the capital of France?")
print(result.output)  # "Paris"

Det er det. Agent omslutter modellen, run_sync sender en prompt og returnerer et resultat. result.output er en vanlig streng her, men det er i ferd med å endre seg.

Strukturerte Utdata -- Hvorfor Pydantic AI Eksisterer

Dette er kjernefunksjonaliteten. I stedet for å få en streng tilbake fra LLM-en og håpe at den er gyldig JSON, definerer du en Pydantic-modell og agenten returnerer et validert Python-objekt.

Før: Rå LLM-utdata

python
# Den gamle måten -- håp på det beste
from openai import OpenAI

client = OpenAI()
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Review the movie Inception. Return JSON with title, rating (1-10), summary."}]
)
# response.choices[0].message.content er en streng
# Kanskje er det JSON. Kanskje har det markdown-kodegjerde. Kanskje er rating "eight".
# Du er på egenhånd.

Etter: Strukturert med Pydantic AI

python
from pydantic import BaseModel
from pydantic_ai import Agent

class MovieReview(BaseModel):
    title: str
    rating: int  # Garantert å være et int, ikke "eight"
    summary: str
    recommended: bool

agent = Agent("openai:gpt-4o", result_type=MovieReview)

result = agent.run_sync("Review the movie Inception")
review = result.output  # Dette er en MovieReview-instans, ikke en streng

print(f"{review.title}: {review.rating}/10")
print(f"Anbefalt: {review.recommended}")
print(review.summary)

Forskjellen er som natt og dag. result.output er et ekte MovieReview-objekt. Hvis LLM-en returnerer rating: "eight" i stedet for rating: 8, fanger Pydantics validering det. For et dypere blikk på hvordan dette fungerer på tvers av forskjellige leverandører, se vår guide om strukturerte utdata på tvers av LLM-leverandører.

Hva Skjer Når Validering Feiler

Her er delen ingen andre opplæringsprogrammer viser: hva skjer når LLM-en gjør feil?

python
from pydantic import BaseModel, Field
from pydantic_ai import Agent

class StrictReview(BaseModel):
    title: str
    rating: int = Field(ge=1, le=10)  # Må være 1-10
    pros: list[str] = Field(min_length=2)  # Minst 2 fordeler

agent = Agent("openai:gpt-4o", result_type=StrictReview)

# Hvis LLM-en returnerer rating=15 eller bare 1 fordel:
# 1. Pydantic-validering feiler
# 2. Feilmeldingen sendes TILBAKE til LLM-en
# 3. LLM-en prøver igjen med korrigert utdata
# 4. Dette gjentas opp til grensen for nye forsøk
result = agent.run_sync("Review the movie Inception")

Denne sløyfen for nye forsøk med tilbakemelding er Pydantic AI:s killerfunksjon. LLM-en lærer av sine egne valideringsfeil. Du skriver ingen logikk for nye forsøk -- rammeverket håndterer det.

Verdict: Strukturerte utdata er den beste enkeltgrunnen til å bruke Pydantic AI fremfor rå API-anrop. Hvis du parser LLM-JSON for hånd, stopp det.

Verktøy og Funksjonanrop

Verktøy lar agenten din kalle Python-funksjoner for å hente virkelige data. I stedet for at LLM-en hallusinerer fakta, kan den spørre databasen din, søke i dokumentene dine eller kalle et API.

Registrere et Verktøy

python
from pydantic_ai import Agent

agent = Agent("openai:gpt-4o")

@agent.tool
async def search_docs(query: str) -> str:
    """Search the documentation for relevant articles."""
    # Din faktiske søkelogikk her
    results = await doc_search_engine.search(query, limit=5)
    return "\n".join(r.title + ": " + r.snippet for r in results)

Dekoratoren @agent.tool registrerer funksjonen. Pydantic AI leser funksjonens typeantydninger og docstring for å fortelle LLM-en hva verktøyet gjør, hvilke argumenter det tar og hva det returnerer. Ingen manuell skjemaskriving -- dine typeantydninger ER skjemaet. For bakgrunn om hvordan LLM-funksjonanrop fungerer under panseret har vi en dedikert guide.

RunContext: Sende Data til Verktøy

Her avviker Pydantic AI fra andre rammeverk. RunContext lar deg sende kjøretidsdata (databasetilkoblinger, brukerinfo, API-klienter) til verktøyene dine uten global tilstand.

python
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext

@dataclass
class SupportDeps:
    customer_id: str
    db_connection: DatabaseConnection

agent = Agent("openai:gpt-4o", deps_type=SupportDeps)

@agent.tool
async def get_order_history(ctx: RunContext[SupportDeps], limit: int = 5) -> str:
    """Fetch recent orders for the current customer."""
    orders = await ctx.deps.db_connection.query(
        "SELECT * FROM orders WHERE customer_id = $1 ORDER BY date DESC LIMIT $2",
        ctx.deps.customer_id, limit
    )
    return format_orders(orders)

ctx.deps gir verktøyet tilgang til alt du sendte ved kjøretid. Verktøyet importerer ikke en global databasetilkobling -- det mottar en. Dette er dependency injection, og det er det som gjør agentene dine testbare.

Et Virkelig Verktøyeksempel

python
@agent.tool
async def run_sql_query(ctx: RunContext[SupportDeps], sql: str) -> str:
    """Run a read-only SQL query against the analytics database.
    Only SELECT queries are allowed."""
    if not sql.strip().upper().startswith("SELECT"):
        return "Error: only SELECT queries are allowed"
    results = await ctx.deps.db_connection.fetch(sql)
    return json.dumps(results, default=str)

Verdict: Verktøyanrop i Pydantic AI er renere enn ethvert annet rammeverk takket være at typeantydninger gjør det tunge arbeidet. Du skriver normale Python-funksjoner med typeantydninger. Rammeverket finner ut resten.

Dependency Injection -- Funksjonen LangChain Ønsker å Ha

Hvis du har brukt FastAPI:s Depends, forstår du allerede Pydantic AI:s DI-system. Hvis du ikke har det, her er kortversjonen: i stedet for at agenten din rekker ut etter det den trenger (globale databasetilkoblinger, API-klienter, konfigurasjon), gir du den alt ved kjøretid.

Definere Avhengigheter

python
from dataclasses import dataclass
from pydantic_ai import Agent

@dataclass
class AppDeps:
    db: AsyncDatabasePool
    search_client: SearchAPIClient
    current_user: User

agent = Agent(
    "openai:gpt-4o",
    deps_type=AppDeps,
    system_prompt="You are a customer support agent."
)

Bruke Avhengigheter i Verktøy

python
@agent.tool
async def lookup_account(ctx: RunContext[AppDeps]) -> str:
    """Look up the current user's account details."""
    account = await ctx.deps.db.fetchrow(
        "SELECT * FROM accounts WHERE user_id = $1",
        ctx.deps.current_user.id
    )
    return json.dumps(account, default=str)

# Kjør med virkelige avhengigheter
result = await agent.run(
    "What's my account status?",
    deps=AppDeps(db=real_db, search_client=real_search, current_user=user)
)

Hvorfor DI Gjør Agentene Dine Testbare

Dette er den virkelige gevinsten. I LangChain ville du sende kontekst via chain kwargs eller closures -- det finnes intet standardmønster. I Pydantic AI er det trivielt å bytte ut virkelige avhengigheter med testdouble:

python
# I testfilen din
from pydantic_ai import Agent
from your_app import agent, AppDeps

async def test_account_lookup():
    mock_deps = AppDeps(
        db=MockDatabase({"user_123": {"status": "active", "plan": "pro"}}),
        search_client=MockSearch(),
        current_user=User(id="user_123")
    )
    result = await agent.run("What's my account status?", deps=mock_deps)
    assert "active" in result.output
    assert "pro" in result.output

Ingen monkey-patching. Ingen mocking av globale importer. Du sender bare forskjellige deps.

Verdict: Dependency injection er hvorfor erfarne Python-utviklere foretrekker Pydantic AI. Det er FastAPI-innflytelsen som vises.

Modellleverandører -- OpenAI, Anthropic, Gemini, Ollama

Pydantic AI er modellagnostisk. Å bytte leverandør er en endring på én linje:

python
# OpenAI
agent = Agent("openai:gpt-4o")

# Anthropic
agent = Agent("anthropic:claude-sonnet-4-20250514")

# Google Gemini
agent = Agent("google-gla:gemini-2.0-flash")

# Lokal Ollama
agent = Agent("ollama:llama3.1")

Alt annet -- verktøy, strukturerte utdata, DI -- forblir identisk. Din forretningslogikk endres ikke når du bytter modell.

LeverandørModellerGratisnivåInstallasjonskompleksitet
OpenAIGPT-4o, GPT-4o mini, o1$5 kreditt (nye kontoer)Lav -- bare API-nøkkel
AnthropicClaude Sonnet, Haiku, OpusIngen gratisnivåLav -- bare API-nøkkel
Google GeminiGemini 2.0 Flash, ProSjenerøst gratisnivåMedium -- prosjektoppsett
GroqLlama, MixtralGratisnivå tilgjengeligLav -- bare API-nøkkel
Ollama (lokal)Llama, Mistral, Phi osv.Helt gratisMedium -- installer Ollama

Verdict: Modellagnostisk design betyr at du aldri er låst til én leverandør. Start med OpenAI for bekvemmelighet, benchmark med Anthropic og bruk Ollama for lokal utvikling.

Strømmingssvar

For chat-UI-er og sanntidsapplikasjoner er strømming viktig. Pydantic AI støtter det mens den opprettholder typesikkerhet:

python
from pydantic_ai import Agent
from pydantic import BaseModel

class AnalysisResult(BaseModel):
    summary: str
    sentiment: str
    confidence: float

agent = Agent("openai:gpt-4o", result_type=AnalysisResult)

async def stream_analysis(text: str):
    async with agent.run_stream(f"Analyze this text: {text}") as stream:
        async for partial in stream.stream_structured():
            # partial er et delvis validert AnalysisResult
            print(f"Strømming: {partial}")

        # Sluttresultatet er fullt validert
        result = await stream.get_output()
        print(f"Endelig: {result.summary} ({result.confidence:.0%} sikkerhet)")

Dette fungerer perfekt med FastAPI:s StreamingResponse -- samme økosystem, samme mønstre. Pydantic AI-agentdokumentasjonen dekker avanserte strømmingsalternativer inkludert kun-tekst-strømming med stream_text().

Pydantic AI vs LangGraph vs OpenAI Agents SDK

Du er her, så du spør sannsynligvis: "bør jeg bruke Pydantic AI eller LangGraph?" Ærlig svar: de løser forskjellige problemer, og du kan bruke begge.

Sammenligningstabell over Funksjoner

FunksjonPydantic AILangGraphOpenAI Agents SDK
TypesikkerhetFull (Pydantic-modeller)Delvis (TypedDict)Minimal
Dependency InjectionInnebygd (FastAPI-stil)IngenIngen
Strukturerte UtdataNative med nye forsøkVia utdataanalysatorerVia JSON-modus
Verktøyanrop@agent.tool-dekorator@tool-dekoratorfunksjonsdefinisoner
Multi-AgentGrunnleggende handoffsAvansert (tilstandsmaskiner)Handoffs + skyddsrekker
StrømmingTypet strømmingStrømmingshendelserStrømming
Modellstøtte10+ leverandørerPrimært LangChain-modellerBare OpenAI
TestingTestModel innebygdIngen innebygd testingIngen innebygd testing
LæringskurveLav (hvis du kjenner Pydantic)Høy (grafkonsepter)Lav (enkelt API)
CommunitystørrelseVoksende (16K stjerner)Stor (LangChain-økosystem)Voksende (OpenAI-støtte)
Best forRene, testbare agenterKomplekse tilstandsflyterProsjekter med bare OpenAI

Når du Skal Bruke Hvert

Velg Pydantic AI når du vil ha ren, typesikker agentkode. Det er ideelt for enkelt-agenthoppgaver med verktøy (kundesupportbotter, datautvinning, kodegjennomgangsagenter) og situasjoner der testbarhet spiller en rolle. Hvis teamet ditt allerede bruker FastAPI og Pydantic, er læringskurven nesten flat.

Velg LangGraph når du trenger komplekse flertrinnsflyters med betinget forgrening, menneskelig godkjenning i løkken og sofistikert tilstandshåndtering. LangGraph utmerker seg ved å orkestrere flere trinn, ikke individuell agentkvalitet. For en dypere gjennomgang, se vår fullstendige LangGraph vs CrewAI vs OpenAI Agents SDK-sammenligning.

Velg OpenAI Agents SDK når du er 100% på OpenAI, vil ha det enkleste mulige oppsettet og ikke trenger støtte for flere leverandører eller DI.

Kombinasjonsmønsteret

Her er hva erfarne team faktisk gjør: bruker Pydantic AI for individuelle agenter (ren kode, testbar, typede utdata) og LangGraph for orkestrering mellom agenter (ruting, tilstandsmaskiner, betinget logikk). De konkurrerer ikke -- de er komplementære lag.

python
# Pydantic AI-agent -- ren, testbar, typesikker
support_agent = Agent("openai:gpt-4o", result_type=SupportResponse, deps_type=SupportDeps)

# LangGraph-graf -- orkestrerer når du skal kalle hvilken agent
graph = StateGraph(SupportState)
graph.add_node("classify", classify_intent)
graph.add_node("support", lambda state: support_agent.run_sync(state["query"]))
graph.add_node("escalate", escalate_to_human)

Verdict: Velg Pydantic AI for ren, testbar agentkode. Velg LangGraph for komplekse flertrinnsflyter. De utelukker ikke hverandre.

Teste Agentene Dine med TestModel

Dette er avsnittet som skiller en nybegynnerguide fra en produksjonsguide. Enhver ekte kodebase trenger tester, og å teste agenter er notorisk vanskelig -- LLM-anrop er trege, dyre og ikke-deterministiske. Pydantic AI leverer en løsning: TestModel.

python
from pydantic_ai import Agent
from pydantic_ai.models.test import TestModel
from pydantic import BaseModel

class SupportResponse(BaseModel):
    answer: str
    confidence: float
    escalate: bool

agent = Agent("openai:gpt-4o", result_type=SupportResponse)

# I tester: bytt ut den virkelige modellen med TestModel
def test_support_agent():
    with agent.override(model=TestModel()):
        result = agent.run_sync("I need help with billing")
        # TestModel returnerer gyldige strukturerte data som samsvarer med din result_type
        assert isinstance(result.output, SupportResponse)
        assert isinstance(result.output.confidence, float)
        assert isinstance(result.output.escalate, bool)

TestModel genererer gyldige data som samsvarer med din result_type uten å gjøre noen API-anrop. Null kostnad, deterministisk, rask. Pydantic AI-testingsdokumentasjonen dekker avanserte mønstre som FunctionModel for tilpassede svar og capture_run_messages for å inspisere verktøyanrop.

Teste Verktøy og DI Sammen

python
def test_order_lookup_tool():
    # Mock-avhengigheter
    mock_deps = SupportDeps(
        customer_id="test-123",
        db_connection=MockDB(orders=[{"id": "ord-1", "status": "shipped"}])
    )

    with agent.override(model=TestModel()):
        result = agent.run_sync(
            "Where is my order?",
            deps=mock_deps
        )
        assert isinstance(result.output, SupportResponse)

Ingen API-anrop. Ingen ustabile tester. Ingen kostnad. Kjør dette i CI/CD ved siden av resten av testsuiten din.

Dette er innhullsgapet nr. 1 på hele SERP-en. Ingen annen Pydantic AI-guide dekker testing. Hvis du bygger agenter for produksjon, er dette det du trenger.

Observerbarhet -- Logfire-integrasjon på 5 Minutter

Produksjonsagenter trenger AI-observerbarhet. Du vil se hvert LLM-anrop, verktøyanrop, latens, tokenantall og kostnad. Pydantic AI integreres nativt med Logfire, Pydantic-teamets observerbarhetsplattform (bygget på OpenTelemetry).

python
import logfire
from pydantic_ai import Agent

logfire.configure()  # Bruker LOGFIRE_TOKEN-miljøvariabelen
logfire.instrument_pydantic_ai()

agent = Agent("openai:gpt-4o", result_type=MovieReview)
# Hvert kjøring er nå sporet automatisk
result = agent.run_sync("Review Inception")

Tre linjer. Du får fullstendige spor som viser: sendt prompt, modellsvar, verktøyanrop (hvis noen), valideringspass/-feil, nye forsøk, latens og estimert kostnad. Hvis Logfire ikke passer for deg, er Langfuse et solid alternativ med åpen kildekode med støtte for kontekstingeniørarbeid for å spore hvordan promptene dine utvikler seg.

Ofte Stilte Spørsmål

Hva er Pydantic AI og hvordan skiller det seg fra LangChain?

Pydantic AI er et typesikkert agent-rammeverk der Python-typeantydninger driver validering, verktøyskjemaer og dependency injection. LangChain er et større rammeverk fokusert på å kjede LLM-anrop. Nøkkelforskjellen: Pydantic AI validerer utdata på rammeverknivå og gir innebygd dependency injection for testbarhet -- LangChain gjør ingen av delene som standard.

Hvordan bygger jeg en typesikker AI-agent med Pydantic AI?

Definer en Pydantic BaseModel for utdataene dine, send den som result_type til Agent og kall run_sync() eller run(). Agenten returnerer en validert instans av modellen din, ikke en rå streng. Se avsnittet Strukturerte Utdata for fullstendige eksempler.

Bør jeg bruke Pydantic AI eller LangGraph for produksjonsagenter?

Bruk Pydantic AI for individuelle agenter der typesikkerhet, testbarhet og ren kode spiller en rolle. Bruk LangGraph for å orkestrere komplekse flertrinnsflyters med betinget ruting. Mange team bruker begge -- Pydantic AI-agenter inni et LangGraph-orkestreringslag.

Hvordan håndterer Pydantic AI verktøyanrop og dependency injection?

Dekorer en funksjon med @agent.tool og Pydantic AI leser dens typeantydninger for å generere verktøyets skjema. For DI, sett deps_typeAgent og aksepter RunContext[YourDeps] i verktøy. Kjøretidsavhengigheter (DB-tilkoblinger, API-klienter) flyter uten global tilstand.

Hvordan legger jeg til strømming i en Pydantic AI-agent?

Bruk agent.run_stream() i stedet for agent.run(). Det returnerer en asynkron kontekstbehandler som produserer delvise resultater via stream_structured() eller stream_text(). Sluttresultatet er fortsatt fullt validert mot din result_type.

Er Pydantic AI produksjonsklar i 2026?

Ja. Versjon 1.0 ble utgitt i september 2025 med et API-stabilitetsløfte. Det støttes av Pydantic-teamet (det mest nedlastede Python-biblioteket for datavalidering) og er for øyeblikket på v1.74.0 med jevnlige oppdateringer.

Kan jeg bruke Pydantic AI med Ollama og lokale modeller?

Ja. Bruk Agent("ollama:llama3.1") og sørg for at Ollama kjører lokalt. Installer ollama-leverandørtillegget: pip install "pydantic-ai[ollama]". Strukturerte utdata og verktøy fungerer på samme måte som med skyleverandører.

Hvordan tester jeg Pydantic AI-agenter?

Bruk TestModel -- en mock-modell som genererer gyldige strukturerte data som samsvarer med din result_type uten API-anrop. Omslut testen din i agent.override(model=TestModel()) og kjør assertions på utdata. Se avsnittet Testing for fullstendige pytest-eksempler.

Fungerer Pydantic AI med FastAPI?

Perfekt. De deler samme filosofi om dependency injection og er bygget av det samme teamet. Du kan bruke Pydantic AI-agenter inni FastAPI-endepunkter, dele avhengighetstyper mellom dem og strømme agentsvar gjennom StreamingResponse.

Hva er forskjellen mellom Pydantic AI og OpenAI Agents SDK?

Pydantic AI er modellagnostisk (fungerer med OpenAI, Anthropic, Gemini, Ollama osv.), har dependency injection, TestModel for testing og Pydantic-validering. OpenAI Agents SDK er enklere men låst til OpenAI-modeller og mangler DI og innebygd testing. Velg Pydantic AI for fleksibilitet; velg OpenAI Agents SDK for det enkleste mulige kun-OpenAI-oppsettet.

Nøkkellærdommer og Neste Steg

KonseptNøkkelinnsiktNeste Steg
Strukturerte UtdataDin result_type valideres og gjenprøves automatiskDefiner Pydantic-modeller for alle agentutdata
VerktøyTypeantydninger ER skjemaet -- ingen manuelle definisjonerBygg verktøy med @agent.tool og RunContext
Dependency InjectionSend kjøretidsavhengigheter eksplisitt for testbarhetDefiner en deps_type-dataclass for hver agent
TestingTestModel eliminerer API-kostnader i CI/CDLegg til agent.override(model=TestModel()) i testsuiten din
ModellleverandørerModellbytte på én linje, ingen kodeendringerStart med OpenAI, benchmark alternativer senere
Observerbarhet3-linjers Logfire-oppsett for fullstendige sporLegg til logfire.instrument_pydantic_ai() i produksjon

Start med en liten agent som har strukturerte utdata. Legg til et verktøy. Legg til avhengigheter. Skriv en test med TestModel. Det er produksjonsveien -- og nå har du alt du trenger for å gå den.

Den offisielle Pydantic AI-dokumentasjonen og GitHub-repositoriet er utmerkede for å gå dypere. Rammeverket beveger seg raskt, så bokmerke endringsloggen.

Kilder

Emneord

pydantic aiai-agenterstrukturerte utdatadependency injectiontypesikre agenterpythonllm-rammeverk

Del denne artikkelen

Kom i gang

Klar til å bygge noe ekstraordinært?

La oss gjøre visjonen din til virkelighet. Teamet vårt er klart til å hjelpe deg med å lage programvare som utgjør en forskjell.