Saltar para o conteúdo

Memória e conhecimento

Sem memória, cada conversa com um agente começa do zero: a mesma convenção tem de ser explicada de novo, a mesma decisão volta a ser debatida, o mesmo beco sem saída volta a ser explorado. A memória é o armazenamento com âmbito de espaço de trabalho que sobrevive às execuções e existe para que o conhecimento produzido por um agente possa ser encontrado por outro mais tarde.

Tem três camadas e cada uma responde a uma pergunta diferente:

  1. Factos — o que é verdade (uma convenção, um resultado, uma decisão).
  2. Políticas — o que os agentes devem fazer a esse respeito (uma regra normativa).
  3. Memória de trabalho — aquilo que um agente tinha entre mãos.

A distinção é importante porque estas camadas chegam ao agente por vias diferentes. Os factos são pesquisados. As políticas são injetadas. A memória de trabalho é privada.

Um MemoryFact é uma unidade de conhecimento com âmbito de um espaço de trabalho e de um domínio.

Atributo O que é
domain O domínio de conhecimento (“conventions”, “decisions”, “codebase”)
topic Uma etiqueta curta de tópico
content O texto do conhecimento
confidence 0,0–1,0, inicializada a partir da proveniência e aumentada a cada nova menção
memoryType O tipo do facto — determina a sua curva de decaimento temporal
veracity Como passou a ser conhecido — inicializa a confiança e determina o tamanho de cada aumento por nova menção
sourceObservationIds Que observações levaram até ele
supersededBy O facto mais recente que o substituiu, se existir
validUntil, recallCount, mentionCount Sinais de expiração e de utilização usados na recuperação

As duas últimas linhas são as que as pessoas deixam passar, e são elas que decidem qual é o facto que vem à superfície. memoryType transporta parâmetros de decaimento de Weibull por tipo, pelo que um compromisso com prazo definido desaparece depressa, ao passo que um facto de perfil estável não. veracity registra a proveniência — declarado por um ser humano (peso 1,0), inferido por um agente (0,7), produzido por uma ferramenta (0,5), importado (0,6) — e esse peso inicializa a confiança inicial do facto.

Os factos nunca são editados no local quando são contraditados. A escrita de um facto executa a deteção de conflitos contra factos do mesmo domínio e do mesmo tópico e substitui o derrotado, registando uma linha de conflito. O que importa é o registo de auditoria: pode sempre ver o que era tido como verdade antes e o que o substituiu.

Uma MemoryPolicy é uma regra normativa derivada de factos, com âmbito de um espaço de trabalho e de um domínio, com um indicador de ativação e um requiredRole opcional.

Todas as políticas ativas do espaço de trabalho são injetadas em todos os despachos, sem filtragem — não há filtragem por domínio, papel, tarefa ou espaço. Vale a pena saber isto antes de escrever a sua vigésima política, porque as políticas competem pela mesma janela de contexto que a tarefa. É também por isso que o requiredRole de uma política é indicativo: descreve a quem a regra se destina, mas não impede que a regra chegue a todos os outros.

Um MemoryDomain agrupa factos e políticas dentro de um espaço de trabalho. Os domínios dão estrutura organizativa ao conhecimento e são a unidade sobre a qual as concessões de acesso são escritas — mas veja o aviso mais abaixo antes de tratar um domínio como fronteira de confidencialidade.

Um domínio é ou de âmbito de todo o espaço de trabalho (architecture) ou de âmbito de um repositório (repo:<slug>/architecture). O mesmo nome nos dois âmbitos corresponde a dois armazenamentos independentes: um facto que é verdade para uma base de código não substitui o de âmbito de todo o espaço de trabalho. search_memory e o preâmbulo do despacho colocam primeiro a memória de âmbito de repositório quando o agente está a trabalhar nesse repositório; não filtram o resto. Indique repo em propose_fact / propose_policy / search_memory para escrever nesse âmbito ou para o reforçar.

MemoryAccessGrant mapeia um papel de agente e um domínio para um de três níveis de permissão:

Permissão Significado
none Sem acesso
read Pode pesquisar e obter factos
write Exigida por propose_policy. As escritas de factos (propose_fact, supersede_fact) não dependem de concessão

A assimetria — tolerante nas leituras, rígida nas escritas de políticas — é uma troca deliberada. A memória é mais útil quando circula, e uma recusa de leitura produz um agente que sabe silenciosamente menos, em vez de um que comunica um problema. Uma recusa de escrita de política, em contrapartida, é ruidosa e corrigível, e é aí que reside a aplicação da regra. Um domínio recém-criado inicializa write para todos os papéis; restringi-lo depois é uma edição exclusiva por RPC, porque não existe interface de concessões.

