نادرًا ما تكون برمجيات المؤسسات جديدة تمامًا. لا تزال معظم المنظمات الكبيرة تشغّل منطق الأعمال الحاسم على الحاسبات المركزية، وتتواصل عبر مهام الدفعة وخدمات ويب SOAP. ومع تحول نماذج اللغة الكبيرة (LLMs) إلى الواجهة المفضلة للتطبيقات الحديثة، لم يعد التحدي مجرد بناء روبوتات محادثة، بل سد الفجوة بين الذكاء الاصطناعي الاحتمالي والأنظمة القديمة الحتمية. يوفر LangChain إطار عمل قوي لتجريد هذه التعقيدات، مما يتيح للمطورين بناء وكلاء يمكنهم الاستدلال على هياكل البيانات القديمة دون الحاجة إلى تحديث شامل للبنية التحتية.
فهم تحدي التكامل
يُقدّم تكامل نموذج لغة كبير مع نظام قديم مشكلتين متميزتين: تنسيق البيانات وإدارة الحالة. تعتمد أنظمة الحاسبات المركزية، مثل تلك التي تشغّل CICS أو Db2، غالبًا على سجلات ذات طول ثابت وبيانات هرمية معقدة (XML أو EDI). بينما تعتمد واجهات برمجة تطبيقات SOAP على المعايير، إلا أنها غالبًا ما تكون مفصلة ومتزامنة، مما يجعلها صعبة الاستدعاء الموثوق من قبل نماذج اللغة الكبيرة دون استخدام موجهات منظمة. فموجه مباشر مثل "احصل على تفاصيل المستخدم للمعرّف 123" يفشل لأن النموذج لا يعرف المخطط المحدد أو عنوان النهاية URL. يحل LangChain هذه المشكلة من خلال السماح لنا بتعريف "أدوات" تغلف هذه الاستدعاءات القديمة، مما يمنح النموذج واجهة واضحة ومفصّلة للتفاعل مع المكدس القديم.
بناء جسر SOAP
الخطوة الأولى هي تغليف خدمة SOAP القديمة في أداة LangChain. يتضمن ذلك تعريف مخطط الإدخال والمنطق الخاص بتحليل غلاف SOAP. نستخدم زخرفة @tool لإنشاء دالة يمكن للنموذج استدعاؤها. المفتاح هنا هو معالجة الأخطاء؛ فغالبًا ما تُعيد الأنظمة القديمة رموز أخطاء غير واضحة. يجب أن تترجم الأداة هذه الرموز إلى رسائل مفهومة يمكن للنموذج استخدامها لإعادة المحاولة أو تعديل استراتيجيته.
from langchain_core.tools import tool
import requests
from pydantic import BaseModel, Field
class LegacyUserRequest(BaseModel):
"""استرجاع تفاصيل المستخدم من واجهة برمجة تطبيقات SOAP القديمة."""
user_id: str = Field(..., description="المعرّف الفريد للمستخدم")
@tool
def get_user_from_mainframe(user_id: str) -> str:
"""
يتصل بنقطة نهاية SOAP القديمة لجلب بيانات المستخدم.
Args:
user_id: المعرّف الخاص بالمستخدم المراد استرجاعه.
"""
soap_envelope = f"""
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:GetUser>
<ns:UserID>{user_id}</ns:UserID>
</ns:GetUser>
</soapenv:Body>
</soapenv:Envelope>
"""
headers = {
"Content-Type": "application/soap+xml",
"SOAPAction": "http://example.com/getUser"
}
try:
response = requests.post("https://legacy.enterprise.com/api", data=soap_envelope, headers=headers)
# في سيناريو حقيقي، ستقوم بتحليل استجابة XML بشكل صحيح
# هنا نحاكي نجاحًا للإيجاز
if response.status_code == 200:
return f"تم العثور على المستخدم {user_id}: جون دو، مهندس أول"
else:
return f"خطأ: أعادت واجهة برمجة التطبيقات القديمة {response.status_code}"
except Exception as e:
return f"فشل الاتصال: {str(e)}"
معالجة مهام الدفعة في الحاسبات المركزية
على عكس واجهات برمجة تطبيقات SOAP، غالبًا ما تكون مهام الدفعة في الحاسبات المركزية غير متزامنة. لا يمكن لنموذج اللغة الكبيرة انتظار اكتمال المهمة في الوقت الفعلي. يجب أن تنفذ بنية وكيل قوية نمط "الاستطلاع" (polling) أو آلية Webhook. في LangChain، يمكنك إنشاء إعداد أداة من خطوتين: واحدة لإرسال المهمة وأخرى للتحقق من حالتها. يجب توجيه منطق الوكيل (الذي يقوده عادةً سلسلة ReAct أو Plan-and-Execute) للانتظار أو إعادة المحاولة إذا كانت المهمة لا تزال "قيد التنفيذ". يتطلب هذا هندسة موجهات دقيقة لمنع النموذج من اختلاق بيانات لم تُعد بعد.
from langchain.agents import AgentExecutor, create_react_agent
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
llm = ChatOpenAI(model="gpt-4", temperature=0)
tools = [get_user_from_mainframe]
prompt = PromptTemplate.from_template("""
أجب عن الأسئلة التالية بأفضل ما تستطيع.
لديك وصول إلى الأدوات التالية:
{tools}
استخدم التنسيق التالي:
السؤال: السؤال المدخل الذي يجب الإجابة عنه
الفكر: يجب أن تفكر دائمًا في ما يجب فعله
الإجراء: الإجراء الذي يجب اتخاذه، ويجب أن يكون واحدًا من [{tool_names}]
إدخال الإجراء: الإدخال الخاص بالإجراء
الملاحظة: نتيجة الإجراء
... (يمكن تكرار هذا الفكر/الإجراء/إدخال الإجراء/الملاحظة N مرات)
الفكر: أنا الآن أعرف الإجابة النهائية
الإجابة النهائية: الإجابة النهائية على السؤال المدخل الأصلي
ابدأ!
السؤال: {input}
الفكر:{agent_scratchpad}
""")
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
response = agent_executor.invoke({
"input": "من هو المستخدم ذو المعرّف 123؟"
})
أفضل الممارسات لتصميم الوكلاء للأنظمة القديمة
عند نشر هذه الوكلاء، خذ في الاعتبار الأمان وزمن الاستجابة. غالبًا ما تكون الأنظمة القديمة خلف جدران نارية صارمة؛ تأكد من أن وكيلك يعمل في منطقة شبكة لديها إذن للوصول إلى هذه النقاط النهائية. علاوة على ذلك، يمكن أن تكون استجابات SOAP كبيرة. يُنصح بمعالجة استجابة XML/JSON ما بعد التنفيذ داخل دالة الأداة لاستخراج الحقول ذات الصلة فقط قبل إرجاع النص إلى النموذج. يقلل هذا من استخدام الرموز (tokens) ويحسن دقة الإجابة النهائية للنموذج.
الخلاصة
إن سد الفجوة بين الذكاء الاصطناعي الحديث والبنية التحتية القديمة لا يتعلق باستبدال الأنظمة القديمة، بل يتعلق بتعزيزها. من خلال استخدام LangChain لإنشاء واجهات منظمة قائمة على الأدوات لخدمات Mainframe وSOAP، يمكن للمطورين تمكين نماذج اللغة الكبيرة للعمل كوسائط ذكية. يتيح هذا النهج للمؤسسات الاستفادة من قوة الذكاء الاصطناعي التوليدي لتعزيز سير العمل الحالية، وتوفير وصول بلغة طبيعية إلى البيانات التاريخية الحاسمة دون العبء الضخم لهجرة نظام كاملة. ومع تطور أطر الوكلاء، سيصبح نمط "تغليف" الأنظمة القديمة بطبقات دلالية ممارسة قياسية في تكامل المؤسسات.