Hoppa till huvudinnehållet

Jev API-handledning: Bygg en biljett-router med TypeSafe AI:s System One-modell

Lär dig hur du sätter upp TypeSafe AI:s Python-SDK, ställer Choice-, Score- och Noul-frågor i ett enda anrop, bygger en supportbiljett-router som behåller dirigeringspolicyn i din egen kod och tar reda på var Jev går sönder innan du skeppar den.
Uppdaterad 24 sep. 2026  · 15 min läsa

Utforska med AI

ChatGPTClaudePerplexity

Det har pratats mycket om Jev, TypeSafe AI:s System One-modell, sedan den släpptes förra veckan: jag såg många som hypade den och många andra som dissade den, och sanningen ligger förmodligen någonstans mitt emellan, beroende på vad du förväntar dig av modellen. Jag var väldigt nyfiken på att prova den och fick äntligen förhandsåtkomst tidigare i veckan. 

I den här handledningen visar jag hur du sätter upp Jev via deras Python-SDK, använder Jevs tre olika frågetyper och bygger ett lager för biljett­dirigering – ett användningsfall som spelar på modellens styrkor. Vi går också igenom var Jev har det svårt, och vad en System One-modell är om du undrar över begreppet.

Bygger du med modell-API:er i Python? Developing LLM Applications with LangChain täcker den generativa sidan av samma stack – prompts, kedjor och agenter.

TL;DR

Jev är TypeSafe AI:s System One-modell. Den genererar inte text. Du skickar in tillstånd plus typade frågor, den returnerar typade svar med sannolikheter, och din kod avgör vad som händer härnäst.

  • Tre frågetyper. Choice väljer ett alternativ ur en uppsättning. Score betygsätter mot ordnade nivåer. Noul returnerar en ja/nej-sannolikhet.
  • Frågorna körs parallellt. Sex frågor kostar ett anrop och knappt mer latens än en, så du frågar allt du kan tänkas behöva.
  • Självförtroendet är den användbara delen. Det låter dig bygga tre vägar: automatisera, lämna till en människa, falla igenom.
  • Den kan inte räkna, kan inte göra datumberäkningar och läser dina frågor bokstavligt. TypeSafe publicerar de taggiga kanterna, och de spelar roll.

Vi bygger en supportbiljett-router i ett enda anrop och tittar sedan på var Jev går sönder.

Varför genererar inte Jev text?

Jag nämnde redan att förväntningarna måste matcha modellen. Det gäller särskilt för Jev, och det handlar mest om dess modellklass, som kallas System One-modeller.

System One-modeller besvarar typade beslut i stället för tokens

En System One-modell returnerar typade beslut i stället för text. Du skickar ett block med tillstånd plus en uppsättning frågor, var och en med ett svarsutrymme du definierar, och modellen returnerar ett svar per fråga med sannolikheter. Inget produceras token för token, så det finns ingen sträng att parsa och inget felaktigt JSON att reparera. TypeSafe myntade termen med hänvisning till Daniel Kahnemans kända uppdelning:

  • System 1-tänkande: snabb, intuitiv bedömning
  • System 2-tänkande: långsam, övervägd slutledning

Eftersom svarsutrymmet är ett schema din kod deklarerar kan System One-modeller per design aldrig returnera en kategori du inte har definierat. Det betyder att den aldrig kan vara utanför schemat. Däremot kan den fortfarande ha fel, och vi kommer till några knepiga fall senare.

Var Jev står

TypeSafe kom ut ur stealth den 15 september 2026 med Jev i tidig åtkomst, med 70 till 500 ms svarstider och $0,042 per miljon inmatningstoken med gratis utdata. På sin egen fyrarbetsflödes-benchmark landar Jev kring 68% noggrannhet, ungefär i mellanskiktet för LLM:er till en bråkdel av kostnaden. 

För mer information om funktioner och benchmarkresultat rekommenderar jag att du läser vår Jev-guide.

När du ska välja Jev i stället för en LLM

Skriv ner de giltiga svaren innan du gör anropet. Om du kan räkna upp dem har du ett Jev-format problem:

  • Dirigering: vilken av sex köer, vilken hanterare, vilken modell
  • Filtrering: Är den här passagen relevant? Är detta ett jailbreak-försök?
  • Betygsättning mot en rubric: hur allvarligt, hur brådskande, hur komplett
  • Gating: kör det dyra steget eller hoppa över det

