Introdução ao Mem0 e ao Milvus
O Mem0 é uma camada de memória inteligente para aplicações de IA, concebida para proporcionar interações personalizadas e eficientes, retendo as preferências do utilizador e adaptando-se continuamente ao longo do tempo. Ideal para chatbots e ferramentas orientadas por IA, o Mem0 cria experiências perfeitas e conscientes do contexto.
Neste tutorial, abordaremos as operações essenciais de gerenciamento de memória do Mem0 - adicionando, recuperando, atualizando, pesquisando, excluindo e rastreando o histórico de memória - usando o Milvus, um banco de dados vetorial de alto desempenho e de código aberto que possibilita o armazenamento e a recuperação eficientes. Esta introdução prática guiá-lo-á através de operações de memória fundamentais para o ajudar a criar interações de IA personalizadas com o Mem0 e o Milvus.
Preparação
Descarregar as bibliotecas necessárias
$ pip install mem0ai pymilvus
Se estiver a utilizar o Google Colab, para ativar as dependências que acabou de instalar, poderá ter de reiniciar o tempo de execução (clique no menu "Tempo de execução" na parte superior do ecrã e selecione "Reiniciar sessão" no menu pendente).
Configurar o Mem0 com o Milvus
Neste exemplo, vamos utilizar o OpenAI como LLM. Deve preparar a chave api OPENAI_API_KEY
como uma variável de ambiente.
import os
os.environ["OPENAI_API_KEY"] = "sk-***********"
Agora, podemos configurar o Mem0 para usar o Milvus como o armazenamento de vetores
# Define Config
from mem0 import Memory
config = {
"vector_store": {
"provider": "milvus",
"config": {
"collection_name": "quickstart_mem0_with_milvus",
"embedding_model_dims": "1536",
"url": "./milvus.db", # Use local vector database for demo purpose
},
},
"version": "v1.1",
}
m = Memory.from_config(config)
- Se só precisar de uma base de dados vetorial local para dados de pequena escala ou prototipagem, definir o uri como um ficheiro local, por exemplo
./milvus.db
, é o método mais conveniente, uma vez que utiliza automaticamente o Milvus Lite para armazenar todos os dados neste ficheiro.- Se tiver uma grande escala de dados, digamos mais de um milhão de vectores, pode configurar um servidor Milvus mais eficiente em Docker ou Kubernetes. Nessa configuração, use o endereço e a porta do servidor como seu uri, por exemplo,
http://localhost:19530
. Se ativar a funcionalidade de autenticação no Milvus, utilize "<your_username>:<your_password>" como token, caso contrário não defina o token.- Se utilizar o Zilliz Cloud, o serviço de nuvem totalmente gerido para o Milvus, ajuste os endereços
uri
etoken
, que correspondem ao Public Endpoint e à chave API no Zilliz Cloud.
Gerir as memórias do utilizador com o Mem0 e o Milvus
Adicionar uma memória
A função add
armazena texto não estruturado no Milvus como uma memória, associando-o a um utilizador específico e a metadados opcionais.
Aqui, estamos a adicionar a memória da Alice, "working on improving my tennis skills", juntamente com metadados relevantes para o contexto do Milvus.
# Add a memory to user: Working on improving tennis skills
res = m.add(
messages="I am working on improving my tennis skills.",
user_id="alice",
metadata={"category": "hobbies"},
)
res
{'results': [{'id': '77162018-663b-4dfa-88b1-4f029d6136ab',
'memory': 'Working on improving tennis skills',
'event': 'ADD'}],
'relations': []}
Atualizar uma memória
Podemos utilizar o valor de retorno da função add
para obter o ID da memória, permitindo-nos atualizar esta memória com novas informações através de update
.
# Get memory_id
memory_id = res["results"][0]["id"]
# Update this memory with new information: Likes to play tennis on weekends
m.update(memory_id=memory_id, data="Likes to play tennis on weekends")
{'message': 'Memory updated successfully!'}
Obter todas as memórias de um utilizador
Podemos utilizar a função get_all
para visualizar todas as memórias inseridas ou filtrar por user_id
no Milvus.
Repare que podemos ver que a memória foi alterada de "Trabalhar para melhorar as capacidades de ténis" para "Gosta de jogar ténis aos fins-de-semana".
# Get all memory for the user Alice
m.get_all(user_id="alice")
{'results': [{'id': '77162018-663b-4dfa-88b1-4f029d6136ab',
'memory': 'Likes to play tennis on weekends',
'hash': '4c3bc9f87b78418f19df6407bc86e006',
'metadata': None,
'created_at': '2024-11-01T19:33:44.116920-07:00',
'updated_at': '2024-11-01T19:33:47.619857-07:00',
'user_id': 'alice'}]}
Ver o histórico de actualizações da memória
Também podemos ver o histórico de actualizações da memória especificando o memory_id em que estamos interessados através da função history
.
m.history(memory_id=memory_id)
[{'id': '71ed3cec-5d9a-4fa6-a009-59802450c0b9',
'memory_id': '77162018-663b-4dfa-88b1-4f029d6136ab',
'old_memory': None,
'new_memory': 'Working on improving tennis skills',
'event': 'ADD',
'created_at': '2024-11-01T19:33:44.116920-07:00',
'updated_at': None},
{'id': 'db2b003c-ffb7-42e4-bd8a-b9cf56a02bb9',
'memory_id': '77162018-663b-4dfa-88b1-4f029d6136ab',
'old_memory': 'Working on improving tennis skills',
'new_memory': 'Likes to play tennis on weekends',
'event': 'UPDATE',
'created_at': '2024-11-01T19:33:44.116920-07:00',
'updated_at': '2024-11-01T19:33:47.619857-07:00'}]
Procurar memória
Podemos utilizar a função search
para procurar a memória mais relacionada com o utilizador.
Vamos começar por adicionar outra memória para a Alice.
new_mem = m.add(
"I have a linear algebra midterm exam on November 20",
user_id="alice",
metadata={"category": "task"},
)
Agora, chamamos get_all
especificando o user_id para verificar se temos de facto 2 entradas de memória para a utilizadora Alice.
m.get_all(user_id="alice")
{'results': [{'id': '77162018-663b-4dfa-88b1-4f029d6136ab',
'memory': 'Likes to play tennis on weekends',
'hash': '4c3bc9f87b78418f19df6407bc86e006',
'metadata': None,
'created_at': '2024-11-01T19:33:44.116920-07:00',
'updated_at': '2024-11-01T19:33:47.619857-07:00',
'user_id': 'alice'},
{'id': 'aa8eaa38-74d6-4b58-8207-b881d6d93d02',
'memory': 'Has a linear algebra midterm exam on November 20',
'hash': '575182f46965111ca0a8279c44920ea2',
'metadata': {'category': 'task'},
'created_at': '2024-11-01T19:33:57.271657-07:00',
'updated_at': None,
'user_id': 'alice'}]}
Podemos executar search
agora fornecendo query
e user_id
. Note-se que, por defeito, estamos a utilizar a métrica L2
para a pesquisa de semelhanças, pelo que um score
mais pequeno significa maior semelhança.
m.search(query="What are Alice's hobbies", user_id="alice")
{'results': [{'id': '77162018-663b-4dfa-88b1-4f029d6136ab',
'memory': 'Likes to play tennis on weekends',
'hash': '4c3bc9f87b78418f19df6407bc86e006',
'metadata': None,
'score': 1.2807445526123047,
'created_at': '2024-11-01T19:33:44.116920-07:00',
'updated_at': '2024-11-01T19:33:47.619857-07:00',
'user_id': 'alice'},
{'id': 'aa8eaa38-74d6-4b58-8207-b881d6d93d02',
'memory': 'Has a linear algebra midterm exam on November 20',
'hash': '575182f46965111ca0a8279c44920ea2',
'metadata': {'category': 'task'},
'score': 1.728922724723816,
'created_at': '2024-11-01T19:33:57.271657-07:00',
'updated_at': None,
'user_id': 'alice'}]}
Apagar memória
Também podemos delete
uma memória fornecendo o memory_id
correspondente.
Vamos apagar a memória "Gosta de jogar ténis aos fins-de-semana", uma vez que o seu memory_id
já foi recuperado, e chamar get_all
para verificar se a eliminação foi bem sucedida.
m.delete(memory_id=memory_id)
m.get_all("alice")
{'results': [{'id': 'aa8eaa38-74d6-4b58-8207-b881d6d93d02',
'memory': 'Has a linear algebra midterm exam on November 20',
'hash': '575182f46965111ca0a8279c44920ea2',
'metadata': {'category': 'task'},
'created_at': '2024-11-01T19:33:57.271657-07:00',
'updated_at': None,
'user_id': 'alice'}]}