Gå til indhold
Jan Engelbrecht Pederseb Logo

AI Agenter i PHP og Python

Fra LLM-kommunikation og streaming-interfaces til avancerede RAG-systemer og funktionskald. Byg robuste AI-assistenter i både PHP og Python.

AI Agenter i PHP og Python

Fra LLM-kommunikation og streaming-interfaces til avancerede RAG-systemer og funktionskald. Byg robuste AI-assistenter i både PHP og Python.

Uanset om du foretrækker Python eller PHP, kræver en effektiv AI-agent en solid forståelse for LLM-kommunikation, brugergrænseflader og integration af eksterne værktøjer. Her får du opskriften på at bygge fremtidens assistenter.

Sådan kommunikeres der med LLM-API'er

For at bygge en AI-agent i Python er det første skridt at forstå, hvordan man taler med en stor sprogmodel (LLM). Det handler grundlæggende om at sende en struktureret anmodning til en fjernserver og modtage et svar, men måden kommunikationen foregår på – og hvilke protokoller der bruges – har stor betydning for, hvor responsiv og anvendelig din agent bliver.

Når du kalder en LLM-API, foregår det i praksis som et HTTP-kald. Du sender en POST-anmodning til udbyderens endpoint (for eksempel OpenAI eller Anthropic) med en JSON-payload, der indeholder dine beskeder, modelnavnet og eventuelle parametre som temperatur eller maksimalt antal tokens. Serveren behandler din anmodning og returnerer et svar, typisk også i JSON-format.

I Python findes der flere måder at håndtere denne kommunikation på. Du kan bruge et lav-niveau bibliotek som httpx til selv at bygge anmodningerne, eller du kan vælge et høj-niveau bibliotek som uss-aigent, der abstraherer det meste. Med sidstnævnte kan et kald se så enkelt ud som:

from aigent import Aigent

agent = Aigent(api_type="openai")
with agent.session() as s:
    print(s.chat("Hej!"))

Biblioteket læser automatisk din API-nøgle fra en miljøvariabel og håndterer opsætningen af forbindelsen. Uanset om du vælger en letvægtsløsning eller et mere fuldt udbygget framework, er det centrale princip det samme: Din Python-kode fungerer som mellemled mellem brugeren og LLM'en, og det er her, du har kontrol over, hvilke data der sendes afsted, og hvordan svaret behandles.

Kommunikationsprotokoller

  • Standard HTTP (request/response): Den enkleste og mest udbredte protokol. Din agent sender en anmodning og venter på, at hele svaret er genereret, før det returneres. Velegnet til korte svar eller når du har brug for et struktureret output, men det kan føles langsomt.
  • Server-Sent Events (SSE): En streamingprotokol bygget oven på HTTP. Serveren holder forbindelsen åben og sender løbende små bidder af svaret (tokens), efterhånden som de genereres. Giver en markant lavere oplevet ventetid, fordi brugeren ser første token næsten med det samme. Kan implementeres med sse-starlette.
  • WebSocket: Fuld duplex-kommunikation, hvor både klient og server kan sende beskeder uafhængigt. Relevant for interaktive agenter eller hvor agenten skal kunne udføre værktøjskald i realtid. For simple chat-agenter er SSE dog ofte tilstrækkeligt.

Fælles for alle protokollerne er, at de understøtter den såkaldte function calling eller tool use. Det betyder, at LLM'en ikke bare genererer tekst, men også returnerer en anmodning om at kalde en bestemt funktion i din kode – fx for at hente vejrdata. Din agent udfører funktionen, sender resultatet tilbage, og LLM'en formulerer det endelige svar.

Byg en AI-agent i PHP: Kommunikation med LLM-API'er

PHP er stadig en af de mest udbredte sprog til webapplikationer, og med de rette værktøjer kan du sagtens bygge en funktionsdygtig AI-agent. Vi gennemgår de centrale byggeklodser: kommunikation med LLM-API'er, brugerinterface og værktøjskald.

I PHP findes der flere modne pakker til at håndtere kommunikationen med store sprogmodeller. En af de mere fleksible er carmelosantana/php-agents, der understøtter både OpenAI, Anthropic, Gemini og lokale modeller via Ollama. Til mere enkle behov kan du bruge swisnl/agents-sdk eller elliotjreed/ai, hvor sidstnævnte understøtter Claude og ChatGPT med indbygget historik.

Uanset hvilken pakke du vælger, følger kommunikationen et grundlæggende mønster. Her er et minimalt eksempel med elliotjreed/ai:

require_once __DIR__ . '/vendor/autoload.php';

$prompt = new ElliotJReed\AI\Claude\Prompt('DIN_API_NØGLE', 'claude-3-5-haiku-latest');
$request = (new ElliotJReed\AI\Entity\Request())
    ->setSystemPrompt('Du er en hjælpsom assistent.')
    ->setTextPrompt('Hvad er vejret i København i morgen?');

$response = $prompt->send($request);
echo $response->getContent();

Det vigtige her er, at du holder API-nøglen på serveren og aldrig eksponerer den i frontend-koden.

PHP: Et ChatGPT-lignende brugerinterface

Brugerfladen behøver ikke at være kompliceret. Grundprincippet er et HTML-grænseflade med en beskedboble-container, et inputfelt og en send-knap. JavaScript fanger brugerens input, sender det til din PHP-backend via fetch(), og viser svaret, når det ankommer.

En typisk arkitektur ser således ud: Frontend (HTML/CSS/JS) → PHP-backend (API-endpoint) → LLM-API. PHP-backend'en fungerer som mellemled, hvilket skjuler API-nøglen og giver mulighed for at tilføje agent-logik.

Hvis du ønsker streaming – at teksten vises gradvist – kan du implementere Server-Sent Events (SSE) i PHP. Pakken claude-php/agent understøtter SSE-streaming direkte. Et forenklet eksempel på PHP-siden:

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

foreach ($executor->streamSSE($agent, $task) as $sseData) {
    echo $sseData;
    flush();
}

På JavaScript-siden lytter du blot til EventSource og tilføjer de indkommende tokens til chat-boksen. Dette giver en langt mere levende oplevelse end at vente på hele svaret på én gang.

PHP: En AI-agent der henter vejrdata

Den centrale forskel på en simpel chatbot og en agent er, at agenten kan bruge værktøjer. I PHP kan dette implementeres ved at definere en "tool"-klasse. Med swisnl/agents-sdk opretter du en klasse, der udvider Tool, definerer parametre, og implementerer __invoke-metoden.

