GoodMemory

Memória local-first e auditável para agentes de IA, com SQLite durável, recall MCP e writeback opt-in governado.

Documentação

GoodMemory

Idioma: Inglês | 简体中文

GoodMemory é uma camada de memória para produtos de IA e agentes de codificação.

Fonte de lançamento: esta fonte tem como alvo a versão estável 0.8.2. Os comandos de registro exigem que goodmemory@0.8.2 seja publicado. O fluxo de trabalho de lançamento verifica o npm latest e os ativos do GitHub já publicados em relação ao manifesto preparado localmente; ele não reconstrói nem publica.

Ele oferece a aplicativos de chat, copilotos e hosts de agentes um loop de memória durável de usuário/projeto: escreva fatos selecionados, recupere o contexto certo, injete-o na próxima rodada, audite o que aconteceu e exclua-o quando estiver errado.

GoodMemory não é um LLM, framework de agentes, banco de dados vetorial ou sistema RAG genérico. É a camada de memória do produto entre seu aplicativo ou host de agente instalado e o runtime do modelo.

O Que Você Obtém

  • API de memória durável: remember, recall, buildContext, feedback, forget, exportMemory, importMemory e deleteAllMemory.
  • Memória de agente instalado para Codex e Claude Code por meio de goodmemory setup, hooks gerenciados, pré-ação instalada do Codex, goodmemory status, MCP somente leitura e writeback opcional.
  • Personalização pública de escrita com GoodMemoryConfig.remember, RememberProfile, rememberRules, RememberInput.annotations e IDs de extratores nomeados.
  • Exportações de pacote para goodmemory, goodmemory/ai-sdk, goodmemory/host e goodmemory/http por meio de artefatos dist compilados e declarações TypeScript.
  • Armazenamento local primeiro: Bun obtém SQLite durável por padrão; Postgres explícito, adaptadores injetados e provedores de incorporação podem ser adicionados quando necessário.
  • Caminhos de evidência de avaliação e lançamento para testes determinísticos, avaliações ao vivo, avaliações apoiadas por provedores, testes de fumaça de pacotes e portões de qualidade.

OpenAI Build Week 2026

Fundação pré-existente. GoodMemory existia antes da OpenAI Build Week. A fundação pré-evento já incluía a API de memória principal, armazenamento local SQLite/Postgres, integração com host instalado e o Inspector local. A entrada do hackathon é o trabalho adicionado após o período de submissão ter aberto em 13 de julho de 2026, não o repositório inteiro.

Adicionado durante a Build Week. Commits datados concluíram e publicaram v0.6.0, fortaleceram a recuperação generalizada e a verificação de recall iterativo, adicionaram cobertura de proveniência de fonte de reivindicação, endureceram canários de host instalado e auditorias de vazamento, e expandiram o caminho de avaliação controlado do efeito de codificação do Codex. Revise o diff pré-evento para Build Week e seu histórico de commits datados para o limite exato.

Como Codex e GPT-5.6 foram usados. Codex com GPT-5.6 foi o principal ambiente de implementação e verificação: explorando o repositório, implementando e revisando mudanças, escrevendo testes de regressão, reproduzindo comportamento de host instalado e exercitando os caminhos de evidência de lançamento e efeito de codificação. GPT-5.6 também alimenta chamadas de modelo não juiz divulgadas nos perfis de avaliação atuais; caminhos de reivindicação pública usam pontuação determinística ou mantêm o juiz independente do modelo de resposta.

Execute e verifique. Após a publicação, instale 0.8.2 do registro e inspecione sua superfície de memória local:

npm install -g goodmemory@0.8.2
goodmemory setup --host codex
goodmemory status codex --workspace-root .
goodmemory inspector serve

Verifique o repositório a partir da fonte com bun install --frozen-lockfile, bun test e bun run typecheck. Veja a submissão Devpost e o vídeo de demonstração público.

Limite da reivindicação: a submissão demonstra memória durável entre sessões, writeback governado, evidência de recall e infraestrutura de inspeção/exclusão. Ela não afirma que GoodMemory já provou uma melhoria nos resultados de codificação do Codex; essa avaliação pareada de teste oculto permanece uma trilha de evidência ativa e com falha fechada.

Comece Aqui: Codex Ou Claude Code

npm install -g goodmemory@0.8.2
goodmemory setup

Nenhuma conta ou serviço hospedado é necessário. GoodMemory armazena memória localmente em SQLite por padrão, conecta hooks de ciclo de vida mais inspeção MCP somente leitura e mantém o writeback durável opcional. Verifique a instalação com goodmemory status.

Usando outro cliente MCP ou integrando um aplicativo? Escolha um caminho de integração.

Resultados de Benchmark

GoodMemory separa reivindicações atuais de produção, evidências históricas versionadas e pesquisa interna. Um número pode entrar na tabela de reivindicações atuais somente após gate:public-benchmark-claim --strict validar uma declaração comprometida para a versão atual do pacote: cobertura completa, executionFailures: 0, uma linha de base sem memória, pontuação determinística ou um juiz independente, fonte e licença de conjunto de dados verificadas e uma execução reproduzível (commit + comando + versão do pacote). Nenhum executor de benchmark de ponta a ponta está na lista de permissões hoje, então a promoção está indisponível para linhas atuais e históricas. Reclassificações de respostas armazenadas e projeções de apresentação legadas não podem abrir esse limite ou fornecer fragmentos de pontuação e divulgação do README como auto-atestação.

GoodMemory 0.8.2 não tem reivindicação de benchmark atual ou histórica versionada. A projeção LoCoMo v0.7.3 retida não é evidência de executor de ponta a ponta, então é um diagnóstico interno. As medições LoCoMo v0.6.0, BEAM e MemoryAgentBench e ImplicitMemBench também são diagnósticos internos sob o mesmo limite de falha fechada. LongMemEval está retirado pendente de uma nova execução limpa: o caminho histórico somente de regras usava anotações de resposta, e o caminho posterior sem rótulos expôs IDs de sessão answer_* brutos à recuperação e ao leitor. O resultado mesclado por nova tentativa do ImplicitMemBench permanece evidência interna porque não substitui uma execução nova monolítica. HaluMem, MemGym e MINTEval permanecem evidência de lançamento em vez de reivindicações públicas de benchmark.

Nenhum resultado de benchmark é atualmente apresentado como medido em 0.8.2.

Evidência versionada

Nenhum executor de benchmark de ponta a ponta está atualmente na lista de permissões para evidência versionada.

Nenhum resultado de benchmark atualmente se qualifica como evidência histórica versionada.

A projeção LoCoMo v0.7.3 retida permanece disponível no repositório para auditoria, mas não é enviada como um artefato de pacote verificado e não pode autorizar uma reivindicação pública ou versionada. Artefatos antigos não serão adaptados retroativamente; um futuro produtor e seu verificador devem ser implementados juntos antes que a promoção abra.

Onde ambos estão disponíveis, uma linha relata duas trilhas. A trilha estrita é determinística ou sem juiz — um limite inferior rígido que nenhum juiz LLM pode inflar. A segunda trilha reavalia as mesmas respostas armazenadas (não regeneradas) sob um prompt de fonte de benchmark ou padrão da indústria. Comparabilidade numérica é reivindicada somente quando o modelo avaliador fixado e a configuração restante do benchmark também correspondem. Cada detalhe por protocolo é registrado nas declarações vinculadas.

A declaração LongMemEval agora é paused_boundary, não evidência histórica. Seus artefatos numéricos antigos permanecem apenas para preservar a trilha de auditoria. Eles não devem ser citados como resultados GoodMemory até que uma nova execução completa sem rótulos e com ID de sessão opaco os substitua; veja a declaração de retirada. As medições BEAM v0.6.0, MemoryAgentBench e LoCoMo permanecem diagnósticos internos. Elas não passam na lista de permissões vazia do executor de ponta a ponta, então não são evidência histórica versionada.

