Thought for 5 seconds### টিউটোরিয়াল ২.৩: মেমরি কম্পোনেন্ট
ভূমিকা
গল্প: কল্পনা করুন, আপনি একটি রেস্টুরেন্টে গেছেন। প্রথমবার যখন ওয়েটার আসে, আপনি পানি চান। কিছুক্ষণ পর ওয়েটার আবার আসে এবং জিজ্ঞেস করে, “আপনার অর্ডার নিতে পারি?” আপনি বলেন, “আমি একটি বার্গার চাই।” ওয়েটার নোট নেয় এবং চলে যায়। পরে, যখন ওয়েটার আপনার বার্গার নিয়ে আসে, সে জানে যে এটি আপনার জন্য, কারণ সে মনে রেখেছে যে আপনি বার্গার অর্ডার করেছিলেন।
এই উদাহরণে, ওয়েটারের “মেমরি” আছে – সে আপনার সাথে আগের কথোপকথন মনে রাখে। LLM-এর ক্ষেত্রেও একই সমস্যা রয়েছে। প্রতিটি প্রম্পট একটি নতুন কনভার্সেশন হিসেবে বিবেচিত হয়, যদি না আমরা আগের কথোপকথন সম্পর্কে তথ্য সরবরাহ করি।
মেমরি কি এবং কেন প্রয়োজন
মেমরি কি?
LangChain-এ, মেমরি হল এমন একটি কম্পোনেন্ট যা LLM-কে আগের ইন্টারাকশন মনে রাখতে সাহায্য করে। এটি কনভার্সেশন হিস্টোরি, ইউজার প্রেফারেন্স, এন্টিটি, বা অন্যান্য রিলেভেন্ট তথ্য স্টোর করতে পারে।
কেন মেমরি প্রয়োজন?
- কন্টেক্সচুয়াল কনভার্সেশন: ইউজার যখন “এটা কি?” বা “এটা কেন?” জিজ্ঞেস করে, LLM-কে জানতে হবে “এটা” কী।
- পার্সোনালাইজেশন: ইউজারের পছন্দ, অভ্যাস, বা প্রয়োজন মনে রাখা।
- কনটিনিউটি: লম্বা কনভার্সেশনে কোহেরেন্স বজায় রাখা।
- কনটেক্সট উইন্ডো সীমাবদ্ধতা: LLM-এর কনটেক্সট উইন্ডো সীমিত (GPT-3.5 = ~4K টোকেন, GPT-4 = ~8K-32K টোকেন)। মেমরি সাহায্য করে এই সীমাবদ্ধতা কাটিয়ে উঠতে।
বাস্তব উদাহরণ:
কল্পনা করুন, আপনি একটি কাস্টমার সাপোর্ট চ্যাটবট তৈরি করছেন। একজন কাস্টমার জিজ্ঞেস করে:
কাস্টমার: আমার অর্ডার #12345 কোথায় আছে?
চ্যাটবট: আপনার অর্ডার শিপিং-এ আছে এবং আগামীকাল পৌঁছাবে।
কাস্টমার: ধন্যবাদ। এটাতে কি ফ্রি শিপিং ছিল?মেমরি ছাড়া, চ্যাটবট জানবে না “এটাতে” বলতে অর্ডার #12345 বোঝানো হচ্ছে। মেমরি সহ, চ্যাটবট কনটেক্সট বুঝতে পারবে এবং সঠিক উত্তর দিতে পারবে।
কনভার্সেশন বাফার মেমরি
গল্প: কনভার্সেশন বাফার মেমরি হল একটি নোটবুকের মতো, যেখানে আপনি প্রতিটি কথোপকথন লিখে রাখেন। যখন আপনি কারো সাথে কথা বলেন, আপনি নোটবুক দেখে আগে কী কথা হয়েছিল তা মনে করতে পারেন।
কনভার্সেশন বাফার মেমরি হল সবচেয়ে সিম্পল মেমরি টাইপ, যা সমস্ত আগের মেসেজ স্টোর করে।
বেসিক ইমপ্লিমেন্টেশন
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os
# .env ফাইল থেকে API কি লোড করুন
load_dotenv()
# LLM সেটআপ করুন
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0.7,
api_key=os.getenv("OPENAI_API_KEY")
)
# কনভার্সেশন বাফার মেমরি তৈরি করুন
memory = ConversationBufferMemory()
# কনভার্সেশন চেইন তৈরি করুন
conversation = ConversationChain(
llm=llm,
memory=memory,
verbose=True
)
# প্রথম প্রম্পট
response1 = conversation.predict(input="আমার নাম করিম। আপনার নাম কি?")
print("AI:", response1)
# দ্বিতীয় প্রম্পট
response2 = conversation.predict(input="আমি বাংলাদেশের ঢাকায় থাকি। আপনি কোথায় থাকেন?")
print("AI:", response2)
# তৃতীয় প্রম্পট
response3 = conversation.predict(input="আমার শহর সম্পর্কে কিছু বলুন।")
print("AI:", response3)
# মেমরি দেখুন
print("\nমেমরি কনটেন্ট:")
print(memory.buffer)কনভার্সেশন বাফার মেমরি কিভাবে কাজ করে
- স্টোরেজ: প্রতিটি ইউজার ইনপুট এবং AI রেসপন্স একটি স্ট্রিং বাফারে স্টোর করা হয়।
- রিট্রিভাল: যখন নতুন প্রম্পট আসে, পুরো কনভার্সেশন হিস্টোরি LLM-এ পাঠানো হয়।
- ফরম্যাট: কনভার্সেশন সাধারণত এভাবে ফরম্যাট করা হয়:
Human: [ইউজার ইনপুট 1]
AI: [AI রেসপন্স 1]
Human: [ইউজার ইনপুট 2]
AI: [AI রেসপন্স 2]
...
Human: [বর্তমান ইউজার ইনপুট]কনভার্সেশন বাফার মেমরির ভেরিয়েন্ট
ConversationBufferWindowMemory
এটি শুধু সর্বশেষ K টি এক্সচেঞ্জ মনে রাখে, যা কনটেক্সট উইন্ডো সীমাবদ্ধতা কাটাতে সাহায্য করে।
from langchain.memory import ConversationBufferWindowMemory
# উইন্ডো সাইজ 2 সহ কনভার্সেশন বাফার উইন্ডো মেমরি তৈরি করুন
window_memory = ConversationBufferWindowMemory(k=2)
# কনভার্সেশন চেইন তৈরি করুন
window_conversation = ConversationChain(
llm=llm,
memory=window_memory,
verbose=True
)
# কয়েকটি প্রম্পট চালান
print("\nConversationBufferWindowMemory উদাহরণ:")
window_conversation.predict(input="আমার নাম করিম।")
window_conversation.predict(input="আমি একজন সফটওয়্যার ইঞ্জিনিয়ার।")
window_conversation.predict(input="আমি বাংলাদেশের ঢাকায় থাকি।")
response = window_conversation.predict(input="আমার পেশা কি?")
print("AI:", response)
# মেমরি দেখুন
print("\nউইন্ডো মেমরি কনটেন্ট:")
print(window_memory.buffer)ConversationTokenBufferMemory
এটি টোকেন কাউন্ট ট্র্যাক করে এবং নির্দিষ্ট টোকেন লিমিটের মধ্যে থাকে।
from langchain.memory import ConversationTokenBufferMemory
from langchain_openai import OpenAI
# টোকেন লিমিট 100 সহ কনভার্সেশন টোকেন বাফার মেমরি তৈরি করুন
token_memory = ConversationTokenBufferMemory(
llm=OpenAI(), # টোকেন কাউন্টিং-এর জন্য LLM প্রয়োজন
max_token_limit=100
)
# কনভার্সেশন চেইন তৈরি করুন
token_conversation = ConversationChain(
llm=llm,
memory=token_memory,
verbose=True
)
# কয়েকটি প্রম্পট চালান
print("\nConversationTokenBufferMemory উদাহরণ:")
token_conversation.predict(input="আমার নাম করিম।")
token_conversation.predict(input="আমি একজন সফটওয়্যার ইঞ্জিনিয়ার।")
token_conversation.predict(input="আমি বাংলাদেশের ঢাকায় থাকি।")
response = token_conversation.predict(input="আমার পেশা কি?")
print("AI:", response)
# মেমরি দেখুন
print("\nটোকেন মেমরি কনটেন্ট:")
print(token_memory.buffer)কনভার্সেশন বাফার মেমরির ইউজ কেস
- সিম্পল চ্যাটবট: যেখানে পুরো কনভার্সেশন হিস্টোরি প্রয়োজন।
- কাস্টমার সাপোর্ট: যেখানে আগের ইন্টারাকশন মনে রাখা গুরুত্বপূর্ণ।
- টিউটোরিং অ্যাপ্লিকেশন: যেখানে শিক্ষার্থীর আগের প্রশ্ন এবং উত্তর ট্র্যাক করা প্রয়োজন।
- ডেভেলপমেন্ট এবং ডিবাগিং: যখন আপনি সমস্ত ইন্টারাকশন দেখতে চান।
কনভার্সেশন বাফার মেমরির সীমাবদ্ধতা
- স্কেলেবিলিটি: লম্বা কনভার্সেশনে, বাফার খুব বড় হয়ে যেতে পারে।
- কনটেক্সট উইন্ডো: LLM-এর কনটেক্সট উইন্ডো সীমাবদ্ধতা অতিক্রম করতে পারে।
- রিলেভেন্স: পুরনো কনভার্সেশন বর্তমান প্রশ্নের জন্য অপ্রাসঙ্গিক হতে পারে।
সামারি মেমরি
গল্প: সামারি মেমরি হল একজন সাংবাদিকের মতো, যিনি লম্বা ইন্টারভিউ নেওয়ার পর মূল পয়েন্টগুলি সংক্ষেপে লিখে রাখেন, পুরো কথোপকথন নয়। পরে, তিনি শুধু সেই সারাংশ দেখে মূল বিষয়গুলি মনে করতে পারেন।
সামারি মেমরি পুরো কনভার্সেশন স্টোর করার পরিবর্তে, কনভার্সেশনের একটি সংক্ষিপ্ত সারাংশ তৈরি করে এবং স্টোর করে।
ConversationSummaryMemory
from langchain.memory import ConversationSummaryMemory
# কনভার্সেশন সামারি মেমরি তৈরি করুন
summary_memory = ConversationSummaryMemory(llm=llm)
# কনভার্সেশন চেইন তৈরি করুন
summary_conversation = ConversationChain(
llm=llm,
memory=summary_memory,
verbose=True
)
# কয়েকটি প্রম্পট চালান
print("\nConversationSummaryMemory উদাহরণ:")
summary_conversation.predict(input="আমার নাম করিম। আমি একজন সফটওয়্যার ইঞ্জিনিয়ার।")
summary_conversation.predict(input="আমি বাংলাদেশের ঢাকায় থাকি এবং AI নিয়ে কাজ করি।")
summary_conversation.predict(input="আমি LangChain শিখছি কারণ আমি একটি AI চ্যাটবট তৈরি করতে চাই।")
response = summary_conversation.predict(input="আমার পেশা এবং আগ্রহ সম্পর্কে কি মনে আছে?")
print("AI:", response)
# সামারি দেখুন
print("\nসামারি মেমরি কনটেন্ট:")
print(summary_memory.buffer)
print("\nMoving Summary:")
print(summary_memory.moving_summary_buffer)ConversationSummaryBufferMemory
এটি বাফার মেমরি এবং সামারি মেমরির একটি হাইব্রিড। এটি সাম্প্রতিক কনভার্সেশন পুরোপুরি স্টোর করে, কিন্তু পুরনো কনভার্সেশন সামারাইজ করে।
from langchain.memory import ConversationSummaryBufferMemory
# কনভার্সেশন সামারি বাফার মেমরি তৈরি করুন
summary_buffer_memory = ConversationSummaryBufferMemory(
llm=llm,
max_token_limit=100
)
# কনভার্সেশন চেইন তৈরি করুন
summary_buffer_conversation = ConversationChain(
llm=llm,
memory=summary_buffer_memory,
verbose=True
)
# কয়েকটি প্রম্পট চালান
print("\nConversationSummaryBufferMemory উদাহরণ:")
summary_buffer_conversation.predict(input="আমার নাম করিম। আমি একজন সফটওয়্যার ইঞ্জিনিয়ার।")
summary_buffer_conversation.predict(input="আমি বাংলাদেশের ঢাকায় থাকি এবং AI নিয়ে কাজ করি।")
summary_buffer_conversation.predict(input="আমি LangChain শিখছি কারণ আমি একটি AI চ্যাটবট তৈরি করতে চাই।")
summary_buffer_conversation.predict(input="আমি পাইথন, জাভাস্ক্রিপ্ট, এবং টেনসরফ্লো ব্যবহার করি।")
summary_buffer_conversation.predict(input="আমি আমার চ্যাটবটে RAG ইমপ্লিমেন্ট করতে চাই।")
response = summary_buffer_conversation.predict(input="আমার পেশা এবং দক্ষতা সম্পর্কে কি মনে আছে?")
print("AI:", response)
# সামারি বাফার দেখুন
print("\nসামারি বাফার মেমরি কনটেন্ট:")
print(summary_buffer_memory.buffer)
print("\nMoving Summary:")
print(summary_buffer_memory.moving_summary_buffer)সামারি মেমরি কিভাবে কাজ করে
- সামারাইজেশন: LLM ব্যবহার করে কনভার্সেশনের একটি সংক্ষিপ্ত সারাংশ তৈরি করা হয়।
- স্টোরেজ: সারাংশ স্টোর করা হয়, পুরো কনভার্সেশন নয়।
- আপডেট: নতুন এক্সচেঞ্জ হলে, সারাংশ আপডেট করা হয়।
- রিট্রিভাল: LLM-এ প্রম্পট পাঠানোর সময়, সারাংশ কনটেক্সট হিসেবে ব্যবহার করা হয়।
সামারি মেমরির ইউজ কেস
- লং-রানিং কনভার্সেশন: যেখানে পুরো হিস্টোরি স্টোর করা অসম্ভব।
- কনটেক্সট উইন্ডো অপ্টিমাইজেশন: টোকেন ব্যবহার কমাতে।
- মিটিং সামারাইজেশন: লম্বা মিটিং বা ডিসকাশনের সারাংশ তৈরি করতে।
- কাস্টমার সাপোর্ট: লম্বা সাপোর্ট সেশনের মূল পয়েন্ট মনে রাখতে।
সামারি মেমরির সীমাবদ্ধতা
- ইনফরমেশন লস: সামারাইজেশনে কিছু ডিটেল হারিয়ে যেতে পারে।
- কম্পিউটেশনাল ওভারহেড: সামারাইজেশন LLM কল প্রয়োজন, যা সময় এবং খরচ বাড়ায়।
- সামারি কোয়ালিটি: LLM-এর সামারাইজেশন ক্ষমতার উপর নির্ভর করে।
এন্টিটি মেমরি
গল্প: এন্টিটি মেমরি হল একজন ব্যবসায়ীর কন্টাক্ট বুকের মতো। তিনি প্রতিটি ক্লায়েন্ট সম্পর্কে গুরুত্বপূর্ণ তথ্য (যেমন তাদের পছন্দ, আগের অর্ডার, পরিবারের সদস্য) লিখে রাখেন। যখন কোনো ক্লায়েন্ট আসে, তিনি কন্টাক্ট বুক দেখে তাদের সম্পর্কে সব তথ্য মনে করতে পারেন।
এন্টিটি মেমরি কনভার্সেশনে উল্লেখিত বিভিন্ন এন্টিটি (ব্যক্তি, স্থান, সংস্থা, ইত্যাদি) সম্পর্কে তথ্য স্টোর করে।
EntityMemory
from langchain.memory import ConversationEntityMemory
from pprint import pprint
# এন্টিটি মেমরি তৈরি করুন
entity_memory = ConversationEntityMemory(llm=llm)
# কনভার্সেশন চেইন তৈরি করুন
entity_conversation = ConversationChain(
llm=llm,
memory=entity_memory,
verbose=True
)
# কয়েকটি প্রম্পট চালান
print("\nEntityMemory উদাহরণ:")
entity_conversation.predict(input="আমার নাম করিম এবং আমি ঢাকা বিশ্ববিদ্যালয়ে পড়ি।")
entity_conversation.predict(input="আমার বন্ধু রহিম ঢাকা মেডিকেল কলেজে পড়ে।")
entity_conversation.predict(input="আমি কম্পিউটার সায়েন্স নিয়ে পড়াশোনা করি।")
entity_conversation.predict(input="রহিম মেডিসিন নিয়ে পড়াশোনা করে।")
response = entity_conversation.predict(input="আমি এবং রহিম কোথায় পড়াশোনা করি?")
print("AI:", response)
# এন্টিটি মেমরি দেখুন
print("\nএন্টিটি মেমরি কনটেন্ট:")
pprint(entity_memory.entity_store.store)এন্টিটি মেমরি কিভাবে কাজ করে
- এন্টিটি এক্সট্রাকশন: LLM ব্যবহার করে কনভার্সেশন থেকে এন্টিটি (ব্যক্তি, স্থান, সংস্থা, ইত্যাদি) চিহ্নিত করা হয়।
- এন্টিটি সামারাইজেশন: প্রতিটি এন্টিটি সম্পর্কে তথ্য সংক্ষেপে লিখে রাখা হয়।
- স্টোরেজ: এন্টিটি এবং তাদের সামারি একটি ডিকশনারিতে স্টোর করা হয়।
- রিট্রিভাল: নতুন প্রম্পটে রিলেভেন্ট এন্টিটি উল্লেখ করা হলে, সেই এন্টিটির সামারি কনটেক্সট হিসেবে যোগ করা হয়।
এন্টিটি মেমরির ইউজ কেস
- পার্সোনাল অ্যাসিস্ট্যান্ট: ইউজারের পরিবার, বন্ধু, সহকর্মী সম্পর্কে তথ্য মনে রাখতে।
- কাস্টমার সাপোর্ট: বিভিন্ন প্রোডাক্ট, সার্ভিস, বা কাস্টমার সম্পর্কে তথ্য ট্র্যাক করতে।
- এডুকেশনাল চ্যাটবট: বিভিন্ন টপিক, কনসেপ্ট, বা ব্যক্তি সম্পর্কে তথ্য মনে রাখতে।
- রিসার্চ অ্যাসিস্ট্যান্ট: বিভিন্ন পেপার, থিওরি, বা রিসার্চার সম্পর্কে তথ্য ট্র্যাক করতে।
এন্টিটি মেমরির সীমাবদ্ধতা
- এন্টিটি এক্সট্রাকশন এরর: LLM সবসময় সঠিকভাবে এন্টিটি চিহ্নিত নাও করতে পারে।
- কম্পিউটেশনাল ওভারহেড: এন্টিটি এক্সট্রাকশন এবং সামারাইজেশন অতিরিক্ত LLM কল প্রয়োজন।
- স্কেলেবিলিটি: অনেক এন্টিটি থাকলে, মেমরি বড় হয়ে যেতে পারে।
কাস্টম মেমরি ইমপ্লিমেন্টেশন
গল্প: কাস্টম মেমরি তৈরি করা হল আপনার নিজের ডায়েরি সিস্টেম তৈরি করার মতো। হয়তো আপনি বিভিন্ন বিষয় আলাদা আলাদা নোটবুকে লিখতে চান, বা আপনার নিজস্ব শর্টহ্যান্ড সিস্টেম আছে, বা আপনি ডিজিটাল এবং ফিজিক্যাল নোট একসাথে ব্যবহার করতে চান।
কাস্টম মেমরি আপনাকে আপনার অ্যাপ্লিকেশনের প্রয়োজন অনুযায়ী মেমরি সিস্টেম তৈরি করতে দেয়।
BaseMemory এক্সটেন্ড করে কাস্টম মেমরি
from langchain.memory.chat_memory import BaseChatMemory
from langchain.schema import HumanMessage, AIMessage
from typing import Dict, List, Any
class TimestampedChatMemory(BaseChatMemory):
"""
টাইমস্ট্যাম্প সহ চ্যাট মেমরি - প্রতিটি মেসেজের সাথে টাইমস্ট্যাম্প স্টোর করে।
"""
# মেমরি স্টোরেজ
chat_history: List[Dict[str, Any]] = []
@property
def memory_variables(self) -> List[str]:
"""মেমরি ভেরিয়েবল নাম রিটার্ন করে"""
return ["chat_history"]
def load_memory_variables(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
"""মেমরি ভেরিয়েবল লোড করে"""
# ফরম্যাটেড চ্যাট হিস্টোরি তৈরি করুন
formatted_history = ""
for message in self.chat_history:
role = message["role"]
content = message["content"]
timestamp = message["timestamp"]
formatted_history += f"{role} ({timestamp}): {content}\n"
return {"chat_history": formatted_history}
def save_context(self, inputs: Dict[str, Any], outputs: Dict[str, str]) -> None:
"""কনভার্সেশন কনটেক্সট সেভ করে"""
# ইউজার মেসেজ সেভ করুন
from datetime import datetime
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# ইনপুট কি নাম পান
input_key = list(inputs.keys())[0]
self.chat_history.append({
"role": "Human",
"content": inputs[input_key],
"timestamp": timestamp
})
# AI মেসেজ সেভ করুন
output_key = list(outputs.keys())[0]
self.chat_history.append({
"role": "AI",
"content": outputs[output_key],
"timestamp": timestamp
})
def clear(self) -> None:
"""মেমরি ক্লিয়ার করে"""
self.chat_history = []
# টাইমস্ট্যাম্পড মেমরি ব্যবহার করুন
timestamped_memory = TimestampedChatMemory()
# কনভার্সেশন চেইন তৈরি করুন
timestamped_conversation = ConversationChain(
llm=llm,
memory=timestamped_memory,
verbose=True
)
# কয়েকটি প্রম্পট চালান
print("\nTimestampedChatMemory উদাহরণ:")
timestamped_conversation.predict(input="আমার নাম করিম।")
timestamped_conversation.predict(input="আমি AI নিয়ে কাজ করি।")
response = timestamped_conversation.predict(input="আমার নাম কি?")
print("AI:", response)
# মেমরি দেখুন
print("\nটাইমস্ট্যাম্পড মেমরি কনটেন্ট:")
print(timestamped_memory.load_memory_variables({})["chat_history"])কাস্টম মেমরি উদাহরণ: টপিক-বেসড মেমরি
এই উদাহরণে, আমরা একটি মেমরি তৈরি করব যা কনভার্সেশনকে বিভিন্ন টপিকে ভাগ করে এবং প্রতিটি টপিকের জন্য আলাদা মেমরি রাখে।
from langchain.memory.chat_memory import BaseChatMemory
from langchain.schema import HumanMessage, AIMessage
from typing import Dict, List, Any
class TopicBasedMemory(BaseChatMemory):
"""
টপিক-বেসড মেমরি - কনভার্সেশনকে বিভিন্ন টপিকে ভাগ করে এবং প্রতিটি টপিকের জন্য আলাদা মেমরি রাখে।
"""
# টপিক-বেসড মেমরি স্টোরেজ
topic_memories: Dict[str, List[Dict[str, str]]] = {}
current_topic: str = "general"
llm: Any # LLM রেফারেন্স
def __init__(self, llm=None, **kwargs):
super().__init__(**kwargs)
self.llm = llm
self.topic_memories = {"general": []}
@property
def memory_variables(self) -> List[str]:
"""মেমরি ভেরিয়েবল নাম রিটার্ন করে"""
return ["chat_history", "current_topic", "all_topics"]
def _detect_topic(self, message: str) -> str:
"""মেসেজের টপিক ডিটেক্ট করে"""
if not self.llm:
return "general"
# LLM ব্যবহার করে টপিক ডিটেক্ট করুন
prompt = f"""
নিম্নলিখিত মেসেজের টপিক নির্ধারণ করুন। নিম্নলিখিত টপিকগুলির মধ্যে একটি বেছে নিন:
{', '.join(self.topic_memories.keys())}
যদি কোনো নতুন টপিক হয়, তাহলে একটি নতুন টপিক নাম সাজেস্ট করুন।
মেসেজ: {message}
টপিক:
"""
response = self.llm.predict(prompt)
# রেসপন্স প্রসেস করুন
detected_topic = response.strip().lower()
# যদি নতুন টপিক হয়, তাহলে যোগ করুন
if detected_topic not in self.topic_memories:
self.topic_memories[detected_topic] = []
return detected_topic
def load_memory_variables(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
"""মেমরি ভেরিয়েবল লোড করে"""
# বর্তমান টপিকের চ্যাট হিস্টোরি ফরম্যাট করুন
formatted_history = ""
for message in self.topic_memories.get(self.current_topic, []):
role = message["role"]
content = message["content"]
formatted_history += f"{role}: {content}\n"
# সমস্ত টপিক লিস্ট করুন
all_topics = list(self.topic_memories.keys())
return {
"chat_history": formatted_history,
"current_topic": self.current_topic,
"all_topics": all_topics
}
def save_context(self, inputs: Dict[str, Any], outputs: Dict[str, str]) -> None:
"""কনভার্সেশন কনটেক্সট সেভ করে"""
# ইনপুট কি নাম পান
input_key = list(inputs.keys())[0]
user_message = inputs[input_key]
# টপিক ডিটেক্ট করুন
self.current_topic = self._detect_topic(user_message)
# ইউজার মেসেজ সেভ করুন
self.topic_memories[self.current_topic].append({
"role": "Human",
"content": user_message
})
# AI মেসেজ সেভ করুন
output_key = list(outputs.keys())[0]
self.topic_memories[self.current_topic].append({
"role": "AI",
"content": outputs[output_key]
})
def clear(self) -> None:
"""মেমরি ক্লিয়ার করে"""
self.topic_memories = {"general": []}
self.current_topic = "general"
# টপিক-বেসড মেমরি ব্যবহার করুন
topic_memory = TopicBasedMemory(llm=llm)
# কনভার্সেশন চেইন তৈরি করুন
topic_conversation = ConversationChain(
llm=llm,
memory=topic_memory,
verbose=True
)
# কয়েকটি প্রম্পট চালান
print("\nTopicBasedMemory উদাহরণ:")
topic_conversation.predict(input="আমার নাম করিম।")
topic_conversation.predict(input="আমি AI নিয়ে কাজ করি।")
topic_conversation.predict(input="বাংলাদেশের রাজধানী কি?")
topic_conversation.predict(input="ঢাকার জনসংখ্যা কত?")
topic_conversation.predict(input="LangChain কি?")
topic_conversation.predict(input="LangChain-এ কি কি কম্পোনেন্ট আছে?")
response = topic_conversation.predict(input="আমার নাম কি এবং আমি কি নিয়ে কাজ করি?")
print("AI:", response)
# মেমরি দেখুন
print("\nটপিক-বেসড মেমরি কনটেন্ট:")
print("বর্তমান টপিক:", topic_memory.current_topic)
print("সমস্ত টপিক:", topic_memory.topic_memories.keys())
for topic, messages in topic_memory.topic_memories.items():
print(f"\nটপিক: {topic}")
for message in messages:
print(f"{message['role']}: {message['content']}")কাস্টম মেমরি ইমপ্লিমেন্টেশনের ইউজ কেস
- ডোমেইন-স্পেসিফিক মেমরি: বিশেষ ডোমেইনের জন্য কাস্টমাইজড মেমরি (যেমন হেলথকেয়ার, লিগাল, ফাইন্যান্স)।
- মাল্টি-ইউজার মেমরি: বিভিন্ন ইউজারের জন্য আলাদা মেমরি ম্যানেজ করা।
- ডাটাবেস-ব্যাকড মেমরি: পারসিস্টেন্ট স্টোরেজের জন্য ডাটাবেস ব্যবহার করা।
- ফেডারেটেড মেমরি: বিভিন্ন সোর্স থেকে মেমরি একত্রিত করা।
- প্রাইভেসি-ফোকাসড মেমরি: সেনসিটিভ ইনফরমেশন ফিল্টার করা বা অবফাসকেট করা।
মেমরি অপ্টিমাইজেশন টেকনিক
গল্প: মেমরি অপ্টিমাইজেশন হল একজন লাইব্রেরিয়ানের মতো, যিনি বইয়ের শেলফ ম্যানেজ করেন। তিনি সবচেয়ে গুরুত্বপূর্ণ বই সামনে রাখেন, পুরনো বা কম ব্যবহৃত বই আর্কাইভ করেন, এবং বইয়ের ক্যাটালগ ব্যবহার করে দ্রুত বই খুঁজে পান।
মেমরি অপ্টিমাইজেশন টেকনিক আপনাকে মেমরি ব্যবহার এফিশিয়েন্ট করতে সাহায্য করে।
1. টোকেন কাউন্টিং এবং ট্রানকেশন
from langchain.memory import ConversationTokenBufferMemory
from langchain_openai import OpenAI
# টোকেন লিমিট সহ মেমরি তৈরি করুন
token_memory = ConversationTokenBufferMemory(
llm=OpenAI(),
max_token_limit=200
)
# কনভার্সেশন চেইন তৈরি করুন
token_conversation = ConversationChain(
llm=llm,
memory=token_memory,
verbose=True
)
# কয়েকটি লম্বা প্রম্পট চালান
print("\nটোকেন কাউন্টিং উদাহরণ:")
token_conversation.predict(input="আমার নাম করিম এবং আমি একজন সফটওয়্যার ইঞ্জিনিয়ার। আমি বাংলাদেশের ঢাকায় থাকি।")
token_conversation.predict(input="আমি AI এবং মেশিন লার্নিং নিয়ে কাজ করি। আমি পাইথন, জাভাস্ক্রিপ্ট, এবং টেনসরফ্লো ব্যবহার করি।")
token_conversation.predict(input="আমি LangChain শিখছি কারণ আমি একটি AI চ্যাটবট তৈরি করতে চাই। আমি RAG ইমপ্লিমেন্ট করতে চাই।")
response = token_conversation.predict(input="আমার পেশা কি?")
print("AI:", response)
# মেমরি দেখুন
print("\nটোকেন মেমরি কনটেন্ট:")
print(token_memory.buffer)2. রিলেভেন্সি-বেসড মেমরি
from langchain.memory import VectorStoreRetrieverMemory
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
# এমবেডিংস তৈরি করুন
embeddings = OpenAIEmbeddings()
# ভেক্টর স্টোর তৈরি করুন
vectorstore = FAISS.from_texts([""], embeddings)
# রিট্রিভার তৈরি করুন
retriever = vectorstore.as_retriever(search_kwargs=dict(k=1))
# ভেক্টর স্টোর মেমরি তৈরি করুন
vector_memory = VectorStoreRetrieverMemory(retriever=retriever)
# মেমরি পপুলেট করুন
vector_memory.save_context(
{"input": "আমার নাম করিম।"},
{"output": "হ্যালো করিম, আপনাকে জানতে পেরে খুশি হলাম।"}
)
vector_memory.save_context(
{"input": "আমি একজন সফটওয়্যার ইঞ্জিনিয়ার।"},
{"output": "সফটওয়্যার ইঞ্জিনিয়ারিং একটি দারুণ পেশা।"}
)
vector_memory.save_context(
{"input": "আমি ঢাকায় থাকি।"},
{"output": "ঢাকা বাংলাদেশের রাজধানী।"}
)
vector_memory.save_context(
{"input": "আমি AI নিয়ে কাজ করি।"},
{"output": "AI একটি আকর্ষণীয় ফিল্ড।"}
)
# রিলেভেন্ট মেমরি রিট্রিভ করুন
print("\nরিলেভেন্সি-বেসড মেমরি উদাহরণ:")
print("প্রশ্ন: আমার পেশা কি?")
relevant_memory = vector_memory.load_memory_variables({"input": "আমার পেশা কি?"})
print("রিলেভেন্ট মেমরি:", relevant_memory["history"])
print("\nপ্রশ্ন: আমি কোথায় থাকি?")
relevant_memory = vector_memory.load_memory_variables({"input": "আমি কোথায় থাকি?"})
print("রিলেভেন্ট মেমরি:", relevant_memory["history"])3. কম্বাইন্ড মেমরি টেকনিক
from langchain.memory import CombinedMemory
# বিভিন্ন মেমরি কম্পোনেন্ট তৈরি করুন
conv_memory = ConversationBufferMemory(memory_key="chat_history")
summary_memory = ConversationSummaryMemory(llm=llm, memory_key="summary")
# কম্বাইন্ড মেমরি তৈরি করুন
combined_memory = CombinedMemory(memories=[conv_memory, summary_memory])
# কনভার্সেশন চেইন তৈরি করুন
combined_conversation = ConversationChain(
llm=llm,
memory=combined_memory,
verbose=True
)
# কয়েকটি প্রম্পট চালান
print("\nCombinedMemory উদাহরণ:")
combined_conversation.predict(input="আমার নাম করিম।")
combined_conversation.predict(input="আমি একজন সফটওয়্যার ইঞ্জিনিয়ার।")
combined_conversation.predict(input="আমি ঢাকায় থাকি।")
response = combined_conversation.predict(input="আমার সম্পর্কে কি মনে আছে?")
print("AI:", response)
# মেমরি দেখুন
print("\nকম্বাইন্ড মেমরি কনটেন্ট:")
print("চ্যাট হিস্টোরি:", conv_memory.buffer)
print("সামারি:", summary_memory.buffer)4. মেমরি কম্প্রেশন
from langchain.memory import ConversationSummaryBufferMemory
# কম্প্রেশন সহ মেমরি তৈরি করুন
compressed_memory = ConversationSummaryBufferMemory(
llm=llm,
max_token_limit=100,
return_messages=True
)
# কনভার্সেশন চেইন তৈরি করুন
compressed_conversation = ConversationChain(
llm=llm,
memory=compressed_memory,
verbose=True
)
# কয়েকটি লম্বা প্রম্পট চালান
print("\nমেমরি কম্প্রেশন উদাহরণ:")
compressed_conversation.predict(input="আমার নাম করিম এবং আমি একজন সফটওয়্যার ইঞ্জিনিয়ার। আমি বাংলাদেশের ঢাকায় থাকি।")
compressed_conversation.predict(input="আমি AI এবং মেশিন লার্নিং নিয়ে কাজ করি। আমি পাইথন, জাভাস্ক্রিপ্ট, এবং টেনসরফ্লো ব্যবহার করি।")
compressed_conversation.predict(input="আমি LangChain শিখছি কারণ আমি একটি AI চ্যাটবট তৈরি করতে চাই। আমি RAG ইমপ্লিমেন্ট করতে চাই।")
compressed_conversation.predict(input="আমার হবি হল প্রোগ্রামিং, বই পড়া, এবং ভ্রমণ করা। আমি সাম্প্রতিক সময়ে নেপাল ভ্রমণ করেছি।")
response = compressed_conversation.predict(input="আমার পেশা এবং হবি কি?")
print("AI:", response)
# মেমরি দেখুন
print("\nকম্প্রেসড মেমরি কনটেন্ট:")
print("মেসেজ:", compressed_memory.buffer)
print("মুভিং সামারি:", compressed_memory.moving_summary_buffer)5. ডাটাবেস-ব্যাকড মেমরি
from langchain.memory import MongoDBChatMessageHistory
from langchain.memory import ConversationBufferMemory
# মঙ্গোডিবি কানেকশন স্ট্রিং (এখানে ডেমো উদ্দেশ্যে)
connection_string = "mongodb://localhost:27017"
# মঙ্গোডিবি মেসেজ হিস্টোরি তৈরি করুন (এখানে কোড শুধু উদাহরণ হিসেবে দেখানো হয়েছে)
# message_history = MongoDBChatMessageHistory(
# connection_string=connection_string,
# session_id="user-123",
# database_name="langchain",
# collection_name="conversations"
# )
# # মেসেজ হিস্টোরি থেকে মেমরি তৈরি করুন
# mongodb_memory = ConversationBufferMemory(
# memory_key="chat_history",
# chat_memory=message_history
# )
# # কনভার্সেশন চেইন তৈরি করুন
# mongodb_conversation = ConversationChain(
# llm=llm,
# memory=mongodb_memory,
# verbose=True
# )
print("\nডাটাবেস-ব্যাকড মেমরি উদাহরণ:")
print("এই উদাহরণে, আমরা মঙ্গোডিবি ব্যবহার করে মেমরি স্টোর করি।")
print("এটি পারসিস্টেন্ট স্টোরেজ প্রদান করে, যাতে অ্যাপ্লিকেশন রিস্টার্ট করার পরেও মেমরি থাকে।")
print("এটি মাল্টিপল ইউজার এবং সেশন ম্যানেজ করতেও সাহায্য করে।")মেমরি অপ্টিমাইজেশন বেস্ট প্র্যাকটিস
- টোকেন ম্যানেজমেন্ট: টোকেন কাউন্ট মনিটর করুন এবং লিমিট সেট করুন।
- রিলেভেন্সি ফিল্টারিং: শুধু বর্তমান প্রম্পটের জন্য রিলেভেন্ট মেমরি ব্যবহার করুন।
- সামারাইজেশন: লম্বা কনভার্সেশন সামারাইজ করুন।
- প্রুনিং: অপ্রয়োজনীয় বা পুরনো মেমরি রিমুভ করুন।
- শার্ডিং: বিভিন্ন টাইপের মেমরি আলাদা করুন (যেমন ফ্যাক্টুয়াল, পার্সোনাল, কনটেক্সচুয়াল)।
- ক্যাশিং: কমন কোয়েরি রেজাল্ট ক্যাশ করুন।
- ইনডেক্সিং: দ্রুত রিট্রিভালের জন্য মেমরি ইনডেক্স করুন।
প্র্যাকটিকাল এক্সারসাইজ: মাল্টি-ইউজার চ্যাটবট
এখন আমরা আমাদের শেখা সবকিছু একত্রিত করে একটি মাল্টি-ইউজার চ্যাটবট তৈরি করব:
# multi_user_chatbot.py
from langchain.memory import ConversationSummaryBufferMemory
from langchain.chains import ConversationChain
from langchain_openai import ChatOpenAI
from typing import Dict, Any
from dotenv import load_dotenv
import os
import json
# .env ফাইল থেকে API কি লোড করুন
load_dotenv()
class MultiUserChatbot:
"""
মাল্টি-ইউজার চ্যাটবট যা প্রতিটি ইউজারের জন্য আলাদা মেমরি রাখে।
"""
def __init__(self, model_name="gpt-3.5-turbo", temperature=0.7, memory_type="summary_buffer"):
"""চ্যাটবট ইনিশিয়ালাইজ করুন"""
self.llm = ChatOpenAI(
model=model_name,
temperature=temperature,
api_key=os.getenv("OPENAI_API_KEY")
)
self.memory_type = memory_type
self.user_memories = {}
self.user_chains = {}
def _create_memory(self, user_id):
"""ইউজারের জন্য মেমরি তৈরি করুন"""
if self.memory_type == "summary_buffer":
return ConversationSummaryBufferMemory(
llm=self.llm,
max_token_limit=500,
return_messages=True
)
else:
# ডিফল্ট: কনভার্সেশন বাফার মেমরি
return ConversationBufferMemory()
def _get_or_create_chain(self, user_id):
"""ইউজারের জন্য কনভার্সেশন চেইন পান বা তৈরি করুন"""
if user_id not in self.user_chains:
# নতুন মেমরি তৈরি করুন
memory = self._create_memory(user_id)
self.user_memories[user_id] = memory
# নতুন চেইন তৈরি করুন
self.user_chains[user_id] = ConversationChain(
llm=self.llm,
memory=memory,
verbose=False
)
return self.user_chains[user_id]
def chat(self, user_id, message):
"""ইউজারের মেসেজের রেসপন্স দিন"""
# ইউজারের চেইন পান
chain = self._get_or_create_chain(user_id)
# মেসেজ প্রসেস করুন
response = chain.predict(input=message)
return response
def get_conversation_history(self, user_id):
"""ইউজারের কনভার্সেশন হিস্টোরি রিটার্ন করুন"""
if user_id in self.user_memories:
memory = self.user_memories[user_id]
return memory.buffer
return "কোন কনভার্সেশন হিস্টোরি নেই।"
def clear_history(self, user_id):
"""ইউজারের কনভার্সেশন হিস্টোরি ক্লিয়ার করুন"""
if user_id in self.user_memories:
self.user_memories[user_id].clear()
return True
return False
def save_histories(self, filename="chat_histories.json"):
"""সমস্ত ইউজারের চ্যাট হিস্টোরি সেভ করুন"""
histories = {}
for user_id, memory in self.user_memories.items():
histories[user_id] = memory.buffer
with open(filename, 'w', encoding='utf-8') as f:
json.dump(histories, f, ensure_ascii=False, indent=4)
return f"{len(histories)} ইউজারের চ্যাট হিস্টোরি সেভ করা হয়েছে।"
def load_histories(self, filename="chat_histories.json"):
"""সমস্ত ইউজারের চ্যাট হিস্টোরি লোড করুন"""
try:
with open(filename, 'r', encoding='utf-8') as f:
histories = json.load(f)
# প্রতিটি ইউজারের হিস্টোরি লোড করুন
for user_id, history in histories.items():
# ইউজারের চেইন পান বা তৈরি করুন
chain = self._get_or_create_chain(user_id)
# হিস্টোরি লোড করুন
self.user_memories[user_id].buffer = history
return f"{len(histories)} ইউজারের চ্যাট হিস্টোরি লোড করা হয়েছে।"
except FileNotFoundError:
return "চ্যাট হিস্টোরি ফাইল পাওয়া যায়নি।"
# চ্যাটবট ব্যবহার করুন
if __name__ == "__main__":
# চ্যাটবট তৈরি করুন
chatbot = MultiUserChatbot()
print("মাল্টি-ইউজার চ্যাটবট")
print("=" * 50)
print("ইউজার আইডি এবং মেসেজ দিয়ে চ্যাট করুন।")
print("'exit' লিখে বের হন।")
print("'switch <user_id>' লিখে ইউজার পরিবর্তন করুন।")
print("'history' লিখে বর্তমান ইউজারের হিস্টোরি দেখুন।")
print("'clear' লিখে বর্তমান ইউজারের হিস্টোরি ক্লিয়ার করুন।")
print("=" * 50)
current_user = "user-1"
print(f"বর্তমান ইউজার: {current_user}")
while True:
user_input = input(f"{current_user} > ")
if user_input.lower() == 'exit':
break
elif user_input.lower().startswith('switch '):
current_user = user_input.split(' ')[1]
print(f"ইউজার পরিবর্তন করা হয়েছে: {current_user}")
elif user_input.lower() == 'history':
history = chatbot.get_conversation_history(current_user)
print("\nকনভার্সেশন হিস্টোরি:")
print(history)
elif user_input.lower() == 'clear':
chatbot.clear_history(current_user)
print("কনভার্সেশন হিস্টোরি ক্লিয়ার করা হয়েছে।")
elif user_input.lower() == 'save':
result = chatbot.save_histories()
print(result)
elif user_input.lower() == 'load':
result = chatbot.load_histories()
print(result)
else:
response = chatbot.chat(current_user, user_input)
print(f"AI: {response}")সারাংশ
এই টিউটোরিয়ালে, আমরা শিখেছি:
- মেমরি কি এবং কেন প্রয়োজন: মেমরি LLM-কে আগের ইন্টারাকশন মনে রাখতে সাহায্য করে, যা কনটেক্সচুয়াল কনভার্সেশন, পার্সোনালাইজেশন, এবং কনটিনিউটি প্রদান করে।
- কনভার্সেশন বাফার মেমরি: সবচেয়ে সিম্পল মেমরি টাইপ, যা সমস্ত আগের মেসেজ স্টোর করে। এর ভেরিয়েন্ট হল ConversationBufferWindowMemory এবং ConversationTokenBufferMemory।
- সামারি মেমরি: কনভার্সেশনের একটি সংক্ষিপ্ত সারাংশ তৈরি করে এবং স্টোর করে, যা টোকেন ব্যবহার কমায় এবং লম্বা কনভার্সেশন হ্যান্ডেল করতে সাহায্য করে।
- এন্টিটি মেমরি: কনভার্সেশনে উল্লেখিত বিভিন্ন এন্টিটি সম্পর্কে তথ্য স্টোর করে, যা পার্সোনালাইজড রেসপন্স তৈরি করতে সাহায্য করে।
- কাস্টম মেমরি ইমপ্লিমেন্টেশন: BaseMemory এক্সটেন্ড করে কাস্টম মেমরি তৈরি করা, যা বিশেষ প্রয়োজন পূরণ করতে পারে।
- মেমরি অপ্টিমাইজেশন টেকনিক: টোকেন কাউন্টিং, রিলেভেন্সি-বেসড মেমরি, কম্বাইন্ড মেমরি, মেমরি কম্প্রেশন, এবং ডাটাবেস-ব্যাকড মেমরি।
অতিরিক্ত অনুশীলনী
- মাল্টি-মোডাল মেমরি: একটি মেমরি সিস্টেম তৈরি করুন যা টেক্সট, ইমেজ, এবং অডিও রেফারেন্স স্টোর করতে পারে।
- প্রাইভেসি-ফোকাসড মেমরি: একটি মেমরি সিস্টেম তৈরি করুন যা সেনসিটিভ ইনফরমেশন (যেমন ইমেইল, ফোন নম্বর) ডিটেক্ট করে এবং অবফাসকেট করে।
- টাইম-বেসড মেমরি ডিকে: একটি মেমরি সিস্টেম তৈরি করুন যেখানে পুরনো মেমরি ধীরে ধীরে কম গুরুত্বপূর্ণ হয়ে যায়।
- মাল্টি-পার্সোনা চ্যাটবট: একটি চ্যাটবট তৈরি করুন যা বিভিন্ন পার্সোনা (যেমন টিচার, ফ্রেন্ড, কোচ) অ্যাডপ্ট করতে পারে এবং প্রতিটি পার্সোনার জন্য আলাদা মেমরি রাখে।
- ডিস্ট্রিবিউটেড মেমরি সিস্টেম: একটি মেমরি সিস্টেম তৈরি করুন যা বিভিন্ন সার্ভারে ডিস্ট্রিবিউট করা যায়।
পরবর্তী ধাপ
পরবর্তী টিউটোরিয়ালে, আমরা LangChain-এর এজেন্ট কম্পোনেন্ট নিয়ে আলোচনা করব। আমরা শিখব কিভাবে এজেন্ট তৈরি করতে হয়, কিভাবে টুল ব্যবহার করতে হয়, এবং কিভাবে এজেন্টকে কমপ্লেক্স টাস্ক সম্পাদন করতে সাহায্য করতে হয়।
উপসংহার
আজকের টিউটোরিয়ালে, আমরা LangChain-এর মেমরি কম্পোনেন্ট সম্পর্কে বিস্তারিত জেনেছি। আমরা দেখেছি কিভাবে বিভিন্ন ধরনের মেমরি ব্যবহার করে LLM-কে আগের ইন্টারাকশন মনে রাখতে সাহায্য করা যায়।
মেমরি হল LangChain-এর একটি গুরুত্বপূর্ণ কম্পোনেন্ট যা আপনার AI অ্যাপ্লিকেশনকে আরও ইন্টেলিজেন্ট, কনটেক্সচুয়াল, এবং পার্সোনালাইজড করতে সাহায্য করে। আপনি যত বেশি মেমরি টেকনিক ব্যবহার করবেন, তত বেশি আপনার অ্যাপ্লিকেশন ইউজারদের সাথে ন্যাচারাল ইন্টারাকশন করতে পারবে।
আপনার অনুশীলনের জন্য, আমি আপনাকে উৎসাহিত করি বিভিন্ন ধরনের মেমরি এক্সপেরিমেন্ট করতে এবং আপনার নিজের প্রয়োজন অনুযায়ী কাস্টম মেমরি তৈরি করতে।
ধন্যবাদ এবং শুভকামনা আপনার LangChain যাত্রায়!