Välj en LLM när utdata är prosa eller kod, när svarsutrymmet är öppet eller när uppgiften kräver flera steg av kedjad slutledning. Jev är också fel verktyg för allt numeriskt, och jag återkommer till varför senare.

Inspektera frågetyperna i TypeSafe AI Playground

Innan du skriver någon kod, skapa ett TypeSafe-konto och öppna Playground. Här kan du klistra in text som tillstånd, lägga till frågor och se hela svarobjekten utan att installera något. Det är det snabbaste sättet att förstå vad varje frågetyp returnerar (och att ta reda på om din fråga är dåligt formulerad).

Jag använder en supportbiljett som tillstånd för alla tre exemplen:

Export to CSV has been broken since Friday. 
It works in Chrome, but half our team is on Safari and they can't pull reports at all. 
We have a board meeting Thursday.

Varje frågetyp tar instructions, den vardagliga formuleringen av frågan du vill få besvarad. Det som skiljer dem åt är criteria och vad som kommer tillbaka.

Choice för kategorisk dirigering

En Choice väljer ett alternativ från en uppsättning du definierar. 

Du skickar criteria som ett dictionary-objekt som mappar varje alternativ till en beskrivning, allt från 1 till 255 stycken, och svaret kommer tillbaka med: 

  • Det vinnande alternativet
  • En sannolikhet för varje alternativ
  • Ett confidence-värde
{
  "department": {
    "type": "choice",
    "instructions": "Which queue should own this ticket?",
    "criteria": {
      "bug_triage": "A defect in a specific feature, reproducible, goes into the backlog",
      "incident_response": "A live breakage affecting multiple users right now, needs a responder today",
      "customer_success": "The account needs managing, not the code"
    }
  }
}

För att se kodutdata som du också skulle få via API, klicka på </>-knappen uppe till höger och klicka på Run för att låta Jev svara på frågan.

Testar en Choice-fråga för Jev i TypeSafe playground

I det här fallet är incident_response choice med 91% sannolikhet. Jevs confidence för valet är 86%.

Den fulla fördelningen är delen som förtjänar din uppmärksamhet. 

  • choice berättar bara vilket alternativ som vann.

  • probabilities berättar med hur mycket.

Det är olika informationsbitar när du ska dirigera en biljett automatiskt. En 0,41/0,38/0,21-fördelning och 0,91/0,09/0 vi fick kan båda returnera samma choice.

Score för ordnade rubrics

En Score betygsätter tillståndet mot ordnade nivåer. Du skickar criteria som en array med 2 till 10 nivåbeskrivningar, lägsta först, och svaret inkluderar en poäng, en legend som mappar varje position till din beskrivning, en sannolikhet per nivå och confidence.

{
  "goodwill_risk": {
    "type": "score",
    "instructions": "How much patience does this customer have left?",
    "criteria": [
      "Reporting a problem, no sign of frustration",
      "Mildly annoyed, still collaborative",
      "Visibly out of patience, mentions the cost to their work",
      "At the point of escalating over our heads or leaving"
    ]
  }
}

Testar en Score-fråga för Jev i TypeSafe playground

Poängen kan landa mellan dina nivåer, och det är hela poängen med legend. En score på 1,93 här betyder att modellen är delad mellan ”milt irriterad” och ”tydligt otålig”, med stark lutning mot det senare, vilket är en rimlig tolkning av en biljett som förblir artig men nämner en deadline den kommer att missa. 

Läs återigen spridningen av probabilities i stället för bara siffran: koncentrerad sannolikhet på en nivå betyder ett avgörande svar, utsmetad över tre betyder att du fick ett medelvärde i stället för en bedömning.

Noul för ja/nej-sannolikheter

En Noul är typen för binära frågor, och namnet myntades av TypeSafe. criteria är valfritt här, men du kan beskriva vad true och false betyder, vilket är värt att göra när ”ja” kan tolkas på två sätt.

Formulera frågan så att ett högt värde betyder ja. TypeSafes dokumentation är tydlig med detta, och en Noul vars true mappar till ”nej” presterar mätbart sämre.

