Bumalik sa blog

Pag-optimize ng gastosGabay

I-trim ang chat history para bawasan ang gastos: sliding window o buod

Limitahan ang ipinapadala mong muli sa bawat turn: panatilihin ang huling ilang mensahe o isang maikling buod. Token math para sa 50-turn na chat at isang Python helper.

Ni CheapTokens TeamNai-publish noong 7 min na pagbabasa

Cover: panatilihing mura ang mahabang chat, gamit ang trim_history helper
Sa pahinang ito
  1. Ano ang aktwal na ipinapadala sa turn 50
  2. Opsyon 1: isang sliding window
  3. Opsyon 2: isang buod ng lumang mga turn
  4. Magkano ang tatlong setup
  5. Alin ang pipiliin

Ang iyong support bot ay nakikipag-chat na nang 50 turn, at bawat bagong mensahe ay mas mahal kaysa sa nauna. Walang natatandaan ang API, kaya ipinapadala muli ng iyong code ang buong usapan sa bawat pagkakataon. Ang solusyon ay limitahan ang ipinapadala mo: panatilihin ang system prompt at ang huling ilang turn (isang sliding window), o palitan ang lumang mga turn ng maikling buod. Nasa ibaba ang aritmetika para sa 50-turn na chat at isang helper na maaari mong kopyahin.

Ang multi-round chat guide ng DeepSeek (api-docs.deepseek.com, sinuri noong 1 Nobyembre 2026) ay malinaw na nagsasabi: hindi itinatala ng server ang konteksto ng mga naunang request, kaya ipinapadala ng client ang buong listahan ng messages sa bawat tawag. Ganoon din ang OpenAI-compatible na format sa CheapTokens. Kung bago ito sa iyo, magsimula sa bakit mas mahal ang mahabang chat at paano gumagana ang messages array.

Ano ang aktwal na ipinapadala sa turn 50#

Sabihin nating may support bot ka na may 400-token na system prompt. Sa karaniwang turn, sumusulat ang user ng mga 60 token at sumasagot ang bot ng mga 190. Isang buong turn ang nagdadagdag ng 250 token sa history. Mga palagay lang iyon: palitan mo ng mga numero mula sa usage field ng sarili mong mga response.

Sa turn 50, dala ng request ang system prompt, 49 na naunang turn at ang bagong mensahe: 400 + 49 × 250 + 60 = 12,710 input token, para makakuha ng 190-token na sagot. Pagsamahin ang buong chat. Ang system prompt at ang bagong mensahe ay ipinapadala sa bawat pagkakataon: 50 × 460 = 23,000. Ang paulit-ulit na history ay nagdadagdag ng 250 × 1,225 = 306,250. Sama-sama: 23,000 + 306,250 = 329,250 input token, laban sa 50 × 190 = 9,500 output token.

Ang history sa bawat request ay lumalaki ng isang turn, kaya ang kabuuan ay lumalaki ayon sa parisukat ng haba ng chat. Mula 50 hanggang 100 turn at ang bahaging paulit-ulit na history ay halos apat na beses na lumalaki.

Subukan mo mismoSubukan: kung ipinadala mo lamang ang system prompt, ang huling 4 na turn at ang bagong mensahe, ilang input token ang dala ng turn 50?Ipakita ang sagot

1,460 (400 + 4 × 250 + 60), laban sa 12,710 kapag buong history. Parehong tanong, parehong haba ng sagot, maliit na bahagi lang ng input.

Opsyon 1: isang sliding window#

Ang ideya: palaging ipadala ang system prompt, itapon ang lahat maliban sa huling N turn. Itatago mo ang buong history sa sarili mong storage at i-trim lamang ang kopyang ipinapadala mo.

python
def trim_history(messages, keep_pairs=4):
    """System prompt + the last keep_pairs turns + the new user message."""
    system = [m for m in messages if m["role"] == "system"]
    rest = [m for m in messages if m["role"] != "system"]
    return system + rest[-(keep_pairs * 2 + 1):]

