OpenAI Responses API för nybörjare: sortera tio meddelanden med strikt JSON

Tio fiktiva kundmeddelanden blev tio JSON-objekt i rätt ordning. Schemat godkändes direkt. Ändå fick den första publiceringskörningen bara 9 av 10 rätt i vår betydelsekontroll: ett trasigt kurslänk för morgondagen hade fått normal prioritet.

Felet satt inte i JSON-formatet. Vår regel för hög prioritet var för luddig. När vi skrev om den till "ett evenemang börjar inom 24 timmar och åtkomsten är blockerad" och körde samma test igen fick vi 10 av 10 matchande kategori- och prioritetspar.

Det är precis därför den här guiden har två kontroller. Structured Outputs begränsar modellens svar till ett JSON-schema som programkod kan läsa. En separat kontroll mot förväntade etiketter avgör om klassificeringen också är rimlig.

Källa: Structured model outputs – OpenAI API.

Vem passar guiden?

Guiden är för dig som har använt AI-chattar och nu vill få ett förutsägbart, maskinläsbart svar från ett API. Du behöver kunna köra en kort Python-fil och läsa JSON, men du behöver inte ha byggt en produktionsintegration.

Det här är inte en guide till kundserviceautomation. Vi stannar före Gmail, CRM, Zapier, svar till kunder och autonoma agenter. Hammer har redan beskrivit den delen i Sluta klistra AI-svar för hand. Här testar vi själva API-kontraktet först.

Det här bygger du

På 15–20 minuter tar du fram:

  • En lokal fil med tio fiktiva meddelanden och tydliga regler.
  • En separat fil med förväntad kategori och prioritet.
  • Ett strikt JSON-schema med obligatoriska fält och tillåtna värden.
  • Ett riktigt svar från POST /v1/responses.
  • Ett kvitto som kontrollerar både struktur och betydelse.

Använd bara påhittade meddelanden i första testet. Då kan du felsöka kontraktet utan att blanda in kunddata eller behörigheter.

Innan du börjar: håll API-nyckeln utanför koden

OpenAI API finns på platform.openai.com. API-tjänsten faktureras och hanteras separat från ChatGPT. Lägg nyckeln i miljövariabeln OPENAI_API_KEY eller i en hemlighetshanterare. Skriv aldrig in den direkt i Python-filen, webbläsarkod, skärmbilder eller Git.

Källa: OpenAI förklarar hur ChatGPT-prenumeration och API-konto skiljer sig åt.

Källa: OpenAI beskriver hur API-nycklar ska hanteras.

Steg 1: skriv regler och förväntade svar först

Vårt test använder fyra kategorier: sales, support, billing och feedback. Prioriteten är antingen high eller normal.

Skriv reglerna innan du skickar något till modellen. Gör sedan expected-labels.json för hand. Den filen är facit för testet. Modellen får inte rätta sitt eget prov.

Var konkret. Efter den första 9/10-körningen ändrade vi regeln för high till:

Ett evenemang börjar inom 24 timmar och åtkomsten är blockerad,
eller en betalning blockerar åtkomsten just nu.

Det gjorde skillnaden mellan meddelandet om en trasig kurslänk och ett vanligt återbetalningsärende tydlig.

Steg 2: bygg ett strikt JSON-schema

Varje svarspost ska ha id, category, urgency och reason. Kategorier och prioritet begränsas med enum. Arrayen ska innehålla exakt tio objekt och additionalProperties: false stoppar extra fält.

schema = \{
    "type": "object",
    "properties": \{
        "items": \{
            "type": "array",
            "minItems": 10,
            "maxItems": 10,
            "items": \{
                "type": "object",
                "properties": \{
                    "id": \{"type": "string"\},
                    "category": \{
                        "type": "string",
                        "enum": ["sales", "support", "billing", "feedback"],
                    \},
                    "urgency": \{
                        "type": "string",
                        "enum": ["high", "normal"],
                    \},
                    "reason": \{"type": "string"\},
                \},
                "required": ["id", "category", "urgency", "reason"],
                "additionalProperties": False,
            \},
        \}
    \},
    "required": ["items"],
    "additionalProperties": False,
\}

Schemat kontrollerar formen. Det kontrollerar inte om modellen har förstått verksamhetens regel.

Steg 3: skicka begäran till Responses API

