Siirtymä ”LLM-keskustelubotista” ”työtä tekeväksi LLM-pohjaiseksi järjestelmäksi” tapahtuu rakenteisten tuotosten ja funktiokutsujen kerroksessa. Siinä LLM lakkaa tuottamasta pelkkää proosaa ja alkaa tuottaa tietoa, tehdä toimintapäätöksiä ja integroitua muuhun infrastruktuuriin.
Tuotannossa ”rakenteinen tuotos” ei tarkoita sitä, että ”JSON-tila toimi kerran testissäni”. Se tarkoittaa vankkaa putkea, joka käsittelee mallien vaihtelua, virheellisesti muotoiltuja tuotoksia, osittaisia epäonnistumisia, skeemojen kehittymistä ja ohjeita epätäydellisesti noudattavien LLM-mallien arkista todellisuutta.
Tämä artikkeli käsittelee tuotantototeutuksen tarvitsemia hallintakeinoja. Rajapintoja koskevat väitteet ja rajoitukset tarkistettiin 4. elokuuta 2026 virallisista OpenAI:n rakenteisten tuotosten ohjeista, Clauden rakenteisten tuotosten ohjeista ja Geminin rakenteisten tuotosten ohjeista. Esimerkit ovat suunnittelumalleja, eivät AIExpertin vertailutestin tuloksia.
Kaksi toimintatapaa
Kyse on kahdesta toisiinsa liittyvästä mutta erillisestä kyvykkyydestä:
Rakenteinen tuotos: LLM tuottaa skeeman mukaista sisältöä, tavallisesti JSON-muodossa. Tätä käytetään, kun LLM:n vastaus tarvitaan ohjelmallisesti käsiteltävässä muodossa.
Funktio- tai työkalukutsu: LLM saa joukon kutsuttavia funktioita, päättää, mitä niistä kutsutaan, jos mitään, ja tuottaa kutsun parametrit. Isäntäjärjestelmä suorittaa funktion ja palauttaa tulokset. LLM voi kutsua lisää funktioita tai tuottaa lopullisen vastauksen.
Mallirajapinnat tarjoavat nämä yleensä seuraavasti:
- Tavallista rakenteista tuotosta varten annetaan tuettu JSON Schema -osajoukko vastauksen muotoa määrittävälle parametrille. OpenAI käyttää JSON Schema -vastausmuotoja, Claude
output_config.format-asetusta ja Gemini skeemaohjattua rakenteista tuotosta. - Kutsuttavat toiminnot kuvataan
tools-taulukossa, ja kutsun yhteydessä palautetaan työkalukutsuvastaus. Nykyiset Claude-mallit tukevat asiakastyökalujen määrittelyssä myösstrict: true-asetusta, joten keinotekoisen työkalun pakottaminen ei ole enää ainoa tapa saada JSON-tuotos.
Molemmat toimivat ja liittyvät toisiinsa. ”Funktiokutsu” on pohjimmiltaan rakenteinen tuotos, jonka skeema on funktion allekirjoitus.
Malli 1: tiukat ja yksiselitteiset skeemat
Suurin yksittäinen luotettavuushyöty syntyy skeemoista.
Väljä skeema:
{
"type": "object",
"properties": {
"category": { "type": "string" },
"priority": { "type": "string" }
}
}
Tiukka skeema:
{
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": ["billing", "technical", "account", "feature_request", "complaint"],
"description": "The ticket category. Use 'technical' for product bugs and 'account' for login/password issues."
},
"priority": {
"type": "string",
"enum": ["low", "medium", "high", "urgent"],
"description": "Use 'urgent' only for outages or business-critical impact. 'high' for blocking issues on important customers. 'medium' for standard impact. 'low' for nice-to-haves."
}
},
"required": ["category", "priority"],
"additionalProperties": false
}
Tiukka versio:
- Rajaa arvot tunnettuihin enum-arvoihin, jolloin vapaamuotoista vaihtelua ei synny.
- Sisältää sisäisinä kehotteina toimivat kuvaukset, joita malli hyödyntää.
- Määrittää kentät pakollisiksi, joten osittaisia vastauksia ei synny.
- Kieltää ylimääräiset kentät, joten satunnaisia hallusinoituja avaimia ei synny.
Tuotannossa jokaisella skeeman kentällä pitäisi olla kuvaus. Jokainen enum pitäisi määrittää yksiselitteisesti. Jokainen pakollinen kenttä pitäisi merkitä. Tässä skeema toimii kehotteena eli skeema tekee osan kehotesuunnittelusta.
Malli 2: rajoitettu generointi
Merkittävät palveluntarjoajat tukevat nykyään rajoitettua generointia: dekoodaustaso rajoittaa mallin tuottamaan vain kelvollisia tuotoksia.
- OpenAI:
response_format: { type: "json_schema", json_schema: { ..., strict: true } } - Anthropic: JSON-tuotokset
output_config.format-asetuksella ja tiukat työkalusyötteetstrict: true-asetuksella. - Avoimilla painoilla julkaistujen mallien ajaminen: kielioppi- tai skeemaohjattu dekoodaus, jos valittu inferenssipalvelin ja malli tukevat sitä.
Suosi rajoitettua tuotosta, kun palveluntarjoaja ja malli tukevat tarvitsemaasi skeemaosajoukkoa. Se ehkäisee syntaksi- ja skeemamuotovirheitä, mutta ei tee poimituista arvoista tosia eikä valtuuta sivuvaikutusta. Palveluntarjoajat dokumentoivat tukemattomat skeema-avainsanat ja monimutkaisuusrajat. Kieliopin kääntäminen voi lisätä ensimmäisen pyynnön viivettä, ja osa palveluntarjoajista tallentaa käännetyt kieliopit välimuistiin. Mittaa siksi sekä kylmän että lämpimän polun suorituskyky äläkä oleta lisäkustannusta mitättömäksi.
Jos rajoitettua generointia ei ole käytettävissä joissakin avoimissa malleissa tai kokoonpanoissa, varavaihtoehtona on validointi ja uusi yritys (katso Malli 4).
Malli 3: skeemojen versiointi
Skeemat kehittyvät. Kenttiä lisätään, vanhennetaan ja luetteloita muutetaan.
Skeemamuutos on koodimuutos. Sen pitäisi olla:
- Versioitu. Merkitse jokaiseen skeemaan versionumero.
- Testattu. Arviointikokonaisuus ajetaan uudella skeemalla ennen käyttöönottoa.
- Viestitty. Tuotoksen jatkokäsittelijät tietävät muutoksesta.
- Mahdollisuuksien mukaan taaksepäin yhteensopiva. Lisää uusia valinnaisia kenttiä, älä poista pakollisia.
Hyvin toimiva malli on tallentaa skeemat TypeScript-tyyppeinä tai Pydantic-malleina, versioida ne lähdekoodin versionhallinnassa ja tuottaa niistä JSON Schema. Samat tyypit palvelevat sekä mallirajapintaa että sovelluskoodia.
class TicketClassificationV2(BaseModel):
category: Literal["billing", "technical", "account", "feature_request", "complaint"]
priority: Literal["low", "medium", "high", "urgent"]
confidence: float = Field(ge=0, le=1, description="Confidence in this classification, 0-1")
needs_human_review: bool = Field(description="True if any field has low confidence or unusual signal")
reasoning: str = Field(description="Brief reasoning for the classification, especially for non-obvious cases")
Pydantic-malli määrittää skeeman, validoi tuotoksen ja toimii Python-koodisi tyyppinä. Käytössä on yksi ensisijainen lähde.
Malli 4: validointi ja uusi yritys
Validoi tuotos ennen käyttöä myös rajoitettua generointia käytettäessä:
from pydantic import ValidationError
def call_with_validation(prompt, schema, max_retries=2):
for attempt in range(max_retries + 1):
response = llm_call(prompt, response_format=schema)
try:
parsed = schema.model_validate_json(response.content)
return parsed
except ValidationError as e:
if attempt < max_retries:
prompt = build_retry_prompt(prompt, response.content, e)
continue
raise
Uuden yrityksen kehotteeseen pitäisi sisällyttää alkuperäiset ohjeet, mallin edellinen tuotos ja täsmällinen kuvaus virheestä:
Your previous response had a validation error:
{error message}
Your previous output:
{previous output}
Please correct the issue and produce a valid response.
Uuden yrityksen onnistuminen riippuu mallista, virheluokasta ja palautteesta. Mittaa palautumisaste validointivirheen tyypin mukaan. Älä muuta epäonnistunutta turvallisuus- tai liiketoimintasääntöjen tarkistusta automaattiseksi mallin uudelleenyritykseksi.
Rajoitukset: älä yritä loputtomasti uudelleen, vaan yritä enintään 2-3 kertaa. Älä yritä uudelleen muiden kuin validointivirheiden, kuten nopeusrajoitusten tai sisältösuodattimen, yhteydessä. Kirjaa uudet yritykset lokiin, jotta niiden määrää voidaan seurata. Kasvava määrä kertoo mallin ajautumisesta tai kehotteen ongelmista.
Malli 5: tuloksen arviointi
Erillinen mallivaihe voi tulkita monimutkaisen funktiokutsun tuloksen ennen vastauksen muodostamista. Se auttaa päättelyssä, mutta ei ole turvallisuusraja.
Pelkistetty silmukka:
1. Call LLM with tools available.
2. Model decides to call tool X.
3. Execute X.
4. Pass result back to model.
5. Model produces final response.
Arviointisilmukka:
1. Kutsu LLM:ää työkalut käytettävissä.
2. Malli päättää kutsua työkalua X.
3. Suorita X.
4. Välitä tulos takaisin mallille.
5. Malli arvioi: vastaako tulos sitä, mitä odotin? Pitäisikö minun toimia sen perusteella?
6. Jos pitäisi, malli tuottaa lopullisen vastauksen. Jos ei, malli kutsuu toista työkalua tai pyytää tarkennusta.
Tällä havaitaan esimerkiksi seuraavat tapaukset:
- Työkalu palautti 0 tulosta, vaikka tietoja olisi pitänyt löytyä → seuraava vaihe käsittelee tyhjän tuloksen erikseen.
- Työkalu palautti virheen → seuraava vaihe käsittelee sen eikä sivuuta sitä.
- Työkalu palautti odottamattomia tietoja → seuraava vaihe merkitsee tilanteen ja mukautuu.
Toteuta tämä kehottamalla mallia arvioimaan työkalutulokset erikseen esimerkiksi rakenteisella ”arvioi ja toimi” -mallilla.
Tämä lisää viivettä ja tokenien käyttöä. Seurauksellisissa toimissa on käytettävä deterministisiä sääntötarkistuksia ja tarvittaessa ihmisen hyväksyntää. Mallin ”arviointi” ei saa valtuuttaa maksua, poistamista, lähettämistä tai tilimuutosta. Pidä ylimääräinen mallivaihe vain, jos se parantaa tuloksia merkityllä tehtäväjoukolla.
Malli 6: idempotenssi
LLM saattaa kutsua saman työkalun kahdesti tai yrittää jo onnistunutta kutsua uudelleen. Ilman idempotenssia syntyy kaksoiskappaleita: kaksi hyvitystä, kaksi lähetettyä sähköpostiviestiä tai kaksi luotua tietuetta.
Idempotenssin toteutusmalleja:
Idempotenssiavaimet. Jokainen työkalukutsu saa yksilöllisen avaimen, joka luodaan asiakaspuolella ja sisällytetään kutsuun. Jatkorajapinta tai työkalusi rajapintakerros tunnistaa avaimen avulla kaksoiskappaleet ja palauttaa aiemman tuloksen.
Atominen hae tai luo -semantiikka. Tue liiketoiminta-avainta tietokannan yksilöllisyysrajoitteella ja tee lisäys tai haku transaktiona. Erillinen ”tarkista ja luo” -sarja aiheuttaa rinnakkaisuudessa kilpailutilanteen eikä takaa idempotenssia.
Idempotenssitietueet. Varaa idempotenssiavain atomisesti pysyvässä tallennustilassa, tallenna toiminnon tila ja lopullinen vastaus ja palauta sama vastaus uusille yrityksille. Pelkkä lisäävä loki ilman atomista varausta on altis kilpailutilanteille.
Varovainen työkalusuunnittelu. Seurauksellisia toimia tekevät työkalut suunnitellaan vaatimaan nimenomainen vahvistus tai ihmisen hyväksyntä. LLM ei voi käynnistää niitä vahingossa tiiviissä silmukassa.
Suunnittele kaikki sivuvaikutuksia aiheuttavat työkalut idempotenteiksi. Tämän ohittaminen on merkittävä tuotantovirheiden lähde.
Malli 7: työkalukutsujen havainnoitavuus
Sinun on tiedettävä, mitä työkalukutsuissa tapahtuu. Kirjaa jokaisesta kutsusta:
- Aikaleima.
- Työkalun nimi ja argumentit.
- Tulos tai virhe.
- Kesto.
- Käyttäjä tai istunto, johon kutsu kuuluu.
- Tämän vuoron kutsuketju eli kuuluiko työkalukutsu pidempään ketjuun.
Rakenna tiedoista koontinäytöt. Tavallisia näkymiä ovat:
- Työkalukohtainen kutsumäärä.
- Työkalukohtainen virheprosentti.
- Työkalukohtainen keskimääräinen kesto.
- Työkalusarjojen mallit eli mitä työkaluja yleensä kutsutaan yhdessä.
- Hallusinoidut työkalukutsut, joissa LLM yritti kutsua työkalua, jota ei ole olemassa.
Näistä tiedoista näet, missä järjestelmä epäonnistuu ja missä kustannuksia syntyy.
Malli 8: hallusinoidut argumentit
LLM-mallit keksivät joskus arvoja työkalujen parametreihin. Ne voivat kutsua search_customers(email="...")-funktiota sähköpostiosoitteella, joka ei liity käyttäjän varsinaiseen kysymykseen, tai book_meeting(date="...")-funktiota päivämäärällä, jota ei ole mainittu.
Lieventämiskeinot:
Tiukka skeema ja kuvaukset. ”user_id-arvon on oltava aiemmin keskustelussa mainittu tunniste. Älä keksi tunnisteita.”
Validointi työkalun rajapintakerroksessa. Jos arvo ei ole uskottava, esimerkiksi user_id-tunnistetta ei ole tai päivämäärä on menneisyydessä, työkalu palauttaa rakenteisen virheen ja malli harkitsee uudelleen.
Arviointi. ”Varmista ennen työkalun kutsumista, että käyttämäsi arvot perustuvat keskusteluun.”
Rajatut työkalukuvaukset. Tiettyjä kohteita käsittelevät työkalut tarjoavat vain aiemmin keskustelussa haettujen kohteiden tunnisteet. Älä tarjoa rajoittamatonta hakua.
Tarkastuslokit. Havaitse hallusinoitujen argumenttien mallit ja säädä kehotteita tai skeemoja.
Malli 9: hallittu heikentyminen
Työkalut epäonnistuvat, rajapinnat kaatuvat ja nopeusrajoitukset ylittyvät. Oikea vastaus on harvoin kertoa käyttäjälle, ettei mikään toimi.
Toimintamalleja:
Välimuistissa oleva tai vanhentunut tieto. Jos reaaliaikainen tietolähde ei ole käytettävissä, palauta välimuistissa oleva tieto ja ilmoita sen olevan vanhentunutta.
Osittainen valmistuminen. Jos 3 tehtävää 5 osatehtävästä onnistuu, kerro, mitä tehtiin ja mitä ei.
Varapolut. Jos ensisijainen työkalu epäonnistuu, dokumentoi vaihtoehto kehotteessa tai työkalujoukossa. Jos esimerkiksi ”search_documents” epäonnistuu, käytä ”search_web”-työkalua asianmukaisin varauksin.
Käyttäjälle näkyvät virhetilat. Jos työkalu ei todella pysty suorittamaan tehtävää, malli tuottaa käyttäjälle selkeän virheilmoituksen eikä hallusinoitua onnistumista.
Mallin on tunnettava nämä toimintamallit. Dokumentoi ne järjestelmäkehotteessa:
Jos työkalu palauttaa virheen:
- Kokeile vaihtoehtoista työkalua, jos sellainen on.
- Raportoi osittaiset tulokset selkeästi, jos käyttäjä on jo antanut tietoja.
- Älä koskaan väitä onnistumista, kun työkalu palautti virheen.
Malli 10: rakenteisten tuotosten suoratoisto
Osittaisen rakenteisen tuotoksen suoratoisto parantaa käyttökokemusta: käyttäjä näkee tulosten muodostuvan reaaliajassa odottamisen sijaan.
Toteutus:
- Useimmat nykyiset mallirajapinnat suoratoistavat JSON-tuotoksen tokeni kerrallaan.
- Jäsennä osittainen JSON vaiheittain esimerkiksi
partial-json-parser-kirjastolla tai pienellä itse kirjoitetulla suoratoistojäsentimellä. - Päivitä käyttöliittymää kenttien saapuessa.
Tämä toimii erityisen hyvin moniosaisissa tuotoksissa. Pitkä tuotekuvaus, useita havaintoja sisältävä analyysi tai useita löydöksiä sisältävä koodikatselmointi tuntuu paljon nopeammalta suoratoistettuna.
Varoitus: älä tee päätöksiä osittaisen tuotoksen perusteella. Suoratoista näyttämistä varten, mutta odota valmistumista ennen rakenteisen tuloksen käyttöä.
Malli 11: funktiokutsut vai erilliset päätöskutsut
Natiivi funktiokutsu on kätevä, koska malli ”päättää”, milloin työkalua kutsutaan. Joissakin työnkuluissa erillinen päätöskutsu on kuitenkin luotettavampi.
Esimerkkinä asiakastukityönkulku, jossa mallin täytyy valita useasta toiminnosta.
Natiivi funktiokutsu: Anna mallille 5 työkalua (refund, send_article, escalate_to_human, ask_clarifying_question ja close_ticket) ja anna sen päättää.
Erillinen päätöskutsu: Kutsu mallia ensin yhdellä decide_action-työkalulla, jonka skeema nimeää sallitut toiminnot. Isäntäjärjestelmä validoi päätöksen deterministisiä käytäntöjä vasten ja tarjoaa vasta sitten vain sallitun seuraavan toiminnon.
Erillinen tapa on hitaampi ja monisanaisempi, mutta se antaa isäntäjärjestelmälle käytäntöjen tarkistuspisteen ja rajatumman joukon seuraavan vaiheen työkaluja. Tehtävän onnistumiseen kohdistuva hyöty riippuu työkuormasta, joten vertaa molempia tapoja samoilla merkityillä tapauksilla.
Seurauksiltaan merkittävissä työnkuluissa erillinen tapa on usein parempi. Tutkivissa tai yksinkertaisissa työnkuluissa natiivi funktiokutsu riittää.
Malli 12: työkalutulosten muotoilu
Työkalutulosten palautustavalla on merkitystä. Malli lukee tuloksen, joten muoto vaikuttaa.
Huono:
{"id": "cus_123", "n": "John", "p": "12345"}
Parempi:
{
"customer_id": "cus_123",
"name": "John Doe",
"phone": "+1-555-0123",
"tier": "premium",
"open_tickets": 0
}
Paras joissakin tapauksissa:
Asiakas löytyi:
- Tunniste: cus_123
- Nimi: John Doe
- Taso: Premium
- Puhelin: +1-555-0123
- Avoimet tukipyynnöt: 0
Tämä asiakas on premium-tasolla, eikä hänellä ole avoimia tukipyyntöjä.
”Paras” muoto on ihmisen luettavissa, sisältää kontekstin ja on mallille helpompi hyödyntää myöhemmässä generoinnissa. ”Parempi” muoto on rakenteisempi ja koneellisesti luettavissa. Käytä muotoa, jota malli käsittelee parhaiten jatkotehtävissäsi, ja testaa valinta.
Joidenkin työkalujen yhteydessä sekä rakenteisen että kertovan muodon palauttaminen toimii hyvin: ”Tässä tulos: [kertova kuvaus]. Raakadata: [JSON].”
Malli 13: skeematietoiset uudelleenyritykset
Joistakin validointivirheistä ei voi palautua, koska malli on ymmärtänyt tehtävän olennaisesti väärin. Toiset on helppo korjata.
Hyödyllinen malli on luokitella virhe ja vastata sen mukaisesti.
def handle_validation_error(error):
# Pydantic exposes stable structured errors; do not branch on human text.
issues = error.errors()
feedback = []
for issue in issues:
location = ".".join(str(part) for part in issue["loc"])
feedback.append({
"field": location,
"type": issue["type"],
"message": issue["msg"],
})
return retry_with_json({"validation_errors": feedback})
Virheeseen mukautetut uudet yritykset onnistuvat yleisiä uusia yrityksiä useammin.
Malli 14: yhdisteltävyys
Työkalujen pitäisi olla yhdisteltävissä. Malli voi yhdistää yhteen asiaan keskittyviä pieniä työkaluja monimutkaisiksi työnkuluiksi.
Kaiken tekevä monoliittinen process_customer_request(query)-työkalu on musta laatikko. Malli ei voi havaita eikä ohjata sen sisäistä logiikkaa.
Malli voi yhdistää joukon kohdennettuja työkaluja — search_customer(email), get_recent_orders(customer_id), check_subscription_status(customer_id) ja escalate_to_human(reason) — kuhunkin tilanteeseen sopivaksi työnkuluksi.
Suunnittele työkalut sopivalla tarkkuustasolla. Jokainen työkalu tekee yhden asian, ja työkaluista muodostetaan työnkulkuja.
Malli 15: skeema ”en tiedä” -vastaukselle
Hienovarainen mutta tärkeä malli on epävarmuuden esittäminen skeemassa.
class CustomerInfo(BaseModel):
name: str
name_confidence: Literal["high", "medium", "low"]
needs_clarification: bool
clarification_question: Optional[str] = None
Malli voi palauttaa matalan luottamustason ja tarkentavan kysymyksen tietojen keksimisen sijaan.
Tämä on paljon parempi kuin malli, joka täyttää kentät aina itsevarmasti ja käyttää joskus hallusinoitua tietoa.
Käytännön esimerkki: laskujen käsittely
Yhdistetään mallit tuotantotasoiseen laskujenkäsittelyjärjestelmään.
Syötteet: sähköpostiin liitetty PDF-lasku. Tavoite: poimia rakenteiset tiedot ja välittää ne taloushallintojärjestelmään.
Skeema:
class LineItem(BaseModel):
description: str
quantity: float
unit_price: float
total: float
confidence: Literal["high", "medium", "low"]
class Invoice(BaseModel):
vendor_name: str
vendor_id: Optional[str] = None # null if not found in our records
invoice_number: str
invoice_date: date
due_date: Optional[date] = None
line_items: List[LineItem]
subtotal: float
tax: float
total: float
currency: str # ISO 4217
confidence: Literal["high", "medium", "low"]
needs_review: bool
review_reasons: List[str] # Specific reasons review is needed
Työnkulku:
- OCR-vaihe: kuvamalli poimii tekstin PDF-tiedostosta.
- Poimintavaihe: LLM-kutsu käyttää edellä olevaa skeemaa, ja rajoitettu generointi on käytössä.
- Validointivaihe: Pydantic validoi tuotoksen. Validointivirhe käynnistää yhden uuden yrityksen, johon sisältyy virhepalaute.
- Ristiintarkistus: työkalukutsu hakee toimittajan omista tietueistamme. Jos
vendor_namevastaa tunnettua toimittajaa, lisäävendor_id. Muussa tapauksessa asetaneeds_review=true. - Laskutoimitusten tarkistus: varmista, että
sum(line_items.total) ≈ subtotaljasubtotal + tax ≈ total. Jos ei, asetaneeds_review=true. - Luottamuksen tarkistus: jos
confidenceon matala tai jonkin laskurivin luottamustaso on matala, asetaneeds_review=true. - Reititys: jos
needs_review=true, lähetä ihmisen tarkistusjonoon. Muussa tapauksessa välitä taloushallintojärjestelmään. - Lokitus: kirjaa jokaisesta vaiheesta syöte, tuotos, kesto ja virheet.
Käsitellyt virhetilat:
- Virheellinen JSON: rajoitettu generointi ehkäisee virheen, ja uusi yritys käsittelee reunatapaukset.
- Hallusinoidut kentät: skeema on tiukka.
- Laskuvirheet: validoidaan.
- Tuntemattomat toimittajat: merkitään.
- Pieni luottamus: merkitään.
- Työkaluvirheet: käsitellään erikseen.
Älä lainaa artikkelista automaattisen läpikäsittelyn prosenttiosuutta. Rakenna merkitty aineisto niistä laskumuodoista, kielistä, valuutoista, skannauksista ja poikkeustyypeistä, joita todella vastaanotat. Sovi ennen automatisointia kenttäkohtainen tarkkuus, rahamäärien täsmäytys, virheellisten automaattihyväksyntöjen sallittu määrä ja ne toimittajat tai summat, jotka vaativat aina tarkistuksen. Aja ensin varjotilassa, raportoi jokainen virheluokka ja ota kirjanpidon kirjoitukset käyttöön vain sille osajoukolle, joka ylittää sovitun rajan.
Tältä tuotantotasoinen rakenteinen tuotos näyttää. Kyse ei ole vain siitä, että ”JSON-tila toimi kerran”, vaan todellisten virhetilanteiden käsittelyyn kykenevästä putkesta.
Yleiset virheet
Näemme toistuvasti seuraavia malleja:
Virhe 1: ei validointia. Käytä Pydanticia, zodia tai mitä tahansa sopivaa, mutta validoi. Älä luota malliin.
Virhe 2: epämääräiset kuvaukset. ”category: string” ei auta mallia. ”category: one of billing, technical, account_access, where billing covers…” auttaa.
Virhe 3: epäolennaiset työkalut. Laaja työkaluluettelo kasvattaa mallin valintakuormaa. Tarjoa vain nykyisessä tilassa olennaiset ja valtuutetut työkalut. Määritä toimiva lukumäärä työkaluvalinnan arvioinnilla, älä yleispätevällä ”alle kymmenen” -säännöllä.
Virhe 4: validointivirheen jälkeen ei yritetä uudelleen. Yksi virheellisesti muotoiltu tuotos pysäyttää koko työnkulun. Yritä kerran uudelleen ja anna palautetta.
Virhe 5: ei havainnoitavuutta. Kun työkalukutsut epäonnistuvat tuotannossa, syytä ei voi selvittää ilman jäljityksiä.
Virhe 6: sivuvaikutuksia aiheuttavat työkalut eivät ole idempotentteja. Kaksoishyvitykset ja kahteen kertaan lähetetyt sähköpostiviestit ovat ennakoitava virhe.
Virhe 7: LLM:n valitsemia argumentteja ei validoida. Hallusinoidut käyttäjätunnisteet ja päivämäärät. Validoi työkalujen argumentit ennen suorittamista.
Virhe 8: skeemojen versiointi ohitetaan. Skeemamuutokset rikkovat jatkokäsittelijät. Versioi skeema.
Demosta tuotantojärjestelmäksi
Rakenteiset tuotokset ja funktiokutsut muodostavat sillan ”puhuvasta LLM:stä” ”työtä tekeväksi LLM:ksi”. Hyvin toteutettuina ne mahdollistavat tuotantotekoälyn. Huonosti toteutettuina ne rikkoutuvat kiinnostavilla ja kalliilla tavoilla.
Olennaisia malleja ovat tiukat skeemat, rajoitettu generointi, validointi ja uusi yritys, työkalutulosten arviointi, idempotenssi, hallittu heikentyminen, skeemat huomioiva virheenkäsittely sekä kokonaisvaltainen havainnoitavuus.
Jokainen näistä malleista erottaa demon tuotantojärjestelmästä. Rakenna ne mukaan alusta alkaen.



