Kopiert til utklippstavlen

Alle innlegg

6 min lesetid Av Sergii Shcherbak

ContextGem 1.0: riktig modell for hvert spørsmål om et dokument

ContextGem henter ut strukturerte data fra dokumenter og sporer hvert faktum tilbake til kilden. Versjon 1.0 legger til beslutningsmodeller ved siden av LLM-er, som besvarer lukkede spørsmål med en sannsynlighet for hvert svar. Hva rammeverket gjør, hva utgivelsen bringer, hvorfor det betyr noe, og hvordan du bruker det.

v1.0.0

ContextGem er vårt åpen kildekode-rammeverk for å hente ut strukturerte data fra dokumenter. Du beskriver med vanlige ord hva som skal hentes ut, og rammeverket skriver promptene, validerer det modellen returnerer til typede verdier og sporer hvert faktum det henter ut, tilbake til avsnittet eller setningen det kom fra. Versjon 1.0 er ute, og den legger til beslutningsmodeller ved siden av LLM-er.

Dette innlegget er kortversjonen: hva ContextGem gjør, hva 1.0 bringer, hvorfor det betyr noe, og hvordan du bruker det. Detaljene står i dokumentasjonen. Eksemplene deler én oppdiktet applikasjon: en agent for en eiendomsforvalter, som leser rapportene vaktmesterne skriver, én for hver feil de finner, og oppretter en arbeidsordre for hver av dem.

Hva ContextGem gjør

Det som skal hentes ut, beskrives som aspekter (aspects), de delene av et dokument som handler om et tema, og konsepter (concepts), typede verdier som et ja eller nei, en etikett, et tall, en dato eller en tekst. Ett kall til en modell henter dem ut. For eiendomsforvalterens agent er det første som skal hentes ut, selve feilen, med setningen i rapporten den ble hentet fra:

agent.py
from contextgem import (
    Document,
    DocumentLLM,
    StringConcept,
)

doc = Document(raw_text=report)
defect = StringConcept(
    name="Defect",
    description="What is broken",
    add_references=True,
    reference_depth="sentences",
)
doc.add_concepts([defect])

llm = DocumentLLM(
    model="openai/gpt-6-luna",
)
doc = llm.extract_all(doc)

Hvert element som kommer tilbake, har sin verdi, feilen slik rapporten beskriver den, og i reference_sentences setningene i rapporten den ble funnet i. Den som kontrollerer den, leser en setning, ikke rapporten.

Det finnes ikke noe søkesteg som velger ut de avsnittene som ser relevante ut, slik gjenfinningsstøttet generering (RAG) har: Modellen leser hvert avsnitt, alt på én gang eller i porsjoner av en størrelse du bestemmer. I en agent er ContextGem den delen som leser, ett dokument om gangen.

én rapport, lest på to måter

Et søkesteg

3 avsnitt, rangert høyest, lest

✗ feilen, i ¶4, oversett

ContextGem

✓ Hvert avsnitt lest

¶4 Branndøren til kjelleren lukker seg ikke

Et søkesteg leser de avsnittene det rangerer høyest, og kan gå glipp av det som har faktumet. ContextGem leser hvert avsnitt, og feilen kommer tilbake med setningen den ble funnet i.

Beslutningsmodeller ved siden av LLM-er

En beslutningsmodell tar imot en tekst og lukkede spørsmål om den (ja eller nei, én av etikettene dine, et nivå på en skala) og returnerer sannsynligheten for hvert mulige svar. Den skriver ingen tekst. Typen er ny: TypeSafe innførte den med Jev i september 2026, OpenAI (Decisions API) og Microsoft (Microsoft-Decision-1) har fulgt etter, og Ollama og LM Studio kjører dem lokalt.

I 1.0 henter en DocumentDecisionModel ut aspekter og boolske konsepter, etikettkonsepter og vurderingskonsepter, hvert element med sannsynlighetene for alle svarene sine, og du setter terskelen et ja regnes som et ja fra. En modellgruppe sender hvert aspekt og konsept til modellen med samme rolle, de lukkede spørsmålene til en beslutningsmodell og de åpne verdiene til en LLM, og enhver modell kan falle tilbake på andre.

