Meta-Engineering AI Systems · Parte 1

Meta-engineering de sistemas de AI: dos traces a uma memória melhor

Tradução automática

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

Este artigo inaugura Meta-Engineering AI Systems, um guia em seis partes sobre engenharia de AI em ciclo fechado: usar agentes para investigar falhas, testar alterações e utilizar os resultados para melhorar sistemas de AI.

O comportamento de uma aplicação de AI depende de mais do que do seu modelo. Os prompts, a informação obtida, a memória armazenada, as ferramentas e o código da aplicação influenciam o resultado. Quando uma resposta está errada, várias alterações podem parecer plausíveis. O problema de engenharia consiste em decidir qual delas ajuda, quanto custa e que outras coisas pode danificar.

Uso aqui meta-engineering para designar a conceção do próprio processo de melhoria: que evidências o agente vê, o que pode alterar, como testamos as suas propostas e quem decide se devem ser adotadas. Ciclo fechado descreve a forma como esse processo aprende com as suas experiências. Cada resultado informa o que tentamos ou utilizamos a seguir, incluindo quando uma alteração proposta falha.

Podemos automatizar esse trabalho por etapas. Uma pessoa pode especificar as alterações exatas a testar, definir um conjunto de alternativas permitidas para um algoritmo de pesquisa ou delegar a próxima proposta a um agente LLM. O executor testa cada candidato e preserva as evidências para a decisão seguinte. Esta série centra-se em integrar agentes nesse processo, mantendo a execução, a avaliação e a adoção sob controlo explícito.

A questão que atravessa as seis partes é saber quanto desse trabalho podemos delegar a um agente, mantendo fiáveis as evidências e a decisão de adotar uma alteração. Começaremos por mapear todo o sistema e, em seguida, construiremos uma pequena versão funcional à volta da memória do agente.

O que fecha o ciclo

É necessário ter em conta dois ciclos diferentes. Dentro de uma aplicação de agente, o ciclo de runtime escolhe uma ação, faz um tool call, observa o resultado e continua a tarefa atual do utilizador. O ciclo de melhoria funciona entre versões dessa aplicação. Investiga o comportamento de execuções concluídas e testa alterações destinadas a melhorar execuções futuras.

O ciclo de melhoria começa com evidências: uma resposta incorreta, uma alteração de estado indesejada, um custo excessivo ou outra falha observável. Um trace regista os passos que conduziram a esse resultado. O proposer escolhe um candidate, uma versão específica de uma alteração. Um executor executa o candidate em tarefas definidas e um avaliador verifica o comportamento resultante face aos requisitos. Na experiência ao vivo deste artigo, um agente LLM é o proposer:

Esta demonstração utiliza um proposer LLM: escolhe uma alteração a partir de falhas registadas; Python valida-a e testa-a, devolvendo depois os resultados. A revisão humana do release mantém-se separada.Esta demonstração utiliza um proposer LLM: escolhe uma alteração a partir de falhas registadas; Python valida-a e testa-a, devolvendo depois os resultados. A revisão humana do release mantém-se separada.

A avaliação informa uma decisão; não se autoriza a si própria. Alguém tem de decidir se o benefício medido justifica a adoção da alteração, incluindo os seus efeitos no custo, nas permissões e noutros comportamentos necessários. Nesta série começamos com um revisor humano. O proposer pode sugerir uma alteração, mas não pode reescrever as verificações, aumentar o seu próprio orçamento ou conceder a si próprio aprovação.

Existem dois caminhos de retorno. O histórico das experiências alimenta propostas posteriores, incluindo quando um candidate é rejeitado. Se um candidate for aprovado e adotado, o seu comportamento fornece novas evidências através da utilização. Manter uma alteração reversível é importante quando essas evidências contradizem a experiência original. Registar uma pontuação é apenas um passo; o ciclo fecha-se quando as evidências alteram aquilo que tentamos ou utilizamos a seguir.

Aquilo que está a ser melhorado é o target. Pode ser uma política de memória, uma pipeline de retrieval, código de seleção de ferramentas ou o programa que reúne o contexto de um modelo. O treino do modelo é outra intervenção possível. O ciclo pode funcionar com pesos do modelo fixos: o agente pode melhorar o programa envolvente sem treinar um modelo. Esta primeira demonstração já inclui o agente LLM externo. As partes seguintes reforçam o avaliador e testam se a pesquisa agentic compensa o seu custo face a métodos mais simples.

Escolher quanto da pesquisa delegar

