Enterprise RAG Challenge 3: lessen uit openbare inzendingen

Automatische vertaling

Dit artikel is automatisch vertaald vanuit de oorspronkelijke Engelse versie.

Enterprise RAG Challenge 3 (ERC3) vroeg agents om zakelijke taken uit te voeren tegen de API van een gesimuleerd bedrijf. Het bevroren prijsklassement is ongewoon nuttig, omdat veel deelnemers meer publiceerden dan een score: architectuur, modelkeuze, kosten en notities over wat misging.

Ik heb die openbare beschrijvingen doorgenomen om een smallere vraag te beantwoorden: welke ontwerpkeuzes kwamen terug in sterke inzendingen, en welke daarvan zijn ook buiten deze benchmark bruikbaar?

Dit artikel is bedoeld voor engineers die agents bouwen die business-APIs aanroepen. Je ziet vijf ontwerpen uit de openbare verslagen, de problemen die elk ontwerp oploste (rechten, paginering, ontbrekende links, contextgrootte) en een volgorde waarin je ze in je eigen agent kunt uitproberen.

Wat is de Enterprise RAG Challenge?

De Enterprise RAG Challenge 3 is een grootschalig, gecrowdsourcet onderzoeksproject dat test hoe autonome AI agents omgaan met complexe zakelijke taken. In tegenstelling tot statische benchmarks draait ERC3 op de Agentic Enterprise Simulation (AGES), een discrete-eventsimulatie die een realistische bedrijfs-API beschikbaar stelt.

Wat de benchmark test

Via AGES werken agents binnen een nepbedrijf met:

  • Medewerkersprofielen met specifieke vaardigheden en afdelingen
  • Projecten met teamtoewijzingen en klantrelaties
  • Een bedrijfswiki met bedrijfsregels en rechtenhiërarchieën
  • Tijdregistratie en financiële handelingen

Elke taak start een geïsoleerde simulatie. De bedrijfswiki wordt gedeeld, maar de operationele gegevens verschillen per taak, dus een agent kan de testset niet oplossen door één bedrijfstoestand uit het hoofd te leren.

Lees de scores als momentopname

ERC3 toont nu zowel een bevroren wedstrijdklassement als een openbare benchmark die ook na het evenement runs bleef ontvangen. Die pagina’s beantwoorden verschillende vragen. De cijfers hieronder beschrijven het prijsklassement op het moment van de afsluiting van de wedstrijd, niet latere sessions met betere resultaten:

MaatstafMomentopname van de wedstrijd
Prijsinzendingen38
Takenset103 zakelijke taken
Hoogste prijsscore0.718
Sluiting prijsronde9 december 2025, 13:40 CET

De pagina van de live benchmark kan hogere scores tonen, omdat die ook latere runs bevat. Daarom is het bevroren klassement de juiste bron voor beweringen over wat de wedstrijd won. Het Ultimate-klassement neemt de beste run van elk account zonder de afsluiting van de wedstrijd, dus die scores zijn niet vergelijkbaar met prijsscores.

Soorten taken

De taken beslaan meerdere vaardigheidsgebieden:

  • Multi-hop reasoning, zoals het koppelen van vaardigheden van medewerkers aan projecttoewijzingen.
  • Rechtenvalidatie, zoals het blokkeren van ongeautoriseerde salariswijzigingen of toegang tot gegevens.
  • Dubbelzinnige vragen, waaronder meertalige en geparafraseerde verzoeken.
  • Strikte naleving van het uitvoerformaat, waaronder verplichte entiteitslinks in antwoorden.

Wat de inzendingen suggereren

