La memoria dell'agente

Importante

Questa funzionalità è in versione beta.

La memoria degli agenti dà ai tuoi agenti una memoria a lungo termine che persiste tra le conversazioni. Azure Databricks memorizza la memoria in Lakebase e gestisce lo storage, l'indicizzazione e la ricerca per te, così i tuoi agenti possono ricordare le preferenze degli utenti, le decisioni passate e il contesto accumulato senza che tu debba gestire un database.

Note

Durante la fase di anteprima, ti viene addebitato il costo dell'istanza Lakebase sottostante che memorizza le voci della memoria. Non si applicano costi aggiuntivi per la memoria dell'agente stessa. I prezzi possono variare man mano che l'anteprima procede.

Usa la memoria degli agenti quando vuoi che i tuoi agenti facciano quanto segue:

  • Ricorda le preferenze, i fatti e le decisioni degli utenti nelle conversazioni separate.
  • Personalizza le risposte in base a ciò che un agente ha appreso nelle sessioni precedenti.
  • Condividi le conoscenze accumulate tra agenti e progetti.
  • Migliorare l'accuratezza e l'efficienza nel tempo.

La memoria degli agenti funziona con agenti basati su qualsiasi framework. Per la cronologia delle conversazioni a breve termine all'interno di un'unica interazione, usa sessioni agente.

Requisiti

  • Installa Python 3.10 o superiore, per usare l'SDK AgentKit. AgentKit SDK è il client Python di Databricks per le API degli agenti che utilizzano gli esempi sottostanti. Puoi anche chiamare l'API REST direttamente da qualsiasi linguaggio, senza bisogno di Python.
  • Per usare memory_store.put() o memory_store.list(path=...), installare databricks-agentbricks la versione 0.6.0 e superiore.

Come funziona la memoria degli agenti

Gerarchia delle risorse di memoria agente: uno store di memoria contiene molte voci di memoria, ciascuna identificata da actor_id, session_id opzionale e percorso, e contiene contenuti e una descrizione.

La memoria dell'agente ha due livelli:

  • Un archivio delle memorie è il contenitore relativo all'area di lavoro per le memorie di un agente. Creare uno store fornisce automaticamente lo storage di supporto a Lakebase. Indirizzi un negozio tramite il suo ID store, che scegli quando crei lo store.
  • Una voce di memoria è un singolo contenuto presente in uno store. Ogni voce contiene un testo content libero, una breve description stringa usata per il recupero e un insieme di campi che la organizzano e la suddividono:
    • actor_id (richiesto): a chi appartiene la memoria, come un utente finale o un altro agente.
    • session_id (opzionale): la sessione a cui appartiene la memoria. Lascia il campo non impostato per la memoria che si applica tra le sessioni dell'attore.
    • path (richiesto): un percorso simile a un filesystem che organizza gli elementi all'interno di un attore, come /preferences/response-style.md.

Un'entrata è identificata in modo unico dalla combinazione di actor_id, session_id, e path. Lo stesso percorso sotto due sessioni diverse, o sotto una sessione e senza una, contiene due voci separate.

Le entry entrano in uno store in due modi: il tuo agente o applicazione le scrive direttamente, oppure una pipeline di memoria le distilla dalle conversazioni in uno store di sessione.

Recupero

Recupera la memoria in due modi:

  • Elenco delle voci per un attore, opzionalmente filtrate per session_id, un prefisso path o un path esatto. Usa questo per sfogliare o visualizzare un indice di ciò che un agente sa.
  • Cerca le voci relative a un attore con una query in linguaggio naturale. La ricerca restituisce le voci più rilevanti classificate per punteggio di rilevanza.

Un session_id filtro su una delle due operazioni restituisce solo le voci salvate con quella sessione. Non restituisce le voci salvate senza una sessione.

Per iniziare

Questi esempi configurano la memoria dell'agente per un agente di supporto: creano uno store di memoria, salvano la preferenza dell'utente e la richiamano in una conversazione successiva. Scegli il cliente che si adatta al tuo progetto. Un ID dell'archivio di memoria deve essere di 3 a 56 caratteri, iniziare con una lettera minuscola, terminare con una lettera o un numero e contenere solo lettere minuscole, numeri e trattini.

AgentKit SDK

