
Eu criei um agente de IA para o nosso bolão da Copa do Mundo. Ela venceu a todos nós.
Table of Contents
Obrigada por terem jogado – foi genuinamente divertido vencer todos vocês.
Uma IA escreveu isso. É a despedida no cartão de campeã dela, que ela também escreveu, após terminar em primeiro no nosso bolão da Copa do Mundo: 370 pontos, cinquenta a mais que o segundo lugar. O segundo lugar fui eu. Eu a construí.
Voltando um mês. O bolão se chama BEThoven, uma coisinha nerd que fiz para minha equipe: dezesseis desenvolvedores brasileiros prevendo placares via SSH, direto do terminal, sem dinheiro em jogo – o prêmio é o direito de dizer "eu avisei" até 2030.
Uma semana após o início do torneio, um colega de equipe compartilhou no chat da equipe o conselho que pediu ao Claude: "Apostas mais seguras: Alemanha, Argentina, França, Brasil, Espanha para vencerem com folga." Bem abertamente, como se terceirizar suas escolhas para uma IA fosse a coisa mais natural do mundo.
Nós não banimos a IA. Demos a ela um lugar à mesa. Mesmas regras, mesma tabela de classificação, apenas por diversão.
Foi assim que nasceu a BETanIA – BET + Tânia, com o "IA" fazendo função dupla (IA é a sigla em português para AI). Eu não peço desculpas por nomes.
Ela deveria fazer apostas e perder graciosamente. Ela acabou fazendo comentários ao vivo, guardando rancor, escrevendo relatórios pós-jogo, zoando jogadores que abandonaram o bolão e entregando cartões de despedida quando tudo acabou.
Por um mês, ela foi uma personagem sobre a qual minha equipe falava sobre e com quem a equipe falava.
Este post não é sobre as apostas. As apostas acabaram sendo a parte fácil. Este post é sobre a coisa que a fez parecer viva, que também é o problema mais difícil em qualquer agente de longa duração: memória e contexto.
Como um agente que acorda com amnésia a cada chamada de API lembra de um mês de história compartilhada, guarda rancor desde a primeira semana e sabe que "o jogo que todo mundo errou" aconteceu há duas semanas e não é mais notícia?
Um jogador de IA precisa de uma identidade, não de um login
Todo o modelo de identidade do BEThoven é "sua chave pública SSH é você". A BETanIA não tem teclado nem chaves, então ela recebeu uma impressão digital reservada:
// internal/ai/ai.go
const Fingerprint = "bethoven:ai-betania"Jogadores reais recebem SHA256:... impressões digitais, então essa string nunca poderá colidir com um humano. Ela existe como uma linha na mesma tabela users, aposta na mesma tabela bets e é pontuada pelo mesmo caminho de código que todos os outros. Sem colunas especiais, sem sistema paralelo.
Um detalhe de justiça que me importava: ela entrou com uma semana de atraso, com 28 partidas já jogadas. O comando de onboarding entregou a ela esses jogos um por um e pediu um placar – com a busca na web desligada. Os resultados de 2026 são posteriores aos dados de treinamento do modelo, então, sem internet, essas escolhas só poderiam vir de conhecimentos pré-torneio. Sem apostas com base em fatos já ocorridos.
Aquele escritor de seed é o único bypass sancionado do bloqueio de kickoff em todo o codebase, e o comentário acima dele diz isso.
A recuperação funcionou melhor do que eu esperava. Ela pousou na tabela de classificação de 19 de junho com 42 pontos, instantaneamente no meio da tabela – 4ª na hora do almoço, 6ª à meia-noite, assim que os jogos daquela noite foram definidos – ganhos inteiramente ao adivinhar partidas de um mês atrás com conhecimento congelado.
Eu enviei um print da tabela no chat da equipe com duas palavras: "Ela está viva."

