Document Review met Unsiloed en TypeSafe Jev

Unsiloed AI | 1 oktober 2026 | Leestijd: 6 minuten

Een extractiepijplijn kan een waarde correct lezen en toch foutieve gegevens doorsturen. Een duidelijk gedrukte extra nul overleeft bijvoorbeeld zelfs uitstekende optische tekenherkenning (OCR).

Door Unsiloed en TypeSafe’s Jev samen te gebruiken, kunnen we controleren op OCR-fouten en algemene fouten in een document. Unsiloed extraheert gestructureerde velden en lokaliseert deze op de pagina. Jev beoordeelt de geëxtraheerde informatie aan de hand van gerichte vragen. We kunnen deze resultaten combineren om te bepalen welke velden moeten worden nagekeken.

Jev zet gerichte vragen om in getypeerde antwoorden

Een Jev-verzoek scheidt de informatie die het overweegt (de state) van de beslissingen die het neemt (de questions). In onze workflow bevat de state de records die Unsiloed heeft geëxtraheerd en de context die nodig is om deze te interpreteren. Elke vraag vertelt Jev wat er gecontroleerd moet worden en welk antwoordtype moet worden teruggegeven; daarnaast kunnen er criteria worden gedefinieerd voor de mogelijke antwoorden.

Het type bepaalt wat de code ontvangt:

  • Noul: geeft de waarschijnlijkheid terug dat een bewering waar is.
  • Choice: selecteert uit benoemde opties.
  • Score: evalueert een rubriek van geordende niveaus.

Zowel Choice als Score geven ook een waarschijnlijkheidsverdeling en een betrouwbaarheidsfunctie (confidence value) terug die de concentratie samenvat. Noul heeft geen apart betrouwbaarheidsveld.

De drie types kunnen de state delen in één enkel verzoek. In ons voorbeeld maken we uitsluitend gebruik van Noul.

Een Noul-waarde van 0,04 betekent dat er 4% kans is op een 'ja' als antwoord op onze vraag, wat duidt op een sterk 'nee'. Het betekent niet dat "Jev voor 4% zeker is". Waarden dicht bij de uiteinden duiden op een duidelijke richting; waarden in het midden vereisen voorzichtigheid.

Geëxtraheerde velden naar Jev sturen en resultaten routeren

Unsiloed behoudt wat er gedrukt staat en levert betrouwbaarheidsscores die helpen bij het identificeren van ambigue lezingen. Voor ons voorbeeld gebruiken we een medicatielijst met zes rijen. Een koffievlek versluiert één dosis, terwijl een andere rij een duidelijk gedrukte maar onwaarschijnlijke hoeveelheid bevat. We volgen beide scenario's door de extractie en de controles van Jev.

Ons extractieschema definieert de velden die Unsiloed per medicijn moet teruggeven. Er wordt gevraagd om de volledige cel van de dosis, inclusief hoeveelheid en eenheid, zonder dat verrassende hoeveelheden worden gecorrigeerd of versluierde tekst wordt gegist op basis van gebruikelijke voorschrijfpraktijken. Door enable_citations=true in te schakelen, worden bronverwijzingen toegevoegd.

Elk veld heeft twee Unsiloed-betrouwbaarheidsscores:

  1. extraction_score: meet de betrouwbaarheid van de geëxtraheerde waarde.
  2. grounding_score: meet de betrouwbaarheid dat de waarde correct is gelokaliseerd in het document.

Beide scores variëren van nul tot één. De bronverwijzing (citation) identificeert de pagina en de bounding box (het rechthoekige kader rond de brontekst).

Hieronder volgt de versluierde dosis cetirizine uit de opgeslagen respons, met pixelcoördinaten op de originele afbeelding van 1.200 × 1.500:

{
  "value": "1 tablet",
  "score": { "grounding_score": 0.76, "extraction_score": 0.74 },
  "citation": {
    "page": 1,
    "bbox": [582, 975, 649, 994],
    "page_width": 1200,
    "page_height": 1500
  }
}

Ken aan elke medicijnrij een ID toe (bijv. row-5) en bewaar dit samen met de geëxtraheerde velden en hun bronverwijzingen. Dit stelt de code in staat om het antwoord van Jev later aan dezelfde rij te koppelen. De bronverwijzingen zijn essentieel zodat reviewers elk geëxtraheerd veld op de originele pagina kunnen terugvinden.

Stuur de geëxtraheerde waarden en context naar Jev. Jev beoordeelt de instructie zoals deze is geëxtraheerd, zonder de afbeelding of de Unsiloed-scores te zien. We stellen per rij één Noul-vraag: is deze dosis en frequentie plausibel voor dit medicijn? Alle zes de rijen delen één verzoek, waarbij elke vraag onafhankelijk wordt geëvalueerd.

In de server-side module die de twee API's verbindt, wordt het verzoek als volgt geconstrueerd (hier getoond voor één rij):

