मेमोरी अवधारणाएँ

मेमोरी का 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 करता है।
  • search recall है। 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 हैं — इन्हें एक न समझें:

सत्र स्थितिस्मृति
अवधिएक बातचीतबातचीतों के बीच
APIadk-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 →