Tawagin ito pagkatapos mong idagdag ang bagong mensahe ng user. Sa keep_pairs=4, iyon ay 4 na user/assistant pair kasama ang bagong mensahe, 9 na mensahe, at ang slice ay laging nagsisimula sa isang user message. Narito ito na naka-wire sa isang tunay na tawag:

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
MODEL = "deepseek-ai/DeepSeek-V4-Flash-0731"

history = [{"role": "system", "content": "You are a concise support assistant."}]

def ask(text):
    history.append({"role": "user", "content": text})
    resp = client.chat.completions.create(
        model=MODEL,
        messages=trim_history(history),
        max_tokens=500,
    )
    answer = resp.choices[0].message.content
    history.append({"role": "assistant", "content": answer})
    print(resp.usage.prompt_tokens, resp.usage.completion_tokens)
    return answer

Ang print na linya ang kapaki-pakinabang: panoorin ang unang numero. Kung walang trimming, umaakyat ito sa bawat turn. Sa window, tumitigil itong lumaki kapag nalampasan na ng chat ang turn 4.

Python helper trim_history: system prompt, huling 4 na turn, bagong mensahe
Ang trimming helper mula sa artikulong ito

Sa mga numero: mula turn 5 pataas, ang bawat request ay 400 + 4 × 250 + 60 = 1,460 input token. Ang unang apat na turn ay normal pa ring lumalaki at umaabot sa 3,340. Ang buong chat: 3,340 + 46 × 1,460 = 70,500 input token, mga ikalimang bahagi ng 329,250 na ipinapadala mo kapag buong history. Nananatiling 50 × 190 = 9,500 ang output.

Turn 50 request: buong history laban sa window na 4 na turn
Mga token part ng turn-50 request, ayon sa mga palagay sa itaas

Sa code, ang buong pagbabago ay isang argumento sa tawag:

Ihambing

Ang one-line na pagbabago

Bago

python
messages=history

Pagkatapos

python
messages=trim_history(history)

Ang problema: nakakalimot ang window. Kung magtanong ang user sa turn 40 ng "ano ang order number ko?" at ang numero ay nasa turn 3, hindi pa ito nakita ng modelo. Dalawang murang solusyon. Kunin ang mga stable na fact (pangalan, order number, plan) mula sa chat sa sarili mong code at idagdag ang mga ito sa system prompt, kung saan hindi kailanman pinuputol ng window. O magdagdag ng buod, na siyang susunod na opsyon.

Opsyon 2: isang buod ng lumang mga turn#

Sa halip na itapon ang lumang mga turn, kinokompress mo ang mga ito. Tuwing ilang turn, ipadala ang mga turn na kalalabas lang ng window, kasama ang kasalukuyang buod, sa modelo at humingi ng bago at maikling buod. Pagkatapos, ilagay ang buod na iyon sa system message.

python
def summarize(summary, old_messages):
    transcript = "\n".join(f"{m['role']}: {m['content']}" for m in old_messages)
    prompt = (
        f"Summary so far:\n{summary}\n\nNew turns:\n{transcript}\n\n"
        "Rewrite the summary in under 200 words. "
        "Keep names, numbers, decisions and open questions."
    )
    resp = client.chat.completions.create(
        model=MODEL,
        messages=[{"role": "user", "content": prompt}],
        max_tokens=400,
    )
    return resp.choices[0].message.content

def build_messages(history, summary, keep_pairs=4):
    system = history[0]["content"]
    if summary:
        system += "\n\nEarlier in this chat: " + summary
    recent = history[1:][-(keep_pairs * 2 + 1):]
    return [{"role": "system", "content": system}] + recent

Hindi libre ang buod: ito ay karagdagang tawag sa modelo. Ipagpalagay na ang buod ay mga 300 token, nire-refresh tuwing 5 turn (9 na beses sa 50 turn), bawat refresh ay nagbabasa ng mga 1,600 token (ang lumang buod kasama ang limang turn at ang instruction) at nagsusulat ng 300. Para manatili sa ligtas na panig, bilangin ang buod sa bawat request mula turn 5 pataas (sa totoo lang lumalabas ito pagkatapos ng unang refresh, kaya bahagyang overestimate ito): 400 + 300 + 4 × 250 + 60 = 1,760 input token.

