“`html
Weaviate Adicione Memória ao Seu Agente: Um Tutorial Direto de 2500 Palavras
Se você quer que seu agente inteligente realmente lembre o contexto entre as conversas, você precisa weaviate add memory to your agent da maneira certa, usando busca vetorial para armazenar e recuperar interações anteriores. Não estamos apenas jogando trechos em um banco de dados; estamos construindo um verdadeiro grafo de conhecimento enriquecido com busca semântica que mantém seu agente afiado.
O Que Você Está Construindo e Por Que Isso Importa
Estamos construindo um agente que usa o Weaviate para armazenamento de memória, de forma que ele possa ter conversas significativas e interativas, não apenas perguntas e respostas sem estado. Esqueça aquelas demonstrações superficiais de chatbots que reiniciam a cada pergunta — isso é sobre persistência contextual que seus usuários realmente sentirão.
Pré-requisitos
- Python 3.11+
- Edição da Comunidade Weaviate (última versão estável, usei 1.19.0)
- Pacotes Pip:
weaviate-client>=4.16.0,requests,dotenv - Chave da API OpenAI ou qualquer outra chave de API de modelo de incorporação (GPT-4, Cohere ou Huggingface)
- Docker instalado (opcional, mas recomendado para rodar o Weaviate localmente)
- Compreensão básica de bancos de dados vetoriais e geração de incorporação
Estatísticas Rápidas sobre o Weaviate
| Métrica | Valor |
|---|---|
| Estrelas no GitHub | 15.839 |
| Forks | 1.227 |
| Problemas Abertos | 582 (a partir de 20 de Mar, 2026) |
| Licença | BSD-3-Clause |
| Última Atualização | 20 de Março, 2026 |
Esses números mostram que o Weaviate é maduro, mas ainda ativo; você não ficará preso esperando por alguma biblioteca abandonada.
Passo a Passo: Weaviate Adicione Memória ao Seu Agente
Passo 1: Configure o Servidor Weaviate
# Execute o Weaviate com Docker para testes locais rápidos
docker run -d \
-p 8080:8080 \
-e AUTH_ANONYMOUS_ACCESS_ENABLED=true \
-e QUERY_DEFAULTS_LIMIT=20 \
-e PERSISTENCE_DATA_PATH=/var/lib/weaviate \
-v $(pwd)/weaviate_data:/var/lib/weaviate \
semitechnologies/weaviate:latest
Por que isso importa: O Weaviate suporta persistência e acesso anônimo ativo por padrão aqui, facilitando o desenvolvimento local. Configurar QUERY_DEFAULTS_LIMIT=20 evita que você enfrente limites irritantes de 10 resultados em consultas, que afetam até desenvolvedores experientes. Lembre-se, se você não quer acesso anônimo, configure chaves de API. Mas para testes, isso está bom.
Erros comuns: Se o contêiner travar, verifique se a porta 8080 está livre. Às vezes, o Docker Desktop ou contêineres anteriores a ocupam. Além disso, se você gerar incorporações mais rápido do que a persistência do Weaviate consegue acompanhar (raro localmente), espere por atrasos.
Passo 2: Defina um Esquema para a Memória do Seu Agente
import weaviate
client = weaviate.Client("http://localhost:8080")
schema = {
"classes": [
{
"class": "MemoryEntry",
"description": "Armazena um único segmento de memória para o agente",
"properties": [
{
"name": "text",
"dataType": ["text"],
"description": "O conteúdo de texto da memória."
},
{
"name": "embedding",
"dataType": ["number[]"],
"description": "Representação de incorporação vetorial."
},
{
"name": "timestamp",
"dataType": ["date"],
"description": "Quando a memória foi armazenada."
}
],
"vectorizer": "none" # Vamos injetar incorporações nós mesmos
}
]
}
client.schema.delete_all() # Começo limpo
client.schema.create(schema)
Por que nenhum vetorizador? O principal erro que os novatos cometem é usar os vetorizadores de texto padrão do Weaviate de forma cega. É bom para busca de texto simples, mas quando você deseja controle rigoroso sobre seu modelo de incorporação (por exemplo, OpenAI, Cohere), você tem que fazer o upload dos vetores você mesmo. Isso elimina a confusão de tutoriais concorrentes que usam excessivamente os vetorizadores ON-BOARD do Weaviate para agentes.
Excluir o esquema antes cria força um começo fresco, o que evita erros estranhos de “esquema já existe”. Claro, isso apaga dados, mas isso é desenvolvimento local.
Passo 3: Gere e Faça Upload das Incorporações da Memória
“““html
import os
import requests
from datetime import datetime
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
def get_openai_embedding(text):
resp = requests.post(
"https://api.openai.com/v1/embeddings",
headers={"Authorization": f"Bearer {OPENAI_API_KEY}"},
json={"input": text, "model": "text-embedding-ada-002"}
)
resp.raise_for_status()
return resp.json()["data"][0]["embedding"]
def add_memory_entry(client, text):
embedding = get_openai_embedding(text)
memory_obj = {
"text": text,
"embedding": embedding,
"timestamp": datetime.utcnow().isoformat()
}
client.data_object.create(memory_obj, "MemoryEntry", vector=embedding)
# Exemplo de uso
add_memory_entry(client, "Eu me lembro que o céu é azul.")
add_memory_entry(client, "O significado da vida é 42.")
Por que gerar embeddings você mesmo? Porque é incrivelmente valioso desacoplar a geração de embeddings e o armazenamento de vetores. Você pode precisar trocar seu modelo de embedding mais tarde ou agregar vetores de diferentes fontes. Aqueles outros tutoriais misturam tudo e você fica preso.
Erro comum aqui: esquecer de passar o embedding como parâmetro de vetor vector=embedding na chamada data_object.create. Se você pular isso, o Weaviate tentará vetorizar automaticamente (e falhará porque configuramos vectorizer: none).
Etapa 4: Consultar Memória com Pesquisa Semântica
def query_memory(client, question, top_k=3):
question_embedding = get_openai_embedding(question)
near_vector = {"vector": question_embedding}
response = client.query.get("MemoryEntry", ["text", "timestamp"])\
.with_near_vector(near_vector)\
.with_limit(top_k)\
.do()
results = response.get("data", {}).get("Get", {}).get("MemoryEntry", [])
return results
# Teste
results = query_memory(client, "Qual a cor do céu?")
for res in results:
print(f"Memória: {res['text']} (armazenada em {res['timestamp']})")
Por que pesquisa semântica? A pesquisa por palavras-chave em memória é inútil para agentes que precisam lidar com conversas de múltiplas etapas com consultas sutis. A verdadeira mágica é a pesquisa de embeddings para “pensamentos similares” sem sobreposição exata de palavras-chave.
A função matadora é como você combina essas consultas dinamicamente em tempo de execução para manter seu agente ciente do contexto, sem engasgar em memórias irrelevantes.
Etapa 5: Conecte Seu Agente para Usar a Memória Weaviate
class MemoryAgent:
def __init__(self, weaviate_client):
self.client = weaviate_client
def remember(self, text):
add_memory_entry(self.client, text)
def recall(self, question):
return query_memory(self.client, question, top_k=5)
def chat(self, question):
memories = self.recall(question)
# Simples concatenação para prompt—substitua pelo seu modelo de prompt
prompt_context = "\n".join([m["text"] for m in memories])
prompt = f"Contexto:\n{prompt_context}\n\nPergunta: {question}\nResposta:"
# Enviar prompt para LLM (não coberto aqui)
# Simular:
return f"Resposta simulada baseada nas memórias:\n{prompt}"
agent = MemoryAgent(client)
agent.remember("O agente foi criado em 20 de março de 2026.")
agent.remember("Python é a linguagem de programação reconhecida para IA.")
print(agent.chat("Quando o agente foi criado?"))
Por que este design? Separar a gestão de memória da lógica de “chat” do agente é crucial. Eu odeio código rigidamente acoplado onde gerenciar o contexto torna sua chamada de geração uma bagunça aninhada. Com este padrão, você rastreia, armazena e recupera de forma independente. Se você quiser trocar por um LLM melhor ou adicionar caching, é trivial.
Os Problemas Que Você Não Ouvirá de Outros Tutoriais
- Confusão de esquema. Muitos tutoriais ignoram o design de esquema, mas se o seu esquema estiver errado, seus vetores e metadados serão lixo. Você vai se arrepender de não planejar timestamps ou metadados como IDs de usuários para filtrar sua memória.
- Custos de embedding têm importância. Os embeddings do OpenAI não são gratuitos. Se você adicionar milhares de memórias, espere uma conta. Agrupe sua geração para reduzir custos e faça caching de embeddings de forma agressiva.
- O inchaço da memória mata o desempenho. Consultando um banco de dados vetorial com dezenas de milhares de entradas? Você verá picos de latência e resultados de recall ruidosos. A poda regular é necessária—uma realidade difícil, mas inevitável.
- Desajustes nas dimensões do vetor. Se você acidentalmente trocar modelos de embedding ou versões, seus vetores armazenados não corresponderão aos vetores de consulta. Você obterá zero resultados ou correspondências enganosas. Sempre conserte a versão do seu modelo de embedding em seu pipeline.
- Consistência de dados é um problema. Sem suporte a transações, gravações ou atualizações parciais podem deixar memórias pendentes sem contexto. Este bug sutil pode assombrá-lo em produção, especialmente se você estiver atualizando memórias.
Exemplo Completo Funcional
“““html
import os
import requests
from datetime import datetime
import weaviate
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
WEAVIATE_URL = "http://localhost:8080"
def get_openai_embedding(text):
r = requests.post(
"https://api.openai.com/v1/embeddings",
headers={"Authorization": f"Bearer {OPENAI_API_KEY}"},
json={"input": text, "model": "text-embedding-ada-002"},
)
r.raise_for_status()
return r.json()["data"][0]["embedding"]
client = weaviate.Client(WEAVIATE_URL)
client.schema.delete_all()
schema = {
"classes": [
{
"class": "MemoryEntry",
"description": "Armazena a memória do agente",
"properties": [
{"name": "text", "dataType": ["text"]},
{"name": "embedding", "dataType": ["number[]"]},
{"name": "timestamp", "dataType": ["date"]}
],
"vectorizer": "none"
}
]
}
client.schema.create(schema)
def add_memory(text):
embedding = get_openai_embedding(text)
data = {"text": text, "embedding": embedding, "timestamp": datetime.utcnow().isoformat()}
client.data_object.create(data, "MemoryEntry", vector=embedding)
def query_memories(question, top_k=5):
q_emb = get_openai_embedding(question)
near_vector = {"vector": q_emb}
res = client.query.get("MemoryEntry", ["text", "timestamp"])\
.with_near_vector(near_vector).with_limit(top_k).do()
return res.get("data", {}).get("Get", {}).get("MemoryEntry", [])
class Agent:
def __init__(self, client):
self.client = client
def remember(self, text):
add_memory(text)
def chat(self, question):
memories = query_memories(question)
context = "\n".join([m["text"] for m in memories])
prompt = f"Context:\n{context}\n\nQuestion: {question}\nAnswer:"
# Dummy answer
return prompt
agent = Agent(client)
agent.remember("O céu é azul.")
agent.remember("A água ferve a 100 graus Celsius.")
print(agent.chat("Qual é a cor do céu?"))
O que vem a seguir?
Depois de dominar a integração da memória do Weaviate, seu próximo passo concreto é construir um pipeline de poda e atualização de memória. Isso significa avaliar periodicamente quais memórias estão desatualizadas ou irrelevantes e excluí-las ou atualizá-las. Se você deixar a memória crescer descontroladamente, as respostas do seu agente irão desacelerar e se tornar inconsistentes.
Considere implementar uma decadência baseada no tempo ou uma classificação da importância da memória para manter seu banco de dados enxuto. Isso irá aprimorar o foco do agente no que realmente importa.
Dúvidas Frequentes
Por que devo desabilitar o vetorizador embutido do Weaviate?
Os vetorizadores embutidos são adequados para demonstrações simples, mas o prendem ao modelo específico de embedding e tornam a atualização impossível. Você quer injetar seus próprios embeddings gerados a partir de modelos como o text-embedding-ada-002 da OpenAI, para controlar a qualidade do vetor e os custos da API.
O que faço se minhas consultas não retornarem resultados?
Primeiro, confirme se as dimensões do seu embedding correspondem. Os embeddings ada-002 da OpenAI são vetores de 1536 dimensões. Se os vetores armazenados e os vetores de consulta diferirem em dimensão, a busca por similaridade não retornará nada. Verifique também se o vetorizador do seu esquema está como ‘none’ e se você envia explicitamente seus próprios vetores ao criar objetos.
Como gerenciar os custos de embedding com milhares de entradas de memória?
Realize o embedding em lotes de seus dados em vez de chamadas pontuais, e armazene embeddings em disco ou Redis. O pré-processamento de novas informações offline também pode ajudar. Além disso, seja estratégico naquilo que você armazena — armazene resumos, não conversas completas. Por fim, explore modelos open-source mais baratos, mas cuidado com a precisão.
Recomendações para Personas de Desenvolvedores
| Tipo de Desenvolvedor | Próximos Passos Recomendações |
|---|---|
| Pesquisador de IA | Integre o Weaviate com embeddings de transformadores personalizados e explore a busca híbrida combinando texto e similaridade vetorial. |
| Engenheiro de Backend | Implemente a gestão do ciclo de vida da memória com poda automatizada, reconstrução de índices e monitoramento de durabilidade. |
| Desenvolvedor Full-Stack | Crie um painel de UI para visualizar e gerenciar entradas de memória, e conecte a memória do Weaviate com sua interface de chat frontend. |
Dados de 21 de março de 2026. Fontes: https://github.com/weaviate/weaviate, https://weaviate.io/product/integrations/mem0
Artigos Relacionados
“`
- Aprimore LLMs com Grafos de Conhecimento Confiáveis: A Inovação de Qinggang Zhang
- Desbloqueie Sua Marca: Criando o Logo Perfeito para Redes Neurais Convolucionais
- Por que Usar Arquitetura de Agente de IA
🕒 Published: