⚡ بناء وكلاء اللغة على شكل رسوم بيانية ⚡
ملحوظة
هل تبحث عن نسخة JS؟ انقر هنا (مستندات JS).
LangGraph هي مكتبة لبناء تطبيقات ذات حالة محددة ومتعددة الممثلين باستخدام LLMs، وتُستخدم لإنشاء مسارات عمل الوكيل ومتعدد الوكلاء. بالمقارنة مع أطر LLM الأخرى، فهو يقدم هذه الفوائد الأساسية: الدورات، وإمكانية التحكم، والمثابرة. يتيح لك LangGraph تحديد التدفقات التي تتضمن دورات، وهي ضرورية لمعظم البنى الوكلاءية، مما يميزها عن الحلول المستندة إلى DAG. وباعتباره إطارًا منخفض المستوى للغاية، فإنه يوفر تحكمًا دقيقًا في كل من تدفق التطبيق وحالته، وهو أمر ضروري لإنشاء عوامل موثوقة. بالإضافة إلى ذلك، يتضمن LangGraph خاصية الثبات المضمنة، مما يتيح ميزات متقدمة للتفاعل البشري والذاكرة.
LangGraph مستوحى من Pregel وApache Beam. الواجهة العامة مستوحاة من NetworkX. تم إنشاء LangGraph بواسطة شركة LangChain Inc، وهي منشئي LangChain، ولكن يمكن استخدامه بدون LangChain.
منصة LangGraph عبارة عن بنية أساسية لنشر وكلاء LangGraph. إنه حل تجاري لنشر التطبيقات الوكيلة في الإنتاج، وهو مبني على إطار عمل LangGraph مفتوح المصدر. يتكون نظام LangGraph من عدة مكونات تعمل معًا لدعم تطوير تطبيقات LangGraph ونشرها وتصحيح الأخطاء ومراقبتها: خادم LangGraph (APIs)، وLangGraph SDKs (عملاء واجهات برمجة التطبيقات)، وLangGraph CLI (أداة سطر الأوامر لبناء الخادم) )، استوديو LangGraph (واجهة المستخدم/مصحح الأخطاء)،
لمعرفة المزيد عن LangGraph، تحقق من أول دورة تدريبية لأكاديمية LangChain، مقدمة إلى LangGraph ، المتاحة مجانًا هنا.
تعد منصة LangGraph حلاً تجاريًا لنشر التطبيقات الوكيلة في الإنتاج، وهي مبنية على إطار عمل LangGraph مفتوح المصدر. فيما يلي بعض المشكلات الشائعة التي تنشأ في عمليات النشر المعقدة، والتي تعالجها منصة LangGraph:
pip install -U langgraph
أحد المفاهيم المركزية في LangGraph هو الحالة. ينشئ كل تنفيذ للرسم البياني حالة يتم تمريرها بين العقد في الرسم البياني أثناء تنفيذها، وتقوم كل عقدة بتحديث هذه الحالة الداخلية بقيمة الإرجاع الخاصة بها بعد تنفيذها. يتم تحديد الطريقة التي يقوم بها الرسم البياني بتحديث حالته الداخلية إما عن طريق نوع الرسم البياني المختار أو وظيفة مخصصة.
دعونا نلقي نظرة على مثال بسيط لوكيل يمكنه استخدام أداة بحث.
pip install langchain-anthropic
export ANTHROPIC_API_KEY=sk-...
اختياريًا، يمكننا إعداد LangSmith للحصول على أفضل إمكانية للمراقبة في فئتها.
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY=lsv2_sk_...
from typing import Annotated , Literal , TypedDict
from langchain_core . messages import HumanMessage
from langchain_anthropic import ChatAnthropic
from langchain_core . tools import tool
from langgraph . checkpoint . memory import MemorySaver
from langgraph . graph import END , START , StateGraph , MessagesState
from langgraph . prebuilt import ToolNode
# Define the tools for the agent to use
@ tool
def search ( query : str ):
"""Call to surf the web."""
# This is a placeholder, but don't tell the LLM that...
if "sf" in query . lower () or "san francisco" in query . lower ():
return "It's 60 degrees and foggy."
return "It's 90 degrees and sunny."
tools = [ search ]
tool_node = ToolNode ( tools )
model = ChatAnthropic ( model = "claude-3-5-sonnet-20240620" , temperature = 0 ). bind_tools ( tools )
# Define the function that determines whether to continue or not
def should_continue ( state : MessagesState ) -> Literal [ "tools" , END ]:
messages = state [ 'messages' ]
last_message = messages [ - 1 ]
# If the LLM makes a tool call, then we route to the "tools" node
if last_message . tool_calls :
return "tools"
# Otherwise, we stop (reply to the user)
return END
# Define the function that calls the model
def call_model ( state : MessagesState ):
messages = state [ 'messages' ]
response = model . invoke ( messages )
# We return a list, because this will get added to the existing list
return { "messages" : [ response ]}
# Define a new graph
workflow = StateGraph ( MessagesState )
# Define the two nodes we will cycle between
workflow . add_node ( "agent" , call_model )
workflow . add_node ( "tools" , tool_node )
# Set the entrypoint as `agent`
# This means that this node is the first one called
workflow . add_edge ( START , "agent" )
# We now add a conditional edge
workflow . add_conditional_edges (
# First, we define the start node. We use `agent`.
# This means these are the edges taken after the `agent` node is called.
"agent" ,
# Next, we pass in the function that will determine which node is called next.
should_continue ,
)
# We now add a normal edge from `tools` to `agent`.
# This means that after `tools` is called, `agent` node is called next.
workflow . add_edge ( "tools" , 'agent' )
# Initialize memory to persist state between graph runs
checkpointer = MemorySaver ()
# Finally, we compile it!
# This compiles it into a LangChain Runnable,
# meaning you can use it as you would any other runnable.
# Note that we're (optionally) passing the memory when compiling the graph
app = workflow . compile ( checkpointer = checkpointer )
# Use the Runnable
final_state = app . invoke (
{ "messages" : [ HumanMessage ( content = "what is the weather in sf" )]},
config = { "configurable" : { "thread_id" : 42 }}
)
final_state [ "messages" ][ - 1 ]. content
"Based on the search results, I can tell you that the current weather in San Francisco is:nnTemperature: 60 degrees FahrenheitnConditions: FoggynnSan Francisco is known for its microclimates and frequent fog, especially during the summer months. The temperature of 60°F (about 15.5°C) is quite typical for the city, which tends to have mild temperatures year-round. The fog, often referred to as "Karl the Fog" by locals, is a characteristic feature of San Francisco's weather, particularly in the mornings and evenings.nnIs there anything else you'd like to know about the weather in San Francisco or any other location?"
الآن عندما نمرر نفس "thread_id"
، يتم الاحتفاظ بسياق المحادثة عبر الحالة المحفوظة (أي قائمة الرسائل المخزنة)
final_state = app . invoke (
{ "messages" : [ HumanMessage ( content = "what about ny" )]},
config = { "configurable" : { "thread_id" : 42 }}
)
final_state [ "messages" ][ - 1 ]. content
"Based on the search results, I can tell you that the current weather in New York City is:nnTemperature: 90 degrees Fahrenheit (approximately 32.2 degrees Celsius)nConditions: SunnynnThis weather is quite different from what we just saw in San Francisco. New York is experiencing much warmer temperatures right now. Here are a few points to note:nn1. The temperature of 90°F is quite hot, typical of summer weather in New York City.n2. The sunny conditions suggest clear skies, which is great for outdoor activities but also means it might feel even hotter due to direct sunlight.n3. This kind of weather in New York often comes with high humidity, which can make it feel even warmer than the actual temperature suggests.nnIt's interesting to see the stark contrast between San Francisco's mild, foggy weather and New York's hot, sunny conditions. This difference illustrates how varied weather can be across different parts of the United States, even on the same day.nnIs there anything else you'd like to know about the weather in New York or any other location?"
ChatAnthropic
باعتباره LLM لدينا. ملاحظة: نحتاج إلى التأكد من أن النموذج يعرف أن لديه هذه الأدوات المتاحة للاتصال به. يمكننا القيام بذلك عن طريق تحويل أدوات LangChain إلى تنسيق استدعاء أداة OpenAI باستخدام طريقة .bind_tools()
.StateGraph
) عن طريق تمرير مخطط الحالة (في حالتنا MessagesState
)MessagesState
هو مخطط حالة تم إنشاؤه مسبقًا وله سمة واحدة - قائمة بكائنات Message
LangChain، بالإضافة إلى منطق لدمج التحديثات من كل عقدة في الحالةهناك عقدتان رئيسيتان نحتاجهما:
agent
: المسؤولة عن تحديد الإجراءات التي يجب اتخاذها (إن وجدت).tools
التي تستدعي الأدوات: إذا قرر الوكيل اتخاذ إجراء، فستقوم هذه العقدة بعد ذلك بتنفيذ هذا الإجراء. أولاً، نحتاج إلى تعيين نقطة الدخول لتنفيذ الرسم البياني - عقدة agent
.
ثم نحدد حافة عادية وأخرى شرطية. الحافة الشرطية تعني أن الوجهة تعتمد على محتويات حالة الرسم البياني ( MessageState
). في حالتنا، الوجهة غير معروفة حتى يقرر الوكيل (LLM).
.invoke()
و .stream()
و .batch()
مع مدخلاتكMemorySaver
- أداة فحص بسيطة في الذاكرة يضيف LangGraph رسالة الإدخال إلى الحالة الداخلية، ثم يمرر الحالة إلى عقدة نقطة الدخول، "agent"
.
يتم تنفيذ عقدة "agent"
واستدعاء نموذج الدردشة.
يقوم نموذج الدردشة بإرجاع رسالة AIMessage
. يضيف LangGraph هذا إلى الحالة.
يقوم الرسم البياني بتدوير الخطوات التالية حتى لا يكون هناك المزيد tool_calls
في AIMessage
:
AIMessage
يحتوي على tool_calls
، فسيتم تنفيذ عقدة "tools"
"agent"
مرة أخرى وإرجاع AIMessage
يتقدم التنفيذ إلى قيمة END
الخاصة ويخرج الحالة النهائية. ونتيجة لذلك، نحصل على قائمة بجميع رسائل الدردشة لدينا كمخرجات.
لمزيد من المعلومات حول كيفية المساهمة، انظر هنا.