~/tools / Ejecutar un LLM local en tu servidor / Ollama Stream Reader
Ollama Stream Reader — Une un stream de Ollama y mira su velocidad y motivo de parada
Pega una respuesta en streaming de Ollama, de /api/chat, /api/generate o del /v1/chat/completions compatible con OpenAI, y la herramienta vuelve a unir las partes en el texto completo, el thinking y las llamadas a herramientas. Muestra por qué se detuvo el modelo, a qué velocidad generó y procesó el prompt, y si el stream se cortó, y te da el mensaje del asistente para añadirlo a la siguiente solicitud. Nada sale de tu navegador.
Cómo guardar un stream con curl
-N desactiva el búfer de curl, y > stream.txt guarda el stream en un archivo. Sustituye el modelo y el mensaje por los tuyos.
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.txtLeído como un stream de /api/chat (un objeto JSON por línea).
Resumen
- Modelo
- qwen2.5:7b
- Motivo de parada
- stop
- Fragmentos
- 7
- Tokens generados
- 7
- Velocidad de generación
- 10.4 tokens/s
- Tokens del prompt
- 35
- Velocidad del prompt (tokens que no estaban en la caché)
- 64.1 tokens/s
- Tiempo de carga del modelo
- 4.923 s
- Tiempo total
- 6.310 s
- Del primer al último fragmento
- 0.675 s
Texto
Hello, nice to meet.
Mensaje del asistente para la siguiente solicitud
Añádelo a messages, seguido de los resultados de las llamadas a herramientas, si las hay.
{
"role": "assistant",
"content": "Hello, nice to meet."
}eval_count cuenta también los tokens de las llamadas a herramientas, que no se envían como texto. En nuestra prueba, una llamada a herramienta llegó en un solo fragmento con eval_count 20.
La documentación de Ollama dice que prompt_eval_duration cubre solo los tokens del prompt que no estaban en la caché. La velocidad del prompt de aquí divide solo esos tokens. Todas las duraciones están en nanosegundos; en la forma OpenAI, los timings están en milisegundos enteros.
En la forma compatible con OpenAI, los recuentos de tokens solo se envían con stream_options.include_usage, en un fragmento adicional antes de data: [DONE]. Si el stream se corta, ese fragmento no llega.
Formatos según la documentación de streaming y de uso de Ollama y su código fuente (v0.40.15), comprobados con streams reales de Ollama 0.40.11 el 2026-11-07. Ollama: Streaming
Todo se hace en tu navegador. La herramienta no se conecta a nada.
Ollama envía sus respuestas en streaming por defecto. /api/chat y /api/generate envían un objeto JSON por línea (newline-delimited JSON): cada línea lleva unos pocos caracteres de la respuesta, y la última línea tiene done en true y lleva los recuentos de tokens y las duraciones, en nanosegundos. El /v1/chat/completions compatible con OpenAI solo hace streaming cuando stream es true. Entonces envía server-sent events: líneas que empiezan por data:, un fragmento aparte con un delta vacío y el finish_reason, y data: [DONE] al final. Los recuentos de tokens llegan solo si la solicitud define stream_options.include_usage, en un fragmento adicional con una lista choices vacía, y Ollama le añade un objeto timings. Esta herramienta lee las tres formas, incluida la salida de curl -i con sus cabeceras HTTP, une content, thinking (reasoning en la forma OpenAI) y las llamadas a herramientas, y enumera lo que está mal: un stream sin línea done o sin [DONE] se cortó; una línea {"error": …} significa que Ollama se detuvo con un error después de haber empezado a enviar; done_reason length significa que se alcanzó num_predict o max_tokens. La velocidad de generación es eval_count dividido por eval_duration. Para el prompt, la documentación de Ollama dice que prompt_eval_duration cubre solo los tokens del prompt que no estaban en la caché, así que la herramienta divide solo esos tokens por ella. En la forma OpenAI, el timings.prompt_per_second de Ollama divide todos los tokens del prompt, incluidos los de la caché, por ese tiempo. En nuestra prueba indicó 360.8 tokens por segundo para un prompt en el que 34 de 35 tokens venían de la caché y el único token restante tardó 97 ms. Las llamadas a herramientas en la forma OpenAI pueden llegar en partes que comparten un index, así que la herramienta une los argumentos por index; Ollama en sí envía cada llamada a herramienta completa, en un solo fragmento. Comprobamos la herramienta con streams reales de Ollama 0.40.11 con qwen2.5:7b, y los formatos con la documentación y el código fuente de Ollama.
La lógica principal de esta herramienta es de código abierto, con licencia MIT. github.com/seigo5555/toolkitbox-lib/src/ollama-stream.ts
Casos de uso
- Ver la respuesta completa de una solicitud en streaming hecha con curl, en lugar de leerla pieza a pieza, una por línea
- Averiguar si un stream se cortó, se detuvo en el límite de longitud o terminó con un error
- Medir la velocidad de generación y de procesamiento del prompt de un modelo en tu máquina o servidor
Cómo usarlo
- Ejecuta tu solicitud con curl -sN y guarda la salida en un archivo, o copia lo que recibió tu programa.
- Pega el stream completo. La herramienta detecta si viene de /api/chat, /api/generate o /v1/chat/completions.
- Lee los problemas y las cifras, y copia el texto o el mensaje del asistente para la siguiente solicitud.
FAQ
¿Por qué no hay recuentos de tokens en mi stream de /v1/chat/completions?
En la forma compatible con OpenAI, los recuentos solo se envían cuando la solicitud define stream_options como {"include_usage": true}. Entonces llegan en un fragmento adicional con una lista choices vacía, justo antes de data: [DONE]. /api/chat y /api/generate siempre los ponen en la última línea.
¿Por qué la velocidad del prompt es tan distinta de timings.prompt_per_second?
La documentación de Ollama dice que prompt_eval_duration cubre solo los tokens del prompt que no estaban en la caché. El timings.prompt_per_second de Ollama divide todos los tokens del prompt, incluidos los de la caché, por ese tiempo, así que parece mucho más rápido cuando se usó la caché. La herramienta divide solo los tokens que no estaban en la caché.
El modelo llamó a una herramienta pero eval_count es 20. ¿Dónde están esos tokens?
El texto de una llamada a herramienta no se envía como content; Ollama lo convierte en tool_calls y lo envía en un solo fragmento. Los tokens se generan y se cuentan igualmente. En nuestra prueba, una llamada a herramienta con un argumento llegó en un solo fragmento con eval_count 20.
¿Por qué /api/chat dice stop cuando el modelo llamó a una herramienta?
/api/chat mantiene done_reason como stop. El endpoint compatible con OpenAI cambia stop por tool_calls en finish_reason cuando se envió una llamada a herramienta.
¿Qué debo hacer con el mensaje del asistente?
La documentación de Ollama señala que hay que unir las partes del stream para conservar el historial de la conversación, lo que importa sobre todo con las llamadas a herramientas. Añade el mensaje a messages, añade el resultado de cada llamada a herramienta como un mensaje con el rol tool y envía la siguiente solicitud.
¿Se envían mis datos a algún sitio?
No. El stream se lee en tu navegador. Los comandos curl son solo texto para que los ejecutes tú.
Artículos relacionados
- Vigilar la memoria de Ollama en un VPS pequeñoMira qué mantiene Ollama en memoria, cuánto tiempo y qué ajustes lo cambian: ollama ps, keep_alive y los límites, según las preguntas frecuentes oficiales.
- Conectar Dify con Ollama en tu propio VPSEjecuta Dify en tu propio VPS y usa Ollama como su modelo: instalación, los campos del plugin, el problema de la dirección en Docker y los embeddings, según la documentación oficial.
- Empieza con un LLM local sin un PC caro: guía para principiantes sobre cómo usar un VPS¿No tienes un PC potente? Alquila un VPS y ejecuta un LLM local pequeño desde el navegador: seis pasos, desde la estimación de memoria hasta una pantalla de chat protegida, con los límites explicados con honestidad.