Powrót do bloga

AI dla początkującychPrzewodnik

Dlaczego odpowiedź AI urywa się w połowie zdania? max_tokens, okno kontekstu i finish_reason wyjaśnione

Odpowiedź AI, która urywa się w połowie zdania, trafiła na limit. Przeczytaj finish_reason, odróżnij max_tokens od pełnego okna kontekstu i sprawdź limit wyjścia każdego modelu.

Autor: CheapTokens TeamOpublikowano Zaktualizowano 6 min czytania

Ciemna okładka z logo cheaptokens: słowa max_tokens, finish_reason i length w ramkach oraz nagłówek „Answer cut off mid-sentence?”
Na tej stronie
  1. Trzy limity, które ucinają odpowiedź
  2. Najpierw przeczytaj finish_reason
  3. Poprawka 1: zwiększ max_tokens
  4. Poprawka 2: gdy okno kontekstu jest pełne
  5. Poprawka 3: uzyskaj długą odpowiedź w częściach
  6. Gdy finish_reason to stop
  7. Wybór modelu według długości odpowiedzi

Odpowiedź, która urywa się w połowie zdania, prawie zawsze została ucięta przez limit. Model nie zgubił wątku — w żądaniu zabrakło miejsca. Odpowiedź mówi, który to limit: przeczytaj finish_reason. length oznacza, że trafiono na limit. stop oznacza, że model zakończył samodzielnie.

O tym, jak długa może być odpowiedź, decydują trzy rzeczy. Gdy już wiesz, która z nich cię ograniczyła, poprawka zajmuje minutę.

Trzy limity, które ucinają odpowiedź#

  • max_tokens to limit, który ustawiasz w żądaniu. Gdy odpowiedź go osiągnie, generowanie się zatrzymuje, nawet w połowie słowa. Dokumentacja API DeepSeek definiuje go jako maksymalną liczbę tokenów wygenerowanych w uzupełnieniu.
  • Limit wyjścia modelu to pułap dla pojedynczej odpowiedzi danego modelu. Należy do modelu, więc trzymaj max_tokens na tym poziomie lub poniżej. Liczby dla naszych modeli są w tabeli poniżej.
  • Okno kontekstu to miejsce na całą wymianę: twoje wejście i odpowiedź razem. Dokumentacja DeepSeek mówi, że tokeny wejściowe i wygenerowane razem są ograniczone długością kontekstu modelu.

Jeśli tokeny to wciąż mgliste pojęcie, zacznij od What is a token in AI?. Ta strona zakłada, że wiesz, czym jest token.

Najpierw przeczytaj finish_reason#

Każdy wybór w odpowiedzi czatu ma pole finish_reason. Obok niego usage mówi, ile tokenów weszło i wyszło.

Oto jak wygląda ucięta odpowiedź obok ukończonej. Żądanie pytało „In one short sentence, what is a token?”, najpierw z max_tokens ustawionym na 16, potem na 200.

Przykład poglądowy, nie zarejestrowana odpowiedź: twoje liczby i dodatkowe pola będą inne.

