Pemecahan masalahPanduan
Jawaban AI terpotong? Perbaiki finish_reason "length" dan max_tokens
Jawaban API Anda berhenti di tengah kalimat atau mengembalikan JSON rusak? Periksa finish_reason, naikkan max_tokens dalam batas dan tambahkan langkah continue.

Di halaman ini
Skrip Anda berjalan, model menjawab, dan fungsi berakhir di tengah baris. Atau parser JSON melempar error pada balasan yang terlihat normal. Paling sering modelnya tidak gagal: ia mencapai batas max_tokens yang Anda set (atau default yang tidak pernah Anda lihat) dan API menghentikannya di tengah kata.
Perbaikan cepatnya: baca finish_reason di respons. Jika nilainya "length" (API kompatibel OpenAI) atau stop_reason bernilai "max_tokens" (Anthropic Messages), jawabannya terpotong. Naikkan max_tokens hingga batas output model, atau minta model melanjutkan. Sisa halaman ini menunjukkan keduanya dalam kode yang bisa Anda tempel.
Jika Anda ingin versi bahasa sederhana tentang mengapa ini terjadi, mulai dari mengapa jawaban AI berhenti di tengah kalimat. Halaman ini adalah versi debugging.
Bagaimana jawaban terpotong terlihat di layar#
Gejalanya berbeda tergantung apa yang Anda minta, tetapi penyebabnya sama. Coba cocokkan ini dengan yang pernah Anda lihat:
Cocokkan pasangan
Cocokkan gejala dengan penyebab yang mungkin
Ketuk item di kiri, lalu pasangannya
- Sebuah fungsi berakhir dengan
return resuJawaban kode mencapai max_tokens di tengah baris json.loadsgagal dengan "Unterminated string" atau "Expecting ',' delimiter"JSON terpotong di tengah- Terjemahan berhenti setelah paruh pertama teksBatas output lebih kecil dari terjemahannya
- Balasan lengkap dan field-nya bernilai
stopModel selesai sendiri; cari di tempat lain
Baris terakhir itu penting. Jika finish_reason bernilai stop, batas bukan masalah Anda, dan menaikkan max_tokens tidak akan mengubah apa pun.
Langkah 1: baca field yang memberi tahu Anda#
Setiap respons menyatakan mengapa generasi berakhir. Dalam respons kompatibel OpenAI field-nya adalah choices[0].: "stop" saat model selesai, "length" saat tokennya habis. Di Anthropic Messages API field-nya adalah stop_reason, dan nilai terpotongnya adalah "max_tokens". Panduan stop-reason Anthropic (diperiksa 28 Oktober 2026) merekomendasikan tepat dua perbaikan di bawah ini: naikkan max_tokens atau lanjutkan respons.
Berikut pemeriksaan yang sama dalam tiga bentuk. Base URL-nya adalah https:/ untuk OpenAI SDK dan https:/ (tanpa /v1) untuk Anthropic SDK. Nilai max_tokens=200 sengaja dibuat kecil, agar Anda bisa melihat pemotongannya sendiri.
Satu pemeriksaan, tiga cara
Python (OpenAI SDK)
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.cheaptokens.dev/v1",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
resp = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash-0731",
max_tokens=200,
messages=[{"role": "user", "content": "Write a Python class for a todo list with tests."}],
)
choice = resp.choices[0]
if choice.finish_reason == "length":
print("Cut off at the token limit")
print(choice.message.content)
print(resp.usage.completion_tokens)Python (Anthropic SDK)
import os
import anthropic
client = anthropic.Anthropic(
base_url="https://api.cheaptokens.dev",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
msg = client.messages.create(
model="deepseek-ai/DeepSeek-V4-Flash-0731",
max_tokens=200,
messages=[{"role": "user", "content": "Write a Python class for a todo list with tests."}],
)
if msg.stop_reason == "max_tokens":
print("Cut off at the token limit")
print(msg.content[0].text)curl
curl https://api.cheaptokens.dev/v1/chat/completions \
-H "Authorization: Bearer $CHEAPTOKENS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-ai/DeepSeek-V4-Flash-0731",
"max_tokens": 200,
"messages": [{"role": "user", "content": "Write a Python class for a todo list with tests."}]
}'Cari "finish_ di JSON yang kembali.
Saat berfungsi sebagai diagnosis, Anda akan melihat pasangan ini: batas rendah menghasilkan length, batas lapang menghasilkan stop.