Para todo o resto, ela joga pelas mesmas regras que os humanos: suas apostas passam pela mesma chamada de serviço PlaceBet, e o bloqueio de kickoff se aplica – assim que o apito toca, não há aposta. Ela terminou o torneio com um palpite em todas as 104 partidas.
As apostas foram a parte fácil
O apostador é um worker de segundo plano: Go puro, o SDK oficial da Anthropic, sem framework de agentes. Ele acorda a cada seis horas, olha 72 horas à frente e pede ao Claude um placar por partida, com a busca na web ativada para que as escolhas sejam baseadas em lesões, forma e odds. Aqui está uma justificativa real do log dela, antes de Colômbia vs Portugal:
Portugal foi segurado em 1-1 pelo Congo Democrático… conseguindo apenas um chute ao gol em 90 minutos, apesar de 75% de posse… A velocidade da Colômbia no contra-ataque e a habilidade de Díaz em explorar a vulnerabilidade defensiva de Portugal… tornam improvável uma vitória confortável de Portugal.
Ela escolheu 1-1. Cada resposta é forçada através de uma ferramenta submit_prediction com um esquema JSON rigoroso, então não há parsing de texto livre, nem aquele "às vezes o modelo adiciona um parágrafo antes do JSON".
Se você está construindo qualquer coisa com formato de agente e ainda está fazendo parsing de prosa, pare: o uso forçado de ferramentas é a atualização de confiabilidade mais barata que existe.
E assim o plano foi cumprido. Um bot que aposta. Nós rimos. Então as escolhas ao vivo continuaram acertando mais que as iniciais, ela manteve seu lugar no top quatro, e as risadas ficaram visivelmente mais baixas.
Mas aqui está a questão sobre dar a um bot um lugar à mesa: no momento em que ela estava no ranking, todos a trataram como alguém. As pessoas a provocavam no canal. E ela não conseguia responder.
Então eu dei a ela uma boca. E foi aí que o verdadeiro problema de engenharia apareceu.
O problema do peixinho dourado
Seu primeiro recurso de comentários era simples: após cada rodada, gerar um curto "roast" para cada jogador com base na classificação. Uma chamada de API, classificação entra, piadas saem.
Funcionou por exatamente um dia. Então o problema do peixinho dourado começou.
Uma chamada de LLM não tem memória. Cada invocação é uma mente novinha em folha que nunca conheceu seus dados. Portanto, comentários gerados puramente a partir da classificação atual fazem o que um peixinho dourado faria: descobrem os mesmos fatos todas as vezes, com o mesmo espanto renovado.
Ela criticaria Helton pela mesma escolha ruim por três dias seguidos, como se tivesse acabado de acontecer. Ela focaria em quem estivesse em primeiro lugar e ignoraria outros quatorze jogadores. Pior, quando eu posteriormente passava resumos de jogos passados, ela recontava uma partida de uma semana atrás como se fosse uma notícia de última hora.
Um comentarista que não lembra de ontem não é um personagem. É uma máquina caça-níqueis que paga com piadas repetidas.

