ব্লগে ফিরে যান

খরচ অপ্টিমাইজেশনগাইড

খরচ কমাতে চ্যাট ইতিহাস ছাঁটাই: স্লাইডিং উইন্ডো বা সারাংশ

প্রতিটি টার্নে আপনি যা আবার পাঠান তা সীমিত করুন: শেষ কয়েকটি বার্তা বা একটি সংক্ষিপ্ত সারাংশ রাখুন। ৫০-টার্নের চ্যাটের টোকেন হিসাব এবং একটি Python হেল্পার।

CheapTokens Team দ্বারাপ্রকাশিত হয়েছে 11 মিনিট পড়ার সময়

কভার: trim_history হেল্পার দিয়ে একটি দীর্ঘ চ্যাট সস্তা রাখুন
এই পৃষ্ঠায়
  1. টার্ন ৫০ আসলে কী পাঠায়
  2. বিকল্প ১: একটি স্লাইডিং উইন্ডো
  3. বিকল্প ২: পুরনো টার্নের সারাংশ
  4. তিনটি সেটআপের খরচ
  5. কোনটি বেছে নেবেন

আপনার সাপোর্ট বট ৫০ টার্ন ধরে চ্যাট করছে, এবং প্রতিটি নতুন বার্তা আগেরটির চেয়ে বেশি খরচ করছে। API কিছুই মনে রাখে না, তাই আপনার কোড প্রতিবার পুরো কথোপকথন আবার পাঠায়। সমাধান হলো আপনি যা পাঠান তা সীমিত করা: সিস্টেম প্রম্পট এবং শেষ কয়েকটি টার্ন রাখুন (একটি স্লাইডিং উইন্ডো), অথবা পুরনো টার্নগুলোকে একটি সংক্ষিপ্ত সারাংশ দিয়ে বদলে দিন। নিচে ৫০-টার্নের চ্যাটের হিসাব এবং একটি হেল্পার দেওয়া হলো যা আপনি কপি করতে পারেন।

DeepSeek-এর মাল্টি-রাউন্ড চ্যাট গাইড (api-docs.deepseek.com, ১ নভেম্বর ২০২৬-এ যাচাই করা) স্পষ্টভাবে বলে: সার্ভার আগের অনুরোধের কনটেক্সট রেকর্ড করে না, তাই ক্লায়েন্ট প্রতিটি কলে সম্পূর্ণ messages তালিকা পাঠায়। CheapTokens-এ OpenAI-সামঞ্জস্যপূর্ণ ফরম্যাট একইভাবে কাজ করে। যদি এটি আপনার কাছে নতুন হয়, তাহলে কেন একটি দীর্ঘ চ্যাট বেশি খরচ করে এবং কীভাবে messages অ্যারে কাজ করে দিয়ে শুরু করুন।

টার্ন ৫০ আসলে কী পাঠায়#

ধরুন আপনি একটি সাপোর্ট বট চালান যার ৪০০-টোকেনের সিস্টেম প্রম্পট আছে। একটি সাধারণ টার্নে ব্যবহারকারী প্রায় ৬০ টোকেন লেখে এবং বট প্রায় ১৯০ টোকেন দিয়ে উত্তর দেয়। একটি সম্পূর্ণ টার্ন ইতিহাসে ২৫০ টোকেন যোগ করে। এগুলো অনুমান: আপনার নিজের প্রতিক্রিয়ার usage ফিল্ডের সংখ্যা দিয়ে এগুলো প্রতিস্থাপন করুন।

টার্ন ৫০-এ অনুরোধে সিস্টেম প্রম্পট, ৪৯টি আগের টার্ন এবং নতুন বার্তা থাকে: 400 + 49 × 250 + 60 = 12,710 ইনপুট টোকেন, একটি ১৯০-টোকেন উত্তর পেতে। পুরো চ্যাট যোগ করুন। সিস্টেম প্রম্পট এবং নতুন বার্তা প্রতিবার পাঠানো হয়: 50 × 460 = 23,000। পুনরাবৃত্ত ইতিহাস যোগ করে 250 × 1,225 = 306,250। একসাথে: 23,000 + 306,250 = 329,250 ইনপুট টোকেন, বনাম 50 × 190 = 9,500 আউটপুট টোকেন।