{
  "is_time_sensitive": {
    "type": "noul",
    "instructions": "The customer names a specific deadline",
    "criteria": {
      "true": "A date, day, or event the work must be done before",
      "false": "Urgency is implied but no deadline is given"
    }
  }
}

Testar en Noul-fråga för Jev i TypeSafe playground

Eftersom ett styrelsemöte på torsdag nämns i tillståndet var det höga noul-värdet 0,97 väntat.

Varför har en Noul inget confidence-fält?

Choice och Score returnerar confidence tillsammans med sina sannolikheter. En Noul gör inte det, och det snubblar folk på, så det är värt att vara exakt med varför.

Confidence och sannolikhet är separata axlar. För en Choice säger sannolikheter hur modellen fördelar tro över dina alternativ, och confidence säger hur fast den håller vid svaret, vilket är varför en Choice kan returnera ett toppalternativ på 0,85 med confidence 0,78. En Noul har bara två utfall, så den enda sannolikheten bär redan båda: 0,97 är ett säkert ja, 0,03 är ett säkert nej och 0,52 är att modellen säger att den inte har någon aning.

Det betyder att avståndet från 0,5 är din beslutsamhetssignal, inte ett separat fält att läsa. Det betyder också att du inte kan porta en tröskel från en Noul till en Choice, och jag återkommer till det i avsnittet om taggighet, för det biter hårdare än det låter.

Sätta upp Jev Python SDK

För att följa med behöver du bara Python 3.10+ och en TypeSafe-nyckel för tidig åtkomst.

Installera SDK:t

Installera SDK:t:

pip install typesafe-sdk

Eller med uv:

uv add typesafe-sdk

Exportera din nyckel

Skapa sedan en nyckel i TypeSafe-konsolen och exportera den. Klienten läser TYPESAFE_API_KEY från miljön, så du skickar den aldrig i kod:

export TYPESAFE_API_KEY="your-key"

Importera svarstyper och klienten

Följande importer ger dig allt från playgrounden:

from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

client = TypeSafeClient()

Choice, Noul och Score är samma frågetyper du just klickade igenom, som Python-objekt. 

Använda TypeSafeClient

TypeSafeClient är den synkrona klienten, och det finns en AsyncTypeSafeClient med samma gränssnitt om du anropar Jev från en asynkron tjänst. Båda fungerar som context managers, vilket är vad jag skulle använda i allt längre än ett skript:

with TypeSafeClient() as client:
    ...

Pinna Jevs version

Lämnad ifred anropar klienten jev-latest, som flyttar när TypeSafe släpper en ny version, vilket är vad vi använder genom hela handledningen. För allt där du redan har trimmat en tröskel, pinna i stället versionen:

client = TypeSafeClient(model="jev-1.13.0")

Svaret talar om vilken modell som faktiskt svarade oavsett, och det finns ett avsnitt mot slutet om varför du bör logga det.

Göra ditt första Jev API-anrop

För att göra ett API-anrop till Jev behöver du definiera ett response-objekt med TypeSafeClient och funktionen system_one(), som tar din frågekontext som parametern state och själva questions i samma format som i playgrounden. 

Vi kan skapa ett enda anrop som besvarar alla våra tre playgroundfrågor, eftersom de delar samma state:

from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

ticket = (
    "Export to CSV has been broken since Friday. It works in Chrome, "
    "but half our team is on Safari and they can't pull reports at all. "
    "We have a board meeting Thursday."
)

with TypeSafeClient() as client:
    response = client.system_one(
        state=ticket,
        questions={
            "queue": Choice(
                instructions="Which queue should own this ticket",
                criteria={
                    "bug_triage": "A defect in a specific feature, reproducible, goes into the backlog",
                    "incident_response": "A live breakage affecting multiple users right now, needs a responder today",
                    "customer_success": "The account needs managing, not the code",
                },
            ),
            "goodwill_risk": Score(
                instructions="How much patience does this customer have left",
                criteria=[
                    "Reporting a problem, no sign of frustration",
                    "Mildly annoyed, still collaborative",
                    "Visibly out of patience, mentions the cost to their work",
                    "At the point of escalating over our heads or leaving",
                ],
            ),
            "is_time_sensitive": Noul(
                instructions="The customer names a specific deadline",
                criteria={
                    "true": "A date, day, or event the work must be done before",
                    "false": "Urgency is implied but no deadline is given",
                },
            ),
        },
    )