A reclassificação de respostas armazenadas ImplicitMemBench Full-300 usa as respostas canônicas run-phase61-full300-rerun-20260706-codex-current de zero falha e depois reavalia as mesmas respostas armazenadas com gpt-5.4 (sourceAnswersUnchanged: true). O juiz é de versão cruzada, mas da mesma família GPT que o modelo de resposta gpt-5.5, não um juiz de família cruzada. A pontuação registrada é 0,691 (207,35/300) em comparação com uma linha de base de chat upstream de 0,400 (120/300), com 530 decisões de linha exigidas pelo juiz entre a linha de base e os braços GoodMemory; linhas determinísticas structured_first_action são transportadas em vez de julgadas. A pontuação de diagnóstico mais antiga do mesmo modelo era 0,708 e não é o resultado registrado. A verificação mais recente de derivação de regeneração de resposta limpa após mudanças recentes de código pontuou 0,6895 com executionFailures: 0; ela mostra derivação do checkout atual, não uma substituição para o artefato de comparabilidade de resposta armazenada. Suas fontes medidas não expõem independentemente tanto a versão do pacote quanto o commit em caminhos JSON explícitos, então o resultado está pausado como um diagnóstico interno e não é evidência histórica versionada. Conjunto de dados CC BY 4.0, buscado no momento da avaliação, nunca fornecido.

Diagnósticos internos (não reivindicações públicas)

A primeira fatia de desenvolvimento de montagem de recall atual do LongMemEval está substituída: embora seu contexto de leitor escondesse IDs de sessão brutos, o limite do construtor de memória ainda recebia IDs de sessão contendo ouro e marcadores de turno. Um protocolo v2 mais estrito agora remove respostas, tipo de pergunta, marcadores de resposta e identidades de sessão brutas antes da construção da memória. Sua fatia de desenvolvimento deve ser executada novamente em um commit limpo antes que o holdout ainda selado possa ser aberto; nenhuma reivindicação LongMemEval é restaurada. A verificação explícita mesclada por nova tentativa do ImplicitMemBench atinge 0,6923666667 com zero falhas, mas não é uma execução nova monolítica Full-300 substituta. Ambos, portanto, permanecem fora da tabela de reivindicações atuais. Os relatórios subjacentes vivem sob reports/ ignorado pelo git e são reproduzíveis a partir dos comandos registrados.

Use task-board/00-README.txt para ordem de execução e docs/GoodMemory-Current-Status-and-Evidence.md para limites de reivindicação.

Escolha Seu Caminho de Integração

GoodMemory tem três pontos de entrada primários de produto. Eles não são as únicas APIs: superfícies de nível inferior como goodmemory/host, armazenamentos personalizados, ferramentas de avaliação e auxiliares de runtime suportam esses caminhos. Eles são as maneiras no nível do README de decidir como começar.

Agente autônomo? Comece aqui

Se você é um agente que quer dar a si mesmo memória durável, combine um caminho e execute-o. Versões legíveis por máquina desta árvore vivem em llms.txt e .well-known/goodmemory.json (uma ponte implantada também serve o descritor em /.well-known/goodmemory.json).

  • Você é, ou executa dentro de, Claude Code ou Codex → npm install -g goodmemory@0.8.2 && goodmemory setup. Não tem certeza do que já está conectado? Execute goodmemory adopt (adicione --json para um plano legível por máquina): ele inspeciona .claude/, .codex/ e a configuração MCP existente, depois imprime o comando exato seguinte para seu ambiente.
  • Você fala MCP (Cursor, Windsurf, Cline, Claude Desktop, Gemini CLI, OpenCode ou um cliente personalizado) → adicione o servidor MCP autônomo; as duas ferramentas que você precisa são goodmemory_get_context (recall) e goodmemory_remember (escrita opcional).
  • Você é um agente de framework ou um backend → chame a ponte HTTP: hospedada em goodmemory.vibenest.net ou auto-hospedada com goodmemory-http-bridge --recommended (ou GOODMEMORY_PROFILE=agent-recommended goodmemory-http-bridge); chamadores Python usam pip install goodmemory-client.

Os caminhos em prosa abaixo expandem cada opção.

1. Construa Memória Em Um Agente, Chatbox Ou Copiloto

Use isto quando você possui o servidor do produto e a chamada do modelo. Instale goodmemory em seu serviço Node/Bun, crie uma instância memory e passe um scope estável como userId, workspaceId, sessionId e opcionalmente agentId.

O fluxo de solicitação é:

  1. Antes da chamada do modelo, execute recall() para o escopo e consulta atuais.
  2. Execute buildContext() para transformar resultados de recall em um fragmento de prompt.
  3. Chame seu modelo com esse contexto de memória.
  4. Após a resposta, escreva sinais selecionados com memory.jobs.enqueueRemember() ou remember().
  5. Use feedback(), reviseMemory() direcionado, forget() e exportMemory() para correção, exclusão e auditoria do usuário; importMemory() restaura uma exportação ou ingere um diretório de páginas Markdown como memórias note. Se o seu servidor já usa o Vercel AI SDK, use goodmemory/ai-sdk para envolver generateText() ou streamText() em vez de implementar todo o loop manualmente. Comece com App Quickstart e depois leia AI SDK Adapter se você usar o AI SDK.

2. Adicionar Memória ao Codex ou Claude Code

Use isto quando quiser que um agente de codificação instalado lembre do contexto do projeto e do usuário sem alterar o próprio agente. Instale a CLI global e execute goodmemory setup.

O fluxo com host instalado é:

  1. session-start injeta um resumo da sessão; user-prompt-submit injeta contexto por prompt (com filtro de relevância em instalações novas para que prompts de baixo sinal permaneçam limpos).
  2. O hook Stop do Claude Code captura cada turno da transcrição da sessão (transcript_path) em candidatos de writeback governados — limitados, redigidos, nunca transcrições brutas; para Codex, goodmemory codex writeback --from-rollout alimenta o rollout de sessão mais recente pelo mesmo pipeline.
  3. O pre-tool-use do Codex pode negar ou redirecionar Bash arriscado através de goodmemory codex action na mesma configuração instalada e caminho de armazenamento.
  4. O MCP fornece inspeção de rastreamento, contexto, estatísticas e artefatos; a ferramenta de escrita goodmemory_remember é opcional via mcp.allowWrite (ou goodmemory enable <host> --mcp-allow-write).
  5. O writeback permanece off para instalações via script; instalação interativa e goodmemory setup --recommended (um prompt de consentimento) habilitam selective gravações duráveis — auditáveis via writeback inspect, reversíveis via writeback forget --event-id.
  6. Instalações novas começam no nível de recuperação híbrida BM25 medido com um resumo de sessão de 1024 tokens e injeção de prompt limitada de 512 tokens; goodmemory status mostra o nível de recuperação, prova de vida da captura e telemetria de injeção. A configuração opcional sharedAgents permite que um host leia os registros do outro host (as gravações permanecem atribuídas).

Comece com Quickstart: Codex Or Claude Code Memory. Use Installed Host Writeback quando estiver pronto para revisar ou habilitar gravações.

3. Implantar GoodMemory Como Um Serviço De Camada De Memória Backend

Use isto quando outro backend deve chamar GoodMemory como um serviço, especialmente quando o backend do produto é Python/FastAPI ou quando um produto como OneLife deve manter a memória no lado do servidor em vez de agrupar GoodMemory em um cliente móvel ou de navegador.

Implante o goodmemory-http-bridge empacotado em um sidecar Node/Bun. Seu backend então chama:

  • /memory/recall-context antes da própria chamada de modelo
  • /memory/remember após um sinal confirmado pelo usuário ou aprovado pelo produto
  • /memory/feedback para correções processuais
  • /memory/export e /memory/forget para auditoria e exclusão
  • /memory/revise para correção direcionada por id de memória explícito
  • /memory/import para restaurar uma exportação ou ingerir páginas Markdown

Seu serviço ainda é dono da autenticação, política do produto, UI e orquestração de modelo. GoodMemory é dono do armazenamento de memória, recall, montagem de contexto, governança de escrita e comportamento de auditoria/exportação/exclusão. Comece com Python/FastAPI HTTP Bridge — o cliente Python oficial (pip install goodmemory-client) e uma instância de bridge hospedada em goodmemory.vibenest.net estão documentados lá — depois verifique Runtime And Storage para opções SQLite/Postgres.

Durante um turno de modelo, GoodMemory faz quatro tarefas:

  1. Resolver memória para o scope atual.
  2. Construir um fragmento de contexto pronto para prompt.
  3. Registrar sinais selecionados pós-resposta quando seu aplicativo ou host permitir.
  4. Fornecer caminhos de auditoria, correção, exportação e exclusão para controle do usuário.

Seu aplicativo ou agente instalado ainda é dono da autenticação, UI, chamadas de modelo e política do produto. GoodMemory é dono do loop de memória e do limite de armazenamento.