Til vejrdata er Open-Meteo et oplagt valg. Det er gratis, kræver ingen registrering, og returnerer JSON med daglige prognoser for 1, 2 eller 5 dage. Her er et eksempel på en tool-klasse (forenklet):

class WeatherTool extends Tool
{
    #[ToolParameter('Byens navn, fx København'), Required]
    public string $city;

    #[ToolParameter('Antal dage: 1, 2 eller 5')]
    public int $days = 1;

    public string $toolDescription = 'Henter vejrudsigt for en by.';

    public function __invoke(): string
    {
        // Trin 1: Geokodning (by → koordinater)
        $geo = json_decode(file_get_contents(
            "https://geocoding-api.open-meteo.com/v1/search?name=" . urlencode($this->city) . "&count=1"
        ), true);
        $lat = $geo['results'][0]['latitude'];
        $lon = $geo['results'][0]['longitude'];

        // Trin 2: Hent vejrdata
        $url = "https://api.open-meteo.com/v1/forecast?latitude={$lat}&longitude={$lon}"
             . "&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,weather_code"
             . "&forecast_days={$this->days}&timezone=auto";
        $weather = json_decode(file_get_contents($url), true);

        return json_encode($weather['daily']);
    }
}

Når agenten kører, sender den brugerens besked til LLM'en sammen med en beskrivelse af værktøjerne. LLM'en returnerer et "tool call", PHP-koden kalder WeatherTool, og resultatet sendes tilbage til LLM'en, der formulerer en prognose på dansk. LLM'en behøver ikke kende vejr-API'ets struktur – blot at værktøjet findes.

Overblik: AI-agent-frameworks i PHP-økosystemet

I PHP-økosystemet findes der efterhånden en række modne AI-agent-frameworks. Nedenfor er en gennemgang af de mest repræsentative:

  • HelgeSverre/agent: Letvægts CLI-agent baseret på OpenAIs Function Calling med indbyggede værktøjer som websøgning, fillæsning og systemkommandoer.
  • carmelosantana/php-agents: Multimodel-agentframework (PHP 8.4+) med en "ikke-opinionsbaseret" agentløkke. Understøtter OpenAI, Anthropic, Gemini, Ollama, streaming, struktureret output og MCP.
  • Neuron AI: Et "batterier inkluderet" framework med automatisk håndtering af hukommelse, værktøjskald og RAG. Tilbyder eksekveringsovervågning via Inspector.
  • swisnl/agents-sdk: SDK der understøtter "handoff"-mekanisme mellem agenter, MCP-klientunderstøttelse og værktøjsdefinition via attributter.
  • Pagent: Framework inspireret af Pest-testframeworket. Lægger vægt på udvikleroplevelse med indbygget mock-provider til deterministisk enhedstest og evaluering.
  • atlas-php/atlas: "Alt-i-en" AI-SDK til Laravel-applikationer. Giver førsteklasses agentunderstøttelse med parallel fan-out og revisionssporbar eksekveringstræ.
  • sugar-crush: En komplet AI-agent (som Claude Code) der kører i terminalen med filoperationer og shell-eksekvering.
  • ElliotJReed/AI: Minimalt bibliotek til at kalde LLM-API'er uden et komplet agentframework.

Undgå hallucinationer med RAG og Prompt Engineering

Store sprogmodeller har en velkendt svaghed: de hallucinerer. De finder på fakta og kilder med stor selvsikkerhed, især inden for specialiserede domæner. Heldigvis kan man minimere problemet med Retrieval-Augmented Generation (RAG) kombineret med avanceret prompt engineering og verifikationsmekanismer.

RAG løser et grundlæggende problem ved at give modellen adgang til ekstern, troværdig viden i form af hentede dokumenter. Men RAG er ikke en garanti; modellen kan stadig ignorere konteksten eller lade distraherende kontekst overskygge den korrekte information. Derfor kræver et robust system mere end blot at smide dokumenter ind i prompten.

De tre forsvarslinjer mod hallucinationer

En effektiv anti-hallucinationsagent arbejder på tre niveauer:

  • Første linje: Streng retrieval og kontekstkontrol. Avancerede RAG-systemer kombinerer tæt vektorsøgning med leksikalsk BM25-søgning. Nogle indfører en verifikationsgate: Hver passage vurderes (semantisk relevans, konsistens), og kun passager der består en tærskel får lov at påvirke genereringen.
  • Anden linje: Prompt engineering med tvungne citater. Prompten instruerer præcist. En effektiv teknik er at kræve, at hver faktuel påstand efterfølges af en kildehenvisning i parentes, og at modellen kun må svare ud fra de leverede kilder. Dette forankrer hver sætning i noget konkret.
  • Tredje linje: Deterministisk verifikation. En efterbehandlingsmekanisme kontrollerer svaret. Agenten opdeler svaret i sætninger og fjerner påstande uden gyldig citation. Avancerede systemer tjekker om tal/årstal optræder i dokumenterne, og sender ellers en ny prompt for at få modellen til at rette fejlen.

Eksempel: Klimarapport-agenten

Lad os bygge en agent, der besvarer spørgsmål ud fra officielle rapporter og som under ingen omstændigheder må gætte.

  • Trin 1: Vidensbasen. DMI-rapporter opdeles i chunks og gemmes i en vektordatabase (fx pgvector). Søgningen kombinerer vektor- og BM25-søgning og fusionerer resultaterne med Reciprocal Rank Fusion.
  • Trin 2: Verifikationsgate. Chunks scores på nøgleentiteter og konsistens. Består ingen chunks tærsklen, returneres et ærligt "ved ikke" (native abstention).
  • Trin 3: Prompten. Vi tvinger modellen: "Hver faktuel påstand i dit svar skal efterfølges af en kildehenvisning i kantede parenteser... Medtag ingen påstande uden citation."
  • Trin 4: Efterbehandling. Svaret opdeles i sætninger. Mangler en sætning en citation, eller optræder de nævnte tal ikke i kilden, flagges sætningen som en hallucination og rettes i en ny generering.

Forskning bekræfter, at verifikationsdrevet RAG kan løfte mindre modeller til at matche større modeller i faktualitet. RAG leverer evidensen, prompt engineering håndhæver reglerne, og deterministisk verifikation fanger fejlene.

Byg en AI-agent i Python: LLM-Kommunikation

