mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-04-04 03:00:48 -04:00
* chore: update memory management and dependencies - Enhance the memory system by introducing a unified memory API that consolidates short-term, long-term, entity, and external memory functionalities. - Update the `.gitignore` to exclude new memory-related files and blog directories. - Modify `conftest.py` to handle missing imports for vcr stubs more gracefully. - Add new development dependencies in `pyproject.toml` for testing and memory management. - Refactor the `Crew` class to utilize the new unified memory system, replacing deprecated memory attributes. - Implement memory context injection in `LiteAgent` to improve memory recall during agent execution. - Update documentation to reflect changes in memory usage and configuration. * feat: introduce Memory TUI for enhanced memory management - Add a new command to the CLI for launching a Textual User Interface (TUI) to browse and recall memories. - Implement the MemoryTUI class to facilitate user interaction with memory scopes and records. - Enhance the unified memory API by adding a method to list records within a specified scope. - Update `pyproject.toml` to include the `textual` dependency for TUI functionality. - Ensure proper error handling for missing dependencies when accessing the TUI. * feat: implement consolidation flow for memory management - Introduce the ConsolidationFlow class to handle the decision-making process for inserting, updating, or deleting memory records based on new content. - Add new data models: ConsolidationAction and ConsolidationPlan to structure the actions taken during consolidation. - Enhance the memory types with new fields for consolidation thresholds and limits. - Update the unified memory API to utilize the new consolidation flow for managing memory records. - Implement embedding functionality for new content to facilitate similarity checks. - Refactor existing memory analysis methods to integrate with the consolidation process. - Update translations to include prompts for consolidation actions and user interactions. * feat: enhance Memory TUI with Rich markup and improved UI elements - Update the MemoryTUI class to utilize Rich markup for better visual representation of memory scope information. - Introduce a color palette for consistent branding across the TUI interface. - Refactor the CSS styles to improve the layout and aesthetics of the memory browsing experience. - Enhance the display of memory entries, including better formatting for records and importance ratings. - Implement loading indicators and error messages with Rich styling for improved user feedback during recall operations. - Update the action bindings and navigation prompts for a more intuitive user experience. * feat: enhance Crew class memory management and configuration - Update the Crew class to allow for more flexible memory configurations by accepting Memory, MemoryScope, or MemorySlice instances. - Refactor memory initialization logic to support custom memory configurations while maintaining backward compatibility. - Improve documentation for memory-related fields to clarify usage and expectations. - Introduce a recall oversample factor to optimize memory recall processes. - Update related memory types and configurations to ensure consistency across the memory management system. * chore: update dependency overrides and enhance memory management - Added an override for the 'rich' dependency to allow compatibility with 'textual' requirements. - Updated the 'pyproject.toml' and 'uv.lock' files to reflect the new dependency specifications. - Refactored the Crew class to simplify memory configuration handling by allowing any type for the memory attribute. - Improved error messages in the CLI for missing 'textual' dependency to guide users on installation. - Introduced new packages and dependencies in the project to enhance functionality and maintain compatibility. * refactor: enhance thread safety in flow management - Updated LockedListProxy and LockedDictProxy to subclass list and dict respectively, ensuring compatibility with libraries requiring strict type checks. - Improved documentation to clarify the purpose of these proxies and their thread-safe operations. - Ensured that all mutations are protected by locks while reads delegate to the underlying data structures, enhancing concurrency safety. * chore: update dependency versions and improve Python compatibility - Downgraded 'vcrpy' dependency to version 7.0.0 for compatibility. - Enhanced 'uv.lock' to include more granular resolution markers for Python versions and implementations, ensuring better compatibility across different environments. - Updated 'urllib3' and 'selenium' dependencies to specify versions based on Python implementation, improving stability and performance. - Removed deprecated resolution markers for 'fastembed' and streamlined its dependencies for better clarity. * fix linter * chore: update uv.lock for improved dependency management and memory management enhancements - Incremented revision number in uv.lock to reflect changes. - Added a new development dependency group in uv.lock, specifying versions for tools like pytest, mypy, and pre-commit to streamline development workflows. - Enhanced error handling in CLI memory functions to provide clearer feedback on missing dependencies. - Refactored memory management classes to improve type hints and maintainability, ensuring better compatibility with future updates. * fix tests * refactor: remove obsolete RAGStorage tests and clean up error handling - Deleted outdated tests for RAGStorage that were no longer relevant, including tests for client failures, save operation failures, and reset failures. - Cleaned up the test suite to focus on current functionality and improve maintainability. - Ensured that remaining tests continue to validate the expected behavior of knowledge storage components. * fix test * fix texts * fix tests * forcing new commit * fix: add location parameter to Google Vertex embedder configuration for memory integration tests * debugging CI * adding debugging for CI * refactor: remove unnecessary logging for memory checks in agent execution - Eliminated redundant logging statements related to memory checks in the Agent and CrewAgentExecutor classes. - Simplified the memory retrieval logic by directly checking for available memory without logging intermediate states. - Improved code readability and maintainability by reducing clutter in the logging output. * udpating desp * feat: enhance thread safety in LockedListProxy and LockedDictProxy - Added equality comparison methods (__eq__ and __ne__) to LockedListProxy and LockedDictProxy to allow for safe comparison of their contents. - Implemented consistent locking mechanisms to prevent deadlocks during comparisons. - Improved the overall robustness of these proxy classes in multi-threaded environments. * feat: enhance memory functionality in Flows documentation and memory system - Added a new section on memory usage within Flows, detailing built-in methods for storing and recalling memories. - Included an example of a Research and Analyze Flow demonstrating the integration of memory for accumulating knowledge over time. - Updated the Memory documentation to clarify the unified memory system and its capabilities, including adaptive-depth recall and composite scoring. - Introduced a new configuration parameter, `recall_oversample_factor`, to improve the effectiveness of memory retrieval processes. * update docs * refactor: improve memory record handling and pagination in unified memory system - Simplified the `get_record` method in the Memory class by directly accessing the storage's `get_record` method. - Enhanced the `list_records` method to include an `offset` parameter for pagination, allowing users to skip a specified number of records. - Updated documentation for both methods to clarify their functionality and parameters, improving overall code clarity and usability. * test: update memory scope assertions in unified memory tests - Modified assertions in `test_lancedb_list_scopes_get_scope_info` and `test_memory_list_scopes_info_tree` to check for the presence of the "/team" scope instead of the root scope. - Clarified comments to indicate that `list_scopes` returns child scopes rather than the root itself, enhancing test clarity and accuracy. * feat: integrate memory tools for agents and crews - Added functionality to inject memory tools into agents during initialization, enhancing their ability to recall and remember information mid-task. - Implemented a new `_add_memory_tools` method in the Crew class to facilitate the addition of memory tools when memory is available. - Introduced `RecallMemoryTool` and `RememberTool` classes in a new `memory_tools.py` file, providing agents with active recall and memory storage capabilities. - Updated English translations to include descriptions for the new memory tools, improving user guidance on their usage. * refactor: streamline memory recall functionality across agents and tools - Removed the 'depth' parameter from memory recall calls in LiteAgent and Agent classes, simplifying the recall process. - Updated the MemoryTUI to use 'deep' depth by default for more comprehensive memory retrieval. - Enhanced the MemoryScope and MemorySlice classes to default to 'deep' depth, improving recall accuracy. - Introduced a new 'recall_queries' field in QueryAnalysis to optimize semantic vector searches with targeted phrases. - Updated documentation and comments to reflect changes in memory recall behavior and parameters. * refactor: optimize memory management in flow classes - Enhanced memory auto-creation logic in Flow class to prevent unnecessary Memory instance creation for internal flows (RecallFlow, ConsolidationFlow) by introducing a _skip_auto_memory flag. - Removed the deprecated time_hints field from QueryAnalysis and replaced it with a more flexible time_filter field to better handle time-based queries. - Updated documentation and comments to reflect changes in memory handling and query analysis structure, improving clarity and usability. * updates tests * feat: introduce EncodingFlow for enhanced memory encoding pipeline - Added a new EncodingFlow class to orchestrate the encoding process for memory, integrating LLM analysis and embedding. - Updated the Memory class to utilize EncodingFlow for saving content, improving the overall memory management and conflict resolution. - Enhanced the unified memory module to include the new EncodingFlow in its public API, facilitating better memory handling. - Updated tests to ensure proper functionality of the new encoding flow and its integration with existing memory features. * refactor: optimize memory tool integration and recall flow - Streamlined the addition of memory tools in the Agent class by using list comprehension for cleaner code. - Enhanced the RecallFlow class to build task lists more efficiently with list comprehensions, improving readability and performance. - Updated the RecallMemoryTool to utilize list comprehensions for formatting memory results, simplifying the code structure. - Adjusted test assertions in LiteAgent to reflect the default behavior of memory recall depth, ensuring clarity in expected outcomes. * Potential fix for pull request finding 'Empty except' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> * chore: gen missing cassette * fix * test: enhance memory extraction test by mocking recall to prevent LLM calls Updated the test for memory extraction to include a mock for the recall method, ensuring that the test focuses on the save path without invoking external LLM calls. This improves test reliability and clarity. * refactor: enhance memory handling by adding agent role parameter Updated memory storage methods across multiple classes to include an optional `agent_role` parameter, improving the context of stored memories. Additionally, modified the initialization of several flow classes to suppress flow events, enhancing performance and reducing unnecessary event triggers. * feat: enhance agent memory functionality with recall and save mechanisms Implemented memory context injection during agent kickoff, allowing for memory recall before execution and passive saving of results afterward. Added new methods to handle memory saving and retrieval, including error handling for memory operations. Updated the BaseAgent class to support dynamic memory resolution and improved memory record structure with source and privacy attributes for better provenance tracking. * test * feat: add utility method to simplify tools field in console formatter Introduced a new static method `_simplify_tools_field` in the console formatter to transform the 'tools' field from full tool objects to a comma-separated string of tool names. This enhancement improves the readability of tool information in the output. * refactor: improve lazy initialization of LLM and embedder in Memory class Refactored the Memory class to implement lazy initialization for the LLM and embedder, ensuring they are only created when first accessed. This change enhances the robustness of the Memory class by preventing initialization failures when constructed without an API key. Additionally, updated error handling to provide clearer guidance for users on resolving initialization issues. * refactor: consolidate memory saving methods for improved efficiency Refactored memory handling across multiple classes to replace individual memory saving calls with a batch method, `remember_many`, enhancing performance and reducing redundancy. Updated related tools and schemas to support single and multiple item memory operations, ensuring a more streamlined interface for memory interactions. Additionally, improved documentation and test coverage for the new functionality. * feat: enhance MemoryTUI with improved layout and entry handling Updated the MemoryTUI class to incorporate a new vertical layout, adding an OptionList for displaying entries and enhancing the detail view for selected records. Introduced methods for populating entry and recall lists, improving user interaction and data presentation. Additionally, refined CSS styles for better visual organization and focus handling. * fix test * feat: inject memory tools into LiteAgent for enhanced functionality Added logic to the LiteAgent class to inject memory tools if memory is configured, ensuring that memory tools are only added if they are not already present. This change improves the agent's capability to utilize memory effectively during execution. * feat: add synchronous execution method to ConsolidationFlow for improved integration Introduced a new `run_sync()` method in the ConsolidationFlow class to facilitate procedural execution of the consolidation pipeline without relying on asynchronous event loops. Updated the EncodingFlow class to utilize this method for conflict resolution, ensuring compatibility within its async context. This change enhances the flow's ability to manage memory records effectively during nested executions. * refactor: update ConsolidationFlow and EncodingFlow for improved async handling Removed the synchronous `run_sync()` method from ConsolidationFlow and refactored the consolidate method in EncodingFlow to be asynchronous. This change allows for direct awaiting of the ConsolidationFlow's kickoff method, enhancing compatibility within the async event loop and preventing nested asyncio.run() issues. Additionally, updated the execution plan to listen for multiple paths, streamlining the consolidation process. * fix: update flow documentation and remove unused ConsolidationFlow Corrected the comment in Flow class regarding internal flows, replacing "ConsolidationFlow" with "EncodingFlow". Removed the ConsolidationFlow class as it is no longer needed, streamlining the memory handling process. Updated related imports and ensured that the memory module reflects these changes, enhancing clarity and maintainability. * feat: enhance memory handling with background saving and query analysis optimization Implemented a background saving mechanism in the Memory class to allow non-blocking memory operations, improving performance during high-load scenarios. Added a query analysis threshold to skip LLM calls for short queries, optimizing recall efficiency. Updated related methods and documentation to reflect these changes, ensuring a more responsive and efficient memory management system. * fix test * fix test * fix: handle synchronous fallback for save operations in Memory class Updated the Memory class to implement a synchronous fallback mechanism for save operations when the background thread pool is shut down. This change ensures that late save requests still succeed, improving reliability in memory management during shutdown scenarios. * feat: implement HITL learning features in human feedback decorator Added support for learning from human feedback in the human feedback decorator. Introduced parameters to enable lesson distillation and pre-review of outputs based on past feedback. Updated related tests to ensure proper functionality of the learning mechanism, including memory interactions and default LLM usage. --------- Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
728 lines
26 KiB
Plaintext
728 lines
26 KiB
Plaintext
---
|
|
title: Memória
|
|
description: Aproveitando o sistema de memória unificado no CrewAI para aprimorar as capacidades dos agentes.
|
|
icon: database
|
|
mode: "wide"
|
|
---
|
|
|
|
## Visão Geral
|
|
|
|
O CrewAI oferece um **sistema de memória unificado** -- uma única classe `Memory` 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
|
|
|
|
```python
|
|
from crewai import Memory
|
|
|
|
memory = Memory()
|
|
|
|
# Armazenar -- o LLM infere escopo, categorias e importância
|
|
memory.remember("Decidimos usar PostgreSQL para o banco de dados de usuários.")
|
|
|
|
# Recuperar -- resultados ranqueados por pontuação composta (semântica + recência + importância)
|
|
matches = memory.recall("Qual banco de dados escolhemos?")
|
|
for m in matches:
|
|
print(f"[{m.score:.2f}] {m.record.content}")
|
|
|
|
# Ajustar pontuação para um projeto dinâmico
|
|
memory = Memory(recency_weight=0.5, recency_half_life_days=7)
|
|
|
|
# Esquecer
|
|
memory.forget(scope="/project/old")
|
|
|
|
# Explorar a árvore de escopos auto-organizada
|
|
print(memory.tree())
|
|
print(memory.info("/"))
|
|
```
|
|
|
|
## 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.
|
|
|
|
```python
|
|
from crewai import Memory
|
|
|
|
memory = Memory()
|
|
|
|
# Construir conhecimento
|
|
memory.remember("O limite da API é 1000 requisições por minuto.")
|
|
memory.remember("Nosso ambiente de staging usa a porta 8080.")
|
|
memory.remember("A equipe concordou em usar feature flags para todos os novos lançamentos.")
|
|
|
|
# Depois, recupere o que precisar
|
|
matches = memory.recall("Quais são nossos limites de API?", limit=5)
|
|
for m in matches:
|
|
print(f"[{m.score:.2f}] {m.record.content}")
|
|
|
|
# Extrair fatos atômicos de um texto mais longo
|
|
raw = """Notas da reunião: Decidimos migrar do MySQL para PostgreSQL
|
|
no próximo trimestre. O orçamento é de $50k. Sarah liderará a migração."""
|
|
|
|
facts = memory.extract_memories(raw)
|
|
# ["Migração de MySQL para PostgreSQL planejada para o próximo trimestre",
|
|
# "Orçamento da migração de banco de dados é $50k",
|
|
# "Sarah liderará a migração do banco de dados"]
|
|
|
|
for fact in facts:
|
|
memory.remember(fact)
|
|
```
|
|
|
|
### Com Crews
|
|
|
|
Passe `memory=True` para configurações padrão, ou passe uma instância `Memory` configurada para comportamento customizado.
|
|
|
|
```python
|
|
from crewai import Crew, Agent, Task, Process, Memory
|
|
|
|
# Opção 1: Memória padrão
|
|
crew = Crew(
|
|
agents=[researcher, writer],
|
|
tasks=[research_task, writing_task],
|
|
process=Process.sequential,
|
|
memory=True,
|
|
verbose=True,
|
|
)
|
|
|
|
# Opção 2: Memória customizada com pontuação ajustada
|
|
memory = Memory(
|
|
recency_weight=0.4,
|
|
semantic_weight=0.4,
|
|
importance_weight=0.2,
|
|
recency_half_life_days=14,
|
|
)
|
|
crew = Crew(
|
|
agents=[researcher, writer],
|
|
tasks=[research_task, writing_task],
|
|
memory=memory,
|
|
)
|
|
```
|
|
|
|
Quando `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.
|
|
|
|
```python
|
|
from crewai import Agent, Memory
|
|
|
|
memory = Memory()
|
|
|
|
# Pesquisador recebe um escopo privado -- só vê /agent/researcher
|
|
researcher = Agent(
|
|
role="Researcher",
|
|
goal="Encontrar e analisar informações",
|
|
backstory="Pesquisador experiente com atenção aos detalhes",
|
|
memory=memory.scope("/agent/researcher"),
|
|
)
|
|
|
|
# Escritor usa memória compartilhada da crew (sem memória própria)
|
|
writer = Agent(
|
|
role="Writer",
|
|
goal="Produzir conteúdo claro e bem estruturado",
|
|
backstory="Escritor técnico experiente",
|
|
# memory não definido -- usa crew._memory quando a crew tem memória habilitada
|
|
)
|
|
```
|
|
|
|
Esse padrão dá ao pesquisador descobertas privadas enquanto o escritor lê da memória compartilhada da crew.
|
|
|
|
### Com Flows
|
|
|
|
Todo Flow possui memória integrada. Use `self.remember()`, `self.recall()` e `self.extract_memories()` dentro de qualquer método do flow.
|
|
|
|
```python
|
|
from crewai.flow.flow import Flow, listen, start
|
|
|
|
class ResearchFlow(Flow):
|
|
@start()
|
|
def gather_data(self):
|
|
findings = "PostgreSQL suporta 10k conexões simultâneas. MySQL limita a 5k."
|
|
self.remember(findings, scope="/research/databases")
|
|
return findings
|
|
|
|
@listen(gather_data)
|
|
def write_report(self, findings):
|
|
# Recuperar pesquisas anteriores para fornecer contexto
|
|
past = self.recall("benchmarks de performance de banco de dados")
|
|
context = "\n".join(f"- {m.record.content}" for m in past)
|
|
return f"Relatório:\nNovas descobertas: {findings}\nContexto anterior:\n{context}"
|
|
```
|
|
|
|
Veja a [documentação de Flows](/concepts/flows) para mais informações sobre memória em Flows.
|
|
|
|
|
|
## 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`.
|
|
|
|
```
|
|
/
|
|
/company
|
|
/company/engineering
|
|
/company/product
|
|
/project
|
|
/project/alpha
|
|
/project/beta
|
|
/agent
|
|
/agent/researcher
|
|
/agent/writer
|
|
```
|
|
|
|
Escopos fornecem **memória dependente de contexto** -- quando você faz recall dentro de um escopo, busca apenas naquela ramificação da árvore, melhorando tanto a precisão quanto o desempenho.
|
|
|
|
### Como a Inferência de Escopo Funciona
|
|
|
|
Quando você chama `remember()` 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.
|
|
|
|
```python
|
|
memory = Memory()
|
|
|
|
# LLM infere escopo a partir do conteúdo
|
|
memory.remember("Escolhemos PostgreSQL para o banco de dados de usuários.")
|
|
# -> pode ser colocado em /project/decisions ou /engineering/database
|
|
|
|
# Você também pode especificar o escopo explicitamente
|
|
memory.remember("Velocidade do sprint é 42 pontos", scope="/team/metrics")
|
|
```
|
|
|
|
### Visualizando a Árvore de Escopos
|
|
|
|
```python
|
|
print(memory.tree())
|
|
# / (15 records)
|
|
# /project (8 records)
|
|
# /project/alpha (5 records)
|
|
# /project/beta (3 records)
|
|
# /agent (7 records)
|
|
# /agent/researcher (4 records)
|
|
# /agent/writer (3 records)
|
|
|
|
print(memory.info("/project/alpha"))
|
|
# ScopeInfo(path='/project/alpha', record_count=5,
|
|
# categories=['architecture', 'database'],
|
|
# oldest_record=datetime(...), newest_record=datetime(...),
|
|
# child_scopes=[])
|
|
```
|
|
|
|
### MemoryScope: Visões de Subárvore
|
|
|
|
Um `MemoryScope` 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.
|
|
|
|
```python
|
|
memory = Memory()
|
|
|
|
# Criar um escopo para um agente específico
|
|
agent_memory = memory.scope("/agent/researcher")
|
|
|
|
# Tudo é relativo a /agent/researcher
|
|
agent_memory.remember("Encontrados três papers relevantes sobre memória de LLM.")
|
|
# -> armazenado em /agent/researcher
|
|
|
|
agent_memory.recall("papers relevantes")
|
|
# -> busca apenas em /agent/researcher
|
|
|
|
# Restringir ainda mais com subscope
|
|
project_memory = agent_memory.subscope("project-alpha")
|
|
# -> /agent/researcher/project-alpha
|
|
```
|
|
|
|
### 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/decisions` em 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:**
|
|
```python
|
|
memory = Memory()
|
|
# Cada projeto recebe sua própria ramificação
|
|
memory.remember("Usando arquitetura de microsserviços", scope="/project/alpha/architecture")
|
|
memory.remember("API GraphQL para apps cliente", scope="/project/beta/api")
|
|
|
|
# Recall em todos os projetos
|
|
memory.recall("decisões de design de API")
|
|
|
|
# Ou dentro de um projeto específico
|
|
memory.recall("design de API", scope="/project/beta")
|
|
```
|
|
|
|
**Contexto privado por agente com conhecimento compartilhado:**
|
|
```python
|
|
memory = Memory()
|
|
|
|
# Pesquisador tem descobertas privadas
|
|
researcher_memory = memory.scope("/agent/researcher")
|
|
|
|
# Escritor pode ler de seu próprio escopo e do conhecimento compartilhado da empresa
|
|
writer_view = memory.slice(
|
|
scopes=["/agent/writer", "/company/knowledge"],
|
|
read_only=True,
|
|
)
|
|
```
|
|
|
|
**Suporte ao cliente (contexto por cliente):**
|
|
```python
|
|
memory = Memory()
|
|
|
|
# Cada cliente recebe contexto isolado
|
|
memory.remember("Prefere comunicação por email", scope="/customer/acme-corp")
|
|
memory.remember("Plano enterprise, 50 licenças", scope="/customer/acme-corp")
|
|
|
|
# Docs de produto compartilhados são acessíveis a todos os agentes
|
|
memory.remember("Limite de taxa é 1000 req/min no plano enterprise", scope="/product/docs")
|
|
```
|
|
|
|
|
|
## Fatias de Memória (Memory Slices)
|
|
|
|
### O Que São Fatias
|
|
|
|
Um `MemorySlice` é 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.
|
|
|
|
```python
|
|
memory = Memory()
|
|
|
|
# Agente pode fazer recall de seu próprio escopo E do conhecimento da empresa,
|
|
# mas não pode escrever no conhecimento da empresa
|
|
agent_view = memory.slice(
|
|
scopes=["/agent/researcher", "/company/knowledge"],
|
|
read_only=True,
|
|
)
|
|
|
|
matches = agent_view.recall("políticas de segurança da empresa", limit=5)
|
|
# Busca em /agent/researcher e /company/knowledge, mescla e ranqueia resultados
|
|
|
|
agent_view.remember("nova descoberta") # Levanta PermissionError (somente leitura)
|
|
```
|
|
|
|
### 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.
|
|
|
|
```python
|
|
view = memory.slice(scopes=["/team/alpha", "/team/beta"], read_only=False)
|
|
|
|
# Deve especificar escopo ao escrever
|
|
view.remember("Decisão entre equipes", scope="/team/alpha", categories=["decisions"])
|
|
```
|
|
|
|
|
|
## Pontuação Composta
|
|
|
|
Os resultados do recall são ranqueados por uma combinação ponderada de três sinais:
|
|
|
|
```
|
|
composite = semantic_weight * similarity + recency_weight * decay + importance_weight * importance
|
|
```
|
|
|
|
Onde:
|
|
- **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
|
|
|
|
Configure diretamente no construtor do `Memory`:
|
|
|
|
```python
|
|
# Retrospectiva de sprint: favorecer memórias recentes, meia-vida curta
|
|
memory = Memory(
|
|
recency_weight=0.5,
|
|
semantic_weight=0.3,
|
|
importance_weight=0.2,
|
|
recency_half_life_days=7,
|
|
)
|
|
|
|
# Base de conhecimento de arquitetura: favorecer memórias importantes, meia-vida longa
|
|
memory = Memory(
|
|
recency_weight=0.1,
|
|
semantic_weight=0.5,
|
|
importance_weight=0.4,
|
|
recency_half_life_days=180,
|
|
)
|
|
```
|
|
|
|
Cada `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:
|
|
|
|
1. **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).
|
|
2. **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.
|
|
3. **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 chamar `remember()` em cada afirmação para que fatos atômicos sejam armazenados em vez de um bloco grande.
|
|
|
|
Toda análise degrada graciosamente em caso de falha do LLM -- veja [Comportamento em Caso de Falha](#comportamento-em-caso-de-falha).
|
|
|
|
|
|
## RecallFlow (Recall Profundo)
|
|
|
|
`recall()` suporta três profundidades:
|
|
|
|
- **`depth="shallow"`** -- Busca vetorial direta com pontuação composta. Rápido; usado por padrão quando agentes carregam contexto.
|
|
- **`depth="deep"` ou `depth="auto"`** -- Executa um RecallFlow em múltiplas etapas: análise da consulta, seleção de escopo, busca vetorial, roteamento baseado em confiança e exploração recursiva opcional quando a confiança é baixa.
|
|
|
|
```python
|
|
# Caminho rápido (padrão para contexto de tarefa do agente)
|
|
matches = memory.recall("O que decidimos?", limit=10, depth="shallow")
|
|
|
|
# Caminho inteligente para perguntas complexas
|
|
matches = memory.recall(
|
|
"Resuma todas as decisões de arquitetura deste trimestre",
|
|
limit=10,
|
|
depth="auto",
|
|
)
|
|
```
|
|
|
|
Os limiares de confiança que controlam o roteador do RecallFlow são configuráveis:
|
|
|
|
```python
|
|
memory = Memory(
|
|
confidence_threshold_high=0.9, # Só sintetizar quando muito confiante
|
|
confidence_threshold_low=0.4, # Explorar mais profundamente de forma mais agressiva
|
|
exploration_budget=2, # Permitir até 2 rodadas de exploração
|
|
)
|
|
```
|
|
|
|
|
|
## 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
|
|
|
|
```python
|
|
from crewai import Memory
|
|
|
|
# Como um dict de configuração
|
|
memory = Memory(embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-small"}})
|
|
|
|
# Como um callable pré-construído
|
|
from crewai.rag.embeddings.factory import build_embedder
|
|
embedder = build_embedder({"provider": "ollama", "config": {"model_name": "mxbai-embed-large"}})
|
|
memory = Memory(embedder=embedder)
|
|
```
|
|
|
|
### Via Configuração de Embedder da Crew
|
|
|
|
Quando usar `memory=True`, a configuração de `embedder` da crew é repassada:
|
|
|
|
```python
|
|
from crewai import Crew
|
|
|
|
crew = Crew(
|
|
agents=[...],
|
|
tasks=[...],
|
|
memory=True,
|
|
embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-small"}},
|
|
)
|
|
```
|
|
|
|
### Exemplos por Provedor
|
|
|
|
<AccordionGroup>
|
|
<Accordion title="OpenAI (padrão)">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "openai",
|
|
"config": {
|
|
"model_name": "text-embedding-3-small",
|
|
# "api_key": "sk-...", # ou defina OPENAI_API_KEY
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Ollama (local, privado)">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "ollama",
|
|
"config": {
|
|
"model_name": "mxbai-embed-large",
|
|
"url": "http://localhost:11434/api/embeddings",
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Azure OpenAI">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "azure",
|
|
"config": {
|
|
"deployment_id": "your-embedding-deployment",
|
|
"api_key": "your-azure-api-key",
|
|
"api_base": "https://your-resource.openai.azure.com",
|
|
"api_version": "2024-02-01",
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Google AI">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "google-generativeai",
|
|
"config": {
|
|
"model_name": "gemini-embedding-001",
|
|
# "api_key": "...", # ou defina GOOGLE_API_KEY
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Google Vertex AI">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "google-vertex",
|
|
"config": {
|
|
"model_name": "gemini-embedding-001",
|
|
"project_id": "your-gcp-project-id",
|
|
"location": "us-central1",
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Cohere">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "cohere",
|
|
"config": {
|
|
"model_name": "embed-english-v3.0",
|
|
# "api_key": "...", # ou defina COHERE_API_KEY
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="VoyageAI">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "voyageai",
|
|
"config": {
|
|
"model": "voyage-3",
|
|
# "api_key": "...", # ou defina VOYAGE_API_KEY
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="AWS Bedrock">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "amazon-bedrock",
|
|
"config": {
|
|
"model_name": "amazon.titan-embed-text-v1",
|
|
# Usa credenciais AWS padrão (sessão boto3)
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Hugging Face">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "huggingface",
|
|
"config": {
|
|
"model_name": "sentence-transformers/all-MiniLM-L6-v2",
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Jina">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "jina",
|
|
"config": {
|
|
"model_name": "jina-embeddings-v2-base-en",
|
|
# "api_key": "...", # ou defina JINA_API_KEY
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="IBM WatsonX">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "watsonx",
|
|
"config": {
|
|
"model_id": "ibm/slate-30m-english-rtrvr",
|
|
"api_key": "your-watsonx-api-key",
|
|
"project_id": "your-project-id",
|
|
"url": "https://us-south.ml.cloud.ibm.com",
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Embedder Customizado">
|
|
```python
|
|
# Passe qualquer callable que receba uma lista de strings e retorne uma lista de vetores
|
|
def my_embedder(texts: list[str]) -> list[list[float]]:
|
|
# Sua lógica de embedding aqui
|
|
return [[0.1, 0.2, ...] for _ in texts]
|
|
|
|
memory = Memory(embedder=my_embedder)
|
|
```
|
|
</Accordion>
|
|
</AccordionGroup>
|
|
|
|
### 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`. |
|
|
|
|
|
|
## Backend de Armazenamento
|
|
|
|
- **Padrão**: LanceDB, armazenado em `./.crewai/memory` (ou `$CREWAI_STORAGE_DIR/memory` se a variável de ambiente estiver definida, ou o caminho que você passar como `storage="path/to/dir"`).
|
|
- **Backend customizado**: Implemente o protocolo `StorageBackend` (veja `crewai.memory.storage.backend`) e passe uma instância para `Memory(storage=your_backend)`.
|
|
|
|
|
|
## Descoberta
|
|
|
|
Inspecione a hierarquia de escopos, categorias e registros:
|
|
|
|
```python
|
|
memory.tree() # Árvore formatada de escopos e contagem de registros
|
|
memory.tree("/project", max_depth=2) # Visão de subárvore
|
|
memory.info("/project") # ScopeInfo: record_count, categories, oldest/newest
|
|
memory.list_scopes("/") # Escopos filhos imediatos
|
|
memory.list_categories() # Nomes e contagens de categorias
|
|
memory.list_records(scope="/project/alpha", limit=20) # Registros em um escopo, mais recentes primeiro
|
|
```
|
|
|
|
|
|
## 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ância `0.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.
|
|
|
|
Nenhuma exceção é levantada para essas falhas de análise; apenas falhas de armazenamento ou do embedder irão levantar.
|
|
|
|
|
|
## 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 com `source_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` |
|
|
|
|
Exemplo: monitorar tempo de consulta:
|
|
|
|
```python
|
|
from crewai.events import BaseEventListener, MemoryQueryCompletedEvent
|
|
|
|
class MemoryMonitor(BaseEventListener):
|
|
def setup_listeners(self, crewai_event_bus):
|
|
@crewai_event_bus.on(MemoryQueryCompletedEvent)
|
|
def on_done(source, event):
|
|
if getattr(event, "source_type", None) == "unified_memory":
|
|
print(f"Query '{event.query}' completou em {event.query_time_ms:.0f}ms")
|
|
```
|
|
|
|
|
|
## Solução de Problemas
|
|
|
|
**Memória não persiste?**
|
|
- Garanta que o caminho de armazenamento seja gravável (padrão `./.crewai/memory`). Passe `storage="./your_path"` para usar outro diretório, ou defina a variável de ambiente `CREWAI_STORAGE_DIR`.
|
|
- Ao usar uma crew, confirme que `memory=True` ou `memory=Memory(...)` está definido.
|
|
|
|
**Recall lento?**
|
|
- Use `depth="shallow"` para contexto rotineiro do agente. Reserve `depth="auto"` ou `"deep"` para consultas complexas.
|
|
|
|
**Erros de análise LLM nos logs?**
|
|
- 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.
|
|
|
|
**Navegar na memória pelo terminal:**
|
|
```bash
|
|
crewai memory # Abre o navegador TUI
|
|
crewai memory --storage-path ./my_memory # Apontar para um diretório específico
|
|
```
|
|
|
|
**Resetar memória (ex.: para testes):**
|
|
```python
|
|
crew.reset_memories(command_type="memory") # Reseta memória unificada
|
|
# Ou em uma instância Memory:
|
|
memory.reset() # Todos os escopos
|
|
memory.reset(scope="/project/old") # Apenas essa subárvore
|
|
```
|
|
|
|
|
|
## Referência de Configuração
|
|
|
|
Toda a configuração é passada como argumentos nomeados para `Memory(...)`. 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. |
|
|
| `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. |
|