Den verifierade publiceringskörningen använde modellaliaset gpt-5.6; API:t rapporterade den effektiva modellen gpt-5.6-sol. Modeller och alias ändras, så kontrollera alltid den aktuella modellöversikten innan du använder exemplet i ett riktigt system.


payload = \{
    "model": "gpt-5.6",
    "input": [
        \{
            "role": "system",
            "content": [\{
                "type": "input_text",
                "text": "Följ bara reglerna. Behåll indataordningen och hitta inte på fakta."
            \}],
        \},
        \{
            "role": "user",
            "content": [\{
                "type": "input_text",
                "text": json.dumps(input_data, ensure_ascii=False)
            \}],
        \},
    ],
    "text": \{
        "format": \{
            "type": "json_schema",
            "name": "support_triage",
            "strict": True,
            "schema": schema,
        \}
    \},
    "store": False,
\}

request = urllib.request.Request(
    "https://api.openai.com/v1/responses",
    data=json.dumps(payload).encode(),
    headers=\{
        "Authorization": f"Bearer \{os.environ['OPENAI_API_KEY']\}",
        "Content-Type": "application/json",
    \},
    method="POST",
)

store: false stänger av lagring av Responses application state, men betyder inte nollagring. OpenAI beskriver separata regler för bland annat missbruksövervakning och särskilt godkända Zero Data Retention-kontroller.

Källa: Data controls in the OpenAI platform.

Steg 4: kontrollera strukturen innan du läser svaret

Hantera HTTP-fel, avslag och ofullständiga svar innan du försöker plocka ut output_text. För ett lyckat svar kontrollerar du sedan:

  • Status är completed.
  • Arrayen innehåller exakt tio objekt.
  • Alla tio ID:n finns i samma ordning som i indata.
  • Endast tillåtna kategorier och prioritetsvärden används.
  • Inga oväntade fält har lagts till.

Strikt schema gör den här kontrollen betydligt enklare. Det gör inte kontrollen onödig.

Steg 5: kontrollera betydelsen separat

Jämför varje id med kategori och prioritet i expected-labels.json. Vår slutliga körning gav:

  • 10 objekt och rätt ID-ordning.
  • Endast tillåtna enum-värden.
  • M02 och M06 som hög prioritet.
  • 10 av 10 kategori- och prioritetspar mot facit.
  • 0 avvikelser.

Vi poängsatte inte texten i reason, och schemat mätte inte den önskade ordgränsen där. Skriv inte "allt var korrekt" när testet bara har granskat vissa fält.

Vad strikt JSON inte löser

Regler kan vara tvetydiga. Kundspråk förändras. Ett schema avgör inte vilka uppgifter som får skickas till en extern tjänst, när en människa ska godkänna en åtgärd eller hur ett system ska hantera 401-, 429- och 5xx-fel.

När det lokala testet passerar kan nästa steg vara en avgränsad integration med hemlighetshantering, snäva behörigheter, en godkännandepunkt och en körlogg. Hammer Automations Verktygssmide kan hjälpa ett team att bygga den delen utan att hoppa över testkontraktet.

Vanliga frågor

Vad är Structured Outputs i OpenAI Responses API?

Structured Outputs låter dig begränsa ett modellsvar till ett JSON-schema. Det gör svaret lättare att läsa i kod, men garanterar inte att klassificeringen följer din verksamhetsregel.

Behöver jag en separat API-nyckel om jag har ChatGPT?

Ja. OpenAI API hanteras och faktureras separat från en ChatGPT-prenumeration. Lägg API-nyckeln i en miljövariabel eller hemlighetshanterare, inte i koden.

Varför behövs ett facit när JSON-schemat redan är strikt?

Schemat testar form, antal fält och tillåtna värden. Ett facit testar om varje meddelande fick rätt kategori och prioritet enligt dina skrivna regler.

Kan jag använda riktiga kundmeddelanden direkt?

Börja med fiktiva testfall. Innan riktiga data används behöver du kontrollera rättslig grund, dataminimering, behörigheter, lagringsinställningar och när en människa ska godkänna nästa steg.

Smedjans nyhetsbrev

Få nya artiklar i inkorgen

Välj de ämnen som intresserar dig. Inget brus, max ett mejl i veckan.

Få nya artiklar i inkorgen

Vi följer GDPR. Avsluta när du vill.