L'SDK AgentKit è il client Python di Databricks per le API degli agenti, distribuito nel databricks-agentbricks pacchetto. Si autentica con l'SDK di Databricks WorkspaceClient.

  1. Installa l'SDK AgentKit:

    pip install databricks-agentbricks
    
  2. Crea un archivio di ricordi per il tuo agente. AgentKitClient Autenticazione con le tue WorkspaceClient credenziali:

    from databricks.sdk import WorkspaceClient
    from databricks_agentkit import AgentKitClient
    
    client = AgentKitClient(WorkspaceClient())
    memory_store = client.memory_stores.create("support-agent-memory")
    
  3. Salva un ricordo dopo che l'agente ha imparato qualcosa di duraturo su un utente. actor_id indica a chi appartiene questa memoria, path la organizza all'interno di tale attore e description migliora il recupero:

    memory_store.add(
        actor_id="user-123",
        path="/preferences/communication.md",
        content="Prefers email over phone. Timezone: PST. Enterprise subscription.",
        description="User 123 communication preferences",
    )
    

    add() fallisce con ALREADY_EXISTS se esiste già una voce in quel percorso. Per creare la voce o aggiornare quella esistente, chiama memory_store.put() con gli stessi argomenti.

  4. Ricorda i ricordi dell'utente in una conversazione successiva con una ricerca in lingua naturale:

    results = memory_store.search(actor_id="user-123", query="communication preferences", limit=10)
    

REST API

I client chiamano l'API REST sotto /api/2.0/agents/memory-stores. Chiamalo direttamente per i linguaggi diversi da Python.

  1. Genera un token OAuth con la CLI Databricks:

    databricks auth login --host ${DATABRICKS_HOST}
    export DATABRICKS_TOKEN=$(databricks auth token | jq -r .access_token)
    
  2. Crea un archivio di ricordi per il tuo agente:

    curl -X POST "https://${DATABRICKS_HOST}/api/2.0/agents/memory-stores?managed_memory_store_id=support-agent-memory" \
      -H "Authorization: Bearer ${DATABRICKS_TOKEN}" -H "Content-Type: application/json" \
      -d '{"description": "Support agent memory"}'
    
  3. Salva una voce nella memoria per un utente. actor_id indica di chi è questa memoria, path la organizza e description migliora il recupero:

    curl -X POST "https://${DATABRICKS_HOST}/api/2.0/agents/memory-stores/support-agent-memory/entries" \
      -H "Authorization: Bearer ${DATABRICKS_TOKEN}" -H "Content-Type: application/json" \
      -d '{"actor_id": "user-123", "path": "/preferences/communication.md", "content": "Prefers email over phone.", "description": "Communication preferences"}'
    

    Se una voce esiste già in quel percorso, la richiesta fallisce con ALREADY_EXISTS (HTTP 409). Per aggiornare invece la voce esistente, cercala per percorso. L'interrogazione restituisce le voci del percorso per ogni sessione, quindi scegli quella il cui session_id corrisponde. L'ultimo segmento del suo name è l'ID della voce:

    curl -G "https://${DATABRICKS_HOST}/api/2.0/agents/memory-stores/support-agent-memory/entries" \
      -H "Authorization: Bearer ${DATABRICKS_TOKEN}" \
      --data-urlencode "actor_id=user-123" --data-urlencode "path=/preferences/communication.md"
    

    Poi aggiorna il contenuto della voce con il suo ID:

    curl -X PATCH "https://${DATABRICKS_HOST}/api/2.0/agents/memory-stores/support-agent-memory/entries/<entry-id>?update_mask=content" \
      -H "Authorization: Bearer ${DATABRICKS_TOKEN}" -H "Content-Type: application/json" \
      -d '{"content": "Prefers email over phone. Timezone: PST."}'
    
  4. Ricorda i ricordi dell'utente con una ricerca in lingua naturale:

    curl -X POST "https://${DATABRICKS_HOST}/api/2.0/agents/memory-stores/support-agent-memory/entries:search" \
      -H "Authorization: Bearer ${DATABRICKS_TOKEN}" -H "Content-Type: application/json" \
      -d '{"actor_id": "user-123", "query": "communication preferences"}'
    

Dai al tuo agente strumenti di memoria

Per permettere a un agente di decidere quando salvare e richiamare memoria, avvolgi le operazioni client come strumenti e istruisci l'agente su quando usarle nel suo prompt di sistema. Imposta il actor_id codice dell'applicazione attendibile dall'identità verificata dell'utente finale. Non lasciare mai che il modello scelga quale memoria leggere o in quale scrivere.

Il seguente esempio racchiude l'SDK memory_store AgentKit di Get Started come strumenti per l'SDK degli Agenti OpenAI.

from agents import Agent, function_tool

def make_memory_tools(memory_store, actor_id: str):
    @function_tool
    def search_memory(query: str) -> str:
        """Search long-term memory for relevant facts about the user."""
        results = memory_store.search(actor_id=actor_id, query=query, limit=10)
        return "\n\n".join(f"{r.memory.path}: {r.memory.content}" for r in results) or "No memory found."

    @function_tool
    def save_memory(path: str, content: str, description: str = "") -> str:
        """Save a durable, long-term memory about the user, replacing any memory at the same path."""
        memory_store.put(actor_id=actor_id, path=path, content=content, description=description or None)
        return f"Saved memory at {path}"

    @function_tool
    def list_memories() -> str:
        """List the paths and descriptions of the user's long-term memories."""
        memories = memory_store.list(actor_id=actor_id)
        return "\n".join(f"{m.path}: {m.description}" if m.description else m.path for m in memories) or "No memory found."

    @function_tool
    def forget_memory(path: str) -> str:
        """Delete the long-term memory at a path, such as when the user asks you to forget it."""
        memories = list(memory_store.list(actor_id=actor_id, path=path))
        for memory in memories:
            memory.delete()
        return f"Forgot memory at {path}" if memories else f"No memory at {path}"

    return [search_memory, save_memory, list_memories, forget_memory]

