Enterprise RAG Challenge 3: lições das submissões públicas

Tradução automática

Este artigo foi traduzido automaticamente a partir da versão original em inglês.

O Enterprise RAG Challenge 3 (ERC3) pediu a agentes que concluíssem tarefas empresariais através da API de uma empresa simulada. A tabela de classificação congelada dos prémios é invulgarmente útil, porque muitos participantes publicaram mais do que uma pontuação: arquitetura, combinação de modelos, custo e notas sobre falhas.

Analisei essas descrições públicas para responder a uma pergunta mais restrita: que escolhas de design se repetiram nas submissões fortes, e quais delas são úteis fora deste benchmark?

Este artigo destina-se a engenheiros que constroem agentes que chamam APIs empresariais. Vai ver cinco designs das descrições públicas, os problemas que cada um resolveu (permissões, paginação, links em falta, tamanho do contexto) e uma ordem pela qual os experimentar no seu próprio agente.

O que é o Enterprise RAG Challenge?

O Enterprise RAG Challenge 3 é um projeto de investigação de grande escala, feito em crowdsourcing, que testa como agentes de AI autónomos lidam com tarefas empresariais complexas. Ao contrário dos benchmarks estáticos, o ERC3 corre sobre a Agentic Enterprise Simulation (AGES), uma simulação de eventos discretos que expõe uma API empresarial realista.

O que o benchmark testa

Através da AGES, os agentes trabalham dentro de uma empresa fictícia que tem:

  • Perfis de colaboradores com competências e departamentos específicos
  • Projetos com atribuições de equipa e relações com clientes
  • Wiki corporativa com regras de negócio e hierarquias de permissões
  • Registo de tempo e operações financeiras

Cada tarefa inicia uma simulação isolada. A wiki da empresa é partilhada, mas os registos operacionais variam consoante a tarefa, pelo que um agente não consegue resolver o conjunto de tarefas decorando o estado de uma única empresa.

Leia as pontuações como um instantâneo

O ERC3 expõe agora tanto uma tabela de classificação da competição, congelada, como um benchmark público que continuou a receber execuções depois do evento. Essas páginas respondem a perguntas diferentes. Os valores abaixo descrevem a tabela de classificação dos prémios no fecho da competição, não as melhores sessões posteriores:

MétricaInstantâneo da competição
Submissões a prémio38
Conjunto de tarefas103 tarefas empresariais
Pontuação mais alta0,718
Fecho dos prémios9 de dezembro de 2025, 13:40 CET

A página do benchmark ativo pode mostrar pontuações mais altas, porque inclui execuções posteriores. Por isso, a tabela congelada é a fonte certa para afirmações sobre o que ganhou a competição. A tabela Ultimate usa a melhor execução de cada conta sem o fecho da competição, pelo que as suas pontuações não são comparáveis com as dos prémios.

Tipos de tarefas

As tarefas abrangem várias áreas de competência:

  • Raciocínio multi-hop, como associar competências de colaboradores a atribuições de projetos.
  • Validação de permissões, como bloquear alterações salariais ou acessos a dados não autorizados.
  • Consultas ambíguas, incluindo pedidos multilingues e parafraseados.
  • Cumprimento estrito do formato de saída, incluindo links obrigatórios para entidades nas respostas.

O que as submissões sugerem

As descrições públicas não sustentam um veredicto simples como “multi-agent vence agente único”. A submissão em quarto lugar nos prémios, a MMzXeM, era um único agente com ferramentas mapeadas 1:1 para os endpoints da API, uma ferramenta ask_wiki e um system prompt de 320 tokens. As descrições sustentam, sim, quatro observações mais restritas:

  1. As equipas separaram um componente quando ele era responsável por um requisito que os agentes falhavam repetidamente: uma verificação de permissões, a validação de passos, a execução de código ou os links para entidades. Não separaram por “papéis de agente” arbitrários.
  2. A validação aproximou-se das ações irreversíveis. Vários sistemas verificaram permissões antes da execução, reviram passos individuais ou protegeram a resposta final.
  3. Os traces falhados orientaram as alterações. O vencedor dos prémios converteu execuções falhadas em revisões do prompt através de um ciclo automático; outras equipas documentaram correções igualmente concretas de ferramentas e prompts.
  4. A política de contexto foi uma escolha de arquitetura. As equipas experimentaram destilação, pré-carregamento, retrieval e compressão do histórico. Os relatórios delas discordam sobre se a compressão ajudou, pelo que não há uma receita universal.

