ailiteracynepal 🇳🇵
पाठ आकार

अध्याय ३ · खण्ड I · 20 मिनेट

मोडेलले किन बिर्सन्छन्, र context windows

हरेक LLM कल fresh हुन्छ — मोडेलसँग तपाईंले हरेक पटक history नपठाएसम्म अघिल्ला कलहरूको memory छैन। Context window के हो, किन महत्त्व राख्छ, र memory लाई design समस्याका रूपमा कसरी सोच्ने बुझ्ने।

Claude.ai मा यो कोसिस गर्नुहोस्। यसलाई सोध्नुहोस् “मेरो नाम निश्चल हो, त्यो सम्झनुहोस्।” अनि नयाँ च्याट विन्डोमा सोध्नुहोस् “मेरो नाम के हो?” मोडेललाई कुनै विचार छैन। LLM मा हरेक कल खाली slate हो — मोडेलले त्यो विशिष्ट अनुरोधमा तपाईंले पठाएको मात्र देख्छ। यो bug होइन; यो technology कसरी काम गर्छ भन्ने हो। यो बुझ्नु — र यसको वरिपरि निर्माण गर्नु — chatbot जुन उपस्थित महसुस हुन्छ र chatbot जुन उही user मा फेरि आफूलाई परिचय दिइरहन्छ — बीचको फरक हो। यो खण्ड त्यो विचारको ध्यानले संस्करण हो।

Forgetful function

LLM API, technically, stateless function हो। तपाईंले यसलाई prompt दिनुहुन्छ, यसले तपाईंलाई प्रतिक्रिया दिन्छ। कलहरू बीच, केही याद हुँदैन। मोडेलसँग पहिलेका कुराकानीहरूको server-side database छैन, “तपाईं” को हुनुहुन्छ भन्ने persistent पहिचान छैन, यो कल कुराकानीमा दसौं वा पहिलो हो भन्ने कुनै विचार छैन।

यो लगभग हरेक web API जस्तै आकार हो। जब तपाईंले requests.get("https://api.example.com/weather?city=kathmandu") बोलाउनुहुन्छ, weather API सँग तपाईंका अघिल्ला कलहरूको memory छैन; यसले आफ्नै merits मा प्रत्येक जवाफ दिन्छ। LLMs पनि उस्तै हुन्।

Claude.ai वा ChatGPT जस्तो chat interface मा memory को illusion पूर्ण रूपमा client द्वारा कायम राखिन्छ, server द्वारा होइन। जब तपाईंले च्याटमा सन्देश #10 पठाउनुहुन्छ, client ले वास्तवमा सन्देश 1-9 को पूरै इतिहास तपाईंको नयाँ सन्देशसँगै पठाइरहेको छ। मोडेलले सबै दस पढ्छ, र यसको प्रतिक्रियाले पूरै कुराकानी विचार गर्छ।

Mechanic, सरल रूपमा

Anthropic को API मा, memory messages सूची मार्फत expose हुन्छ:

# Turn 1: user asks a question
response1 = client.messages.create(
    model="claude-haiku-4-5-20251001",
    max_tokens=400,
    messages=[
        {"role": "user", "content": "My name is Nischal. What's a good name for a NEPSE-tracking bot?"},
    ],
)
# → "Nice to meet you, Nischal. How about 'NepseNepal' or ..."

# Turn 2: user asks a follow-up — you must send the history
response2 = client.messages.create(
    model="claude-haiku-4-5-20251001",
    max_tokens=400,
    messages=[
        {"role": "user", "content": "My name is Nischal. What's a good name for a NEPSE-tracking bot?"},
        {"role": "assistant", "content": response1.content[0].text},
        {"role": "user", "content": "Which of those would you actually pick?"},
    ],
)
# → "For your bot idea, I'd pick 'NepseNepal' because ..."

यदि तपाईंले दोस्रो कलबाट पहिलो दुई सन्देश omit गर्नुभयो भने, मोडेललाई “those” ले के लाई सन्दर्भ गर्दैछ, वा तपाईं Nischal हुनुहुन्छ भन्ने कुनै विचार हुनेथिएन। कुराकानीको पूरै स्थिति client मा बस्छ र हरेक turn मा पुन: पठाइन्छ।