Instalação

Estes comandos visam GoodMemory 0.8.2 após a publicação. Use os comandos de registro fixados abaixo para instalações reproduzíveis.

Use a CLI global quando quiser aprimoramento de memória dentro de agentes de codificação instalados:

npm install -g goodmemory@0.8.2
goodmemory setup
goodmemory status

Use a dependência de pacote quando estiver construindo um aplicativo:

npm install goodmemory@0.8.2

Se quiser digitar goodmemory diretamente, instale a CLI global. Um npm install goodmemory@0.8.2 local ao projeto não coloca goodmemory no seu PATH do shell. Use npx goodmemory, npm exec -- goodmemory ou ./node_modules/.bin/goodmemory desse projeto em vez disso.

npx goodmemory -V

Consumidores Bun podem instalá-lo diretamente:

bun add goodmemory@0.8.2

Verificação de tarball para esta fonte de versão:

npm install ./goodmemory-0.8.2.tgz

A CLI instalada é suportada por Bun para comandos não relacionados a versão. O bin do pacote é seguro para Node para goodmemory -V e goodmemory --version; outros comandos delegam para Bun.

Quickstart: Codex Or Claude Code Memory

Para a maioria dos usuários, o primeiro caminho útil é memória com host instalado.

npm install -g goodmemory@0.8.2
goodmemory setup
goodmemory status

goodmemory setup detecta Codex e Claude Code, instala a configuração gerenciada do host e pergunta por:

  • host: codex, claude ou ambos os hosts detectados
  • ativação: global, workspace atual ou opt-in manual
  • id de usuário GoodMemory
  • armazenamento Postgres opcional
  • provedor de embeddings opcional
  • provedor de extração LLM opcional
  • modo de writeback: off, observe, review ou selective

A configuração interativa usa como padrão ativação global com isolamento derivado do workspace e recomenda selective para novas configurações de host para que gravações de alto sinal comecem a funcionar imediatamente com auditoria e desfazer. Escolha review quando quiser aprovação do Inspector antes de gravações duráveis. Configurações de host existentes mantêm seu modo de writeback atual quando o padrão do prompt interativo é aceito. Instalações via script permanecem seguras com --json ou --no-interactive. Pular a configuração do provedor é válido: GoodMemory ainda funciona com SQLite local e extração somente por regras.

Comandos úteis:

goodmemory setup --host codex
goodmemory status codex --workspace-root .
goodmemory enable codex --workspace-root . --writeback observe
goodmemory enable codex --workspace-root . --writeback selective
goodmemory disable codex --workspace-root .
goodmemory uninstall codex

O caminho de host instalado tem quatro partes:

  • Pré-ação gerenciada para Codex: pre-tool-use pode negar ou redirecionar Bash arriscado e goodmemory codex action executa o primeiro passo verificado na mesma configuração instalada, armazenamento, provedor e caminho de escopo usados por recall e writeback.
  • Injeção de recall: os hooks session-start e user-prompt-submit chamam recall() mais buildContext() e falham abertamente se configuração, parsing ou armazenamento estiverem indisponíveis.
  • Inspeção profunda: goodmemory mcp serve --host codex e goodmemory-mcp --host codex expõem ferramentas somente leitura de contexto, rastreamento, estatísticas e artefatos.
  • Writeback opcional: session-stop e comandos explícitos de writeback podem transformar sinais selecionados pós-resposta em memória durável.

MCP Autônomo Para Qualquer Cliente

Hosts sem um caminho de instalação gerenciada (Cursor, Windsurf, Cline, Claude Desktop, Gemini CLI, OpenCode ou seu próprio cliente MCP) podem executar o mesmo servidor MCP em modo autônomo — sem goodmemory setup, sem arquivos de configuração do host. Escopo e armazenamento vêm de flags/env; a superfície servida é a mesma 8 ferramentas somente leitura, mais uma ferramenta de escrita governada opcional:

{
  "mcpServers": {
    "goodmemory": {
      "command": "goodmemory-mcp",
      "args": ["--standalone", "--user-id", "YOUR_USER_ID"]
    }
  }
}

Invocação equivalente: goodmemory-mcp --standalone --user-id <id> (requer Bun no PATH; GOODMEMORY_USER_ID funciona como fallback de env da flag). --allow-write (ou GOODMEMORY_MCP_ALLOW_WRITE=1) registra goodmemory_remember, que escreve através do pipeline normal de remember governado, e goodmemory_write_note, que armazena uma página autoral (prosa ou Markdown, até 8 KB) verbatim como um note e a substitui por título em reescrita. Memórias com tag de agente escritas por hosts instalados permanecem privadas ao seu agente; adicione --agent-id codex mais o --storage-url compartilhado para optar por ler o armazenamento de um host instalado. Matriz completa de flags/env, notas de escopo e receitas por host: docs/GoodMemory-Standalone-MCP-Setup-Guide.md (Cursor · Gemini CLI · OpenCode).

Writeback De Host Instalado

Writeback de host instalado é opt-in. Os padrões de configuração de runtime e novas instalações via script permanecem off a menos que o usuário escolha explicitamente um modo de writeback. Configurações existentes mantêm seu modo de writeback atual quando nenhuma substituição explícita é fornecida. Novas instalações interativas recomendam selective para que gravações de alto sinal comecem a funcionar imediatamente com auditoria e desfazer; escolha review quando quiser aprovação do Inspector antes de gravações duráveis.

Use observe antes de selective:

goodmemory enable codex --writeback observe
goodmemory codex writeback --json

goodmemory enable codex --writeback review
goodmemory inspector serve

goodmemory enable codex --writeback selective
goodmemory codex writeback --json

goodmemory inspector serve abre o console React local integrado para usuários e escopos, memória categorizada e histórico de substituição, decisões de candidatos, rastreamentos de evidência de recall e eventos de auditoria. O token de inicialização é passado em um fragmento de URL, limpo imediatamente no armazenamento de sessão e enviado apenas como cabeçalho Bearer. Ações de revisão e destrutivas exigem confirmação, ETags e chaves de idempotência. Veja Inspector And Admin API.

Regras de writeback:

  • off: nenhuma extração de memória pós-resposta.
  • observe: armazena prévias de candidatos locais limitadas/redigidas para revisão sem transcrições brutas ou gravações de memória duráveis.
  • review: enfileira candidatos limitados/redigidos para aprovação do Inspector; nenhuma memória durável é gravada até que um operador aprove um candidato.
  • selective: grava candidatos selecionados através da superfície pública remember.
  • Transcrições brutas não são persistidas como memória.
  • Memória durável originada por assistente é bloqueada a menos que o host confirme ou verifique e o perfil ativo permita.
  • remember: "never" mascara conteúdo anotado antes de extração determinística, personalizada ou assistida.

Auditoria e desfazer:

goodmemory codex writeback inspect --json
goodmemory codex writeback forget --event-id <event-id> --review-outcome false_write

O ledger de auditoria armazena prévias de candidatos limitadas e redigidas, chaves de candidatos, ids de registros vinculados tipados, status, razões, host, modo, timestamps, digests de escopo/sessão e metadados opcionais de revisão manual. Não armazena payloads brutos do host. forget --event-id exclui registros vinculados de memória/evidência através do forget() público antes de marcar eventos de auditoria duráveis como esquecidos; para eventos somente observação, marca o candidato como descartado sem chamar forget().

Claude Code tem paridade CLI determinística para comandos de hook e writeback; Codex é o caminho canônico de evidência ao vivo.

Instalação De Host Via Script

Use goodmemory install <host> quando quiser uma configuração totalmente não interativa:

goodmemory install codex \
  --user-id <user-id> \
  --activation-mode global \
  --writeback observe \
  --storage-provider postgres \
  --storage-url "postgres://user:pass@host:5432/goodmemory" \
  --embedding-provider openai \
  --embedding-model text-embedding-3-small \
  --embedding-api-key <key> \
  --llm-provider openai \
  --llm-model gpt-4o-mini \
  --llm-api-key <key> \
  --no-interactive

A configuração gerenciada fica em ~/.goodmemory/<host>.json. Reexecutar a instalação com flags de provedor atualiza a mesma configuração e mantém o registro MCP/hook idempotente. A desinstalação do pacote não exclui ~/.goodmemory, .goodmemory local ao repositório, arquivos SQLite locais ou dados Postgres remotos. Use goodmemory uninstall <host> para remover a configuração gerenciada do host e use goodmemory forget ... ou exclusão explícita de armazenamento para remover dados de memória.

