Usa la API de Genie One

Importante

Esta característica se encuentra en su versión beta. Un administrador de espacio de trabajo debe activar la vista previa de la API de Genie One . Vea Requisitos.

La API de Genie One permite que tu propia aplicación, servicio de backend o agente haga preguntas en lenguaje natural sobre tus datos a través de HTTP y transmita las respuestas en streaming. Genie One trabaja con todos los datos a los que el usuario puede acceder y basa sus respuestas en Genie Ontology, así que no necesitas configurar primero un agente depurado. Las nuevas preguntas se ejecutan con los permisos del Catálogo Unity del llamante, por lo que las respuestas solo incluyen datos a los que el llamante puede acceder. Leer una respuesta guardada o el historial de conversaciones devuelve el contenido almacenado. No vuelve a ejecutar consultas ni vuelve a comprobar permisos sobre los datos subyacentes.

Esta página explica cómo autenticarse, hacer preguntas, transmitir respuestas y gestionar conversaciones. Para los formatos completos de solicitud y respuesta, consulte la referencia de la API de Genie One.

Requirements

  • Un administrador de espacio de trabajo debe activar la vista previa de la API de Genie One desde la página de previsualizaciones del espacio de trabajo.
  • El llamante debe ser capaz de usar Genie One. El permiso de acceso del consumidor o cualquier permiso de espacio de trabajo de nivel superior es suficiente. Consulte ¿Qué es el acceso del consumidor?.
  • El llamante debe tener SELECT privilegios sobre los datos del Catálogo de Unity que usen las consultas que realice.
  • Para ejecutar consultas en un almacén de SQL específico, el llamante debe tener al menos el permiso CAN USE en ese almacén. Si no especificas un almacén, Genie One elige uno.

Authenticate

La API de Genie One acepta tokens de acceso OAuth con el alcance genie.

  • Para aplicaciones donde hay un usuario presente, utiliza OAuth para usuarios (OAuth U2M). Las peticiones se ejecutan como ese usuario, por lo que las respuestas reflejan los permisos del propio Catálogo de Unity del usuario.
  • Para cargas de trabajo automatizadas, utiliza un principal de servicio con OAuth para los principales de servicio (OAuth M2M). La entidad de servicio debe tener acceso a los almacenes de datos y SQL que usan sus preguntas.

También necesitas la URL de tu espacio de trabajo. Los ejemplos de esta página usan <workspace-url> para ello. Consulte Obtener identificadores para objetos del área de trabajo.

Haz una pregunta y recibe la respuesta en streaming

Envía una pregunta a POST /api/2.0/genie/one/responses. El endpoint devuelve una text/event-stream respuesta que transmite el progreso y la respuesta final de Genie One como Server-Sent Eventos (SSE).

Inicia una conversación

Omite conversation_id para empezar una nueva conversación. Configuremos input a la pregunta:

curl

curl -N -X POST "https://<workspace-url>/api/2.0/genie/one/responses" \
  -H "Authorization: Bearer <access-token>" \
  -H "Content-Type: application/json" \
  -d '{"input": "How did revenue change last quarter?"}'

La -N opción desactiva el búfer de salida para que el curl imprima cada evento a medida que llega.

Python

El siguiente ejemplo utiliza el SDK Databricks para Python solo para resolver tu autenticación, así que funciona con OAuth U2M, OAuth M2M o un perfil de configuración. Envía la solicitud con la requests biblioteca, entrega los IDs de respuesta y conversación a una on_created callback tan pronto como se acepta la respuesta, y recupera con una GET solicitud si la transmisión termina antes de tiempo. Luego imprime la respuesta final.

Instala los paquetes que utiliza el ejemplo:

pip install databricks-sdk requests
import json
import time

import requests
from databricks.sdk import WorkspaceClient

w = WorkspaceClient()
base_url = f"{w.config.host}/api/2.0/genie/one"
terminal_events = ("response.completed", "response.failed", "response.incomplete")


def get_response(conversation_id, response_id, timeout_seconds=600):
    # Poll the stored response until it reaches a terminal status.
    deadline = time.time() + timeout_seconds
    while True:
        resp = requests.get(
            f"{base_url}/conversations/{conversation_id}/responses/{response_id}",
            headers=w.config.authenticate(),
        )
        resp.raise_for_status()
        response = resp.json()
        if response["status"] != "in_progress" or time.time() > deadline:
            return response
        time.sleep(3)


def ask(question, conversation_id=None, on_created=None):
    body = {"input": question}
    if conversation_id:
        body["conversation_id"] = conversation_id

    created = None
    try:
        with requests.post(
            f"{base_url}/responses",
            headers={**w.config.authenticate(), "Content-Type": "application/json"},
            json=body,
            stream=True,
        ) as resp:
            resp.raise_for_status()
            # The stream is UTF-8, but its content type doesn't declare a charset.
            resp.encoding = "utf-8"
            for line in resp.iter_lines(decode_unicode=True):
                if not line or not line.startswith("data:"):
                    continue
                # SSE allows an optional single space after "data:".
                data = line[len("data:"):]
                if data.startswith(" "):
                    data = data[1:]
                if data == "[DONE]":
                    break
                event = json.loads(data)
                if event["type"] == "response.created":
                    created = event["response"]
                    if on_created:
                        on_created(created["conversation_id"], created["id"])
                elif event["type"] in terminal_events:
                    return event["response"]
    except requests.RequestException:
        # Without response.created, you can't tell whether the request was accepted.
        if created is None:
            raise
    if created is None:
        raise RuntimeError("The stream ended before the response was accepted.")
    # The stream ended or disconnected before a terminal event. Recover with GET.
    return get_response(created["conversation_id"], created["id"])


