نرمافزارهای سازمانی به ندرت از صفر (greenfield) ساخته میشوند. اکثر سازمانهای بزرگ همچنان منطق تجاری حیاتی خود را روی مینفریمها اجرا میکنند و از طریق شغلهای دستهای (batch jobs) و سرویسهای وب SOAP ارتباط برقرار میکنند. با تبدیل شدن مدلهای زبانی بزرگ (LLM) به رابط انتخابی برای اپلیکیشنهای مدرن، چالش دیگر صرفاً ساخت چتباتها نیست، بلکه پل زدن بر شکاف بین هوش مصنوعی احتمالی (probabilistic) و سیستمهای قدیمی قطعی (deterministic) است. LangChain یک چارچوب قدرتمند برای انتزاع این پیچیدگی ارائه میدهد و به توسعهدهندگان اجازه میسازد عاملهایی (agents) بسازند که بتوانند روی ساختارهای دادهای قدیمی استدلال کنند، بدون نیاز به مدرنسازی کامل زیرساخت.
درک چالش یکپارچهسازی
یکپارچهسازی یک LLM با یک سیستم قدیمی دو مشکل متمایز را مطرح میکند: قالببندی داده و مدیریت وضعیت. سیستمهای مینفریمی، مانند سیستمهایی که CICS یا Db2 را اجرا میکنند، اغلب به رکوردهای طول ثابت و دادههای سلسلهمراتبی پیچیده (XML یا EDI) تکیه میکنند. APIهای SOAP، با وجود مبتنی بودن بر استانداردها، اغلب پرحرف (verbose) و همگام (synchronous) هستند که باعث میشود برای LLMها بدون پرامپتهای ساختاریافته، فراخوانی قابل اعتماد آنها دشوار باشد. یک پرامپت مستقیم مانند "جزئیات کاربر با شناسه 123 را دریافت کن" شکست میخورد زیرا LLM اسکیمای خاص یا URL نقطه پایانی را نمیداند. LangChain این مشکل را با امکان تعریف "ابزارها" (Tools) که این فراخوانیهای قدیمی را میپیچند، حل میکند و به LLM یک رابط واضح و تایپشده برای تعامل با استک قدیمی میدهد.
ساخت پل SOAP
گام اول، کپسوله کردن سرویس SOAP قدیمی در یک ابزار LangChain است. این کار شامل تعریف اسکیمای ورودی و منطق برای تجزیه (parse) پوشه SOAP (envelope) است. ما از دکوریتور @tool برای ایجاد یک تابع استفاده میکنیم که LLM میتواند آن را فراخوانی کند. نکته کلیدی در اینجا مدیریت خطا است؛ سیستمهای قدیمی اغلب کدهای خطای مبهم برمیگردانند. ابزار باید این کدها را به پیامهای قابل فهم برای انسان تبدیل کند تا LLM بتواند برای تلاش مجدد یا تنظیم استراتژی از آنها استفاده کند.
from langchain_core.tools import tool
import requests
from pydantic import BaseModel, Field
class LegacyUserRequest(BaseModel):
"""دریافت جزئیات کاربر از API 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"خطا: API قدیمی {response.status_code} را برگرداند"
except Exception as e:
return f"اتصال ناموفق بود: {str(e)}"
مدیریت شغلهای دستهای مینفریم
برخلاف APIهای SOAP، شغلهای دستهای مینفریم اغلب ناهمگام (asynchronous) هستند. LLM نمیتواند برای تکمیل یک شغل در زمان واقعی صبر کند. یک معماری عامل (agent) مقاوم باید الگوی "پولینگ" (polling) یا مکانیزم وبهوک (webhook) را پیادهسازی کند. در LangChain، میتوانید یک تنظیم ابزار دو مرحلهای ایجاد کنید: یکی برای ارسال شغل و دیگری برای بررسی وضعیت. منطق عامل (معمولاً هدایت شده توسط زنجیره ReAct یا Plan-and-Execute) باید دستورالعملی برای صبر کردن یا تلاش مجدد در صورتی که شغل هنوز در حال "اجرا" (Running) باشد، دریافت کند. این کار نیازمند مهندسی پرامپت دقیق است تا از هالوسیناسیون (توهم) LLM در مورد دادههایی که هنوز بازگشت نکردهاند، جلوگیری شود.
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 کیست؟"
})
بهترین روشها برای طراحی عاملهای قدیمی
هنگام استقرار این عاملها، امنیت و تأخیر (latency) را در نظر بگیرید. سیستمهای قدیمی اغلب پشت فایروالهای سختگیرانه قرار دارند؛ اطمینان حاصل کنید که عامل شما در یک ناحیه شبکه با مجوز دسترسی به این نقاط پایانی اجرا میشود. علاوه بر این، پاسخهای SOAP میتوانند بزرگ باشند. توصیه میشود پاسخ XML/JSON را در داخل تابع ابزار پسپردازش (post-process) کنید تا فقط فیلدهای مرتبط را استخراج کنید، قبل از بازگرداندن رشته به LLM. این کار مصرف توکن را کاهش میدهد و دقت پاسخ نهایی مدل را بهبود میبخشد.
نتیجهگیری
پل زدن بر شکاف بین هوش مصنوعی مدرن و زیرساخت قدیمی، درباره جایگزینی سیستمهای قدیمی نیست، بلکه درباره تقویت آنهاست. با استفاده از LangChain برای ایجاد رابطهای ساختاریافته و مبتنی بر ابزار برای سرویسهای مینفریم و SOAP، توسعهدهندگان میتوانند LLMها را توانمند سازند تا به عنوان یک میانیافزار (middleware) هوشمند عمل کنند. این رویکرد به سازمانها اجازه میدهد از قدرت هوش مصنوعی مولد برای بهبود جریانهای کاری موجود استفاده کنند و دسترسی به زبان طبیعی به دادههای تاریخی حیاتی را فراهم کنند، بدون هزینه سنگین مهاجرت کامل سیستم. با تکامل چارچوبهای عامل، این الگوی "پیچیدن" سیستمهای قدیمی در لایههای معنایی (semantic layers) به یک روش استاندارد در یکپارچهسازی سازمانی تبدیل خواهد شد.