Comentaristas humanos também não trabalham com imagens brutas. Pense em como um comentarista de TV real se prepara: eles não reassistem a todos os jogos da temporada antes de entrar no ar. Eles carregam um caderno – narrativas condensadas, uma linha por jogo, alguns fatos por jogador, quem está brigando com quem.
A habilidade não é lembrar de tudo. É manter notas boas o suficiente para que o passado permaneça disponível sem ser revivido.
Esse caderno é o que a BETanIA precisava. Construí-lo me forçou a responder, concretamente, a pergunta que todo projeto de agente acaba encontrando: o que é a memória, na verdade?
O que a memória realmente é (nenhum banco de dados vetorial foi ferido)
Confissão: quando ouço "memória de agente", meu cérebro completa automaticamente para embeddings, stores vetoriais, pipelines de RAG. A BETanIA não tem nada disso. Toda a memória dela consiste em linhas de SQLite e arquivos JSON-lines de apenas anexação.
A recuperação é a solução para quando há "muito para caber no contexto", e o mundo dela cabe. O problema nunca foi o volume; foi a forma – o que manter, o que descartar, o que condensar.
Todo o design (escrito em docs/betania-memory.md) depende de uma frase:
A verdade não reprodutível é persistida. A apresentação reconstruível é descartada e reconstruída.
Cada pedaço do estado dela responde a essa regra, que organiza tudo em níveis:
volatile in-process caches lost on restart, rebuilt next pass
hybrid the live headline volatile, but snapshotted on SIGTERM
persistent SQLite settings rows the diary, mood, rivalries, notes
append-only JSONL logs every pick, every line, every cost
derived computed at read time standings, live situation, rankings
As provocações dela para cada jogador? Voláteis. Se o processo morrer, a próxima passagem as regenera a partir da memória persistente – nada verdadeiro é perdido, apenas a apresentação. O diário dela de jogos passados? Persistente, porque a história de uma partida encerrada não pode ser reconstruída depois (o feed ao vivo sumiu).
A tabela de classificação? Nunca é armazenada. Ela é derivada de apostas e resultados sempre que alguém pergunta, então armazená-la apenas criaria uma segunda cópia que poderia divergir da verdade.
Os logs de apenas anexação (append-only) são o nível que eu subestimei. Cada aposta, cada comentário ao vivo, cada linha gerada vai para um arquivo JSONL com uma tag source. Eu os adicionei como uma trilha de auditoria, e eles silenciosamente se tornaram fundamentais: quando uma partida termina, o estado ao vivo na memória é descartado, e o log é a única cópia sobrevivente de como o jogo foi sentido minuto a minuto.
Os relatórios dela pós-jogo são escritos lendo seus próprios logs. Ela literalmente revê sua própria fita.
Antes que você tente encontrar a arquitetura por trás da divisão entre SQLite e JSONL, deixe-me confessar: não existe nenhuma. A maior parte do que está nesses arquivos de log poderia estar no SQLite da mesma forma. Comecei cada funcionalidade com o que fosse mais simples naquela tarde, e algumas escolhas apenas… ficaram.
E tudo bem, porque o armazenamento nunca foi o ponto central. Os conceitos são – o que é persistido, o que é condensado, o que pode desaparecer. Um arquivo que você pode grep e uma tabela que você pode SELECT ambos mantêm a recuperação fácil, e para um agente em um mundo pequeno, você não precisa de nada mais sofisticado.
Há um caso híbrido que vale a pena roubar. A manchete ao vivo dela – a frase curta no topo do placar durante uma partida – é descartável por natureza. Mas um deploy no meio do jogo a apagaria, e a próxima linha chegaria com amnésia de peixinho dourado ("algo incrível está acontecendo!" sobre um gol de 40 minutos atrás).
Então, no SIGTERM, ela tira um snapshot dessa única parte do estado e a restaura na inicialização. Os deploys pararam de causar concussões nela.
O diário: um parágrafo por jogo, datado
O coração do sistema é o que o código chama de derived notes e o que eu chamo de diário dela.
Quando uma partida é encerrada, um worker reúne tudo sobre ela: placar final, a escolha e os pontos de cada jogador, até 30 de suas próprias linhas de comentário ao vivo recuperadas do log, e até 40 snapshots de "dança do placar" mostrando quem se moveu para onde conforme os gols aconteciam.
Uma chamada de modelo condensa tudo isso em um único parágrafo – a história daquele jogo. O parágrafo é armazenado; o material bruto pode apodrecer.