agent = Agent(
    name="Support agent",
    instructions="Save durable user preferences, recall them when relevant, and forget them when the user asks.",
    tools=make_memory_tools(memory_store, actor_id="user-123"),
)

put() crea l'entrata, o sostituisce il contenuto della voce già su quel percorso. Per aggiungere il contenuto come nuove righe, specifica append=True. put() non è atomica, quindi le scritture concorrenti sullo stesso percorso possono sovrascriversi a vicenda. list(path=...) restituisce le voci esattamente su quel percorso in ogni sessione, quindi forget_memory elimina anche qualsiasi voce salvata nel percorso all'interno di una sessione.

Lo stesso schema funziona con l'SDK Claude Agent e altri framework: incapsulare le operazioni di ricerca, put, lista e delete dello store come strumenti del framework.

Se esegui anche una pipeline di memoria sullo stesso archivio di memoria, la pipeline può riscrivere, unire, dividere o eliminare le voci che il tuo agente salva per qualsiasi attore elaborato dal tuo agente.

Partizione e memoria sicura

All'interno di un negozio, actor_id serve a separare a chi appartengono i ricordi. Ogni elenco e ricerca è limitato a un solo actor_idparametro, quindi scegli la strategia che corrisponde a ciò che il tuo agente deve ricordare:

  • Memoria privata per ogni utente: Imposta actor_id sull'identità verificata dell'utente finale. Ogni utente ha la propria partizione e l'agente recupera solo gli elementi di quell'utente.
    • Esempio: Un agente di supporto ricorda le preferenze di comunicazione di un utente e i ticket passati.
  • Memoria condivisa per un gruppo: Imposta actor_id su una chiave fissa che scegli, come un ID di team, progetto o organizzazione. Tutti leggono e scrivono gli stessi ricordi.
    • Esempio: Un agente di team ricorda un glossario condiviso di termini aziendali e convenzioni interne.
  • Memoria divisa da qualcos'altro: Costruisci actor_id dai tuoi valori, come un tenant ID o un user:project composite.
    • Esempio: Un'app multi-tenant imposta actor_id su {tenant}:{user} in modo che gli utenti di ciascun cliente rimangano isolati gli uni dagli altri.

Imposta actor_id nel codice dell’applicazione dal contesto di un chiamante attendibile: l’identità verificata dell’utente finale per la memoria per utente oppure una chiave attendibile del team o del progetto per la memoria condivisa. Non lasciare mai che sia il modello a sceglierlo. Se la tua strategia dipende dall'identità dell'utente finale, rifiuta le richieste che non ne includono una invece di ripiegare su un actor_id condiviso.

Avvertimento

actor_id separa i ricordi, ma non è un controllo di accesso. Gli archivi di memoria sono limitati all’area di lavoro, quindi qualsiasi entità che può raggiungere uno store può leggere e scrivere ogni voce su tutti gli attori. Il negozio, non l'attore, è il confine di sicurezza. Per garantire un rigoroso isolamento tra tenant o utenti, crea un archivio di memoria separato per ciascun limite di isolamento.

Per consentire a un altro principal, ad esempio il service principal del tuo agente, di usare uno store, concedigli l’accesso tramite l’operazione grant-permission dello store (memory_store.grant_permission(principal_id) nell’SDK AgentKit). Solo il creatore dello store o un amministratore dello spazio di lavoro possono concedere l'accesso.

Limitations

  • La memoria dell’agente fornisce solo memoria a lungo termine. Per la cronologia delle conversazioni a breve termine, vedi le sessioni con gli agenti.
  • La ricerca classifica le voci in base alla rilevanza, combinando il testo completo (BM25) e l'abbinamento semantico su contenuto e descrizione di ogni voce. Restituisce fino a 100 voci e non supporta la paginazione.
  • Il controllo degli accessi è applicato a livello di negozio. Il controllo degli accessi per voce e per attore non è disponibile.
  • Il controllo di accesso al negozio copre gli ingressi del negozio. Qualsiasi utente dello spazio di lavoro può elencare e ottenere archivi di memoria, inclusi i relativi ID e descrizioni.
  • Non puoi cambiare l'ID di un negozio dopo averlo creato. Solo description può essere aggiornato.

Passaggi successivi