Interroga agenti distribuiti su Azure Databricks

Il modo in cui si interroga un agente dipende dal server dell'agente che lo serve. Trova il tuo agente nella tabella seguente, poi segui la sezione corrispondente. Per saperne di più su Agent Server, consulta Agent Server.

Il tuo agente Ospitato su Come eseguire una query
Usi DurableAgentServer Runtime dell'agente sulle app Databricks API di invocazione in /api/invocations
Utilizza MLflow AgentServer o LongRunningAgentServer (precedente) Applicazioni Databricks Databricks client OpenAI o l'API OpenAI Responses a /responses
Distribuito in Model Serving (legacy) Endpoint di gestione del modello Databricks client OpenAI, API REST, ai_query, o AI Playground

Gli agenti ospitati su Databricks Apps richiedono un token Databricks OAuth. I token di accesso personale non funzionano per le app Databricks. Per generare token OAuth da uno script, un service principal, un'altra app o un notebook, vedi Connettere un'app Databricks a un'API tramite autenticazione con token.

Interroga un agente che utilizza DurableAgentServer

Gli agenti che usano DurableAgentServer servono l'API di invocazione. Gli agenti che crei con la CLI di Agent Bricks usano DurableAgentServer, e agentbricks deploy li distribuisce su Agent Runtime come un'app chiamata agent-bricks-<name>. Ogni richiesta all'API avvia una run del tuo agente, chiamata invocazione.

Endpoint Description
POST /api/invocations Inizia un'invocazione. Per impostazione predefinita, la richiesta aspetta e restituisce il risultato. Impostare stream per ricevere gli eventi man mano che accadono o background per tornare immediatamente.
GET /api/invocations/<id> Restituisce lo stato di un'invocazione e, dopo il completamento, il suo output.
GET /api/invocations/<id>/events?after=<event-id> Trasmette in streaming gli eventi memorizzati dopo <event-id>. Usa questo endpoint per riconnetterti a un stream.

Corpo della richiesta

Il corpo della richiesta per POST /api/invocations accetta i seguenti campi. Il server rifiuta le richieste che contengono altri campi.

Campo Description
id Required. Un UUID che generi per ogni invocazione. Il server tratta l'ID come una chiave di idempotenza: riinviare la stessa richiesta con lo stesso ID restituisce l'invocazione esistente invece di eseguire di nuovo l'agente. Riutilizzare un ID per una richiesta diversa restituisce un errore 409.
session_id La conversazione a cui appartiene l'invocazione. Le invocazioni che condividono un ID sessione vengono eseguite una alla volta, in ordine. Gli agenti generati dai template CLI richiedono questo campo.
input L'input per il tuo agente. Gli agenti generati dai template CLI accettano una lista di messaggi o un oggetto con un elenco messages.
stream Impostato su true per ricevere eventi come Server-Sent Events (SSE).
background Imposta true per restituire immediatamente una risposta 202 con un URL di stato, e poi consulta il risultato.

Il gestore del tuo agente definisce la struttura di input. Gli agenti generati dai template CLI leggono i seguenti campi quando input è un oggetto:

Campo Description
messages La conversazione viene inoltrata all'agente.
actor L'identità dalla cui memoria a lungo termine l'agente legge e in cui scrive. Se non passi un actor, l'agente usa l'ID della sessione, quindi le memorie non si trasferiscono in una nuova sessione. Imposta actor dall'utente che ha effettuato l'accesso alla tua applicazione, non dal testo che l'utente digita.
model Il modello da usare per questa invocazione, invece del modello impostato nel codice dell'agente.
resume La risposta a un agente che si è messo in pausa per un input umano, come l'approvazione di una chiamata a uno strumento. Quando un agente va in pausa, l'invocazione status è interrupted. Invia resume in una nuova invocazione con la stessa session_id per continuare.

Per permettere all'agente di ricordare ciò che ha appreso su un utente durante le sessioni, passa l'ID dell'utente come actor:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "session_id": "support-case-123",
  "input": {
    "messages": [{ "role": "user", "content": "What does Databricks do?" }],
    "actor": "user-42"
  }
}

Mattoni agente

Per testare un agente distribuito dal tuo terminale, usa agentbricks endpoint invoke. Il comando cerca l'app e si autentica con il tuo profilo CLI.

agentbricks --profile <profile> endpoint invoke agent-bricks-<name> \
  --path /api/invocations \
  --json "{\"id\":\"$(uuidgen)\",\"session_id\":\"$(uuidgen)\",\"input\":[{\"role\":\"user\",\"content\":\"Hello\"}]}"

Per eseguire lo streaming della risposta, aggiungi "stream":true al corpo JSON e passa --sse. Per testare l'agente mentre viene eseguito localmente con agentbricks dev, sostituisci il nome dell'app con --url http://localhost:8000.