প্রতিটি অনুরোধে ইতিহাস এক টার্ন করে বাড়ে, তাই মোট চ্যাটের দৈর্ঘ্যের বর্গের সাথে বাড়ে। ৫০ থেকে ১০০ টার্নে গেলে পুনরাবৃত্ত-ইতিহাসের অংশ মোটামুটি চারগুণ হয়।

নিজে চেষ্টা করুনচেষ্টা করুন: যদি আপনি শুধুমাত্র সিস্টেম প্রম্পট, শেষ ৪টি টার্ন এবং নতুন বার্তা পাঠান, তাহলে টার্ন ৫০-এ কত ইনপুট টোকেন বহন করবে?উত্তর দেখান

১,৪৬০ (400 + 4 × 250 + 60), সম্পূর্ণ ইতিহাসের সাথে ১২,৭১০-এর বিপরীতে। একই প্রশ্ন, একই উত্তর দৈর্ঘ্য, ইনপুটের একটি ভগ্নাংশ।

বিকল্প ১: একটি স্লাইডিং উইন্ডো#

ধারণাটি: সর্বদা সিস্টেম প্রম্পট পাঠান, শেষ N টার্ন ছাড়া সবকিছু বাদ দিন। আপনি আপনার নিজের স্টোরেজে সম্পূর্ণ ইতিহাস রাখেন এবং শুধুমাত্র আপনি যে কপি পাঠান তা ছাঁটাই করেন।

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):]

ব্যবহারকারীর নতুন বার্তা যোগ করার পরে এটি কল করুন। keep_pairs=4 দিয়ে এটি ৪টি ব্যবহারকারী/সহায়ক জোড়া প্লাস নতুন বার্তা, ৯টি বার্তা, এবং স্লাইস সর্বদা একটি ব্যবহারকারী বার্তা দিয়ে শুরু হয়। এখানে এটি একটি বাস্তব কলে সংযুক্ত করা হলো:

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

print লাইনটি দরকারী: প্রথম সংখ্যাটি লক্ষ্য করুন। ছাঁটাই ছাড়া এটি প্রতিটি টার্নে বাড়ে। উইন্ডোর সাথে চ্যাট টার্ন ৪ পার হলে এটি বাড়া বন্ধ করে।

Python হেল্পার trim_history: সিস্টেম প্রম্পট, শেষ ৪টি টার্ন, নতুন বার্তা
এই নিবন্ধের ছাঁটাই হেল্পার

সংখ্যায়: টার্ন ৫ থেকে, প্রতিটি অনুরোধ 400 + 4 × 250 + 60 = 1,460 ইনপুট টোকেন। প্রথম চারটি টার্ন এখনও স্বাভাবিকভাবে বাড়ে এবং মোট ৩,৩৪০ হয়। পুরো চ্যাট: 3,340 + 46 × 1,460 = 70,500 ইনপুট টোকেন, সম্পূর্ণ ইতিহাসের সাথে আপনি যে ৩২৯,২৫০ পাঠান তার প্রায় এক-পঞ্চমাংশ। আউটপুট 50 × 190 = 9,500 থাকে।

টার্ন ৫০ অনুরোধ: সম্পূর্ণ ইতিহাস বনাম ৪ টার্নের উইন্ডো
উপরের অনুমান অনুসারে টার্ন-৫০ অনুরোধের টোকেন অংশ

কোডে, পুরো পরিবর্তনটি কলে একটি আর্গুমেন্ট:

তুলনা করুন

এক-লাইন পরিবর্তন

আগে

python
messages=history

পরে

python
messages=trim_history(history)

