Artfical AI / API
Obter uma chave de API Abrir tAI
Introdução

Streaming

Defina "stream": true e o mesmo endpoint devolve a resposta de forma incremental através de eventos enviados pelo servidor, em vez de esperar que tudo termine.

Porquê usar streaming

Um pedido sem streaming bloqueia até o modelo ter terminado de gerar toda a resposta, e só depois a devolve de uma vez. Para uma resposta curta, isso raramente se nota. Para uma mais longa, significa esperar vários segundos (por vezes mais) a olhar para o vazio antes de aparecer qualquer texto. O streaming resolve isto enviando a resposta peça a peça, à medida que o modelo a produz, para que um cliente possa começar a apresentar texto numa fração de segundo após o pedido sair, em vez de esperar pelo conjunto todo. É essa a diferença entre uma interface de chat que parece instantânea e uma que parece estar presa em cada mensagem. É opcional e não custa nada extra utilizá-lo.

Ativar o streaming

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

O Content-Type da resposta passa a ser text/event-stream em vez de application/json. Cada linha de evento tem o prefixo data: , e a ligação mantém-se aberta, enviando um evento por cada fragmento de conteúdo novo, até o stream terminar com uma linha literal data: [DONE].

O formato de um chunk

A maioria dos chunks transporta um pequeno fragmento de texto recém-gerado em 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 pela ordem, ao longo de todos os chunks, reconstrói o texto completo da resposta. Construir essa concatenação é tarefa do cliente; a API não envia o texto acumulado em nenhum momento, apenas o fragmento incremental que cada chunk acrescenta.

O chunk final

O último chunk com conteúdo transporta um delta vazio e um finish_reason real ("stop", ou "tool_calls" se o modelo estiver a pedir para chamar uma ferramenta, consulte Chamada de ferramentas):

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

O chunk de utilização

Depois do chunk final, é enviado mais um chunk com um array choices vazio e um objeto usage preenchido, com o mesmo formato do campo usage da resposta sem 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]

Um cliente que apenas se preocupa com o texto visível pode ignorar em segurança qualquer chunk com um array choices vazio; um cliente que queira mostrar a utilização de tokens ou o custo estimado depois de terminado deve procurar especificamente este chunk, em vez de assumir que o chunk final o transporta.

Ler um stream em código

# Python, usando o pacote oficial openai
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)

Os SDKs oficiais da OpenAI (Python e Node) já sabem interpretar este formato de eventos, uma vez que é o mesmo que a própria API deles usa; não é necessário nada específico da tAI no cliente, além de apontar base_url para https://api.artfical.com/v1, como abordado na página Autenticação.

Um stream termina sempre de forma limpa

Mesmo que algo corra mal a meio, a geração falha, um pedido expira internamente, seja qual for a causa, o stream continua a terminar com um sinal visível em vez de a ligação simplesmente cair sem explicação. Nesse caso verá um chunk de conteúdo com um pequeno aviso entre parênteses retos, um chunk final com "finish_reason": "stop", e depois [DONE], o mesmo final bem formado de um stream normal e bem-sucedido. Um cliente deve sempre tratar a chegada de [DONE] como o fim definitivo do turno, e não deve assumir que um stream que termina sem isso foi bem-sucedido; uma ligação que cai sem [DONE] significa tratar o pedido como falhado e tentar novamente, tal como faria para um pedido sem streaming que expirou.