SSD Nodes Learn 🎉 VPS desde $5.50/mês
Guias Matt ConnorPor Matt Connor · Atualizado 2026-08-21

Tipos de memória de agentes e custo no VPS

Compare memória semântica, episódica e procedural em uma tabela e veja o custo real de armazenar e re-embutir cada tipo em um VPS.

Quais são os três tipos de memória dos agentes

Os tipos de memória dos agentes dividem-se em três categorias, e cada uma delas tem um impacto diferente no hardware pelo qual paga: a memória semântica armazena factos, a memória episódica armazena o que aconteceu e a memória procedural armazena como executar uma tarefa. A tabela abaixo define cada tipo com um exemplo de servidor. O conteúdo seguinte trata da parte que normalmente fica por explicar: o custo de armazenar cada tipo e o custo de o reconstruir.

ChartThe three agent memory types, with one server example of each
The data behind this chart
[
  {
    "label": "Semantic",
    "what_it_holds": "Facts the agent should treat as currently true",
    "server_example": "The database listens on 10.8.0.4:5432 and the nightly dump runs at 03:15 UTC"
  },
  {
    "label": "Episodic",
    "what_it_holds": "A record of one past event or session",
    "server_example": "On 2026-08-11 the deploy failed because the disk was full, and rotating logs fixed it"
  },
  {
    "label": "Procedural",
    "what_it_holds": "How to carry out a task, as steps the agent can run",
    "server_example": "The restore runbook: stop the service, load the dump, run migrations, start the service"
  }
]

Os nomes são emprestados da psicologia humana, mas a correspondência é aproximada. A divisão é útil por uma razão prática: os três tipos têm dimensões e processos de recuperação diferentes. Armazená-los todos num único vector store prejudica cada um deles.

A memória semântica é pequena, e vai querer editá-la manualmente

Algumas centenas de factos sobre os seus próprios servidores correspondem a algumas dezenas de kilobytes de texto. O armazenamento não é o problema. A correção é. Um facto incorreto na memória semântica fica incorreto em todas as respostas seguintes do agente. Por isso, o armazenamento tem de permitir localizar um facto pelo nome, alterá-lo e confirmar que o valor antigo desapareceu.

Isto aponta para um armazenamento com chaves: uma tabela PostgreSQL com uma chave primária ou um diretório de pequenos ficheiros Markdown num repositório Git. Ambos permitem executar uma consulta, ver o valor e editá-lo no local. A pesquisa por similaridade não oferece isso, porque recupera informação por semelhança e não por chave. "Alterar a porta da base de dados" transforma-se em "localizar todos os fragmentos que mencionam a porta da base de dados", e não é possível provar que todos foram encontrados. Mantenha os factos indexados por chaves. Também pode gerar embeddings se quiser obter recuperação aproximada, mas trate a cópia indexada por chaves como a fonte de verdade.

Os factos obsoletos não se identificam por si próprios. A porta muda e a linha permanece, pelo que o agente continua a responder com um número que estava correto em junho. Uma política de obsolescência e remoção para a memória do agente é a outra parte desta página e é muito mais barato defini-la enquanto a tabela ainda é pequena.

Por que a memória episódica cresce sem limite

A memória episódica é um log, e os logs crescem. Cada sessão, cada chamada de ferramenta e cada comando que falhou é um episódio possível. Um agente que escreve uma linha por turno escreverá muito mais linhas num mês do que alguém alguma vez conseguirá ler. O disco não é o único custo: cada episódio incorporado também entra no índice que a pesquisa precisa de percorrer.

Defina a regra de retenção no dia em que criar a tabela, enquanto eliminar ainda é simples. Duas perguntas resolvem a maior parte do problema. Primeiro, o que vale a pena escrever: normalmente, um resumo de uma sessão vale a pena; a saída completa de um ls -la normalmente não. Segundo, durante quanto tempo cada classe de episódio deve permanecer: por exemplo, episódios brutos durante 30 dias e resumos de sessões durante um ano.

Adicione a cada linha de episódio um carimbo de data e hora created_at e uma coluna source. Sem created_at, não é possível eliminar dados por idade. Sem source, não é possível eliminar tudo o que veio de uma origem problemática. Isto é exatamente o que precisa de fazer quando uma página Web ou um ticket acaba por ter inserido instruções na memória.

DELETE FROM episodes WHERE created_at < now() - interval '30 days';

Execute isso a partir de um temporizador do systemd. Depois, confirme se a contagem de linhas e o tamanho da tabela diminuem efetivamente. Uma política de retenção que ninguém executa é apenas um comentário.

psql -d agentmem -c "SELECT count(*) FROM episodes;"
psql -d agentmem -c "SELECT pg_size_pretty(pg_total_relation_size('episodes'));"

A memória procedural deve ficar num repositório

A memória procedural define como o agente executa uma tarefa: um shell script, um ficheiro de skill ou um runbook com passos numerados. Isto é código, e o código deve ficar onde o código é mantido: num repositório git com revisão, versões e um diff legível.

