Det lærte vi af at lancere med ChatGPT Apps SDK

Praktiske erfaringer med ChatGPT Apps SDK viser, hvornår arkitekturen passer, og hvor der er behov for mere kontrol.

Resumé

  • Apps SDK er en praktisk løsning, hvis du snart skal bruge et workflow i ChatGPT, eller hvis du vil afprøve dine værktøjer dér, før du investerer i din egen agent-stack. Hvis du skal styre hvert eneste trin i agentens adfærd, er det normalt ikke den rette løsning.

  • Vælg Apps SDK, når ChatGPT skal være den primære grænseflade, og du vil have værktøjer samt mindre UI-elementer uden at bygge et komplet chatprodukt. Vælg din egen agent-stack, når du har brug for tæt kontrol over flow, hukommelse, prompts og skrivehandlinger.

  • Apps SDK passer til produkter, der kombinerer chat med nogle få korte UI-trin. Du lancerer hurtigere, men afgiver noget kontrol.

  • Det, der virkede for os, var tydelige værktøjer, tydelig widgetadfærd og tydelige næste trin. Vi brugte dem – ikke LLM'en – til at fastlægge flowet. Modellen var mest nyttig, når den forklarede resultater, som systemet allerede havde valgt.

  • Nedenfor gennemgår vi først, hvordan du vælger, og dernæst hvad der virkede, og hvad der ikke gjorde.

De fleste teams kører stadig AI-pilotprojekter eller bruger AI til perifere formål med lav risiko og begrænset gevinst. Kun få lancerer et forretningskritisk produkt, som brugerne benytter hver uge. ChatGPT Apps SDK er én måde at lukke det hul på, hvis målet er at være til stede i ChatGPT frem for selv at bygge hele assistenten.

Derfor brugte vi Apps SDK

Vores erfaringer stammer fra et kundeprojekt, hvor kravene pegede på ChatGPT som den primære grænseflade og en hurtig løsning, der ikke krævede finansiering af et komplet, skræddersyet chatprodukt.

Apps SDK passede til opgaven, fordi kunden havde brug for:

  • Intet særskilt chatprodukt, der skulle bygges og hostes – de ønskede rækkevidde i ChatGPT, ikke endnu en selvstændig assistentgrænseflade.

  • Chat plus en lille, opgavespecifik brugergrænseflade – nogle få fokuserede widgettrin, ikke endnu et komplet produkt i workflowet.

  • Backendadfærd gjort tilgængelig via MCP-værktøjer – standardiserede værktøjskald, ikke et specialbygget agent-runtime, som de selv ejede fra start til slut.

  • Synlighed i ChatGPT – brugerne skulle møde workflowet dér, hvor de allerede arbejdede.

Vi validerede løbende disse valg med kunden under udviklingen. Afvejningen gælder stadig: Når ChatGPT hoster sessionen, ejer du ikke det ydre runtime. Du kan styre det, men ikke kontrollere det fuldt ud.

Det får du med Apps SDK

En Apps SDK-app forbinder tre ting:

  1. ChatGPT's agent-runtime

  2. Dine MCP-værktøjer

  3. Din widgetgrænseflade

Sådan fungerer flowet i praksis:

  1. Brugeren beder ChatGPT om noget.

  2. ChatGPT kan kalde et af dine MCP-værktøjer.

  3. Din server returnerer et struktureret værktøjsresultat.

  4. ChatGPT læser resultatet og vælger næste trin: flere værktøjskald, et svar til brugeren eller begge dele. Hvis du har knyttet en widget til værktøjet, kan den blive vist i denne runde.

  5. Brugeren fortsætter i chatten eller widgetten med opfølgende tekst, et valg eller et værktøjskald udløst af widgetten. Det opdaterer tråden. ChatGPT kører endnu en runde, og trin 2-4 gentages, indtil opgaven er løst.

Pointen er netop denne kombination af chat, backendhandlinger og korte UI-trin. Det betyder også, at de skrøbelige dele er overleveringerne mellem chat, værktøjer og brugergrænseflade.

Du skal ikke bygge chatgrænseflade, værktøjsintegration, godkendelsesmønstre eller widgetramme fra bunden. For mange produkter reducerer det udviklingstiden markant, så du kan fokusere på domænelogik og sikkerhedsforanstaltninger.

At bygge i ChatGPT er ikke det samme som at drive sin egen agent. Det svære ved projektet var ikke smarte prompttricks. Det var at gøre værktøjer, widgets og næste trin så tydelige, at modellen og brugergrænsefladen forblev afstemt.

Sådan vælger du

Apps SDK giver produktet en anden form end en traditionel frontend, så det er vigtigt at vide, hvilke scenarier løsningen egner sig bedst til.