Cinco abordagens informativas

Estas não são as cinco primeiras por classificação. Escolhi-as porque as descrições públicas mostram cinco formas distintas de construir o sistema: revisão automática de prompts, fases especializadas, validação por passo, guards de resposta e isolamento plan-execute.

EquipaContexto da classificaçãoPontuação publicada
VZS9FLPrémios, 1.º0,718
LcnxuyPrémios, 8.º0,505
NLN7DwPrémios, 2.º0,621
J8GvbiPrémios, 16.º0,437
5qsp7i (key_concept_parallel)Ultimate, 3.º0,670

1. Prompt engineering evolutivo (equipa VZS9FL / @aostrikov)

A abordagem com a pontuação mais alta automatizou o prompt engineering através de um ciclo de auto-melhoria.

Versões do prompt v1 a v80 e uma volta do ciclo: o agente principal regista as tarefas falhadas, o analisador propõe causas, o versionador guarda algumas e escreve a versão seguinteVersões do prompt v1 a v80 e uma volta do ciclo: o agente principal regista as tarefas falhadas, o analisador propõe causas, o versionador guarda algumas e escreve a versão seguinte

Em vez de afinar à mão o prompt de produção, a equipa construiu um ciclo de três agentes que transformava traces falhados em revisões candidatas.

Pipeline de três agentes:

AgenteFunção
Main AgentExecuta o benchmark, regista todas as ações e falhas
Analyzer AgentRevê as tarefas falhadas, formula hipóteses sobre as causas de fundo
Versioner AgentGera uma nova versão do prompt que incorpora o que foi aprendido

O prompt de produção foi a 80.ª versão gerada automaticamente. A equipa descreve o ciclo como a análise de tarefas falhadas, a proposta de causas e a decisão sobre quais sugestões incorporar. A tabela de classificação estabelece a pontuação final e o número de iterações. Não isola quanto do ganho veio da automatização e não dos modelos, das ferramentas ou do feedback acumulado do benchmark.

Stack: claude-opus-4.5 com o Anthropic Python SDK e tool use nativo.


2. Pipeline sequencial multi-agent (equipa Lcnxuy / @andrey_aiweapps)

Esta submissão construiu um fluxo sequencial em que componentes especializados tratavam das verificações de segurança, da extração de contexto, da execução e da formatação dos links para entidades.

Quatro fases, da verificação de segurança à ferramenta de resposta, as cinco fases de execução e duas respostas: uma sem os links, outra com os links construídos dentro da ferramenta de respostaQuatro fases, da verificação de segurança à ferramenta de resposta, as cinco fases de execução e duas respostas: uma sem os links, outra com os links construídos dentro da ferramenta de resposta

Os componentes documentados:

  1. Security Gate Agent: verificação prévia à execução, que valida as permissões face às regras da wiki antes de o ciclo principal começar.
  2. Context Extraction Agent: extrai as regras críticas de system prompts com mais de 500 linhas e pré-carrega dados de utilizadores, projetos e clientes.
  3. Execution Agent: planeamento ao estilo ReAct, com 5 fases internas (Identidade → Deteção de ameaças → Recolha de informação → Validação de acesso → Execução).
  4. LinkGeneratorAgent: embutido na ferramenta de resposta, analisa o contexto para incluir os links obrigatórios para entidades.

O relatório da equipa diz que o LinkGeneratorAgent existia para evitar falhas por links em falta: respostas com o texto certo, mas sem os links obrigatórios para entidades. É a parte mais transferível. Colocá-lo dentro da ferramenta de resposta faz de um requisito do benchmark (links obrigatórios para entidades) uma propriedade da interface, em vez de mais uma instrução que o modelo de execução pode esquecer.

Stack: os frameworks atomic-agents e instructor com gpt-5.1-codex-max, gpt-4.1 e claude-sonnet-4.5.


3. Schema-guided reasoning com validação de passos (equipa NLN7Dw / Ilia Ris)

O schema-guided reasoning (SGR) obriga o modelo a preencher, em cada passo, um schema de saída fixo, por exemplo o seu raciocínio, um plano e a tool call seguinte, para que o programa possa ler e verificar cada campo. O artigo sobre SGR deste blogue mostra como impor esse schema com vLLM. Esta equipa combinou o SGR com inferência rápida e um validador em cada passo proposto. O design torna a revisão barata: rejeitar um passo defeituoso antes de ele se tornar uma tool call e pedir ao fluxo principal que o refaça com os comentários do validador.

