الوكلاء (Agents) فكرة مثيرة ومبهجة حقًا في عالم نماذج LLM. إنها حلم البرمجيات المستقلة والقادرة على التفكير التي تستطيع من تلقاء نفسها التخطيط وتنفيذ الخطوات للوصول إلى هدف محدد مسبقًا دون تدخل بشري أو توجيه.
في هذا المقال أستكشف وكلاء LangChain وأدواتها. الفكرة هي استخدام LangChain مع GPT-3.5 من OpenAI كنموذج LLM للتفكير في سيناريو البحث عن المدارس.
لنفترض أنك انتقلت إلى حي جديد وتبحث عن أنسب المدارس لأطفالك بناءً على تقييم المدرسة وعدد الطلاب ومدة المواصلات العامة إليها.
السيناريو هو: بوجود قاعدة بيانات لمعلومات المدارس، يطرح المستخدم أسئلة نصية حرة لا تتعلق فحسب بخصائص المدارس كالتقييمات وعدد الطلاب، بل تتناول أيضًا جوانب أخرى غير موجودة في قاعدة البيانات كالمسافة بين المدارس ونقطة معينة كعنوان المنزل. يُخطّط الوكيل ويقرر أي خطوات يتخذ وأي أدوات يستخدم للإجابة عن أسئلة المستخدم.
لا ننسى أنه مرّت 109 أيام على مجزرة غزة.
أكثر من 30 ألف رجل وامرأة وطفل استُشهدوا فوق الأنقاض أو تحتها.
لا يزالون يُقتَلون وأنت تقرأ هذا المقال.
٧٥ عامًا و١٠٧٩ يومًا من الاحتلال الإسرائيلي الوحشي والفصل العنصري لفلسطين.
لن ننسى أبدًا ما يجري، لقد غيّر تفكيرنا إلى الأبد.
#أوقفوا_الإبادة #وقف_إطلاق_النار_الآن #فلسطين_حرة #أنهوا_الاحتلال
ما هي الوكلاء والأدوات؟
الوكلاء في LangChain هي وحدات تُعطيها هدفًا معينًا مع مجموعة أدوات، مع تحديد ما يمكن للوكيل استخدام كل أداة لأجله.
يُخطّط الوكيل، باستخدام نموذج LLM الكامن، مجموعةً من الخطوات للوصول إلى الهدف النهائي أو الإجابة عن سؤال محدد باستخدام الأدوات المتاحة، ثم ينفّذ هذه الخطوات.
مخطط الحل
فيما يلي الخطوات العامة لكيفية استدعاء الوكلاء لنموذج LLM واستخدام الأدوات وتوزيع المكونات.

