فریمورک‌ها — LangChain، CrewAI و بقیه

قسمت ۶ ۲۰ دقیقه

مقدمه: حتماً باید فریمورک استفاده کنی؟

تا الان توی این سری، Agent رو از صفر ساختیم — با کد خالص پایتون. ولی تو دنیای واقعی، فریمورک‌های آماده‌ای وجود دارن که خیلی از کارها رو برات انجام می‌دن.

سوال اینه: کدوم فریمورک رو استفاده کنی؟ اصلاً لازمه فریمورک استفاده کنی؟ تو این اپیزود مهم‌ترین فریمورک‌ها رو بررسی می‌کنیم و بهت کمک می‌کنم درست انتخاب کنی.

LangChain — پادشاه (قدیمی) فریمورک‌ها

LangChain اولین فریمورک بزرگ برای ساخت اپلیکیشن‌های LLM بود. محبوبیت زیادی داره ولی انتقادهای زیادی هم بهش وارده.

چیکار می‌کنه؟

LangChain یه جعبه‌ابزار بزرگه که شامل: اتصال به LLM ها، مدیریت حافظه، کار با ابزارها، پایپلاین‌های RAG، و خیلی چیزای دیگه‌ست.

from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain.tools import tool
from langchain_core.prompts import ChatPromptTemplate

# تعریف ابزار
@tool
def calculate(expression: str) -> str:
    """یه عبارت ریاضی رو محاسبه می‌کنه."""
    try:
        return str(eval(expression))
    except:
        return "خطا در محاسبه"

@tool
def get_weather(city: str) -> str:
    """آب‌وهوای یه شهر رو برمی‌گردونه."""
    # در واقعیت اینجا API call می‌زنیم
    weather_data = {
        "تهران": "آفتابی، ۲۸ درجه",
        "اصفهان": "ابری، ۲۴ درجه",
    }
    return weather_data.get(city, f"اطلاعاتی برای {city} ندارم")

# ساخت Agent
llm = ChatOpenAI(model="gpt-4o")
tools = [calculate, get_weather]

prompt = ChatPromptTemplate.from_messages([
    ("system", "تو یه دستیار مفید هستی. از ابزارها استفاده کن."),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}"),
])

agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

# اجرا
result = executor.invoke({
    "input": "هوای تهران چطوره و ۲۵ ضرب‌در ۴ چنده؟"
})
print(result["output"])

مزایا:

  • اکوسیستم بزرگ — برای تقریباً هر کاری یه ماژول داره
  • مستندات زیاد و جامعه بزرگ
  • یکپارچگی با خیلی از سرویس‌ها (OpenAI، Anthropic، Pinecone، و …)

معایب:

  • پیچیدگی زیاد — برای کارهای ساده بیش از حد سنگینه
  • لایه‌های انتزاع زیاد — دیباگ سخته
  • API مرتب عوض می‌شه — کدی که ۳ ماه پیش نوشتی ممکنه کار نکنه
  • عملکرد بعضی وقتا مشکل‌داره

LangGraph — نسل بعدی LangChain

LangGraph از همون تیم LangChain هست ولی رویکرد متفاوتی داره. به جای chain های خطی، از گراف استفاده می‌کنه. هر مرحله یه node تو گرافه و Agent می‌تونه بین node ها حرکت کنه.

from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
from langchain_openai import ChatOpenAI
import operator

class AgentState(TypedDict):
    messages: Annotated[list, operator.add]
    next_action: str

llm = ChatOpenAI(model="gpt-4o")

def analyze_request(state: AgentState) -> AgentState:
    """درخواست کاربر رو تحلیل می‌کنه."""
    messages = state["messages"]
    response = llm.invoke([
        {"role": "system", "content": """
        درخواست کاربر رو بررسی کن.
        اگه سوال فنیه، بگو 'technical'
        اگه سوال عمومیه، بگو 'general'
        فقط یه کلمه بگو.
        """},
        {"role": "user", "content": messages[-1]}
    ])
    return {
        "messages": [f"تحلیل: {response.content}"],
        "next_action": response.content.strip().lower()
    }

def handle_technical(state: AgentState) -> AgentState:
    """سوالات فنی رو جواب می‌ده."""
    messages = state["messages"]
    response = llm.invoke([
        {"role": "system", "content": "تو یه متخصص فنی هستی."},
        {"role": "user", "content": messages[0]}
    ])
    return {
        "messages": [response.content],
        "next_action": "done"
    }