O modelo lê o plano, os registos e o histórico comprimido, escreve um passo como schema e o StepValidator devolve um passo com falhas antes de qualquer tool callO modelo lê o plano, os registos e o histórico comprimido, escreve um passo como schema e o StepValidator devolve um passo com falhas antes de qualquer tool call

Componentes principais:

ComponenteFunção
StepValidatorInspeciona cada passo proposto. Se algo estiver errado, devolve-o para ser refeito, com comentários.
Gestão de contextoPlano completo do turno anterior, mais histórico comprimido para os turnos mais antigos
Enriquecimento dinâmicoObtém automaticamente perfil de utilizador, projetos e clientes; o LLM filtra para injetar só dados da tarefa
Wrappers de paginação automáticaTodos os endpoints de listagem devolvem automaticamente resultados completos

A equipa reportou ter corrido o gpt-oss-120b na Cerebras a até cerca de 3000 tokens por segundo. A equipa combinou a validação com inferência de alto débito, o que pode ter reduzido o custo de latência. O resultado público não isola esse efeito.

Stack: um agente NextStep modificado, o agente de exemplo SGR publicado para o ERC3.


4. Sistema de enrichers e guards (equipa J8Gvbi / @mishka)

Esta submissão acrescentou a uma base SGR dicas não bloqueantes e um sistema de guards por níveis. À medida que as respostas da API chegavam, os enrichers inspecionavam-nas e acrescentavam orientações operacionais ao contexto seguinte. Os guards verificavam a resposta do agente antes de ser submetida.

Dois enrichers transformam respostas da API em dicas, depois três modos de guard: o bloqueio rígido rejeita, o bloqueio suave aceita uma resposta repetida, a dica suave aceita com orientaçãoDois enrichers transformam respostas da API em dicas, depois três modos de guard: o bloqueio rígido rejeita, o bloqueio suave aceita uma resposta repetida, a dica suave aceita com orientação

Mais de 20 enrichers inspecionavam as respostas da API e injetavam dicas contextuais:

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

Sistema de guards com três modos:

ModoComportamento
Hard blockUma resposta que os dados da API mostram ser impossível, como uma que nomeia um colaborador fora da equipa do projeto, é rejeitada
Soft blockUma resposta de risco é rejeitada uma vez com um aviso e aceite se o agente a submeter de novo depois desse aviso
Soft hintA orientação é acrescentada sem bloquear

Wiki com RAG híbrido: a equipa pesquisou uma cópia local da wiki da empresa de três formas: regex para padrões estruturados como salary|privacy, embeddings de sentence-transformer para correspondências semânticas e sobreposição de tokens como alternativa por palavras-chave. A minha leitura de porquê três: o regex encontra nomes de campos e termos exatos, e os embeddings encontram regras formuladas de forma diferente da pergunta.

Stack: qwen/qwen3-235b-a22b-2507 no framework SGR sobre LangChain.


5. REPL plan-execute (equipa 5qsp7i / key_concept_parallel)

Esta arquitetura manteve o planeamento e a escrita de código em chamadas de modelo separadas. O Python gerado corre num REPL (read-eval-print loop): uma sessão de Python que mantém as variáveis entre passos. Apareceu na tabela Ultimate, mais ampla, e não no top cinco congelado dos prémios. A sua descrição pública continua a ser útil, porque mostra uma forma diferente de decomposição: isolamento por fase de execução e não por papel de negócio.

Planeador, modelo de código, REPL e modelo de decisão com os seus resultados, e um trace de quatro passos em que um replaneamento reescreve os passos 3 e 4 mas mantém as variáveis do REPL s1 e s2Planeador, modelo de código, REPL e modelo de decisão com os seus resultados, e um trace de quatro passos em que um replaneamento reescreve os passos 3 e 4 mas mantém as variáveis do REPL s1 e s2

Modelos diferentes ficaram com tarefas diferentes: um planeava, outro escrevia Python e um modelo de decisão separado escolhia o que fazer após cada passo.

Configuração multimodelo:

FaseModelo
Planeamentoopenai/gpt-5.1
Geração de códigodeepseek/deepseek-v3.2
Decisão pós-passoopenai/gpt-4.1
Resposta finalopenai/gpt-4.1