De openbare verslagen ondersteunen geen eenduidig oordeel zoals “multi-agent verslaat single-agent”. De inzending op de vierde plaats in het prijsklassement, MMzXeM, was één agent met tools die 1:1 overeenkwamen met de API-endpoints, een ask_wiki-tool en een system prompt van 320 tokens. De verslagen ondersteunen wel vier smallere observaties:

  1. Teams splitsten een component af wanneer die één eis beheerde waar agents steeds op faalden: een rechtencontrole, stapvalidatie, code-uitvoering of entiteitslinks. Ze splitsten niet op basis van willekeurige “agentrollen”.
  2. Validatie verschoof naar onomkeerbare acties. Meerdere systemen controleerden rechten vóór de uitvoering, beoordeelden afzonderlijke stappen of bewaakten het eindantwoord.
  3. Mislukte traces stuurden de wijzigingen aan. De prijswinnaar zette mislukte runs om in prompt-herzieningen via een geautomatiseerde lus; andere teams documenteerden vergelijkbaar concrete verbeteringen aan tools en prompts.
  4. Contextbeleid was een architectuurkeuze. Teams probeerden distillatie, preloading, retrieval en geschiedeniscompressie. Hun eigen verslagen spreken elkaar tegen over de vraag of compressie hielp, dus er is geen universeel recept.

Vijf leerzame aanpakken

Dit zijn niet de eerste vijf in volgorde van ranglijst. Ik heb ze gekozen omdat hun openbare beschrijvingen vijf verschillende manieren laten zien om het systeem te bouwen: automatische promptherziening, gespecialiseerde stappen, validatie per stap, guards voor het antwoord en plan-execute-isolatie.

TeamContext in klassementGepubliceerde score
VZS9FLPrijs, 1e0.718
LcnxuyPrijs, 8e0.505
NLN7DwPrijs, 2e0.621
J8GvbiPrijs, 16e0.437
5qsp7i (key_concept_parallel)Ultimate, 3e0.670

1. Evolutionaire prompt engineering (Team VZS9FL / @aostrikov)

De aanpak met de hoogste score automatiseerde prompt engineering met een zelfverbeterende lus.

Promptversies v1 tot v80 en één lus: de hoofdagent logt mislukte taken, de analyzer stelt oorzaken voor, de versioner houdt er enkele en schrijft de volgende versiePromptversies v1 tot v80 en één lus: de hoofdagent logt mislukte taken, de analyzer stelt oorzaken voor, de versioner houdt er enkele en schrijft de volgende versie

In plaats van de productieprompt met de hand af te stellen, bouwde het team een lus met drie agents die mislukte traces omzette in kandidaat-herzieningen.

Pipeline met drie agents:

AgentRol
Main AgentDraait de benchmark en logt alle acties en fouten
Analyzer AgentBeoordeelt mislukte taken en formuleert hypotheses over de grondoorzaak
Versioner AgentGenereert een nieuwe promptversie met de opgedane inzichten

De productieprompt was de 80e automatisch gegenereerde versie. Het team beschrijft de lus als het analyseren van mislukte taken, het voorstellen van oorzaken en het beslissen welke suggesties worden overgenomen. Het klassement stelt de eindscore en het aantal iteraties vast. Het scheidt niet hoeveel van de winst kwam van de automatisering in plaats van van de models, de tools of de opgebouwde benchmarkfeedback.

Stack: claude-opus-4.5 met de Anthropic Python SDK en native tool use.


2. Sequentiële multi-agent-pipeline (Team Lcnxuy / @andrey_aiweapps)

Deze inzending bouwde een sequentiële workflow waarin gespecialiseerde componenten de beveiligingscontroles, contextextractie, uitvoering en opmaak van entiteitslinks verzorgden.

Vier fasen van beveiligingscontrole tot response-tool, de vijf uitvoeringsfasen en twee antwoorden: één zonder links, één met links gebouwd in de response-toolVier fasen van beveiligingscontrole tot response-tool, de vijf uitvoeringsfasen en twee antwoorden: één zonder links, één met links gebouwd in de response-tool

De gedocumenteerde componenten:

  1. Security Gate Agent: controle vóór de uitvoering die rechten valideert tegen de wikiregels voordat de hoofdlus draait.
  2. Context Extraction Agent: haalt de kritieke regels uit system prompts van meer dan 500 regels en laadt gebruikers-, project- en klantgegevens vooraf.
  3. Execution Agent: planning in ReAct-stijl met 5 interne fasen (identiteit → dreigingsdetectie → informatie verzamelen → toegangsvalidatie → uitvoering).
  4. LinkGeneratorAgent: ingebouwd in de response-tool; parset de context om de vereiste entiteitslinks op te nemen.