Brug Apps SDK, når du vil

  • Lancere et ChatGPT-workflow hurtigt.

  • Lade ChatGPT hoste samtalen.

  • Kombinere naturligt sprog med nogle få fokuserede UI-trin.

  • Undgå at bygge din egen chatgrænseflade, agent-container og løsning til synlighed.

Det sidste punkt er vigtigt, når dine brugere allerede arbejder i ChatGPT.

Byg din egen agent, når du har brug for det

  • Et fast trinvist flow, som du kan håndhæve i kode.

  • En tilpasset brugergrænseflade og godkendelsesproces, som du ejer fra start til slut.

  • Din egen model for hukommelse og tilstand.

  • Adfærd, der skal være forudsigelig ved hver kørsel.

  • Sporinger, logfiler og målinger for agenten.

Hvis planlæggeren, systemprompts og hele workflowet udgør dit produkt, passer en specialbygget stack som regel bedre.

Kort overblik over afvejningerne

Spørgsmål

ChatGPT Apps SDK

Dine egne agenter

Hvor foregår brugeroplevelsen?

I ChatGPT

I dit produkt

Hvem styrer samtalens trin?

ChatGPT, styret af dine værktøjer og din brugergrænseflade

Dit agentsystem

Hvor meget brugergrænseflade bygger du?

Fokuserede widgets i chatten

Alt det, du har brug for

Hvor stor kontrol har du over prompts?

Indirekte

Fuld

Hvor nemme er faste flows, der kan gentages?

Kræver omhyggeligt design

Nemmere at håndhæve i kode

Tid til første lancering

Ofte hurtigere

Ofte langsommere i starten

Platformsarbejde, du selv står for

Mindre

Mere

Mulighed for at ændre retning senere

Mindre

Mere

I vores projekt vendte ét ord hele tiden tilbage: kontrol. På den ene side hastighed og en velkendt platform, på den anden side kun delvist ejerskab over runtime-miljøet. Det var den afvejning, kunden accepterede, da de prioriterede at møde brugerne i ChatGPT frem for at eje hele stacken.

Her bliver det svært

Det ideelle flow lyder enkelt: Brugeren spørger, værktøjet kører, data returneres, og widgetten vises, når der skal træffes et valg.

I praksis var overleveringerne problemet. En widget er ikke pynt. Når den først vises, ændrer den, hvad modellen ser og gør som det næste. Behandl widgethandlinger som navngivne hændelser, ikke som løs chat.

Teknologistacken i projektet var enkel: FastMCP, Pydantic, React og TypeScript. Det var uproblematisk at integrere dem. Arbejdet bestod i at få modellen, værktøjerne og brugergrænsefladen til at være enige om næste trin.

Det virkede

Gør hver overlevering tydelig

Vi holdt op med at behandle værktøjsresultater som rå payloads fra backend. Hvert svar blev en overlevering.

Et godt værktøjsresultat:

  • Giver widgetten det, den skal bruge for at blive gengivet.

  • Giver ChatGPT strukturerede fakta at basere svaret på.

  • Angiver om nødvendigt næste trin, så modellen ikke behøver at gætte.

Widgethandlinger bør ikke sende uklar prosa tilbage til tråden. De bør angive, hvad brugeren gjorde, og hvad der skal ske bagefter.

Pålideligheden steg, da overleveringerne blev tydelige.

Modellen følger korte, tydelige instruktioner, når de står i værktøjets output og i widgethandlingerne.

Nedenfor ses en lille Pydantic-struktur, som vi brugte. Feltet output indeholder de strukturerede data, som widgetten skal bruge, når den vises, samt de fakta, ChatGPT skal bruge i sessionen. Feltet agent_directions indeholder en kort linje, der angiver, hvad assistenten skal gøre som det næste. Reason er valgfrit.

Python

from typing import Generic, TypeVar
from pydantic import BaseModel
T = TypeVar("T")
class AgentDirections(BaseModel): assistant_instruction: str reason: str | None = None
class ToolResults(BaseModel, Generic[T]): agent_directions: AgentDirections output: T

Hold widgets små

De widgets, der fungerede, håndterede én beslutning og gav derefter kontrollen tilbage. Korte lister, bekræftelser eller en enkel oversigt fungerede bedre end at gøre widgetten til en miniapp. Lidt logik i widgetten, f.eks. enkel validering eller et fast næste trin, hjalp stadig, når vi ønskede et mere deterministisk flow.

Tredjeperson i widgetbeskeder