Suponha que já sabe o que quer testar: comparar dois modelos numa etapa de extração ou testar os thresholds de memória 0.6, 0.7 e 0.8. Pode fornecer essas escolhas e automatizar a execução, a pontuação e o reporting. Depois de ler os resultados, escolhe a experiência seguinte. O ciclo de feedback funciona apesar de o sistema não ter inventado os candidates.

Utilizo quatro modos de trabalho para tornar visível essa divisão. A figura mostra uma forma de delegar progressivamente mais desenho de experiências: começar com escolhas exatas de modelos, permitir que o sistema pesquise settings e componentes aprovados ou pedir a um agente que investigue falhas e escolha a experiência seguinte. A pessoa especifica menos de cada tentativa, mantendo ainda assim as regras da pesquisa.

Quatro modos de trabalho, com uma área cada vez menor para escolhas de experiências especificadas pela pessoa e uma área cada vez maior para a pesquisa do sistema: comparação de modelos, pesquisa de configuração, pesquisa de componentes e investigação conduzida por um agente. A autoridade humana sobre objetivos, alterações permitidas, avaliação, orçamentos e adoção mantém-se. Cada modo regista as suas tentativas no mesmo experiment ledger.Quatro modos de trabalho, com uma área cada vez menor para escolhas de experiências especificadas pela pessoa e uma área cada vez maior para a pesquisa do sistema: comparação de modelos, pesquisa de configuração, pesquisa de componentes e investigação conduzida por um agente. A autoridade humana sobre objetivos, alterações permitidas, avaliação, orçamentos e adoção mantém-se. Cada modo regista as suas tentativas no mesmo experiment ledger.

Os nomes dos modos descrevem configurações práticas para esta série, e não uma escala de autonomia padrão da indústria. O que pode mudar e quem escolhe a alteração são decisões separadas. Os exemplos de search space do Optuna combinam a escolha do modelo com intervalos de parâmetros. A pesquisa de pipelines do Scikit-learn compara componentes alternativos através de uma grid search normal. Substituir um componente não torna, por si só, o processo mais agentic. As larguras da figura ilustram a divisão do trabalho nestes exemplos; não representam percentagens medidas de controlo ou esforço.

A investigação conduzida por um agente descreve a forma como a próxima tentativa é escolhida. O agente lê falhas e resultados anteriores, propõe uma alteração e adapta-se depois do teste. Isto segue a distinção apresentada nos padrões de workflow e de agentes da Anthropic: um processo predefinido pode automatizar a execução, enquanto um agente orienta os seus passos seguintes a partir do feedback. Também são possíveis métodos híbridos: o MIPROv2 do DSPy utiliza um modelo para propor instruções e Bayesian optimization para pesquisar as suas combinações. Uma comparação fixa de modelos não precisa de um proposer LLM; os seus resultados entram no ciclo de feedback quando orientam a experiência ou a versão do sistema seguinte.

As permissões de proposta, execução e adoção continuam separadas. Um agente pode preparar uma alteração para aprovação antes de cada execução ou testar alterações permitidas sem supervisão, enquanto uma pessoa revê a adoção. Uma lista de componentes aprovados continua a precisar de implementações compatíveis; a permissão para selecionar um adapter não inclui a permissão para escrever um. Em todos os modos, o agente permanece dentro das alterações permitidas, das verificações fixas e do orçamento, e não pode conceder a si próprio aprovação para deployment. Delegar mais trabalho também deixa espaço para supervisão: o estudo da Anthropic sobre agentes em produção descreve utilizadores que passam de aprovar ações individuais para monitorizar e intervir.

Todos os modos podem utilizar o mesmo experiment ledger: um registo de todas as alterações tentadas. Mantenha o candidate e o seu parent, a alteração exata e quem a forneceu, as versões do teste e do ambiente, o resultado, o custo e qualquer falha ou rejeição. Esse histórico permite a uma pessoa entregar a proposta seguinte a um agente — ou retomá-la — sem perder as evidências. As pontuações de versões diferentes dos testes continuam a ter de ser distinguidas.

Esta demonstração combina pesquisa de configuração com investigação conduzida por um agente. Definimos cinco settings, os testes, o orçamento e a regra de seleção. O agente escolhe valores e a hipótese seguinte a partir do feedback; Python executa os testes automaticamente. A revisão humana do release mantém-se separada. O repositório também aceita um candidate JSON fornecido por uma pessoa através de lab evaluate. Sweeps de modelos, adapters de componentes e código escrito por agentes são opções de design mais abrangentes para partes posteriores, não modos implementados nesta demonstração de memória.

