استخراج بيانات مهيكلة (Output Parsers): إجبار الذكاء الاصطناعي على الرد بصيغة JSON فقط


مرحباً بكم! سنتعلم اليوم كيفية إجبار نماذج الذكاء الاصطناعي على إنتاج استجابات مهيكلة بصيغة JSON باستخدام Output Parsers في LangChain. هذا سيمكننا من التعامل مع مخرجات الذكاء الاصطناعي برمجياً وبسهولة.

الخطوة 1: تهيئة البيئة وتحديد هيكل JSON المطلوب

سنبدأ بتثبيت المكتبات الضرورية وتحديد كيف نريد أن تبدو بيانات JSON التي نتوقعها من النموذج. سنستخدم Pydantic لتعريف هذا الهيكل بشكل واضح.

ملاحظة تقنية: Pydantic هي مكتبة قوية للتحقق من صحة البيانات وإدارتها باستخدام تلميحات النوع (Type Hints) في Python، وهي مثالية لتعريف schemas لـ JSON.

# تثبيت المكتبات اللازمة
# pip install langchain-community langchain-openai pydantic

from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI
import os

# قم بتعيين مفتاح API الخاص بك (يفضل استخدام متغيرات البيئة)
# os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"

# تحديد هيكل البيانات المتوقع باستخدام Pydantic
# نريد أن يحتوي الرد على اسم المنتج ووصفه وسعره بالدولار
class ProductInfo(BaseModel):
    product_name: str = Field(description="اسم المنتج")
    description: str = Field(description="وصف موجز للمنتج")
    price_usd: float = Field(description="سعر المنتج بالدولار الأمريكي")

# إنشاء parser من Pydantic model
parser = JsonOutputParser(pydantic_object=ProductInfo)

في هذه الخطوة، قمنا بتعريف نموذج Pydantic ProductInfo الذي يصف بالضبط الحقول التي نتوقعها في استجابة JSON. ثم أنشأنا JsonOutputParser الذي سيستخدم هذا النموذج للتحقق من صحة الإخراج وتحليله.

الخطوة 2: بناء الموجه (Prompt) مع تعليمات التنسيق

لإجبار النموذج على الرد بصيغة JSON، يجب أن نضمن أن الموجه الخاص بنا يتضمن تعليمات واضحة حول التنسيق المطلوب. نستخدم parser.get_format_instructions() لإضافة هذه التعليمات تلقائياً إلى الموجه.

# تهيئة النموذج اللغوي (يمكنك استخدام أي نموذج مدعوم)
llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")

# بناء قالب الموجه
# نستخدم format_instructions لإخبار النموذج بكيفية تنسيق الإخراج كـ JSON
prompt = PromptTemplate(
    template="اجب على سؤال المستخدم بصيغة JSON.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={
        "format_instructions": parser.get_format_instructions()
    },
)

هنا، قمنا بإنشاء PromptTemplate الذي يأخذ query المستخدم ويضيف إليه format_instructions التي ينتجها الـ parser. هذه التعليمات ضرورية لتوجيه النموذج لإنشاء JSON يتوافق مع ProductInfo.

الخطوة 3: ربط المكونات واستدعاء النموذج

الآن، سنربط الموجه والنموذج والـ parser معًا في سلسلة (chain) واحدة، ثم نستدعيها بسؤال. الـ parser سيقوم تلقائياً بتحليل إخراج النموذج إلى كائن Pydantic.

# إنشاء سلسلة (chain) تربط الموجه بالنموذج بالـ parser
chain = prompt | llm | parser

# استدعاء السلسلة مع استعلام
user_query = "أعطني معلومات عن هاتف ذكي جديد من Apple"
response = chain.invoke({"query": user_query})

# طباعة الاستجابة المهيكلة
print(response)
print(type(response))

في هذه الخطوة، ربطنا prompt بـ llm وأخيراً بـ parser. عندما نستدعي السلسلة بـ invoke، يقوم النموذج بإنشاء استجابة نصية، ثم يقوم الـ parser بتحويلها إلى كائن Python (Pydantic object) يتوافق مع ProductInfo.

الكود النهائي الكامل

# تثبيت المكتبات اللازمة
# pip install langchain-community langchain-openai pydantic

from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI
import os

# قم بتعيين مفتاح API الخاص بك (يفضل استخدام متغيرات البيئة)
# os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"

# الخطوة 1: تحديد هيكل البيانات المتوقع باستخدام Pydantic
# نريد أن يحتوي الرد على اسم المنتج ووصفه وسعره بالدولار
class ProductInfo(BaseModel):
    product_name: str = Field(description="اسم المنتج")
    description: str = Field(description="وصف موجز للمنتج")
    price_usd: float = Field(description="سعر المنتج بالدولار الأمريكي")

# إنشاء parser من Pydantic model
parser = JsonOutputParser(pydantic_object=ProductInfo)

# الخطوة 2: بناء قالب الموجه مع تعليمات التنسيق
# تهيئة النموذج اللغوي (يمكنك استخدام أي نموذج مدعوم)
llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")

# بناء قالب الموجه
# نستخدم format_instructions لإخبار النموذج بكيفية تنسيق الإخراج كـ JSON
prompt = PromptTemplate(
    template="اجب على سؤال المستخدم بصيغة JSON.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={
        "format_instructions": parser.get_format_instructions()
    },
)

# الخطوة 3: إنشاء سلسلة (chain) وربط المكونات واستدعاء النموذج
chain = prompt | llm | parser

# استدعاء السلسلة مع استعلام
user_query = "أعطني معلومات عن هاتف ذكي جديد من Apple"
response = chain.invoke({"query": user_query})

# طباعة الاستجابة المهيكلة
print(response)
print(type(response))

النتيجة المتوقعة

عند تشغيل السكربت، ستحصل على كائن Python (قاموس Pydantic) يمثل معلومات المنتج المطلوبة، مطبوعاً مباشرةً من النموذج اللغوي بعد معالجته بواسطة JsonOutputParser. لن تكون الاستجابة مجرد نص خام، بل بيانات مهيكلة يمكنك الوصول إلى حقولها بسهولة.

{'product_name': 'iPhone 15 Pro', 'description': 'أحدث هاتف ذكي من Apple يتميز بشريحة A17 Bionic، كاميرا متطورة من التيتانيوم، ومنفذ USB-C.', 'price_usd': 999.0}
<class 'langchain_core.pydantic_v1.main.ProductInfo'>

كما ترى، النتيجة هي كائن Python من النوع ProductInfo، مما يؤكد أن الـ parser نجح في تحويل النص الخام إلى بيانات مهيكلة قابلة للاستخدام برمجياً.