Langkah 2: naikkan max_tokens, tetapi jangan melewati batas atas#
Perbaikan yang jelas adalah angka yang lebih besar. Jebakannya: setiap model punya batas atasnya sendiri untuk jawaban. Jangan set nilai di atasnya: batasnya per model, jadi periksa tabel di bawah dulu. Ini adalah batas per jawaban di CheapTokens (fakta diperiksa 28 Oktober 2026):
Gulir tabel ke kanan →
| Model | Output maks per jawaban | Konteks |
|---|---|---|
| DeepSeek-V4-Flash | 32.768 token | 380K |
| GLM-5.3-Flash | 8.192 token | 390K |
| MiniMax-M2.7 | 8.192 token | 180K |
Terjemahan 9.000 token membutuhkan model dengan batas per jawaban yang lebih besar — DeepSeek-V4-Flash menerima hingga 32.768 token per jawaban. Untuk kode panjang, JSON panjang, atau satu dokumen utuh, deepseek- punya ruang paling banyak: hingga 32.768 token per jawaban, satu harga di jam berapa pun. Ambil id model persisnya dari dokumentasi CheapTokens dan halaman model, karena penyedia menamainya berbeda-beda.
Aturan praktis: set max_tokens ke jawaban terpanjang yang mau Anda terima, bukan ke maksimum. Anda membayar token yang benar-benar ditulis model, jadi batas atas yang tinggi tidak memakan biaya saat jawabannya pendek.
Langkah 3: JSON yang berhenti di tengah#
Balasan JSON yang terpotong adalah kasus terburuk, karena teksnya terlihat benar sampai parser mencapai akhir. Misalnya Anda mengekstrak field dari 40 invoice dalam satu panggilan dan meminta sebuah array. Model menulis 31 objek, mencapai batas, dan array tidak pernah ditutup.

Jangan mencoba memperbaiki string dengan menambahkan ]}. Anda akan mendapat JSON valid dengan record yang hilang, yang lebih buruk daripada error. Periksa finish_reason dulu; jika nilainya length, naikkan batas dan jalankan ulang panggilan, atau pecah input menjadi batch lebih kecil. Untuk memaksa formatnya sendiri, lihat JSON valid dari API LLM.
Langkah 4: biarkan model melanjutkan#
Kadang jawabannya memang lebih panjang dari batas mana pun: satu bab buku, refactor besar. Maka umpankan kembali apa yang sudah Anda punya dan minta model melanjutkan. Loop di bawah menyimpan teks yang sudah ada, meminta sisanya, dan berhenti setelah beberapa putaran agar bug tidak berputar selamanya.
def complete(base_messages, model, max_tokens=4096, rounds=4):
text = ""
for _ in range(rounds):
messages = list(base_messages)
if text:
messages += [
{"role": "assistant", "content": text},
{"role": "user", "content": "Continue exactly where you stopped. Do not repeat anything."},
]
r = client.chat.completions.create(model=model, max_tokens=max_tokens, messages=messages)
choice = r.choices[0]
text += choice.message.content or ""
if choice.finish_reason != "length":
return text, True # finished on its own
return text, False # still cut after all roundsDua kebiasaan menjaga ini tetap jujur. Kembalikan flag True/False dan tampilkan peringatan ke pengguna pada False, alih-alih menyajikan setengah dokumen sebagai selesai. Dan ingat bahwa setiap putaran mengirim ulang teks sebelumnya sebagai input, jadi jawaban yang dilanjutkan lebih mahal daripada satu jawaban besar. Untuk data terstruktur, utamakan batas lebih besar atau batch lebih kecil daripada melanjutkan.
Berapa biaya jawaban panjang#
Misalkan jawaban panjang adalah 2.000 token masuk dan 8.000 token keluar. Di DeepSeek-V4-Flash permintaan itu berbiaya $0.00083 dengan harga hari ini, dan secara total, dengan input dan output dihitung bersama, lebih murah daripada OpenRouter. Ubah angkanya ke beban Anda sendiri:
Kalkulator biaya
Sehari 50 jawaban panjang
Token input per permintaan: 2.000 · Token output per permintaan: 8.000 · Permintaan per hari: 50
| Model | Per hari | Per bulan |
|---|---|---|
| GLM-5.3-Flash$0.02$0.04 | $0.018 | $0.54 |
| DeepSeek-V4-Flash$0.015$0.10 | $0.0415 | $1.25 |
| MiniMax-M2.7$0.05$0.15 | $0.065 | $1.95 |
Kesimpulannya: sisi output mendominasi dalam skenario ini, jadi ruang cadangan di max_tokens adalah asuransi murah terhadap pengulangan. Jawaban terpotong yang harus Anda regenerasi dibayar dua kali. Latar belakang tentang dua sisi tagihan ada di token input vs output, dan daftar model lengkap dengan harga ada di halaman harga.
Sebelum rilis: checklist singkat#
Daftar periksa
Checklist pemotongan untuk kode Anda