json
{
  "choices": [
    {
      "message": { "role": "assistant", "content": "A token is a small piece of text that a model reads and writes, usu" },
      "finish_reason": "length"
    }
  ],
  "usage": { "prompt_tokens": 21, "completion_tokens": 16, "total_tokens": 37 }
}
json
{
  "choices": [
    {
      "message": { "role": "assistant", "content": "A token is a small piece of text that a model reads and writes, usually a word or part of a word." },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 21, "completion_tokens": 24, "total_tokens": 45 }
}

W pierwszej odpowiedzi completion_tokens wynosi 16, dokładnie tyle, ile limit, a tekst kończy się na „usu”. W drugiej model zatrzymał się na 24 tokenach, znacznie poniżej limitu 200, bo skończył.

Aby ustalić, co się stało, przejdź przez to po kolei:

  1. Spójrz na finish_reason. Jeśli to stop, odpowiedź jest kompletna. Model zdecydował się zakończyć albo trafił na ustawioną przez ciebie sekwencję stopu. Jeśli to length, limit uciął odpowiedź, a następny krok powie ci który. Istnieją inne wartości, takie jak content_filter i tool_calls; żadna z nich nie jest problemem z długością.
  2. Porównaj completion_tokens z max_tokens, które wysłałeś. Jeśli są równe lub prawie równe, trafiłeś na max_tokens.
  3. Jeśli completion_tokens jest znacznie poniżej max_tokens, a prompt_tokens jest duże, prawdopodobnie zapełniło się okno kontekstu. Dokumentacja DeepSeek używa length w obu przypadkach, więc samo pole nie pozwala ich rozróżnić; porównanie z kroku 2 mówi, który to przypadek. Dokumentacja Anthropic i Z.ai nazywa drugi przypadek osobno, jako model_context_window_exceeded. Spójrz na pole we własnych odpowiedziach, aby zobaczyć, jaką nazwę dostajesz.

Wszystkie trzy opisy pochodzą z dokumentacji deweloperów, sprawdzonej 20 października 2026: DeepSeek, Anthropic i Z.ai.

Co widzisz finish_reason Przyczyna Co zrobić
Ucięte, completion_tokens równa się max_tokens length Osiągnięto max_tokens Zwiększ max_tokens albo poproś o odpowiedź w częściach
Ucięte, completion_tokens znacznie poniżej max_tokens, długie wejście length (lub model_context_window_exceeded w niektórych API) Okno kontekstu pełne Skróć wejście lub historię albo wybierz model z większym oknem
Kompletne, ale krótsze, niż chciałeś stop Model skończył albo zadziałała sekwencja stopu Poproś o więcej szczegółów; sprawdź parametr stop
Brak tekstu lub odmowa content_filter Odpowiedź została odfiltrowana Przeformułuj żądanie
Brak tekstu, zamiast tego żądanie narzędzia tool_calls Model chce wywołać narzędzie Uruchom narzędzie i odeślij wynik

Poprawka 1: zwiększ max_tokens#

Najczęstsza przyczyna jest też najłatwiejsza do naprawienia. Ustaw max_tokens sam, żeby wiedzieć, który limit obowiązuje. Nie licz na wartość domyślną.

python
from openai import OpenAI

client = OpenAI(base_url="https://api.cheaptokens.dev/v1", api_key="YOUR_API_KEY")

resp = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": "Write a detailed guide to setting up a home network."}],
    max_tokens=16000,  # example value: stay at or below the model's output limit
)

choice = resp.choices[0]
print(choice.finish_reason, resp.usage.completion_tokens)

To pokazuje kształt wywołania. Klucz wstawia się tutaj jako YOUR_API_KEY; prawdziwy klucz trzymaj poza udostępnianym kodem.

Zwiększanie liczby pomaga tylko do limitu samego modelu. Oto limity w CheapTokens, sprawdzone 20 października 2026 na liście modeli CheapTokens:

Model ID modelu Maks. wyjście na odpowiedź Kontekst
DeepSeek-V4-Flash (0731) deepseek-ai/DeepSeek-V4-Flash-0731 32 768 tokenów 380K
GLM-5.3-Flash zai-org/GLM-5.3-Flash 8 192 tokeny 390K
MiniMax-M2.7 MiniMaxAI/MiniMax-M2.7 8 192 tokeny 200K

Deweloperzy publikują własne limity dla swoich API. Z.ai na przykład podaje do 128K wyjścia dla serii GLM-5. To nie są limity GLM-5.3-Flash w CheapTokens, które wynoszą 8 192 tokeny na odpowiedź. Dla wszystkiego, co budujesz na CheapTokens, używaj tabeli powyżej.

Poprawka 2: gdy okno kontekstu jest pełne#

W czacie cała historia jest wysyłana ponownie z każdą wiadomością, więc wejście rośnie z każdą turą. Okno kontekstu musi pomieścić tę historię plus nową odpowiedź. Jeśli sama historia zajmuje prawie całe okno, na odpowiedź prawie nie zostaje miejsca.

Te okna są duże i jedno krótkie pytanie ich nie zapełni. Długie czaty i wklejone dokumenty tak. Co pomaga:

  • Rozpocznij nowy czat dla nowego zadania zamiast kontynuować stary.
  • Poproś model o podsumowanie dotychczasowej rozmowy i przenoś dalej tylko podsumowanie.
  • Wytnij stare wiadomości i załączniki, których już nie potrzebujesz.
  • Jeśli samo wejście jest ogromne, wybierz model z największym oknem. Wśród naszych to GLM-5.3-Flash z 390K. Jego limit wyjścia to 8 192 tokeny, więc poproś o długi wynik w częściach.