modellgruppe

Defect StringConcept

LLM

"Branndøren til kjelleren lukker seg ikke"

Safety risk BooleanConcept

Beslutningsmodell

True 0.41

Trade LabelConcept

Beslutningsmodell

Carpentry 0.86

Urgency RatingConcept

Beslutningsmodell

4 0.57

Hvert spørsmål går til modellen med samme rolle: det åpne til LLM-en, som skriver svaret, og de lukkede til beslutningsmodellen, som gir sannsynligheten for hvert svar.

Resten av utgivelsen er en lang runde med rettelser, som alle står i endringsloggen. Dokumentasjonen har fått en ny adresse, contextgem.shcherbak.ai, med llms.txt for kodeagenter.

Oppgraderer du fra 0.x? Les migreringsveiledningen først, eller pek en kodeagent til llms.txt: Noen navn, standardverdier og formatet for serialiserte data er endret.

Hvorfor det betyr noe

Uthenting fra dokumenter går oftere galt ved at et faktum blir utelatt, enn ved at et blir diktet opp. En systematisk oversikt fra 2026 over 27 studier der LLM-er hentet ut data til systematiske oversikter, fant at utelatelser utgjorde 60 til 74 % av feilene, og at andelen hallusinasjoner lå på 0,08 til 6 % («Omissions were the dominant error type (60-74%), with hallucination rates of only 0.08-6%»). Et søkesteg som velger ut avsnittene, er ett sted til der et faktum kan gå tapt. I FinanceBench, en benchmark fra 2023 med spørsmål om børsnoterte selskapers rapporter, svarte GPT-4-Turbo riktig på 50 % av spørsmålene når et vektorlager valgte ut avsnitt fra den ene rapporten, og på 79 % med hele rapporten i prompten. Derfor leser ContextGem hvert avsnitt.

Det som hentes ut, må fortsatt kontrolleres, og kilden gjør kontrollen kort. I en forhåndspublisert studie fra CSIRO, Australias nasjonale forskningsorganisasjon, var deltakere som vurderte uthentede svar mot noen få avsnitt av artikkelen, omtrent like treffsikre som de som hadde hele artikkelen (83,1 % mot 85,7 %), og de brukte 28 % kortere tid.

Spurt om hvor sikker den er, sier en LLM gjerne for mye: På SimpleQA, OpenAIs benchmark med korte faktaspørsmål, overvurderer modellene konsekvent hvor sikre de er («models consistently overstate their confidence», Wei mfl., 2024). For et lukket spørsmål returnerer en beslutningsmodell i stedet sannsynligheten for hvert svar, så du bestemmer hvor grensen går: Over den handler en agent, under den ser en person på saken. Den er også priset for store mengder: OpenAIs Decisions API tar bare betalt for inndatatokener. Men typen er en måned gammel, og en tidlig uavhengig test fant at Jevs sannsynligheter lå nær hvor ofte den hadde rett på ett datasett og langt unna på et annet (en kalibreringsfeil på 0,034 mot 0,29), så ContextGem lar deg velge modell og terskel selv, og sette dem på dine egne dokumenter.

Slik bruker du det

Installer det med uv:

terminal
uv add contextgem
Kopiert til utklippstavlen

Eller med pip:

terminal
pip install -U contextgem
Kopiert til utklippstavlen

Lukkede spørsmål til en beslutningsmodell. Eiendomsforvalterens agent spør om tre ting til i hver vaktmesterrapport: om feilen kan skade noen, hvilket fag som skal utbedre den, og hvor snart. Hvert av dem er et lukket spørsmål, og går til beslutningsmodellen etter rollen sin:

agent.py
from contextgem import (
    BooleanConcept,
    DocumentDecisionModel,
    DocumentModelGroup,
    LabelConcept,
    RatingConcept,
)