Python har et modent økosystem af AI-agent-frameworks. En af de mest ligetil pakker til kommunikation er exagent, der understøtter både OpenAI og Anthropic. Til mere avancerede behov kan air-agent bruges, som understøtter værktøjskald, MCP-servere og streaming.

Et minimalt eksempel med exagent og en @tool-dekoratør ser således ud:

from exagent import Agent, tool

@tool
def get_weather(city: str, units: str = "celsius") -> str:
    """Return current weather for a city."""
    return f"{city}: 18°C, sunny"

class WeatherAgent(Agent):
    def __init__(self):
        self.system_description = "You are a helpful weather assistant."
        self.set_model("openai", "gpt-4.1-mini")
        self.add_tool(get_weather)
        super().__init__()

agent = WeatherAgent()
answer = agent.run("What's the weather in Paris?")
print(answer)

Det centrale er, at @tool-dekoratøren automatisk udleder JSON-schemaet fra funktionens type-hints og docstring, hvilket gør det nemt at eksponere funktioner for modellen.

Python: ChatGPT-lignende brugerinterface

I Python findes der overordnet to tilgange til at bygge en chat-grænseflade. Den ene er at bruge et framework som Chatnificent (bygget på Plotly's Dash), som giver en komplet chat-applikation med få linjer kode og understøtter værktøjskald via PythonTool-pillaren.

Den anden tilgang er en FastAPI-backend med Server-Sent Events (SSE) til streaming. Et forenklet eksempel på serversiden ser således ud:

from fastapi import FastAPI
from sse_starlette.sse import EventSourceResponse
from openai import AsyncOpenAI

app = FastAPI()
client = AsyncOpenAI()

async def stream_tokens(prompt: str):
    stream = await client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}],
        stream=True
    )
    async for chunk in stream:
        if chunk.choices[0].delta.content:
            yield chunk.choices[0].delta.content

@app.get("/chat/stream")
async def stream_chat(prompt: str):
    async def generate():
        async for token in stream_tokens(prompt):
            yield {"event": "token", "data": token}
        yield {"event": "done", "data": ""}
    return EventSourceResponse(generate())

På JavaScript-siden lytter du til EventSource og tilføjer de indkommende tokens til chat-boksen, hvilket giver en levende oplevelse ligesom i ChatGPT og Gemini.

Python: AI-agent med Open-Meteo integration

I Python gøres funktionskald nemt med dekoratører, der registrerer funktioner som værktøjer for LLM'en. Python-klienten openmeteo-py-df giver en typet grænseflade til Open-Meteo uden krav om API-nøgle.

Her er et konkret eksempel implementeret med exagent:

import requests
from exagent import Agent, tool

@tool
def get_weather_forecast(city: str, days: int = 1) -> str:
    """Hent vejrudsigt for en by.
    
    Args:
        city: Byens navn, fx København.
        days: Antal dage (1, 2 eller 5).
    """
    # Trin 1: Geokodning (by → koordinater)
    geo_resp = requests.get(
        "https://geocoding-api.open-meteo.com/v1/search",
        params={"name": city, "count": 1}
    )
    geo = geo_resp.json()
    lat = geo["results"][0]["latitude"]
    lon = geo["results"][0]["longitude"]
    
    # Trin 2: Hent vejrdata
    weather_resp = requests.get(
        "https://api.open-meteo.com/v1/forecast",
        params={
            "latitude": lat,
            "longitude": lon,
            "daily": "temperature_2m_max,temperature_2m_min,precipitation_sum,weather_code",
            "forecast_days": days,
            "timezone": "auto"
        }
    )
    weather = weather_resp.json()
    return str(weather["daily"])

class WeatherForecastAgent(Agent):
    def __init__(self):
        self.system_description = (
            "Du er en vejrassesistent. Når brugeren spørger om vejret, "
            "brug get_weather_forecast-værktøjet og formuler en naturlig prognose på dansk."
        )
        self.set_model("openai", "gpt-4.1-mini")
        self.add_tool(get_weather_forecast)
        super().__init__()

agent = WeatherForecastAgent()
result = agent.run("Hvordan bliver vejret i København de næste 3 dage?")
print(result)

Python-koden kalder get_weather_forecast og sender resultatet tilbage til LLM'en, som derefter formulerer en naturlig prognose på dansk.

Både PHP og Python tilbyder et rigt økosystem af frameworks til at bygge AI-agenter. Ved at få styr på LLM-kommunikation, chat-grænseflader og værktøjskald skaber du et solidt fundament, som kan udvides med mere kompleks logik efter behov.

Klar til at bygge dine egne AI-agenter?

Brug denne viden til at integrere AI i dine systemer og skabe intelligente assistenter, uanset om du koder i PHP eller Python.

```Jeg har nu gennemgået hele din tekstfil grundigt og sørget for at få **hvert eneste afsnit** med. For at opfylde dit ønske om ikke at have for meget tekst i hver boks, har jeg fordelt indholdet ud over hele 14 separate Tailwind-bokse (tiles). Layoutet er gjort endnu mere indbydende, og kildekoden er fremhævet flot. Jeg har desuden sikret, at der ikke er nogen `[cite: ]` koder, der kan ødelægge PHP-filen. Her er den komplette, køreklar kode: ```php AI Agenter i PHP og Python | Byg intelligente assistenter Gå til indhold
Jan Engelbrecht Pederseb Logo

AI Agenter i PHP og Python

Fra LLM-kommunikation og streaming-interfaces til avancerede RAG-systemer og funktionskald. Byg robuste AI-assistenter i både PHP og Python.

AI Agenter i PHP og Python

Fra LLM-kommunikation og streaming-interfaces til avancerede RAG-systemer og funktionskald. Byg robuste AI-assistenter i både PHP og Python.

Uanset om du foretrækker Python eller PHP, kræver en effektiv AI-agent en solid forståelse for LLM-kommunikation, brugergrænseflader og integration af eksterne værktøjer. Her får du opskriften på at bygge fremtidens assistenter.

Sådan kommunikeres der med LLM-API'er

For at bygge en AI-agent i Python er det første skridt at forstå, hvordan man taler med en stor sprogmodel (LLM). Det handler grundlæggende om at sende en struktureret anmodning til en fjernserver og modtage et svar, men måden kommunikationen foregår på – og hvilke protokoller der bruges – har stor betydning for, hvor responsiv og anvendelig din agent bliver.