O REPL de conclusão de passo:

  1. O planeador cria um passo de alto nível.
  2. O modelo de geração de código trabalha num contexto de modelo novo e escreve um script Python para esse passo.
  3. O script é executado num REPL limitado à tarefa, cujas variáveis persistem entre passos.
  4. O modelo de decisão analisa o resultado e escolhe um de quatro desfechos: continuar com o passo seguinte, terminar porque a tarefa está concluída, abortar porque falhou, ou replanear.

O caminho de replaneamento é a ideia reutilizável. Quando o resultado de um passo mostra que o plano já não serve, o modelo de decisão pode manter o trabalho concluído e reescrever apenas os passos restantes do plano. No diagrama, “concluído” e “falhou” partilham uma única saída para a resposta final.


Padrões que se repetiram nas submissões

As implementações diferiam, mas várias preocupações de engenharia surgiram repetidamente nas descrições públicas.

A gestão de contexto foi explícita

Nenhuma equipa podia dar ao modelo todas as regras, registos e passos anteriores sem fazer uma escolha de política. Os sistemas diferiam no ponto onde filtravam a informação: antes da execução, na pesquisa ou no histórico. O diagrama divide o contexto do modelo em quatro partes e mostra qual política controla cada uma, quando corre e que equipas a usaram.

O contexto dividido em regras da wiki, registos, resultados de pesquisa e histórico de turnos, cada um com a sua política, quando corre e as equipas que a usaramO contexto dividido em regras da wiki, registos, resultados de pesquisa e histórico de turnos, cada um com a sua política, quando corre e as equipas que a usaram

EstratégiaAbordagemMelhor para
Destilação de regrasPré-processar as regras da wiki em instruções compactas, preservando as restriçõesPrompts compactos, arranque rápido
Pré-carregamento intensivoCarregar dados de utilizador/projeto/cliente antes da execuçãoMinimizar tool calls
RAG híbridoFluxos de pesquisa por regex + semântica + palavras-chaveNecessidades de retrieval complexas
Compressão do históricoManter os turnos recentes completos, comprimir o histórico mais antigoConversas longas

Compromisso: a NLN7Dw comprimiu os turnos mais antigos, enquanto a f1Uixf reportou que a compressão do histórico prejudicou as suas experiências e manteve a conversa completa. Trate a compressão como uma escolha medida, não como predefinição. As submissões fortes também diferiram no tamanho do prompt. A Kc7F2N (3.º lugar nos prémios) manteve as suas instruções mínimas, apoiou-se em regras da wiki destiladas e construiu as suas ferramentas de pesquisa sobre embeddings. A MMzXeM (4.º lugar nos prémios) manteve o prompt principal em 320 tokens e pôs a wiki inteira atrás da sua ferramenta ask_wiki, que dependia de context caching para ser barata.


Verificações antes, durante e depois do ciclo principal

Várias equipas colocaram verificações antes, durante ou depois do ciclo principal. Estas verificações precisam de dados diferentes em cada fase. Uma implementação partilhada pode executá-las se receber os dados de entrada certos em cada fase. Um crítico invocado apenas para a resposta final não pode impedir um tool call não autorizado anterior. O diagrama situa cada verificação numa linha temporal da tarefa ao avaliador e mostra o que vê e a falha que impede.

Uma linha temporal da tarefa ao avaliador, com a verificação de segurança antes do ciclo, uma verificação de passo dentro dele e o guard de três modos depois, cada um com o que vê e o que travaUma linha temporal da tarefa ao avaliador, com a verificação de segurança antes do ciclo, uma verificação de passo dentro dele e o guard de três modos depois, cada um com o que vê e o que trava

Tipo de guardrailQuandoExemplo
Verificações antes da execuçãoAntes de o ciclo principal começarO Security Gate Agent valida as permissões face às regras da wiki
Validadores no cicloDurante o raciocínioO StepValidator verifica cada ação proposta e pede que seja refeita se estiver errada
Verificações após a execuçãoAntes da submissão finalO sistema de guards de três modos verifica a resposta do agente face aos dados da API e à política

Wrappers de ferramentas