Svar kommer tillbaka under samma namn du valde för varje fråga, vilket är detaljen som gör hela grejen trevlig att jobba med:

print(response.model)
print(response.answers["queue"].choice, response.answers["queue"].confidence)
print(response.answers["goodwill_risk"].score)
print(response.answers["is_time_sensitive"].noul)
jev-1.13.0
Incidence_response 0.95
1.95
0.97

Felsöka TypeErrors

Om ditt första anrop misslyckas med en TypeError om output_buffer_limit: det är en versions­mismatch i SDK:ns komprimeringsbackend, inte din kod. SDK:t skickar med sin egen HTTP-klient, httpx2, som dekomprimerar svar via zstandard och brotli, och en äldre kopia av endera saknar argumentet den anropas med. pip install -U typesafe-sdk httpx2 zstandard brotli löste det för mig.

Vad utdata berättar

Två saker i den utdata är värda att stanna upp vid.

För det första returnerade response.model jev-1.13.0, inte jev-latest. Du bad om den rörliga aliasen och Jev berättade vilken version som faktiskt svarade, vilket är den enda anledningen att logga det fältet är billigt nog för att vara värt det.

För det andra är svarobjekten typade per frågetyp, så .choice, .score och .noul är riktiga attribut och din editor känner till dem. Det finns ingen JSON-sträng någonstans i den här koden, inget att parsa och ingen gren för anropet som kom tillbaka felaktigt. Om du föredrar gruppering exponerar SDK:t också response.choices, response.scores och response.nouls, nycklade på samma sätt.

Kolla också response.usage:

print(response.usage.input_tokens, response.usage.output_tokens)
524
78

Utdata-token är ensiffriga och gratis. Du betalar för tillståndet och frågorna, så du kan helt styra kostnadsreglaget genom att avgöra hur mycket kontext du skickar. Det spelar större roll än det ser ut och kommer upp igen i taggighetsavsnittet: ett uppsvällt tillstånd kostar dig både pengar och noggrannhet samtidigt.

Bygga en biljett-router i ett Jev-anrop

Detta är ett av de användningsfall Jev är byggd för. En supportbiljett anländer, och något måste avgöra vilken kö den ska till, om en människa ska titta först och hur snabbt. Var och en av dessa är en bedömning med ett svarsutrymme du kan skriva ner innan biljetten anländer.

Designregeln som är värd att säga direkt: Jev avgör vad som är fallet, din kod avgör vad som händer. Jev dirigerar aldrig något. Den returnerar siffror, och dirigeringen lever i en vanlig funktion du kan läsa, testa och ändra utan att röra modellen.

Ställa alla frågor i ett anrop

Frågor i ett enda anrop utvärderas parallellt, så en sjätte fråga kostar dig tokenen den är skriven i och nästan ingen extra latens. Det ändrar hur du frågar. Med en LLM skulle du batcha noga för att spara tur-och-retur-tid, men här frågar du allt du kan tänkas vilja veta om en viss kontext, inklusive frågor du troligen ignorerar.

Låt oss utöka våra tidigare frågor med tre ytterligare Noul som ger oss viktig information om hur biljetten ska hanteras:

  • Innehåller biljetten tillräcklig information för att reproducera problemet?
  • Nämner den förlorade intäkter eller extra kostnader kopplade till problemet?
  • Behöver biljetten ett mänskligt svar?
QUESTIONS = {
    "queue": Choice(
        instructions="Which queue should own this ticket",
        criteria={
            "bug_triage": "A defect in a specific feature, reproducible, goes into the backlog",
            "incident_response": "A live breakage affecting multiple users right now, needs a responder today",
            "customer_success": "The account needs managing, not the code",
        },
    ),
    "goodwill_risk": Score(
        instructions="How much patience does this customer have left",
        criteria=[
            "Reporting a problem, no sign of frustration",
            "Mildly annoyed, still collaborative",
            "Visibly out of patience, mentions the cost to their work",
            "At the point of escalating over our heads or leaving",
        ],
    ),
    "is_time_sensitive": Noul(
        instructions="The customer names a specific deadline",
        criteria={
            "true": "A date, day, or event the work must be done before",
            "false": "Urgency is implied but no deadline is given",
        },
    ),
    "has_reproduction": Noul(
        instructions="The ticket contains enough detail to reproduce the problem",
    ),
    "mentions_money": Noul(
        instructions="The customer mentions lost revenue, refunds, or cancelling",
    ),
    "is_automated": Noul(
        instructions="This ticket is a machine-generated notification, not a person writing in",
    ),
}