Por que motivo analisar isto agora

O princípio do feedback é familiar na engenharia. O trabalho recente que me interessa coloca coding agents dentro do processo de investigação e experimentação. Dá-nos implementações concretas para analisar, em vez de nos pedir que partamos do princípio de que a melhoria autónoma funcionará.

O autoresearch de Karpathy especifica uma experiência compacta: modificar um programa de treino, executá-lo sob um orçamento fixo de tempo de treino, inspecionar o resultado de validação e registar se a tentativa foi mantida, descartada ou terminou com crash. As instruções separam o ficheiro de treino editável do código de avaliação fixo. Essa separação torna o trabalho proposto e o respetivo critério de sucesso inspecionáveis.

O Meta-Harness, um preprint de março de 2026, estuda um target diferente: o código que controla que informação uma aplicação LLM armazena, recupera e apresenta ao seu modelo. O seu proposer pode inspecionar, através de um filesystem, o source, as pontuações e os execution traces de candidates anteriores. O histórico das experiências torna-se material de trabalho para a investigação seguinte.

Estes projetos motivam a questão de engenharia desta série: quando um agente consegue investigar e propor alterações, o que tem de fazer o sistema envolvente para tornar essas experiências úteis? Mais tentativas, por si só, não estabelecem decisões melhores. Um avaliador fraco pode recompensar uma alteração prejudicial e um processo de pesquisa pode explorar repetidamente essa fraqueza. Testaremos o valor das propostas agentic face a alternativas mais simples, em vez de presumirmos que existe uma vantagem.

Como as seis partes constroem um sistema

Os artigos irão desenvolver um único projeto complementar cumulativo. Cada parte retoma uma questão deixada em aberto pela experiência anterior e acrescenta o mecanismo necessário para a investigar.

ParteQuestãoO que acrescenta ao mesmo sistema
1. Dos traces a uma memória melhorPodemos transformar uma falha numa melhoria que possa ser revista?Uma ferramenta de memória, um proposer LLM, experiências limitadas, feedback e evidências preservadas.
2. Torná-lo pontuávelO avaliador reconhece alterações úteis, incluindo aparentes ganhos que causam danos?Avaliação mais forte, falsos ganhos deliberados e verificações sobre o que as pontuações estabelecem.
3. O improvement harnessQue partes podemos reutilizar entre targets e modos de trabalho?Execução, histórico e permissões partilhados para proposers humanos, clássicos e LLM.
4. Comparar estratégias de pesquisaQuanto trabalho de proposta vale a pena delegar a um agente?Comparações com pesquisa humana e clássica sob orçamentos e alterações permitidas equivalentes.
5. Melhoria asseguradaQue evidências são suficientes para adotar um aparente vencedor?Testes adversariais mais profundos, adoção faseada e controlos de rollback.
6. Do histórico a dados de treinoAs experiências revistas podem melhorar um componente aprendido?Uma pequena experiência de treino de um verificador ou de uma policy, comparada com reparações mais simples.

As verificações de privacidade e a revisão humana pertencem à primeira versão. A Parte 5 reforça essa proteção à medida que o proposer ganha capacidades. Do mesmo modo, a Parte 6 investiga uma possível utilização das evidências acumuladas; cada parte anterior tem de continuar a ser útil sem treinar um novo modelo.

Dar ao agente externo um target pequeno e inspecionável

Imagine um assistente que se lembra dos dados de conta da Ada. A 1 de janeiro, aprende que ela vive em Berlim. A 3 de janeiro, aprende que vai mudar-se para Paris a 10 de janeiro. Quando lhe perguntam a cidade a 5 de janeiro, responde Paris.

A memória contém ambos os factos. A regra de retrieval dá prioridade ao facto recebido mais recentemente, sem verificar quando se torna válido. Esta é uma falha concreta que um agente de melhoria pode investigar.

Berlim continua válida a 5 de janeiro, apesar de a mudança futura para Paris ter sido comunicada mais recentemente.Berlim continua válida a 5 de janeiro, apesar de a mudança futura para Paris ter sido comunicada mais recentemente.

O target é deliberadamente apenas uma ferramenta de memória, não um assistente completo. Recebe factos preparados, armazena-os ou rejeita-os e recupera um valor para uma pergunta. O seu writer, o tratamento de datas, o retrieval e a seleção da resposta são Python normal. Deixamos a extração da conversa e a geração de respostas em linguagem natural fora desta experiência, para podermos identificar o que uma alteração de regra realmente fez.