Volgens het verslag van het team diende de LinkGeneratorAgent om ontbrekende links te voorkomen: antwoorden met de juiste tekst maar zonder de vereiste entiteitslinks. Dit is het best overdraagbare onderdeel. Door de agent in de response-tool te plaatsen wordt een benchmarkeis (verplichte entiteitslinks) een eigenschap van de interface, in plaats van nog een instructie die het uitvoerende model kan vergeten.

Stack: de frameworks atomic-agents en instructor met gpt-5.1-codex-max, gpt-4.1 en claude-sonnet-4.5.


3. Schema-guided reasoning met stapvalidatie (Team NLN7Dw / Ilia Ris)

Schema-guided reasoning (SGR) laat het model bij elke stap een vast uitvoerschema invullen, bijvoorbeeld de reasoning, een plan en de volgende tool call, zodat het programma elk veld kan lezen en controleren. Het SGR-artikel op deze blog laat zien hoe je zo’n schema afdwingt met vLLM. Dit team combineerde SGR met snelle inference en een validator op elke voorgestelde stap. Dat ontwerp maakt herziening goedkoop: verwerp een gebrekkige stap voordat die een tool call wordt en laat de hoofdstroom hem opnieuw uitwerken met de opmerkingen van de validator.

Het model leest het plan, de records en de gecomprimeerde geschiedenis, schrijft één stap als schema, en de StepValidator stuurt een foutieve stap terug vóór elke tool callHet model leest het plan, de records en de gecomprimeerde geschiedenis, schrijft één stap als schema, en de StepValidator stuurt een foutieve stap terug vóór elke tool call

Belangrijkste componenten:

ComponentFunctie
StepValidatorInspecteert elke voorgestelde stap. Klopt er iets niet, dan gaat de stap met opmerkingen terug voor herwerking.
ContextbeheerVolledig plan van de vorige beurt, plus gecomprimeerde geschiedenis voor oudere beurten
Dynamische verrijkingHaalt automatisch gebruikersprofiel, projecten en klanten op; een LLM filtert zodat alleen taakrelevante gegevens worden toegevoegd
Wrappers voor automatische pagineringAlle lijst-endpoints geven automatisch de volledige resultaten terug

Het team meldde dat het gpt-oss-120b op Cerebras draaide met tot ongeveer 3.000 tokens per seconde. Het team combineerde validatie met inference met hoge throughput, wat de kosten in latency mogelijk heeft verlaagd. Het openbare resultaat scheidt dat effect niet.

Stack: een aangepaste NextStep-agent, de SGR-voorbeeldagent die voor ERC3 is gepubliceerd.


4. Enricher- en guardsysteem (Team J8Gvbi / @mishka)

Deze inzending voegde niet-blokkerende hints en een gelaagd guardsysteem toe aan een SGR-basis. Naarmate API-antwoorden binnenkwamen, inspecteerden enrichers ze en voegden ze operationele aanwijzingen toe aan de latere context. De guards controleerden het antwoord van de agent voordat het werd ingediend.

Twee enrichers zetten API-antwoorden om in hints, daarna drie guardmodi: hard block weigert, soft block accepteert een herhaald antwoord, soft hint accepteert met adviesTwee enrichers zetten API-antwoorden om in hints, daarna drie guardmodi: hard block weigert, soft block accepteert een herhaald antwoord, soft hint accepteert met advies

Meer dan 20 enrichers inspecteerden API-antwoorden en voegden contextuele hints toe:

RoleEnricher: "You are LEAD of this project, proceed with update."
PaginationHintEnricher: "next_offset=5 means MORE results! MUST paginate."

Guardsysteem met drie modi:

ModusGedrag
Hard blockEen antwoord dat volgens de API-gegevens onmogelijk is, zoals een antwoord dat een medewerker buiten het projectteam noemt, wordt geweigerd
Soft blockEen riskant antwoord wordt eenmaal geweigerd met een waarschuwing en geaccepteerd als de agent het na die waarschuwing opnieuw indient
Soft hintEr wordt een aanwijzing toegevoegd zonder te blokkeren