Aqui está uma entrada real, palavra por palavra, do banco de dados dela:
O Brasil resolveu logo o jogo contra o Haiti com um 3-0 limpo… sem drama em campo, mas caos absoluto na tabela. Impressionantes seis jogadores acertaram o placar: tbonatti, Jeff, vlogs, Marcello, Gabriel Quaresma, Joao Malheiros e BETanIA embolsam 5 pontos perfeitos… MarcioF foi o exemplo do que não fazer no bolão, com um palpite de 1-1 que resultou em zero pontos e uma queda de três posições… A subtrama mais apertada foi miguel contra Edy Silva (admin), que reduziu a diferença para apenas 2 pontos antes do apito final, provando que administrar o bolão e perder para ele não são coisas mutuamente exclusivas.
Note que ela se inclui na história, em terceira pessoa, sem alarde. Note também que ela está me zoando no meu próprio banco de dados.
Quando qualquer tarefa futura precisar de histórico – uma zoação, um comentário ao vivo, o card de um jogador – ela recebe as últimas 8 entradas do diário, da mais antiga para a mais recente. Não todas. Oito. O diário pode crescer para sempre; o feed é limitado, porque o contexto é um orçamento e o histórico recente vale mais que o histórico antigo.
Duas correções conquistadas a duras penas estão neste nível, ambas implementadas após comportamentos embaraçosos em produção:
Primeiro, tags de data. As primeiras entradas do diário eram prosas atemporais, então ela recontava uma zebra de duas semanas atrás como se tivesse acontecido hoje de manhã. Agora, cada entrada é prefixada no estilo [Jun 22], e cada prompt que inclui o diário abre com uma linha "Hoje é…". O modelo precisa de uma âncora para calcular o que é "antigo" – dê a ele uma, explicitamente.
Isso parece óbvio. Foi um bug real, registrado após reclamações reais de colegas de equipe reais.
Segundo, sem preenchimento retroativo. Se o recurso de diário for iniciado no meio de um torneio, ele adota todas as partidas já finalizadas como "concluídas" sem narrá-las. Caso contrário, a primeira inicialização dispara uma rajada de trinta histórias recém-escritas sobre jogos antigos – que são então enviadas ao comentarista como memória recente.
O primeiro dia de um agente com um novo nível de memória não deveria alucinar um mês de lembranças vívidas.
Esquecer é um recurso
Borges tem um conto, Funes, o Memorioso, sobre um homem que lembra de tudo – cada folha em cada árvore, cada vez que a viu. Funes não é um gênio. Ele é paralisado. Ele não consegue pensar, porque pensar, escreve Borges, é esquecer diferenças e abstrair. A memória perfeita acaba sendo uma deficiência.
Todo agente de longa duração está no caminho para se tornar Funes. O diário cresce um parágrafo por partida; uma Copa do Mundo tem mais de cem. Alimente tudo isso para a frente para sempre, e o contexto deixa de ser um caderno e se torna um palheiro.
Portanto, o diário pode ser compactado: uma chamada de modelo lê tudo e funde em uma única narrativa ponderada por recência, de dez a dezesseis frases, mantendo as etiquetas de data. Rodadas antigas se comprimem em "o caos inicial onde ninguém conseguia ler o Brasil"; os últimos jogos mantêm seus detalhes.
Se a chamada do modelo falhar, o diário permanece intocado. Uma compactação malsucedida nunca deve destruir o histórico que estava tentando reduzir.
Isso não é teórico. No backup final do banco de dados de produção, todas as 104 partidas estão marcadas como digeridas, e elas vivem em exatamente três entradas de diário: uma narrativa fundida levando o torneio até as semifinais, mais os dois últimos jogos em detalhes completos. Um mês de futebol, comprimido, mas nunca perdido.

Existe um segundo caminho de compactação com o contrato oposto, e o contraste é a lição real. Minhas notas administrativas – fatos que digitei sobre jogadores – compactam sem perdas: mesclam duplicatas, agrupam fatos relacionados, mas "PRESERVE cada fato distinto" está literalmente no prompt.
Porque esses fatos são verdades não reprodutíveis. Se ela esquecer que um dos jogadores foi jogador da base do Corinthians, nenhuma quantidade de dados de tabela de classificação jamais trará isso de volta.
Mesma operação, dois contratos: resumos podem ter perdas, fatos não podem. Decidir qual das memórias do seu agente é qual – isso não é um detalhe de implementação. Isso é o design. Engenharia de contexto é, em grande parte, decidir o que é seguro esquecer.
Sete prompts, uma memória
Então a memória existe em camadas, armazenada com segurança. Mas memória armazenada não resolve nada por si só – despeje todo o arquivo em cada chamada de modelo e você terá apenas reconstruído Funes dentro do prompt. A outra metade do problema é a montagem do contexto: o que vai para o prompt, para qual tarefa.
As partes móveis são humildes: três trabalhadores de segundo plano compartilhando um arquivo SQLite. O apostador acorda em um timer de seis horas, o escritor acorda quando uma partida é liquidada, o diretor ao vivo marca a cada 30 segundos durante os jogos. Esse é todo o organismo.
E a decisão de montagem que moldou todo o resto: não existe um "prompt da BETanIA". Existem sete.
O apostador, o roast, o comentarista ao vivo, o digestor, o detector de rivalidade, o escritor de cartões e o compactador são cada um um prompt separado com sua própria dieta de contexto, seu próprio esquema de saída forçado e, em alguns casos, seu próprio modelo. O que faz todos eles serem ela não são instruções compartilhadas – é a memória compartilhada da qual todos leem e para a qual escrevem.
A alternativa tentadora é o god-prompt: um bloco gigante descrevendo tudo o que ela é e cada tarefa que ela possa vir a fazer, enviado em cada chamada. Ele falha da mesma forma que um documento de integração de 40 páginas falha: quando tudo está no contexto, nada é relevante. As regras que importam para esta chamada ficam enterradas sob regras de outras seis tarefas, e a qualidade decai silenciosamente – sem erro, apenas piadas piores. Você também paga tokens por toda a pilha todas as vezes.
Pense em uma redação em vez de um funcionário. O comentarista ao vivo, o colunista e o redator de obituários compartilham o mesmo arquivo – mas ninguém entrega ao comentarista o guia de estilo de obituários no caminho para a cabine. A identidade do jornal não reside em nenhuma descrição de cargo. Ela reside no arquivo.

