from crewai import Memorymemory = Memory()# Store -- the LLM infers scope, categories, and importancememory.remember("We decided to use PostgreSQL for the user database.")# Retrieve -- results ranked by composite score (semantic + recency + importance)matches = memory.recall("What database did we choose?")for m in matches: print(f"[{m.score:.2f}] {m.record.content}")# Tune scoring for a fast-moving projectmemory = Memory(recency_weight=0.5, recency_half_life_days=7)# Forgetmemory.forget(scope="/project/old")# Explore the self-organized scope treeprint(memory.tree())print(memory.info("/"))
from crewai import Memorymemory = Memory()# Build up knowledgememory.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.")# Later, recall what you needmatches = memory.recall("What are our API limits?", limit=5)for m in matches: print(f"[{m.score:.2f}] {m.record.content}")# Extract atomic facts from a longer textraw = """Meeting notes: We decided to migrate from MySQL to PostgreSQLnext 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)
from crewai.flow.flow import Flow, listen, startclass 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 research to provide context 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}"
memory = Memory()# LLM infers scope from contentmemory.remember("We chose PostgreSQL for the user database.")# -> might be placed under /project/decisions or /engineering/database# You can also specify scope explicitlymemory.remember("Sprint velocity is 42 points", scope="/team/metrics")
memory = Memory()# Create a scope for a specific agentagent_memory = memory.scope("/agent/researcher")# Everything is relative to /agent/researcheragent_memory.remember("Found three relevant papers on LLM memory.")# -> stored under /agent/researcheragent_memory.recall("relevant papers")# -> searches only under /agent/researcher# Narrow further with subscopeproject_memory = agent_memory.subscope("project-alpha")# -> /agent/researcher/project-alpha
memory = Memory()# Each project gets its own branchmemory.remember("Using microservices architecture", scope="/project/alpha/architecture")memory.remember("GraphQL API for client apps", scope="/project/beta/api")# Recall across all projectsmemory.recall("API design decisions")# Or within a specific projectmemory.recall("API design", scope="/project/beta")
具有共享知识的各智能体私有背景
memory = Memory()# Researcher has private findingsresearcher_memory = memory.scope("/agent/researcher")# Writer can read from both its own scope and shared company knowledgewriter_view = memory.slice( scopes=["/agent/writer", "/company/knowledge"], read_only=True,)
客户支持(按客户划分上下文)
memory = Memory()# Each customer gets isolated contextmemory.remember("Prefers email communication", scope="/customer/acme-corp")memory.remember("On enterprise plan, 50 seats", scope="/customer/acme-corp")# Shared product docs are accessible to all agentsmemory.remember("Rate limit is 1000 req/min on enterprise plan", scope="/product/docs")
memory = Memory()# Agent can recall from its own scope AND company knowledge,# but cannot write to company knowledgeagent_view = memory.slice( scopes=["/agent/researcher", "/company/knowledge"], read_only=True,)matches = agent_view.recall("company security policies", limit=5)# Searches both /agent/researcher and /company/knowledge, merges and ranks resultsagent_view.remember("new finding") # Raises PermissionError (read-only)
# Only 2 records are stored (the third is a near-duplicate of the first)memory.remember_many([ "CrewAI supports complex workflows.", "Python is a great language.", "CrewAI supports complex workflows.", # dropped by intra-batch dedup])
# Returns immediately -- save happens in backgroundmemory.remember_many(["Fact A.", "Fact B.", "Fact C."])# recall() automatically waits for pending saves before searchingmatches = memory.recall("facts") # sees all 3 records
# Tag memories with their originmemory.remember("User prefers dark mode", source="user:alice")memory.remember("System config updated", source="admin")memory.remember("Agent found a bug", source="agent:debugger")# Recall only memories from a specific sourcematches = memory.recall("user preferences", source="user:alice")
# Store a private memorymemory.remember("Alice's API key is sk-...", source="user:alice", private=True)# This recall sees the private memory (source matches)matches = memory.recall("API key", source="user:alice")# This recall does NOT see it (different source)matches = memory.recall("API key", source="user:bob")# Admin access: see all private records regardless of sourcematches = memory.recall("API key", include_private=True)
# Shallow: pure vector search, no LLMmatches = memory.recall("What did we decide?", limit=10, depth="shallow")# Deep (default): intelligent retrieval with LLM analysis for long queriesmatches = memory.recall( "Summarize all architecture decisions from this quarter", limit=10, depth="deep",)
控制 RecallFlow 路由器的置信度阈值是可配置的。
memory = Memory( confidence_threshold_high=0.9, # Only synthesize when very confident confidence_threshold_low=0.4, # Explore deeper more aggressively exploration_budget=2, # Allow up to 2 exploration rounds query_analysis_threshold=200, # Skip LLM for queries shorter than this)
# Pass any callable that takes a list of strings and returns a list of vectorsdef my_embedder(texts: list[str]) -> list[list[float]]: # Your embedding logic here return [[0.1, 0.2, ...] for _ in texts]memory = Memory(embedder=my_embedder)
from crewai import Memory, LLM# Default: gpt-4o-minimemory = Memory()# Use a different OpenAI modelmemory = Memory(llm="gpt-4o")# Use Anthropicmemory = Memory(llm="anthropic/claude-3-haiku-20240307")# Use Ollama for fully local/private analysismemory = Memory(llm="ollama/llama3.2")# Use Google Geminimemory = Memory(llm="gemini/gemini-2.0-flash")# Pass a pre-configured LLM instance with custom settingsllm = LLM(model="gpt-4o", temperature=0)memory = Memory(llm=llm)
LLM 是延迟加载的——仅在首次需要时创建。这意味着 Memory() 在构建时绝不会失败,即使未设置 API 密钥也是如此。错误仅在实际调用 LLM 时才会出现(例如在没有明确作用域/类别的情况下保存,或在深度回忆期间)。对于完全离线/私有的操作,请对 LLM 和嵌入器都使用本地模型:
memory.tree() # Formatted tree of scopes and record countsmemory.tree("/project", max_depth=2) # Subtree viewmemory.info("/project") # ScopeInfo: record_count, categories, oldest/newestmemory.list_scopes("/") # Immediate child scopesmemory.list_categories() # Category names and countsmemory.list_records(scope="/project/alpha", limit=20) # Records in a scope, newest first
crewai memory # Opens the TUI browsercrewai memory --storage-path ./my_memory # Point to a specific directory
重置记忆(例如用于测试)
crew.reset_memories(command_type="memory") # Resets unified memory# Or on a Memory instance:memory.reset() # All scopesmemory.reset(scope="/project/old") # Only that subtree