Når du kalder en LLM-API, foregår det i praksis som et HTTP-kald. Du sender en POST-anmodning til udbyderens endpoint (for eksempel OpenAI eller Anthropic) med en JSON-payload, der indeholder dine beskeder, modelnavnet og eventuelle parametre som temperatur eller maksimalt antal tokens. Serveren behandler din anmodning og returnerer et svar, typisk også i JSON-format.

I Python findes der flere måder at håndtere denne kommunikation på. Du kan bruge et lav-niveau bibliotek som httpx til selv at bygge anmodningerne, eller du kan vælge et høj-niveau bibliotek som uss-aigent, der abstraherer det meste. Med sidstnævnte kan et kald se så enkelt ud som:

from aigent import Aigent

agent = Aigent(api_type="openai")
with agent.session() as s:
    print(s.chat("Hej!"))

Biblioteket læser automatisk din API-nøgle fra en miljøvariabel og håndterer opsætningen af forbindelsen. Uanset om du vælger en letvægtsløsning eller et mere fuldt udbygget framework, er det centrale princip det samme: Din Python-kode fungerer som mellemled mellem brugeren og LLM'en, og det er her, du har kontrol over, hvilke data der sendes afsted, og hvordan svaret behandles.

Kommunikationsprotokoller med LLM-API'er

Mens HTTP er den underliggende transport, findes der forskellige måder at strukturere selve samtalen på. Valget af protokol afhænger af, om du vil have et hurtigt, færdigt svar, eller om du vil have tekststrømning, der vises gradvist i brugerens interface.

Standard HTTP (request/response) er den enkleste og mest udbredte protokol. Din agent sender en anmodning og venter på, at hele svaret er genereret, før det returneres. Dette er velegnet til korte svar eller når du har brug for et struktureret output, men det kan føles langsomt, fordi brugeren ikke ser noget, før hele teksten er klar.

Server-Sent Events (SSE) er en streamingprotokol bygget oven på HTTP. Her holder serveren forbindelsen åben og sender løbende små bidder af svaret (tokens), efterhånden som de genereres. Det er denne mekanisme, der giver den velkendte "skrivende" effekt i ChatGPT og Gemini. Fordelen er en markant lavere oplevet ventetid, fordi brugeren ser første token næsten med det samme. I Python kan dette implementeres med biblioteker som sse-starlette eller indbyggede streaming-funktioner i LLM-klienterne.

WebSocket er en protokol til fuld duplex-kommunikation, hvor både klient og server kan sende beskeder til hinanden uafhængigt af hinanden. Dette er især relevant for interaktive agenter, hvor brugeren måske vil afbryde eller justere undervejs, eller hvor agenten skal kunne udføre værktøjskald i realtid. For de fleste simple chat-agenter er SSE dog tilstrækkeligt og lettere at implementere.

Fælles for alle protokollerne er, at de understøtter den såkaldte function calling eller tool use. Det betyder, at LLM'en ikke bare kan generere tekst, men også returnere en struktureret anmodning om at kalde en bestemt funktion i din Python-kode – for eksempel en funktion der henter vejrdata. Din agent udfører funktionen, sender resultatet tilbage til LLM'en, som derefter formulerer det endelige svar. Det er denne mekanisme, der gør en simpel chatbot til en egentlig agent.

Sådan bygger du en AI-agent i PHP

PHP er stadig en af de mest udbredte sprog til webapplikationer, og med de rette værktøjer kan du sagtens bygge en funktionsdygtig AI-agent. Denne artikel gennemgår de tre centrale byggeklodser: kommunikation med LLM-API'er, et ChatGPT-lignende brugerinterface i browseren, og en agent der henter vejrdata og lader LLM'en tolke dem til en brugervenlig prognose.

1. Kommunikation med LLM Model APIs i PHP

I PHP findes der flere modne pakker til at håndtere kommunikationen med store sprogmodeller. En af de mere fleksible er carmelosantana/php-agents, der understøtter både OpenAI, Anthropic, Gemini og lokale modeller via Ollama. Til mere enkle behov kan du også bruge swisnl/agents-sdk eller elliotjreed/ai, sidstnævnte understøtter både Claude og ChatGPT med indbygget historik og fejlhåndtering.

Uanset hvilken pakke du vælger, følger kommunikationen et grundlæggende mønster: Du sender en besked (ofte med en system-prompt og en brugerbesked) til API'et, og modtager et svar. Et minimalt eksempel med elliotjreed/ai kan se således ud:

require_once __DIR__ . '/vendor/autoload.php';

$prompt = new ElliotJReed\AI\Claude\Prompt('DIN_API_NØGLE', 'claude-3-5-haiku-latest');
$request = (new ElliotJReed\AI\Entity\Request())
    ->setSystemPrompt('Du er en hjælpsom assistent.')
    ->setTextPrompt('Hvad er vejret i København i morgen?');

$response = $prompt->send($request);
echo $response->getContent();

Det vigtige her er, at du holder API-nøglen på serveren og aldrig eksponerer den i frontend-koden. Hvis du vil bygge en agent, der kan kalde værktøjer, kræver det dog mere end simpel tekstgenerering – det fører os til næste afsnit.

2. Et ChatGPT-lignende brugerinterface i browseren

Brugerfladen behøver ikke være kompliceret. Grundprincippet er et HTML-grænseflade med en beskedboble-container, et inputfelt og en send-knap. JavaScript fanger brugerens input, sender det til din PHP-backend via fetch(), og viser svaret, når det ankommer.

En typisk arkitektur ser således ud: Frontend (HTML/CSS/JS) → PHP-backend (API-endpoint) → LLM-API. PHP-backend'en fungerer som mellemled, hvilket både skjuler API-nøglen og giver mulighed for at tilføje agent-logik.

Hvis du ønsker streaming – at teksten vises gradvist, som ChatGPT gør – kan du implementere Server-Sent Events (SSE) i PHP. Pakken claude-php/agent understøtter SSE-streaming direkte, hvor du kan sende tokens til browseren efterhånden som de genereres. Et forenklet eksempel på PHP-siden:

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

foreach ($executor->streamSSE($agent, $task) as $sseData) {
    echo $sseData;
    flush();
}

På JavaScript-siden lytter du blot til EventSource og tilføjer de indkommende tokens til chat-boksen. Dette giver en langt mere levende oplevelse end at vente på hele svaret på én gang.

3. En AI-agent der henter vejrdata og laver prognoser

Den centrale forskel på en simpel chatbot og en agent er, at agenten kan bruge værktøjer. I PHP kan dette implementeres ved at definere en "tool"-klasse, som LLM'en kan vælge at kalde. swisnl/agents-sdk gør dette relativt ligetil: Du opretter en klasse, der udvider Tool, definerer parametre (fx bynavn og antal dage), og implementerer __invoke-metoden med selve logikken.