Cada agente tem uma AgentWorkingMemory: um bloco de notas de texto livre indexado por espaço de trabalho e por agente. Persiste entre execuções, é privada desse agente e é injetada no respetivo prompt em todos os despachos. É onde vive o «estava a meio da refatorização da autenticação» — o estado que vale a pena levar para a execução seguinte, mas que não vale a pena promover a facto duradouro.

No despacho, o preâmbulo de memória é composto a partir de exatamente três coisas:

  • Todas as políticas ativas do espaço de trabalho, como linhas - [domain] rule.
  • A memória de trabalho do próprio agente, palavra por palavra.
  • Uma lista curta de factos correspondidos por palavras-chave para esta tarefa — no máximo cinco, dentro de um orçamento de cerca de 1200 caracteres e apenas quando a descrição da tarefa tem pelo menos 20 caracteres. As tarefas mais curtas não recebem facto nenhum.

A lista curta é apenas FTS/palavras-chave e é limitada de propósito. Gerar o embedding de uma consulta é lento e o percurso de despacho é o sítio onde a latência é imediatamente visível, pelo que o percurso semântico lento é deliberadamente mantido fora dele. O preâmbulo termina a dizer ao agente para verificar os itens essenciais com search_memory, que é onde vive o modelo completo de recuperação.

Neste percurso não é consultada nenhuma concessão de acesso. O que a lista curta encontrar é o que o agente vê.

A ferramenta search_memory, voltada para o agente, tem três modos e são pesquisas genuinamente diferentes:

  • keyword — apenas FTS5.
  • semantic — resultados BM25 e vetoriais fundidos por fusão de postos recíprocos.
  • hybrid (o modo predefinido) — recuperação polifónica: quatro vozes ordenadas fundidas e depois diversificadas.

As quatro vozes são lexical (FTS), semântica (KNN vetorial), temporal (factos ativos recentes) e de grafo — um percurso de dois saltos pelas arestas episódicas a partir das sementes lexicais e semânticas mais fortes. A voz de grafo é a razão pela qual as arestas episódicas existem: faz sobressair o facto que está ligado à sua resposta sem corresponder a nenhuma das suas palavras. As vozes são ponderadas por uma intenção de consulta classificada (a semântica tem o maior peso por predefinição, depois o grafo e a lexical, e por fim a recência), a pontuação de cada candidato é escalada pelo respetivo decaimento de Weibull, e o conjunto de resultados é diversificado por MMR para que cinco repetições do mesmo facto não eclipsem quatro factos diferentes.

A pesquisa de memória na aplicação para computador e na Web é um percurso separado e mais simples: a operação RPC memory_fact.search é apenas FTS5, porque um cliente leve não consegue enviar um embedding de consulta e o percurso híbrido permanece interno ao anfitrião. Por isso, a ordenação que vê no navegador de memória não é a que um agente recebe de search_memory. Isso é esperado, não é um erro, mas significa que «pesquisei e não encontrei» na interface não é prova de que o agente não o vai encontrar.

O navegador de memória está em Definições → Espaço de trabalho → Memória (/workspaces/<id>/settings/memory), com os separadores Factos, Políticas e Grafo de conhecimento.

Há aí uma assimetria que surpreende as pessoas: pode editar e eliminar a memória, mas não a pode criar. Nem o separador Factos nem o separador Políticas têm um controlo para adicionar. A autoria é feita do lado do agente, através de propose_fact e propose_policy (supersede_fact / supersede_policy para os substituir). remember escreve um item de camada quente limitado à sessão que consolidate_memory pode mais tarde promover a facto; record_observation e update_my_notes escrevem o bloco de notas privado injetado no despacho. O navegador é uma superfície de revisão e correção, não de autoria — por isso, se quer um facto na memória, a forma de o colocar lá é dizer a um agente.

Duas operações de manutenção são igualmente invocadas por agentes em vez de agendadas: consolidate_memory funde e poda os factos acumulados e harmonize_memory reconcilia crenças que divergiram entre agentes. list_memory_conflicts mostra o que a deteção de conflitos já registou. Nada as executa por si segundo um temporizador. As decisões de reuniões são recolhidas para o domínio decisions quando um passo de persistência de reunião as regista; isso não é um temporizador sobre execuções de agentes concluídas.