const request = {
  model: "jev-1.13.0",
  state: {
    context: "Check for obvious quantity, unit or frequency errors. " +
             "Dose means amount taken each time, not supply quantity. " +
             "Do not assess patient-specific safety or propose corrections.",
    careContext: "Adult outpatient medication reconciliation, age 52",
    medications: [{
      id: "row-5",
      medicine: "Cetirizine 10 mg tablet",
      dose: "1 tablet",
      frequency: "Once daily as needed",
      route: "Oral",
      instructions: "For allergy symptoms."
    }]
  },
  questions: {
    "row-5": {
      type: "noul",
      instructions: {
        question: "Is the extracted dose and frequency plausible on its " +
                 "face for this medicine and strength in the stated adult " +
                 "outpatient context, without an obvious quantity or " +
                 "frequency transcription error?",
        row_id: "row-5"
      },
      criteria: {
        true: "Plausible on its face; no obvious quantity, unit or frequency error.",
        false: "Clearly implausible; warrants review of the original prescription."
      }
    }
  }
};

De context en criteria zijn hier ingekort; het volledige verzoek bevat de exacte tekst voor alle zes de rijen. We gebruiken row-5 als vraag-ID zodat de code het antwoord aan die rij kan koppelen. We voegen het ook toe als row_id binnen de instructies zodat Jev weet welk record beoordeeld moet worden (vraag-ID's worden namelijk niet naar het model gestuurd).

Post het verzoek als JSON naar https://api.typesafe.ai/v1/systemone met authenticatie via een TypeSafe API-key in de header. Het geregistreerde antwoord bij answers["row-5"] is { "type": "noul", "noul": 0.94 }.

De code bepaalt nu of de rij moet worden nagekeken. Voor de lezingcontrole nemen we de laagste Unsiloed-score van alle velden in de rij; een lage score op één veld vlagt de hele rij. Voor de plausibiliteitscontrole gebruiken we de noul-waarde van Jev.

De volgende functie bepaalt de redenen om een rij ter review voor te leggen:

const valid = n => Number.isFinite(n) && n >= 0 && n <= 1;

function reviewReasons(reading, plausible) {
  return [
    ...(!valid(reading) || reading < 0.90 ? ["Verify source reading"] : []),
    ...(!valid(plausible) || plausible < 0.50 ? ["Review instruction"] : [])
  ];
}

In dit voorbeeld triggert een leesscore onder de 0,90 of een plausibiliteitsantwoord onder de 0,50 een review. Dit zijn voorbeeldwaarden; test deze tegen handmatig gecontroleerde documenten voordat ze in productie worden gebruikt. Antwoorden van Jev rond de 0,50 kunnen ook een review vereisen, omdat er geen duidelijke voorkeur is voor ja of nee.

Behoud beide redenen wanneer beide controles falen. Een plausibele instructie kan nog steeds misgelezen tekst bevatten, dus een hoge Jev-score mag een lage Unsiloed-score niet tenietdoen. Sla de originele extractie en het Jev-verzoek/antwoord op samen met de beslissing van de reviewer om later te kunnen analyseren waarom een rij is gevlagd en hoe dit is opgelost.

Gevlagde rijen volgen: van extractie naar review

Aan de hand van de API-resultaten zien we waarom twee rijen verschillende soorten review nodig hebben:

  1. De versluierde cetirizine-dosis: Unsiloed extraheert "1 tablet" met een extraction score van 0,74 en een grounding score van 0,76. Jev geeft een plausibiliteitsscore van 0,94, maar ziet de vlek niet. Het oordeel van Jev is afhankelijk van de juistheid van de geëxtraheerde tekst. De lezingcontrole vlagt de rij, omdat iemand de versluierde markering moet bevestigen.
  2. De ibuprofen-rij: Hier is het patroon omgekeerd. Unsiloed leest "10 tablets, drie keer per dag" met scores van 0,99. Jev geeft echter 0,04 voor de plausibiliteitsvraag. De reviewer moet hier de duidelijk gedrukte instructie onderzoeken. Geen van beide modellen vult een veronderstelde beoogde dosis in.

Elke controle vlagt een reviewbehoefte die de andere mist. De overige vier rijen voldoen aan beide drempelwaarden.

De kosten van Jev per document

Eén medicatielijst in deze demo produceert een Jev-verzoek met zes vragen en 1.812 input-tokens. Bij de gepubliceerde prijs van Jev 1.13.0 van $42 per miljard input-tokens (output is gratis, gecontroleerd op 30 september 2026), kost dit $0,000076 per document. Het verwerken van 100.000 vergelijkbare documenten zou ongeveer $7,61 aan Jev-kosten toevoegen.

Dit is een schatting voor enkel Jev; de kosten voor Unsiloed-extractie en menselijke review komen hier apart bij. De werkelijke kosten hangen af van de verzonden tekst en vragen. Voor een nauwkeurigere schatting kunt u de input_tokens uit een representatieve Jev-respons nemen en toepassen op het gepubliceerde tarief.