def handle_general(state: AgentState) -> AgentState:
    """سوالات عمومی رو جواب می‌ده."""
    messages = state["messages"]
    response = llm.invoke([
        {"role": "system", "content": "تو یه دستیار عمومی هستی."},
        {"role": "user", "content": messages[0]}
    ])
    return {
        "messages": [response.content],
        "next_action": "done"
    }

def route(state: AgentState) -> str:
    """مسیر بعدی رو مشخص می‌کنه."""
    if state["next_action"] == "technical":
        return "technical"
    return "general"

# ساخت گراف
graph = StateGraph(AgentState)
graph.add_node("analyze", analyze_request)
graph.add_node("technical", handle_technical)
graph.add_node("general", handle_general)

graph.set_entry_point("analyze")
graph.add_conditional_edges("analyze", route, {
    "technical": "technical",
    "general": "general"
})
graph.add_edge("technical", END)
graph.add_edge("general", END)

app = graph.compile()

# اجرا
result = app.invoke({
    "messages": ["چطور یه REST API با FastAPI بسازم؟"],
    "next_action": ""
})
print(result["messages"][-1])

کی LangGraph بهتره؟

  • وقتی Agent ات flow پیچیده‌ای داره (شرط، حلقه، شاخه‌بندی)
  • وقتی می‌خوای دقیقاً کنترل کنی Agent چطور تصمیم می‌گیره
  • وقتی نیاز به state management داری

CrewAI — وقتی چند Agent باید با هم کار کنن

CrewAI مخصوص سیستم‌های Multi-Agent ه. هر Agent یه نقش داره و با بقیه همکاری می‌کنه — مثل یه تیم واقعی.

from crewai import Agent, Task, Crew, Process

# تعریف Agent ها
researcher = Agent(
    role="محقق",
    goal="اطلاعات دقیق و به‌روز درباره موضوع پیدا کن",
    backstory="""تو یه محقق باتجربه هستی که 
    سال‌ها تو حوزه تحقیق کار کردی. منابع معتبر رو 
    از نامعتبر تشخیص می‌دی.""",
    verbose=True,
    allow_delegation=False,
)

writer = Agent(
    role="نویسنده",
    goal="مقاله جذاب و خوانا بنویس",
    backstory="""تو یه نویسنده حرفه‌ای هستی که 
    می‌تونه موضوعات پیچیده رو ساده و جذاب توضیح بده.""",
    verbose=True,
    allow_delegation=False,
)

editor = Agent(
    role="ویراستار",
    goal="متن رو بررسی و بهبود بده",
    backstory="""تو یه ویراستار سخت‌گیر هستی که 
    هم به دقت محتوا و هم به کیفیت نگارش اهمیت می‌دی.""",
    verbose=True,
    allow_delegation=False,
)

# تعریف وظایف
research_task = Task(
    description="درباره {topic} تحقیق کن. حداقل ۵ نکته کلیدی پیدا کن.",
    expected_output="لیست نکات کلیدی با منبع",
    agent=researcher,
)

write_task = Task(
    description="بر اساس تحقیق، یه مقاله ۵۰۰ کلمه‌ای بنویس.",
    expected_output="مقاله کامل با عنوان و پاراگراف‌بندی",
    agent=writer,
)

edit_task = Task(
    description="مقاله رو بررسی کن. غلط‌ها رو بگیر و بهبود بده.",
    expected_output="مقاله نهایی ویرایش‌شده",
    agent=editor,
)

# ساخت Crew
crew = Crew(
    agents=[researcher, writer, editor],
    tasks=[research_task, write_task, edit_task],
    process=Process.sequential,  # به ترتیب اجرا بشن
    verbose=True,
)

# اجرا
result = crew.kickoff(
    inputs={"topic": "تأثیر هوش مصنوعی بر آموزش"}
)
print(result)

مزایا:

  • API ساده و شهودی
  • تعریف نقش‌ها خیلی طبیعیه
  • مناسب برای workflow های چند مرحله‌ای

معایب:

  • هنوز در حال بالغ شدنه
  • کنترل دقیق روی رفتار Agent ها سخته
  • مصرف توکن بالا (چون هر Agent جداگانه LLM رو صدا می‌زنه)

AutoGen (مایکروسافت)

AutoGen از مایکروسافته و تمرکزش روی مکالمه بین Agent هاست. Agent ها با هم چت می‌کنن و از طریق بحث به نتیجه می‌رسن.

from autogen import ConversableAgent

# Agent ها
assistant = ConversableAgent(
    name="assistant",
    system_message="""تو یه برنامه‌نویس پایتون هستی.
    کد تمیز و با توضیحات بنویس.""",
    llm_config={"model": "gpt-4o"},
)

