मेमोरी अवधारणाएँ
मेमोरी का semantic-store पक्ष कुछ छोटे प्रकारों से बना है। इन्हें ये चार समझ लें, फिर अनुभाग का बाकी हिस्सा अपने-आप समझ में आ जाएगा।
MemoryEntry
एकल मेमोरी रिकॉर्ड: कुछ सामग्री, किसने इसे लिखा, और कब।
use adk_memory::MemoryEntry;
use adk_core::Content;
use chrono::Utc;
let entry = MemoryEntry {
content: Content::new("user").with_text("I prefer dark mode"),
author: "user".to_string(),
timestamp: Utc::now(),
};
Entries संग्रह की इकाई हैं और recall की भी इकाई — search क्वेरी से सबसे संबंधित entries लौटाता है।
MemoryService trait
हर backend एक trait लागू करता है। दो methods आवश्यक हैं; बाकी के default implementations होते हैं जिन्हें backend override कर सकता है:
#[async_trait]
pub trait MemoryService: Send + Sync {
// Required
async fn add_session(&self, app: &str, user: &str, session: &str,
entries: Vec<MemoryEntry>) -> Result<()>;
async fn search(&self, req: SearchRequest) -> Result<SearchResponse>;
// Optional (default: "not implemented")
async fn delete_user(&self, app: &str, user: &str) -> Result<()>; // GDPR
async fn delete_session(&self, app: &str, user: &str, session: &str) -> Result<()>;
async fn add_entry(&self, app: &str, user: &str, entry: MemoryEntry) -> Result<()>;
async fn delete_entries(&self, app: &str, user: &str, query: &str) -> Result<u64>;
// …plus a health check
}
add_sessionपूरी हुई बातचीत के entries को ingest करता है। जब memory attached होती है, Runner यह आपके लिए call करता है।searchrecall है। Backends query की व्याख्या अलग-अलग तरीके से करते हैं — keyword, embedding similarity, या graph token-scoring — लेकिन contract वही रहता है।
SearchRequest / SearchResponse
use adk_memory::SearchRequest;
let req = SearchRequest {
app_name: "support".into(),
user_id: "alice".into(),
query: "contact preference".into(),
..Default::default() // top_k, project scoping, etc.
};
let resp = memory.search(req).await?; // resp.entries: Vec<MemoryEntry>
Session state vs. memory
ये अलग tools हैं — इन्हें एक न समझें:
| सत्र स्थिति | स्मृति | |
|---|---|---|
| अवधि | एक बातचीत | बातचीतों के बीच |
| API | adk-session (SessionService, state map) | adk-memory (MemoryService) |
| रखता है | लाइव प्रतिलिपि + स्क्रैच स्थिति | बाद में याद रखने योग्य स्थायी तथ्य |
| पढ़ता है | हमेशा संदर्भ में | आवश्यकता पर, search_memory के माध्यम से |
एक सामान्य प्रवाह: बातचीत session state में रहती है; जब यह समाप्त होती है (या हर turn पर), प्रासंगिक हिस्से memory में लिखे जाते हैं; अगला session context को फिर से लाने के लिए memory में search करता है। देखें Sessions & State.
Isolation: app, user, और project
Memory हमेशा (app_name, user_id) द्वारा keyed होती है, इसलिए users कभी एक-दूसरे की
memories नहीं देखते। आप user के भीतर एक तीसरा स्तर — project — scope कर सकते हैं:
- Global entries (
project_id = None) — हर context में visible. - Project entries (
project_id = Some(id)) — केवल उसी project के भीतर visible. - Project search global + matching project entries लौटाता है; global search केवल global entries लौटाता है।
use adk_memory::{MemoryServiceAdapter, InMemoryMemoryService};
use std::sync::Arc;
let service = Arc::new(InMemoryMemoryService::new());
// store within a project
service.add_session_to_project("app", "user", "sess", "acme-project", entries).await?;
// an adapter scoped to that project
let adapter = MemoryServiceAdapter::new(service, "app", "user")
.with_project_id("acme-project");
Projects का उपयोग करके, मान लीजिए, किसी user के work और personal assistants को memory साझा करने से रोकें, जबकि वास्तव में global facts अभी भी साझा रहें।
हर backend project scoping लागू नहीं करता
Project isolation backend की एक capability है, trait द्वारा guaranteed कुछ नहीं। इस पर निर्भर करने से पहले पूछें:
if service.supports_project_scoping() {
service.add_entry_to_project("app", "user", "acme-project", entry).await?;
} else {
// Decide explicitly: refuse, or store globally on purpose.
}
| बैकएंड | प्रोजेक्ट स्कोपिंग |
|---|---|
InMemoryMemoryService | हाँ |
SqliteMemoryService | हाँ |
PostgresMemoryService | हाँ |
RedisMemoryService | हाँ |
MongoMemoryService | हाँ |
Neo4jMemoryService | हाँ |
GraphMemoryService | नहीं — परियोजना विधियाँ एक त्रुटि लौटाती हैं |
प्रोजेक्ट समर्थन के बिना एक बैकएंड चुपचाप वैश्विक रूप से लिखने या हटाने के बजाय कॉल को असफल कर देता है। किसी write के scope को बढ़ाने से एक प्रोजेक्ट के लिए अभिप्रेत डेटा उसी app और user के अंतर्गत मौजूद हर चीज़ के लिए दिखाई देने लगेगा, और किसी delete के scope को बढ़ाने से नामित प्रोजेक्ट के बाहर की प्रविष्टियाँ हट जाएँगी — इनमें से किसी को भी caller return value से नहीं पहचान सकता। MemoryServiceAdapter::supports_project_scoping
अपने backend द्वारा समर्थित चीज़ों की रिपोर्ट करता है।
GDPR मिटाना
delete_user(app, user) सभी projects में user की सभी memories (entries और
embeddings) हटाता है — right-to-erasure primitive। जो backends durably store करते हैं, वे इसे implement करते हैं; अपने account-deletion path से इसे call करें।
memory.delete_user("support", "alice").await?;
Next: Backends →