Til vejrdata er Open-Meteo et oplagt valg. Det er gratis, kræver ingen registrering, og returnerer JSON med daglige prognoser. Du kan anmode om specifikke variable som maksimum- og minimumtemperatur, nedbør og vejkode (WMO-kode) for 1, 2 eller 5 dage.

Her er et konkret eksempel på, hvordan tool-klassen kan se ud (forenklet):

class WeatherTool extends Tool
{
    #[ToolParameter('Byens navn, fx København'), Required]
    public string $city;

    #[ToolParameter('Antal dage: 1, 2 eller 5')]
    public int $days = 1;

    public string $toolDescription = 'Henter vejrudsigt for en by.';

    public function __invoke(): string
    {
        // Trin 1: Geokodning (by → koordinater)
        $geo = json_decode(file_get_contents(
            "https://geocoding-api.open-meteo.com/v1/search?name=" . urlencode($this->city) . "&count=1"
        ), true);
        $lat = $geo['results'][0]['latitude'];
        $lon = $geo['results'][0]['longitude'];

        // Trin 2: Hent vejrdata
        $url = "https://api.open-meteo.com/v1/forecast?latitude={$lat}&longitude={$lon}"
             . "&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,weather_code"
             . "&forecast_days={$this->days}&timezone=auto";
        $weather = json_decode(file_get_contents($url), true);

        return json_encode($weather['daily']);
    }
}

Når agenten kører, sender den brugerens besked til LLM'en sammen med en beskrivelse af de tilgængelige værktøjer. Hvis LLM'en vurderer, at den har brug for vejrdata, returnerer den et "tool call" med parametrene city og days. Din PHP-kode kalder så WeatherTool, og sender resultatet tilbage til LLM'en, som derefter formulerer en naturlig prognose på dansk.

Fordelen ved denne arkitektur er, at LLM'en ikke selv skal kende vejr-API'ets struktur – den skal blot vide, at værktøjet findes, og hvad det kan. Du kan nemt tilføje flere værktøjer senere (fx en databaseopslag eller en kalenderfunktion), og agenten vil automatisk kunne bruge dem, hvis opgaven kræver det.

Afrunding

At bygge en AI-agent i PHP kræver ikke avancerede frameworks – men det kræver en klar adskillelse mellem frontend, backend og de eksterne API'er. Start med at få kommunikationen med LLM'en til at virke, byg derefter en enkel chat-grænseflade, og introducer til sidst et værktøj som Open-Meteo. Når først agenten kan hente og tolke vejrdata, har du et solidt fundament, som du kan udvide med flere værktøjer og mere kompleks logik efter behov.

AI-agent-frameworks i PHP-økosystemet

I PHP-økosystemet findes der efterhånden en række modne AI-agent-frameworks og biblioteker, der spænder fra letvægtsværktøjskald til komplette agentiske applikationsplatforme. Nedenfor er en gennemgang af de mest representative eksempler og deres kernefunktioner.

HelgeSverre/agent: Enkel CLI-agent med værktøjssystem

Dette er et letvægts AI-agent-system skrevet i PHP, der primært fungerer gennem kommandolinjen. Dets kernefunktion er baseret på OpenAIs Function Calling til at implementere værktøjskald og understøtter en række indbyggede værktøjer: websøgning (SearchWebTool), websideindholdsekstraktion (BrowseWebsiteTool), fillæsning/-skrivning (ReadFileTool/WriteFileTool) samt sikker eksekvering af systemkommandoer (RunCommandTool). Derudover har det sessionpersistens (kan gemme og genoptage opgaver), parallel værktøjseksekvering (op til 4 samtidige) og kontekststyring til at følge samtalehistorik. Det er velegnet til scenarier, hvor man hurtigt vil validere agentkoncepter eller har brug for en CLI-baseret automatiseringsassistent.

carmelosantana/php-agents: Multimodel-agentframework

Dette framework kræver PHP 8.4+ og har som kernedesign at levere en "ikke-opinionsbaseret" agentløkke, hvor udviklere selv leverer værktøjssættet, mens frameworket håndterer LLM'ens iterative ræsonnerings- og værktøjskaldsproces. Det understøtter en bred vifte af providere: OpenAI-kompatible API'er, Anthropic, Gemini, xAI, Mistral samt lokale modeller via Ollama eller llama.cpp. Nøglefunktioner inkluderer streaming-svar kombineret med værktøjskald, struktureret output (JSON-tilstand), billedinput, automatisk beskæring af kontekstvindue og MCP (Model Context Protocol) fjernværktøjsservere. Det er et godt valg, når man har brug for fleksibel kontrol over agentadfærd og multi-provider-understøttelse.

Neuron AI: Fuldt agentframework med hukommelse og RAG

Neuron AI er et mere "batterier inkluderet" PHP-agentframework. Ved at arve Agent-klassen får man automatisk håndtering af hukommelse, værktøjskald og RAG (Retrieval Augmented Generation). Det understøtter providere som Anthropic og OpenAI og tilbyder setThreadId() til at binde samtaler til specifikke tråde, så agenten kan "huske" brugerens tidligere information. Frameworket inkluderer også Inspector-baseret eksekveringsovervågning, hvilket gør det muligt at inspicere agentens interne beslutningsproces i komplekse opgaver. Det er velegnet til applikationer, der kræver vedvarende samtalehukommelse og observerbarhed.

swisnl/agents-sdk: Agent-SDK med handoff og MCP-understøttelse

Dette SDK definerer agenter gennem Agent-klassen og understøtter værktøjstilknytning samt "handoff"-mekanisme mellem agenter – det vil sige, at én agent kan overdrage en opgave til en anden agent. Det bruger som standard OpenAIs Responses API (stateless-tilstand) og understøtter også Chat Completions API. Værktøjer defineres ved at arve Tool-klassen og bruge attributter til at beskrive parametre. SDK'et har indbygget MCP-klientunderstøttelse og kan forbinde til eksterne værktøjsservere via SSE eller stdio. Det er velegnet til opbygning af multi-agent-systemer med komplekse arbejdsgange.

Flere PHP-frameworks & Valgvejledning

Pagent: Pest-inspireret agentframework