response = ask(
    "How did revenue change last quarter?",
    on_created=lambda conversation_id, response_id: print(
        f"conversation_id={conversation_id} response_id={response_id}"
    ),
)
print(response["status"])
for item in response["output"]:
    if item.get("phase") == "final_answer":
        # Keep parts separate so Markdown tables and source notes stay on their own lines.
        print("\n\n".join(part["text"] for part in item["content"]))

Este ejemplo espera al evento terminal. Para mostrar el progreso mientras Genie One funciona, gestiona también los eventos de salida del ítem, como se describe en Leer el flujo de eventos.

Lee el stream del evento

Cada evento tiene un nombre SSE event y un cuerpo JSON data con un type correspondiente y un sequence_number creciente. Un flujo acortado se ve así:

event: response.created
data: {"type":"response.created","sequence_number":0,"response":{"object":"response","id":"9f7c84c6d3af4ae8ac5cc43590a15366","model":"genie-one","status":"in_progress","output":[],"conversation_id":"6a34b9a50cb4435da7c463130c9d42c1"}}

event: response.output_item.added
data: {"type":"response.output_item.added","sequence_number":1,"output_index":0,"item":{"type":"message","role":"assistant","status":"in_progress","phase":"final_answer","content":[{"type":"output_text","text":"Revenue increased 12% last quarter.","annotations":[]}]}}

event: response.output_item.done
data: {"type":"response.output_item.done","sequence_number":2,"output_index":0,"item":{"type":"message","role":"assistant","status":"completed","phase":"final_answer","content":[{"type":"output_text","text":"Revenue increased 12% last quarter.","annotations":[]}]}}

event: response.completed
data: {"type":"response.completed","sequence_number":3,"response":{"object":"response","id":"9f7c84c6d3af4ae8ac5cc43590a15366","status":"completed","output":[...],"conversation_id":"6a34b9a50cb4435da7c463130c9d42c1"}}

data: [DONE]

Gestiona los eventos de la siguiente manera:

  • response.created: Se acepta la respuesta. Guarde response.id y response.conversation_id. Necesitas que hagan una pregunta de seguimiento o que se recuperen si la transmisión se desconecta.
  • response.output_item.added, response.output_item.updated, y response.output_item.done: Se añadió, cambió o terminó un mensaje de asistente. Cada evento lleva el mensaje completo, así que sustituye el mensaje en output_index en lugar de añadirle texto.
  • response.completed, response.failed, o response.incomplete: La respuesta alcanzó un estado terminal. El response.output array contiene los mensajes finales del asistente. El flujo termina entonces con data: [DONE].

Cada mensaje de asistente tiene un phase. Los mensajes con la etiqueta commentary describen el progreso de Genie One mientras funciona, y puedes mostrarlos como actualizaciones de estado. El mensaje con la final_answer fase es la respuesta. El texto de la respuesta es Markdown y puede incluir tablas de resultados.

Si la respuesta falla después de ser aceptada, el estado HTTP sigue siendo 200, y el flujo termina con un evento response.failed. El response.error objeto describe el fallo. Vea Solución de problemas.

Haz una pregunta de seguimiento

Para continuar una conversación, pasa el conversation_id desde response.created. Genie One utiliza las preguntas y respuestas anteriores como contexto.

curl -N -X POST "https://<workspace-url>/api/2.0/genie/one/responses" \
  -H "Authorization: Bearer <access-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Break that down by region.",
    "conversation_id": "<conversation-id>"
  }'

También puedes configurar warehouse_id para ejecutar consultas en un almacén SQL específico y user_timezone con una zona horaria IANA, como America/Los_Angeles, para que Genie One interprete las fechas relativas en la zona horaria del usuario.

Recuperar la conexión tras una desconexión

Desconectarse de la transmisión no cancela la respuesta. Genie One sigue funcionando, y puedes recuperar el resultado con los IDs de response.created:

curl "https://<workspace-url>/api/2.0/genie/one/conversations/<conversation-id>/responses/<response-id>" \
  -H "Authorization: Bearer <access-token>"

La solicitud devuelve el mismo objeto Response que el evento del flujo terminal. Mientras status esté in_progress, consulta el endpoint cada pocos segundos. Deténgase cuando status sea completed, failed o incomplete.

No vuelvas a enviar la solicitud POST para recuperar. Cada POST petición inicia una nueva respuesta.

Leer citas