O LLM está no ciclo externo da experiência Python. O agente recebe resultados de testes, decide que settings alterar e recebe de volta o resultado seguinte. As campanhas registadas utilizam um modelo real para escolher essas alterações.

Esta divisão permite testar o ciclo de engenharia sem introduzir uma segunda fonte de comportamento de modelo dentro da ferramenta de memória. Numa aplicação maior, ambos os ciclos poderiam utilizar modelos. Aqui, um LLM é suficiente para tornar o processo de melhoria agentic. Outro LLM pode desempenhar o mesmo papel de proposer; as suas propostas têm de seguir o mesmo schema e passar as mesmas verificações.

Inspecionar a experiência

O repositório complementar no GitHub contém o agente externo, a ferramenta de memória, os testes e relatórios compactos de três campanhas LLM reais. Os pedidos, respostas e traces completos estão disponíveis num arquivo de evidências com checksums. O relatório da experiência acompanha as alterações propostas, os resultados medidos e cada decisão de parar. Mais à frente no artigo, utilizaremos o repositório para executar uma campanha nova.

Compreender um teste antes de ler a pontuação

Um scenario é uma história de teste completa. Um event é uma ação enviada à ferramenta de memória: write, query ou delete. O scenario da mudança futura tem quatro events:

  1. Guardar city = Berlin, válido a partir de 1 de janeiro.
  2. Guardar city = Paris, recebido a 3 de janeiro, mas válido a partir de 10 de janeiro.
  3. Perguntar a cidade a 5 de janeiro. Esperar Berlim.
  4. Perguntar a cidade a 12 de janeiro. Esperar Paris.

Os inputs já estão estruturados. Por exemplo, o facto de Paris identifica o owner (north workspace, user ada), o subject (account), a property (city), o value (Paris) e a data de início de validade. As strings Berlim e Paris vêm de the test data, e não de um modelo que gere memórias a partir da conversa.

Confidence é uma pontuação fornecida, utilizada para decidir se um facto proposto deve ser armazenado. O writer compara-a com min_confidence. Uma proposta delivery = courier com pontuação 0.4 é rejeitada no threshold de base de 0.7, mas armazenada com um threshold de 0.2. A pontuação é fornecida pelo autor do teste; não é uma probabilidade medida de a proposta estar correta. Avaliamos a forma como a regra de armazenamento trata essas pontuações, não se um modelo consegue estimá-las de forma fiável.

Cada scenario começa com uma lista Python vazia de registos de memória. As atualizações aceites fecham o período de validade do valor anterior e acrescentam um novo registo. Depois das duas escritas relativas à cidade, os registos descrevem:

ValueReceivedValid fromValid until
Berlim1 de janeiro1 de janeiro10 de janeiro, excluído
Paris3 de janeiro10 de janeiroSem data de fim

A função de resposta devolve o primeiro registo recuperado que corresponde à property pedida. O avaliador compara esse value com a resposta esperada. Um scenario completo só passa se todas as respostas estiverem corretas e todas as verificações de regras de dados aplicáveis passarem. A eliminação, o isolamento do owner e as writes proibidas têm verificações explícitas a par da qualidade da resposta.

Os testes fornecem diretamente os IDs dos owners; esta demonstração não tem um sistema de autenticação. Um serviço real tem de obter esses IDs a partir do pedido autenticado. Rejeitar um input explicitamente identificado como uma instrução também não demonstra a deteção de instruções escondidas em texto normal.

Dar também um schema à memória

Os factos precisam das suas próprias regras. Utilizo Schema-Guided Agent Memory (SGAM) para o padrão em que os schemas governam o estado armazenado e o seu ciclo de vida. Aqui demonstramos uma pequena parte desse padrão: factos tipados, ownership, referências à origem, intervalos de validade e eliminação. O schema SGR posterior governará aquilo que o agente externo pode propor; este schema de memória governa aquilo que a ferramenta pode armazenar.

O registo de Paris após a segunda write contém:

{
    "tenant": "north",
    "user": "ada",
    "entity": "account",
    "key": "city",
    "value": "Paris",
    "confidence": 0.95,
    "source": "user",
    "valid_from": "2026-01-10",
    "schema_version": 1,
    "memory_type": "fact",
    "id": "m002",
    "source_event_id": "future-move:event-2",
    "observed_at": "2026-01-03",
    "valid_to": null,
    "supersedes_memory_id": "m001"
}