Context window: माथिल्लो सीमा

तपाईंले किन असीमित history पठाउन सक्नुहुन्न भन्ने कारण context window हो — मोडेलले एउटा कलमा process गर्न सक्ने अधिकतम token सङ्ख्या। 2026 मा:

  • Claude Haiku 4.5: 200,000 tokens (~150,000 words)
  • Claude Sonnet 4.6: 200,000 tokens
  • Claude Opus 4.7: 200,000 tokens
  • GPT-4.1: 200,000 tokens
  • GPT-5: variant मा निर्भर 400,000-1M tokens
  • Gemini Pro: 1,000,000+ tokens

यी ठूला छन् — 200k-token window ले लगभग उपन्यासको मूल्यको पाठ फिट गर्छ। तर तिनी finite छन्। एक पटक तपाईंको कुराकानी इतिहास र प्रतिक्रिया window भन्दा बढ्यो भने, API ले error फर्काउँछ।

बढी सूक्ष्म रूपमा, धेरै context प्रयोग गर्दा प्रति कल बढी लागत लाग्छ (तपाईं प्रति input token तिर्नुहुन्छ) र मोडेलहरू context धेरै लामो हुँदा अलिकति खराब हुन्छन् — तिनले बीचमा गहिरो buried विवरणहरूमा कम ध्यान दिन्छन्। यसलाई “lost in the middle” भनिन्छ र यो उत्पादन प्रणालीहरूमा वास्तविक प्रभाव हो।

निर्माणका लागि यसको अर्थ

यो सबैबाट तीन design implications बग्छन्:

1. हरेक अर्थपूर्ण कुराकानीलाई memory रणनीति चाहिन्छ। तपाईंले पूरा इतिहास राख्ने (सरल), पुरानो turns summarise गर्ने (सस्तो), वा माग अनुसार सान्दर्भिक विगत सन्देश ल्याउने (RAG-शैली, अध्याय 5) — तपाईंले निर्णय गर्नुपर्छ।

2. Context बजेट हो। घण्टौं चल्ने च्याटमा, कुराकानी इतिहास बढ्छ। कुनै बिन्दुमा तपाईंले काट्नुपर्छ, summarise गर्नुपर्छ, वा scroll गर्नुपर्छ। यसलाई बेवास्ता गर्नाले क्रमशः बढ्दो लागत र eventual API त्रुटिहरू निम्त्याउँछ।

3. दीर्घकालीन memory छुट्टै प्रणाली हो। यदि तपाईं sessions (हप्ता, महिना) भर user सम्झने chatbot चाहनुहुन्छ भने, तपाईं LLM को context window मा भर पर्न सक्नुहुन्न। तपाईंलाई user facts को database चाहिन्छ जुन तपाईंले हरेक session मा system prompt मा inject गर्नुहुन्छ। LLM memory होइन; LLM reasoner हो।

तीन memory रणनीति, संक्षेपमा

हामी अर्को खण्डमा प्रत्येकलाई गहिरो ओगट्छौँ, तर एक झलक:

Strategy A — पूरा इतिहास। हरेक सन्देश राख्नुहोस् र सबै पठाउनुहोस्। सरल, सही, scale मा महँगो। छोटा कुराकानीका लागि काम गर्छ।

Strategy B — sliding window। केवल अन्तिम N turns राख्नुहोस्। सरल, सस्तो, पुरानो context बिर्सन्छ। जब केवल हालैको context महत्त्व राख्छ (customer support, छिटो Q&A) काम गर्छ।

Strategy C — summarised इतिहास। कुराकानी बढ्दै जाँदा, पुरानो turns लाई periodic रूपमा छोटो block मा summarise गर्नुहोस् जुन prepend हुन्छ। Complex, tuning-heavy, तर arbitrarily लामो कुराकानीहरूमा scale गर्छ। लामो-जीवन सहायकहरूका लागि काम गर्छ।