with TypeSafeClient() as client:
    response = client.system_one(state=ticket, questions=QUESTIONS)

Sex frågor, alla besvarade i ett anrop och en faktura. is_automated är den spekulativa: den är falsk på nästan alla riktiga biljetter, och den är värd att ställa ändå eftersom den enda gången den är sann sparar den en person från att öppna en mailer-daemon-bounce. 

Två vanor jag skulle ta till mig här. 

  • Behåll frågeuppsättningen som en modulkonstant i stället för att bygga den inline, eftersom det är den du versionshanterar tillsammans med dina trösklar. 

  • Och namnge frågor efter vad de mäter, inte vad du gör med svaret, eftersom is_time_sensitive överlever en policyändring och route_to_incident gör det inte.

  • Formulera frågor positivt: Vi hade också kunnat kalla is_automated något i stil med needs_no_reply, men enligt TypeSafe är prestandan bättre för positivt formulerade frågor.

Göra svar till åtgärder med självsäkerhetströsklar

Nu kommer delen Jev inte gör. Varje svar kommer med antingen ett confidence-värde eller en sannolikhet, och det där andra talet är vad som låter dig bygga tre vägar i stället för två:

  • Hög confidence: agera automatiskt
  • Mellanband: skicka till en människa, med modellens svar bifogat som förslag
  • Allt som policyn inte täcker: falla igenom till standardkön

Jev avgör vad. Din kod avgör vad som händer.

Låt oss översätta det till ett par regler för dirigering av biljetter:

  • Om biljetten sannolikt är maskin­genererad, arkivera biljetten och agera automatiskt
  • Om kunden verkar frustrerad och nämner ekonomiska förluster, skicka biljetten till en människa i customer success-teamet
  • Om modellen inte är tillräckligt säker på vilken kö som gäller, skicka den till en människa i den mest sannolika kön
  • Om biljetten sannolikt är brådskande, markera den för hantering idag
AUTO_ROUTE_CONFIDENCE = 0.75
YES = 0.8
FRUSTRATED = 2.0

def route(answers):
    if answers["is_automated"].noul > YES:
        return "archive", "auto"

    queue = answers["queue"]
    urgent = answers["is_time_sensitive"].noul > YES
    unhappy = answers["goodwill_risk"].score >= FRUSTRATED

    if unhappy and answers["mentions_money"].noul > YES:
        return "customer_success", "human_first"

    if queue.confidence < AUTO_ROUTE_CONFIDENCE:
        return queue.choice, "human_first"

    priority = "today" if urgent else "normal"
    return queue.choice, priority

Läs vad den funktionen gör. Modellen gav sex bedömningar, och policyn bestämde att en av dem, mentions_money korsad med en frustrerad kund, väger tyngre än den kö Jev valde. Den override:n är ett affärsbeslut, den hör hemma i kod, och du kan ändra den en fredagseftermiddag utan att återtesta en modell.

has_reproduction används aldrig. Jag lämnade den kvar med flit, för det är så fan-out-mönstret ser ut i praktiken: du frågar efter mer än vad den aktuella policyn konsumerar, loggar allt och när någon frågar om bug_triage-biljetter utan reprosteg tar längre tid att stänga har du redan sex veckors svar.

Trösklarna ovan är bara exempel. Att hitta rätt är en fråga om kalibrering, och det finns ett avsnitt i slutet om hur du sätter dem med data i stället för känsla.

Köra skriptet

Du kan komma åt hela skriptet från det medföljande GitHub-repot. När jag körde Python-skriptet med vårt scenario blev bedömningen att skicka biljetten till incident response-teamet idag.

python routing.py
('incident_response', 'today')

Var Jev går sönder: Läsning av taggighetslistan

TypeSafe publicerar en taggighets­sida per modellversion som listar de felmoder man känner till. Jag önskar att fler labb gjorde detta. Läs den innan du bygger något, och läs den igen när du uppgraderar, eftersom listan är versionshanterad och kanterna flyttar sig.