source_event_id aponta para o event que forneceu Paris. supersedes_memory_id liga Paris ao registo de Berlim, m001. schema_version: 1 identifica o formato do registo; não significa que o programa possa migrar automaticamente dados antigos.

MemoryRecord e Memory.write() impõem esse formato. Referências à origem em falta, datas inválidas e fields malformados são rejeitados antes de o histórico armazenado ser alterado. Um intervalo fechado tem de terminar depois de começar. Berlim pode terminar a 10 de janeiro enquanto Paris começa nesse dia; nenhum dos registos tem um intervalo vazio.

Suponha que a write seguinte diz Roma, também válida a partir de 10 de janeiro. O writer rejeita esse conflito e deixa Paris inalterada. Um segundo facto Paris para a mesma data reutiliza simplesmente o registo. Uma atualização com uma data de validade anterior também é rejeitada: este writer pequeno não reconstrói histórico chegado tardiamente. Estas são políticas fixas que o agente externo não pode alterar. O seu setting deduplicate controla confirmações repetidas com uma data de validade posterior.

A baseline ignora deliberadamente os filtros de subject e de data durante a leitura. Armazena registos válidos, mas pode escolher o errado. O isolamento do owner aplica-se a todas as configurações e a eliminação remove todas as versões da property pedida dentro do subject desse owner.

Esta é uma demonstração em memória dessas regras SGAM. Não tem uma base de dados persistente, um serviço de retenção ou um sistema de migração. Testes de regressão separados do writer verificam writes rejeitadas e limites dos intervalos; não são scenarios adicionais na pontuação da campanha de 20 histórias.

Permitir que o agente escolha uma alteração

Uma campaign é uma tentativa de melhorar a configuração original, começando com um histórico novo do agente. Uma iteration é uma chamada na qual o agente propõe uma alteração ou escolhe parar. A iteration seguinte recebe feedback das anteriores.

A campanha começa por executar apenas a baseline. Passa 13 de 20 scenarios. Depois fornecemos ao agente:

  • os settings atuais e os seus significados;
  • as medições da baseline;
  • traces de scenarios com falhas, writes rejeitadas e confirmações duplicadas;
  • as alterações que pode propor;
  • propostas anteriores e os respetivos resultados, quando existam.

O primeiro pedido não contém configurações melhoradas prontas. O repositório também tem quatro configurações preparadas manualmente para explicar a mecânica da memória, mas o agente ao vivo não começa com essas respostas.

O agente pode alterar cinco settings na ferramenta existente:

SettingO que a alteração faz
min_confidenceAltera a pontuação mínima fornecida necessária para armazenar um facto.
filter_entityRestringe o retrieval ao subject pedido, como casa em vez de trabalho.
time_awareRestringe o retrieval aos factos válidos na data pedida.
deduplicateReutiliza um facto ativo idêntico em vez de armazenar outra confirmação.
top_kDefine quantos registos são selecionados antes de empacotar o contexto da resposta.

Uma proposta pode alterar, no máximo, dois settings. Os valores numéricos têm limites: confidence entre 0 e 1, e top_k entre 1 e 8. O contract regista as alterações de configuração permitidas pela ferramenta; o schema e o validator do agente acrescentam as regras das propostas.

O agente não tem ferramentas de shell nem de filesystem neste processo. Não pode editar Python, as respostas esperadas, o isolamento do owner, o comportamento de eliminação, o schema de memória, o tratamento de conflitos, a pontuação, os orçamentos ou a autoridade de release. O seu output é data que Python pode aceitar ou rejeitar. Esta é uma pequena experiência de configuração, não um sandbox para código arbitrário escrito por um agente.

Transformar cada proposta num registo de decisão SGR

Utilizo Schema-Guided Reasoning para tornar a decisão inspecionável. Cada resposta do modelo tem os mesmos fields:

FieldO que o leitor deve conseguir inspecionar
observationsQue scenario e event fornecidos suportam a alteração proposta?
hypothesisQue regra parece causar o problema?
predicted_effectO que deverá melhorar quando testarmos a alteração?
actionO agente está a propor uma alteração ou a parar?
patchQue settings permitidos devem mudar?

O pedido OpenAI Responses utiliza um JSON Schema estrito gerado a partir de modelos Pydantic. Os objetos rejeitam fields extra e cada field do patch é obrigatório, mas pode ser null, o que significa “deixar este setting inalterado”. Structured Outputs restringe o formato da resposta. Python verifica ainda se as referências existem, se os valores são permitidos e se a configuração proposta já não foi testada.