Hybrid RAG-wiki: het team doorzocht een lokale kopie van de bedrijfswiki op drie manieren: regex voor gestructureerde patronen zoals salary|privacy, sentence-transformer-embeddings voor semantische treffers en tokenoverlap als terugvaloptie op trefwoorden. Mijn lezing van waarom drie: regex vindt exacte veldnamen en termen, en embeddings vinden regels die anders zijn geformuleerd dan de vraag.

Stack: qwen/qwen3-235b-a22b-2507 op het SGR-framework van LangChain.


5. Plan-execute-REPL (Team 5qsp7i / key_concept_parallel)

Deze architectuur hield planning en het schrijven van code gescheiden in aparte modelaanroepen. Gegenereerde Python draait in een REPL (read-eval-print loop): een Python-session die haar variabelen tussen stappen behoudt. De inzending stond in het bredere Ultimate-klassement, niet in de bevroren top vijf van de prijzen. De openbare beschrijving blijft nuttig, omdat ze een andere vorm van opdeling laat zien: isolatie per uitvoeringsfase in plaats van per bedrijfsrol.

Planner, codemodel, REPL en beslismodel met hun uitkomsten, en een trace van vier stappen waarin een replan stap 3 en 4 herschrijft maar de REPL-variabelen s1 en s2 behoudtPlanner, codemodel, REPL en beslismodel met hun uitkomsten, en een trace van vier stappen waarin een replan stap 3 en 4 herschrijft maar de REPL-variabelen s1 en s2 behoudt

Verschillende models deden verschillende taken: één maakte het plan, één schreef Python en een apart beslismodel koos wat er na elke stap moest gebeuren.

Opzet met meerdere models:

FaseModel
Planningopenai/gpt-5.1
Codegeneratiedeepseek/deepseek-v3.2
Beslissing na stapopenai/gpt-4.1
Eindantwoordopenai/gpt-4.1

De REPL voor het voltooien van een stap:

  1. De planner maakt een stap op hoog niveau.
  2. Het codegeneratiemodel werkt in een verse modelcontext en schrijft er een Python-script voor.
  3. Het script draait in een REPL die aan de taak is gekoppeld en waarvan de variabelen over stappen heen blijven bestaan.
  4. Het beslismodel bekijkt het resultaat en kiest een van vier uitkomsten: doorgaan met de volgende stap, afronden omdat de taak klaar is, afbreken omdat die is mislukt, of opnieuw plannen.

Het replan-pad is het herbruikbare idee. Als een stapresultaat laat zien dat het plan niet meer past, kan het beslismodel het voltooide werk behouden en alleen de resterende planstappen herschrijven. In het diagram delen klaar en mislukt één uitgang naar het eindantwoord.


Patronen die in meerdere inzendingen terugkwamen

De implementaties verschilden, maar meerdere technische vraagstukken kwamen steeds terug in de openbare beschrijvingen.

Contextbeheer was expliciet

Geen enkel team kon het model elke regel, elk record en elke eerdere stap geven zonder een beleidskeuze te maken. De systemen verschilden in waar ze informatie filterden: vóór de run, bij retrieval of in de geschiedenis. Het diagram verdeelt de context van het model in vier delen en toont welk beleid elk deel bepaalt, wanneer het draait en welke teams het gebruikten.

De context verdeeld in wikiregels, records, zoekresultaten en beurtgeschiedenis, elk met zijn beleid, het moment waarop het draait en de teams die het gebruiktenDe context verdeeld in wikiregels, records, zoekresultaten en beurtgeschiedenis, elk met zijn beleid, het moment waarop het draait en de teams die het gebruikten

StrategieAanpakHet beste voor
RegeldistillatieWikiregels vooraf omzetten in compacte instructies met behoud van de beperkingenSlanke prompts, snelle start
Uitgebreid vooraf ladenGebruikers-, project- en klantgegevens laden vóór de uitvoeringMinder tool calls
Hybride RAGZoekstromen met regex, semantiek en trefwoordenComplexe retrieval-behoeften
GeschiedeniscompressieRecente beurten volledig houden, oudere geschiedenis comprimerenLange gesprekken