REST API

  1. Ottieni l'URL dell'app. Il campo URL nell'output è l'URL base per l'API delle invocazioni.

    agentbricks --profile <profile> deployments get agent-bricks-<name>
    
  2. Ottieni un token OAuth per il tuo profilo. L'output contiene il token nel access_token campo.

    databricks auth token --profile <profile>
    
  3. Inviare una richiesta:

    curl --request POST \
      --url <app-url>/api/invocations \
      --header 'Authorization: Bearer <OAuth token>' \
      --header 'content-type: application/json' \
      --data '{
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "session_id": "support-case-123",
        "input": [{ "role": "user", "content": "What does Databricks do?" }]
      }'
    

La risposta contiene l'invocazione id, il suo status e un campo output con il valore che il tuo agente restituisce. Il server non richiede uno schema di output: il tuo handler può restituire qualsiasi valore serializzabile in JSON. Gli agenti generati dai template CLI restituiscono un oggetto con i seguenti campi:

  • output: i messaggi che l'agente ha prodotto in questa invocazione.
  • status: completed, oppure interrupted se l'agente si fermava per un input umano.

Python

Il seguente esempio utilizza l'SDK Databricks per cercare l'URL dell'app e generare un token OAuth, e poi chiama l'API delle invocazioni. Il WorkspaceClient deve usare l'autenticazione OAuth.

import uuid

import requests
from databricks.sdk import WorkspaceClient

w = WorkspaceClient()
app_url = w.apps.get("agent-bricks-<name>").url
session_id = str(uuid.uuid4())

response = requests.post(
    f"{app_url}/api/invocations",
    headers=w.config.authenticate(),
    json={
        "id": str(uuid.uuid4()),
        "session_id": session_id,
        "input": [{"role": "user", "content": "What does Databricks do?"}],
    },
)
response.raise_for_status()
print(response.json()["output"])

Per continuare la conversazione, invia il messaggio successivo con lo stesso session_id e un nuovo id.

Stream, esegui in background e riconnettiti

  • Stream: Imposta "stream": true. La risposta è un flusso SSE che include eventi run.started e run.failed (o delta), oltre agli eventi emessi dal tuo agente, come eventi run.completed con testo in streaming. Ogni evento ha un ID.
  • Esegui in background: Imposta "background": true. Il server restituisce una 202 risposta con un status_url. Interroga GET /api/invocations/<id> finché lo stato non è completed. Se imposti "stream": trueanche , la risposta include un events_url da cui puoi leggere gli eventi.
  • Riconnettiti: Se un flusso si disconnette, chiama GET /api/invocations/<id>/events?after=<event-id> con l'ID dell'ultimo evento che hai ricevuto.

Il seguente esempio di Python genera una risposta in streaming:

with requests.post(
    f"{app_url}/api/invocations",
    headers=w.config.authenticate(),
    json={
        "id": str(uuid.uuid4()),
        "session_id": session_id,
        "input": [{"role": "user", "content": "Summarize our last conversation."}],
        "stream": True,
    },
    stream=True,
) as response:
    response.raise_for_status()
    for line in response.iter_lines(decode_unicode=True):
        if line.startswith("data: "):
            print(line[len("data: "):])

Se distribuisci l'agente con più di un'istanza, invia l'ID della sessione in un'intestazione X-Routing-Key per instradare tutte le richieste di una sessione alla stessa istanza.

Interroga un agente che utilizza il MLflow legacy AgentServer

Usa questa sezione per gli agenti che distribuisci sulle app Databricks con il server agente legacy: MLflow AgentServer o LongRunningAgentServer, con l'interfaccia ResponsesAgent . Questi agenti supportano l'API OpenAI Responses a /responses.

LongRunningAgentServer serve la stessa API, quindi i seguenti esempi si applicano anche ad essa. Supporta anche esecuzioni in background: imposta background su true nella richiesta, e poi recupera la risposta con GET /responses/<response-id>?stream=true&starting_after=<sequence-number>, che trasmette gli eventi dopo quel numero di sequenza.

client OpenAI di Databricks

Databricks raccomanda il client Databricks OpenAI per questi agenti. Includere il apps/ prefisso nel nome del modello.

from databricks.sdk import WorkspaceClient
from databricks_openai import DatabricksOpenAI

input_msgs = [{"role": "user", "content": "What does Databricks do?"}]
app_name = "<agent-app-name>"

# The WorkspaceClient must use OAuth authentication.
w = WorkspaceClient()
client = DatabricksOpenAI(workspace_client=w)

# Non-streaming request
response = client.responses.create(model=f"apps/{app_name}", input=input_msgs)
print(response)

# Streaming request
streaming_response = client.responses.create(
    model=f"apps/{app_name}", input=input_msgs, stream=True
)
for chunk in streaming_response:
    print(chunk)

Per superare custom_inputs, usa il parametro extra_body :

