Criar uma memória semântica do projeto com o Basic Memory e o Milvus

O Basic Memory armazena o conhecimento do projeto em ficheiros Markdown comuns e disponibiliza-o através de uma CLI e de um servidor MCP. Isto proporciona a um agente de programação um local duradouro para guardar decisões, manuais de procedimentos e lições que devem perdurar para além de uma única conversa.

Neste tutorial, iremos criar um pequeno projeto de memória para uma equipa de desenvolvimento de aplicações. Iremos registar notas sobre cache, autenticação, implementações e cópias de segurança e, em seguida, recuperar a nota correta através de pesquisa semântica e híbrida.

O Milvus armazenará os vetores e executará a pesquisa de similaridade. O Basic Memory continuará a gerir as notas Markdown, os metadados do projeto, a pesquisa de texto completo e o manifesto de vetores no PostgreSQL.

Markdown notes
      |
      v
Basic Memory CLI / MCP
      |-- PostgreSQL: projects, metadata, full-text search, vector manifest
      |-- OpenAI: embeddings
      `-- Milvus: vector persistence and similarity search

Este tutorial utiliza o Milvus Lite, que é executado localmente num caminho na sua máquina. A mesma configuração do Basic Memory pode, posteriormente, apontar para o Milvus Standalone, o Milvus Distributed ou o Zilliz Cloud.

Pré-requisitos

É necessário:

  • Python 3.12 ou posterior
  • uv
  • Uma base de dados PostgreSQL e a respetiva URL de ligação postgresql+asyncpg://...
  • Uma chave de API da OpenAI

Instale o Basic Memory com as suas dependências opcionais do Milvus a partir do PyPI:

uv tool install --python 3.12 "basic-memory[milvus]"

Configure o Basic Memory

Crie um espaço de trabalho para o tutorial. Manter aqui a configuração do Basic Memory e os dados do Milvus Lite facilita a análise do exemplo e a sua remoção posterior.

mkdir -p basic-memory-milvus-demo/notes
cd basic-memory-milvus-demo

export BASIC_MEMORY_CONFIG_DIR="$PWD/.basic-memory"

Configure o PostgreSQL como base de dados principal, a OpenAI como fornecedor de incorporação e o Milvus como índice vetorial:

export BASIC_MEMORY_DATABASE_BACKEND=postgres
export BASIC_MEMORY_DATABASE_URL="postgresql+asyncpg://USER:PASSWORD@HOST:5432/DATABASE"

export BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED=true
export BASIC_MEMORY_SEMANTIC_VECTOR_INDEX=milvus
export BASIC_MEMORY_MILVUS_URI="$PWD/basic-memory-vectors.db"

export BASIC_MEMORY_SEMANTIC_EMBEDDING_PROVIDER=openai
export BASIC_MEMORY_SEMANTIC_EMBEDDING_MODEL=text-embedding-3-small
export OPENAI_API_KEY="sk-***********"

Aqui, BASIC_MEMORY_MILVUS_URI é um caminho local, pelo que o PyMilvus inicia o Milvus Lite automaticamente. Não é necessário um servidor Milvus separado.

O Milvus é opcional na «Memória Básica» como um todo, mas é o backend de vetores selecionado neste tutorial. Atualmente, a seleção aplica-se apenas quando o backend da base de dados principal é o PostgreSQL. Os projetos de «Memória Básica» baseados em SQLite utilizam, em vez disso, sqlite-vec.

Criar um projeto de memória

Um projeto de Basic Memory associa um nome a um diretório de notas em Markdown. Adicione o diretório do tutorial como projeto e defina-o como predefinido:

bm project add app-memory "$PWD/notes" --default

A equipa de aplicação dispõe agora de um espaço de memória duradouro. Vamos preenchê-lo com um pequeno catálogo misto. Algumas notas serão relevantes para as nossas questões posteriores, enquanto outras servirão de distrações realistas.

Registar as memórias do projeto

Comece pela decisão de cache da aplicação:

bm tool write-note \
  --title "Caching Strategy" \
  --folder "engineering" \
  --project app-memory <<'EOF'
# Caching Strategy

The application caches read-heavy product responses in Redis for five minutes. This avoids repeated database queries and makes repeated requests faster. Cache entries are invalidated immediately after a write.
EOF

Registe como os tokens de autenticação são tratados:

bm tool write-note \
  --title "Authentication Tokens" \
  --folder "engineering" \
  --project app-memory <<'EOF'
# Authentication Tokens

JWT access tokens expire after fifteen minutes. Refresh tokens rotate on every use. After suspicious activity, revoke the entire token family and require the user to sign in again.
EOF

Adicione dois manuais operacionais:

bm tool write-note \
  --title "Deployment Reliability" \
  --folder "operations" \
  --project app-memory <<'EOF'
# Deployment Reliability

Production releases use a canary deployment. Readiness probes must pass before traffic shifts, and the rollout automatically stops when the error rate crosses the agreed threshold.
EOF

bm tool write-note \
  --title "Database Backups" \
  --folder "operations" \
  --project app-memory <<'EOF'
# Database Backups

PostgreSQL uses daily snapshots and continuous write-ahead log archiving. The team runs a restore drill every month and records the recovery point and recovery time.
EOF

Por fim, adicione duas notas de produto não relacionadas. Estas tornam o exercício de pesquisa mais representativo do que um catálogo em que todos os documentos são relevantes:

bm tool write-note \
  --title "UI Accessibility" \
  --folder "product" \
  --project app-memory <<'EOF'
# UI Accessibility

The settings screen must support keyboard navigation, visible focus states, sufficient color contrast, and descriptive labels for screen readers.
EOF

bm tool write-note \
  --title "Content Planning" \
  --folder "product" \
  --project app-memory <<'EOF'
# Content Planning

The content calendar tracks blog drafts, launch screenshots, reviewers, and publication dates for the next product release.
EOF

Cada nota continua a ser um ficheiro Markdown comum em notes/. O Basic Memory adiciona a estrutura pesquisável sem retirar a propriedade ao sistema de ficheiros.

Crie os índices de pesquisa

Execute uma reindexação completa após adicionar ou alterar substancialmente um grupo de notas:

bm reindex --full --project app-memory

Durante este passo, o Basic Memory:

  1. Lê e divide as notas Markdown em blocos.
  2. Cria o índice de texto completo no PostgreSQL.
  3. Envia os fragmentos para o modelo de incorporação OpenAI configurado.
  4. Armazena os vetores resultantes na coleção Milvus específica do projeto.
  5. Marca os fragmentos armazenados com sucesso como «prontos» no seu manifesto de vetores do PostgreSQL.

O Basic Memory utiliza uma coleção Milvus determinística para cada projeto. Não é necessário criar nem nomear a coleção manualmente.

Recuperar uma memória por significado

Suponha que um novo engenheiro se lembre de que a aplicação tem uma otimização para pedidos repetidos, mas não se lembre de que a equipa lhe chamava «estratégia de cache».

Utilize a pesquisa vetorial para fazer a pergunta em linguagem natural:

bm tool search-notes \
  "How does the application make repeated requests faster?" \
  --vector \
  --project app-memory \
  --page-size 3 \
  --plain

Caching Strategy deve ser o resultado principal, mesmo que a consulta não precise de repetir o título da nota. A pesquisa vetorial incorpora a pergunta e solicita ao Milvus os blocos armazenados mais próximos.

As pontuações exatas e os resultados com classificação inferior podem variar consoante o modelo de incorporação e o conteúdo do projeto.

Combinar sinais semânticos e de palavras-chave

Imagine agora que está a responder a um incidente de segurança. A consulta contém termos exatos, como « JWT », mas também queremos linguagem conceptualmente relacionada com a revogação de tokens e o login novamente.

Utilize a pesquisa híbrida:

bm tool search-notes \
  "JWT rotation after suspicious activity" \
  --hybrid \
  --project app-memory \
  --page-size 3 \
  --plain

Authentication Tokens deve ser o resultado principal. O Basic Memory combina a recuperação de texto completo do PostgreSQL com a recuperação vetorial do Milvus, privilegiando o conteúdo que se destaca em qualquer uma das vias e, especialmente, o conteúdo encontrado por ambas.

Os três modos de pesquisa têm pontos fortes diferentes:

ModoSinalizador de comandoMelhor utilização
Texto completoSem sinalizador de modoTermos exatos, frases e consultas booleanas com palavras-chave
Vetorial--vectorParafrases, conceitos e questões exploratórias
Híbrido--hybridRecuperação de uso geral utilizando tanto sinais de palavras-chave como sinais semânticos

Utilize outra implementação do Milvus

O código da aplicação e os comandos do Basic Memory não se alteram quando ultrapassar os limites do Milvus Lite. Altere o URI e, quando necessário, forneça um token.

Para um servidor Milvus:

export BASIC_MEMORY_MILVUS_URI="http://localhost:19530"
export BASIC_MEMORY_MILVUS_TOKEN="root:Milvus"

Para o Zilliz Cloud:

export BASIC_MEMORY_MILVUS_URI="https://YOUR_CLUSTER_ENDPOINT"
export BASIC_MEMORY_MILVUS_TOKEN="YOUR_API_KEY"

Crie uma nova coleção de destino ou siga o procedimento de migração do armazenamento de vetores do Basic Memory antes de mudar um projeto existente entre backends de vetores. Em seguida, recompile os vetores:

bm reindex --full --project app-memory

Utilize a mesma memória através do MCP

A CLI é útil para a configuração, manutenção, criação de scripts e compreensão do fluxo de dados. No trabalho quotidiano, um cliente MCP pode iniciar o mesmo serviço da Basic Memory e chamar ferramentas como write_note, search_notes e build_context diretamente.

Por exemplo, uma configuração do Codex MCP pode executar o comando instalado por uv tool:

[mcp_servers.basic-memory]
command = "basic-memory"
args = ["mcp"]

[mcp_servers.basic-memory.env]
BASIC_MEMORY_CONFIG_DIR = "/absolute/path/to/basic-memory-milvus-demo/.basic-memory"
BASIC_MEMORY_DATABASE_BACKEND = "postgres"
BASIC_MEMORY_DATABASE_URL = "postgresql+asyncpg://USER:PASSWORD@HOST:5432/DATABASE"
BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED = "true"
BASIC_MEMORY_SEMANTIC_VECTOR_INDEX = "milvus"
BASIC_MEMORY_MILVUS_URI = "/absolute/path/to/basic-memory-milvus-demo/basic-memory-vectors.db"
BASIC_MEMORY_SEMANTIC_EMBEDDING_PROVIDER = "openai"
BASIC_MEMORY_SEMANTIC_EMBEDDING_MODEL = "text-embedding-3-small"
OPENAI_API_KEY = "sk-***********"

Outros clientes MCP utilizam o mesmo executável e argumentos no formato JSON:

{
  "mcpServers": {
    "basic-memory": {
      "command": "basic-memory",
      "args": ["mcp"],
      "env": {
        "BASIC_MEMORY_CONFIG_DIR": "/absolute/path/to/basic-memory-milvus-demo/.basic-memory",
        "BASIC_MEMORY_DATABASE_BACKEND": "postgres",
        "BASIC_MEMORY_DATABASE_URL": "postgresql+asyncpg://USER:PASSWORD@HOST:5432/DATABASE",
        "BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED": "true",
        "BASIC_MEMORY_SEMANTIC_VECTOR_INDEX": "milvus",
        "BASIC_MEMORY_MILVUS_URI": "/absolute/path/to/basic-memory-milvus-demo/basic-memory-vectors.db",
        "BASIC_MEMORY_SEMANTIC_EMBEDDING_PROVIDER": "openai",
        "BASIC_MEMORY_SEMANTIC_EMBEDDING_MODEL": "text-embedding-3-small",
        "OPENAI_API_KEY": "sk-***********"
      }
    }
  }
}

Sempre que possível, mantenha as palavras-passe da base de dados e as chaves da API na gestão de segredos ou no ambiente de execução do seu cliente. O requisito importante é que o processo do MCP receba a mesma configuração de «Basic Memory» utilizada pela CLI.

O que cada camada de armazenamento possui

No final do tutorial, as responsabilidades são deliberadamente separadas:

  • O diretório do projeto é responsável pelas notas Markdown originais.
  • O PostgreSQL é responsável pelos projetos, entidades, metadados, índice de texto completo e manifesto vetorial de referência do Basic Memory.
  • A OpenAI transforma fragmentos de notas e questões de pesquisa em embeddings.
  • O Milvus é responsável pela persistência de vetores e pela recuperação do vizinho mais próximo.
  • O Basic Memory coordena as camadas e disponibiliza uma experiência unificada de CLI e MCP.

O Milvus, portanto, não substitui o PostgreSQL nesta integração. Substitui o caminho « pgvector » do PostgreSQL para o armazenamento de vetores e a pesquisa de similaridade, enquanto as restantes funcionalidades relacionais e de texto completo da Basic Memory permanecem no PostgreSQL.