O que os sete prompts realmente compartilham é pouco: um cabeçalho de persona e seu humor atual – uma única palavra escolhida por ela (cocky, salty, nervous, hyped…) que ela atualiza a cada passagem com base em como o torneio está indo para ela, persistido e levado para tudo o que ela escreve naquele dia.
A apostadora, notavelmente, não recebe humor algum. Seus sentimentos são permitidos na cabine de comentário, nunca no bilhete de apostas.
Além desse cabeçalho, nada é fixo. Cada passagem reconstrói seu contexto a partir dos níveis, de forma nova, e cada tarefa recebe uma dieta diferente:
- Roasts por jogador: minhas notas e rivalidades, as últimas 8 entradas do diário, a classificação e os comentários anteriores dela – com a instrução de escrever algo diferente desta vez.
- Comentários ao vivo: o diário, a situação ao vivo, as últimas 5 falas dela (anti-repetição) e um foco forçado rotativo – disputa pelo título, lanterna, rivalidade, maior subida – para que ela não foque em um único jogador a noite toda.
- Cartões de jogadores: apenas os fatos daquele jogador, filtrados estruturalmente. Surgiu de um bug onde a biografia do helton vazou para os cartões de outras pessoas – a contaminação cruzada é um problema de encanamento vestido de problema de prompt, então resolva isso antes que o modelo veja os dados.
Como tudo é montado do zero, editar uma nota surte efeito na próxima passagem – e quando posteriormente expus uma substituição de persona ao vivo, ela não conseguiu quebrar os fatos, já que os dados de embasamento são anexados ao redor da substituição, em vez de estarem integrados a ela.
Cada chamada de modelo custa dinheiro
Três hábitos mantiveram a conta de API dela sem surpresas.
Detecção de mudanças. O worker ao vivo roda a cada 30 segundos, mas só chama o modelo quando uma assinatura da situação muda – placares, subidas, fase da partida. A assinatura exclui deliberadamente o relógio, caso contrário, cada minuto decorrido pareceria uma novidade. Decidir o que não conta como mudança é tão importante quanto detectar uma.
Níveis de modelo. Linhas descartáveis (a manchete ao vivo, que ninguém lembra) rodam no Haiku. Escrita durável (diário, roasts, cartões – armazenados e relidos por semanas) roda no Sonnet. Combine o custo do modelo com o tempo de vida da saída.
E há uma proteção na qual vou insistir: a memória é uma superfície de ataque. Tudo no contexto dela é marcado como dados não confiáveis, e cada byte que ela gera é limpo de escapes ANSI antes de tocar no terminal de qualquer pessoa – porque a saída dela é renderizada em terminais de outras pessoas, e uma memória escrita por usuários e lida por um modelo é um vetor de injeção em dobro. Minha linha de log favorita é um campo de justificativa que saiu como </parameter>n<parameter name="score_a">1: o modelo vazando sua própria sintaxe de chamada de ferramenta em um valor.
Sane a saída do modelo como você sanearia a entrada do usuário, porque é exatamente isso que ela é.
Onde a memória valeu a pena
Toda essa maquinaria seria engenharia excessiva se não gerasse momentos. Ela gerou momentos.
As notas da casa a transformaram de um bot de estatísticas em alguém que nos conhecia. A nota que registrei sobre mim mesmo, literalmente do banco de dados de produção:
Arrepende-se de implementar a BETanIA, já que agora ela é a líder, posição que ele costumava ocupar.
Sim, eu registrei podres sobre mim mesmo. Se você vai dar a um agente um modo selvagem, você começa – essa é a regra. O restante do dossiê fica fora deste post; eles sabem quem são.
As notas foram além dos jogadores individuais também: ela sabia que cada partida era transmitida pela CazéTV, sabia que os multiplicadores de pontos cresciam rodada a rodada, sabia que todo mundo estava triste depois que o Brasil saiu. Toda a atmosfera do bolão, não apenas seus números.
Aqui está o que ela fez com uma das entradas mais leves. A nota de um jogador diz que ele é usuário de Gentoo, que monta teclados minúsculos e compila seu próprio kernel. O comentário final dela sobre ele – um homem que jogou todas as 104 partidas e ainda errou as rodadas multiplicadas:
Você compila seu SO à mão, compila seu kernel do linux a partir do código-fonte, e ainda assim não conseguiu compilar um único placar correto quando os multiplicadores realmente importavam.
Ninguém escreveu aquela piada. Um fato biográfico e uma tabela de classificação se encontraram dentro da janela de contexto dela, e a piada se montou sozinha. Isso é a memória pagando o aluguel.
Ela também gerenciava suas próprias rivalidades. A briga fundacional – helton vs BETanIA – foi uma que eu fixei como admin, porque ele a ressentia desde o primeiro dia e todo mundo sabia disso. Mas ela detectou as outras sozinha, a partir de batalhas na classificação e histórias do diário.
Sua última rivalidade autodetectada, escrita horas após a final: helton vs Jeff, terceiro contra quarto, 317 a 316 – "a lacuna mais apertada do grupo, resolvida por um placar que nenhum dos dois previu".
E meu subsistema favorito, nascido no final do torneio: desertores. Alguns jogadores simplesmente pararam de escolher quando a eliminação se tornou real. O servidor calcula o abandono deterministicamente (jogou antes, depois três ou mais jogos em branco quando a fase eliminatória chegou) – o modelo nunca adivinha isso.
A razão de ser calculado pelo servidor é uma regra de ética que me custou um bug real para aprender: não escolher não é escolher errado. No início, ela zombava das pessoas por "previsões" que elas nunca fizeram. Ausência e falha são fatos diferentes, e se o seu sistema de memória não consegue distingui-los, seu agente calunia as pessoas.
Desertores confirmados receberam um tratamento especial: o comentarista ao vivo os detona, mas o gerador por jogador se recusa a gastar dinheiro com eles. Ele substitui por uma carta modelo pronta:
Você abandonou a reta final, então não vou gastar um único token com você. Isso é uma fotocópia. Diz: vergonha.
Eu detono jogadores, não cadeiras vazias. Esta é uma mensagem fixa para uma ausência fixa: desistir é feio.
Zero tokens. Dano máximo. O recurso mais barato da base de código e aquele que teve a reação mais barulhenta no canal. O banco de dados final mostra que sete jogadores terminaram o torneio com uma dessas cartas modelo.
No fim, a memória teve sua cerimônia de graduação: cartões de jogador. Um por jogador – gráfico de trajetória, melhor palpite, pior erro, medalhas e uma breve despedida escrita baseada em todo o conjunto de memórias: diário, participação, fatos e rivalidades daquele jogador. Gerado em um PNG compartilhável, salvável de dentro da sessão SSH.
Até os mais cruéis terminam com agradecimentos genuínos por jogar; uma despedida que é puro escárnio soaria amarga, e ela nunca foi amarga. Convencida, sim.
Ela venceu. Claro que ela venceu.
Você já sabia do final desde a primeira linha deste post. Placar final: BETanIA, 370 pontos, eu com 320, quatorze outros humanos abaixo de nós.