लगभग हरेक वास्तविक chatbot ले केही combination प्रयोग गर्छ। सामान्य recipe: अन्तिम 10 turns को sliding window, प्लस सबै भन्दा पहिलेको running summary।

नेपाली chatbots विशेष रूपमा

नेपाली पाठले अंग्रेजी को लगभग 2x token प्रयोग गर्छ, त्यसैले 200k अंग्रेजी token फिट गर्ने context window ले लगभग ~100k नेपाली token मात्र फिट गर्छ। यदि तपाईंको bot bilingual (नेपाली/अंग्रेजी) छ भने, तदनुसार बजेट बनाउनुहोस्।

साथै: मोडेलले कहिलेकाहीँ लामो इतिहासहरूमा भाषा switches को track गुमाउँछन्। नेपाली मा सुरु भएको र अंग्रेजी मा drift भएको कुराकानीले मोडेललाई अनौठो mix मा प्रतिक्रिया दिन सक्छ। System prompt लाई भाषाबारे स्पष्ट राख्नाले (“सबैभन्दा हालैको user सन्देशकै भाषामा प्रतिक्रिया दिनुहोस्”) मद्दत गर्छ।

सानो कार्य गरिएको प्रदर्शन

Statelessness लाई मूर्त रूपमा महसुस गर्न, यो चलाउनुहोस्:

# Two calls with the same client, but no shared history

response1 = client.messages.create(
    model="claude-haiku-4-5-20251001",
    max_tokens=200,
    messages=[
        {"role": "user", "content": "Remember: my favourite Nepali dish is momo. Now respond with just 'ok'."},
    ],
)
print("Call 1:", response1.content[0].text.strip())

response2 = client.messages.create(
    model="claude-haiku-4-5-20251001",
    max_tokens=200,
    messages=[
        {"role": "user", "content": "What's my favourite Nepali dish?"},
    ],
)
print("Call 2:", response2.content[0].text.strip())

Output:

Call 1: ok
Call 2: I don't have any information about your favourite Nepali dish. Could you tell me what it is?

दोस्रो कललाई पहिलोमा के भयो कुनै विचार छैन। केही पनि पार गएन। यो Claude को सीमा होइन; यो API कसरी काम गर्छ।

अब memory सँगको संस्करण:

history = [
    {"role": "user", "content": "Remember: my favourite Nepali dish is momo. Now respond with just 'ok'."},
]

response1 = client.messages.create(model="...", max_tokens=200, messages=history)
history.append({"role": "assistant", "content": response1.content[0].text})

history.append({"role": "user", "content": "What's my favourite Nepali dish?"})
response2 = client.messages.create(model="...", max_tokens=200, messages=history)

print(response2.content[0].text.strip())
# → "Your favourite Nepali dish is momo."

उही दुई प्रश्न। एउटै फरक हामीले history सूचीलाई मैन्युअल रूपमा maintain गर्‍यौं। अर्को खण्ड यो ढाँचाको पूर्ण संस्करण हो।

आफ्नो बुझाइ जाँच्नुहोस्

Quick check

एक साथीले दाबी गर्छन् कि Claude ले users बारेका facts 'सम्झन्छ' किनकि यसले तिनको chatbot मा follow-up प्रश्नमा सही प्रतिक्रिया दियो। के भइरहेको छ भन्ने सटीक विवरण के हो?

Quick check

नेपाली customer-support chatbot ले दिनमा 100 कुराकानी चलाउनेछ, प्रत्येकको औसत 30 turns। यो खण्डबाट सबैभन्दा तत्काल व्यवहारिक चिन्ता के हो?

अब के आउँछ

मोडेलले किन बिर्सन्छ तपाईं बुझ्नुहुन्छ। अर्को खण्ड turns भर कुराकानी state राख्ने व्यवहारिक कला हो — sliding-window ढाँचा, summarised-history ढाँचा, र multi-turn chat लाई भरपर्दो बनाउने कोड। खण्ड 2 को अन्त्यसम्म तपाईंसँग reusable Conversation class हुनेछ जुन तपाईंले निर्माण गर्ने कुनै पनि chatbot मा drop गर्न सक्नुहुन्छ।