Afweging: NLN7Dw comprimeerde oudere beurten, terwijl f1Uixf meldde dat geschiedeniscompressie zijn experimenten schaadde en in plaats daarvan het volledige gesprek bewaarde. Behandel compressie als een gemeten keuze, niet als standaard. Sterke inzendingen verschilden ook in promptgrootte. Kc7F2N (3e prijs) hield zijn eigen instructies minimaal, vertrouwde op gedistilleerde wikiregels en bouwde zijn zoektools op embeddings. MMzXeM (4e prijs) hield de hoofdprompt op 320 tokens en plaatste de hele wiki achter zijn ask_wiki-tool, die op context caching leunde om goedkoop te blijven.


Controles vóór, tijdens en na de hoofdlus

Verschillende teams plaatsten controles vóór, tijdens of na de hoofdlus. Deze controles hebben in elke fase andere gegevens nodig. Eén gedeelde implementatie kan ze uitvoeren als die in elke fase de juiste invoer krijgt. Een critic die alleen voor de eindrespons wordt aangeroepen, kan een eerdere ongeautoriseerde tool call niet voorkomen. Het diagram plaatst elke controle op een tijdlijn van taak tot grader en toont wat de controle ziet en welke fout die voorkomt.

Een tijdlijn van taak tot grader met de beveiligingscontrole vóór de lus, een stapcontrole erin en de guard met drie modi erna, elk met wat het ziet en tegenhoudtEen tijdlijn van taak tot grader met de beveiligingscontrole vóór de lus, een stapcontrole erin en de guard met drie modi erna, elk met wat het ziet en tegenhoudt

Type guardrailWanneerVoorbeeld
Controles vóór uitvoeringVoordat de hoofdlus startSecurity Gate Agent valideert rechten tegen de wikiregels
Validators in de lusTijdens reasoningStepValidator controleert elke voorgestelde actie en start herwerking bij een gebrek
Guards na uitvoeringVóór de eindindieningHet guardsysteem met drie modi controleert het antwoord van de agent tegen API-gegevens en beleid

Tool wrappers

Meerdere teams veranderden de toollaag die het model ziet, in plaats van instructies over de ruwe API toe te voegen:

  • Auto-pagination: NLN7Dw haalde paginering uit elke tool. Eén functie doorloopt alle pagina’s en geeft de volledige lijst terug.
  • Fuzzy normalization: de toolparsers van J8Gvbi koppelen menselijke formuleringen aan API-namen, zodat “Willingness to travel” het veld will_travel wordt.
  • Schema cleanup: f1Uixf verwijderde ongebruikte velden uit tool schemas en breidde de parameterbeschrijvingen uit. NLN7Dw bouwde Req_LogTimeEntry opnieuw, de ene SDK-tool waarvan de velden in een andere volgorde stonden, omdat die volgorde het model in verwarring bracht.
  • Reasoning tools: xoDvsa (7e prijs, 0.515) voegde plan-, think- en critic-tools toe aan een gewone ReAct-agent. De critic-tool geeft structured output terug met eigen velden voor de reasoning.

Een wrapper verbergt paginering voor het model: de agent vraagt één keer om een lijst en list_all volgt next_offset totdat de waarde -1 is, de eindwaarde uit het officiële ERC3-voorbeeld. De code hieronder schetst stap 1 van de invoervolgorde aan het einde van dit artikel en is geen code van een team. respond bouwt de entiteitslinks op uit IDs die de agent heeft opgehaald en weigert een ID die hij nooit heeft gezien. Zo komt elke link uit code en wordt een verzonnen ID afgewezen voordat de grader die ziet.

# Stand-in for the benchmark API: 12 projects, 5 per page.
PROJECTS = [{"id": f"proj_{i}", "name": f"Project {i}"} for i in range(12)]

def call_api(endpoint: str, offset: int = 0, limit: int = 5) -> dict:
    page = PROJECTS[offset : offset + limit]
    more = offset + limit < len(PROJECTS)
    return {"items": page, "next_offset": offset + limit if more else -1}