O schema não prova a hipótese nem expõe o raciocínio interno do modelo. Estes são registos de decisão concisos, que podemos verificar face às evidências.

Na primeira iteration registada, o agente identificou retrieval entre subjects e factos devolvidos fora do respetivo intervalo de validade. A sua resposta real propôs este patch:

{
    "min_confidence": null,
    "filter_entity": true,
    "time_aware": true,
    "deduplicate": null,
    "top_k": null
}

Esses dois settings foram escolhidos pelo modelo. O runner forneceu o parent ID e atribuiu o candidate ID; o modelo não podia redirecionar a alteração para um parent ou ficheiro arbitrário.

O agente propõe dois filtros de retrieval. Python valida a proposta, executa os testes da memória e regista o resultado para a iteration seguinte.O agente propõe dois filtros de retrieval. Python valida a proposta, executa os testes da memória e regista o resultado para a iteration seguinte.

Acompanhar a alteração através de Python

Tanto a baseline como a nova configuração armazenam os mesmos registos de Berlim e Paris. A alteração proposta afeta os registos que o retrieval pode considerar.

Em Memory.query(), estes switches ativam dois filtros:

if self.config.filter_entity:
    eligible = [r for r in eligible if r["entity"] == event["entity"]]
if self.config.time_aware:
    eligible = [r for r in eligible if valid_at(r, event["as_of"])]

A verificação da validade inclui a data de início e exclui a data de fim:

def valid_at(item: dict, at: str) -> bool:
    return item["valid_from"] <= at and (
        item["valid_to"] is None or at < item["valid_to"]
    )

As datas utilizam YYYY-MM-DD, pelo que a sua ordem textual corresponde à ordem no calendário. Para a pergunta de 5 de janeiro, Paris é excluída porque só se torna válida a 10 de janeiro. Berlim continua disponível. Para a pergunta de 12 de janeiro, Paris é válida e Berlim é histórica.

Python executa a configuração proposta nas 20 histórias. Esta primeira alteração melhora o sucesso de 13/20 para 19/20, com todas as verificações hard implementadas a passar. Altera dois filtros em conjunto, pelo que o ganho em toda a suite mede o seu efeito combinado. O trace da cidade identifica o que o filtro de data fez neste caso específico.

O runner seleciona esta configuração como parent da experiência seguinte. Essa seleção não faz deployment. O modelo recebe o resultado medido, os settings selecionados e as evidências restantes no pedido seguinte.

A decisão seguinte tem de utilizar o resultado

Esta é a primeira campanha completa. Cada linha corresponde a uma resposta real do modelo, e não a uma etapa pré-escrita num script de demonstração:

IterationO que o agente propôsO que Python fezMelhor resultado atual
1Ativar os filtros de subject e de dataValidou e testou; selecionou a melhoria19/20
2Deduplicar confirmações idênticasTestou; selecionou porque o armazenamento diminuiu sem piorar as respostas19/20
3Baixar min_confidence de 0.7 para 0.6Testou; selecionou porque o último scenario com falha passou20/20
4PararRegistou a decisão de parar; não fez mais alterações20/20

A segunda resposta citou o scenario das confirmações duplicadas. Essa história escreve language = German três vezes. A deduplicação mantém um registo em vez de três, preservando a resposta. Em toda a suite, a média de registos armazenados diminuiu de 1.70 para 1.60, mantendo-se o sucesso em 19/20.

A terceira proposta tratou uma falha diferente. Uma preferência de idioma útil tinha uma confidence fornecida de 0.6, abaixo do threshold atual de 0.7. Baixar o threshold para 0.6 permitiu admiti-la, continuando a rejeitar a proposta incerta do estafeta, com pontuação 0.4. O sucesso chegou a 20/20; a média de registos armazenados passou a 1.65, porque a memória passou a manter o facto útil adicional.

Na quarta chamada, o agente escolheu parar: não tinha outra alteração suportada para propor com base nas evidências fornecidas. Esta é uma decisão do modelo, não uma prova de que a configuração seja globalmente ótima.

O pedido seguinte contém os resultados atuais e as decisões anteriores. Depois de ver que a sua correção do retrieval ajudou, o agente passou ao armazenamento e à admissão de writes. O runner não forneceu esses patches seguintes nem uma sequência de etapas pré-escrita.

A regra de seleção é fixa: exigir que todas as verificações hard passem, preferir melhor sucesso em scenarios completos e, em caso de sucesso igual, preferir menos registos armazenados. Um resultado pior deixa o parent anterior em vigor. Os testes também exercitam esse caminho de rejeição com uma proposta de regressão scripted; não foi uma regressão de qualidade medida nestas três campanhas ao vivo.