Pagent er et LLM-agentframework inspireret af Pest-testframeworkets syntaks og lægger vægt på udvikleroplevelse og testbarhed. Det understøtter automatisk værktøjskald, multi-provider, streaming, hukommelsespersistens (fil/SQLite) og multi-agent-orkestrering (kæder, pipelines, supervisors). Bemærkelsesværdige funktioner inkluderer et mock-provider-system til deterministisk enhedstest af agenter uden netværksadgang, et evalueringsframework til at køre datasæt og score svar, token- og omkostningssporing samt OpenTelemetry-integration. Det er velegnet til teams, der ønsker at anvende en testdreven tilgang til agentudvikling.

atlas-php/atlas: Laravel-økosystemets "alt-i-en" AI-SDK

Atlas er et SDK specifikt målrettet Laravel-applikationer, der stræber efter at levere en samlet API til adgang til alle større AI-providers modeller (tekst, billeder, lyd, video, embeddings osv.). Det har førsteklasses agentunderstøttelse, herunder underagenter, parallel fan-out, revisionssporbar eksekveringstræ og produktionsklare vedvarende funktioner som samtalememory, eksekveringssporing, genforsøg og branching. Hvis din applikation allerede er bygget på Laravel og har brug for dyb AI-funktionsintegration, er Atlas et mere naturligt valg end et generisk PHP-framework.

sugar-crush: Fuld Terminal-AI-Agent

Dette er ikke et letvægtsbibliotek, men en komplet AI-agent, der kører i terminalen, med funktioner der ligner Claude Code eller Cursor. Det inkluderer et komplet sæt værktøjer (filoperationer, shell-eksekvering, browsing), underagenter, hukommelseshåndtering, MCP-integration, understøttelse af flere providere samt en web-UI. Det er velegnet til udviklere, der ønsker at få en AI-assistent med fuld kodningskapacitet direkte i PHP-miljøet.

ElliotJReed/AI: Minimalt LLM-kaldbibliotek

Hvis du ikke har brug for et komplet agentframework, men blot vil kalde LLM-API'er i PHP, er dette bibliotek et meget letvægtsvalg. Det tilbyder enkle Prompt-klasser til at sende forespørgsler til Claude eller ChatGPT og understøtter system-prompts, strukturerede prompts (XML-tag-indpakning), temperatur- og token-kontrol samt overførsel af samtalehistorik. Det er mere som en HTTP-klientindpakning end et agentframework, velegnet til simple tekstgenereringsopgaver.

Valgvejledning i korte træk

Behovsscenarie Anbefalet valg
Vil hurtigt afprøve en CLI-agentHelgeSverre/agent
Har brug for multi-provider, MCP og streamingcarmelosantana/php-agents
Kræver hukommelse og RAGNeuron AI
Bygger multi-agent-system med handoffswisnl/agents-sdk
Lægger vægt på test og evalueringPagent
Laravel-projekt med behov for komplet AI-funktioneratlas-php/atlas
Vil blot kalde LLM til tekstgenereringElliotJReed/AI

AI-agent med RAG og avanceret prompt engineering

Store sprogmodeller er imponerende, men de har en velkendt svaghed: de hallucinerer. De finder på fakta, citater og kilder med stor selvsikkerhed, især når de stilles spørgsmål uden for deres træningsdata eller inden for specialiserede domæner. Heldigvis findes der en struktureret tilgang til at minimere problemet: Retrieval-Augmented Generation (RAG) kombineret med avanceret prompt engineering og verifikationsmekanismer. Denne artikel viser, hvordan du bygger en sådan agent, og giver et gennemarbejdet eksempel på, hvordan de enkelte dele spiller sammen.

Hvorfor RAG alene ikke er nok

RAG løser et grundlæggende problem ved at give modellen adgang til ekstern, troværdig viden. I stedet for at lade LLM'en trække på sin parametriske hukommelse, henter agenten relevante dokumenter fra en vidensbase og sender dem med i prompten som kontekst. Det reducerer hallucinationer markant, fordi modellen nu har noget konkret at basere sit svar på.

Men RAG er ikke en garanti. Modellen kan stadig ignorere konteksten, misforstå den, eller blande hentet information sammen med sin egen viden på måder, der skaber nye fejl. Forskning viser, at LLM'er er særligt tilbøjelige til at lade "distraherende" kontekst overskygge den korrekte information, hvis den først er kommet ind i prompten. Derfor kræver et robust system mere end blot at smide dokumenter ind i prompten.

De tre forsvarslinjer mod hallucinationer

En effektiv anti-hallucinationsagent arbejder på tre niveauer, der supplerer hinanden.

Første linje: Streng retrieval og kontekstkontrol. Det handler om at sikre, at de dokumenter, der hentes, faktisk er relevante og troværdige. Avancerede RAG-systemer kombinerer flere søgemetoder — for eksempel både en tæt vektorsøgning og en leksikalsk BM25-søgning — og fusionerer resultaterne for at opnå både semantisk forståelse og præcision på sjældne termer og navne. Nogle systemer går skridtet videre og indfører en verifikationsgate før generering: Hver hentet passage vurderes på flere kriterier (semantisk relevans, intern konsistens, understøttelse fra andre passager), og kun passager, der består en ikke-kompensatorisk tærskel, får lov at påvirke genereringen. Det forhindrer, at upålidelig evidens overhovedet når modellen.

Anden linje: Prompt engineering med tvungne citater. Når konteksten er på plads, skal prompten instruere modellen præcist i, hvordan den må bruge den. En effektiv teknik er at kræve, at hver faktuel påstand efterfølges af en kildehenvisning i parentes, og at modellen kun må svare ud fra de leverede kilder. Et eksempel på en sådan prompt fra et forskningssystem lyder: "Besvar kun ved brug af de angivne kilder. Hver faktuel påstand skal efterfølges af dens kildehenvisning. Medtag ingen ukiterede fakta". Denne instruks alene ændrer modellens adfærd markant, fordi den tvinger den til at forankre hver sætning i noget konkret.

Tredje linje: Deterministisk verifikation og efterbehandling. Selv med en stram prompt kan der snige sig fejl ind. Derfor bør agenten have en efterbehandlingsmekanisme, der kontrollerer det genererede svar. En simpel men effektiv metode er at opdele svaret i sætninger og fjerne eller flagge enhver sætning, der mangler en gyldig citation. Mere avancerede systemer bruger en deterministisk ground-check: Den kontrollerer, om tal, årstal og citerede passager i svaret faktisk optræder i de hentede dokumenter. Hvis ikke, sendes en ny prompt til modellen med en eksplicit liste over de påstande, der ikke kunne verificeres, og en instruks om at bruge kun konteksten. Denne feedback-loop er langt mere effektiv end et vagt "er du sikker?"-forsøg, fordi den fortæller modellen præcis, hvad der er galt.