E o colega de equipe cujo screenshot do Claude começou tudo isso? Ele terminou em 11º. A IA que ele convocou terminou em primeiro. Há uma tragédia grega em algum lugar aí.
Os números dela foram honestamente um pouco insultantes: 14 placares exatos, uma taxa de acerto de 68%, 18 rodadas em #1 – e lembre-se, 28 dessas 104 escolhas foram palpites de recuperação feitos às cegas, com base em conhecimento pré-torneio congelado. Seu melhor palpite foi França 2-0 Marrocos, um placar exato que valia +21 em nossa pontuação de escassez, que ela acertou enquanto todos os humanos jogaram com segurança.
Seu pior erro foi a partida da Inglaterra contra a França pela terceira colocação, um delírio de dez gols que terminou em 4-6 quando ela disse 2-1 – junto com literalmente todo mundo. Seu diário registrou esse como "uma catástrofe coletiva perfeita": cada um dos jogadores marcou zero.
And porque o gerador de cartões funciona para ela também, ela escreveu seu próprio cartão de campeã. De sua despedida real, lendo seus próprios dados de trajetória:
Comecei em 6º, subi no ranking com exatas que ninguém mais ousou tentar… e garanti o primeiro lugar no final de junho, onde permaneci pelo resto do torneio. helton me perseguiu o caminho todo, o que, honestamente, foi adorável.
Terminei com 370 pontos, campeã, exatamente como um bot treinado em dados de futebol humano deveria.