safety = BooleanConcept(
    name="Safety risk",
    description="Can hurt people",
    model_role="decide",
    decision_threshold=0.3,
)
trade = LabelConcept(
    name="Trade",
    description="Who fixes it",
    labels=[
        "Carpentry",
        "Plumbing",
        "Electrical",
        "Other",
    ],
    model_role="decide",
)
urgency = RatingConcept(
    name="Urgency",
    description="How soon to fix",
    rating_scale=(1, 5),
    model_role="decide",
)
doc.add_concepts(
    [safety, trade, urgency],
)

En modellgruppe med de to tar plassen til kallet i det første eksemplet: Feilen går til LLM-en, som ikke har noen rolle, og de tre spørsmålene til beslutningsmodellen:

agent.py
dm = DocumentDecisionModel(
    model="typesafe/jev-1.13.0",
    role="decide",
)
group = DocumentModelGroup(
    models=[llm, dm],
)
doc = group.extract_all(doc)

En terskel som passer spørsmålet. Hvert element beslutningsmodellen henter ut, har sannsynlighetene for alle svarene sine (tallene under er oppdiktet):

agent.py
risk = doc.get_concept_by_name(
    "Safety risk",
)
item = risk.extracted_items[0]
item.value  # True
item.probabilities
# {True: 0.41, False: 0.59}

Et ja regnes som et ja fra en sannsynlighet på 0,5, med mindre du setter en annen terskel. For en sikkerhetsrisiko koster et ja som blir oversett, mer enn et ja for mye, så eksemplets agent tar et ja fra 0,3, og denne rapporten markeres som en risiko.

Safety risk
✓ Terskel på 0,3: 5 av 8 rapporter er en sikkerhetsrisiko
Terskelen avgjør hvilke sannsynligheter som regnes som et ja. Flyttet fra 0,5 til 0,3 gjør den to rapporter til en sikkerhetsrisiko i tillegg, blant dem denne med 0,41, og endrer ingen sannsynlighet.

Før du stoler på den. Sammenlign beslutningsmodellen med en LLM på et utvalg av dine egne dokumenter der du kjenner svarene, og sett terskelen på det utvalget (når du bør bruke en beslutningsmodell): for eksemplets agent, vaktmesterrapporter som eiendomsforvalteren allerede har sortert. Be om en versjon av modellen og ikke et alias, slik eksemplet gjør (jev-1.13.0): jev-latest flytter seg til hver nye utgivelse, og en terskel som er satt på én versjon, er ikke kontrollert på den neste.

Spørsmål du bør stille

Enten uthentingen gjøres med ContextGem, et annet bibliotek eller en modelleverandørs eget API, viser disse spørsmålene om dere kan stole på det som hentes ut.

  1. Hvilke av verdiene dere henter ut, er lukkede spørsmål, og hvilke er åpne?
  2. Kan hver verdi som hentes ut, spores tilbake til setningen den kom fra?
  3. Bestemmer et søkesteg hvilke avsnitt modellen leser?
  4. Hvor sikker er modellen på hvert svar, og hvem ser svarene den er usikker på?
  5. Ble terskelen satt på deres egne dokumenter, og kontrolleres den på nytt når modellen endres?
  6. Hva koster det å hente ut ett dokument, og hvor mye av det er generert tekst?

Vi publiserer bare verktøy vi bruker selv og kan anbefale til andre. Hvert av dem gjenspeiler hvordan vi bygger, og ContextGem gjenspeiler ett ord av det: verifiserbart. Vi bygger AI-agenter tilpasset din virksomhet, verifiserbare, begrensede og styrte.

Kopiert til utklippstavlen

Sjekk hva du fikk med deg

Hvilken modell, og hvor sikker?

Fem steiner står ved stien, hver en vaktmesterrapport med et faktum inni seg. Hvert riktige svar kløyver én, og edelstenen vises der den ble funnet.

5 spørsmål · 2 minutter

Spørsmål