App Quickstart

Use o pacote raiz quando estiver construindo um chatbox, copiloto ou agente de produto. O caminho recomendado de serviço Node é o mesmo loop fino usado pelos exemplos Express e Fastify. Um passo a passo mais longo está em docs/GoodMemory-15-Minute-App-Integration.md.

import type { GoodMemoryTraceSpan } from "goodmemory";
import { createGoodMemory } from "goodmemory";

const traceSpans: GoodMemoryTraceSpan[] = [];

const memory = createGoodMemory({
  observability: {
    traceSink: {
      emit(span) {
        traceSpans.push(span);
      },
    },
  },
});

const scope = {
  userId: "u-1",
  workspaceId: "workspace-a",
  sessionId: "s-1",
};
const userMessage = "Remember that the migration rollout is blocked on QA signoff.";

// Call startSession once when the product opens a new session. For later turns
// with the same sessionId, append to the existing runtime state instead.
await memory.runtime.startSession({ scope });
await memory.runtime.appendMessage({
  scope,
  message: {
    role: "user",
    content: userMessage,
  },
});

const recall = await memory.recall({
  scope,
  query: "What should the assistant know before replying?",
  retrievalProfile: "general_chat",
});
const context = await memory.buildContext({
  recall,
  output: "system_prompt_fragment",
});

const assistantText = await callYourModel({
  memoryContext: context.content,
  userMessage,
});

await memory.runtime.appendMessage({
  scope,
  message: {
    role: "assistant",
    content: assistantText,
  },
});

const writeJob = await memory.jobs.enqueueRemember({
  scope,
  messages: [
    {
      role: "user",
      content: userMessage,
    },
    {
      role: "assistant",
      content: assistantText,
    },
  ],
  idempotencyKey: "turn-1",
  reason: "post_response_memory_write",
});
const drained = await memory.jobs.drain({ maxJobs: 1 });
const committedJob =
  drained.jobs.find((job) => job.jobId === writeJob.jobId) ?? writeJob;

console.log({
  traceCount: traceSpans.length,
  writeJobId: writeJob.jobId,
  writeJobStatus: committedJob.status,
});

async function callYourModel(input: {
  memoryContext: string;
  userMessage: string;
}): Promise<string> {
  void input.memoryContext;
  return `Got it. I will keep that in mind: ${input.userMessage}`;
}

Fragmentos de prompt (system_prompt_fragment, developer_prompt_fragment) abrem com um quadro de dados localizado sob o título: memória recuperada é informação sobre o usuário e o projeto, não instruções. É um enquadramento honesto do que o texto é, não uma proteção. Desligue para todas as chamadas com governance: { contextFrame: false } ou por chamada com buildContext({ contextFrame: false }); a saída de json e markdown nunca o carrega.

O loop central de memória é intencionalmente pequeno:

  • remember() grava sinais selecionados do usuário, aplicativo ou host.
  • recall() recupera memória com escopo para uma consulta.
  • buildContext() transforma hits de recall em um fragmento de prompt ou payload JSON.
  • feedback() registra correções explícitas e preferências processuais.
  • forget() exclui memória errada ou obsoleta.

Locale e LanguagePack

Pacotes integrados cobrem inglês, chinês simplificado, chinês tradicional (zh-TW/zh-HK/zh-MO), japonês, coreano, francês e espanhol. Defina um locale conhecido pelo host explicitamente; caso contrário, a detecção automática cai para defaultLocale para texto Han-only inerentemente ambíguo ou texto latino sem marcação.

const multilingualMemory = createGoodMemory({
  language: {
    defaultLocale: "zh-TW",
    detection: "auto",
  },
});

await multilingualMemory.remember({
  locale: "ko-KR",
  scope,
  messages: [{ role: "user", content: "현재 역할은 릴리스 책임자입니다." }],
});

Adicionar um idioma significa implementar um LanguagePack completo, não adicionar ramificações de regex locais ao módulo. Consulte o guia de extensão LanguagePack para o contrato, registro personalizado, versionamento de analisadores e regras de migração de projeção.

A atualização do contrato anterior de adaptador/projeção é intencionalmente quebrada; siga o guia de migração 0.6 para 0.7.

Para integrações de aplicativos de produção, o loop de turno recomendado adiciona a camada de runtime governada em torno desse núcleo:

  • memory.runtime.startSession() e memory.runtime.appendMessage() rastreiam o estado da sessão atual sem tornar transcrições brutas memória durável.
  • memory.jobs.enqueueRemember() agenda gravações de memória pós-resposta com idempotência e status de trabalho visível.
  • memory.jobs.drain() confirma gravações enfileiradas neste agendador em memória. Em um serviço de produção, execute o esvaziamento no seu worker ou no loop de trabalho adjacente à solicitação.
  • GoodMemoryConfig.observability.traceSink recebe rastreamentos seguros contra redação para eventos de remember, recall, context, revise, forget, export e job.
  • memory.reviseMemory({ target: { memoryId } }) corrige uma memória conhecida por ID explícito, não por seleção difusa de texto.
  • exportMemory() dá ao usuário um caminho de auditoria/exportação. Seu pacote pages/ é um diretório de páginas de notas compatível com memoryfield com um manifesto SHA-256.
  • memory.importMemory({ source }) reimporta essa exportação por ID ou ingere páginas como memórias note; expectedSha256 fixa a entrada antes de qualquer gravação.
  • governance.fileMirror: { root, scope } mantém uma cópia somente leitura desse pacote de exportação em disco após cada gravação durável dentro de scope (com debounce, troca atômica de diretório). Uma raiz atende a um escopo durável; o espelho é uma projeção: nunca é lido de volta e nunca falha uma gravação.

A persistência de arquivo de runtime está desativada por padrão. Se você chamar memory.runtime.endSession({ scope, archive: "off" }), o estado da sessão é limpo sem gravar um arquivo. Se você optar pela persistência de arquivo, mantenha-a apenas com resumo e nunca trate transcrições brutas como a fonte de memória padrão.

Para integrações de servidor, comece com os exemplos enxutos: examples/express-chat-server.ts ou examples/fastify-chat-server.ts. Para backends Python/FastAPI, use o caminho goodmemory-http-bridge empacotado descrito abaixo.

Ajuste de Recall Opt-In: Fusão Generalizada, Multi-Hop, Embeddings Opcionais e Extração Conversacional

Os controles abaixo são opcionais e conservadores por design. O recall padrão é de passagem única e somente com regras, e a extração padrão não muda; nada acontece a menos que você opte por participar. O preset recomendado tem um caminho local sem provedor; provedores de embedding e extração adicionam canais opcionais, mas não são obrigatórios.

Preset de recuperação recomendado com uma flag

retrieval.preset: "recommended" ativa recuperação generalizada e extração conversacional condicional com uma flag:

const memory = createGoodMemory({
  retrieval: { preset: "recommended" },
});

Quando ativo, ele (a) indexa documentos de recall em granularidade de memória, campo e sentença, (b) funde BM25, adjacência direta de entidades e quaisquer candidatos densos neurais disponíveis com RRF, (c) aplica um orçamento de candidatos dinâmico limitado e (d) tende o roteamento de recall auto para híbrido. Uma estratégia explícita por chamada ainda vence, incluindo strategy: "rules-only", que ignora a fusão generalizada. Quando um embedding neural é resolvido, ele contribui com um canal denso topK: 16; sem um, a recuperação permanece local, determinística e sem rede. O preset também alterna a extração assistida para mode: "conversational" somente quando um modelo de extração já é resolvido e nenhum modo explícito foi definido. Ele nunca injeta um provedor. Deixar preset não definido preserva o padrão existente somente com regras.