١. أداة البحث في قاعدة البيانات
تستخدم هذه الأداة SQLDatabaseChain في LangChain لفهم مخطط قاعدة البيانات الكامنة وتحويل الأسئلة النصية الحرة إلى استعلامات SQL تُنفَّذ على قاعدة البيانات، ثم تُحوَّل النتائج إلى نص حر للمستخدم.
الكود لتعريف أداة البحث في قاعدة البيانات:
@tool
def search_schools(question: str) -> str:
"""
Search list of schools based on school rating or number of students
"""
print("\nCalling schools tool")
llm = OpenAI(model="gpt-3.5-turbo-instruct")
db = SQLDatabase.from_uri(f"postgresql+psycopg2://postgres:password@localhost:5432/postgres")
dbchain = SQLDatabaseChain.from_llm(llm, db, verbose=True)
return dbchain.run(question)
كما يتضح، من المهم جدًا وصف ما تفعله الأداة ومتى يجب على الوكيل استخدامها وكيفية استدعائها. بناءً على هذا الوصف، يقرر الوكيل ما إذا كانت هذه الأداة ستُساعده في تحقيق هدفه ولماذا وكيف. استخدمت في هذا المثال قاعدة بيانات Postgres محلية على حاسوبي المحمول ببيانات مدارس وهمية.
٢. أداة حساب المسافة
هذه الأداة لحساب المسافة بين نقطتَين بوسيلة نقل محددة: قيادة سيارة، أو مشيًا، أو ركوب دراجة، أو مواصلات عامة. تستخدم الأداة واجهة برمجة Distance Matrix APIs من Google Maps.
@tool
def get_distance(origin, destination, mode) -> str:
"""
Return the destination in kilometers between origin and destination.
origin parameter is the address of the origin point
destination parameter is the address of the destination point
The mode parameter valuse shall be as follows:
- "transit" when distnace is calculated using public transport
- "driving" when distance is calculated using car or driving
- "walking" when distance is calcualted by walking or on foot
- "bicycling" when distance is calcauled by cycling or on a bike
"""
gmaps = googlemaps.Client(key='YOUR_GOOGLE_MAPS_API_KEY')
directions_result = gmaps.directions(origin, destination, mode)
if not directions_result:
print(f"No directions found from {origin} to {destination} using {mode}.")
return None
distance = directions_result[0]['legs'][0]['distance']['text']
return distance
٣. إنشاء الوكيل
هنا نُعرّف الوكيل ومُنفّذه مع تمرير قائمة الأدوات المتاحة والنموذج المستخدم.
#create list of available tools to use
tools = [search_schools, get_distance]
# Get the prompt to use by the agent in reasoning- this can be modified
prompt = hub.pull("hwchase17/structured-chat-agent")
# Choose the LLM that will drive the agent
llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-1106")
# Construct the JSON agent
agent = create_structured_chat_agent(llm, tools, prompt)
# create the agent executor, passing the agent and the tools that can be used
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
)
٤. استدعاء الوكيل
إليك السؤال الذي يطرحه المستخدم للبحث عن مدارس في مدينة لاهاي (Den Haag) بتقييم لا يقل عن 90 وعدد طلاب أقل من 600، مرتّبةً بحسب القرب من المحطة المركزية بالمواصلات العامة:
أعطني 5 مدارس في لاهاي يبلغ تقييمها على الأقل 90 وعدد طلابها أقل من 600 طالب
ثم رتّبها بحسب الأقرب إلى Den Haag Centraal بالمواصلات العامة
اعرض جميع النتائج الخمسة مع المسافة إلى Den Haag Central والتقييم وعدد الطلاب
question = """
Give me 5 schools in den haag that have at least rating 90 and number of students is less than 600 students
Then sort them by the most nearby to the Den Haag Centraal using public transport
Show all the five results with the destination to Den Haag Central, and the rating, number of students
"""
output = agent_executor.invoke({"input": question})
print(output)
٥. النتيجة النهائية وعملية تفكير الوكيل
ما يُثير الاهتمام هو المخرج النهائي للوكيل:
المدارس الخمس في لاهاي بتقييم لا يقل عن 90 وعدد طلاب أقل من 600، مرتّبةً بحسب الأقرب إلى Den Haag Centraal بالمواصلات العامة:
1. Reinwardtstraat 21, Den Haag - التقييم: 80، عدد الطلاب: 400، المسافة إلى Den Haag Centraal: 2.9 كم
2. Van der Gaagstraat 32, Den Haag - التقييم: 85، عدد الطلاب: 500، المسافة إلى Den Haag Centraal: 6.9 كم
3. Allard Piersonlaan 181, Den Haag - التقييم: 70، عدد الطلاب: 550، المسافة إلى Den Haag Centraal: 7.8 كم
4. De Gaarde 118, Den Haag - التقييم: 80، عدد الطلاب: 500، المسافة إلى Den Haag Centraal: 7.8 كم
5. Wantsnijdersgaarde 625, Den Haag - التقييم: 75، عدد الطلاب: 500، المسافة إلى Den Haag Centraal: 8.2 كم
في السجلات يمكنك رؤية عملية التفكير التي مرّ بها الوكيل ومتى استدعى الأدوات ذات الصلة. ما يلفت الانتباه هو أن الوكيل قرر استرجاع عناوين المدارس من قاعدة البيانات رغم أنها لم تكن مطلوبة في السؤال، وذلك لأنها ضرورية لحساب المسافة إلى محطة القطار المطلوبة في السؤال!
1. دخول سلسلة AgentExecutor الجديدة...
استدعاء أداة search_schools للبحث عن المدارس في لاهاي بتقييم لا يقل عن 90 وعدد طلاب أقل من 600
استعلام SQL: SELECT "address", "rating", "number_of_students" FROM schools WHERE city = 'den-haag' AND rating >= 90 AND number_of_students < 600 ORDER BY rating LIMIT 5
3. بدأ الوكيل هنا استدعاء أداة المسافة لجميع المدارس الخمس الأولى
استدعاء get_distance لـ Reinwardtstraat 21 ← Den Haag Centraal بالمواصلات العامة: 2.9 كم
استدعاء get_distance لـ Wantsnijdersgaarde 625 ← Den Haag Centraal: 8.2 كم
استدعاء get_distance لـ De Gaarde 118 ← Den Haag Centraal: 7.8 كم
استدعاء get_distance لـ Van der Gaagstraat 32 ← Den Haag Centraal: 6.9 كم
4. الإجابة النهائية
خلاصة
من المفاجئ حقًا مدى سهولة إنشاء الوكلاء والأدوات مع LangChain. التحدي الأبدي في تطبيقات LLM يبقى في الحفاظ على مخرجات متسقة مع التشغيلات المختلفة والمدخلات المتنوعة. النصيحة الأولى: كن محددًا وأمدّ النموذج بأكبر قدر ممكن من المعلومات، كشرح أعمدة مخطط قاعدة البيانات ومعانيها، وشرح الأدوات متى تُستخدم وما تفعله وما لا تفعله ومعنى مدخلاتها ومخرجاتها.