reviewer = ConversableAgent(
    name="reviewer",
    system_message="""تو یه بررسی‌کننده کد هستی.
    کد رو بررسی کن و مشکلات رو بگو.
    اگه کد خوبه، بگو 'APPROVED'.""",
    llm_config={"model": "gpt-4o"},
)

user_proxy = ConversableAgent(
    name="user",
    human_input_mode="NEVER",
    is_termination_msg=lambda msg: "APPROVED" in msg.get("content", ""),
)

# شروع مکالمه
user_proxy.initiate_chat(
    assistant,
    message="یه تابع بنویس که palindrome بودن رشته رو چک کنه.",
    max_turns=6,
)

ویژگی خاص:

Agent ها می‌تونن چند دور با هم بحث کنن. مثلاً برنامه‌نویس کد می‌نویسه، بررسی‌کننده ایراد می‌گیره، برنامه‌نویس اصلاح می‌کنه — تا وقتی که هر دو راضی بشن.

Semantic Kernel (مایکروسافت)

Semantic Kernel یه فریمورک دیگه از مایکروسافته که بیشتر سازمانی‌تره. اگه تو اکوسیستم مایکروسافت (Azure، .NET) کار می‌کنی، گزینه خوبیه.

import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import (
    OpenAIChatCompletion,
)
from semantic_kernel.functions import kernel_function

kernel = sk.Kernel()
kernel.add_service(
    OpenAIChatCompletion(
        ai_model_id="gpt-4o",
        service_id="chat",
    )
)

class HelperPlugin:
    @kernel_function(
        name="summarize",
        description="متن رو خلاصه می‌کنه"
    )
    def summarize(self, text: str) -> str:
        return f"خلاصه: {text[:100]}..."

    @kernel_function(
        name="translate",
        description="متن رو ترجمه می‌کنه"
    )
    def translate(self, text: str, target_lang: str) -> str:
        return f"ترجمه به {target_lang}: {text}"

kernel.add_plugin(HelperPlugin(), "helper")

کی مناسبه؟

  • پروژه‌های سازمانی روی Azure
  • تیم‌هایی که با C# یا .NET کار می‌کنن
  • وقتی نیاز به پشتیبانی رسمی مایکروسافت داری

مقایسه کلی — کدوم رو انتخاب کنم؟

بذار خلاصه‌اش کنم:

LangChain: اگه پروژه ساده‌ای داری و می‌خوای سریع شروع کنی. ولی برای پروژه‌های پیچیده، ممکنه دردسرساز بشه.

LangGraph: اگه Agent ات flow پیچیده‌ای داره و می‌خوای دقیقاً کنترلش کنی.

CrewAI: اگه چند Agent متخصص داری که باید با هم کار کنن.

AutoGen: اگه می‌خوای Agent ها با هم بحث و تبادل نظر کنن.

Semantic Kernel: اگه تو اکوسیستم مایکروسافت هستی.

بدون فریمورک: اگه پروژه‌ات ساده‌ست، فریمورک لازم نداری. کد خالص پایتون + API مدل = کافیه.

کی فریمورک استفاده نکنی؟

این بخش مهمه. فریمورک همیشه جواب نیست:

  • پروژه ساده: اگه فقط یه چت‌بات ساده می‌خوای، فریمورک بار اضافیه.
  • یادگیری: اگه داری Agent رو یاد می‌گیری، اول بدون فریمورک بساز تا مفاهیم رو بفهمی.
  • عملکرد حیاتی: فریمورک‌ها لایه‌های انتزاع اضافه می‌کنن که سرعت رو کم می‌کنه.
  • نیاز به کنترل کامل: اگه می‌خوای دقیقاً بدونی هر خط کد چیکار می‌کنه.
توصیه من: اول مسئله رو حل کن، بعد ببین فریمورک کمکت می‌کنه یا نه. فریمورک ابزاره — نه هدف. خیلی از بهترین Agent های دنیا بدون فریمورک ساخته شدن.

جمع‌بندی

فریمورک‌ها ابزارهای مفیدین ولی نه ضروری:

  • LangChain و LangGraph برای اکوسیستم بزرگ و flow پیچیده
  • CrewAI برای Multi-Agent ساده
  • AutoGen برای مکالمه بین Agent ها
  • بدون فریمورک برای پروژه‌های ساده و یادگیری
  • هیچ فریمورکی «بهترین» نیست — بستگی به پروژه‌ات داره

اپیزود بعدی درباره امنیت Agent ها صحبت می‌کنیم — چطور جلوی رفتار خطرناک Agent رو بگیری.

نظرات

هنوز نظری ثبت نشده. اولین نفر باشید!

نظر خود را بنویسید