ক্যাচ: একটি উইন্ডো ভুলে যায়। যদি ব্যবহারকারী টার্ন ৪০-এ জিজ্ঞাসা করে "আমার অর্ডার নম্বর কী ছিল?" এবং নম্বরটি টার্ন ৩-এ ছিল, মডেল এটি কখনও দেখেনি। দুটি সস্তা সমাধান। আপনার নিজের কোডে চ্যাট থেকে স্থিতিশীল তথ্য (নাম, অর্ডার নম্বর, প্ল্যান) বের করুন এবং সিস্টেম প্রম্পটে যোগ করুন, যেখানে উইন্ডো কখনও সেগুলো কাটে না। অথবা একটি সারাংশ যোগ করুন, যা পরবর্তী বিকল্প।

বিকল্প ২: পুরনো টার্নের সারাংশ#

পুরনো টার্ন বাদ দেওয়ার পরিবর্তে, আপনি সেগুলো সংকুচিত করেন। প্রতি কয়েক টার্নে, যে টার্নগুলো এইমাত্র উইন্ডো থেকে বাদ পড়েছে, সেগুলো এবং বর্তমান সারাংশ মডেলে পাঠান এবং একটি নতুন, সংক্ষিপ্ত সারাংশ চান। তারপর সেই সারাংশটি সিস্টেম বার্তায় রাখুন।

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

সারাংশটি বিনামূল্যে নয়: এটি একটি অতিরিক্ত মডেল কল। ধরুন প্রায় ৩০০ টোকেনের একটি সারাংশ, প্রতি ৫ টার্নে রিফ্রেশ করা হয় (৫০ টার্নে ৯ বার), প্রতিটি রিফ্রেশে প্রায় ১,৬০০ টোকেন পড়া হয় (পুরনো সারাংশ প্লাস পাঁচ টার্ন প্লাস নির্দেশনা) এবং ৩০০ লেখা হয়। নিরাপদ দিকে থাকতে, টার্ন ৫ থেকে প্রতিটি অনুরোধে সারাংশ গণনা করুন (বাস্তবে এটি প্রথম রিফ্রেশের পরে উপস্থিত হয়, তাই এটি একটি সামান্য অতিরিক্ত অনুমান): 400 + 300 + 4 × 250 + 60 = 1,760 ইনপুট টোকেন।

চ্যাটের মোট: প্রধান অনুরোধ 3,340 + 46 × 1,760 = 84,300 ইনপুট টোকেন, সারাংশ কল 9 × 1,600 = 14,400 ইনপুট এবং 9 × 300 = 2,700 আউটপুট। সব মিলিয়ে 84,300 + 14,400 = 98,700 ইনপুট এবং 9,500 + 2,700 = 12,200 আউটপুট টোকেন।

সারাংশটি খালি উইন্ডোর চেয়ে সামান্য বেশি খরচ করে, এবং বিনিময়ে মডেল এখনও জানে টার্ন ৩-এ কী ঘটেছিল।

তিনটি সেটআপের খরচ#

এখানে DeepSeek-V4-Flash-এ একই ৫০-টার্নের চ্যাট, উপরের মোট থেকে লাইভ মূল্যায়িত:

DeepSeek-V4-Flash-এ একটি ৫০-টার্নের চ্যাট
  • সম্পূর্ণ ইতিহাস (৩২৯,২৫০ ইন, ৯,৫০০ আউট)$0.0059
  • উইন্ডো প্লাস সারাংশ (৯৮,৭০০ ইন, ১২,২০০ আউট)$0.0027
  • স্লাইডিং উইন্ডো, ৪ টার্ন (৭০,৫০০ ইন, ৯,৫০০ আউট)$0.002

দামগুলো লাইভ মূল্য তালিকা থেকে আসে, তাই ট্যারিফ পরিবর্তন হলে সংখ্যাগুলো আপডেট হয়। ক্রমটি হবে না: উইন্ডো সবচেয়ে কম পাঠায়, সারাংশ মাঝখানে থাকে, সম্পূর্ণ ইতিহাস সবচেয়ে ব্যয়বহুল।