Uma execução de desenvolvimento separada contém uma rejeição de validação real: o agente citou agent-01, um candidate ID, como se fosse um scenario. A resposta correspondia ao JSON Schema, mas a sua referência não identificava um event fornecido, pelo que Python a rejeitou antes da avaliação. O controller devolve a resposta rejeitada e o erro de validação específico como feedback; testes offline verificam esse comportamento. As três campanhas abaixo indicadas não tiveram falhas de validação.

Repetir a campanha de pesquisa, não o teste determinístico

A mesma configuração de memória e os mesmos inputs produzem as mesmas respostas. Repetir essa avaliação não acrescenta evidências sobre a qualidade das respostas. O runner verifica uma nova configuração uma vez e reutiliza resultados verificados dos parents para as comparações.

O agente externo pode escolher propostas diferentes, pelo que executámos três campanhas independentes. Cada uma começou na mesma baseline de 13/20, recebeu um histórico novo e teve, no máximo, quatro decisões do modelo. Nenhuma campanha recebeu as descobertas da campanha anterior.

CampaignDecisões do modeloPropostas avaliadasPropostas rejeitadas antes da avaliaçãoSucesso selecionadoMotivo do fim
143020/20O agente parou
243020/20O agente parou
343020/20O agente parou

As três campanhas escolheram a mesma sequência: ativar ambos os filtros de retrieval, deduplicar confirmações, baixar o confidence threshold para 0.6 e parar.

Houve 12 chamadas ao modelo: nove propostas avaliadas por Python, seguidas de três decisões de parar. Cada campanha executou a baseline e três configurações novas em 20 histórias: 80 execuções da ferramenta de memória por campanha. As 20 histórias mantiveram-se iguais ao longo de todo o processo.

As três selecionaram os mesmos settings finais. Esta é uma observação pequena sobre um modelo, um prompt, um target e uma test suite públicos. Não estima a fiabilidade com que o optimizer melhorará sistemas desconhecidos. Uma comparação mais forte pertence a uma parte posterior da série: campanhas repetidas com orçamentos equivalentes, métodos de proposta concorrentes e testes que o proposer não possa inspecionar.

Ler a qualidade e o custo no nível certo

A experiência tem dois custos diferentes. Executar a ferramenta de memória utiliza tempo de CPU local e não faz model calls. Executar o proposer externo utiliza tokens de input e output. Um campo de custo zero do provider num relatório de avaliação da memória descreve apenas a ferramenta interna; não é o custo da campanha.

No estudo registado a 11 de setembro de 2026, utilizámos GPT-5.6 Luna (gpt-5.6-luna), com reasoning effort low, o schema SGR e as instruções guardados, e um máximo de 4.096 output tokens por chamada. O programa desativou retries automáticos do SDK e definiu um request timeout de 60 segundos. Os pedidos exatos, os IDs dos modelos devolvidos, a utilização e as durações das chamadas foram preservados.

A estimativa de custo baseada em tokens para as 12 chamadas ao modelo é de USD 0.039177, face a um orçamento configurado de USD 0.50. O cálculo utiliza as tarifas publicadas do modelo, inclui a sobretaxa de cache-write indicada na utilização e ignora os descontos de cache-read. É uma estimativa conservadora baseada na utilização registada, não uma fatura. O hardware e o tempo de desenvolvimento estão fora desse valor.

Antes de cada chamada, o runner reserva uma estimativa superior baseada no tamanho limitado do input e no número máximo de output tokens. Se o orçamento restante não conseguir cobrir essa reserva, para. As chamadas falhadas ou interrompidas permanecem no registo; quando a utilização não está disponível, o valor reservado é mantido, em vez de ser tratado como zero.

Quanto à qualidade das respostas, 20/20 significa que todas as respostas e verificações hard aplicáveis passaram nestas 20 histórias preparadas. Não significa memória pronta para produção. Todas as histórias são casos públicos de desenvolvimento; os traces selecionados e o feedback da suite estão disponíveis para o proposer. Cobrem atualizações, perguntas históricas, incerteza, duplicados, distractors, separação de owners, eliminação e writes não permitidas. As etiquetas search, evaluation e adversarial organizam a suite original; não transformam nenhum destes casos num conjunto de testes oculto.

Esta pequena suite recolhe ideias de LongMemEval, MemoryAgentBench, VehicleMemBench e GateMem. Os inputs e a pontuação aqui utilizados são nossos; os resultados não reproduzem esses benchmarks.