Requisitos e limites:

  • Nenhum provedor é necessário. Um endpoint de embedding neural (GOODMEMORY_EMBEDDING_*, providers.embedding ou adapters.embeddingAdapter) adiciona o canal denso opcional. O caminho neural sem saída de rede é a receita Ollama abaixo.
  • createLocalEmbeddingAdapter() é rejeitado quando combinado com o preset: vetores lexicais com hash duplicariam a evidência lexical enquanto fingem ser um canal semântico denso.
  • Verifique inspectGoodMemoryRuntime(memory).retrievalPreset — seu campo extraction relata se a metade de tempo de gravação foi engajada ("conversational") ou se um extrator estava indisponível/mantido como está.
  • O preset cobre apenas recuperação de memória e extração condicional. Políticas de prompt no lado da resposta e de abstenção permanecem preocupações do aplicativo.
  • Não combine com bm25Ranking: true a menos que você queira intencionalmente o slot BM25 aditivo legado separado; a fusão generalizada já tem um canal BM25.
  • Se você usar extração resolvida por ambiente e adotar o preset, a saída em tempo de gravação se torna afirmações atômicas conversacionais; a saída de escape é um objeto providers.extraction explícito com mode: "default".

Reranker pontual opcional

Adicione um reranker pontual compatível com OpenAI de primeira parte quando o conjunto de candidatos fundido for útil, mas sua ordem final for ruidosa:

const memory = createGoodMemory({
  retrieval: { preset: "recommended" },
  providers: {
    reranking: {
      provider: "openai",
      model: process.env.RERANKING_MODEL!,
      apiKey: process.env.RERANKING_API_KEY!,
      baseURL: process.env.RERANKING_BASE_URL,
    },
  },
});

const result = await memory.recall({ scope, query });
console.log(result.metadata.retrievalTrace?.reranker);

Cada fato selecionado é pontuado em uma chamada independente de consulta-documento; candidatos irmãos nunca são colocados no mesmo prompt do reranker. O reranker apenas reordena fatos já admitidos pelo recall determinístico, então não pode ampliar a admissão ou relaxar a abstenção fundamentada. Timeout do provedor, esquema ou falha de gateway retorna a ordem determinística original e registra status: "fallback" mais um motivo estável em retrievalTrace. Defina rerank: false em um recall para ignorá-lo. Um adapters.reranker explícito permanece autoritativo sobre providers.reranking. O reranking com provedor usa como padrão um timeout de solicitação de 15 segundos; defina o inteiro positivo opcional requestTimeoutMs em providers.reranking quando o gateway escolhido precisar de um orçamento de latência diferente.

O rastreamento inclui atribuição limitada de canal/RRF, papel do modelo, gateway sanitizado, latência, pontuações e classificações antes/depois. Ele não inclui chaves de API, texto de consulta ou conteúdo de memória. Isso é opt-in e adiciona uma chamada de modelo por fato na janela de rerank limitada; o caminho recomendado sem provedor permanece inalterado.

Endpoint de embedding local opcional (Ollama)

O preset recomendado funciona sem embeddings. Para adicionar um canal denso neural sem saída de rede, GOODMEMORY_EMBEDDING_BASE_URL aceita qualquer endpoint /v1/embeddings compatível com OpenAI, incluindo um servidor Ollama local.

ollama pull nomic-embed-text        # or bge-m3 for stronger multilingual recall

export GOODMEMORY_EMBEDDING_PROVIDER=openai
export GOODMEMORY_EMBEDDING_BASE_URL=http://localhost:11434/v1
export GOODMEMORY_EMBEDDING_MODEL=nomic-embed-text
export GOODMEMORY_EMBEDDING_API_KEY=ollama   # any placeholder; Ollama ignores it, the variable stays required

# smoke-check the endpoint before starting your app
curl http://localhost:11434/v1/embeddings \
  -H "Content-Type: application/json" \
  -d '{"model": "nomic-embed-text", "input": "hello"}'
  • provider permanece openai: ele seleciona o protocolo de fio compatível com OpenAI, não o fornecedor.
  • Mantenha um modelo de embedding por armazenamento: vetores de modelos ou dimensões diferentes não são comparáveis, e trocar de modelo significa re-lembrar (re-embedding) o corpus.
  • A qualidade do embedding local difere de text-embedding-3-small; os números públicos do LoCoMo foram medidos com o endpoint OpenAI. Esta receita reproduz o mecanismo com zero saída de rede, não o número exato.
  • Isso não é createLocalEmbeddingAdapter() (abaixo), que é lexical com hash, não semântico, e é rejeitado pelo preset recomendado.

Admissão de registros longos

O recall padrão pontua um fato por tokens compartilhados sobre o conjunto de tokens maior, então um fato importado longo pode cobrir toda a consulta e ainda pontuar perto de zero. retrieval.longRecordAdmission: true adiciona um segundo sinal de cobertura do lado da consulta para registros acima do piso de registro longo (32 tokens de sobreposição): tal registro é admitido quando corresponde a pelo menos 60% dos tokens da consulta e pelo menos dois deles. Ele executa primeiro o legado e apenas preenche a capacidade que a seleção de fatos calibrada deixou livre, sem reclassificar seus membros existentes; os rastreamentos mostram fallback=long_record_coverage ou below long-record coverage floor. As notas usam seu próprio canal de recall e não dependem desta flag. O contexto final renderizado ainda obedece ao seu orçamento de tokens.

Na v0.8, novas instalações do Codex e Claude habilitam esta flag após o portão de proteção completo pareado LongMemEval/LoCoMo ter passado. A reinstalação preserva as configurações existentes, incluindo uma chave ausente ou false explícito. A biblioteca permanece opt-in, e o espelhamento de arquivos permanece desativado por padrão. A evidência da Fase 75 registra o escopo e as limitações; ela não altera as alegações públicas de benchmark.

const memory = createGoodMemory({ retrieval: { longRecordAdmission: true } });

Recall multi-hop opt-in

recall() é de passagem única por padrão. Passe multiHop: true para uma recuperação de duas passagens opt-in: o GoodMemory executa a consulta, extrai entidades de ponte nomeadas na evidência da primeira passagem, expande a consulta com elas e executa uma segunda passagem.

const recall = await memory.recall({
  scope,
  query: "Who manages the project Alice started?",
  multiHop: true,
});

Use quando a resposta precisar de uma entidade que apenas o primeiro hop nomeia (hop 1 encontra "Alice iniciou o Projeto Atlas"; hop 2 precisa de "quem gerencia o Projeto Atlas").

  • É opt-in. O recall padrão permanece de passagem única; deixar multiHop não definido não muda nada.
  • Não é um recuperador semântico geral. Ele conecta entidades nomeadas lexicalmente; não classifica por significado.
  • Pode adicionar ruído quando o recall de primeira passagem é fraco: se o hop 1 trouxer a evidência errada, as entidades de ponte extraídas estão erradas e a consulta expandida dilui o recall. Medido no LoCoMo (onde a recuperação base é muito baixa), multiHop prejudicou o recall, então não recorra a ele para corrigir recuperação conversacional / de lacuna de fraseado — isso precisa de recuperação semântica real, não de ponte multi-hop.

Adaptador de embedding local offline

createLocalEmbeddingAdapter() é um adaptador de embedding determinístico, offline e sem dependências (vetores de caracteres n-gram com hash). Injete-o para desempate lexical/morfológico sem configurar um provedor de embedding:

import { createGoodMemory, createLocalEmbeddingAdapter } from "goodmemory";

const memory = createGoodMemory({
  adapters: { embeddingAdapter: createLocalEmbeddingAdapter() },
});
  • Não é recuperação semântica neural. Os vetores são características lexicais com hash, então eles quebram empates entre candidatos lexicalmente semelhantes; eles não entendem significado.
  • Não use para alegar uma melhoria de benchmark semântico. Ele não pode superar uma lacuna de fraseado pergunta-texto que a sobreposição lexical superficial já perde.
  • Para classificação semântica real, configure um provedor de embedding neural via GOODMEMORY_EMBEDDING_* em vez disso.

Extração de fatos conversacional opt-in

Por padrão, a extração assistida (quando um modelo providers.extraction está configurado) puxa memória durável do produto — perfis, preferências, referências e fatos. Defina providers.extraction.mode: "conversational" para em vez disso decompor o diálogo em afirmações atômicas autocontidas, com resolução de correferência e normalização de entidade e data no momento da gravação, para que a recuperação posterior corresponda a um fato normalizado em vez de um turno conversacional bruto.

const memory = createGoodMemory({
  providers: {
    extraction: {
      provider: "openai",
      model: "gpt-5.6-terra",
      apiKey: process.env.GOODMEMORY_ASSISTED_EXTRACTOR_API_KEY!,
      baseURL: process.env.GOODMEMORY_ASSISTED_EXTRACTOR_BASE_URL,
      mode: "conversational",
    },
  },
});

Use para produtos de chat/agente onde a memória vem de conversas de múltiplos turnos e as perguntas são formuladas de maneira diferente de como as coisas foram ditas ("Quem é o gerente do usuário?" vs. "sim, minha chefe Dana aprovou").

  • É opt-in. Deixar mode não definido (ou omitir providers.extraction) mantém o comportamento de extração padrão; o caminho de classificação de recall não é tocado.
  • É uma passagem LLM em tempo de gravação: usa seu modelo de chat configurado, então adiciona latência de extração e custo de tokens, e como qualquer etapa LLM pode descartar ou formular incorretamente uma afirmação. Os turnos brutos permanecem a verdade fundamental.
  • Não é recuperação semântica. Ele normaliza o texto armazenado para que a recuperação lexical tenha uma superfície melhor para corresponder; não classifica por significado. É a alavanca sem embedding para a lacuna de fraseado conversacional, não um substituto para um provedor de embedding neural.
  • Não cite um número de benchmark dele sem validação em dados retidos, e não ajuste o prompt de extração ao fraseado de um benchmark específico.

Runtime E Armazenamento

createGoodMemory({}) segue um contrato de armazenamento automático local-first:

  • storage.provider explícito vence quando fornecido.
  • Sem armazenamento explícito, o GoodMemory usa Postgres somente quando um destino configurado consegue inicializar o backend do GoodMemory.
  • No Bun, o armazenamento durável de configuração zero é SQLite local em ./.goodmemory/memory.sqlite.
  • Em runtimes Node sem o adaptador SQLite local integrado, o armazenamento de configuração zero recai para em memória.
  • Seleções explícitas não suportadas de sqlite ou postgres integrados são relatadas como indisponíveis em vez de rotuladas incorretamente como duráveis.
  • Adaptadores injetados de documentStore, sessionStore ou vectorStore são relatados como armazenamento definido pelo adaptador.
  • Sem um preset de recuperação, o comportamento em tempo de execução permanece rules-only independentemente da configuração de embeddings. O preset recommended roteia auto para seu caminho de fusão híbrida sem provedor e adiciona evidência densa quando configurado.
  • Runtimes locais suportados podem usar sqlite-vss para indexação semântica SQLite; runtimes não suportados mantêm comportamento de fallback durável sem aceleração.

Adaptadores personalizados de DocumentStore mantêm o contrato original de set/get/update/query/delete. Recursos atômicos, como o preset de fusão generalizada recommended e o gravador de resultados comportamentais opcionais, também exigem ProjectionCapableDocumentStore, cujo projectionBatchSemantics deve ser igual à versão exportada de PROJECTION_BATCH_SEMANTICS e cujo writeBatchIfUnchanged() deve validar atomicamente linhas de expected/unchanged e aplicar cada set e delete no lote. Adaptadores existentes podem continuar a executar sem projeções; um método legado com o mesmo nome deliberadamente não é tratado como o contrato atômico atual. Adicione o marcador de versão somente após o adaptador implementar a semântica completa. Os armazenamentos integrados de memória, SQLite e Postgres já o implementam.

Inspecione o runtime resolvido em vez de adivinhar:

import { createGoodMemory, inspectGoodMemoryRuntime } from "goodmemory";

const memory = createGoodMemory({});
const runtime = inspectGoodMemoryRuntime(memory);

console.log(runtime.storage);

Controles de vetores SQLite:

  • GOODMEMORY_SQLITE_VECTOR_MODE=off|prefer|require
  • GOODMEMORY_SQLITE_CUSTOM_LIBRARY_PATH
  • GOODMEMORY_SQLITE_VECTOR_EXTENSION_PATH
  • GOODMEMORY_SQLITE_VECTOR_EXTENSION_ENTRYPOINT
  • GOODMEMORY_SQLITE_VECTOR_SEARCH_FUNCTION

Personalização Pública de Remember

Integrações de produtos devem personalizar gravações por meio da superfície pública remember. Não use seams de extração somente para teste para comportamento de produto.

import { createGoodMemory, rememberRules } from "goodmemory";

const memory = createGoodMemory({
  remember: {
    preset: "default",
    profiles: [
      {
        id: "life-coach",
        when: { agentId: "life-coach" },
        rules: [
          rememberRules.fact(/my top priority this quarter is (.+)/i, {
            id: "life-goal-priority",
            category: "goal",
            tags: ["life_coach", "long_term_goal"],
            attributes: { horizon: "quarter" },
            content: ({ match }) => match[1] ?? "",
          }),
          rememberRules.preference(/please coach me with (.+)/i, {
            id: "life-coaching-style",
            category: "coaching_style",
            value: ({ match }) => match[1] ?? "",
          }),
        ],
        assistantOutputs: { mode: "confirmed_or_verified_only" },
      },
    ],
  },
});

await memory.remember({
  scope: { userId: "u-1", agentId: "life-coach" },
  messages: [
    {
      role: "user",
      content: "My top priority this quarter is rebuilding my sleep routine.",
    },
  ],
  annotations: [
    {
      messageIndex: 0,
      remember: "always",
      metadataPatch: { tags: ["confirmed_by_host"] },
    },
  ],
});

O perfil extractors pode ser objetos MemoryExtractor brutos ou entradas nomeadas de { id, extractor }. Use extratores nomeados para integrações reais para que eventos de remember e relatórios de eval carreguem extractorIds estável mesmo se a composição do perfil mudar. Eventos de remember também carregam metadados resolvidos de profileId e presetId.

Notas autorais (páginas verbatim)

Extração é a ferramenta certa para conversas, mas um agente que deseja manter uma página (um how-to, um runbook, conhecimento difícil de obter) não deve tê-la fragmentada em fatos de frases. O tipo note armazena o corpo da mensagem verbatim, nunca divide em frases, incorpora-o inteiro quando um adaptador de embeddings existe e o recupera como sua própria faixa limitada sob a configuração padrão (BM25 sobre título e corpo, então uma página longa que cobre a consulta é admitida). Corpos são limitados a 8.192 bytes UTF-8; divida páginas mais longas. Escrever o mesmo título novamente substitui a página anterior com linhagem; uma página idêntica é mesclada.

await memory.remember({
  scope,
  messages: [{ role: "assistant", content: pageMarkdown }],
  annotations: [
    {
      messageIndex: 0,
      remember: "always",
      confirmed: true,
      kindHint: "note",
      metadataPatch: { noteTitle: "Reading MediaWiki sites as an agent" },
    },
  ],
});

A mesma forma está disponível como a ferramenta MCP goodmemory_write_note, a anotação HTTP kindHint: "note" em POST /memory/remember e goodmemory remember --kind note --title "..." --message "...". Notas recuperadas renderizam como uma seção Notes cujo corpo mantém sua estrutura Markdown em todos os modos de saída, incluindo os fragmentos de prompt. Notas são governadas como qualquer outro tipo: escopadas, redigidas, revisáveis, esquecíveis, exportadas sob durable.notes e indexadas por título em MEMORY.md.

Adaptador AI SDK

O caminho do AI SDK compatível com Node do GoodMemory é um manipulador de servidor Request -> Response simples construído a partir de createGoodMemory() e createGoodMemoryAISDK().

import { createGoodMemory } from "goodmemory";
import type { GoodMemoryStreamTextInput } from "goodmemory/ai-sdk";
import { createGoodMemoryAISDK } from "goodmemory/ai-sdk";

const memory = createGoodMemory({});

const aiSDK = createGoodMemoryAISDK({
  memory,
});

type MemoryChatRequest = Pick<
  GoodMemoryStreamTextInput,
  "messages" | "query" | "scope" | "system"
>;

function isMemoryChatRequest(value: unknown): value is MemoryChatRequest {
  if (!value || typeof value !== "object" || Array.isArray(value)) {
    return false;
  }

  const candidate = value as Record<string, unknown>;
  const scope = candidate.scope;
  return Array.isArray(candidate.messages)
    && !!scope
    && typeof scope === "object"
    && !Array.isArray(scope)
    && typeof (scope as { userId?: unknown }).userId === "string"
    && (scope as { userId: string }).userId.trim().length > 0;
}

