~/tools / Rodar um LLM local no seu servidor / Ollama Stream Reader

Ollama Stream Reader — Junte um stream do Ollama e veja sua velocidade e motivo de parada

Cole uma resposta em streaming do Ollama, de /api/chat, /api/generate ou do /v1/chat/completions compatível com a OpenAI, e a ferramenta junta as partes de volta no texto completo, no thinking e nas chamadas de ferramenta. Ela mostra por que o modelo parou, a que velocidade gerou e processou o prompt, e se o stream foi cortado, e entrega a mensagem do assistente para adicionar à próxima requisição. Nada sai do seu navegador.

Como salvar um stream com curl

-N desativa o buffer do curl, e > stream.txt salva o stream em um arquivo. Troque o modelo e a mensagem pelos seus.

curl -sN http://localhost:11434/api/chat -d '{"model":"qwen2.5:7b","messages":[{"role":"user","content":"Hello"}]}' > stream.txt

curl -sN http://localhost:11434/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"qwen2.5:7b","stream":true,"stream_options":{"include_usage":true},"messages":[{"role":"user","content":"Hello"}]}' > stream.txt

Lido como um stream de /api/chat (um objeto JSON por linha).

Resumo

Modelo
qwen2.5:7b
Motivo da parada
stop
Chunks
7
Tokens gerados
7
Velocidade de geração
10.4 tokens/s
Tokens do prompt
35
Velocidade do prompt (tokens que não estavam no cache)
64.1 tokens/s
Tempo de carga do modelo
4.923 s
Tempo total
6.310 s
Do primeiro ao último chunk
0.675 s

Texto

Hello, nice to meet.

Mensagem do assistente para a próxima requisição

Adicione-a a messages, seguida dos resultados das chamadas de ferramenta, se houver.

{
  "role": "assistant",
  "content": "Hello, nice to meet."
}

eval_count também conta os tokens das chamadas de ferramenta, que não são enviados como texto. No nosso teste, uma chamada de ferramenta chegou em um único chunk com eval_count 20.

A documentação do Ollama diz que prompt_eval_duration cobre apenas os tokens do prompt que não estavam no cache. A velocidade do prompt aqui divide apenas esses tokens. Todas as durações estão em nanossegundos; na forma OpenAI, os timings estão em milissegundos inteiros.

Na forma compatível com a OpenAI, as contagens de tokens só são enviadas com stream_options.include_usage, em um chunk extra antes de data: [DONE]. Se o stream for cortado, esse chunk não chega.

Formatos conforme a documentação de streaming e de uso do Ollama e seu código-fonte (v0.40.15), verificados com streams reais do Ollama 0.40.11 em 2026-11-07. Ollama: Streaming

Tudo é feito no seu navegador. A ferramenta não se conecta a nada.

O Ollama envia suas respostas em streaming por padrão. /api/chat e /api/generate enviam um objeto JSON por linha (newline-delimited JSON): cada linha traz alguns caracteres da resposta, e a última linha tem done como true e traz as contagens de tokens e as durações, em nanossegundos. O /v1/chat/completions compatível com a OpenAI só faz streaming quando stream é true. Ele então envia server-sent events: linhas que começam com data:, um chunk separado com um delta vazio e o finish_reason, e data: [DONE] no final. As contagens de tokens só vêm se a requisição define stream_options.include_usage, em um chunk extra com uma lista choices vazia, e o Ollama acrescenta a ele um objeto timings. Esta ferramenta lê as três formas, inclusive a saída de curl -i com seus cabeçalhos HTTP, junta content, thinking (reasoning na forma OpenAI) e as chamadas de ferramenta, e lista o que está errado: um stream sem linha done ou sem [DONE] foi cortado; uma linha {"error": …} significa que o Ollama parou com um erro depois de ter começado a enviar; done_reason length significa que num_predict ou max_tokens foi atingido. A velocidade de geração é eval_count dividido por eval_duration. Para o prompt, a documentação do Ollama diz que prompt_eval_duration cobre apenas os tokens do prompt que não estavam no cache, então a ferramenta divide apenas esses tokens por ela. Na forma OpenAI, o timings.prompt_per_second do Ollama divide todos os tokens do prompt, inclusive os do cache, por esse tempo. No nosso teste ele informou 360.8 tokens por segundo para um prompt em que 34 de 35 tokens vieram do cache e o único token restante levou 97 ms. As chamadas de ferramenta na forma OpenAI podem chegar em partes que compartilham um index, então a ferramenta junta os argumentos por index; o próprio Ollama envia cada chamada de ferramenta inteira, em um só chunk. Verificamos a ferramenta com streams reais do Ollama 0.40.11 com qwen2.5:7b, e os formatos com a documentação e o código-fonte do Ollama.

A lógica principal desta ferramenta é de código aberto, sob a licença MIT. github.com/seigo5555/toolkitbox-lib/src/ollama-stream.ts

Casos de uso

  • Ver a resposta inteira de uma requisição em streaming feita com curl, em vez de lê-la peça por peça, uma por linha
  • Descobrir se um stream foi cortado, parou no limite de tamanho ou terminou com um erro
  • Medir a velocidade de geração e de processamento do prompt de um modelo na sua máquina ou servidor

Como usar

  1. Execute sua requisição com curl -sN e salve a saída em um arquivo, ou copie o que seu programa recebeu.
  2. Cole o stream inteiro. A ferramenta detecta se ele vem de /api/chat, /api/generate ou /v1/chat/completions.
  3. Leia os problemas e os números, e copie o texto ou a mensagem do assistente para a próxima requisição.

FAQ

Por que não há contagens de tokens no meu stream de /v1/chat/completions?

Na forma compatível com a OpenAI, as contagens só são enviadas quando a requisição define stream_options como {"include_usage": true}. Elas então vêm em um chunk extra com uma lista choices vazia, logo antes de data: [DONE]. /api/chat e /api/generate sempre as colocam na última linha.

Por que a velocidade do prompt é tão diferente de timings.prompt_per_second?

A documentação do Ollama diz que prompt_eval_duration cobre apenas os tokens do prompt que não estavam no cache. O timings.prompt_per_second do Ollama divide todos os tokens do prompt, inclusive os do cache, por esse tempo, então parece muito mais rápido quando o cache foi usado. A ferramenta divide apenas os tokens que não estavam no cache.

O modelo chamou uma ferramenta, mas eval_count é 20. Onde estão esses tokens?

O texto de uma chamada de ferramenta não é enviado como content; o Ollama o transforma em tool_calls e o envia em um só chunk. Os tokens são gerados e contados do mesmo jeito. No nosso teste, uma chamada de ferramenta com um argumento chegou em um único chunk com eval_count 20.

Por que /api/chat diz stop quando o modelo chamou uma ferramenta?

/api/chat mantém done_reason como stop. O endpoint compatível com a OpenAI troca stop por tool_calls em finish_reason quando uma chamada de ferramenta foi enviada.

O que devo fazer com a mensagem do assistente?

A documentação do Ollama observa que é preciso juntar as partes do stream para manter o histórico da conversa, o que importa principalmente para as chamadas de ferramenta. Adicione a mensagem a messages, adicione o resultado de cada chamada de ferramenta como uma mensagem com o papel tool e envie a próxima requisição.

Meus dados são enviados para algum lugar?

Não. O stream é lido no seu navegador. Os comandos curl são apenas texto para você executar.

Artigos relacionados

Relacionados