response = client.responses.create(
    model=f"apps/{app_name}",
    input=input_msgs,
    extra_body={"custom_inputs": {"id": 5}},
)

Per ottenere l'ID traccia di una richiesta, includere l'intestazione x-mlflow-return-trace-id (header). Usare quindi MLflow get_trace per recuperare la traccia completa.

response = client.responses.create(
    model=f"apps/{app_name}",
    input=input_msgs,
    extra_headers={"x-mlflow-return-trace-id": "true"},
)
trace_id = response.metadata["trace_id"]
trace = client.get_trace(trace_id)

REST API

Invia richieste al percorso /responses dell'URL dell'app. Il corpo della richiesta segue l'API OpenAI Responses, quindi puoi utilizzare qualsiasi client HTTP o strumento che la supporti.

curl --request POST \
  --url <app-url>/responses \
  --header 'Authorization: Bearer <OAuth token>' \
  --header 'content-type: application/json' \
  --data '{
    "input": [{ "role": "user", "content": "hi" }],
    "stream": true
  }'

Per passarli a custom_inputs, aggiungili al corpo della richiesta:

curl --request POST \
  --url <app-url>/responses \
  --header 'Authorization: Bearer <OAuth token>' \
  --header 'content-type: application/json' \
  --data '{
    "input": [{ "role": "user", "content": "hi" }],
    "custom_inputs": { "id": 5 }
  }'

Per ottenere l'ID della traccia, includere l'intestazione x-mlflow-return-trace-id: true (header). Il corpo della risposta include l'ID della traccia in un campo metadata.trace_id. Per le richieste di streaming, l'ID della traccia arriva come evento SSE separato (data: {"trace_id": "tr-..."}) verso la fine del flusso.

Consulta un agente legacy in Model Serving

Usa questa sezione per gli agenti legacy distribuiti negli endpoint Model Serving. Puoi autenticarti con un token Databricks OAuth o un token di accesso personale. Per trasferire questi agenti su Databricks Apps, vedi Migra un agente da Model Serving a Databricks Apps.

client OpenAI di Databricks

Per gli agenti che utilizzano l'interfaccia ResponsesAgent , chiama responses.create con il nome dell'endpoint come modello:

from databricks_openai import DatabricksOpenAI

input_msgs = [{"role": "user", "content": "What does Databricks do?"}]
endpoint = "<agent-endpoint-name>"

client = DatabricksOpenAI()

# Non-streaming request. Calls predict.
response = client.responses.create(model=endpoint, input=input_msgs)
print(response)

# Streaming request. Calls predict_stream.
streaming_response = client.responses.create(model=endpoint, input=input_msgs, stream=True)
for chunk in streaming_response:
    print(chunk)

Per gli agenti che utilizzano il legacy ChatAgent o ChatModel interfacce, usa il client di completamento delle chat:

from databricks.sdk import WorkspaceClient

messages = [{"role": "user", "content": "What does Databricks do?"}]
endpoint = "<agent-endpoint-name>"

client = WorkspaceClient().serving_endpoints.get_open_ai_client()
response = client.chat.completions.create(model=endpoint, messages=messages)
print(response)

Con uno dei due client, passa custom_inputs o databricks_options tramite il parametro extra_body. Ad esempio, extra_body={"databricks_options": {"return_trace": True}} restituisce la traccia con la risposta.

REST API

Per gli agenti che utilizzano l'interfaccia ResponsesAgent , inviare una richiesta a /serving-endpoints/responses con il nome dell'endpoint come modello:

curl --request POST \
  --url https://<workspace-url>/serving-endpoints/responses \
  --header 'Authorization: Bearer <token>' \
  --header 'content-type: application/json' \
  --data '{
    "model": "<agent-endpoint-name>",
    "input": [{ "role": "user", "content": "hi" }],
    "stream": true
  }'

Per gli agenti che utilizzano le interfacce ChatAgent o ChatModel, invia una richiesta a /serving-endpoints/chat/completions con una lista messages invece di input. Per passare custom_inputs o databricks_options, aggiungilo al corpo della richiesta. Puoi anche inviare richieste all'URL dell'endpoint /serving-endpoints/<agent-endpoint-name>/invocations . Vedi Consulta i singoli modelli dietro un endpoint.

Area di Sperimentazione IA

Per chattare con un agente su Model Serving senza scrivere codice, apri AI Playground e seleziona l'endpoint di servizio dell'agente. Per passare custom_inputs all'agente da AI Playground, consulta Fornire custom_inputs in AI Playground e nell'app Review.

SQL con

Usare ai_query per interrogare un agente su Model Serving da SQL. Vedi la ai_queryfunzione per sintassi e parametri.

SELECT ai_query(
  "<agent-endpoint-name>", question
) FROM (VALUES ('what is MLflow?'), ('how does MLflow work?')) AS t(question);

Risorse aggiuntive