Trả lời nhanh
Làm sao tôi stream một chat completion từ LLMwithCrypto?
Thêm "stream": true vào body của POST https://llmwithcrypto.com/api/v1/chat/completions. LLMwithCrypto sau đó trả lời bằng server-sent events: mỗi dòng data: chứa một chat.completion.chunk với một phần văn bản trong delta.content, và stream kết thúc bằng data: [DONE]. Thêm "stream_options": {"include_usage": true} để nhận số lượng token trong một chunk cuối. Điều này hoạt động trên mọi model, theo tài liệu ngày 23 tháng 10 năm 2026.
Tại sao lại stream?
Với con người, vì những từ đầu tiên xuất hiện ngay lập tức thay vì sau khi toàn bộ câu trả lời được viết xong. Một câu trả lời dài từ một model lớn có thể mất nhiều giây để hoàn tất; khi stream, người đọc bắt đầu đọc ngay.
Với chương trình thì ít quan trọng hơn: một script cần toàn bộ văn bản chẳng được gì từ streaming mà còn phải parse nhiều hơn. Hãy stream khi có người đang xem, và gửi một yêu cầu bình thường nếu không. Giá như nhau ở cả hai cách. Bạn trả tiền theo token từ số dư của mình: token đầu vào và đầu ra được đếm bằng tokenizer của chính model và tính theo giá của model đó trên 1M token. Một lần gọi kết thúc bằng lỗi thì không mất phí.
curl -sN "https://llmwithcrypto.com/api/v1/chat/completions" \
-H "Authorization: Bearer $LLMWITHCRYPTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4.1-flash",
"messages": [{"role": "user", "content": "Write a haiku about latency."}],
"stream": true,
"stream_options": {"include_usage": true},
"max_tokens": 120
}'
import os
from openai import OpenAI
client = OpenAI(
base_url="https://llmwithcrypto.com/api/v1",
api_key=os.environ["LLMWITHCRYPTO_API_KEY"],
)
stream = client.chat.completions.create(
model="deepseek-v4.1-flash",
messages=[{"role": "user", "content": "Write a haiku about latency."}],
stream=True,
stream_options={"include_usage": True},
max_tokens=120,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.usage:
print("\n", chunk.usage.prompt_tokens, "in,", chunk.usage.completion_tokens, "out")
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://llmwithcrypto.com/api/v1',
apiKey: process.env.LLMWITHCRYPTO_API_KEY,
});
const stream = await client.chat.completions.create({
model: 'deepseek-v4.1-flash',
messages: [{ role: 'user', content: 'Write a haiku about latency.' }],
stream: true,
stream_options: { include_usage: true },
max_tokens: 120,
});
for await (const chunk of stream) {
const text = chunk.choices[0]?.delta?.content;
if (text) process.stdout.write(text);
if (chunk.usage) console.log(`\n${chunk.usage.prompt_tokens} in, ${chunk.usage.completion_tokens} out`);
}
Stream trông thế nào trên đường truyền?
Mỗi event là một dòng bắt đầu bằng data: , theo sau là một dòng trống. Chunk đầu tiên thường mang role, các chunk tiếp theo vài ký tự của content mỗi chunk, và chunk có finish_reason kết thúc câu trả lời. Với include_usage, thêm một chunk nữa theo sau với mảng choices rỗng và object usage. Stream luôn kết thúc bằng data: [DONE]. Các id và số lượng bên dưới chỉ là minh họa.
data: {"id":"chatcmpl-5a1e","object":"chat.completion.chunk","created":1792742400,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
data: {"id":"chatcmpl-5a1e","object":"chat.completion.chunk","created":1792742400,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{"content":"Packets"},"finish_reason":null}]}
data: {"id":"chatcmpl-5a1e","object":"chat.completion.chunk","created":1792742400,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{"content":" cross the"},"finish_reason":null}]}
data: {"id":"chatcmpl-5a1e","object":"chat.completion.chunk","created":1792742400,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"id":"chatcmpl-5a1e","object":"chat.completion.chunk","created":1792742400,"model":"deepseek-v4.1-flash","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":19,"total_tokens":33}}
data: [DONE]
Nếu stream bị ngắt thì sao?
Lỗi phát hiện trước token đầu tiên, như khóa sai hoặc số dư rỗng, trả về dưới dạng lỗi HTTP bình thường với body JSON, không phải stream; trang errors liệt kê chúng. Lỗi trong lúc sinh kết thúc stream sớm, không có finish_reason.
Nếu bạn tự đóng kết nối, quá trình sinh dừng lại. Bạn vẫn trả tiền cho đầu vào và các token đã sinh, như với mọi lần gọi. Code của bạn nên coi một stream kết thúc mà không có finish_reason và không có [DONE] là chưa hoàn chỉnh, và gửi lại yêu cầu nếu cần toàn bộ câu trả lời.
Streaming: các câu hỏi thường gặp
Streaming có tốn thêm không?
Không. Cùng số token được tính cùng một giá. Bạn trả tiền theo token từ số dư của mình: token đầu vào và đầu ra được đếm bằng tokenizer của chính model và tính theo giá của model đó trên 1M token. Một lần gọi kết thúc bằng lỗi thì không mất phí.
Tôi có thể stream với tool calling không?
Có, trên những model hỗ trợ tools: tên hàm và các đối số đến thành từng mảnh trong delta.tool_calls và phải được ghép lại trước khi dùng. Trang tool calling hiển thị vòng lặp không stream, cách này đơn giản hơn để bắt đầu.
Tại sao tôi không nhận được usage trong một lần gọi streamed?
Thêm "stream_options": {"include_usage": true}. Không có nó, một stream không mang số lượng token; dashboard vẫn hiển thị chúng.