Mga kabuuan para sa chat: pangunahing mga request 3,340 + 46 × 1,760 = 84,300 input token, mga tawag sa buod 9 × 1,600 = 14,400 input at 9 × 300 = 2,700 output. Sa kabuuan 84,300 + 14,400 = 98,700 input at 9,500 + 2,700 = 12,200 output token.

Ang buod ay mas mahal nang kaunti kaysa sa bare na window, at bilang kapalit, alam pa rin ng modelo ang nangyari sa turn 3.

Magkano ang tatlong setup#

Narito ang parehong 50-turn na chat sa DeepSeek-V4-Flash, na naka-price live mula sa mga kabuuan sa itaas:

Isang 50-turn na chat sa DeepSeek-V4-Flash
  • Buong history (329,250 in, 9,500 out)$0.0059
  • Window kasama ang buod (98,700 in, 12,200 out)$0.0027
  • Sliding window, 4 na turn (70,500 in, 9,500 out)$0.002

Ang mga presyo ay mula sa live na price list, kaya nag-a-update ang mga numero kapag nagbago ang taripa. Hindi magbabago ang pagkakasunod-sunod: pinakamaliit ang ipinapadala ng window, nasa gitna ang buod, pinakamahal ang buong history.

Para sa chat na tulad nito, ang CheapTokens model na dapat simulan ay DeepSeek-V4-Flash. Mayroon itong 380K context window (kasya ang 50-turn na chat kahit hindi trimmed), hanggang 32,768 output token bawat sagot, isang fixed na presyo sa kahit anong oras ng araw, at sa kabuuan, kapag pinagsama ang input at output, mas mura ito kaysa sa OpenRouter. Ang model id ay deepseek-ai/DeepSeek-V4-Flash-0731. Kung gusto mong ihambing ang mga modelo sa window setup (1,410 input token bawat request sa average, 190 output, 50 request), narito ang live na table:

Modelo Bawat kahilingan 50 mga kahilingan OpenRouter, 50 mga kahilingan
GLM-5.3-Flash $0.000036 $0.0018 $0.0032
DeepSeek-V4-Flash $0.00004 $0.002 $0.0063
MiniMax-M2.7 $0.000099 $0.005 $0.0594

1,410 input at 190 output na token bawat kahilingan. Ang mga presyo kada 1M token ay kasalukuyan at nagbabago kasabay ng aming mga taripa; ang column ng OpenRouter ay nagpapakita ng reference na presyo para sa parehong workload.

Ang GLM-5.3-Flash ay may 390K context at ang MiniMax-M2.7 ay may 180K, na sapat para sa trimmed na chat. Ang kasalukuyang mga presyo ay nasa pricing page, at ipinapakita ng docs kung paano ipadala ang unang request.

Alin ang pipiliin#

Ang window ang default: tatlong linya ng code, walang karagdagang tawag, walang karagdagang failure mode. Gamitin ito para sa support bots, tutors at role-play, kung saan ang huling ilang turn ang nagdadala ng usapan at ang system prompt ang nagdadala ng mga patakaran. Idagdag ang buod kapag bumabalik ang mga user sa mga bagay na sinabi matagal na, tulad ng sa isang personal assistant na may isang walang katapusang usapan. Panatilihing sapat na maliit ang window para makita pa rin ng modelo ang agarang konteksto, at sapat na malaki para magkasya ang isang buong question-and-answer exchange. Gaano karami ang kasya sa lahat ay hiwalay na limitasyon, na tinalakay sa ano ang context window.

Mabilisang pagsusuri

Nagtanong ang user sa turn 40 tungkol sa isang order number na ibinigay sa turn 3. Gumamit ka ng 4-turn na window na walang buod. Ano ang mangyayari?

Ipakita ang sagot

Sagot: Hindi ito makita ng modelo, dahil pinutol ang turn 3 mula sa request

Stateless ang API. Nakikita lamang ng modelo ang nasa request, kaya ang mga fact na kailangan mo pa ay dapat manatili sa system prompt o sa isang buod.