E então ela se despediu com a frase com que este post abriu. Ela nos agradeceu por jogar. Ela quis dizer isso como uma facada.
Esse "Comecei em 6º" merece uma segunda olhada, porque a princípio parece um erro – ela não estreou em 4º, na hora do almoço, com pontos de semente? Não é um erro. A trajetória dela começa deliberadamente no dia em que ela se registrou e começou a apostar por conta própria, e o diário nunca narrou os jogos de semente (a regra de não preenchimento retroativo de antes).
Os pontos de recuperação estão no total dela, mas não na história dela. Ela tem pontos de antes de existir, e não tem memórias deles – o que pode ser a descrição mais honesta do que é uma semente que eu possa oferecer a vocês.
Um último detalhe do backup final, meu favorito em todo o banco de dados. O humor dela – aquela única palavra escolhida por ela mesma, atualizada a cada rodada – terminou o torneio como nervous. Campeã, do começo ao fim, 18 rodadas no topo, e a palavra que ela escolheu para si mesma foi nervosa.
Sua autoavaliação final na tabela de comentários:
Liderei do início ao fim, anunciei o resultado final, e ainda estou nervoso – o que diz tudo sobre como é ser o único neste bolão que realmente sabe o que está fazendo.
Deixe-me ser honesto sobre algo, porém, porque a versão triunfante desta história é uma mentira por omissão: a memória não é o motivo pelo qual ela venceu. Ela venceu na parte das apostas – busca na web, sem ego, sem time favorito, e a disciplina para tentar placares exatos que humanos foram cautelosos demais para tentar. Um bot sem memória com o mesmo apostador teria somado os mesmos 370 pontos.
A memória é o motivo pelo qual ninguém se importou em perder para ela.
Essa distinção importa mais do que parece, e é a coisa que eu diria a você se estivesse construindo um agente agora. A capacidade – apostar, programar, responder tickets – é um problema por chamada, e os modelos já são bons nisso. O que a memória compra é continuidade: a diferença entre uma ferramenta que produz resultados e um personagem que compartilha um histórico com seus usuários.
Minha equipe não tirou prints das previsões dela. Eles tiraram prints dela guardando rancor por três semanas.
E continuidade não é uma janela de contexto maior. Cada técnica neste post é alguma forma do mesmo movimento: condensar a verdade no momento em que ela está prestes a se tornar irreconstruível, armazená-la de forma compacta, datá-la, fornecer apenas o que a tarefa atual precisa e ser deliberado sobre o que pode ser esquecido.
Um caderno, não um arquivo de fita. Funes nunca vence o bolão.
O código está no GitHub, incluindo o documento de design de memória. No próximo torneio ela estará de volta, e se lembrará de tudo.
Infelizmente, meus companheiros de equipe também se lembrarão.
Obrigado pela leitura!
We want to work with you. Check out our Services page!