Vi holdt op med at skrive widgetopfølgninger som chatbeskeder fra brugeren (»Jeg valgte …«, »Jeg bekræftede …«). Vi skrev dem som korte rapporter om brugerens handlinger (»Brugeren valgte …«, »Brugeren bekræftede …«). Vi afprøvede denne tilgang, fordi ChatGPT tilføjede widgetbeskeder som værktøjsbeskeder i stedet for brugerbeskeder.

Direkte handlinger, når næste trin er oplagt

Hvis en knap tydeligt indebærer det næste værktøjskald, fungerede det bedre at lade widgetten udløse det direkte end at gennemtvinge endnu en chatrunde. Det gælder kun, hvis det næste værktøjskald ikke kræver input fra ChatGPT.

Det gjorde det lettere at håndhæve deterministiske flows og reducerede samtidig svartiden ved at undgå endnu en chatrunde.

Fejlhåndtering

Når et værktøjskald mislykkedes, returnerede vi de korrekte MCP-fejlkoder og korte, tydelige beskeder fra værktøjet. ChatGPT fik dermed konkrete oplysninger om mislykkede kald og kunne forklare problemet for brugeren og/eller vælge et fornuftigt næste trin.

Håndtering af værktøjskontekst

Vi opbevarede sessionstilstanden på vores server. ChatGPT sender sessionsafgrænset kontekst med værktøjskald. I FastMCP gav vi hvert værktøj en Context-parameter, så handleren kunne læse og opdatere tilstanden.

  • Stabile id'er og tidligere resultater blev gemt i sessionen, så ChatGPT ikke skulle sende dem igen som værktøjsargumenter ved hvert kald.

  • Når der opstod løkker af værktøjskald, kunne vi opfange dubletter og returnere en tydelig fejl via værktøjsresultatet.

  • Sessionslogfilerne blev hos os til fejlfinding og support.

Hvad der ikke virkede

At antage, at modellen kunne udlede næste trin

I begyndelsen viste vi en widget, antog, at modellen »forstod det«, og ventede på det rigtige opfølgende værktøjskald. Nogle gange skete det. Ofte gjorde det ikke.

Uden en tydelig overlevering kunne ChatGPT opsummere, når vi ønskede en handling, bede brugeren gentage et valg eller fortsætte planlægningen, når den burde være stoppet.

Løsningen var at angive næste trin tydeligt i strukturerede outputs og widget-payloads frem for at håbe, at modellen kunne udlede det.

At sprede betydningen på tværs af lag

Vi forsøgte at være smarte ved at opdele svarene mellem værktøjets output, skjulte metadata og chattekst som beskrevet i dokumentationen til Apps SDK. Men vi kunne ikke læse de skjulte metadata i widgetterne. Derfor kunne vi ikke bruge denne løsning.

At skjule værktøjer for modellen

Dokumentationen til Apps SDK beskriver værktøjer, som kan holdes væk fra agentens værktøjsliste, så den ikke vælger dem, mens widgetten stadig kan kalde dem. Da vi satte synligheden til app-only, blev værktøjerne også utilgængelige fra widgetten – ikke kun fra agenten. Det lykkedes os aldrig at finde en opsætning, hvor agenten ikke kunne se et værktøj, men widgetten stadig kunne.

Utydelige fejl

Tavshed eller en generisk »fuldført«-besked, når der ikke var sket noget nyttigt, var værre end en direkte fejl. Derfor behandlede vi værktøjs- og widgetfejl som selvstændige outputs: Hvis et trin ikke kunne fortsætte, forklarede vi det tydeligt og returnerede en eksplicit fejl frem for at efterlade brugeren med en widget, der blev vist uden at føre processen videre. Det forbedrede brugervenligheden og gjorde modellens adfærd mere pålidelig.

Afsluttende betragtninger

Hvis målet er et workflow i ChatGPT med mindre specialbygget platformsarbejde, er Apps SDK en praktisk vej dertil. Du afgiver noget kontrol til gengæld for hastighed og muligheden for at møde brugerne dér, hvor de allerede arbejder.

Hvis du skal eje hver gren af flowet, brugergrænsefladen og beslutningen om hvert trin, bør du planlægge din egen agent-stack fra begyndelsen. Du vil sandsynligvis vokse fra udelukkende at bygge i ChatGPT.

Du kan også bruge Apps SDK til at køre din MCP-server i ChatGPT, før du selv bygger chat, godkendelse og agent-infrastruktur, og senere flytte til din egen stack, når produktet kræver det.

Næste skridt for teams i samme situation er at vælge ét workflow med et tydeligt resultat, beskrive overleveringerne mellem chat, værktøjer og widgets og derefter stressteste gentagne forsøg og fejl, før I bruger meget tid på at finjustere prompts.

Forfatter

Malan Evans