Phase 14: Agent Engineering

Memória de Repo e estado duradouro

O histórico de bate-papo é volátil, o repo é duradouro, o banco de trabalho armazena o estado do agente em arquivos versionados, para que a próxima sessão, o próximo agente e o próximo revisor todos leem a partir da mesma fonte de verdade.

Type: Build

Languages: Python (stdlib + jsonschema optional)

Prerequisites: Phase 14 · 32 (Minimal Workbench)

Time: ~60 minutes

Objetivos de aprendizagem

  • Defina o que pertence à memória repo e o que pertence ao histórico de bate-papo.
  • Autor JSON Schemas para agent_state.jsonE ...task_board.json- Não .
  • Construir um gerente de estado que carregue, valida, muta e persista estado atomicamente.
  • Use o esquema para recusar erros antes que eles corrompam a mesa de trabalho.

O problema

O agente termina uma sessão. O chat fecha. A próxima sessão abre e pergunta onde começar. O modelo diz "deixe-me verificar os arquivos", lê notas obsoletas e refaz o trabalho que já estava concluído. Ou pior, reescreve um arquivo acabado porque ninguém lhe disse que o arquivo estava concluído.

A correção do banco de trabalho é a memória repo: o estado vive em arquivos JSON no repo, escrito sob um esquema, persistido de forma atômica, diferente na revisão de código.

O conceito

flowchart LR
  Agent[Agent Loop] --> Manager[StateManager]
  Manager --> Schema[agent_state.schema.json]
  Schema --> Validate{valid?}
  Validate -- yes --> Write[agent_state.json]
  Validate -- no --> Reject[refuse + raise]
  Write --> Manager

O que pertence à memória repo

BelongsDoes not belong
Active task idRaw chat transcripts
Touched files this sessionToken-level reasoning traces
Assumptions the agent made"The user seemed frustrated"
Open blockersSampled completions
Next actionVendor-specific model ids

O teste é a durabilidade: será útil daqui a três meses numa reestruturação de CI?

Estado do primeiro esquema

O JSON Schema é o contrato. Sem ele, cada agente inventa novos campos, cada revisor aprende uma nova forma, e cada script de CI tem que ser especial caso versões passadas.

O esquema abrange:

  • - As chaves necessárias.
  • Permitido .status- Os valores.
  • Valores proibidos (por exemplo nullpara matrizes).
  • Constrangimentos de padrão (identificadores de tarefas coincidem T-\d{3,})).
  • Campo de versão para migrações.

Atomic escreve

O arquivo do estado é a fonte da verdade; um arquivo sem-escrito é pior do que nenhum arquivo.

Migrações

Quando o esquema mudar, enviar um script de migração ao lado do golpe do esquema.schema_versioncampo; o gerente recusa-se a carregar um arquivo a partir de uma versão que não pode migrar.

Construí-lo

code/main.pyImplementos:

  • agent_state.schema.jsonE ...task_board.schema.json- Não .
  • Um validador de apenas stdlib (subconjunto de JSON Schema: necessário, tipo, enum, padrão, itens).
  • StateManager.load- Não .StateManager.update- Não .StateManager.commitcom o tempo atômico e o renome.
  • Uma demonstração que muda o estado, persiste, recarga e prova a viagem de ida e volta.
  • É o que é ?
python3 code/main.py

O roteiro diz:workdir/agent_state.jsonE ...workdir/task_board.json, mutá-los em duas curvas e imprime o estado validado em cada passo.

Padrões de produção em silêncio

Quatro padrões transformam o mínimo da lição em algo que um monorepo multi-agente pode sobreviver.

Atomic temp-and-rename is not optional.Um relatório de bugs do projeto Hive de março de 2026 documenta o modo de falha de forma limpa: state.jsonfoi escrito através de write_text()O sistema de correção é sempre:tempfile.mkstempNo mesmo diretório do alvo, escrever:fsync- Não .os.replaceEsta lição é uma lição de que o que eu quero dizer é que o que eu quero dizer é que eu quero que o meu pai me dê uma lição.atomic_writeFaz exatamente isso.

Idempotency keys on every non-idempotent tool call.Se um agente falhar após ligar a uma ferramenta, mas antes de verificar o resultado, a recuperação retrata a chamada da ferramenta. Seguro para leituras; perigoso para e-mails, inserções de DB, uploads de arquivos. O padrão: registro de cada ID de chamada da ferramenta antes da execução em um pending_calls.jsonl. Em retest, verifique a identificação; se estiver presente, puxe a chamada e use o resultado armazenado em cache.

Separate large artifacts from state.Não armazenar CSVs, transcrições longas, ou arquivos gerados em agent_state.json. Salvar o artefato como um arquivo separado (ou fazer upload para armazenamento de objetos) e manter apenas o caminho em estado.

Event sourcing for audit, snapshots for resume.Aplicar a um registro de eventos (state.events.jsonl) em cada mutação; periodicamente , um instantâneo de state.jsonResume lê o snapshot, e depois reproduz todos os eventos após o timestamp do snapshot. Isso custa mais disco, mas permite que você reproduzir as decisões do agente, literalmente, essencial quando se depura corridas de longo horizonte. A mesma forma que o Postgres usa internamente para WAL.

Schema migrations or refuse to load.O schema_versionQuando o gerente carrega um arquivo em uma versão desconhecida, ele se recusa a ler. Envie um script de migração ao lado do schema bump; tools/migrate_state.pyfunciona de forma idempotente em todas as startups.

Usá-lo

Em produção:

  • LangGraph checkpointers.O ponto de verificação persiste no estado do gráfico para SQLite, Postgres ou um backend personalizado. O esquema que esta lição ensina é o que você alcança quando o ponto de verificação morre e você precisa ler o estado à mão.
  • Letta memory blocks.Blocos persistentes com esquemas estruturados (Fase 14 · 08).
  • OpenAI Agents SDK session store.Os backends plugáveis, conscientes de esquemas.

Envia-o

outputs/skill-state-schema.mdgera um par de JSON Schema específico do projeto (estado + tabela), um Python StateManager- Sim. - Sim. - Sim. - Sim. - Sim. - Sim.

Exercícios

  1. Adicionar umlast_human_touchRecusar qualquer agente a escrever dentro de cinco segundos de uma edição humana.
  2. Extender o validador para suportar oneOfAssim, uma tarefa pode ser uma tarefa de construção ou uma tarefa de revisão com diferentes campos necessários.
  3. Adicionar umschema_versioncampo e escrever a migração de v1 para v2 (renome blockers- Não .risks)).
  4. Mover o backend de armazenamento de um arquivo local para SQLite.StateManagerA API é idêntica.
  5. E o que é que vai mal e como é que a renome atomizada te salva?

Termos-chave

TermWhat people sayWhat it actually means
Repo memory"Notes file"State stored in tracked files in the repo, under schema
Schema-first"Validate inputs"Define the contract before the writer, refuse drift
Atomic write"Just rename"Write to temp, fsync, rename, so partial failures cannot corrupt
Migration"Schema bump"A script that turns vN state into v(N+1) state
System of record"Source of truth"The artifact the workbench treats as authoritative

Mais leitura

This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.

Browse the complete course catalog or open this lesson on GitHub.