Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Importante
Questa funzionalità è in versione beta.
Se hai già creato un agente in Python, puoi dargli una cronologia delle conversazioni duratura e memoria a lungo termine su Azure Databricks senza riscriverlo. In questo tutorial, colleghi l'agente a un archivio sessioni che persiste ogni conversazione, a uno store di memoria che contiene fatti duraturi tra le conversazioni e a una pipeline di memoria che distilla le conversazioni memorizzate in memoria. I passaggi coprono gli agenti costruiti con l'SDK OpenAI Agents, LangGraph o qualsiasi altro framework Python, ovunque l'agente venga eseguito.
Tip
Se non hai ancora un agente, inizia invece con il quickstart di Agent Bricks . La CLI di Agent Bricks prepara un nuovo agente con sessioni e memoria già configurate.
In questo esempio, un operatore di supporto dovrebbe riprendere la conversazione del cliente dal punto in cui si era interrotta e ricordare le preferenze del cliente nelle conversazioni successive e separate.
Per come le sessioni e la memoria si relazionano, vedi Memoria e sessioni dell'agente.
Requirements
- Un agente esistente scritto in Python 3.10 o superiore. I passaggi specifici del framework coprono l'SDK degli Agenti OpenAI e LangGraph. I passaggi per altri framework richiamano direttamente l'SDK AgentKit.
- Autenticazione di Azure Databricks. L'SDK AgentKit utilizza l'autenticazione predefinita dell'SDK Databricks per Python. Per lo sviluppo locale, esegui
databricks auth login --host <workspace-url>, oppure imposta le variabili d'ambienteDATABRICKS_HOSTeDATABRICKS_TOKEN. - La CLI Databricks, per controllare lo stato delle esecuzioni della pipeline di memoria.
- Per creare una pipeline di memoria, sono necessari il permesso di interrogare il modello utilizzato dalla pipeline e gli altri accessi elencati nei requisiti della pipeline di memoria.
Passo 1: Installa l'SDK AgentKit e la CLI Agent Bricks
Il databricks-agentbricks pacchetto contiene quanto segue:
- AgentKit SDK (
databricks_agentkit), client Python per gli archivi di sessione e memoria. - La CLI di Agent Bricks (
agentbricks). - Adattatori per l'SDK degli Agenti OpenAI e LangGraph che collegano i storage di sessione e memoria alle interfacce di sessione e strumenti esistenti di ciascun framework. Gli adattatori utilizzano i pacchetti framework che il tuo agente ha già installati.
Installa la versione 0.6.0 o superiore nell'ambiente del tuo agente:
pip install --upgrade "databricks-agentbricks>=0.6.0"
Passo 2: Crea uno store sessione e uno store di memoria
Il tuo agente utilizza due store, che Azure Databricks gestisce per te:
- Un archivio di sessione contiene la cronologia delle conversazioni. Ogni sessione è la trascrizione di una conversazione, che l'agente ricarica per continuare la conversazione da dove aveva interrotto.
- Una memoria contiene fatti durevoli su ogni utente, come preferenze e decisioni passate. L'agente lo esamina per ricordare cosa ha appreso in conversazioni precedenti e separate.
Lo store è il confine di sicurezza: qualsiasi principal con accesso a uno store può leggere e scrivere tutte le sue voci. Per isolare i tenant tra loro, crea una coppia separata di store per ciascun tenant. Vedi Partizionare e proteggere la memoria.
Crea ogni store una volta e riutilizzalo per ogni conversazione. Il tuo agente si riferisce a entrambi i negozi per nome.
AgentKit SDK
from databricks.sdk import WorkspaceClient
from databricks_agentkit import AgentKitClient
client = AgentKitClient(WorkspaceClient())
client.session_stores.create("support-agent-sessions", description="Support agent conversations")
client.memory_stores.create("support-agent-memory", description="Support agent long-term memory")
Mattoni agente
agentbricks sessions stores create --name support-agent-sessions --description "Support agent conversations"
agentbricks memory stores create --display-name support-agent-memory --description "Support agent long-term memory"
REST API
Imposta DATABRICKS_HOST sul nome host del tuo workspace, quindi esegui quanto segue:
export DATABRICKS_TOKEN=$(databricks auth token --profile <profile> | jq -r .access_token)
curl -X POST "https://${DATABRICKS_HOST}/api/2.0/agents/session-stores?session_store_id=support-agent-sessions" \
-H "Authorization: Bearer ${DATABRICKS_TOKEN}" -H "Content-Type: application/json" \
-d '{"description": "Support agent conversations"}'
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 long-term memory"}'
Gli ID dello store devono essere unici nello spazio di lavoro. 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. Un ID di session store deve essere di 3 a 55 caratteri.
Passo 3: Scegli gli ID degli attori e delle sessioni
Ogni chiamata che il tuo agente effettua ai negozi porta due identificatori:
-
actor_iddetermina a chi appartengono le conversazioni e i ricordi. Entrambi gli store lo usano, e una pipeline di memoria scrive i ricordi di ogni attore nello stessoactor_iddelle sessioni di quell'attore, così l'agente richiama i ricordi distillati solo quando i due corrispondono. -
session_ididentifica una conversazione, così che una richiesta di follow-up la riprenda.
Per questo tutorial, usa test-user come actor_id e conversation-1 come session_id. Le handle_message funzioni nei passaggi seguenti le considerano come user_id e conversation_id.
In produzione, imposta actor_id nel codice dell'applicazione dal contesto delle richieste affidabili, come l'identità verificata dell'utente che ha effettuato l'accesso, e non lasciare mai che il modello o il messaggio dell'utente lo scelgano. Per condividere la memoria tra un team o isolare i tenant, vedi Partizionare e proteggere la memoria. Per session_id, usa l'ID della conversazione o thread già presente nella tua app, oppure genera un UUID quando una conversazione inizia.
Passo 4: Persisti le conversazioni nello store delle sessioni
La cronologia della conversazione è il registro ordinato di una conversazione: i messaggi dell'utente, le risposte dell'agente e qualsiasi chiamata e risultato degli strumenti. Un archivio di sessione salva quella cronologia per ogni conversazione, così l'agente può ricaricarla alla prossima richiesta, anche dopo un riavvio. Sostituisci la cronologia delle conversazioni in corso del tuo agente con lo store sessioni che hai creato nel Passo 2.
Gli adattatori del framework si collegano all'interfaccia che ciascun framework già usa per lo stato della sessione, così il modello, gli strumenti e i prompt del tuo agente rimangono gli stessi.
OpenAI Agents SDK
L'SDK OpenAI Agents legge e scrive la cronologia delle conversazioni tramite un Session oggetto.
session_store() restituisce un Session supportato dal Managed Session Store. Passalo a Runner.run:
from agents import Agent, Runner
from databricks_agentkit.openai import session_store
SESSION_STORE = "support-agent-sessions"
# Your existing agent, unchanged.
agent = Agent(name="Support agent", instructions="You help customers with their Databricks workspaces.")
async def handle_message(user_id: str, conversation_id: str, message: str) -> str:
session = session_store(conversation_id, actor=user_id, store=SESSION_STORE)
result = await Runner.run(agent, message, session=session)
return result.final_output
Al primo messaggio di una conversazione, l'adattatore crea la sessione. Ad ogni esecuzione, l'SDK carica la cronologia della conversazione dalla sessione e aggiunge il nuovo messaggio utente, l'output del modello e gli elementi dello strumento.
LangGraph
LangGraph persiste lo stato del grafo tramite un checkpointer associato a un ID del thread.
checkpointer() restituisce un checkpointer supportato dallo store di sessione gestito e thread_config() mappa una conversazione e il suo utente su un thread:
from langchain.agents import create_agent
from databricks_agentkit.langgraph import checkpointer, thread_config
SESSION_STORE = "support-agent-sessions"
# Your existing model and tools, unchanged, with the managed checkpointer added.
agent = create_agent(model=model, tools=tools, checkpointer=checkpointer(store=SESSION_STORE))
async def handle_message(user_id: str, conversation_id: str, message: str) -> str:
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": message}]},
config=thread_config(conversation_id, actor=user_id),
)
return result["messages"][-1].content
Se il tuo agente usa già un checkpointer, sostituiscilo con checkpointer(). Se costruisci un StateGraph direttamente, passa il checkpointer a compile(). Il checkpointer memorizza lo stato completo del grafo, incluse le interruzioni con intervento umano, così un'esecuzione in pausa può riprendere dopo un riavvio.
Note
Il checkpointer memorizza checkpoint di grafo serializzati, che una pipeline di memoria non legge. Per utilizzare una pipeline di memoria con un agente LangGraph, registrare anche una trascrizione.
Altri framework
Per qualsiasi altro framework, o per chiamate dirette al modello, leggi e aggiungi la cronologia delle conversazioni con l'SDK AgentKit. Memorizza ogni messaggio come {"type": "message", "role": "user" | "assistant", "content": "<text>"}. Una pipeline di memoria distilla i messaggi dell'utente e dell'assistente in questa forma, e nella forma di messaggi OpenAI Responses con parti di contenuto testuale. Salta tutti gli altri elementi, come chiamate e risultati degli strumenti.
from databricks.sdk import WorkspaceClient
from databricks_agentkit import AgentKitClient
client = AgentKitClient(WorkspaceClient())
session_store = client.session_stores.get("support-agent-sessions")
def start_conversation(user_id: str, conversation_id: str) -> None:
session_store.add(actor_id=user_id, session_id=conversation_id)
def handle_message(user_id: str, conversation_id: str, message: str) -> str:
session = session_store.get(conversation_id)
if session.actor_id != user_id:
raise PermissionError("This conversation belongs to a different user.")
# Rebuild context from the stored history, oldest first.
history = [item.data for item in session.list_items(order_by="create_time asc")]
user_item = {"type": "message", "role": "user", "content": message}
reply = run_agent([*history, user_item]) # Your framework or model call.
session.append_items([user_item, {"type": "message", "role": "assistant", "content": reply}])
return reply
Cercare una sessione per session_id non è limitato a un attore, quindi verifica che la sessione appartenga all'utente richiedente prima di riprenderla.
Passare al session store non sposta le conversazioni che il tuo agente aveva memorizzato altrove. Per portare avanti una conversazione esistente, aggiungi i suoi elementi a una nuova sessione.
Passo 5: Dai memoria all'agente
La cronologia della sessione copre una conversazione. Per utilizzare ciò che l'agente ha appreso nelle conversazioni precedenti, collega l'agente al memory store. Ci sono due schemi, e puoi combinarli:
- Strumenti di memoria: Il modello decide quando richiamare la memoria e quando salvare un nuovo fatto.
- Promemoria prima di ogni esecuzione: La tua applicazione cerca in memoria il messaggio in arrivo e aggiunge i risultati al contesto dell'agente, così l'agente vede la memoria rilevante senza chiamare uno strumento.
Se una pipeline di memoria scrive la tua memoria (vedi Passaggio 6), l'agente deve solo richiamare la memoria. Puoi ignorare gli strumenti che salvano memoria.
OpenAI Agents SDK
Il seguente esempio utilizza entrambi i pattern in una copia per richiesta del tuo agente:
-
memory_tools()restituisce quattro strumenti:recallcerca nella memoria dell'utente,remembersalva un fatto sotto un argomento,forgetrimuove un fatto elist_memorieselenca ciò che è memorizzato. Gli strumenti sono legati a un solo attore, quindi il modello non può leggere o scrivere la memoria di un altro utente. -
recalled_facts()cerca nella memoria il messaggio in arrivo prima dell'esecuzione e aggiunge i risultati alle istruzioni dell'agente.
from databricks.sdk import WorkspaceClient
from databricks_agentkit import AgentKitClient
from databricks_agentkit.openai import memory_tools, session_store
MEMORY_STORE = "support-agent-memory"
memory_store = AgentKitClient(WorkspaceClient()).memory_stores.get(MEMORY_STORE)
def recalled_facts(user_id: str, message: str) -> str:
results = memory_store.search(actor_id=user_id, query=message, limit=5)
return "\n".join(f"- {r.memory.content}" for r in results)
async def handle_message(user_id: str, conversation_id: str, message: str) -> str:
instructions = agent.instructions # Your agent's existing instructions, as a string.
if facts := recalled_facts(user_id, message): # Recall before the run.
instructions += f"\n\nWhat you know about this user:\n{facts}"
user_agent = agent.clone(
instructions=instructions,
tools=[*agent.tools, *memory_tools(user_id, store=MEMORY_STORE)], # Memory tools.
)
session = session_store(conversation_id, actor=user_id, store=SESSION_STORE)
result = await Runner.run(user_agent, message, session=session)
return result.final_output
I fatti richiamati vanno nelle istruzioni, non nell'input, quindi la sessione non li memorizza. Per usare un solo pattern, elimina l'altro: rimuovi la memory_tools() linea o rimuovi la recalled_facts() chiamata. Se tieni gli strumenti, aggiorna le istruzioni del tuo agente per indicare quando usarli, ad esempio: "Usa recall per consultare le preferenze dell'utente prima di rispondere. Usa Remember per conservare dati duraturi che l'utente condivide. Usa il comando "forget" quando l'utente ti chiede di dimenticare qualcosa.
LangGraph
Il seguente esempio utilizza entrambi i pattern e costruisce l'agente per ogni richiesta. Il checkpointer viene creato una volta e condiviso:
-
memory_tools()restituisce quattro strumenti:recallcerca nella memoria dell'utente,remembersalva un fatto sotto un argomento,forgetrimuove un fatto elist_memorieselenca ciò che è memorizzato. Gli strumenti sono legati a un solo attore, quindi il modello non può leggere o scrivere la memoria di un altro utente. -
recalled_facts()cerca in memoria il messaggio in arrivo prima dell'esecuzione e aggiunge i risultati al prompt di sistema.
from databricks.sdk import WorkspaceClient
from databricks_agentkit import AgentKitClient
from langchain.agents import create_agent
from databricks_agentkit.langgraph import checkpointer, memory_tools, thread_config
MEMORY_STORE = "support-agent-memory"
memory_store = AgentKitClient(WorkspaceClient()).memory_stores.get(MEMORY_STORE)
def recalled_facts(user_id: str, message: str) -> str:
results = memory_store.search(actor_id=user_id, query=message, limit=5)
return "\n".join(f"- {r.memory.content}" for r in results)
async def handle_message(user_id: str, conversation_id: str, message: str) -> str:
system_prompt = SYSTEM_PROMPT # Tell the agent when to use the memory tools.
if facts := recalled_facts(user_id, message): # Recall before the run.
system_prompt += f"\n\nWhat you know about this user:\n{facts}"
agent = create_agent(
model=model,
tools=[*tools, *memory_tools(user_id, store=MEMORY_STORE)], # Memory tools.
system_prompt=system_prompt,
checkpointer=checkpointer(store=SESSION_STORE),
)
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": message}]},
config=thread_config(conversation_id, actor=user_id),
)
return result["messages"][-1].content
LangGraph aggiunge il prompt di sistema a ogni chiamata al modello senza salvarlo nello stato del grafo, quindi il checkpointer non memorizza i fatti richiamati. Per usare un solo pattern, elimina l'altro: rimuovi la memory_tools() linea o rimuovi la recalled_facts() chiamata.
Altri framework
Cerca in memoria il messaggio in arrivo prima di ogni esecuzione e passa i risultati all'agente come contesto. La ricerca corrisponde sia per parole chiave che per significato, quindi il messaggio dell'utente funziona bene come query.
memory_store = client.memory_stores.get("support-agent-memory")
def recall(user_id: str, message: str) -> list[dict]:
results = memory_store.search(actor_id=user_id, query=message, limit=5)
if not results:
return []
facts = "\n".join(f"- {r.memory.content}" for r in results)
return [{"role": "system", "content": f"What you know about this user:\n{facts}"}]
In handle_message del Passo 4, aggiungi il contesto richiamato all'input dell'agente. Non aggiungerlo alla sessione:
reply = run_agent([*recall(user_id, message), *history, user_item])
Per permettere all'agente di salvare autonomamente la memoria, incapsula le operazioni search e add dello store come strumenti per il tuo framework. Consulta Dai al tuo agente strumenti di memoria.
Passo 6: Crea una pipeline di memoria
Una pipeline di memoria legge le conversazioni nel tuo archivio sessione e distilla fatti, preferenze e decisioni durature per ogni attore nello store di memoria. Inoltre, unisce le voci sovrapposte nel tempo, così la memoria del tuo agente rimane consolidata senza codice aggiuntivo dell'agente.
Crea una pipeline che colleghi i due store:
agentbricks memory pipeline create \ --session-store support-agent-sessions \ --memory-store support-agent-memory \ --trigger scheduled \ --model system.ai.claude-sonnet-5 \ --instructions "Focus on durable customer preferences and account details. Ignore one-off troubleshooting steps."-
--trigger scheduledLa pipeline viene eseguita automaticamente circa ogni 24 ore. Senza di essa, la pipeline utilizza il trigger predefinito,manual, e funziona solo quando inizi una run. Vedi Eseguire una pipeline in base a una pianificazione. -
--modelimposta il modello che distilla i ricordi. Puoi usare qualsiasi modello che hai l'autorizzazione a interrogare. Se ometti--model, la pipeline utilizza un modello predefinito che Azure Databricks sceglie. -
--instructionsè opzionale e determina cosa la pipeline conserva. Vedi la distillazione di Steer con istruzioni.
Il comando restituisce il nome della risorsa della pipeline, nella forma
memory-pipelines/<pipeline-id>. Per ogni opzione, eseguiagentbricks memory pipeline create --helpo consulta il riferimento del comando CLI di Agent Bricks.-
L’utilità di pianificazione sceglie quando inizia la prima esecuzione pianificata. Per condensare le conversazioni già presenti nell'archivio sessioni, avvia un'esecuzione ora:
agentbricks memory pipeline run <pipeline-id>Il comando restituisce il nome della risorsa della run, nella forma
memory-pipelines/<pipeline-id>/runs/<run-id>.Controlla il risultato della run con l'API REST. Imposta
DATABRICKS_HOSTsul nome host del tuo workspace, quindi esegui quanto segue:export DATABRICKS_TOKEN=$(databricks auth token --profile <profile> | jq -r .access_token) curl "https://${DATABRICKS_HOST}/api/2.0/agents/memory-pipelines/<pipeline-id>/runs/<run-id>" \ -H "Authorization: Bearer ${DATABRICKS_TOKEN}"Quando l'esecuzione
stateèSUCCEEDED, i ricordi distillati sono nell'archivio di memoria.
Le esecuzioni di pipeline usano l'identità che ha creato la pipeline, non quella del tuo agente. Una pipeline può riscrivere, unire o cancellare qualsiasi voce sotto un actor_id che elabora, inclusi i voci che il tuo agente ha salvato con strumenti di memoria. Per l'API REST, gli stati di esecuzione e le limitazioni, vedi Pipeline di memoria agente.
Registra una trascrizione per gli agenti LangGraph
Una pipeline di memoria distilla solo i messaggi dell'utente e dell'assistente. Il checkpointer LangGraph memorizza checkpoint serializzati, quindi una pipeline che legge lo store sessione del checkpointer non trova messaggi da distillare. Per utilizzare una pipeline con un agente LangGraph, aggiungi anche i messaggi di ogni turno a uno store sessione separato e crea la pipeline su quel store:
transcripts = client.session_stores.create("support-agent-transcripts") # Create once.
def start_conversation(user_id: str, conversation_id: str) -> None:
transcripts.add(actor_id=user_id, session_id=conversation_id)
def record_turn(conversation_id: str, message: str, reply: str) -> None:
transcripts.get(conversation_id).append_items(
[
{"type": "message", "role": "user", "content": message},
{"type": "message", "role": "assistant", "content": reply},
]
)
Chiama start_conversation quando una conversazione inizia, prima della sua prima ainvoke, e chiama record_turn dopo ogni ainvoke. Passa a --session-store support-agent-transcripts quando crei la pipeline. In alternativa, saltare la pipeline e lasciare che l'agente salvi memoria con strumenti di memoria.
Passo 7: Concedi l'accesso al tuo agente distribuito
Quando esegui l'agente localmente, usa le tue credenziali. Un agente distribuito di solito funziona come entità servizio, che necessita di accesso a ogni store che legge o scrive. Concedere l'accesso con l'SDK AgentKit, passando l'ID dell'applicazione (client) del principale del servizio:
from databricks.sdk import WorkspaceClient
from databricks_agentkit import AgentKitClient
w = WorkspaceClient()
client = AgentKitClient(w)
# For an agent deployed as a Databricks app, look up the app's service principal.
sp_client_id = w.apps.get("support-agent").service_principal_client_id
client.session_stores.get("support-agent-sessions").grant_permission(sp_client_id)
client.memory_stores.get("support-agent-memory").grant_permission(sp_client_id)
grant_permission Garantisce l'accesso in scrittura per impostazione predefinita. Per concedere l'accesso di sola lettura, specifica permission="READ". Se hai creato un archivio di trascrizioni per un agente LangGraph, concedi anche l'accesso all'archivio. La pipeline di memoria non ha bisogno di una concessione per l'entità servizio del tuo agente, perché le esecuzioni della pipeline utilizzano l'identità che ha creato la pipeline.
Passo 8: Testa l'agente end-to-end
Chiama
handle_messageconuser_id="test-user"econversation_id="conversation-1", e condividi una preferenza duratura, come "Preferisco l'email al telefono e sono nel fuso orario del Pacifico." Se hai seguito i passaggi per altri framework, chiamastart_conversation("test-user", "conversation-1")prima. Invia un messaggio di follow-up nella stessa conversazione e conferma che l'agente abbia il contesto precedente.Conferma che lo store della sessione contenga la conversazione:
agentbricks sessions items list --store support-agent-sessions --session-id conversation-1Avvia un'esecuzione della pipeline di memoria e aspetta che il suo
statesiaSUCCEEDED, come nel Passo 6.Conferma che lo store di memoria contenga la preferenza per l'utente di test:
agentbricks memory entries search --store support-agent-memory --actor-id test-user --query "contact preferences"Inizia una nuova conversazione per
test-userconconversation_id="conversation-2", e chiedi "Come dovresti contattarmi?" L'agente risponde a memoria.
Troubleshooting
-
PERMISSION_DENIED(HTTP 403) dall'agente distribuito. Il service principal dell'agente non può accedere a un archivio. Concedigli l'accesso, come nel Passo 7. - Una pipeline ha successo ma non scrive voci. Conferma che lo store sessioni conservi i messaggi utente e assistente in una forma che la pipeline legge. Una pipeline salta chiamate di strumenti, risultati di strumenti e checkpoint LangGraph. Una run elabora solo i turni aggiunti dal checkpoint dell'attore, e i turni degli ultimi 60 secondi attendono la successiva esecuzione.
- L'agent non ricorda i ricordi distillati. Conferma che l'agente cerca la memoria con la stessa
actor_idche usano le sue sessioni. - L'avvio di una run non riesce con
ABORTED. Un'altra esecuzione della pipeline è in corso. Aspetta che finisca, poi avvia una nuova esecuzione.
Pulizia
Per eliminare le risorse create da questo tutorial, esegui quanto segue. Eliminare un archivio cancella tutto ciò che contiene.
agentbricks memory pipeline delete <pipeline-id>
agentbricks sessions stores delete support-agent-sessions
agentbricks memory stores delete support-agent-memory