Se armazenar um runbook como blocos incorporados, obterá uma cópia aproximada. A recuperação devolve os blocos com a pontuação mais elevada. Assim, o agente pode executar o passo 2 e o passo 5, enquanto o passo 3 nunca é apresentado. Além disso, não fica registada a versão do procedimento executado. No git, git log responde às duas perguntas. O custo de armazenamento é praticamente nulo. Esse é outro motivo para não pagar preços de vetores por este conteúdo.

Quanto custa realmente um embedding em disco

ChartVector storage in pgvector, at 4 bytes per dimension plus an 8 byte header
The data behind this chart
[
  {
    "label": "bge-small-en-v1.5 (384 dims)",
    "bytes_per_vector": 1544,
    "mib_per_100k_rows": 147.2
  },
  {
    "label": "bge-base-en-v1.5 (768 dims)",
    "bytes_per_vector": 3080,
    "mib_per_100k_rows": 293.7
  },
  {
    "label": "bge-large-en-v1.5 (1024 dims)",
    "bytes_per_vector": 4104,
    "mib_per_100k_rows": 391.4
  },
  {
    "label": "text-embedding-3-small (1536 dims)",
    "bytes_per_vector": 6152,
    "mib_per_100k_rows": 586.7
  },
  {
    "label": "text-embedding-3-large (3072 dims)",
    "bytes_per_vector": 12296,
    "mib_per_100k_rows": 1172.6
  }
]

O pgvector armazena um vector com 4 bytes por dimensão, mais um cabeçalho de 8 bytes. Este cálculo é fixo e permite planear o armazenamento antes de carregar qualquer dado. Um vetor com 384 dimensões ocupa 1544 bytes. Assim, 100,000 chunks ocupam 147.2 MiB de vetores. O mesmo corpus, convertido para 3,072 dimensões, ocupa 1172.6 MiB, com 12296 bytes por linha. O texto é o mesmo, mas o armazenamento é quase oito vezes maior.

Isto corresponde apenas à coluna de vetores. O texto dos chunks, a chave primária, o overhead das linhas e o índice são adicionais. O índice é a parte que costuma ser esquecida. O HNSW (hierarchical navigable small world, o índice de grafos criado pelo pgvector) mantém a sua própria cópia dos vetores a que faz referência. Por isso, um armazenamento indexado ocupa confortavelmente mais do dobro dos valores acima. Meça o seu ambiente em vez de fazer estimativas.

SELECT pg_size_pretty(pg_total_relation_size('memories')) AS total,
       pg_size_pretty(pg_relation_size('memories_embedding_idx')) AS idx;

A RAM determina se a pesquisa parece rápida, porque o grafo só pode ser percorrido rapidamente enquanto estiver na memória. Quando o índice é maior do que a memória disponível para o Postgres, as pesquisas começam a ler dados do disco e a latência aumenta. A compilação tem o seu próprio limite, maintenance_work_mem. Quando o grafo ultrapassa esse limite, a compilação informa o problema e fica mais lenta:

NOTICE:  hnsw graph no longer fits into maintenance_work_mem after 61440 tuples
HINT:  Increase maintenance_work_mem to speed up builds.

Há duas formas de reduzir o tamanho do mesmo corpus. Escolha um modelo menor. 384 dimensões custam um quarto do armazenamento de 1,536 dimensões e, para reencontrar as suas próprias notas, a diferença de precisão costuma ser pequena o suficiente para ser aceitável. Outra opção é armazenar os valores com metade da precisão. O tipo halfvec utiliza 2 bytes por dimensão, mais o mesmo cabeçalho de 8 bytes. Assim, reduz quase para metade a coluna e o respetivo índice.

Vale a pena conhecer um limite antes de escolher um modelo. Em agosto de 2026, uma coluna vector pode ser indexada até 2,000 dimensões. Por isso, um embedding com 3,072 dimensões é aceite pela coluna, mas recusado pelo índice:

ERROR:  column cannot have more than 2000 dimensions for hnsw index

halfvec permite indexar até 4,000 dimensões. A correção habitual é indexar o resultado da conversão:

CREATE INDEX ON memories USING hnsw ((embedding::halfvec(3072)) halfvec_cosine_ops);

Quando o pgvector é melhor do que um serviço de memória separado

Se o servidor já executa o Postgres, os vetores ficam num único pacote e numa única instrução.

psql -V
sudo apt install postgresql-16-pgvector
CREATE EXTENSION vector;

O número no nome do pacote corresponde à versão principal do Postgres: 16 no Ubuntu 24.04. Por isso, leia psql -V antes de executar o comando.

Manter a memória nessa base de dados permite fazer uma única cópia de segurança da memória e dos dados da aplicação ao mesmo tempo, usar um único pool de ligações e tirar partido de transações: o facto e a linha que o descreve são confirmados juntos ou falham juntos. Um serviço separado não pode garantir isso.

Mude para um serviço de memória dedicado quando uma destas condições se aplicar. A carga de pesquisa compete com a aplicação e precisa da sua própria máquina. Vários agentes em vários hosts partilham uma memória. Ou pretende usar a lógica de extração e deduplicação incluída num produto completo, que é o motivo para escolher um servidor de memória Mem0 autoalojado. Para um agente e um corpus com poucos milhões de chunks, o pgvector no servidor que já utiliza exige menos operação e apresenta menos pontos de falha. A escolha do mecanismo e os requisitos de RAM de cada mecanismo são abordados em executar uma base de dados vetorial numa VPS.