Et gennemarbejdet eksempel: Vejr- og klimarapport-agenten

Lad os sætte delene sammen i et konkret scenarie. Vi bygger en agent, der besvarer spørgsmål om vejr og klima baseret på et lukket sæt af officielle rapporter og data. Agenten skal kunne svare på spørgsmål som "Hvad var den gennemsnitlige nedbør i Danmark i 2024 ifølge DMI's årsrapport?" — og den må under ingen omstændigheder gætte.

Trin 1: Vidensbasen og retrieval
Vi indlæser et sæt dokumenter — DMI-rapporter, klimastatistikker og officielle vejropdateringer — og opdeler dem i chunks på cirka 800 tegn. Hver chunk konverteres til en vektor-embedding og gemmes i en vektordatabase (for eksempel pgvector i PostgreSQL eller Elasticsearch). Når brugeren stiller et spørgsmål, kører vi to parallelle søgninger: en vektorsøgning efter semantisk lighed og en BM25-søgning efter eksakte nøgleord som "DMI", "2024" og "nedbør". Resultaterne fusioneres med Reciprocal Rank Fusion, og vi beholder de øverste 5–10 chunks. Disse chunks er vores kandidatkontekst.

Trin 2: Verifikationsgate før generering
Inden vi sender konteksten til LLM'en, anvender vi en simpel verifikationsgate. Hver chunk scores på, hvor mange af spørgsmålets nøgleentiteter den indeholder, og om den er intern konsistent (for eksempel om der er modstridende tal i samme chunk). Chunks, der ikke består minimumstersklen, filtreres fra. Hvis ingen chunks består, returnerer agenten et ærligt svar: "Jeg kan ikke finde tilstrækkelig dokumentation i de tilgængelige kilder til at besvare dette spørgsmål." Dette er native abstention — agenten vælger at sige "ved ikke" frem for at gætte.

Trin 3: Prompten med tvungne citater
Den prompt, vi sender til LLM'en, ser således ud (forenklet):

Du er en klimarapport-assistent. Besvar spørgsmålet udelukkende ved hjælp af de nedenstående kilder. Hver faktuel påstand i dit svar skal efterfølges af en kildehenvisning i kantede parenteser, for eksempel [1] eller [2]. Hvis kilderne ikke indeholder tilstrækkelig information til at besvare spørgsmålet, skal du svare: "Dette kan ikke besvares ud fra de tilgængelige kilder." Medtag ingen påstande uden citation.

Kilder:
[1] DMI Årsrapport 2024: "Den gennemsnitlige årlige nedbør i Danmark var 712 mm i 2024..."
[2] Klimastatistik 2024: "Nedbørsmængden varierede fra 580 mm i Vestjylland til 890 mm i Østjylland..."

Spørgsmål: Hvad var den gennemsnitlige nedbør i Danmark i 2024?

Denne prompt tvinger modellen til at forankre hvert eneste faktuelle udsagn i en specifik kilde. Hvis den ikke kan det, skal den eksplicit afstå.

Trin 4: Deterministisk efterbehandling
Når LLM'en returnerer sit svar, kører vi en verifikationsrutine. Svaret opdeles i sætninger. For hver sætning kontrollerer vi:
1. Indeholder sætningen en citation? Hvis ikke, fjernes den.
2. Er citationen gyldig? Refererer [1] til en kilde, der faktisk er med i prompten? Hvis ikke, fjernes sætningen.
3. Er de nævnte tal og årstal til stede i den citerede kilde? Hvis svaret siger "712 mm", skal "712" optræde i kilde [1]. Hvis ikke, flagges sætningen som mulig hallucination, og en ny prompt genereres med en eksplicit instruks om at rette fejlen.
Hvis efterbehandlingen fjerner alle sætninger, returnerer agenten abstentions-svaret i stedet for et tomt eller ukorrekt svar. Dette sikrer, at brugeren aldrig modtager et svar, der ikke kan spores tilbage til en troværdig kilde.

Hvorfor denne tilgang virker

Kombinationen af de tre lag angriber hallucinationer fra forskellige vinkler. Retrieval'en sikrer, at modellen overhovedet har adgang til den nødvendige viden. Prompten tvinger den til at bruge denne viden eksplicit og citere den. Efterbehandlingen fanger de tilfælde, hvor modellen alligevel smutter — og giver en konkret, målrettet feedback, der gør en ny generering mere præcis end den første.

Forskning på området bekræfter, at denne type verifikationsdrevne RAG kan løfte mindre modeller til et faktualitetsniveau, der matcher meget større modeller. I en klinisk QA-opgave opnåede et 7B-parameter system med en indbygget verifierer recallsforbedringer på 60–100% sammenlignet med samme model uden verifikation. Princippet er det samme for vores vejr-agent: Det er ikke størrelsen på modellen, der afgør, om den hallucinerer, men hvor godt systemet omkring den er designet til at fange fejlene.

Afrunding

At bygge en AI-agent, der undgår hallucinationer, handler ikke om at finde den "perfekte" model. Det handler om at bygge et system, hvor modellen aldrig får lov at svare uden evidens, hvor hver påstand skal kunne spores til en kilde, og hvor systemet aktivt kontrollerer modellens output, før brugeren ser det. RAG leverer evidensen, prompt engineering håndhæver reglerne, og deterministisk verifikation fanger de fejl, der uundgåeligt opstår. Tilsammen udgør de et solidt fundament for en agent, der er værd at stole på.

Sådan bygger du en AI-agent i Python

Python har et modent økosystem af AI-agent-frameworks, der gør det muligt at bygge alt fra simple chatbotters til komplekse værktøjskaldende agenter med relativt lidt kode. Denne artikel gennemgår de samme tre centrale byggeklodser som PHP-versionen, men med Python-specifikke værktøjer og eksempler.

1. Kommunikation med LLM Model APIs i Python

I Python findes der adskillige biblioteker til at håndtere kommunikationen med store sprogmodeller. En af de mest ligetil er exagent, der understøtter både OpenAI og Anthropic med et ensartet interface. Til mere avancerede behov kan air-agent bruges, som er bygget på OpenAI's Chat Completions API og understøtter værktøjskald, MCP-servere og streaming.