এই ধরনের চ্যাটের জন্য, শুরু করার জন্য CheapTokens মডেল হলো DeepSeek-V4-Flash। এটির ৩৮০K কনটেক্সট উইন্ডো আছে (একটি ৫০-টার্নের চ্যাট এমনকি না ছাঁটিয়েও ফিট করে), প্রতি উত্তরে ৩২,৭৬৮ আউটপুট টোকেন পর্যন্ত, দিনের যেকোনো সময়ে একটি নির্দিষ্ট মূল্য, এবং মোটে, ইনপুট এবং আউটপুট একসাথে গণনা করলে, এটি OpenRouter-এর চেয়ে সস্তা। মডেল আইডি deepseek-ai/DeepSeek-V4-Flash-0731। আপনি যদি উইন্ডো সেটআপে মডেল তুলনা করতে চান (প্রতি অনুরোধে গড়ে ১,৪১০ ইনপুট টোকেন, ১৯০ আউটপুট, ৫০ অনুরোধ), এখানে লাইভ টেবিল:

মডেল প্রতি অনুরোধে ৫০টি অনুরোধ OpenRouter, ৫০টি অনুরোধ
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

প্রতি অনুরোধে ১,৪১০ ইনপুট এবং ১৯০ আউটপুট টোকেন। প্রতি 1M টোকেনের দাম বর্তমান এবং আমাদের ট্যারিফের সাথে পরিবর্তিত হয়; OpenRouter কলামটি একই ওয়ার্কলোডের জন্য রেফারেন্স মূল্য দেখায়।

GLM-5.3-Flash-এর ৩৯০K কনটেক্সট এবং MiniMax-M2.7-এর ১৮০K আছে, যা একটি ছাঁটা চ্যাটের জন্য যথেষ্ট। বর্তমান দাম মূল্য পৃষ্ঠা-এ আছে, এবং ডক্স দেখায় কীভাবে প্রথম অনুরোধ পাঠাতে হয়।

কোনটি বেছে নেবেন#

একটি উইন্ডো ডিফল্ট: তিন লাইন কোড, কোনো অতিরিক্ত কল নেই, কোনো অতিরিক্ত ব্যর্থতার মোড নেই। সাপোর্ট বট, টিউটর এবং রোল-প্লে-এর জন্য এটি ব্যবহার করুন, যেখানে শেষ কয়েকটি টার্ন কথোপকথন বহন করে এবং সিস্টেম প্রম্পট নিয়ম বহন করে। সারাংশ যোগ করুন যখন ব্যবহারকারীরা অনেক আগে বলা জিনিস উল্লেখ করে, যেমন একটি ব্যক্তিগত সহায়ক যার একটি কখনও শেষ না হওয়া কথোপকথন আছে। উইন্ডোটি যথেষ্ট ছোট রাখুন যাতে মডেল এখনও তাৎক্ষণিক প্রসঙ্গ দেখে, এবং যথেষ্ট বড় যাতে একটি সম্পূর্ণ প্রশ্ন-উত্তর বিনিময় ধরে রাখে। কতটা আদৌ ফিট করে তা একটি পৃথক সীমা, যা কনটেক্সট উইন্ডো কী-তে কভার করা হয়েছে।

দ্রুত যাচাই

ব্যবহারকারী টার্ন ৪০-এ টার্ন ৩-এ দেওয়া একটি অর্ডার নম্বর সম্পর্কে জিজ্ঞাসা করে। আপনি সারাংশ ছাড়া একটি ৪-টার্ন উইন্ডো ব্যবহার করেন। কী হয়?

উত্তর দেখান

উত্তর: মডেল এটি দেখতে পায় না, কারণ টার্ন ৩ অনুরোধ থেকে কাটা হয়েছিল

API স্টেটলেস। মডেল শুধুমাত্র অনুরোধে যা আছে তা দেখে, তাই আপনার এখনও প্রয়োজনীয় তথ্য সিস্টেম প্রম্পটে বা একটি সারাংশে থাকতে হবে।