Visão Geral
O CrewAI oferece um sistema de memória unificado — uma única classeMemory que substitui memórias de curto prazo, longo prazo, entidades e externa por uma API inteligente. A memória usa um LLM para analisar o conteúdo ao salvar (inferindo escopo, categorias e importância) e suporta recall com profundidade adaptativa e pontuação composta que combina similaridade semântica, recência e importância.
Você pode usar a memória de quatro formas: standalone (scripts, notebooks), com Crews, com Agentes ou dentro de Flows.
Início Rápido
Quatro Formas de Usar Memória
Standalone
Use memória em scripts, notebooks, ferramentas CLI ou como base de conhecimento independente — sem agentes ou crews necessários.Com Crews
Passememory=True para configurações padrão, ou passe uma instância Memory configurada para comportamento customizado.
memory=True, a crew cria um Memory() padrão e repassa a configuração de embedder da crew automaticamente. Todos os agentes compartilham a memória da crew, a menos que um agente tenha sua própria.
Após cada tarefa, a crew extrai automaticamente fatos discretos da saída da tarefa e os armazena. Antes de cada tarefa, o agente recupera contexto relevante da memória e o injeta no prompt da tarefa.
Com Agentes
Agentes podem usar a memória compartilhada da crew (padrão) ou receber uma visão com escopo para contexto privado.Com Flows
Todo Flow possui memória integrada. Useself.remember(), self.recall() e self.extract_memories() dentro de qualquer método do flow.
Escopos Hierárquicos
O Que São Escopos
As memórias são organizadas em uma árvore hierárquica de escopos, similar a um sistema de arquivos. Cada escopo é um caminho como/, /project/alpha ou /agent/researcher/findings.
Como a Inferência de Escopo Funciona
Quando você chamaremember() sem especificar um escopo, o LLM analisa o conteúdo e a árvore de escopos existente, e sugere o melhor posicionamento. Se nenhum escopo existente é adequado, ele cria um novo. Com o tempo, a árvore de escopos cresce organicamente a partir do conteúdo — você não precisa projetar um esquema antecipadamente.
Visualizando a Árvore de Escopos
MemoryScope: Visões de Subárvore
UmMemoryScope restringe todas as operações a uma ramificação da árvore. O agente ou código que o utiliza só pode ver e escrever dentro daquela subárvore.
Boas Práticas para Design de Escopos
-
Comece plano, deixe o LLM organizar. Não projete demais sua hierarquia de escopos antecipadamente. Comece com
memory.remember(content)e deixe a inferência de escopo do LLM criar estrutura conforme o conteúdo se acumula. -
Use padrões
/{tipo_entidade}/{identificador}. Hierarquias naturais emergem de padrões como/project/alpha,/agent/researcher,/company/engineering,/customer/acme-corp. -
Escopo por preocupação, não por tipo de dado. Use
/project/alpha/decisionsem vez de/decisions/project/alpha. Isso mantém conteúdo relacionado junto. -
Mantenha profundidade rasa (2-3 níveis). Escopos profundamente aninhados ficam muito esparsos.
/project/alpha/architectureé bom;/project/alpha/architecture/decisions/databases/postgresqlé demais. -
Use escopos explícitos quando souber, deixe o LLM inferir quando não souber. Se está armazenando uma decisão de projeto conhecida, passe
scope="/project/alpha/decisions". Se está armazenando saída livre de um agente, omita o escopo e deixe o LLM decidir.
Exemplos de Casos de Uso
Equipe multi-projeto:Fatias de Memória (Memory Slices)
O Que São Fatias
UmMemorySlice é uma visão sobre múltiplos escopos, possivelmente disjuntos. Diferente de um escopo (que restringe a uma subárvore), uma fatia permite recall de várias ramificações simultaneamente.
Quando Usar Fatias vs Escopos
- Escopo: Use quando um agente ou bloco de código deve ser restrito a uma única subárvore. Exemplo: um agente que só vê
/agent/researcher. - Fatia: Use quando precisar combinar contexto de múltiplas ramificações. Exemplo: um agente que lê de seu próprio escopo mais conhecimento compartilhado da empresa.
Fatias Somente Leitura
O padrão mais comum: dar a um agente acesso de leitura a múltiplas ramificações sem permitir que ele escreva em áreas compartilhadas.Fatias de Leitura e Escrita
Quando somente leitura está desabilitado, você pode escrever em qualquer um dos escopos incluídos, mas deve especificar qual escopo explicitamente.Pontuação Composta
Os resultados do recall são ranqueados por uma combinação ponderada de três sinais:- similarity =
1 / (1 + distance)do índice vetorial (0 a 1) - decay =
0.5^(age_days / half_life_days)— decaimento exponencial (1.0 para hoje, 0.5 na meia-vida) - importance = pontuação de importância do registro (0 a 1), definida no momento da codificação
Memory:
MemoryMatch inclui uma lista match_reasons para que você possa ver por que um resultado ficou na posição que ficou (ex.: ["semantic", "recency", "importance"]).
Camada de Análise LLM
A memória usa o LLM de três formas:- Ao salvar — Quando você omite escopo, categorias ou importância, o LLM analisa o conteúdo e sugere escopo, categorias, importância e metadados (entidades, datas, tópicos).
- Ao fazer recall — Para recall profundo/automático, o LLM analisa a consulta (palavras-chave, dicas temporais, escopos sugeridos, complexidade) para guiar a recuperação.
- Extrair memórias —
extract_memories(content)quebra texto bruto (ex.: saída de tarefa) em afirmações de memória discretas. Os agentes usam isso antes de chamarremember()em cada afirmação para que fatos atômicos sejam armazenados em vez de um bloco grande.
Consolidação de Memória
Ao salvar novo conteúdo, o pipeline de codificação verifica automaticamente registros similares existentes no armazenamento. Se a similaridade estiver acima deconsolidation_threshold (padrão 0.85), o LLM decide o que fazer:
- keep — O registro existente ainda é preciso e não é redundante.
- update — O registro existente deve ser atualizado com novas informações (o LLM fornece o conteúdo mesclado).
- delete — O registro existente está desatualizado, substituído ou contradito.
- insert_new — Se o novo conteúdo também deve ser inserido como um registro separado.
Dedup Intra-batch
Ao usarremember_many(), os itens dentro do mesmo batch são comparados entre si antes de atingir o armazenamento. Se dois itens tiverem similaridade de cosseno >= batch_dedup_threshold (padrão 0.98), o posterior é silenciosamente descartado. Isso captura duplicatas exatas ou quase exatas dentro de um único batch sem chamadas ao LLM (pura matemática vetorial).
Saves Não-Bloqueantes
remember_many() é não-bloqueante — ele envia o pipeline de codificação para uma thread em background e retorna imediatamente. Isso significa que o agente pode continuar para a próxima tarefa enquanto as memórias estão sendo salvas.
Barreira de Leitura
Cada chamadarecall() executa automaticamente drain_writes() antes de buscar, garantindo que a consulta sempre veja os registros mais recentes persistidos. Isso é transparente — você nunca precisa pensar nisso.
Encerramento da Crew
Quando uma crew termina,kickoff() drena todos os saves de memória pendentes em seu bloco finally, então nenhum save é perdido mesmo que a crew complete enquanto saves em background estão em andamento.
Uso Standalone
Para scripts ou notebooks onde não há ciclo de vida de crew, chamedrain_writes() ou close() explicitamente:
Origem e Privacidade
Cada registro de memória pode carregar uma tagsource para rastreamento de procedência e uma flag private para controle de acesso.
Rastreamento de Origem
O parâmetrosource identifica de onde uma memória veio:
Memórias Privadas
Memórias privadas só são visíveis no recall quando osource corresponde:
RecallFlow (Recall Profundo)
recall() suporta duas profundidades:
depth="shallow"— Busca vetorial direta com pontuação composta. Rápido (~200ms), sem chamadas ao LLM.depth="deep"(padrão) — Executa um RecallFlow em múltiplas etapas: análise da consulta, seleção de escopo, busca vetorial paralela, roteamento baseado em confiança e exploração recursiva opcional quando a confiança é baixa.
query_analysis_threshold (padrão 200 caracteres) pulam a análise de consulta do LLM inteiramente, mesmo no modo deep. Consultas curtas como “Qual banco de dados usamos?” já são boas frases de busca — a análise do LLM agrega pouco valor. Isso economiza ~1-3s por recall para consultas curtas típicas. Apenas consultas mais longas (ex.: descrições completas de tarefas) passam pela destilação do LLM em sub-consultas direcionadas.
Configuração de Embedder
A memória precisa de um modelo de embedding para converter texto em vetores para busca semântica. Você pode configurar de três formas.Passando Diretamente para o Memory
Via Configuração de Embedder da Crew
Quando usarmemory=True, a configuração de embedder da crew é repassada:
Exemplos por Provedor
OpenAI (padrão)
OpenAI (padrão)
Ollama (local, privado)
Ollama (local, privado)
Azure OpenAI
Azure OpenAI
Google AI
Google AI
Google Vertex AI
Google Vertex AI
Cohere
Cohere
VoyageAI
VoyageAI
AWS Bedrock
AWS Bedrock
Hugging Face
Hugging Face
Jina
Jina
IBM WatsonX
IBM WatsonX
Embedder Customizado
Embedder Customizado
Referência de Provedores
| Provedor | Chave | Modelo Típico | Notas |
|---|---|---|---|
| OpenAI | openai | text-embedding-3-small | Padrão. Defina OPENAI_API_KEY. |
| Ollama | ollama | mxbai-embed-large | Local, sem API key. |
| Azure OpenAI | azure | text-embedding-ada-002 | Requer deployment_id. |
| Google AI | google-generativeai | gemini-embedding-001 | Defina GOOGLE_API_KEY. |
| Google Vertex | google-vertex | gemini-embedding-001 | Requer project_id. |
| Cohere | cohere | embed-english-v3.0 | Forte suporte multilíngue. |
| VoyageAI | voyageai | voyage-3 | Otimizado para retrieval. |
| AWS Bedrock | amazon-bedrock | amazon.titan-embed-text-v1 | Usa credenciais boto3. |
| Hugging Face | huggingface | all-MiniLM-L6-v2 | Sentence-transformers local. |
| Jina | jina | jina-embeddings-v2-base-en | Defina JINA_API_KEY. |
| IBM WatsonX | watsonx | ibm/slate-30m-english-rtrvr | Requer project_id. |
| Sentence Transformer | sentence-transformer | all-MiniLM-L6-v2 | Local, sem API key. |
| Custom | custom | — | Requer embedding_callable. |
Configuração de LLM
A memória usa um LLM para análise de save (inferência de escopo, categorias e importância), decisões de consolidação e análise de consulta no recall profundo. Você pode configurar qual modelo usar.Memory() nunca falha no momento da construção, mesmo que chaves de API não estejam definidas. Erros só aparecem quando o LLM é realmente chamado (ex.: ao salvar sem escopo/categorias explícitos, ou durante recall profundo).
Para operação totalmente offline/privada, use um modelo local tanto para o LLM quanto para o embedder:
Backend de Armazenamento
- Padrão: LanceDB, armazenado em
./.crewai/memory(ou$CREWAI_STORAGE_DIR/memoryse a variável de ambiente estiver definida, ou o caminho que você passar comostorage="path/to/dir"). - Backend customizado: Implemente o protocolo
StorageBackend(vejacrewai.memory.storage.backend) e passe uma instância paraMemory(storage=your_backend).
Descoberta
Inspecione a hierarquia de escopos, categorias e registros:Comportamento em Caso de Falha
Se o LLM falhar durante a análise (erro de rede, limite de taxa, resposta inválida), a memória degrada graciosamente:- Análise de save — Um aviso é registrado e a memória ainda é armazenada com escopo padrão
/, categorias vazias e importância0.5. - Extrair memórias — O conteúdo completo é armazenado como uma única memória para que nada seja descartado.
- Análise de consulta — O recall usa fallback para seleção simples de escopo e busca vetorial, então você ainda obtém resultados.
Nota sobre Privacidade
O conteúdo da memória é enviado ao LLM configurado para análise (escopo/categorias/importância no save, análise de consulta e recall profundo opcional). Para dados sensíveis, use um LLM local (ex.: Ollama) ou garanta que seu provedor atenda aos requisitos de conformidade.Eventos de Memória
Todas as operações de memória emitem eventos comsource_type="unified_memory". Você pode escutar para timing, erros e conteúdo.
| Evento | Descrição | Propriedades Principais |
|---|---|---|
| MemoryQueryStartedEvent | Consulta inicia | query, limit |
| MemoryQueryCompletedEvent | Consulta bem-sucedida | query, results, query_time_ms |
| MemoryQueryFailedEvent | Consulta falha | query, error |
| MemorySaveStartedEvent | Save inicia | value, metadata |
| MemorySaveCompletedEvent | Save bem-sucedido | value, save_time_ms |
| MemorySaveFailedEvent | Save falha | value, error |
| MemoryRetrievalStartedEvent | Retrieval do agente inicia | task_id |
| MemoryRetrievalCompletedEvent | Retrieval do agente completo | task_id, memory_content, retrieval_time_ms |
Solução de Problemas
Memória não persiste?- Garanta que o caminho de armazenamento seja gravável (padrão
./.crewai/memory). Passestorage="./your_path"para usar outro diretório, ou defina a variável de ambienteCREWAI_STORAGE_DIR. - Ao usar uma crew, confirme que
memory=Trueoumemory=Memory(...)está definido.
- Use
depth="shallow"para contexto rotineiro do agente. Reservedepth="deep"para consultas complexas. - Aumente
query_analysis_thresholdpara pular a análise do LLM em mais consultas.
- A memória ainda salva/recupera com padrões seguros. Verifique chaves de API, limites de taxa e disponibilidade do modelo se quiser análise LLM completa.
- Os saves de memória rodam em uma thread em background. Erros são emitidos como
MemorySaveFailedEventmas não derrubam o agente. Verifique os logs para a causa raiz (geralmente problemas de conexão com LLM ou embedder).
- As operações do LanceDB são serializadas com um lock compartilhado e reexecutadas automaticamente em caso de conflito. Isso lida com múltiplas instâncias
Memoryapontando para o mesmo banco de dados (ex.: memória do agente + memória da crew). Nenhuma ação necessária.
Referência de Configuração
Toda a configuração é passada como argumentos nomeados paraMemory(...). Cada parâmetro tem um padrão sensato.
| Parâmetro | Padrão | Descrição |
|---|---|---|
llm | "gpt-4o-mini" | LLM para análise (nome do modelo ou instância BaseLLM). |
storage | "lancedb" | Backend de armazenamento ("lancedb", string de caminho ou instância StorageBackend). |
embedder | None (OpenAI padrão) | Embedder (dict de config, callable ou None para OpenAI padrão). |
recency_weight | 0.3 | Peso da recência na pontuação composta. |
semantic_weight | 0.5 | Peso da similaridade semântica na pontuação composta. |
importance_weight | 0.2 | Peso da importância na pontuação composta. |
recency_half_life_days | 30 | Dias para a pontuação de recência cair pela metade (decaimento exponencial). |
consolidation_threshold | 0.85 | Similaridade acima da qual a consolidação é ativada no save. Defina 1.0 para desativar. |
consolidation_limit | 5 | Máx. de registros existentes para comparar durante consolidação. |
default_importance | 0.5 | Importância atribuída quando não fornecida e a análise LLM é pulada. |
batch_dedup_threshold | 0.98 | Similaridade de cosseno para descartar quase-duplicatas dentro de um batch remember_many(). |
confidence_threshold_high | 0.8 | Confiança de recall acima da qual resultados são retornados diretamente. |
confidence_threshold_low | 0.5 | Confiança de recall abaixo da qual exploração mais profunda é ativada. |
complex_query_threshold | 0.7 | Para consultas complexas, explorar mais profundamente abaixo desta confiança. |
exploration_budget | 1 | Número de rodadas de exploração por LLM durante recall profundo. |
query_analysis_threshold | 200 | Consultas menores que isso (em caracteres) pulam análise LLM durante recall profundo. |