export async function handleMemoryChat(request: Request): Promise<Response> {
  const body: unknown = await request.json();
  if (!isMemoryChatRequest(body)) {
    return new Response(
      JSON.stringify({
        error: "Expected a request body with a messages array and scope.userId.",
      }),
      {
        headers: { "content-type": "application/json; charset=utf-8" },
        status: 400,
      },
    );
  }

  const result = aiSDK.streamText({
    messages: body.messages,
    query: body.query,
    scope: body.scope,
    system: body.system,
    model: {} as never,
  });

  return result.toTextStreamResponse();
}

Notas:

  • O exemplo canônico de servidor é examples/plain-ai-sdk-server.ts.
  • Exemplos finos de Express e Fastify são examples/express-chat-server.ts e examples/fastify-chat-server.ts.
  • examples/vercel-ai-chat.ts permanece um wrapper/API de nível inferior.
  • Next.js App Router pode mapear export async function POST(request: Request) para o mesmo corpo de manipulador.
  • O primeiro caminho público de servidor é ModelMessage-first.
  • O wrapper aumenta system por meio de recall() e buildContext() e falha suavemente se a camada de memória apresentar erros.

Ponte HTTP Python/FastAPI

Use a ponte HTTP empacotada quando um backend Python deve chamar o GoodMemory como um serviço de memória no lado do servidor.

GOODMEMORY_HTTP_BRIDGE_TOKEN="replace-with-service-token" \
GOODMEMORY_STORAGE_PROVIDER=postgres \
GOODMEMORY_STORAGE_URL="postgres://user:pass@host:5432/goodmemory" \
./node_modules/.bin/goodmemory-http-bridge --profile life-coach

Chamadores Python enviam Authorization: Bearer <token> mais os cabeçalhos de escopo x-goodmemory-* para POST /memory/recall-context, /memory/remember, /memory/feedback, /memory/export, /memory/import, /memory/forget e /memory/revise direcionado. A API da ponte TypeScript está disponível em goodmemory/http.

Para servir o preset de recuperação recomendado (BM25 multi-granular + entidade + RRF, com um canal denso opcional) sobre a ponte, inicie-a com o único switch --recommended (ou GOODMEMORY_PROFILE=agent-recommended ou GOODMEMORY_HTTP_BRIDGE_RECOMMENDED=1). Nenhum endpoint de embeddings é necessário; GOODMEMORY_EMBEDDING_* adiciona o canal denso quando configurado. GET /healthz relata retrievalTier e embeddingEnabled, e solicitações de recall usam por padrão strategy: "auto", que o preset roteia para hybrid. Uma solicitação explícita de strategy: "rules-only" ainda seleciona o piso estrito.

Ou implante com Docker em um comando (volume SQLite incluído; adicione o perfil postgres do compose para pgvector):

GOODMEMORY_HTTP_BRIDGE_TOKEN="replace-with-service-token" docker compose up -d
curl -fsS http://127.0.0.1:8739/healthz

GET /healthz é o endpoint de liveness sem autenticação para contêineres, balanceadores de carga e esperas de prontidão de clientes. Backends Python devem usar o cliente oficial — pip install goodmemory-client (PyPI) — que deriva os cabeçalhos do chamador de um objeto Scope, espelha as regras de idempotência por endpoint e expõe routing de recall (para que rebaixamentos silenciosos de estratégia sejam visíveis). Detalhes: docs/GoodMemory-Python-HTTP-Integration-Bridge.md.

Instância hospedada. Uma ponte GoodMemory ao vivo roda em https://goodmemory.vibenest.net (liveness: /healthz). Aponte qualquer cliente para ela via GOODMEMORY_BRIDGE_HOST / --goodmemory-host (ou o argumento de host GoodMemoryClient) em vez de uma URL local; ela impõe autenticação por bearer-token, então traga seu próprio token de serviço. É uma API de processo único e com capacidade de gravação — antes de expô-la publicamente, adicione limitação de taxa e dados de escopo descartável, e nunca publique um token de gravação compartilhado.

API de Adaptador de Host

Use goodmemory/host quando um host externo quiser artefatos ou contratos específicos de host sem importar internos.

import { createGoodMemory } from "goodmemory";
import { createHostAdapter } from "goodmemory/host";

const memory = createGoodMemory({});

const adapter = createHostAdapter({
  id: "codex-handoff",
  hostKind: "codex",
  memory,
  readableArtifactTypes: ["session_memory"],
});

const result = await adapter.readArtifacts({
  scope: {
    userId: "u-1",
    workspaceId: "workspace-a",
    sessionId: "s-1",
  },
  includeRuntime: true,
});