Várias equipas alteraram a camada de ferramentas que o modelo vê, em vez de acrescentarem instruções sobre a API em bruto:

  • Auto-pagination: a NLN7Dw removeu a paginação de todas as ferramentas. Uma função percorre todas as páginas e devolve a lista completa.
  • Fuzzy normalization: os parsers de ferramentas da J8Gvbi mapeiam a linguagem humana para nomes da API, pelo que “Willingness to travel” passa a ser o campo will_travel.
  • Schema cleanup: a f1Uixf removeu campos não usados dos tool schemas e expandiu as descrições dos parâmetros. A NLN7Dw reconstruiu Req_LogTimeEntry, a única ferramenta do SDK cujos campos vinham noutra ordem, porque essa ordem confundia o modelo.
  • Reasoning tools: a xoDvsa (7.º lugar nos prémios, 0,515) acrescentou as ferramentas plan, think e critic a um agente ReAct simples. A ferramenta critic devolve structured output com campos de raciocínio dedicados.

Um wrapper oculta a paginação ao modelo: o agente pede uma lista uma vez, e list_all segue next_offset até o valor ser -1, o valor de fim usado no exemplo oficial do ERC3. O código abaixo ilustra o passo 1 da ordem de adoção no fim deste artigo; não é código de nenhuma equipa. respond cria os links para entidades a partir dos IDs obtidos pelo agente e rejeita um ID que nunca tenha visto. Assim, cada link vem do código, e um ID inventado é rejeitado antes de chegar ao avaliador.

# 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))

O agente nunca vê o limite de uma página, e proj_11, da terceira página, é um link válido.


Modos de falha e as correções estruturais reportadas pelas equipas

As descrições mencionam repetidamente falhas em que o agente chama a API ou aplica uma política da empresa. As correções mais reutilizáveis passaram o requisito para o código ou para um passo de validação dedicado:

Modo de falhaDescriçãoCorreção arquitetural
Contorno de permissõesExecutar ações restritas sem verificar as permissões do utilizadorSecurity Gate Agent pré-execução; sequência obrigatória Identidade → Permissões → Execução
Ligações a entidades em faltaResposta de texto correta, mas sem os links de referência obrigatóriosLinkGeneratorAgent embutido na ferramenta de resposta
Paginação incompletaProcessar apenas a primeira página dos resultados de uma listaWrappers de auto-pagination para todos os endpoints de listagem
Ciclos de tool callsChamadas repetidas com pequenas variaçõesLimites de turnos; tool schemas mais claros; modelo escolhido com teste no fluxo de trabalho real
Excesso de contextoEncher o contexto com secções irrelevantes da wikiDestilação de regras; filtragem dinâmica do contexto

Dois relatórios acrescentam detalhe à linha dos ciclos. A f1Uixf viu ciclos de tool calling com o GPT-5, mas não com o modelo Qwen3, mais pequeno. A NLN7Dw definiu o limite de turnos demasiado baixo, e 5 de 103 tarefas não terminaram, pelo que um limite de turnos precisa de margem.


Uma ordem prática de adoção

O ERC3 é uma única empresa simulada, não um estudo de ablação geral de agentes. Use-o como fonte de hipóteses de design e depois teste essas hipóteses nos seus próprios traces. Uma ordem de adoção sensata é:

  1. Torne primeiro determinística a correção da API. Pagine automaticamente os endpoints de listagem, normalize campos aproximados, valide schemas e gere os links obrigatórios dentro da ferramenta de resposta.
  2. Acrescente verificações onde um erro é caro. Verifique identidade e permissão antes de alterar dados; valide um passo antes da execução apenas quando a chamada extra ao modelo apanha falhas que compensam o seu custo.
  3. Escreva uma política de contexto. Decida o que é pré-carregado, recuperado, comprimido ou mantido textualmente. Meça a política por fatia de tarefas e não apenas por contagem de tokens.
  4. Transforme traces falhados em casos de regressão. Classifique a falha, altere um mecanismo e volte a executar a fatia afetada. Automatize a revisão de prompts só depois de esse ciclo ser fiável.
  5. Decomponha quando a responsabilidade ficar mais clara. Um componente separado justifica-se quando consegue ser responsável por uma restrição, usar outro modelo ou ferramenta, ou ser testado de forma independente, e não apenas porque “multi-agent” soa mais capaz.

A figura abaixo esboça o aspeto de cada falha num trace e aponta para a correção a tentar primeiro. Os números correspondem aos passos acima.

Sete falhas esboçadas como aparecem num trace, cada uma a apontar para a correção a tentar primeiro e o respetivo número de passoSete falhas esboçadas como aparecem num trace, cada uma a apontar para a correção a tentar primeiro e o respetivo número de passo

Referências