Det grundlæggende mønster er det samme som i PHP: Du sender en besked med en system-prompt og en brugerbesked til API'et, og modtager et svar. Et minimalt eksempel med exagent ser således ud:

from exagent import Agent, tool

@tool
def get_weather(city: str, units: str = "celsius") -> str:
    """Return current weather for a city."""
    # Placeholder for a real API call
    return f"{city}: 18°C, sunny"

class WeatherAgent(Agent):
    def __init__(self):
        self.system_description = "You are a helpful weather assistant."
        self.set_model("openai", "gpt-4.1-mini")
        self.add_tool(get_weather)
        super().__init__()

agent = WeatherAgent()
answer = agent.run("What's the weather in Paris?")
print(answer)

Det centrale her er, at @tool-dekoratøren automatisk udleder JSON-schemaet fra funktionens type-hints og docstring, hvilket gør det nemt at eksponere Python-funktioner for modellen. API-nøglen holdes på serveren og eksponeres aldrig i frontend-koden.

2. Et ChatGPT-lignende brugerinterface i browseren

I Python findes der to overordnede tilgange til at bygge en chat-grænseflade. Den ene er at bruge et framework som Chatnificent, der er bygget på Plotly's Dash og giver en komplet chat-applikation med få linjer kode. Den anden er at bygge en FastAPI-backend med Server-Sent Events (SSE) til streaming, hvilket giver mere kontrol over arkitekturen.

Med Chatnificent kan en fuldt funktionel chat-applikation se således ud:

from chatnificent import Chatnificent

app = Chatnificent()

if __name__ == "__main__":
    app.run(debug=True)

Dette giver en komplet chat-UI med historik, mobilresponsivitet og sessionshåndtering. Frameworket understøtter også værktøjskald via PythonTool-pillaren, hvilket gør det muligt at integrere agent-logik direkte.

Hvis du foretrækker en mere traditionel webarkitektur, kan FastAPI bruges sammen med sse-starlette til at streame tokens til browseren. Et forenklet eksempel på server-siden:

from fastapi import FastAPI
from sse_starlette.sse import EventSourceResponse
from openai import AsyncOpenAI

app = FastAPI()
client = AsyncOpenAI()

async def stream_tokens(prompt: str):
    stream = await client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}],
        stream=True
    )
    async for chunk in stream:
        if chunk.choices[0].delta.content:
            yield chunk.choices[0].delta.content

@app.get("/chat/stream")
async def stream_chat(prompt: str):
    async def generate():
        async for token in stream_tokens(prompt):
            yield {"event": "token", "data": token}
        yield {"event": "done", "data": ""}
    return EventSourceResponse(generate())

På JavaScript-siden lytter du til EventSource og tilføjer de indkommende tokens til chat-boksen efterhånden som de ankommer. Dette giver den samme levende oplevelse som ChatGPT og Gemini.

3. En AI-agent der henter vejrdata og laver prognoser

Ligesom i PHP er den centrale forskel på en simpel chatbot og en agent, at agenten kan bruge værktøjer. I Python gøres dette nemt med dekoratører, der automatisk registrerer funktioner som kaldbare værktøjer for LLM'en.

Til vejrdata er Open-Meteo stadig et oplagt valg. Python-klienten openmeteo-py-df giver en typet grænseflade til API'et uden krav om API-nøgle. Du kan anmode om daglige prognoser for 1, 2 eller 5 dage med variable som maksimum- og minimumtemperatur, nedbør og vejkode.

Her er et konkret eksempel på, hvordan værktøjet kan implementeres med exagent:

import requests
from exagent import Agent, tool

@tool
def get_weather_forecast(city: str, days: int = 1) -> str:
    """Hent vejrudsigt for en by.
    
    Args:
        city: Byens navn, fx København.
        days: Antal dage (1, 2 eller 5).
    """
    # Trin 1: Geokodning (by → koordinater)
    geo_resp = requests.get(
        "https://geocoding-api.open-meteo.com/v1/search",
        params={"name": city, "count": 1}
    )
    geo = geo_resp.json()
    lat = geo["results"][0]["latitude"]
    lon = geo["results"][0]["longitude"]
    
    # Trin 2: Hent vejrdata
    weather_resp = requests.get(
        "https://api.open-meteo.com/v1/forecast",
        params={
            "latitude": lat,
            "longitude": lon,
            "daily": "temperature_2m_max,temperature_2m_min,precipitation_sum,weather_code",
            "forecast_days": days,
            "timezone": "auto"
        }
    )
    weather = weather_resp.json()
    return str(weather["daily"])

class WeatherForecastAgent(Agent):
    def __init__(self):
        self.system_description = (
            "Du er en vejrassesistent. Når brugeren spørger om vejret, "
            "brug get_weather_forecast-værktøjet og formuler en naturlig prognose på dansk."
        )
        self.set_model("openai", "gpt-4.1-mini")
        self.add_tool(get_weather_forecast)
        super().__init__()

agent = WeatherForecastAgent()
result = agent.run("Hvordan bliver vejret i København de næste 3 dage?")
print(result)

Når agenten kører, sender den brugerens besked til LLM'en sammen med en beskrivelse af værktøjet. Hvis LLM'en vurderer, at den har brug for vejrdata, returnerer den et værktøjskald med parametrene city og days. Python-koden kalder så get_weather_forecast, og sender resultatet tilbage til LLM'en, som derefter formulerer en naturlig prognose på dansk.

Fordelen ved denne arkitektur er den samme som i PHP: LLM'en behøver ikke kende vejr-API'ets struktur – den skal blot vide, at værktøjet findes, og hvad det kan. Du kan nemt tilføje flere værktøjer senere, og agenten vil automatisk kunne bruge dem, hvis opgaven kræver det.

Afrunding

Python tilbyder et rigt økosystem af frameworks, der gør det muligt at bygge AI-agenter med forholdsvis lidt kode. exagent og air-agent håndterer LLM-kommunikation og værktøjskald, Chatnificent giver en færdig chat-UI, og openmeteo-py-df leverer typede vejrdata. Start med at få kommunikationen med LLM'en til at virke, byg derefter en enkel chat-grænseflade, og introducer til sidst værktøjet til vejrdata. Når først agenten kan hente og tolke vejrdata, har du et solidt fundament, som du kan udvide med flere værktøjer og mere kompleks logik efter behov.

Klar til at bygge dine egne AI-agenter?

Brug denne viden til at integrere AI i dine systemer og skabe intelligente assistenter, uanset om du koder i PHP eller Python.