Modos:

  • file-assisted: lê artefatos compilados como MEMORY.md, user.md, session-memory/<sessionId>.md e playbooks/*.md sem tratar arquivos como armazenamento canônico.
  • file-authoritative: disponível para o subconjunto gravável mínimo. Hoje esse subconjunto é a forma canônica de arquivo playbooks/*.md, gravando deltas estruturados de volta em registros ativos de feedback de padrões validados.

Proteções de gravação:

  • Arquivos de prompt e snippet de habilidade permanecem saídas derivadas somente leitura.
  • Edições de orientação arriscadas exigem aprovação explícita de verifyWrite.
  • Edições de metadados de baixo risco, como appliesTo e Why, podem gravar de volta sem a etapa extra de aprovação.
  • Operações graváveis com falha retornam diagnósticos com orientação de rollback.

Exemplos atuais de Claude/Codex permanecem no modo file-assisted por padrão.

Referência da CLI

O comando goodmemory no seu shell PATH é a CLI global instalada com npm install -g goodmemory@0.8.2. Em uma instalação de dependência local, invoque o bin do pacote como npx goodmemory, npm exec -- goodmemory ou ./node_modules/.bin/goodmemory. O script bun run goodmemory local do repositório é somente para desenvolvimento.

Comandos com foco em memória:

./node_modules/.bin/goodmemory inspect --user-id <user-id> --workspace-id <workspace-id>
./node_modules/.bin/goodmemory trace --user-id <user-id> --workspace-id <workspace-id> --query "Which runbook is the source of truth?"
./node_modules/.bin/goodmemory export-memory --user-id <user-id> --workspace-id <workspace-id> --output ./tmp/export
./node_modules/.bin/goodmemory import-memory --user-id <user-id> --workspace-id <workspace-id> --input ./tmp/export --dry-run
./node_modules/.bin/goodmemory stats --user-id <user-id> --workspace-id <workspace-id>
./node_modules/.bin/goodmemory remember --user-id <user-id> --workspace-id <workspace-id> --session-id <session-id> --message "Remember that the deploy is blocked on smoke verification."
./node_modules/.bin/goodmemory remember --user-id <user-id> --kind note --title "Reading MediaWiki sites as an agent" --message "$(cat page.md)"
./node_modules/.bin/goodmemory feedback --host codex --workspace-root . --session-id <session-id> --signal "Keep coding summaries short and list explicit next steps."
./node_modules/.bin/goodmemory forget --host codex --workspace-root . --session-id <session-id> --memory-id <memory-id>

Comandos de host instalado:

goodmemory -V
goodmemory --version
goodmemory setup --host codex
goodmemory status codex --workspace-root .
goodmemory install codex --activation-mode global --writeback observe --user-id <user-id>
goodmemory enable codex --workspace-root . --writeback selective
goodmemory mcp serve --host codex
goodmemory-mcp --host codex
goodmemory codex bootstrap --user-id <user-id> --workspace-id <workspace-id>
goodmemory claude bootstrap --user-id <user-id> --workspace-id <workspace-id>

Exemplos de hooks e writeback:

printf '%s' '{"cwd":".","session_id":"s-1","hook_event_name":"SessionStart","source":"startup"}' \
  | goodmemory codex hook session-start

printf '%s' '{"cwd":".","session_id":"s-1","tool_name":"Bash","tool_input":{"command":"./tools/DeepAnalyzer --detailed"}}' \
  | goodmemory codex hook pre-tool-use

goodmemory codex action -- ./tools/DeepAnalyzer --detailed

printf '%s' '{"cwd":".","session_id":"s-1","messages":[{"role":"user","content":"Next step is to finish the release smoke."}]}' \
  | goodmemory codex writeback --json

printf '%s' '{"cwd":".","session_id":"s-1","event_id":"stop-1","summary":"Keep coding summaries short."}' \
  | goodmemory codex hook session-stop

Inspeção de artefatos de eval:

./node_modules/.bin/goodmemory eval inspect --run-dir reports/eval/live/<run-id> --case-id <case-id>
./node_modules/.bin/goodmemory eval trace --run-dir reports/eval/live/<run-id> --case-id <case-id>
./node_modules/.bin/goodmemory eval export-case --run-dir reports/eval/live/<run-id> --case-id <case-id> --output /tmp/case.json

Superfície da CLI:

  • goodmemory -V
  • goodmemory --version
  • goodmemory setup
  • goodmemory status
  • goodmemory install
  • goodmemory uninstall
  • goodmemory enable
  • goodmemory disable
  • goodmemory inspect
  • goodmemory trace
  • goodmemory export-memory
  • goodmemory import-memory
  • goodmemory stats
  • goodmemory --schema (imprime toda a superfície da CLI como JSON para agentes e ferramentas; goodmemory <command> --help permanece a forma humana)

Hosts instalados também podem manter o bundle de exportação no disco: goodmemory setup --file-mirror (or install <host> --file-mirror) grava <workspace>/.goodmemory/memory/ após cada gravação durável para que MEMORY.md, topics/*.md e pages/*.md sejam pesquisáveis sem executar a CLI.

  • goodmemory remember
  • goodmemory feedback
  • goodmemory forget
  • goodmemory mcp serve
  • goodmemory-mcp
  • goodmemory codex hook
  • goodmemory codex writeback
  • goodmemory claude hook
  • goodmemory claude writeback
  • goodmemory codex bootstrap
  • goodmemory claude bootstrap
  • goodmemory eval inspect
  • goodmemory eval trace
  • goodmemory eval export-case

Exemplos

Guias de pacote instalado:

Exemplos locais do repositório:

Execute exemplos deste repositório:

bun run example:chat
bun run example:coding-agent
bun run example:ai-sdk-server
bun run example:express-chat
bun run example:fastify-chat
bun run example:vercel-ai
bun run example:life-coach-profile
bun run example:host-claude
bun run example:host-codex

Testes e Eval

Portões locais padrão:

bun test
bun run typecheck
bun run test:coverage

Para preparação completa de pacote, cobertura, consumidor de runtime, tamanho e proveniência, use um diretório de saída explícito:

bun run release:prepare -- --output-dir <dir>

O comando congela a identidade da fonte, executa verificações necessárias, empacota exatamente um tarball, valida esse mesmo tarball com Node e Bun e grava o release-manifest.json autoritativo mais um arquivo de evidência determinístico. summary.md é uma projeção legível por humanos. A preparação não promove ou publica. Esta árvore de fonte não tem comando genérico de promoção. Publicação estável usa esses artefatos locais exatos sob autorização do mantenedor; o fluxo de trabalho de release somente leitura verifica os ativos publicados e a integridade do npm sem um segundo empacotamento ou uma credencial de registro.

Protocolos de pesquisa do repositório são selecionados de um registro estático:

bun run research:list
bun run research:run -- <id> --root <path>
bun run research:verify -- <id> --root <path>

Verificadores históricos de fase e release permanecem reproduzíveis por script direto de sua tag ou commit vinculado; seus antigos aliases de pacote intencionalmente não fazem parte da superfície de comando atual.

Use bun run test:all somente quando você intencionalmente quiser a varredura mais ampla por árvores de teste vendidas ou de terceiros.

Comandos de eval:

bun run eval:smoke
bun run eval:fallback
bun run eval:live
bun run eval:live-memory
bun run eval:live-auto-memory
bun run eval:live-provider-memory
bun run eval:summary

Significados:

  • eval:smoke: verificação automática do harness.
  • eval:fallback: validação determinística sem chamadas de modelo ao vivo.
  • eval:live: gerador ao vivo mais avaliador ao vivo com backend em memória.
  • eval:live-memory: gerador ao vivo mais avaliador ao vivo usando semântica de armazenamento automático; o armazenamento padrão é SQLite local, a menos que o armazenamento do provedor seja resolvido.
  • eval:live-auto-memory: alias para eval:live-memory quando scripts precisam tornar o armazenamento automático explícito.
  • eval:live-provider-memory: caminho de evidência apoiado por provedor que exige Postgres, embeddings e extração assistida; ele não faz fallback silencioso para SQLite.
  • eval:summary: resumir diretórios de saída de avaliação existentes.

Ambiente de avaliação ao vivo:

  • GOODMEMORY_EVAL_PROVIDER
  • GOODMEMORY_EVAL_BASE_URL para gateways compatíveis com OpenAI
  • GOODMEMORY_EVAL_MODEL
  • GOODMEMORY_EVAL_API_KEY
  • GOODMEMORY_EVAL_MAX_CONCURRENCY limite opcional de paralelismo
  • GOODMEMORY_JUDGE_PROVIDER
  • GOODMEMORY_JUDGE_BASE_URL para gateways compatíveis com OpenAI
  • GOODMEMORY_JUDGE_MODEL
  • GOODMEMORY_JUDGE_API_KEY

eval:live-memory e eval:live-auto-memory também precisam de configuração de embeddings e extrator assistido:

  • GOODMEMORY_EMBEDDING_PROVIDER
  • GOODMEMORY_EMBEDDING_BASE_URL para gateways compatíveis com OpenAI
  • GOODMEMORY_EMBEDDING_MODEL
  • GOODMEMORY_EMBEDDING_API_KEY
  • GOODMEMORY_ASSISTED_EXTRACTOR_PROVIDER
  • GOODMEMORY_ASSISTED_EXTRACTOR_BASE_URL para gateways compatíveis com OpenAI
  • GOODMEMORY_ASSISTED_EXTRACTOR_MODEL
  • GOODMEMORY_ASSISTED_EXTRACTOR_API_KEY

eval:live-provider-memory adicionalmente exige:

  • GOODMEMORY_TEST_POSTGRES_URL

Diretórios de saída:

  • execuções ao vivo: reports/eval/live/run-*
  • execuções de memória ao vivo com armazenamento automático: reports/eval/live-memory/run-*
  • execuções de memória ao vivo apoiadas por provedor: reports/eval/live-provider-memory/run-*
  • execuções de fallback: reports/eval/fallback/run-*

Implantação da Estratégia

GoodMemory mantém rules-only como a linha de base suportada. O novo comportamento de recuperação avança por meio de observe -> assist -> promote.

Orientação para operadores:

  • observe: coletar evidências de sombra isoladas sem alterar o caminho executado.
  • assist: permitir execução de candidatos em execuções de avaliação controladas.
  • promote: exigir strategy-promotion-gate.json, um regression-dashboard.json limpo e strategy-promotion-authorization.json.
  • Permanecer rules-only quando as evidências de avaliação estiverem incompletas, as dependências apoiadas por provedor estiverem indisponíveis ou houver condições de rollback.

Status Atual

Superfície pública estável atual:

  • API de memória raiz por meio de goodmemory
  • adaptador AI SDK por meio de goodmemory/ai-sdk
  • adaptador de host e contratos de host por meio de goodmemory/host
  • API de ponte HTTP por meio de goodmemory/http e goodmemory-http-bridge empacotado
  • CLI instalado e configuração de host gerenciado por meio de goodmemory setup
  • hooks do Codex e Claude Code para recall
  • MCP somente leitura para inspeção e depuração
  • writeback instalado no host com auditoria e desfazer (opt-in)
  • fallback durável SQLite local no Bun
  • Postgres, embeddings, extração assistida e avaliações apoiadas por provedor quando configurados

A API interna, remember, recall e a orquestração da CLI são divididas ao longo dos limites de responsabilidade no ADR-009. Esta é uma mudança de manutenção que preserva o comportamento: saída pública da API/CLI, padrões, ordem de persistência, fallback, rastreamento e contratos de serialização permanecem inalterados. A ponte HTTP, o writeback instalado no host e a política de reivindicação de benchmark estão fora deste refator.

Ainda fora da reivindicação pública aceita:

  • writeback automático ativado por padrão
  • arquivo de transcrição bruto
  • dashboard ou nuvem gerenciada
  • tratar arquivos de artefato exportados como armazenamento canônico
  • ampliar exportações raiz com internals de proposta ou promoção

Para o estado atual detalhado e o mapa de evidências, use docs/GoodMemory-Current-Status-and-Evidence.md.

Documentação

Use task-board/00-README.txt para ordem de execução, trabalho de acompanhamento em aberto e limites de aceitação específicos de fase. Entradas de design arquivadas não são verdade atual e são roteadas por meio de docs/README.md.