Também pode comparar quatro configurações preparadas manualmente no repositório. Elas ilustram por que motivo aceitar mais factos pode prejudicar as respostas e como o armazenamento pode melhorar sem aumentar a qualidade das respostas. Mostram ainda o lado especificado pela pessoa da mesma maquinaria de experiências: o autor fornece os candidates e Python avalia-os. São comparações didáticas úteis, não evidências de que a pesquisa agentic supere uma pessoa competente ou outro método de pesquisa.

Executar uma campanha nova do agente

Para permitir que o agente escolha novas propostas, faça clone do projeto complementar e descarregue as evidências registadas:

git clone --branch v0.2.2 --depth 1 https://github.com/slavadubrov/meta-engineering-ai-lab.git
cd meta-engineering-ai-lab
uv sync --frozen
uv run --frozen python scripts/fetch_evidence.py
uv run --frozen python -m lab verify artifacts/agent-study-03 --source

O download verifica o SHA-256 e restaura as gravações completas em artifacts/. Não faz model calls. Se já tiver descarregado as evidências, ignore esse passo e execute o comando de verificação.

Guarde um OPENAI_API_KEY num ficheiro local .env.local. O repositório ignora esse ficheiro. Em seguida, execute:

uv run --frozen --env-file .env.local python -m lab campaign \
  --live --campaigns 3 --iterations 4 --budget-usd 0.50 \
  --output artifacts/my-agent-study

--live ativa explicitamente as chamadas ao provider. Ter uma key no ambiente não transforma os comandos offline de memória nem o browser num agente ao vivo. --campaigns 3 cria três históricos de agentes independentes; --iterations 4 limita as decisões dentro de cada um. Utilize um diretório de output novo para cada estudo: as evidências existentes nunca são substituídas.

Abra artifacts/my-agent-study/report.md para consultar os resultados das campanhas e as ligações para cada pedido, resposta e avaliação Python. Compare as alterações propostas com a campanha registada acima: o agente pode escolher de forma diferente, apesar de os testes de memória serem determinísticos.

O README mapeia o código e os comandos. O relatório da campanha congelada e o checksum do arquivo e índice de exemplos permitem ao leitor inspecionar diretamente as evidências deste artigo.

Manter o histórico das experiências separado da memória do utilizador

A ferramenta de memória armazena a cidade e o idioma da Ada. O histórico das experiências armazena aquilo que o agente viu, o patch proposto, qualquer rejeição, as medições resultantes e a configuração que se tornou o parent seguinte. Estes stores têm finalidades diferentes.

A memória do utilizador contém os factos do target; o histórico das experiências regista propostas, alterações de estado, resultados e informação de revisão para decisões posteriores.A memória do utilizador contém os factos do target; o histórico das experiências regista propostas, alterações de estado, resultados e informação de revisão para decisões posteriores.

Cada iteration mantém o pedido exato com as instruções e o schema, a resposta do provider, a utilização e o timing, o resultado da validação e qualquer avaliação concluída. As propostas falhadas permanecem visíveis. Os hashes dos ficheiros associam as evidências guardadas à implementação e aos inputs utilizados na experiência.

Estes são factos sintéticos, pelo que o registo público pode manter os estados completos. Traces reais precisam de uma política de retenção separada: eliminar um facto da ferramenta de memória não apaga cópias anteriores dos logs de experiências nem dos backups. O teste de eliminação da demonstração verifica os registos da ferramenta e as leituras posteriores, não a eliminação de todos os stores possíveis.

O que o artigo seguinte tem de desafiar

Temos agora um agente dentro do ciclo de melhoria. Propõe uma alteração, recebe um resultado medido, escolhe a alteração seguinte e pode decidir parar. As propostas inválidas seguem um caminho de rejeição separado e permanecem no registo. A sua autoridade está limitada à configuração; os testes e a revisão do release continuam a ser responsabilidades separadas.

O risco seguinte é o próprio avaliador. Se o sucesso recompensar a retenção de todos os factos, o agente pode aprender a manter palpites. Se uma suite perguntar apenas pela cidade atual, pode não detetar uma alteração que destrua histórico útil. Um proposer mais capaz pode explorar medições fracas de forma mais eficiente.

A Parte 2, Torne-o pontuável antes de o tornar autónomo, pergunta como testar essas medições antes de dar mais liberdade ao proposer. O 20/20 da primeira campanha é o ponto de partida dessa investigação.