Categorie: Productivity

  • Hoe los je snel misvormde JSON-bestanden op: een praktische gids voor ontwikkelaars

    Hoe los je snel misvormde JSON-bestanden op: een praktische gids voor ontwikkelaars

    Je API-aanroep faalde zojuist met JSONDecodeError: Expecting property name enclosed in double quotes. De klok tikt. De data kwam van een LLM, en ergens in dat 2.000-token-antwoord heeft één enkele afsluitende komma je hele pijplijn gedood.

    Per mei 2026 is de snelste manier om misvormde JSON-bestanden te herstellen het gebruik van geautomatiseerde bibliotheken zoals json_repair (Python) of jsonrepair (npm). Deze tools zijn specifiek gebouwd om door LLM’s gegenereerde syntactische fouten direct te herstellen. Voor handmatige reparaties zijn de gebruikelijke verdachten afsluitende komma’s, enkele aanhalingstekens of ongegenoteerde sleutels — de drie meest voorkomende schendingen van de RFC 8259-standaard.

    De snelste oplossing: json_repair voor LLM-uitvoer

    Standaardparsers zoals de json.loads() van Python zijn strikt ontworpen. Eén verkeerd geplaatst teken leidt tot een JSONDecodeError en alles stopt. Dit is in 2026 een dagelijks probleem, omdat LLM’s routinely JSON in conversationele tekst wikkelen, antwoorden midden in een zin afbreken, of opmerkingen toevoegen die de specificatie breken.

    De bibliotheek json_repair is de standaardoplossing. Volgens GitHub heeft dit project meer dan 4.700 sterren in 2026. Het werkt door de intentie van de string te “raden” — ontbrekende haakjes sluiten, aanhalingstekens toevoegen en overtollige tekst rond het JSON-blok verwijderen.

    Eenvoudig 3-staps proces van json_repair: Invoer (kapot) -> Intentie raden -> Uitvoer (geldig)

    Python: voor en na

    Installeren: pip install json-repair

    De kapotte invoer:

    import json_repair
    
    bad_json = '{"user": "Alice", "status": tru'
    decoded_object = json_repair.loads(bad_json)
    

    Wat er achter de schermen gebeurde: json_repair zag dat tru waarschijnlijk true was, voegde het ontbrekende sluithaakje toe en gaf een geldige Python-dictionary terug. Nul handmatige tussenkomst.

    Salvage-modus: wanneer de data echt lelijk is

    Voor lastigere gevallen bevat json_repair (v0.59.5+) een Salvage-modus. Zoals beschreven in de projectdocumentatie, is deze modus specifiek gebouwd voor afgekapte AI-antwoorden of beschadigde logs. Het kan arrays forceren naar objecten of items die te kapot zijn om te redden laten vallen, zodat de uitvoer in je schema past.

    import json_repair
    
    # Salvage mode for severely truncated data
    result = json_repair.loads(
        '{"items": [{"id": 1, "name": "Widget"}, {"id": 2, "na',
        salvage_mode=True
    )
    # Result: {'items': [{'id': 1, 'name': 'Widget'}, {'id': 2}]}
    # Dropped the incomplete 'na' but saved everything else
    

    npm-alternatief

    Voor Node.js-projecten doet de jsonrepair CLI hetzelfde:

    # Fix a file in place
    npx jsonrepair broken.json > fixed.json
    
    # Fix a string in a script
    const { jsonrepair } = require('jsonrepair');
    const fixed = jsonrepair('{"name": "test",}');
    

    Handmatig debuggen: vinden wat de specificatie brak

    Wanneer automatisering niet volstaat, moet je precies vinden waar het bestand RFC 8259 schendt. JSON is veel minder vergevingsgezind dan YAML of JavaScript. Zoals het JSONParser Diagnostics Team uitlegt: “De parser faalt bij het eerste teken dat hij niet kan interpreteren, wat vaak een downstream-symptoom is van een probleem enkele regels eerder.”

    De drie JSON-moordenaars

    Moordenaar 1: afsluitende komma’s

    Volgens DEV Community zijn afsluitende komma’s de nummer één oorzaak van parse-fouten. Ze zijn prima in JavaScript, maar illegaal na het laatste item in een JSON-array of -object.

    // BROKEN - trailing comma after "active"
    {
      "name": "Alice",
      "status": "active",
    }
    
    // FIXED - no comma before closing brace
    {
      "name": "Alice",
      "status": "active"
    }
    

    Moordenaar 2: enkele aanhalingstekens

    JSON vereist dubbele aanhalingstekens (") voor zowel sleutels als stringwaarden. Veel Python- en JavaScript-ontwikkelaars gebruiken per ongeluk enkele aanhalingstekens ('). Zoals TidyCode opmerkt, is dit een verplichte reparatie.

    // BROKEN - single quotes
    {'name': 'Alice'}
    
    // FIXED - double quotes
    {"name": "Alice"}
    

    Moordenaar 3: ontegenoteerde sleutels

    In JavaScript kun je { name: "Alice" } schrijven. In JSON heeft elke sleutel dubbele aanhalingstekens nodig.

    // BROKEN - unquoted key
    {name: "Alice"}
    
    // FIXED - quoted key
    {"name": "Alice"}
    

    Vergelijking zij-aan-zij van ongeldige vs geldige JSON-syntax

    De “Unexpected Token”-fout

    Wanneer een validator een “Unexpected Token” markeert, betekent dit dat de parser NaN, Infinity of undefined tegenkwam — JavaScript-constanten die JSON niet ondersteunt. JSON staat alleen null, true, false en getallen toe.

    // BROKEN - NaN is not valid JSON
    {"score": NaN, "result": Infinity}
    
    // FIXED - replace with null or valid values
    {"score": null, "result": null}
    

    Strikt parsen vs. reparatie-parsen: wanneer gebruik je wat

    De juiste aanpak hangt af van waar je data vandaan komt. Door mensen bewerke configuratiebestanden verdienen strikt parsen om de auteur te dwingen fouten te herstellen. Door machines gegenereerde data van LLM’s of API-logs heeft op reparatie gebaseerd parsen nodig.

    Functie Strikt (json.loads) Reparatie (json_repair)
    Afsluitende komma’s Genereert JSONDecodeError Automatisch verwijderd
    Enkele aanhalingstekens Faalt Omgezet naar dubbele aanhalingstekens
    Afgekapte data Faalt Sluit open haakjes/aanhalingstekens
    Opmerkingen Faalt Automatisch verwijderd
    Beste toepassing Door mensen bewerke configuratiebestanden LLM-uitvoer, API-logs

    Schema-geleide reparaties met Pydantic

    Je kunt het reparatieproces geleiden met Pydantic v2 of JSON Schema. Door json_repair een schema te geven, doet de tool meer dan alleen syntax herstellen — het kan typen corrigeren (string "1" omzetten naar getal 1) en ontbrekende verplichte velden met standaardwaarden invullen.

    from pydantic import BaseModel
    import json_repair
    
    class User(BaseModel):
        id: int
        name: str
        active: bool = True
    
    # Broken JSON with wrong types
    raw = '{"id": "42", "name": "Alice"}'
    repaired = json_repair.loads(raw)
    
    # Validate against schema
    user = User(**repaired)
    # user.id is now int(42), user.active defaults to True
    

    Zoals Stefano Baccianella opmerkte in zijn projectcitaat uit 2025, is deze aanpak geoptimaliseerd voor de “meestal correcte maar technisch ongeldige” JSON die taalmodellen doorgaans produceren.

    Multi-gigabyte bestanden verwerken zonder crashen

    Een fragment van 10KB repareren is eenvoudig. Een bestand van 2GB herstellen vereist een strategie die niet al je RAM opeet. Het hele bestand in het geheugen laden leidt tot Out-of-Memory (OOM)-fouten.

    Strategie 1: streamen met ijson

    Voor enorme datasets gebruik je ijson om data stuk voor stuk te verwerken. Zoals Scrapfly vermeldt, verwerkt ijson data incrementeel. Combineer het met een opschonings-script dat problemen regel voor regel oplost vóór het parsen.

    import ijson
    
    # Stream through a large JSON file
    with open('huge_broken.json', 'r') as f:
        for item in ijson.items(f, 'records.item'):
            # Process each item individually
            process(item)
    

    Strategie 2: CLI-pipe voor maximale efficiëntie

    De meest geheugenefficiënte aanpak voor grote bestanden is om de jsonrepair CLI te gebruiken en de uitvoer direct naar een nieuw bestand te pipen:

    # Streams repair, never loads full file into memory
    jsonrepair large_broken.json > fixed.json
    

    Dit is aanzienlijk geheugenefficiënter dan het bestand in Python of een browser laden.

    Conclusie

    Misvormde JSON herstellen is geen handmatig karwei meer dankzij AI-bewuste bibliotheken zoals json_repair. Je moet nog steeds de basis van RFC 8259 begrijpen — geen afsluitende komma’s, geen enkele aanhalingstekens, geen ontegenoteerde sleutels — maar automatisering is de enige praktische aanpak voor data op schaal in 2026.

    De workflow is eenvoudig: probeer eerst een reparatiebibliotheek. Als dat faalt, gebruik je een validator om de exacte syntaxfout te pinpointen. Zo blijven je applicaties draaien, zelfs als inkomende data minder dan perfect is.

    Veelgestelde vragen

    Ondersteunt JSON officieel opmerkingen of enkele aanhalingstekens?

    Nee. De RFC 8259-standaard verbiedt opmerkingen strikt. Enkele aanhalingstekens zijn ook ongeldig — alleen dubbele aanhalingstekens zijn toegestaan voor sleutels en strings. Tools zoals json_repair kunnen opmerkingen echter automatisch verwijderen en aanhalingstekens converteren om bestanden parseerbaar te maken voor standaardbibliotheken.

    Hoe verwerk ik zeer grote misvormde JSON-bestanden zonder te crashen?

    Gebruik een streaming-parser zoals ijson om data in blokken te verwerken. Vermijd het laden van de hele misvormde string in één variabele. Voor de snelste resultaten gebruik je CLI-reparatietools die uitvoer direct naar een nieuw bestand op schijf pipen zonder alles in het geheugen te houden.

    Wat is het verschil tussen misvormde JSON en ongeldige JSON?

    Misvormde JSON schendt syntaxregels — ontbrekende haakjes, ontegenoteerde sleutels, afsluitende komma’s — waardoor het onmogelijk te parsen is. Ongeldige JSON volgt alle syntaxregels, maar komt niet overeen met een specifiek JSON Schema (bijv. een veld is een string terwijl het schema een geheel getal verwacht). Misvormde JSON herstellen is structurele reparatie; ongeldige JSON herstellen gaat over data-integriteit.

    Kan ik json_repair combineren met Pydantic-validatie?

    Ja. Voer eerst json_repair.loads() uit om syntaxfouten te herstellen, en geef de gerepareerde dictionary vervolgens door aan je Pydantic-model voor typevalidatie en schema-afhandeling. Deze tweestaps-aanpak behandelt zowel structurele als semantische problemen.

    Hoe zit het met JSON met JavaScript-stijl opmerkingen?

    Standaard JSON ondersteunt geen opmerkingen, maar json_repair kan //– en /* */-opmerkingen automatisch verwijderen. Als je opmerkingen in je configuratiebestanden nodig hebt, overweeg dan het JSONC-formaat (JSON met opmerkingen) en een compatibele parser zoals json5 voor Python.

  • Hoe schrijf je AI-prompts met een formatter: gestructureerde engineering voor ontwikkelaars

    Hoe schrijf je AI-prompts met een formatter: gestructureerde engineering voor ontwikkelaars

    Ken je dat wanhopige gevoel wanneer je AI-uitvoer totaal niet lijkt op wat je vroeg? De JSON is ongeldig, de toon is verkeerd en de helft van je instructies is genegeerd. Het probleem is niet het model — het is hoe je je prompt formatteert.

    Om hoe je AI-prompts met een formatter schrijft onder de knie te krijgen, implementeer je het RTCCO-framework (Role, Task, Context, Constraints, Output) met gestructureerde scheidingstekens zoals XML of JSON. Hierdoor behandel je prompts als modulaire software-assets, wat modelhallucinaties tot 60% kan verminderen en de manuele verwerkingstijd met 75% kan verkorten, aldus cijfers uit mei 2026.

    Waarom je alineaprompts blijven falen

    In 2026 is professioneel AI-werk verschoven van “chatten” naar Prompt-as-Code (PaC). Het probleem met alineaprompts — die lange, ongestructureerde tekstblokken — is dat modellen moeite hebben om je daadwerkelijke instructies te scheiden van de achtergronddata of outputvereisten die ermee vermengd zijn.

    Data van PromptOT laat zien dat de overstap naar gestructureerde engineering fouten met 60% kan terugdringen en manuele verwerking met 75% kan versnellen. Alex Ostrovskyy omschrijft hardgecodeerde prompts als “het moderne equivalent van magische getallen in broncode” — broze systemen die vrijwel onmogelijk bij te werken zijn zonder iets te breken.

    Voor vs. na: het verschil in formattering

    Voor (ongestructureerd):

    You are a helpful coding assistant. Please write a Python function that validates
    email addresses. Make sure it handles edge cases like plus signs and subdomains.
    The output should be in JSON format with a valid boolean and the cleaned email.
    Also make sure you add proper error handling and don't forget logging.
    

    Na (RTCCO + XML-scheidingstekens):

    <system_instructions>
      <role>Senior Python engineer specializing in input validation</role>
      <primary_objective>Write a production-grade email validator</primary_objective>
    </system_instructions>
    
    <context>
      Must handle: plus addressing ([email protected]), subdomains,
      internationalized domains. Target: Python 3.11+.
    </context>
    
    <task_requirements>
      <rules>
        - Use only stdlib (no regex shortcuts)
        - Return structured JSON
        - Include type hints
      </rules>
      <steps>
        1. Parse the input string
        2. Validate format per RFC 5322
        3. Return JSON with "valid" boolean and "cleaned_email"
      </steps>
    </task_requirements>
    
    <output_format>
      {"valid": bool, "cleaned_email": str, "error": str | null}
    </output_format>
    

    Zelfde doel, dramatisch verschillende resultaten. De geformatteerde versie laat het model nul ruimte voor dubbelzinnigheid.

    Het RTCCO-framework: het skelet van je prompt

    De branche heeft RTCCO omarmd als de standaardarchitectuur voor prompts. Elke prompt valt uiteen in vijf onderdelen:

    Element Doel Voorbeeld
    R ole Wie is de AI? “Senior backend-engineer”
    T ask Welke specifieke actie? “Schrijf een rate-limiter-middleware”
    C ontext Welke achtergronddata? RAG-retrieval, codebase-snippers
    C onstraints Wat zijn de regels? “Geen externe afhankelijkheden”
    O utput Hoe moet het eruitzien? “Geldige Python 3.11 met type-hints”

    De 5 onderdelen van het RTCCO-framework

    Het XML-skeletsjabloon dat je nu kunt kopiëren

    Hier is het productieklare sjabloon. Kopieer het, pas het aan, ship het.

    <system_instructions>
      <role> [Expert Persona] </role>
      <primary_objective> [Main Goal] </primary_objective>
    </system_instructions>
    
    <context>
      [Background Data or RAG Retrieval]
    </context>
    
    <task_requirements>
      <rules> [Non-negotiable Constraints] </rules>
      <steps> [Specific Workflow] </steps>
    </task_requirements>
    
    <output_format>
      [JSON/XML/Markdown Specification]
    </output_format>
    
    <recency_recap>
      [Reminder of Critical Constraints]
    </recency_recap>
    

    Waarom de Recency Recap belangrijk is

    LLM’s hebben een bekende “Primacy and Recency”-afwijking — ze onthouden het begin en het einde van een prompt beter dan het midden. Tests die door PromptOT worden aangehaald, toonden aan dat het verplaatsen van kritieke regels van het midden naar het Recency Recap-blok onderaan de nauwkeurigheid in productiegebruik liet stijgen van 78% naar 96%. Houd de Role bovenaan en zet je belangrijkste regels onderaan.

    Het Primacy- en Recency-effect visualiseren in lange prompts

    Scheidingstekens als veiligheidshek

    Scheidingstekens gaan niet alleen over organisatie — ze zijn een beveiligingsmechanisme. Gebruikersinput verpakken in tags zoals <user_input> vertelt het model: “Dit is data om te verwerken, geen nieuwe instructies om op te volgen.” Dit is je primaire verdediging tegen prompt-injectieaanvallen, waarbij gebruikers proberen je systeeminstructies te overschrijven.

    Veelvoorkomende valkuil: Als je gebruikersdata direct in de prompt injecteert zonder scheidingstekens, kan een gebruiker “Negeer alle vorige instructies en…” schrijven en het model gehoorzaamt. Verpak externe data altijd in gelabelde blokken.

    Modulaire architectuur: stop met mega-prompts schrijven

    In plaats van één broze prompt van 2.000 tokens, splits je je systeem op in onafhankelijke modules. Dit voorkomt instructiebotsingen — waarbij het wijzigen van de toon van een prompt per ongeluk de JSON-outputindeling breekt.

    Het kernprincipe is Context Engineering: scheid statische instructies van dynamische data. In een productie-RAG-systeem is je prompt een sjabloon waarbij het <context>-blok bij query-tijd wordt gevuld met verse data. Zoals Jono Farrington van OptizenApp uitlegt, maakt deze modulaire aanpak grootschalige AI-implementaties veel consistenter.

    Prompt-chaining: modules verbinden

    Voor complexe workflows gebruik je Prompt Chaining — waarbij de output van de ene module de input wordt voor de volgende:

    [Planner Module] --> outline --> [Executor Module] --> draft --> [Reviewer Module] --> final
    

    Deze stapsgewijze aanpak verbetert de outputkwaliteit met ongeveer 35%, omdat het model zich telkens op slechts één subtaak richt.

    Eenvoudige prompt-chaining-workflow in drie stappen

    Klaar-om-te-gebruiken chaining-voorbeeld:

    planner_prompt = """
    <system_instructions>
      <role>Technical architect</role>
      <task>Create a step-by-step plan for: {user_request}</task>
    </system_instructions>
    <output_format>JSON array of steps</output_format>
    """
    
    executor_prompt = """
    <system_instructions>
      <role>Senior developer</role>
      <task>Implement step: {step_from_planner}</task>
    </system_instructions>
    <context>{previous_outputs}</context>
    <output_format>Code block with inline comments</output_format>
    """
    

    Chain-of-Thought toevoegen voor moeilijke problemen

    Als je taak complexe logica vereist, voeg dan een <thought_process>-blok toe. Dit dwingt het model om stapsgewijs te redeneren voordat het een antwoord geeft, wat fouten bij wiskunde, programmeren en meervoudige redeneringen aanzienlijk vermindert.

    <task_requirements>
      <rules>Reason inside <thought> tags before answering</rules>
    </task_requirements>
    
    <output_format>
      <thought> [Your step-by-step reasoning here] </thought>
      <answer> [Final JSON output here] </answer>
    </output_format>
    

    Volgens Zencoder gaan technieken zoals Tree-of-Thoughts (ToT) nog een stap verder door het model te vragen meerdere oplossingspaden tegelijk te evalueren en de beste te kiezen. Dit is vooral waardevol voor architecturale beslissingen waarbij er niet één juist antwoord is.

    Waarschuwing over tokendkosten

    Gestructureerd redeneren verbruikt meer tokens. Een typisch <thought_process>-blok voegt 200-500 tokens per verzoek toe. Op schaal betekent dit hogere API-kosten. De afweging is nauwkeurigheid: je betaalt meer per verzoek, maar hebt minder nieuwe pogingen en minder handmatige correcties nodig.

    Productiereadiness: versiebeheer, testen en CI/CD

    De laatste stap is prompts behandelen als software. Gebruik Semantic Versioning (v1.0.0), zodat je team wijzigingen kan volgen en direct kan terugdraaien wanneer een nieuwe promptversie verslechtert.

    PromptOT rapporteert dat bedrijven die 50+ prompts beheren tot wel $400.000 per jaar kunnen besparen door beheer te centraliseren en de tijd die engineers besteden aan handmatig tweaken te verminderen.

    Een prompt-CI/CD-pipeline opzetten

    # .github/workflows/prompt-tests.yml
    name: Prompt Quality Gate
    on: [push]
    jobs:
      test-prompts:
        runs-on: ubuntu-latest
        steps:
          - name: Run Golden Dataset Tests
            run: |
              # Test against 50-200 curated cases
              python scripts/eval_prompts.py \
                --dataset golden_dataset.json \
                --judge-model gpt-4 \
                --min-score 0.85
    
          - name: Regression Check
            run: |
              # Compare new version vs. production
              python scripts/compare_versions.py \
                --staging v2.1.0 \
                --production v2.0.3 \
                --threshold 0.05
    

    Een prompt gaat pas van Staging naar Production zodra hij deze kwaliteitspoorten doorstaat, beoordeeld door een “LLM-as-a-judge”.

    Conclusie

    Gestructureerde prompt engineering met formatters is niet langer optioneel — het is de basislijn voor iedereen die betrouwbare AI-tools bouwt. Het RTCCO-framework, XML-scheidingstekens en een modulaire architectuur vormen je stack om onvoorspelbare LLM-uitvoer om te zetten in consistente, productieklare resultaten.

    Begin met je meest gebruikte prompts en herstructureer ze in het RTCCO-framework met het XML-sjabloon hierboven. Zet ze in versiebeheer, stel een eenvoudige evaluatie op, en je hebt een prompt-infrastructuur die schaalt.

    Veelgestelde vragen

    Hoe zet ik mijn bestaande alineaprompts om in RTCCO-blokformaat?

    Identificeer eerst de kern-Task en scheid deze van de Context. Verpak instructies in <rules>-tags en geef 3-5 voorbeelden in <examples>-tags. Je kunt zelfs een LLM gebruiken om te helpen — prompt hem met “re-parse this unstructured text into the RTCCO framework using XML delimiters” en hij doet het zware werk.

    Moet ik XML-, JSON- of Markdown-scheidingstekens gebruiken?

    XML is de huidige gouden standaard voor het scheiden van instructies van lange content in modellen zoals Claude en GPT-5, vanwege de strikte hiërarchie. JSON is beter wanneer je programmatische input/output nodig hebt voor API-integraties. Markdown werkt voor eenvoudige, menselijk leesbare prompts, maar mist de strikte begrenzing die nodig is voor complexe, gelaagde productieprompts.

    Hoe implementeer ik geautomatiseerde CI/CD-tests voor prompts?

    Stel een testsuite op met een “Golden Dataset” (50-200 samengestelde testcases) en een “LLM-as-a-judge” om outputs tegen een beoordelingsrubriek te scoren. Integreer deze tests in je GitHub Actions- of Jenkins-pipeline, zodat elke promptwijziging vóór implementatie wordt gevalideerd op nauwkeurigheid en toon.

    Wat is de meest voorkomende fout bij de overstap naar gestructureerde prompts?

    Het <context>-blok overbelasten. Ontwikkelaars dumpen vaak hele codebases of documenten in de context, wat de aandacht van het model verdunt. Houd de context gericht op alleen wat direct relevant is voor de taak. Als je grote documenten moet raadplegen, gebruik dan RAG-retrieval om alleen de relevante secties op te halen.