Poprawka 3: uzyskaj długą odpowiedź w częściach#

Gdy odpowiedź, której chcesz, jest dłuższa niż limit wyjścia modelu, żadne ustawienie nie zmieści jej w jednej odpowiedzi. Poproś o nią w kawałkach: gdy finish_reason to length, odeślij częściową odpowiedź i poproś model o kontynuację.

python
messages = [{"role": "user", "content": "Write a detailed guide to setting up a home network."}]
parts = []

for _ in range(4):  # example limit: at most 4 rounds
    resp = client.chat.completions.create(
        model="zai-org/GLM-5.3-Flash",
        messages=messages,
        max_tokens=8000,  # example value: below this model's output limit
    )
    choice = resp.choices[0]
    parts.append(choice.message.content)
    if choice.finish_reason != "length":
        break
    messages.append({"role": "assistant", "content": choice.message.content})
    messages.append({"role": "user", "content": "Continue exactly where you stopped. Don't repeat anything."})

text = "".join(parts)

Ta sama uwaga: to przykład wzorca, nie zarejestrowane uruchomienie. Czytaj szwy między częściami. Model czasem powtarza zdanie albo zaczyna listę od nowa na łączeniu.

Każda runda ponownie wysyła wszystko dotychczasowe jako wejście, a każdy token wyjścia jest rozliczany. Długa odpowiedź kosztuje więcej niż krótka. Oto odpowiedź na osiem tysięcy tokenów przy 2 000 tokenów wejścia, co mieści się w każdym modelu z tabeli:

Model Koszt OpenRouter
GLM-5.3-Flash $0.00036 $0.00069
DeepSeek-V4-Flash $0.00083 $0.0013
MiniMax-M2.7 $0.0013 $0.0102

2000 tokenów wejściowych i 8000 tokenów wyjściowych łącznie. Ceny za 1 mln tokenów są aktualne i zmieniają się wraz z naszymi taryfami; kolumna OpenRouter pokazuje ceny referencyjne dla tego samego obciążenia.

Gdy finish_reason to stop#

stop oznacza, że model zakończył odpowiedź. Jeśli skończył wcześniej, niż chciałeś, to nie jest problem z limitem i większe max_tokens niczego nie zmieni. Powiedz, czego chcesz: długości, sekcji, poziomu szczegółowości. Sprawdź też, czy żądanie ustawia parametr stop; sekwencja stopu, która pojawi się w odpowiedzi, kończy ją na miejscu.

Wybór modelu według długości odpowiedzi#

Zacznij od odpowiedzi, której potrzebujesz. Jeśli mieści się w 8 192 tokenach, MiniMax-M2.7 (MiniMaxAI/MiniMax-M2.7) obsłuży ją w CheapTokens. Jego wyjście jest tańsze niż cena referencyjna OpenRouter i jest rozliczane po $0.15 (za 1M tokenów wyjścia). Cena jest taka sama o każdej porze, nie ma godzin szczytu, a API jest zgodne z OpenAI i Anthropic.

Oto aktualny cennik dla każdego modelu:

Model Kontekst Wejście $/1M Wyjście $/1M OpenRouter wejście OpenRouter wyjście
GLM-5.3-Flash reasoning 390K $0.02 $0.04 $0.0413 $0.0758
DeepSeek-V4-Flash 380K $0.015 $0.10 $0.0475 $0.1568
MiniMax-M2.7 180K $0.05 $0.15 $0.30 $1.20

Ceny w USD za 1 mln tokenów. Dane OpenRouter służą do porównania i mogą ulec zmianie.

Jeśli jeszcze nie wysłałeś żądania, Your first API request with CheapTokens przeprowadzi cię przez to. Czym jest token i dlaczego wejście i wyjście są liczone osobno, opisuje What is a token in AI?.

Punkty końcowe, identyfikatory modeli i limity dla każdego modelu są w CheapTokens docs.