ভূমিকা
গল্প: রহিম একজন ডেভেলপার যিনি একটি AI-ভিত্তিক কন্টেন্ট জেনারেশন সিস্টেম তৈরি করছেন। তিনি LangChain ব্যবহার করে শুরু করেছেন এবং সিম্পল প্রম্পট-রেসপন্স পাটার্ন ব্যবহার করে কিছু ফিচার তৈরি করেছেন। কিন্তু তিনি দেখলেন যে তার অ্যাপ্লিকেশনে আরও জটিল ওয়ার্কফ্লো প্রয়োজন – যেমন একটি ইনপুট নিয়ে বিভিন্ন ধাপে প্রসেস করা, বিভিন্ন মডেল একসাথে ব্যবহার করা, বা ইনপুটের উপর ভিত্তি করে ভিন্ন ভিন্ন প্রসেসিং পাথ বেছে নেওয়া।
রহিম ভাবছেন, “আমি কিভাবে এই জটিল ওয়ার্কফ্লোগুলি সহজে ম্যানেজ করতে পারি? আমি কিভাবে বিভিন্ন কম্পোনেন্ট একসাথে কানেক্ট করতে পারি?”
এই টিউটোরিয়ালে, আমরা LangChain-এর চেইন কনসেপ্ট নিয়ে আলোচনা করব, যা রহিমের মতো ডেভেলপারদের জটিল AI ওয়ার্কফ্লো তৈরি করতে সাহায্য করে।
চেইন কি এবং কেন ব্যবহার করবেন
গল্প: চেইন বোঝার জন্য, একটি রেস্টুরেন্টের কিচেন কল্পনা করুন। একজন শেফ (LLM) সবকিছু একা করতে পারেন, কিন্তু একটি বড় রেস্টুরেন্টে, বিভিন্ন শেফ বিভিন্ন কাজ করেন – কেউ সালাদ তৈরি করে, কেউ মেইন ডিশ রান্না করে, কেউ ডেজার্ট তৈরি করে। এই শেফদের কাজের ফ্লো একটি চেইনের মতো – একজনের আউটপুট অন্যজনের ইনপুট হয়।
চেইন কি?
LangChain-এ, চেইন হল একটি কম্পোনেন্ট যা একটি বা একাধিক LLM কল, প্রম্পট, পার্সার, বা অন্যান্য চেইন একত্রিত করে একটি সিঙ্গেল, কোহেরেন্ট অ্যাপ্লিকেশন তৈরি করে।
চেইন আপনাকে সাহায্য করে:
- বিভিন্ন কম্পোনেন্ট একসাথে কানেক্ট করতে
- জটিল ওয়ার্কফ্লো সিম্পল ইন্টারফেস দিয়ে ম্যানেজ করতে
- ডাটা প্রসেসিং স্টেপ সিকোয়েন্স ডিফাইন করতে
- রিইউজেবল কম্পোনেন্ট তৈরি করতে
কেন চেইন ব্যবহার করবেন?
- মডুলারিটি: জটিল লজিক ছোট, ম্যানেজেবল কম্পোনেন্টে ভাগ করা যায়
- রিইউজেবিলিটি: একবার তৈরি করা চেইন বিভিন্ন অ্যাপ্লিকেশনে ব্যবহার করা যায়
- কমপ্লেক্সিটি ম্যানেজমেন্ট: জটিল ওয়ার্কফ্লো সহজে ম্যানেজ করা যায়
- ডিবাগিং: ওয়ার্কফ্লোর বিভিন্ন অংশ আলাদাভাবে টেস্ট করা যায়
- ফ্লেক্সিবিলিটি: ওয়ার্কফ্লো সহজে মডিফাই করা যায়
সিম্পল LLM চেইন
সবচেয়ে বেসিক চেইন হল LLMChain, যা একটি প্রম্পট টেমপ্লেট এবং একটি LLM একত্রিত করে।
LLMChain
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
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")
)
# প্রম্পট টেমপ্লেট তৈরি করুন
prompt = PromptTemplate(
input_variables=["topic"],
template="আমাকে {topic} সম্পর্কে পাঁচটি আকর্ষণীয় তথ্য দিন।"
)
# LLMChain তৈরি করুন
chain = LLMChain(llm=llm, prompt=prompt)
# চেইন রান করুন
result = chain.invoke({"topic": "বাংলাদেশের মুক্তিযুদ্ধ"})
print("LLMChain রেজাল্ট:")
print(result["text"])LLMChain-এর কম্পোনেন্ট
- প্রম্পট টেমপ্লেট: ইউজার ইনপুট ফরম্যাট করে LLM-এ পাঠানোর জন্য
- LLM: প্রম্পট প্রসেস করে রেসপন্স জেনারেট করে
- আউটপুট পার্সার (অপশনাল): LLM আউটপুট পার্স করে স্ট্রাকচারড ফরম্যাটে কনভার্ট করে
LLMChain-এর ইউজ কেস
- সিম্পল টেক্সট জেনারেশন
- কোয়েশ্চেন আন্সারিং
- সামারাইজেশন
- ক্লাসিফিকেশন
- ট্রান্সলেশন
LLMChain-এর ভেরিয়েশন
# স্ট্রাকচারড আউটপুট সহ LLMChain
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
# আউটপুট স্কিমা ডিফাইন করুন
response_schemas = [
ResponseSchema(name="fact_1", description="প্রথম আকর্ষণীয় তথ্য"),
ResponseSchema(name="fact_2", description="দ্বিতীয় আকর্ষণীয় তথ্য"),
ResponseSchema(name="fact_3", description="তৃতীয় আকর্ষণীয় তথ্য"),
ResponseSchema(name="fact_4", description="চতুর্থ আকর্ষণীয় তথ্য"),
ResponseSchema(name="fact_5", description="পঞ্চম আকর্ষণীয় তথ্য"),
]
# পার্সার তৈরি করুন
parser = StructuredOutputParser.from_response_schemas(response_schemas)
format_instructions = parser.get_format_instructions()
# প্রম্পট টেমপ্লেট আপডেট করুন
structured_prompt = PromptTemplate(
input_variables=["topic"],
template="আমাকে {topic} সম্পর্কে পাঁচটি আকর্ষণীয় তথ্য দিন।\n{format_instructions}"
)
# স্ট্রাকচারড আউটপুট সহ LLMChain তৈরি করুন
structured_chain = LLMChain(
llm=llm,
prompt=structured_prompt,
output_parser=parser
)
# চেইন রান করুন
structured_result = structured_chain.invoke({
"topic": "বাংলাদেশের মুক্তিযুদ্ধ",
"format_instructions": format_instructions
})
print("\nস্ট্রাকচারড LLMChain রেজাল্ট:")
for key, value in structured_result["text"].items():
print(f"{key}: {value}")সিকোয়েন্শিয়াল চেইন
গল্প: সিকোয়েন্শিয়াল চেইন একটি অ্যাসেম্বলি লাইনের মতো কাজ করে। প্রথম ওয়ার্কার (চেইন) একটি কাজ করে, তারপর সেই আউটপুট পরবর্তী ওয়ার্কারের কাছে পাঠায়, এভাবে চলতে থাকে।
সিকোয়েন্শিয়াল চেইন দুই বা ততোধিক চেইন একসাথে কানেক্ট করে, যেখানে একটি চেইনের আউটপুট পরবর্তী চেইনের ইনপুট হিসেবে ব্যবহৃত হয়।
SimpleSequentialChain
SimpleSequentialChain হল সবচেয়ে সিম্পল সিকোয়েন্শিয়াল চেইন, যেখানে প্রতিটি চেইনের একটি সিঙ্গেল ইনপুট এবং একটি সিঙ্গেল আউটপুট থাকে।
from langchain.chains import SimpleSequentialChain
# প্রথম চেইন: টপিক জেনারেশন
topic_prompt = PromptTemplate(
input_variables=["country"],
template="বাংলাদেশের ইতিহাসের একটি গুরুত্বপূর্ণ ঘটনা উল্লেখ করুন যা {country} এর সাথে সম্পর্কিত।"
)
topic_chain = LLMChain(llm=llm, prompt=topic_prompt)
# দ্বিতীয় চেইন: বিস্তারিত বিবরণ
detail_prompt = PromptTemplate(
input_variables=["topic"],
template="নিম্নলিখিত ঘটনা সম্পর্কে বিস্তারিত বিবরণ দিন: {topic}"
)
detail_chain = LLMChain(llm=llm, prompt=detail_prompt)
# সিকোয়েন্শিয়াল চেইন তৈরি করুন
sequential_chain = SimpleSequentialChain(chains=[topic_chain, detail_chain], verbose=True)
# চেইন রান করুন
sequential_result = sequential_chain.invoke({"country": "ভারত"})
print("\nSimpleSequentialChain রেজাল্ট:")
print(sequential_result)SequentialChain
SequentialChain আরও ফ্লেক্সিবল, যেখানে প্রতিটি চেইনের মাল্টিপল ইনপুট এবং আউটপুট থাকতে পারে।
from langchain.chains import SequentialChain
# প্রথম চেইন: ঘটনা জেনারেশন
event_prompt = PromptTemplate(
input_variables=["country", "year"],
template="{year} সালে {country} এবং বাংলাদেশের মধ্যে একটি গুরুত্বপূর্ণ ঘটনা উল্লেখ করুন।"
)
event_chain = LLMChain(
llm=llm,
prompt=event_prompt,
output_key="event" # আউটপুট কি নাম
)
# দ্বিতীয় চেইন: ঘটনার প্রভাব
impact_prompt = PromptTemplate(
input_variables=["event", "country"],
template="নিম্নলিখিত ঘটনার বাংলাদেশ এবং {country} এর উপর প্রভাব বিশ্লেষণ করুন: {event}"
)
impact_chain = LLMChain(
llm=llm,
prompt=impact_prompt,
output_key="impact" # আউটপুট কি নাম
)
# তৃতীয় চেইন: ভবিষ্যৎ সম্পর্ক
future_prompt = PromptTemplate(
input_variables=["event", "impact", "country"],
template="""
নিম্নলিখিত ঘটনা এবং প্রভাব বিবেচনা করে, বাংলাদেশ এবং {country} এর ভবিষ্যৎ সম্পর্ক কেমন হতে পারে তা বিশ্লেষণ করুন:
ঘটনা: {event}
প্রভাব: {impact}
"""
)
future_chain = LLMChain(
llm=llm,
prompt=future_prompt,
output_key="future_relations" # আউটপুট কি নাম
)
# SequentialChain তৈরি করুন
sequential_chain = SequentialChain(
chains=[event_chain, impact_chain, future_chain],
input_variables=["country", "year"], # মূল ইনপুট ভেরিয়েবল
output_variables=["event", "impact", "future_relations"], # আউটপুট ভেরিয়েবল
verbose=True
)
# চেইন রান করুন
sequential_result = sequential_chain.invoke({
"country": "ভারত",
"year": "1971"
})
print("\nSequentialChain রেজাল্ট:")
print("ঘটনা:", sequential_result["event"])
print("\nপ্রভাব:", sequential_result["impact"])
print("\nভবিষ্যৎ সম্পর্ক:", sequential_result["future_relations"])সিকোয়েন্শিয়াল চেইনের ইউজ কেস
- মাল্টি-স্টেপ কন্টেন্ট জেনারেশন (আউটলাইন → ড্রাফ্ট → এডিট)
- ডাটা ট্রান্সফরমেশন পাইপলাইন (রো ডাটা → ক্লিন → অ্যানালাইজ)
- কমপ্লেক্স রিসার্চ টাস্ক (টপিক জেনারেশন → ইনফরমেশন গ্যাদারিং → সামারাইজেশন)
- কন্টেন্ট ট্রান্সলেশন এবং অ্যাডাপ্টেশন (ট্রান্সলেট → লোকালাইজ → ফরম্যাট)
ট্রান্সফরমেশন চেইন
গল্প: ট্রান্সফরমেশন চেইন একটি রেসিপি ট্রান্সফরমারের মতো। আপনি একটি রেসিপি দিলে, এটি সেই রেসিপিকে বিভিন্নভাবে ট্রান্সফর্ম করতে পারে – যেমন ভেজিটেরিয়ান ভার্সনে, গ্লুটেন-ফ্রি ভার্সনে, বা বড় গ্রুপের জন্য স্কেল করে।
ট্রান্সফরমেশন চেইন একটি ইনপুট নিয়ে সেটিকে বিভিন্ন ফরম্যাটে ট্রান্সফর্ম করে। LangChain-এ MapReduceChain এবং MapRerankChain হল ট্রান্সফরমেশন চেইনের উদাহরণ।
MapReduceChain
MapReduceChain বড় ডকুমেন্ট প্রসেস করার জন্য ব্যবহৃত হয়। এটি ডকুমেন্টকে ছোট ছোট অংশে ভাগ করে (map), প্রতিটি অংশ প্রসেস করে, এবং তারপর রেজাল্টগুলি একত্রিত করে (reduce)।
from langchain.chains.mapreduce import MapReduceChain
from langchain.text_splitter import CharacterTextSplitter
from langchain_openai import OpenAI
# টেক্সট স্প্লিটার সেটআপ করুন
text_splitter = CharacterTextSplitter.from_tiktoken_encoder(
chunk_size=1000,
chunk_overlap=0
)
# LLM সেটআপ করুন (OpenAI টেক্সট মডেল)
llm = OpenAI(
model="gpt-3.5-turbo-instruct",
temperature=0,
api_key=os.getenv("OPENAI_API_KEY")
)
# MapReduceChain তৈরি করুন
map_reduce_chain = MapReduceChain.from_params(
llm=llm,
prompt=PromptTemplate(
input_variables=["text"],
template="নিম্নলিখিত টেক্সট থেকে মূল পয়েন্টগুলি বের করুন:\n\n{text}"
),
combine_prompt=PromptTemplate(
input_variables=["text"],
template="নিম্নলিখিত পয়েন্টগুলি একত্রিত করে একটি সংক্ষিপ্ত সারাংশ তৈরি করুন:\n\n{text}"
),
text_splitter=text_splitter,
return_intermediate_steps=True,
verbose=True
)
# লম্বা টেক্সট
long_text = """
বাংলাদেশের স্বাধীনতা যুদ্ধ ১৯৭১ সালে সংঘটিত হয়েছিল। এটি ছিল পাকিস্তানের বিরুদ্ধে বাঙালি জাতির মুক্তি সংগ্রাম। যুদ্ধের প্রধান কারণ ছিল পশ্চিম পাকিস্তানের শাসকগোষ্ঠীর দ্বারা পূর্ব পাকিস্তানের (বর্তমান বাংলাদেশ) উপর রাজনৈতিক, অর্থনৈতিক, সামাজিক ও সাংস্কৃতিক শোষণ।
১৯৭০ সালের নির্বাচনে আওয়ামী লীগ পূর্ব পাকিস্তানে নিরঙ্কুশ সংখ্যাগরিষ্ঠতা লাভ করে। কিন্তু পাকিস্তানি সামরিক জান্তা ক্ষমতা হস্তান্তর করতে অস্বীকার করে। ১৯৭১ সালের ২৫ মার্চ রাতে পাকিস্তানি সেনাবাহিনী 'অপারেশন সার্চলাইট' নামে একটি গণহত্যা শুরু করে, যাতে হাজার হাজার নিরীহ বাঙালি নিহত হয়।
২৬ মার্চ বঙ্গবন্ধু শেখ মুজিবুর রহমান বাংলাদেশের স্বাধীনতা ঘোষণা করেন। এরপর শুরু হয় নয় মাসব্যাপী রক্তক্ষয়ী যুদ্ধ। ভারত বাংলাদেশের স্বাধীনতা যুদ্ধে সামরিক, কূটনৈতিক ও মানবিক সহায়তা প্রদান করে। ১৬ ডিসেম্বর পাকিস্তানি বাহিনী আত্মসমর্পণ করে এবং বাংলাদেশ স্বাধীন হয়।
স্বাধীনতা যুদ্ধে প্রায় ৩০ লক্ষ বাঙালি শহীদ হন এবং প্রায় ২ লক্ষ নারী সম্ভ্রমহারা হন। এটি ছিল বিশ্বের অন্যতম বড় গণহত্যা। যুদ্ধের সময় প্রায় ১ কোটি বাঙালি ভারতে শরণার্থী হিসেবে আশ্রয় নেয়।
স্বাধীনতার পর বাংলাদেশ ধীরে ধীরে পুনর্গঠিত হয়। ১৯৭২ সালে বাংলাদেশের সংবিধান প্রণীত হয়, যেখানে গণতন্ত্র, জাতীয়তাবাদ, সমাজতন্ত্র ও ধর্মনিরপেক্ষতাকে রাষ্ট্রের মূলনীতি হিসেবে গ্রহণ করা হয়।
বর্তমানে বাংলাদেশ দক্ষিণ এশিয়ার একটি গুরুত্বপূর্ণ দেশ। গার্মেন্টস শিল্প, কৃষি, রেমিট্যান্স ইত্যাদি দেশের অর্থনীতির প্রধান চালিকাশক্তি। বাংলাদেশ এখন মধ্যম আয়ের দেশে উন্নীত হয়েছে এবং ২০৪১ সালের মধ্যে উন্নত দেশে পরিণত হওয়ার লক্ষ্য নিয়ে এগিয়ে চলেছে।
"""
# MapReduceChain রান করুন
map_reduce_result = map_reduce_chain.invoke({"input_documents": [long_text]})
print("\nMapReduceChain রেজাল্ট:")
print(map_reduce_result["output_text"])
# ইন্টারমিডিয়েট স্টেপ দেখুন
print("\nম্যাপ স্টেপ রেজাল্ট:")
for i, step in enumerate(map_reduce_result["intermediate_steps"]):
print(f"চাংক {i+1}:")
print(step)
print("-" * 50)RefineChain
RefineChain একটি ইটারেটিভ অ্যাপ্রোচ ব্যবহার করে। এটি প্রথম চাংক প্রসেস করে, তারপর সেই রেজাল্ট এবং পরবর্তী চাংক নিয়ে রিফাইন করে, এভাবে চলতে থাকে।
from langchain.chains.summarize import load_summarize_chain
from langchain.docstore.document import Document
# ডকুমেন্ট তৈরি করুন
docs = [Document(page_content=long_text)]
# RefineChain তৈরি করুন
refine_chain = load_summarize_chain(
llm=llm,
chain_type="refine",
verbose=True
)
# RefineChain রান করুন
refine_result = refine_chain.invoke({"input_documents": docs})
print("\nRefineChain রেজাল্ট:")
print(refine_result["output_text"])ট্রান্সফরমেশন চেইনের ইউজ কেস
- লং ডকুমেন্ট সামারাইজেশন
- লার্জ ডাটাসেট অ্যানালাইসিস
- পারাললাইজেবল টাস্ক (একই টাইপের মাল্টিপল টাস্ক)
- ইনক্রিমেন্টাল রিফাইনমেন্ট (ধাপে ধাপে উন্নত করা)
রাউটার চেইন
গল্প: রাউটার চেইন একজন ট্রাফিক পুলিশের মতো কাজ করে। ট্রাফিক পুলিশ যেমন গাড়িগুলোকে বিভিন্ন রাস্তায় নির্দেশিত করে, রাউটার চেইনও ইনপুটের উপর ভিত্তি করে বিভিন্ন চেইনে নির্দেশিত করে।
রাউটার চেইন ইনপুটের উপর ভিত্তি করে কোন চেইন ব্যবহার করবে তা ডিসাইড করে। এটি ডিফারেন্ট টাইপের কোয়েরি বা টাস্ক হ্যান্ডেল করার জন্য ব্যবহৃত হয়।
MultiPromptChain
from langchain.chains.router import MultiPromptChain
from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.prompts import PromptTemplate
# ডিফারেন্ট টপিকের জন্য প্রম্পট ডিফাইন করুন
history_prompt = PromptTemplate(
template="""আপনি একজন ইতিহাস বিশেষজ্ঞ। নিম্নলিখিত প্রশ্নের উত্তর দিন:
{input}
""",
input_variables=["input"],
)
science_prompt = PromptTemplate(
template="""আপনি একজন বিজ্ঞান বিশেষজ্ঞ। নিম্নলিখিত প্রশ্নের উত্তর দিন:
{input}
""",
input_variables=["input"],
)
literature_prompt = PromptTemplate(
template="""আপনি একজন সাহিত্য বিশেষজ্ঞ। নিম্নলিখিত প্রশ্নের উত্তর দিন:
{input}
""",
input_variables=["input"],
)
# রাউটার টেমপ্লেট তৈরি করুন
router_template = """নিম্নলিখিত প্রশ্নটি কোন ক্যাটাগরির অন্তর্গত তা নির্ধারণ করুন।
প্রশ্ন: {input}
ক্যাটাগরি: "ইতিহাস", "বিজ্ঞান", বা "সাহিত্য"। যদি কোনটিই না হয়, তাহলে "ইতিহাস" লিখুন।
"""
router_prompt = PromptTemplate(
template=router_template,
input_variables=["input"],
)
# ডেস্টিনেশন চেইন তৈরি করুন
destination_chains = {
"ইতিহাস": LLMChain(llm=llm, prompt=history_prompt),
"বিজ্ঞান": LLMChain(llm=llm, prompt=science_prompt),
"সাহিত্য": LLMChain(llm=llm, prompt=literature_prompt),
}
# ডিফল্ট চেইন
default_chain = LLMChain(llm=llm, prompt=history_prompt)
# রাউটার চেইন তৈরি করুন
router_chain = LLMRouterChain.from_llm(
llm=llm,
prompt=router_prompt,
output_parser=RouterOutputParser()
)
# মাল্টি প্রম্পট চেইন তৈরি করুন
multi_prompt_chain = MultiPromptChain(
router_chain=router_chain,
destination_chains=destination_chains,
default_chain=default_chain,
verbose=True
)
# বিভিন্ন টাইপের প্রশ্ন টেস্ট করুন
history_q = "বাংলাদেশের স্বাধীনতা যুদ্ধ কবে হয়েছিল এবং কেন?"
science_q = "ব্ল্যাক হোল কী এবং কিভাবে তৈরি হয়?"
literature_q = "রবীন্দ্রনাথ ঠাকুরের প্রধান সাহিত্যকর্ম কী কী?"
# রাউটার চেইন রান করুন
print("\nইতিহাস প্রশ্ন:")
history_result = multi_prompt_chain.invoke({"input": history_q})
print(history_result["text"])
print("\nবিজ্ঞান প্রশ্ন:")
science_result = multi_prompt_chain.invoke({"input": science_q})
print(science_result["text"])
print("\nসাহিত্য প্রশ্ন:")
literature_result = multi_prompt_chain.invoke({"input": literature_q})
print(literature_result["text"])LangChain Expression Language (LCEL) দিয়ে রাউটার
LangChain Expression Language (LCEL) ব্যবহার করে আরও ফ্লেক্সিবল রাউটার তৈরি করা যায়:
from langchain.schema.runnable import RunnableBranch
from typing import Literal
from pydantic import BaseModel, Field
# ক্লাসিফায়ার ফাংশন
def classify_query(query: str) -> str:
# সিম্পল কিওয়ার্ড-বেসড ক্লাসিফিকেশন
if any(word in query.lower() for word in ["ইতিহাস", "যুদ্ধ", "স্বাধীনতা", "রাজা", "রানী"]):
return "ইতিহাস"
elif any(word in query.lower() for word in ["বিজ্ঞান", "পদার্থ", "রসায়ন", "জীববিজ্ঞান", "মহাকাশ"]):
return "বিজ্ঞান"
elif any(word in query.lower() for word in ["সাহিত্য", "কবিতা", "উপন্যাস", "লেখক", "কবি"]):
return "সাহিত্য"
else:
return "সাধারণ"
# ডিফারেন্ট চেইন তৈরি করুন
history_chain = LLMChain(llm=llm, prompt=history_prompt)
science_chain = LLMChain(llm=llm, prompt=science_prompt)
literature_chain = LLMChain(llm=llm, prompt=literature_prompt)
general_chain = LLMChain(
llm=llm,
prompt=PromptTemplate(
template="নিম্নলিখিত প্রশ্নের উত্তর দিন:\n\n{input}",
input_variables=["input"],
)
)
# রাউটার ফাংশন
def route_query(query):
category = classify_query(query)
if category == "ইতিহাস":
return history_chain
elif category == "বিজ্ঞান":
return science_chain
elif category == "সাহিত্য":
return literature_chain
else:
return general_chain
# RunnableBranch তৈরি করুন
branch = RunnableBranch(
(lambda x: classify_query(x["input"]) == "ইতিহাস", history_chain),
(lambda x: classify_query(x["input"]) == "বিজ্ঞান", science_chain),
(lambda x: classify_query(x["input"]) == "সাহিত্য", literature_chain),
general_chain
)
# RunnableBranch টেস্ট করুন
print("\nLCEL RunnableBranch:")
print("ইতিহাস প্রশ্ন:")
history_result = branch.invoke({"input": history_q})
print(history_result["text"])
print("\nবিজ্ঞান প্রশ্ন:")
science_result = branch.invoke({"input": science_q})
print(science_result["text"])রাউটার চেইনের ইউজ কেস
- মাল্টি-ডোমেইন Q&A সিস্টেম
- টাস্ক-স্পেসিফিক এজেন্ট সিলেকশন
- কন্টেন্ট টাইপ ডিটেকশন এবং প্রসেসিং
- ইউজার ইন্টেন্ট ক্লাসিফিকেশন এবং রাউটিং
- ল্যাঙ্গুয়েজ-স্পেসিফিক প্রসেসিং
কাস্টম চেইন তৈরি করা
গল্প: কাস্টম চেইন তৈরি করা হল নিজের রেসিপি তৈরি করার মতো। আপনি বিভিন্ন উপাদান একত্রিত করে আপনার পছন্দ মতো একটি নতুন ডিশ তৈরি করতে পারেন।
LangChain-এ কাস্টম চেইন তৈরি করার দুটি প্রধান উপায় আছে:
- Chain ক্লাস এক্সটেন্ড করা: ট্র্যাডিশনাল অবজেক্ট-ওরিয়েন্টেড অ্যাপ্রোচ
- LCEL ব্যবহার করা: ফাংশনাল অ্যাপ্রোচ
Chain ক্লাস এক্সটেন্ড করা
from langchain.chains.base import Chain
from typing import Dict, List, Any
class TranslationSummaryChain(Chain):
"""
একটি টেক্সট অনুবাদ করে এবং তারপর সারাংশ তৈরি করে।
"""
translation_chain: LLMChain
summary_chain: LLMChain
@property
def input_keys(self) -> List[str]:
"""চেইনের ইনপুট কি"""
return ["text", "source_language", "target_language"]
@property
def output_keys(self) -> List[str]:
"""চেইনের আউটপুট কি"""
return ["translation", "summary"]
def _call(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
"""চেইন রান করুন"""
# টেক্সট অনুবাদ করুন
translation = self.translation_chain.invoke({
"text": inputs["text"],
"source_language": inputs["source_language"],
"target_language": inputs["target_language"]
})
# অনুবাদিত টেক্সটের সারাংশ তৈরি করুন
summary = self.summary_chain.invoke({
"text": translation["text"]
})
return {
"translation": translation["text"],
"summary": summary["text"]
}
# ট্রান্সলেশন প্রম্পট
translation_prompt = PromptTemplate(
input_variables=["text", "source_language", "target_language"],
template="""
নিম্নলিখিত {source_language} টেক্সটকে {target_language} ভাষায় অনুবাদ করুন:
{text}
{target_language} অনুবাদ:
"""
)
# সামারাইজেশন প্রম্পট
summary_prompt = PromptTemplate(
input_variables=["text"],
template="""
নিম্নলিখিত টেক্সটের একটি সংক্ষিপ্ত সারাংশ তৈরি করুন (3-4 বাক্য):
{text}
সারাংশ:
"""
)
# চেইন তৈরি করুন
translation_chain = LLMChain(llm=llm, prompt=translation_prompt)
summary_chain = LLMChain(llm=llm, prompt=summary_prompt)
# কাস্টম চেইন তৈরি করুন
custom_chain = TranslationSummaryChain(
translation_chain=translation_chain,
summary_chain=summary_chain
)
# কাস্টম চেইন রান করুন
english_text = """
The Liberation War of Bangladesh was a revolutionary independence war in South Asia that resulted in the independence of Bangladesh from Pakistan in 1971. It began after the Pakistani military junta based in West Pakistan launched Operation Searchlight against the people of East Pakistan (now Bangladesh) on the night of 25 March 1971. The war ended on 16 December 1971 after West Pakistan surrendered.
"""
custom_result = custom_chain.invoke({
"text": english_text,
"source_language": "ইংরেজি",
"target_language": "বাংলা"
})
print("\nকাস্টম চেইন রেজাল্ট:")
print("অনুবাদ:")
print(custom_result["translation"])
print("\nসারাংশ:")
print(custom_result["summary"])LCEL ব্যবহার করা
LangChain Expression Language (LCEL) ব্যবহার করে আরও সহজে কাস্টম চেইন তৈরি করা যায়:
from langchain.schema.runnable import RunnablePassthrough, RunnableLambda
# ট্রান্সলেশন প্রম্পট
translation_prompt = PromptTemplate(
input_variables=["text", "source_language", "target_language"],
template="""
নিম্নলিখিত {source_language} টেক্সটকে {target_language} ভাষায় অনুবাদ করুন:
{text}
{target_language} অনুবাদ:
"""
)
# সামারাইজেশন প্রম্পট
summary_prompt = PromptTemplate(
input_variables=["text"],
template="""
নিম্নলিখিত টেক্সটের একটি সংক্ষিপ্ত সারাংশ তৈরি করুন (3-4 বাক্য):
{text}
সারাংশ:
"""
)
# ট্রান্সলেশন চেইন
translation_chain = translation_prompt | llm | (lambda x: {"translation": x.content})
# সামারাইজেশন চেইন
def get_summary(inputs):
summary_input = summary_prompt.format(text=inputs["translation"])
summary_output = llm.invoke(summary_input)
return {"translation": inputs["translation"], "summary": summary_output.content}
# LCEL চেইন
lcel_chain = (
RunnablePassthrough.assign(
translation=translation_chain
)
| RunnableLambda(get_summary)
)
# LCEL চেইন রান করুন
lcel_result = lcel_chain.invoke({
"text": english_text,
"source_language": "ইংরেজি",
"target_language": "বাংলা"
})
print("\nLCEL চেইন রেজাল্ট:")
print("অনুবাদ:")
print(lcel_result["translation"])
print("\nসারাংশ:")
print(lcel_result["summary"])কাস্টম চেইন ডিজাইন বেস্ট প্র্যাকটিস
- সিঙ্গেল রেসপন্সিবিলিটি প্রিন্সিপল: প্রতিটি চেইন একটি নির্দিষ্ট কাজ করা উচিত
- মডুলারিটি: চেইনকে ছোট, রিইউজেবল কম্পোনেন্টে ভাগ করুন
- এরর হ্যান্ডলিং: এরর হ্যান্ডলিং এবং ফলব্যাক লজিক যোগ করুন
- ডিবাগিং:
verbose=Trueব্যবহার করে ডিবাগিং সহজ করুন - ডকুমেন্টেশন: ইনপুট, আউটপুট, এবং চেইনের উদ্দেশ্য ডকুমেন্ট করুন
- টেস্টিং: ইউনিট টেস্ট লিখুন যাতে চেইন সঠিকভাবে কাজ করে
প্র্যাকটিকাল এক্সারসাইজ: বাংলা কন্টেন্ট জেনারেটর
এখন আমরা আমাদের শেখা সবকিছু একত্রিত করে একটি বাংলা কন্টেন্ট জেনারেটর তৈরি করব:
# bengali_content_generator.py
from langchain.chains.base import Chain
from langchain.chains import LLMChain, SequentialChain
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from typing import Dict, List, Any
from dotenv import load_dotenv
import os
# .env ফাইল থেকে API কি লোড করুন
load_dotenv()
class BengaliContentGenerator(Chain):
"""
বিভিন্ন ধরনের বাংলা কন্টেন্ট জেনারেট করে।
"""
llm: ChatOpenAI
@property
def input_keys(self) -> List[str]:
"""চেইনের ইনপুট কি"""
return ["topic", "content_type", "tone", "length"]
@property
def output_keys(self) -> List[str]:
"""চেইনের আউটপুট কি"""
return ["title", "content", "keywords"]
def _call(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
"""চেইন রান করুন"""
topic = inputs["topic"]
content_type = inputs["content_type"]
tone = inputs["tone"]
length = inputs["length"]
# কন্টেন্ট টাইপ অনুযায়ী রাউটিং
if content_type == "ব্লগ পোস্ট":
return self._generate_blog_post(topic, tone, length)
elif content_type == "সোশ্যাল মিডিয়া পোস্ট":
return self._generate_social_media_post(topic, tone)
elif content_type == "নিউজ আর্টিকেল":
return self._generate_news_article(topic, tone, length)
elif content_type == "টিউটোরিয়াল":
return self._generate_tutorial(topic, tone, length)
else:
# ডিফল্ট: ব্লগ পোস্ট
return self._generate_blog_post(topic, tone, length)
def _generate_blog_post(self, topic, tone, length):
"""ব্লগ পোস্ট জেনারেট করে"""
# টাইটেল জেনারেট করুন
title_prompt = PromptTemplate(
input_variables=["topic", "tone"],
template="""
{topic} সম্পর্কে একটি আকর্ষণীয় ব্লগ পোস্টের শিরোনাম তৈরি করুন।
টোন: {tone}
শিরোনাম:
"""
)
title_chain = LLMChain(llm=self.llm, prompt=title_prompt)
title_result = title_chain.invoke({"topic": topic, "tone": tone})
title = title_result["text"].strip()
# কন্টেন্ট জেনারেট করুন
content_prompt = PromptTemplate(
input_variables=["title", "topic", "tone", "length"],
template="""
নিম্নলিখিত শিরোনামের জন্য একটি ব্লগ পোস্ট লিখুন:
শিরোনাম: {title}
টপিক: {topic}
টোন: {tone}
দৈর্ঘ্য: {length} শব্দ
ব্লগ পোস্টটি সাবহেডিং, বুলেট পয়েন্ট, এবং উদাহরণ সহ স্ট্রাকচারড হওয়া উচিত।
ব্লগ পোস্ট:
"""
)
content_chain = LLMChain(llm=self.llm, prompt=content_prompt)
content_result = content_chain.invoke({
"title": title,
"topic": topic,
"tone": tone,
"length": length
})
content = content_result["text"].strip()
# কিওয়ার্ড জেনারেট করুন
keyword_prompt = PromptTemplate(
input_variables=["title", "content"],
template="""
নিম্নলিখিত ব্লগ পোস্টের জন্য 5-7টি রিলেভেন্ট কিওয়ার্ড তৈরি করুন:
শিরোনাম: {title}
কন্টেন্ট: {content}
কিওয়ার্ড (কমা দিয়ে আলাদা করুন):
"""
)
keyword_chain = LLMChain(llm=self.llm, prompt=keyword_prompt)
keyword_result = keyword_chain.invoke({
"title": title,
"content": content
})
keywords = keyword_result["text"].strip()
return {
"title": title,
"content": content,
"keywords": keywords
}
def _generate_social_media_post(self, topic, tone):
"""সোশ্যাল মিডিয়া পোস্ট জেনারেট করে"""
# টাইটেল/ক্যাপশন জেনারেট করুন
title_prompt = PromptTemplate(
input_variables=["topic", "tone"],
template="""
{topic} সম্পর্কে একটি আকর্ষণীয় সোশ্যাল মিডিয়া পোস্টের ক্যাপশন তৈরি করুন।
টোন: {tone}
ক্যাপশন:
"""
)
title_chain = LLMChain(llm=self.llm, prompt=title_prompt)
title_result = title_chain.invoke({"topic": topic, "tone": tone})
title = title_result["text"].strip()
# কন্টেন্ট জেনারেট করুন
content_prompt = PromptTemplate(
input_variables=["title", "topic", "tone"],
template="""
নিম্নলিখিত ক্যাপশনের জন্য একটি সোশ্যাল মিডিয়া পোস্ট লিখুন:
ক্যাপশন: {title}
টপিক: {topic}
টোন: {tone}
পোস্টটি 280 থেকে 300 অক্ষরের মধ্যে হওয়া উচিত এবং 2-3টি হ্যাশট্যাগ থাকা উচিত।
সোশ্যাল মিডিয়া পোস্ট:
"""
)
content_chain = LLMChain(llm=self.llm, prompt=content_prompt)
content_result = content_chain.invoke({
"title": title,
"topic": topic,
"tone": tone
})
content = content_result["text"].strip()
# হ্যাশট্যাগ জেনারেট করুন
keyword_prompt = PromptTemplate(
input_variables=["title", "content"],
template="""
নিম্নলিখিত সোশ্যাল মিডিয়া পোস্টের জন্য 5টি ট্রেন্ডিং হ্যাশট্যাগ তৈরি করুন:
ক্যাপশন: {title}
কন্টেন্ট: {content}
হ্যাশট্যাগ (কমা দিয়ে আলাদা করুন):
"""
)
keyword_chain = LLMChain(llm=self.llm, prompt=keyword_prompt)
keyword_result = keyword_chain.invoke({
"title": title,
"content": content
})
keywords = keyword_result["text"].strip()
return {
"title": title,
"content": content,
"keywords": keywords
}
def _generate_news_article(self, topic, tone, length):
"""নিউজ আর্টিকেল জেনারেট করে"""
# হেডলাইন জেনারেট করুন
title_prompt = PromptTemplate(
input_variables=["topic", "tone"],
template="""
{topic} সম্পর্কে একটি আকর্ষণীয় নিউজ হেডলাইন তৈরি করুন।
টোন: {tone}
হেডলাইন:
"""
)
title_chain = LLMChain(llm=self.llm, prompt=title_prompt)
title_result = title_chain.invoke({"topic": topic, "tone": tone})
title = title_result["text"].strip()
# আর্টিকেল জেনারেট করুন
content_prompt = PromptTemplate(
input_variables=["title", "topic", "tone", "length"],
template="""
নিম্নলিখিত হেডলাইনের জন্য একটি নিউজ আর্টিকেল লিখুন:
হেডলাইন: {title}
টপিক: {topic}
টোন: {tone}
দৈর্ঘ্য: {length} শব্দ
আর্টিকেলটি নিউজ স্টাইলে লিখুন, প্রথম অনুচ্ছেদে মূল তথ্য দিন, এবং 5W1H (কে, কী, কোথায়, কখন, কেন, কিভাবে) অনুসরণ করুন।
নিউজ আর্টিকেল:
"""
)
content_chain = LLMChain(llm=self.llm, prompt=content_prompt)
content_result = content_chain.invoke({
"title": title,
"topic": topic,
"tone": tone,
"length": length
})
content = content_result["text"].strip()
# কিওয়ার্ড জেনারেট করুন
keyword_prompt = PromptTemplate(
input_variables=["title", "content"],
template="""
নিম্নলিখিত নিউজ আর্টিকেলের জন্য 5-7টি রিলেভেন্ট কিওয়ার্ড তৈরি করুন:
হেডলাইন: {title}
কন্টেন্ট: {content}
কিওয়ার্ড (কমা দিয়ে আলাদা করুন):
"""
)
keyword_chain = LLMChain(llm=self.llm, prompt=keyword_prompt)
keyword_result = keyword_chain.invoke({
"title": title,
"content": content
})
keywords = keyword_result["text"].strip()
return {
"title": title,
"content": content,
"keywords": keywords
}
def _generate_tutorial(self, topic, tone, length):
"""টিউটোরিয়াল জেনারেট করে"""
# টাইটেল জেনারেট করুন
title_prompt = PromptTemplate(
input_variables=["topic", "tone"],
template="""
{topic} সম্পর্কে একটি টিউটোরিয়ালের শিরোনাম তৈরি করুন।
টোন: {tone}
শিরোনাম:
"""
)
title_chain = LLMChain(llm=self.llm, prompt=title_prompt)
title_result = title_chain.invoke({"topic": topic, "tone": tone})
title = title_result["text"].strip()
# কন্টেন্ট জেনারেট করুন
content_prompt = PromptTemplate(
input_variables=["title", "topic", "tone", "length"],
template="""
নিম্নলিখিত শিরোনামের জন্য একটি টিউটোরিয়াল লিখুন:
শিরোনাম: {title}
টপিক: {topic}
টোন: {tone}
দৈর্ঘ্য: {length} শব্দ
টিউটোরিয়ালটি স্টেপ-বাই-স্টেপ নির্দেশনা, টিপস, এবং উদাহরণ সহ স্ট্রাকচারড হওয়া উচিত।
টিউটোরিয়াল:
"""
)
content_chain = LLMChain(llm=self.llm, prompt=content_prompt)
content_result = content_chain.invoke({
"title": title,
"topic": topic,
"tone": tone,
"length": length
})
content = content_result["text"].strip()
# কিওয়ার্ড জেনারেট করুন
keyword_prompt = PromptTemplate(
input_variables=["title", "content"],
template="""
নিম্নলিখিত টিউটোরিয়ালের জন্য 5-7টি রিলেভেন্ট কিওয়ার্ড তৈরি করুন:
শিরোনাম: {title}
কন্টেন্ট: {content}
কিওয়ার্ড (কমা দিয়ে আলাদা করুন):
"""
)
keyword_chain = LLMChain(llm=self.llm, prompt=keyword_prompt)
keyword_result = keyword_chain.invoke({
"title": title,
"content": content
})
keywords = keyword_result["text"].strip()
return {
"title": title,
"content": content,
"keywords": keywords
}
# কন্টেন্ট জেনারেটর ব্যবহার করুন
if __name__ == "__main__":
# LLM সেটআপ করুন
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0.7,
api_key=os.getenv("OPENAI_API_KEY")
)
# কন্টেন্ট জেনারেটর তৈরি করুন
content_generator = BengaliContentGenerator(llm=llm)
print("বাংলা কন্টেন্ট জেনারেটর")
print("=" * 50)
# ইউজার ইনপুট নিন
topic = input("টপিক: ")
print("\nকন্টেন্ট টাইপ সিলেক্ট করুন:")
print("1. ব্লগ পোস্ট")
print("2. সোশ্যাল মিডিয়া পোস্ট")
print("3. নিউজ আর্টিকেল")
print("4. টিউটোরিয়াল")
content_type_choice = input("আপনার পছন্দ (1-4): ")
content_type_map = {
"1": "ব্লগ পোস্ট",
"2": "সোশ্যাল মিডিয়া পোস্ট",
"3": "নিউজ আর্টিকেল",
"4": "টিউটোরিয়াল"
}
content_type = content_type_map.get(content_type_choice, "ব্লগ পোস্ট")
print("\nটোন সিলেক্ট করুন:")
print("1. ইনফরমেটিভ (তথ্যমূলক)")
print("2. ক্যাজুয়াল (অনানুষ্ঠানিক)")
print("3. প্রফেশনাল (পেশাদার)")
print("4. এন্টারটেইনিং (মনোরঞ্জনমূলক)")
tone_choice = input("আপনার পছন্দ (1-4): ")
tone_map = {
"1": "তথ্যমূলক",
"2": "অনানুষ্ঠানিক",
"3": "পেশাদার",
"4": "মনোরঞ্জনমূলক"
}
tone = tone_map.get(tone_choice, "তথ্যমূলক")
length = input("\nকন্টেন্টের দৈর্ঘ্য (শব্দ সংখ্যা): ")
if not length.isdigit():
length = "500"
print("\nকন্টেন্ট জেনারেট করা হচ্ছে...")
result = content_generator.invoke({
"topic": topic,
"content_type": content_type,
"tone": tone,
"length": length
})
print("\n" + "=" * 50)
print(f"শিরোনাম: {result['title']}")
print("-" * 50)
print(result["content"])
print("-" * 50)
print(f"কিওয়ার্ড: {result['keywords']}")
print("=" * 50)সারাংশ
এই টিউটোরিয়ালে, আমরা শিখেছি:
- চেইন কি এবং কেন ব্যবহার করবেন: চেইন হল LangChain-এর একটি কম্পোনেন্ট যা বিভিন্ন LLM কল, প্রম্পট, পার্সার একত্রিত করে
- সিম্পল LLM চেইন: LLMChain ব্যবহার করে সিম্পল টেক্সট জেনারেশন
- সিকোয়েন্শিয়াল চেইন: SimpleSequentialChain এবং SequentialChain ব্যবহার করে মাল্টি-স্টেপ প্রসেসিং
- ট্রান্সফরমেশন চেইন: MapReduceChain এবং RefineChain ব্যবহার করে বড় ডকুমেন্ট প্রসেসিং
- রাউটার চেইন: MultiPromptChain এবং RunnableBranch ব্যবহার করে ডিফারেন্ট টাইপের কোয়েরি হ্যান্ডেল করা
- কাস্টম চেইন তৈরি করা: Chain ক্লাস এক্সটেন্ড করে বা LCEL ব্যবহার করে কাস্টম চেইন তৈরি করা
অতিরিক্ত অনুশীলনী
- মাল্টি-লিঙ্গুয়াল কন্টেন্ট জেনারেটর: বাংলা কন্টেন্ট জেনারেটরকে এক্সটেন্ড করে বিভিন্ন ভাষায় কন্টেন্ট জেনারেট করার ফিচার যোগ করুন।
- কন্টেন্ট এনহ্যান্সার: একটি চেইন তৈরি করুন যা বিদ্যমান কন্টেন্ট নিয়ে সেটিকে এনহ্যান্স করে (গ্রামার চেক, টোন অ্যাডজাস্টমেন্ট, SEO অপ্টিমাইজেশন)।
- ইন্টারেক্টিভ স্টোরিটেলার: একটি চেইন তৈরি করুন যা ইউজার ইনপুটের উপর ভিত্তি করে ইন্টারেক্টিভ স্টোরি জেনারেট করে।
- রিসার্চ অ্যাসিস্ট্যান্ট: একটি চেইন তৈরি করুন যা একটি টপিক নিয়ে রিসার্চ করে, তথ্য সংগ্রহ করে, এবং একটি স্ট্রাকচারড রিপোর্ট তৈরি করে।
- কন্টেন্ট রিপারপাসিং টুল: একটি চেইন তৈরি করুন যা একই কন্টেন্টকে বিভিন্ন ফরম্যাটে রিপারপাস করে (ব্লগ → সোশ্যাল মিডিয়া → ইমেইল → ভিডিও স্ক্রিপ্ট)।
পরবর্তী ধাপ
পরবর্তী টিউটোরিয়ালে, আমরা LangChain-এর মেমোরি কম্পোনেন্ট নিয়ে আলোচনা করব। আমরা শিখব কিভাবে কনভার্সেশন হিস্টোরি মনে রাখতে হয় এবং কিভাবে বিভিন্ন ধরনের মেমোরি ব্যবহার করতে হয়।
উপসংহার
আজকের টিউটোরিয়ালে, আমরা LangChain-এর চেইন কনসেপ্ট সম্পর্কে বিস্তারিত জেনেছি। আমরা দেখেছি কিভাবে বিভিন্ন ধরনের চেইন ব্যবহার করে জটিল AI ওয়ার্কফ্লো তৈরি করা যায়।
চেইন হল LangChain-এর একটি পাওয়ারফুল ফিচার যা আপনাকে মডুলার, রিইউজেবল, এবং মেইনটেইনেবল AI অ্যাপ্লিকেশন তৈরি করতে সাহায্য করে। আপনি যত বেশি চেইন ব্যবহার করবেন, তত বেশি আপনি LangChain-এর ফ্লেক্সিবিলিটি এবং পাওয়ার উপলব্ধি করতে পারবেন।
আপনার অনুশীলনের জন্য, আমি আপনাকে উৎসাহিত করি বিভিন্ন ধরনের চেইন এক্সপেরিমেন্ট করতে এবং আপনার নিজের প্রয়োজন অনুযায়ী কাস্টম চেইন তৈরি করতে।
ধন্যবাদ এবং শুভকামনা আপনার LangChain যাত্রায়!