O que custa gerar novos embeddings quando se muda o modelo

Os vetores gerados por dois modelos diferentes não são comparáveis. Por isso, não pode gerar embeddings para novas memórias com um modelo novo e deixar as linhas antigas inalteradas. Uma tabela com vetores misturados devolve resultados sem sentido, porque uma distância calculada entre dois sistemas de coordenadas diferentes não tem significado. Mudar de modelo implica gerar novamente os embeddings de todo o corpus.

Esse custo tem quatro componentes: os tokens (uma cobrança de API ou tempo de CPU e GPU no seu próprio servidor), o tempo de execução, o espaço em disco necessário para manter ambas as colunas durante o preenchimento e a reconstrução do índice no final. A ordem segura é adicionar uma coluna nova, preenchê-la em lotes, alterar a consulta para usar essa coluna e, depois, remover a coluna antiga e o respetivo índice.

Meça a taxa no seu próprio hardware em vez de confiar num valor publicado. A geração de embeddings apenas com CPU num VPS pequeno é muito mais lenta do que a execução do mesmo modelo numa GPU. Cronometre um fragmento representativo e multiplique o resultado pelo tamanho do corpus.

ollama pull nomic-embed-text
time curl -s http://localhost:11434/api/embed \
  -d '{"model": "nomic-embed-text", "input": "one representative chunk of your corpus"}' > /dev/null

Um modelo local de embeddings também armazena os seus pesos no mesmo disco que o armazenamento de memórias. onde o Ollama armazena os modelos transferidos explica onde esse espaço é utilizado.

Um requisito torna tudo isto possível: mantenha o texto de origem junto de cada vetor. Um armazenamento que contenha apenas vetores não pode gerar novos embeddings, porque já não há texto para fornecer ao novo modelo. Se não consegue responder à pergunta "que texto produziu esta linha", o caminho de migração é uma reconstrução completa a partir do local de onde o texto veio originalmente.

O que monitorizar quando a memória está em execução

O custo não é a única coisa que muda à medida que o armazenamento fica cheio. Factos antigos ficam desatualizados e episódios antigos ocupam o espaço de resultados úteis. O problema volta a ser a poda. Um armazenamento de memória também é uma entrada gravável para o comportamento futuro do agente. Por isso, tudo o que puder escrever nesse armazenamento poderá orientar o agente mais tarde. Se texto de páginas Web ou de tickets chegar à memória, leia como funciona o envenenamento da memória do agente antes de alargar o que pode escrever nela. O tamanho da recuperação também determina o consumo de tokens em cada pedido. É aí que começa manter previsível o custo operacional de um agente.

FAQ

Preciso de um banco de dados vetorial para a memória do agente?

Não para factos. A memória semântica é pequena e precisa de ser corrigida pelo nome, por isso uma tabela indexada por chave ou um diretório de ficheiros Markdown num repositório git é mais adequado: pode ver um valor e editá-lo. Os embeddings compensam o custo quando é necessário procurar por significado num corpus demasiado grande para ser listado, o que normalmente corresponde a memória episódica e documentos. Se já executa Postgres, CREATE EXTENSION vector trata dessa necessidade sem adicionar outro serviço para administrar.

Quanto espaço em disco ocupa um armazenamento de memória de agente?

Os vetores têm um tamanho previsível: 4 bytes por dimensão, mais um cabeçalho de 8 bytes no pgvector. Com 768 dimensões, isso corresponde a 293.7 MiB por 100.000 linhas; com 384 dimensões, corresponde a 147.2 MiB. Depois, acrescente o texto dos chunks, a sobrecarga das linhas e um índice HNSW que mantém a sua própria cópia dos vetores. Por isso, reserve pelo menos o dobro do espaço indicado para os vetores e meça o valor real com pg_total_relation_size.

Onde deve ficar a memória procedural?

Num repositório git, como scripts ou ficheiros de skills que o agente executa diretamente. Um procedimento precisa de ser recuperado com exatidão e de ter um histórico de versões. A pesquisa por similaridade não fornece nenhuma dessas garantias. Um runbook dividido em chunks devolve as partes com maior pontuação. Isso pode fazer com que os passos 2 e 5 sejam devolvidos sem o passo 3, e não fica registada a versão executada.

Qual é o custo de mudar o modelo de embeddings?

É necessário gerar novamente os embeddings de todo o corpus, porque não é possível comparar diretamente vetores de modelos diferentes. Reserve o custo dos tokens ou o tempo de GPU, o espaço em disco para as colunas antiga e nova durante a migração e a reconstrução do índice. Adicione a coluna nova, preencha-a em lotes, altere a consulta para a utilizar e depois remova a coluna antiga. Tudo isto depende de ter mantido o texto de origem junto de cada vetor.

#agent-memory#semantic-memory#episodic-memory#pgvector#storage