def list_all(endpoint: str) -> list[dict]:
    """Follow next_offset until the API returns the terminal value -1."""
    items, offset = [], 0
    while offset != -1:
        page = call_api(endpoint, offset=offset)
        items.extend(page["items"])
        offset = page["next_offset"]
    return items

def respond(text: str, entity_ids: list[str], fetched: list[dict]) -> dict:
    """Build required links from IDs; refuse IDs the agent never fetched."""
    known = {row["id"] for row in fetched}
    unknown = [i for i in entity_ids if i not in known]
    if unknown:
        raise ValueError(f"unknown entity ids: {unknown}")
    return {"message": text, "links": [{"id": i} for i in entity_ids]}

projects = list_all("/projects/list")
assert len(projects) == 12  # three pages, one list
print(respond("You lead two projects.", ["proj_3", "proj_11"], projects))

De agent ziet nooit een paginagrens, en proj_11 van de derde pagina is een geldige link.


Faalwijzen en de structurele oplossingen die teams meldden

De verslagen noemen herhaaldelijk fouten waarbij de agent de API aanroept of bedrijfsbeleid toepast. De best herbruikbare oplossingen verplaatsten de eis naar code of naar een aparte validatiestap:

FaalwijzeBeschrijvingArchitectuuroplossing
Rechten omzeilenBeperkte acties uitvoeren zonder de rechten van de gebruiker te controlerenSecurity Gate Agent vóór de uitvoering; verplichte volgorde identiteit → rechten → uitvoering
Ontbrekende entiteitslinksCorrect tekstantwoord maar zonder de vereiste verwijzingslinksIngebouwde LinkGeneratorAgent in de response-tool
Onvolledige pagineringAlleen de eerste pagina van lijstresultaten verwerkenAuto-pagination wrappers voor alle lijst-endpoints
Lussen met tool callsHerhaalde aanroepen met kleine variatiesBeurtlimieten; duidelijkere tool schemas; modelkeuze getest op de werkelijke workflow
Te veel contextDe context vullen met irrelevante wikisectiesRule distillation; dynamisch filteren van context

Twee verslagen voegen detail toe aan de rij over loops. f1Uixf zag tool-calling loops met GPT-5 maar niet met het kleinere Qwen3-model. NLN7Dw stelde zijn beurtlimiet te laag in, waardoor 5 van de 103 taken niet werden afgerond, dus een beurtlimiet heeft ruimte nodig.


Een praktische adoptievolgorde

ERC3 is één gesimuleerd bedrijf, geen algemene ablatiestudie voor agents. Gebruik het als bron van ontwerphypotheses en test die hypotheses vervolgens op je eigen traces. Een verstandige adoptievolgorde is:

  1. Maak eerst de correctheid van de API deterministisch. Pagineer lijst-endpoints automatisch, normaliseer vage velden, valideer schemas en genereer vereiste links in de response-tool.
  2. Voeg controles toe waar een fout duur is. Controleer identiteit en rechten vóór een mutatie; valideer een stap vóór de uitvoering alleen als de extra modelaanroep fouten vangt die de kosten waard zijn.
  3. Schrijf een contextbeleid op. Bepaal wat vooraf wordt geladen, opgehaald, gecomprimeerd of letterlijk bewaard. Meet het beleid per taakdeel in plaats van alleen op tokenaantal.
  4. Zet mislukte traces om in regressietests. Classificeer de fout, verander één mechanisme en draai het getroffen deel opnieuw. Automatiseer promptherziening pas als die lus betrouwbaar is.
  5. Splits op wanneer het eigenaarschap duidelijker wordt. Een aparte component is gerechtvaardigd wanneer die een beperking kan beheren, een ander model of een andere tool kan gebruiken, of onafhankelijk kan worden getest, niet simpelweg omdat “multi-agent” capabeler klinkt.

De figuur hieronder schetst hoe elk falen er in een trace uitziet en wijst naar de oplossing die je als eerste probeert. De nummers komen overeen met de stappen hierboven.

Zeven fouten zoals ze in een trace eruitzien, elk met de oplossing die je als eerste probeert en het stapnummerZeven fouten zoals ze in een trace eruitzien, elk met de oplossing die je als eerste probeert en het stapnummer

Referenties