mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-04-14 23:12:37 +00:00
Some checks failed
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* 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: 메모리
|
|
description: CrewAI의 통합 메모리 시스템을 활용하여 에이전트 역량을 강화합니다.
|
|
icon: database
|
|
mode: "wide"
|
|
---
|
|
|
|
## 개요
|
|
|
|
CrewAI는 **통합 메모리 시스템**을 제공합니다 -- 단기, 장기, 엔터티, 외부 메모리 유형을 하나의 지능형 API인 단일 `Memory` 클래스로 대체합니다. 메모리는 저장 시 LLM을 사용하여 콘텐츠를 분석하고(범위, 카테고리, 중요도 추론) 의미 유사도, 최신성, 중요도를 결합한 복합 점수로 적응형 깊이 recall을 지원합니다.
|
|
|
|
메모리를 네 가지 방법으로 사용할 수 있습니다: **독립 실행** (스크립트, 노트북), **Crew와 함께**, **에이전트와 함께**, 또는 **Flow 내부에서**.
|
|
|
|
## 빠른 시작
|
|
|
|
```python
|
|
from crewai import Memory
|
|
|
|
memory = Memory()
|
|
|
|
# 저장 -- LLM이 scope, categories, importance를 추론
|
|
memory.remember("We decided to use PostgreSQL for the user database.")
|
|
|
|
# 검색 -- 복합 점수(의미 + 최신성 + 중요도)로 결과 순위
|
|
matches = memory.recall("What database did we choose?")
|
|
for m in matches:
|
|
print(f"[{m.score:.2f}] {m.record.content}")
|
|
|
|
# 빠르게 변하는 프로젝트를 위한 점수 조정
|
|
memory = Memory(recency_weight=0.5, recency_half_life_days=7)
|
|
|
|
# 삭제
|
|
memory.forget(scope="/project/old")
|
|
|
|
# 자동 구성된 scope 트리 탐색
|
|
print(memory.tree())
|
|
print(memory.info("/"))
|
|
```
|
|
|
|
## 메모리를 사용하는 네 가지 방법
|
|
|
|
### 독립 실행
|
|
|
|
스크립트, 노트북, CLI 도구 또는 독립 지식 베이스로 메모리를 사용합니다 -- 에이전트나 crew가 필요하지 않습니다.
|
|
|
|
```python
|
|
from crewai import Memory
|
|
|
|
memory = Memory()
|
|
|
|
# 지식 구축
|
|
memory.remember("The API rate limit is 1000 requests per minute.")
|
|
memory.remember("Our staging environment uses port 8080.")
|
|
memory.remember("The team agreed to use feature flags for all new releases.")
|
|
|
|
# 나중에 필요한 것을 recall
|
|
matches = memory.recall("What are our API limits?", limit=5)
|
|
for m in matches:
|
|
print(f"[{m.score:.2f}] {m.record.content}")
|
|
|
|
# 긴 텍스트에서 원자적 사실 추출
|
|
raw = """Meeting notes: We decided to migrate from MySQL to PostgreSQL
|
|
next quarter. The budget is $50k. Sarah will lead the migration."""
|
|
|
|
facts = memory.extract_memories(raw)
|
|
# ["Migration from MySQL to PostgreSQL planned for next quarter",
|
|
# "Database migration budget is $50k",
|
|
# "Sarah will lead the database migration"]
|
|
|
|
for fact in facts:
|
|
memory.remember(fact)
|
|
```
|
|
|
|
### Crew와 함께 사용
|
|
|
|
기본 설정은 `memory=True`를 전달하고, 사용자 정의 동작은 설정된 `Memory` 인스턴스를 전달합니다.
|
|
|
|
```python
|
|
from crewai import Crew, Agent, Task, Process, Memory
|
|
|
|
# 옵션 1: 기본 메모리
|
|
crew = Crew(
|
|
agents=[researcher, writer],
|
|
tasks=[research_task, writing_task],
|
|
process=Process.sequential,
|
|
memory=True,
|
|
verbose=True,
|
|
)
|
|
|
|
# 옵션 2: 조정된 점수가 있는 사용자 정의 메모리
|
|
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,
|
|
)
|
|
```
|
|
|
|
`memory=True`일 때 crew는 기본 `Memory()`를 생성하고 crew의 `embedder` 설정을 자동으로 전달합니다. crew의 모든 에이전트는 자체 메모리가 없는 한 crew의 메모리를 공유합니다.
|
|
|
|
각 작업 후 crew는 자동으로 작업 출력에서 개별 사실을 추출하여 저장합니다. 각 작업 전에 에이전트는 메모리에서 관련 컨텍스트를 recall하여 작업 프롬프트에 주입합니다.
|
|
|
|
### 에이전트와 함께 사용
|
|
|
|
에이전트는 crew의 공유 메모리(기본값)를 사용하거나 비공개 컨텍스트를 위한 범위 지정 뷰를 받을 수 있습니다.
|
|
|
|
```python
|
|
from crewai import Agent, Memory
|
|
|
|
memory = Memory()
|
|
|
|
# 연구원은 비공개 scope를 받음 -- /agent/researcher만 볼 수 있음
|
|
researcher = Agent(
|
|
role="Researcher",
|
|
goal="Find and analyze information",
|
|
backstory="Expert researcher with attention to detail",
|
|
memory=memory.scope("/agent/researcher"),
|
|
)
|
|
|
|
# 작성자는 crew 공유 메모리 사용 (에이전트 수준 메모리 미설정)
|
|
writer = Agent(
|
|
role="Writer",
|
|
goal="Produce clear, well-structured content",
|
|
backstory="Experienced technical writer",
|
|
# memory 미설정 -- crew에 메모리가 활성화되면 crew._memory 사용
|
|
)
|
|
```
|
|
|
|
이 패턴은 연구원에게 비공개 발견을 제공하면서 작성자는 crew 공유 메모리에서 읽습니다.
|
|
|
|
### Flow와 함께 사용
|
|
|
|
모든 Flow에는 내장 메모리가 있습니다. 모든 flow 메서드 내부에서 `self.remember()`, `self.recall()`, `self.extract_memories()`를 사용합니다.
|
|
|
|
```python
|
|
from crewai.flow.flow import Flow, listen, start
|
|
|
|
class ResearchFlow(Flow):
|
|
@start()
|
|
def gather_data(self):
|
|
findings = "PostgreSQL handles 10k concurrent connections. MySQL caps at 5k."
|
|
self.remember(findings, scope="/research/databases")
|
|
return findings
|
|
|
|
@listen(gather_data)
|
|
def write_report(self, findings):
|
|
# 컨텍스트를 위해 과거 연구 recall
|
|
past = self.recall("database performance benchmarks")
|
|
context = "\n".join(f"- {m.record.content}" for m in past)
|
|
return f"Report:\nNew findings: {findings}\nPrevious context:\n{context}"
|
|
```
|
|
|
|
Flow에서의 메모리에 대한 자세한 내용은 [Flows 문서](/concepts/flows)를 참조하세요.
|
|
|
|
|
|
## 계층적 범위(Scopes)
|
|
|
|
### 범위란 무엇인가
|
|
|
|
메모리는 파일 시스템과 유사한 계층적 scope 트리로 구성됩니다. 각 scope는 `/`, `/project/alpha` 또는 `/agent/researcher/findings`와 같은 경로입니다.
|
|
|
|
```
|
|
/
|
|
/company
|
|
/company/engineering
|
|
/company/product
|
|
/project
|
|
/project/alpha
|
|
/project/beta
|
|
/agent
|
|
/agent/researcher
|
|
/agent/writer
|
|
```
|
|
|
|
범위는 **컨텍스트 의존적 메모리**를 제공합니다 -- 범위 내에서 recall하면 해당 트리 분기만 검색하여 정밀도와 성능을 모두 향상시킵니다.
|
|
|
|
### 범위 추론 작동 방식
|
|
|
|
`remember()` 호출 시 scope를 지정하지 않으면 LLM이 콘텐츠와 기존 scope 트리를 분석한 후 최적의 배치를 제안합니다. 적합한 기존 scope가 없으면 새로 생성합니다. 시간이 지남에 따라 scope 트리는 콘텐츠 자체에서 유기적으로 성장합니다 -- 미리 스키마를 설계할 필요가 없습니다.
|
|
|
|
```python
|
|
memory = Memory()
|
|
|
|
# LLM이 콘텐츠에서 scope 추론
|
|
memory.remember("We chose PostgreSQL for the user database.")
|
|
# -> /project/decisions 또는 /engineering/database 아래에 배치될 수 있음
|
|
|
|
# scope를 명시적으로 지정할 수도 있음
|
|
memory.remember("Sprint velocity is 42 points", scope="/team/metrics")
|
|
```
|
|
|
|
### 범위 트리 시각화
|
|
|
|
```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: 하위 트리 뷰
|
|
|
|
`MemoryScope`는 모든 연산을 트리의 한 분기로 제한합니다. 이를 사용하는 에이전트나 코드는 해당 하위 트리 내에서만 보고 쓸 수 있습니다.
|
|
|
|
```python
|
|
memory = Memory()
|
|
|
|
# 특정 에이전트를 위한 scope 생성
|
|
agent_memory = memory.scope("/agent/researcher")
|
|
|
|
# 모든 것이 /agent/researcher 기준으로 상대적
|
|
agent_memory.remember("Found three relevant papers on LLM memory.")
|
|
# -> /agent/researcher 아래에 저장
|
|
|
|
agent_memory.recall("relevant papers")
|
|
# -> /agent/researcher 아래에서만 검색
|
|
|
|
# subscope로 더 좁히기
|
|
project_memory = agent_memory.subscope("project-alpha")
|
|
# -> /agent/researcher/project-alpha
|
|
```
|
|
|
|
### 범위 설계 모범 사례
|
|
|
|
- **평평하게 시작하고 LLM이 구성하게 하세요.** 범위 계층 구조를 미리 과도하게 설계하지 마세요. `memory.remember(content)`로 시작하고 콘텐츠가 축적됨에 따라 LLM의 scope 추론이 구조를 만들게 하세요.
|
|
|
|
- **`/{엔터티_유형}/{식별자}` 패턴을 사용하세요.** `/project/alpha`, `/agent/researcher`, `/company/engineering`, `/customer/acme-corp` 같은 패턴에서 자연스러운 계층 구조가 나타납니다.
|
|
|
|
- **데이터 유형이 아닌 관심사별로 scope를 지정하세요.** `/decisions/project/alpha` 대신 `/project/alpha/decisions`를 사용하세요. 이렇게 하면 관련 콘텐츠가 함께 유지됩니다.
|
|
|
|
- **깊이를 얕게 유지하세요 (2-3 수준).** 깊이 중첩된 scope는 너무 희소해집니다. `/project/alpha/architecture`는 좋지만 `/project/alpha/architecture/decisions/databases/postgresql`은 너무 깊습니다.
|
|
|
|
- **알 때는 명시적 scope를, 모를 때는 LLM 추론을 사용하세요.** 알려진 프로젝트 결정을 저장할 때는 `scope="/project/alpha/decisions"`를 전달하세요. 자유 형식 에이전트 출력을 저장할 때는 scope를 생략하고 LLM이 결정하게 하세요.
|
|
|
|
### 사용 사례 예시
|
|
|
|
**다중 프로젝트 팀:**
|
|
```python
|
|
memory = Memory()
|
|
# 각 프로젝트가 자체 분기를 가짐
|
|
memory.remember("Using microservices architecture", scope="/project/alpha/architecture")
|
|
memory.remember("GraphQL API for client apps", scope="/project/beta/api")
|
|
|
|
# 모든 프로젝트에서 recall
|
|
memory.recall("API design decisions")
|
|
|
|
# 특정 프로젝트 내에서만
|
|
memory.recall("API design", scope="/project/beta")
|
|
```
|
|
|
|
**공유 지식과 에이전트별 비공개 컨텍스트:**
|
|
```python
|
|
memory = Memory()
|
|
|
|
# 연구원은 비공개 발견을 가짐
|
|
researcher_memory = memory.scope("/agent/researcher")
|
|
|
|
# 작성자는 자체 scope와 공유 회사 지식에서 읽을 수 있음
|
|
writer_view = memory.slice(
|
|
scopes=["/agent/writer", "/company/knowledge"],
|
|
read_only=True,
|
|
)
|
|
```
|
|
|
|
**고객 지원 (고객별 컨텍스트):**
|
|
```python
|
|
memory = Memory()
|
|
|
|
# 각 고객이 격리된 컨텍스트를 가짐
|
|
memory.remember("Prefers email communication", scope="/customer/acme-corp")
|
|
memory.remember("On enterprise plan, 50 seats", scope="/customer/acme-corp")
|
|
|
|
# 공유 제품 문서는 모든 에이전트가 접근 가능
|
|
memory.remember("Rate limit is 1000 req/min on enterprise plan", scope="/product/docs")
|
|
```
|
|
|
|
|
|
## 메모리 슬라이스
|
|
|
|
### 슬라이스란 무엇인가
|
|
|
|
`MemorySlice`는 여러 개의 분리된 scope에 대한 뷰입니다. 하나의 하위 트리로 제한하는 scope와 달리, 슬라이스는 여러 분기에서 동시에 recall할 수 있게 합니다.
|
|
|
|
### 슬라이스 vs 범위 사용 시기
|
|
|
|
- **범위(Scope)**: 에이전트나 코드 블록을 단일 하위 트리로 제한해야 할 때 사용. 예: `/agent/researcher`만 보는 에이전트.
|
|
- **슬라이스(Slice)**: 여러 분기의 컨텍스트를 결합해야 할 때 사용. 예: 자체 scope와 공유 회사 지식에서 읽는 에이전트.
|
|
|
|
### 읽기 전용 슬라이스
|
|
|
|
가장 일반적인 패턴: 에이전트에게 여러 분기에 대한 읽기 액세스를 제공하되 공유 영역에 쓰지 못하게 합니다.
|
|
|
|
```python
|
|
memory = Memory()
|
|
|
|
# 에이전트는 자체 scope와 회사 지식에서 recall 가능,
|
|
# 하지만 회사 지식에 쓸 수 없음
|
|
agent_view = memory.slice(
|
|
scopes=["/agent/researcher", "/company/knowledge"],
|
|
read_only=True,
|
|
)
|
|
|
|
matches = agent_view.recall("company security policies", limit=5)
|
|
# /agent/researcher와 /company/knowledge 모두에서 검색, 결과 병합 및 순위 매기기
|
|
|
|
agent_view.remember("new finding") # PermissionError 발생 (읽기 전용)
|
|
```
|
|
|
|
### 읽기/쓰기 슬라이스
|
|
|
|
읽기 전용이 비활성화되면 포함된 scope 중 어디에든 쓸 수 있지만, 어떤 scope인지 명시적으로 지정해야 합니다.
|
|
|
|
```python
|
|
view = memory.slice(scopes=["/team/alpha", "/team/beta"], read_only=False)
|
|
|
|
# 쓸 때 scope를 반드시 지정
|
|
view.remember("Cross-team decision", scope="/team/alpha", categories=["decisions"])
|
|
```
|
|
|
|
|
|
## 복합 점수(Composite Scoring)
|
|
|
|
Recall 결과는 세 가지 신호의 가중 조합으로 순위가 매겨집니다:
|
|
|
|
```
|
|
composite = semantic_weight * similarity + recency_weight * decay + importance_weight * importance
|
|
```
|
|
|
|
여기서:
|
|
- **similarity** = 벡터 인덱스에서 `1 / (1 + distance)` (0에서 1)
|
|
- **decay** = `0.5^(age_days / half_life_days)` -- 지수 감쇠 (오늘은 1.0, 반감기에서 0.5)
|
|
- **importance** = 레코드의 중요도 점수 (0에서 1), 인코딩 시 설정
|
|
|
|
`Memory` 생성자에서 직접 설정합니다:
|
|
|
|
```python
|
|
# 스프린트 회고: 최근 메모리 선호, 짧은 반감기
|
|
memory = Memory(
|
|
recency_weight=0.5,
|
|
semantic_weight=0.3,
|
|
importance_weight=0.2,
|
|
recency_half_life_days=7,
|
|
)
|
|
|
|
# 아키텍처 지식 베이스: 중요한 메모리 선호, 긴 반감기
|
|
memory = Memory(
|
|
recency_weight=0.1,
|
|
semantic_weight=0.5,
|
|
importance_weight=0.4,
|
|
recency_half_life_days=180,
|
|
)
|
|
```
|
|
|
|
각 `MemoryMatch`에는 결과가 해당 위치에 순위된 이유를 볼 수 있는 `match_reasons` 목록이 포함됩니다 (예: `["semantic", "recency", "importance"]`).
|
|
|
|
|
|
## LLM 분석 레이어
|
|
|
|
메모리는 LLM을 세 가지 방식으로 사용합니다:
|
|
|
|
1. **저장 시** -- scope, categories, importance를 생략하면 LLM이 콘텐츠를 분석하여 scope, categories, importance, 메타데이터(엔터티, 날짜, 주제)를 제안합니다.
|
|
2. **recall 시** -- deep/auto recall의 경우 LLM이 쿼리(키워드, 시간 힌트, 제안 scope, 복잡도)를 분석하여 검색을 안내합니다.
|
|
3. **메모리 추출** -- `extract_memories(content)`는 원시 텍스트(예: 작업 출력)를 개별 메모리 문장으로 나눕니다. 에이전트는 각 문장에 `remember()`를 호출하기 전에 이를 사용하여 하나의 큰 블록 대신 원자적 사실이 저장되도록 합니다.
|
|
|
|
모든 분석은 LLM 장애 시 우아하게 저하됩니다 -- [오류 시 동작](#오류-시-동작)을 참조하세요.
|
|
|
|
|
|
## RecallFlow (딥 Recall)
|
|
|
|
`recall()`은 세 가지 깊이를 지원합니다:
|
|
|
|
- **`depth="shallow"`** -- 복합 점수를 사용한 직접 벡터 검색. 빠름; 에이전트가 컨텍스트를 로드할 때 기본 사용.
|
|
- **`depth="deep"` 또는 `depth="auto"`** -- 다단계 RecallFlow 실행: 쿼리 분석, scope 선택, 벡터 검색, 신뢰도 기반 라우팅, 신뢰도가 낮을 때 선택적 재귀 탐색.
|
|
|
|
```python
|
|
# 빠른 경로 (에이전트 작업 컨텍스트 기본값)
|
|
matches = memory.recall("What did we decide?", limit=10, depth="shallow")
|
|
|
|
# 복잡한 질문용 지능형 경로
|
|
matches = memory.recall(
|
|
"Summarize all architecture decisions from this quarter",
|
|
limit=10,
|
|
depth="auto",
|
|
)
|
|
```
|
|
|
|
RecallFlow 라우터를 제어하는 신뢰도 임계값은 설정 가능합니다:
|
|
|
|
```python
|
|
memory = Memory(
|
|
confidence_threshold_high=0.9, # 매우 확신할 때만 합성
|
|
confidence_threshold_low=0.4, # 더 적극적으로 깊이 탐색
|
|
exploration_budget=2, # 최대 2라운드 탐색 허용
|
|
)
|
|
```
|
|
|
|
|
|
## Embedder 설정
|
|
|
|
메모리는 의미 검색을 위해 텍스트를 벡터로 변환하는 임베딩 모델이 필요합니다. 세 가지 방법으로 설정할 수 있습니다.
|
|
|
|
### Memory에 직접 전달
|
|
|
|
```python
|
|
from crewai import Memory
|
|
|
|
# 설정 dict로
|
|
memory = Memory(embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-small"}})
|
|
|
|
# 사전 구축된 callable로
|
|
from crewai.rag.embeddings.factory import build_embedder
|
|
embedder = build_embedder({"provider": "ollama", "config": {"model_name": "mxbai-embed-large"}})
|
|
memory = Memory(embedder=embedder)
|
|
```
|
|
|
|
### Crew Embedder 설정으로
|
|
|
|
`memory=True` 사용 시 crew의 `embedder` 설정이 전달됩니다:
|
|
|
|
```python
|
|
from crewai import Crew
|
|
|
|
crew = Crew(
|
|
agents=[...],
|
|
tasks=[...],
|
|
memory=True,
|
|
embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-small"}},
|
|
)
|
|
```
|
|
|
|
### 제공자 예시
|
|
|
|
<AccordionGroup>
|
|
<Accordion title="OpenAI (기본)">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "openai",
|
|
"config": {
|
|
"model_name": "text-embedding-3-small",
|
|
# "api_key": "sk-...", # 또는 OPENAI_API_KEY 환경 변수 설정
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Ollama (로컬, 비공개)">
|
|
```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": "...", # 또는 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": "...", # 또는 COHERE_API_KEY 환경 변수 설정
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="VoyageAI">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "voyageai",
|
|
"config": {
|
|
"model": "voyage-3",
|
|
# "api_key": "...", # 또는 VOYAGE_API_KEY 환경 변수 설정
|
|
},
|
|
})
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="AWS Bedrock">
|
|
```python
|
|
memory = Memory(embedder={
|
|
"provider": "amazon-bedrock",
|
|
"config": {
|
|
"model_name": "amazon.titan-embed-text-v1",
|
|
# 기본 AWS 자격 증명 사용 (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": "...", # 또는 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">
|
|
```python
|
|
# 문자열 목록을 받아 벡터 목록을 반환하는 callable 전달
|
|
def my_embedder(texts: list[str]) -> list[list[float]]:
|
|
# 임베딩 로직
|
|
return [[0.1, 0.2, ...] for _ in texts]
|
|
|
|
memory = Memory(embedder=my_embedder)
|
|
```
|
|
</Accordion>
|
|
</AccordionGroup>
|
|
|
|
### 제공자 참조
|
|
|
|
| 제공자 | 키 | 일반적인 모델 | 참고 |
|
|
| :--- | :--- | :--- | :--- |
|
|
| OpenAI | `openai` | `text-embedding-3-small` | 기본값. `OPENAI_API_KEY` 설정. |
|
|
| Ollama | `ollama` | `mxbai-embed-large` | 로컬, API 키 불필요. |
|
|
| Azure OpenAI | `azure` | `text-embedding-ada-002` | `deployment_id` 필요. |
|
|
| Google AI | `google-generativeai` | `gemini-embedding-001` | `GOOGLE_API_KEY` 설정. |
|
|
| Google Vertex | `google-vertex` | `gemini-embedding-001` | `project_id` 필요. |
|
|
| Cohere | `cohere` | `embed-english-v3.0` | 강력한 다국어 지원. |
|
|
| VoyageAI | `voyageai` | `voyage-3` | 검색에 최적화. |
|
|
| AWS Bedrock | `amazon-bedrock` | `amazon.titan-embed-text-v1` | boto3 자격 증명 사용. |
|
|
| Hugging Face | `huggingface` | `all-MiniLM-L6-v2` | 로컬 sentence-transformers. |
|
|
| Jina | `jina` | `jina-embeddings-v2-base-en` | `JINA_API_KEY` 설정. |
|
|
| IBM WatsonX | `watsonx` | `ibm/slate-30m-english-rtrvr` | `project_id` 필요. |
|
|
| Sentence Transformer | `sentence-transformer` | `all-MiniLM-L6-v2` | 로컬, API 키 불필요. |
|
|
| Custom | `custom` | -- | `embedding_callable` 필요. |
|
|
|
|
|
|
## 스토리지 백엔드
|
|
|
|
- **기본값**: LanceDB, `./.crewai/memory` 아래에 저장 (또는 환경 변수 `$CREWAI_STORAGE_DIR/memory`가 설정된 경우, 또는 `storage="path/to/dir"`로 전달한 경로).
|
|
- **사용자 정의 백엔드**: `StorageBackend` 프로토콜 구현 (`crewai.memory.storage.backend` 참조) 후 `Memory(storage=your_backend)`에 인스턴스 전달.
|
|
|
|
|
|
## 탐색(Discovery)
|
|
|
|
scope 계층 구조, 카테고리, 레코드를 검사합니다:
|
|
|
|
```python
|
|
memory.tree() # scope 및 레코드 수의 포맷된 트리
|
|
memory.tree("/project", max_depth=2) # 하위 트리 뷰
|
|
memory.info("/project") # ScopeInfo: record_count, categories, oldest/newest
|
|
memory.list_scopes("/") # 직계 자식 scope
|
|
memory.list_categories() # 카테고리 이름 및 개수
|
|
memory.list_records(scope="/project/alpha", limit=20) # scope의 레코드, 최신순
|
|
```
|
|
|
|
|
|
## 오류 시 동작
|
|
|
|
분석 중 LLM이 실패하면(네트워크 오류, 속도 제한, 잘못된 응답) 메모리는 우아하게 저하됩니다:
|
|
|
|
- **저장 분석** -- 경고가 로깅되고 메모리는 기본 scope `/`, 빈 categories, importance `0.5`로 저장됩니다.
|
|
- **메모리 추출** -- 전체 콘텐츠가 단일 메모리로 저장되어 누락되지 않습니다.
|
|
- **쿼리 분석** -- recall은 단순 scope 선택 및 벡터 검색으로 폴백하여 결과를 계속 반환합니다.
|
|
|
|
이러한 분석 실패에서는 예외가 발생하지 않으며, 스토리지 또는 embedder 실패만 예외를 발생시킵니다.
|
|
|
|
|
|
## 개인정보 참고
|
|
|
|
메모리 콘텐츠는 분석을 위해 설정된 LLM으로 전송됩니다(저장 시 scope/categories/importance, 쿼리 분석 및 선택적 딥 recall). 민감한 데이터의 경우 로컬 LLM(예: Ollama)을 사용하거나 제공자가 규정 요구 사항을 충족하는지 확인하세요.
|
|
|
|
|
|
## 메모리 이벤트
|
|
|
|
모든 메모리 연산은 `source_type="unified_memory"`로 이벤트를 발생시킵니다. 시간, 오류, 콘텐츠를 수신할 수 있습니다.
|
|
|
|
| 이벤트 | 설명 | 주요 속성 |
|
|
| :---- | :---------- | :------------- |
|
|
| **MemoryQueryStartedEvent** | 쿼리 시작 | `query`, `limit` |
|
|
| **MemoryQueryCompletedEvent** | 쿼리 성공 | `query`, `results`, `query_time_ms` |
|
|
| **MemoryQueryFailedEvent** | 쿼리 실패 | `query`, `error` |
|
|
| **MemorySaveStartedEvent** | 저장 시작 | `value`, `metadata` |
|
|
| **MemorySaveCompletedEvent** | 저장 성공 | `value`, `save_time_ms` |
|
|
| **MemorySaveFailedEvent** | 저장 실패 | `value`, `error` |
|
|
| **MemoryRetrievalStartedEvent** | 에이전트 검색 시작 | `task_id` |
|
|
| **MemoryRetrievalCompletedEvent** | 에이전트 검색 완료 | `task_id`, `memory_content`, `retrieval_time_ms` |
|
|
|
|
예: 쿼리 시간 모니터링:
|
|
|
|
```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}' completed in {event.query_time_ms:.0f}ms")
|
|
```
|
|
|
|
|
|
## 문제 해결
|
|
|
|
**메모리가 유지되지 않나요?**
|
|
- 저장 경로에 쓰기 권한이 있는지 확인하세요(기본값 `./.crewai/memory`). 다른 디렉터리를 사용하려면 `storage="./your_path"`를 전달하거나 `CREWAI_STORAGE_DIR` 환경 변수를 설정하세요.
|
|
- crew 사용 시 `memory=True` 또는 `memory=Memory(...)`가 설정되었는지 확인하세요.
|
|
|
|
**recall이 느린가요?**
|
|
- 일상적인 에이전트 컨텍스트에는 `depth="shallow"`를 사용하세요. 복잡한 쿼리에만 `depth="auto"` 또는 `"deep"`을 사용하세요.
|
|
|
|
**로그에 LLM 분석 오류가 있나요?**
|
|
- 메모리는 안전한 기본값으로 계속 저장/recall합니다. 전체 LLM 분석을 원하면 API 키, 속도 제한, 모델 가용성을 확인하세요.
|
|
|
|
**터미널에서 메모리 탐색:**
|
|
```bash
|
|
crewai memory # TUI 브라우저 열기
|
|
crewai memory --storage-path ./my_memory # 특정 디렉터리 지정
|
|
```
|
|
|
|
**메모리 초기화(예: 테스트용):**
|
|
```python
|
|
crew.reset_memories(command_type="memory") # 통합 메모리 초기화
|
|
# 또는 Memory 인스턴스에서:
|
|
memory.reset() # 모든 scope
|
|
memory.reset(scope="/project/old") # 해당 하위 트리만
|
|
```
|
|
|
|
|
|
## 설정 참조
|
|
|
|
모든 설정은 `Memory(...)`에 키워드 인수로 전달됩니다. 모든 매개변수에는 합리적인 기본값이 있습니다.
|
|
|
|
| 매개변수 | 기본값 | 설명 |
|
|
| :--- | :--- | :--- |
|
|
| `llm` | `"gpt-4o-mini"` | 분석용 LLM (모델 이름 또는 `BaseLLM` 인스턴스). |
|
|
| `storage` | `"lancedb"` | 스토리지 백엔드 (`"lancedb"`, 경로 문자열 또는 `StorageBackend` 인스턴스). |
|
|
| `embedder` | `None` (OpenAI 기본값) | Embedder (설정 dict, callable 또는 `None`으로 기본 OpenAI). |
|
|
| `recency_weight` | `0.3` | 복합 점수에서 최신성 가중치. |
|
|
| `semantic_weight` | `0.5` | 복합 점수에서 의미 유사도 가중치. |
|
|
| `importance_weight` | `0.2` | 복합 점수에서 중요도 가중치. |
|
|
| `recency_half_life_days` | `30` | 최신성 점수가 절반으로 줄어드는 일수(지수 감쇠). |
|
|
| `consolidation_threshold` | `0.85` | 저장 시 통합이 트리거되는 유사도. `1.0`으로 설정하면 비활성화. |
|
|
| `consolidation_limit` | `5` | 통합 중 비교할 기존 레코드 최대 수. |
|
|
| `default_importance` | `0.5` | 미제공 시 및 LLM 분석이 생략될 때 할당되는 중요도. |
|
|
| `confidence_threshold_high` | `0.8` | recall 신뢰도가 이 값 이상이면 결과를 직접 반환. |
|
|
| `confidence_threshold_low` | `0.5` | recall 신뢰도가 이 값 미만이면 더 깊은 탐색 트리거. |
|
|
| `complex_query_threshold` | `0.7` | 복잡한 쿼리의 경우 이 신뢰도 미만에서 더 깊이 탐색. |
|
|
| `exploration_budget` | `1` | 딥 recall 중 LLM 기반 탐색 라운드 수. |
|