Cada output_text parte tiene un annotations array que lista las fuentes que Genie One usó para ese texto. Cada anotación incluye:

  • title: El nombre para mostrar del origen.
  • asset_type: El tipo de fuente, como TABLE, NOTEBOOK, o WEB.
  • identifier: El identificador del activo, una ruta de volumen o una URL web.
  • index: El número de cita con índice base 1 al que se refiere el texto de la respuesta.

Gestionar conversaciones

Las conversaciones que creas con la API de Genie One pertenecen al usuario o a la entidad de servicio que llama. También aparecen en el historial de chat de ese usuario en Genie One.

  • Lista de conversaciones: GET /api/2.0/genie/one/conversations devuelve las conversaciones Genie One del llamante, actualizadas más recientemente primero. No incluye conversaciones con Genie Agent. Usa page_size (por defecto 20, máximo 100) y pasa next_page_token como page_token para obtener la siguiente página.
  • Obtener una conversación: GET /api/2.0/genie/one/conversations/{conversation_id} devuelve el título y las marcas de tiempo de la conversación, sin sus mensajes.
  • Lista los elementos de la conversación: GET /api/2.0/genie/one/conversations/{conversation_id}/items devuelve los mensajes del usuario y asistente en la conversación. Úsalo para reconstruir el historial de chat en tu aplicación.
  • Eliminar una conversación: DELETE /api/2.0/genie/one/conversations/{conversation_id} elimina la conversación.

Por ejemplo, para enumerar tus tres conversaciones más recientes:

curl "https://<workspace-url>/api/2.0/genie/one/conversations?page_size=3" \
  -H "Authorization: Bearer <access-token>"

Limitaciones

  • Cada solicitud acepta una pregunta como texto, hasta 25.000 bytes UTF-8. No se soportan imágenes, archivos y múltiples mensajes en una sola petición.
  • Una conversación solo puede tener una respuesta activa. Una nueva pregunta en esa conversación devuelve HTTP 409 hasta que termina la respuesta activa.
  • Las solicitudes tienen un límite de tasa por espacio de trabajo. Las solicitudes por encima del límite devuelven HTTP 429.

Prácticas recomendadas

  • Guarda los IDs de response.created: Guarda los IDs de respuesta y conversación tan pronto como empiece el stream, para que puedas recuperar la respuesta si la conexión se cae.
  • Reintentar solicitudes rechazadas con retroceso exponencial: Cuando la API devuelve una respuesta de error antes de que comience el flujo, como 429, intenta de nuevo con un retraso creciente entre intentos. Después de recibir response.created, recupera la respuesta con GET en lugar de volver a enviar la solicitud POST.
  • No lo intentes a ciegas tras un tiempo de espera o un error de gateway: Si una petición expira o devuelve un error de gateway como 502 o 504 antes de que llegue response.created, la API podría haberlo aceptado igualmente. Reenviar la POST solicitud puede entonces crear una segunda respuesta.
  • Vuelve a intentar respuestas fallidas solo cuando el error se puede volver a intentar: Cuando una respuesta falla, comprueba response.error.retryable antes de volver a hacer la pregunta.
  • Inicia una nueva conversación para cada sesión: Reutilizar una conversación entre sesiones no relacionadas puede reducir la precisión porque Genie One usa turnos anteriores como contexto.
  • Registrar solicitudes y respuestas: Registre los ID de respuesta, estados y errores para ayudar con la depuración y el seguimiento del uso.

Solución de problemas

Síntoma Causa y corrección
404 con el mensaje "El recurso solicitado no fue encontrado." La vista previa Genie One API está apagada para el espacio de trabajo, un ID de conversación o respuesta está incorrecto o pertenece a otro usuario, o el almacén no está disponible para el llamante. Pide a un administrador del espacio de trabajo que revise la página de Previsualizaciones del espacio de trabajo, luego comprueba los IDs y los permisos del llamante.
401 o 403 La solicitud no tiene un token válido, o el llamante no puede añadir una respuesta a la conversación. Revisa tu token OAuth y su genie ámbito. Consulta Autenticación.
400 con INVALID_PARAMETER_VALUE El cuerpo de la solicitud tiene un campo desconocido o una opción no soportada, más de un mensaje o una pregunta de más de 25.000 bytes. Envía solo los campos de la referencia de la API.
409 con ALREADY_EXISTS Otra respuesta está activa en la conversación. Espera a que termine y luego vuelve a intentarlo.
429 con RESOURCE_EXHAUSTED El espacio de trabajo superó el límite de solicitudes. Vuelva a intentarlo con retroceso exponencial. Consulte Limitaciones.
El flujo termina con response.failed La respuesta fracasó tras ser aceptada. Lee response.error.message, y vuelve a intentarlo solo si response.error.retryable es true.
El flujo se desconecta antes de un evento de terminación Recupera la respuesta con los IDs desde response.created. Ver Recuperarse de una conexión perdida.

Pricing

La API de Genie One ejecuta el chat en Genie One, por lo que las solicitudes se facturan igual que el chat de Genie One. Consulte precios de Genie.

Recursos adicionales