Artfical AI / API
Obtener una clave de API Abrir tAI
Primeros pasos

Streaming

Configure "stream": true y el mismo endpoint devuelve la respuesta de forma incremental mediante eventos enviados por el servidor, en lugar de esperar a que todo termine.

Por qué usar streaming

Una solicitud sin streaming se bloquea hasta que el modelo termina de generar toda la respuesta, y luego la devuelve toda de una vez. Para una respuesta corta, eso rara vez se nota. Para una más larga, significa esperar varios segundos (a veces más) mirando una pantalla vacía antes de que aparezca cualquier texto. El streaming resuelve esto enviando la respuesta pieza por pieza, a medida que el modelo la produce, de modo que un cliente puede empezar a mostrar texto en una fracción de segundo desde que se envía la solicitud, en lugar de esperar todo el conjunto. Esa es la diferencia entre una interfaz de chat que se siente instantánea y una que parece quedarse colgada en cada mensaje. Es opcional y no cuesta nada extra usarlo.

Activarlo

{
  "model": "tai-4.1",
  "messages": [{"role": "user", "content": "1'den 5'e kadar say"}],
  "stream": true
}

El Content-Type de la respuesta pasa a ser text/event-stream en lugar de application/json. Cada línea de evento lleva el prefijo data: , y la conexión permanece abierta, enviando un evento por cada fragmento de contenido nuevo, hasta que el stream termina con una línea literal data: [DONE].

La forma de un chunk

La mayoría de los chunks llevan un pequeño fragmento de texto recién generado en choices[0].delta.content:

data: {"id": "chatcmpl-b94...", "object": "chat.completion.chunk", "created": 1788960276, "model": "tai-4.0.6P", "choices": [{"index": 0, "delta": {"content": "1"}, "finish_reason": null}]}

data: {"id": "chatcmpl-b94...", "object": "chat.completion.chunk", "created": 1788960276, "model": "tai-4.0.6P", "choices": [{"index": 0, "delta": {"content": ", 2"}, "finish_reason": null}]}

Concatenar cada valor de delta.content en orden, a lo largo de todos los chunks, reconstruye el texto completo de la respuesta. Construir esa concatenación es tarea del cliente; la API no envía el texto acumulado en ningún momento, solo el fragmento incremental que añade cada chunk.

El chunk de finalización

El último chunk que lleva contenido tiene un delta vacío y un finish_reason real ("stop", o "tool_calls" si el modelo está pidiendo invocar una herramienta, vea Llamadas a herramientas):

data: {"id": "chatcmpl-b94...", "object": "chat.completion.chunk", "created": 1788960276, "model": "tai-4.0.6P", "choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}]}

El chunk de uso

Después del chunk de finalización, se envía un chunk más con un array choices vacío y un objeto usage completo, con la misma forma que el campo usage de la respuesta sin streaming:

data: {"id": "chatcmpl-b94...", "object": "chat.completion.chunk", "created": 1788960276, "model": "tai-4.0.6P", "choices": [], "usage": {"prompt_tokens": 2, "completion_tokens": 3, "total_tokens": 5}}

data: [DONE]

Un cliente al que solo le importe el texto visible puede ignorar sin problema cualquier chunk con un array choices vacío; un cliente que quiera mostrar el uso de tokens o el costo estimado después del hecho debe buscar específicamente este chunk en lugar de asumir que el chunk de finalización lo lleva.

Leer un stream en código

# Python, using the official openai package
stream = client.chat.completions.create(
    model="tai-4.1",
    messages=[{"role": "user", "content": "Kısa bir şiir yaz"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Los SDK oficiales de OpenAI (Python y Node) ya saben interpretar esta forma de evento, dado que es la misma que usa su propia API; no se requiere nada específico de tAI en el cliente, más allá de apuntar base_url a https://api.artfical.com/v1, como se explica en la página Autenticación.

Un stream siempre termina de forma limpia

Incluso si algo sale mal a mitad de camino, la generación falla, una solicitud agota el tiempo internamente, sea cual sea la causa, el stream de todos modos termina con una señal visible en lugar de que la conexión simplemente se caiga sin explicación. En ese caso verá un chunk de contenido con un breve aviso entre corchetes, un chunk de finalización con "finish_reason": "stop", y luego [DONE], el mismo final bien formado que un stream exitoso normal. Un cliente siempre debe tratar la llegada de [DONE] como el final definitivo del turno, y tampoco debe asumir que un stream que termina sin él fue exitoso; una conexión caída sin [DONE] significa tratar la solicitud como fallida y reintentarla, igual que haría con una solicitud sin streaming que agotó el tiempo.