Här är de fem som skulle ha kostat mig mest tid.

Noul och Choice är inte överens

Du kan inte porta en tröskel mellan frågetyper. TypeSafes eget exempel frågar ”Ber kunden om återbetalning?” på båda sätten på samma biljett: Noul returnerar 0,22, Choice med ja/nej returnerar 0,01 för ja, med 0,97 i confidence. Samma fråga, två tal, två tiopotenser isär.

Negationer samarbetar inte heller. En Noul och dess motsats kom tillbaka på 0,72 och 0,47, vilket summerar till 1,19.

Anledningen är att de två typerna frågar efter olika saker. En Choice är relativ och avgör vilket alternativ som vinner, medan varje Noul är absolut och kan vara låg för dem alla. Trimma trösklar per fråga, i den form du skeppar, och anta aldrig att P(yes) och 1 - P(no) är samma tal.

En Score är en rang, inte en mätning

Score-nivåer är ordnade, inte jämnt fördelade. En 1,6 berättar att modellen ligger mellan din andra och tredje nivå, med lutning mot den tredje, och det är allt den berättar.

Vad du inte kan göra är att interpolera en verklig kvantitet ur den. Om dina nivåer är ”under en timme”, ”några timmar” och ”en dag” betyder inte 1,5 fem timmar. Använd poängen för att testa en tröskel och behåll sedan varje faktisk siffra i kod.

Tillståndet kan argumentera för sitt eget svar

Jev behandlar tillståndet som data, men är inte härdat mot kod i tillståndet som styr in det. En injicerad instruktion, en missvisande inramning eller text som argumenterar för sin egen klassificering kan flytta svaret, och TypeSafe säger att man förväntar sig förbättringar här. Om attackytan är ny för dig täcker vi the allmänna fallet i vår guide till prompt injection.

Det spelar störst roll där tillståndet är användarinlämnat, vilket för en biljett-router alltid är fallet. Skriv kriterier tillräckligt precisa så att biljettens egna påståenden om sig själv inte avgör utfallet, och testa med fientliga indata innan du dirigerar något automatiskt.

Jev kan inte räkna, göra datum- eller talberäkningar

Räkning är opålitligt och blir sämre ju större det som räknas är, eftersom modellen känner igen formen på ett svar snarare än summerar. Datum läses som text, så ordning, avstånd och fönster fallerar. Numeriska kodningar underpresterar sina semantiska motsvarigheter, så fråga om ”röd” i stället för #FF0000.

Fixen är densamma i alla tre fallen: dela upp arbetet

  • Extraktion är en bedömning, så ge den till Jev som en Choice över uppräknade alternativ. 
  • Behåll aritmetiken endast i kod.

Om du behöver en räkning, iterera i kod och ställ en Noul per objekt:

count = sum(
    result.nouls[f"item_{i}"].noul > 0.5
    for i in range(len(items))
)

Bokstavlig läsning, indirection och utfyllt tillstånd

Tre mindre som delar orsak. Jev besvarar frågan du skrev, inte den du menade, så avgränsande ord och negationer läses bokstavligt. Dubbla negationer och frågor om en egenskap hos en egenskap kostar noggrannhet. Och ett stort tillstånd utfyllt med irrelevant detalj kostar både noggrannhet och pengar, eftersom orelaterat material fungerar som distraktor.

Tecknet på det första: när du tittar på ett fel svar och kommer på dig själv med att förklara vad du egentligen menade, då är den förklaringen den saknade halvan av din instruktion.

Vad du ska göra innan du sätter Jev i produktion

Baserat på det vi redan lärt oss kommer här några bästa praxis för att få ut det mesta av Jev.

Skriva frågor som Jev svarar bra på

Skriv villkoret i stället för avsikten. Om du förklarar vad du menade när du granskar ett fel svar, hör den förklaringen hemma i instruktionerna. Det innebär:

  • Begränsa dig till en bedömning per fråga.
  • Välj kriterier som täcker gränsfallen.
  • Välj en formulering där ett högt värde betyder ja. 
  • Skicka bara det tillstånd frågan behöver.

Pinna en version och logga vad Jev svarade

jev-latest rör på sig. Pinna versionen när en tröskel beror på modellbeteende:

client = TypeSafeClient(model="jev-1.13.0")

Logga response.model tillsammans med fullständiga svar vid varje anrop, inte bara värdet du agerade på. När en tröskel börjar bete sig annorlunda är den loggen det enda sättet att skilja en modellförändring från drift i dina biljetter.

Testa trösklar innan du litar på dem

Slutligen är trösklar inte givna utan resultatet av experiment.

  • Samla in 20 eller fler riktiga biljetter med de svar du hade velat ha. Kör Jev vid sidan av din befintliga dirigering utan att ändra beteende, och jämför.
  • Fixa frågorna först, trösklarna sen. Automatisera sedan den billigaste vägen att få fel och lämna resten till en människa.
  • Versionshantera frågor, kriterier och trösklar tillsammans. Re-spela uppsättningen när något av de tre ändras.

Avslutande tankar

Jev är ett smalt verktyg, och det är faktiskt poängen. Det besvarar frågor vars svar du kan räkna upp, billigt nog att du slutar ransonera dem, och lämnar beslutet tillbaka till din kod.

Det jag vill invända mot är inramningen ”kan inte hallucinera”. Det är sant i snäv mening att modellen inte kan svara utanför schemat, men det säger ingenting om huruvida svaret är rätt. En Choice returnerar alltid en giltig kö. Det kan fortfarande vara fel kö vid 0,9 i confidence, och typade utdata gör det felet tystare.

För att testa den för ditt eget arbete föreslår jag att du hittar ett beslut din kod fattar med en spröd regel eller ett långsamt LLM-anrop och försöker skriva ner de giltiga svaren. Om du kan, är det Jev-format. Om du inte kan, kommer ingen mängd fråge­ingenjörskonst ändra det.

Om du vill komma igång med att bygga system som använder AI rekommenderar jag varmt att registrera dig på vår Associate AI Engineer for Developers-karriärspår. Det lär dig arbeta med OpenAI API, MCP, LangChain och mycket mer.

FAQs

Vilken Jev-frågetyp ska jag använda?

Choice när du kan räkna upp alternativen, Score när svaren bildar ordnade nivåer, Noul för ett enda ja/nej. Tumregeln: om svaren har en ordning, använd Score, eftersom en Choice kastar bort den ordningen. Om du märker att du skriver en Choice med alternativ som ”låg”, ”medel”, ”hög”, vill du ha en Score.

Kan jag ställa flera frågor till Jev i ett och samma API-anrop?

Ja, och det bör du. Frågor i ett enda anrop utvärderas i ett parallellt svep, så en sjätte fråga kostar tokenen den är skriven i och nästan ingen extra latens. Du betalar för tillståndet en gång i stället för en gång per fråga, vilket gör det billigare att fråga allt du kan tänkas vilja ha och ignorera svaren du inte använder.

Returnerar en Noul ett confidence-värde?

Nej. Choice- och Score-svar inkluderar ett confidence-fält, men en Noul returnerar bara sannolikheten, eftersom det med två utfall redan täcks av det enda talet. Hur långt värdet ligger från 0,5 är din beslutsamhetssignal, så 0,97 är ett säkert ja och 0,52 betyder att modellen inte har någon aning.

Kan Jev räkna eller göra aritmetik?

Nej. Räkning är opålitligt och blir sämre ju större antalet blir, datum läses som text snarare än ordnade värden, och numeriska kodningar underpresterar sina vardagliga motsvarigheter. Dela upp arbetet: låt Jev göra bedömningen och behåll aritmetiken i din egen kod.

Ska jag pinna Jev-modellens version?

Ja, när någon tröskel i din kod beror på modellbeteende. jev-latest rör sig när TypeSafe skeppar en ny version, och TypeSafe publicerar en separat taggighetslista per version, så felmoder ändras också. Skicka in en explicit version till klienten och logga response.model vid varje anrop.

Ämnen
Artificiell intelligens

Lär dig AI Engineering med DataCamp!

track

Associate AI Engineer för utvecklare

26 timmar
Lär dig hur du integrerar AI i mjukvaruapplikationer med hjälp av API:er och bibliotek med öppen källkod. Börja din resa mot att bli AI Engineer idag!
Se detaljerRight Arrow
Starta Kursen
Se merRight Arrow