المخرجات المنظّمة باستخدام Pydantic
عرّفوا نماذج Pydantic كمخطط للمخرجات، ومرّروها إلى API عبر ميزة المخرجات المنظّمة الجديدة، وأزيلوا تسلسل الاستجابات تلقائيًا إلى كائنات Python ذات أنواع محددة.
المخرجات المنظّمة باستخدام Pydantic درس مجاني في AI Engineering Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Engineering Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
لماذا نستخدم Pydantic لمخرجات النماذج اللغوية الكبيرة؟
إن Pydantic مكتبة Python للتحقق من صحة البيانات، وتعرّف مخططات البيانات باستخدام تلميحات الأنواع في Python. وهي متخصصة في التحقق من صحة البيانات القادمة من مصادر خارجية وفك تسلسلها — وتُعد مخرجات النماذج اللغوية الكبيرة من أكثر المصادر الخارجية عدمًا للموثوقية التي ستتعامل معها. ويمنحك الجمع بين مخططات Pydantic والمخرجات المهيكلة من OpenAI استجابات آمنة من ناحية الأنواع، تم التحقق من صحتها وفك تسلسلها تلقائيًا من نموذج ذكاء اصطناعي.
بدلًا من كتابة data = json.loads(response) ثم استخراج الحقول وتحويل أنواعها يدويًا، تحصل على كائن Python ذي أنواع محددة بالكامل، حيث يُضمن أن يكون لكل حقل النوع الصحيح، مع الإكمال التلقائي في بيئة التطوير المتكاملة والتحقق أثناء التشغيل. هذه هي الطريقة التي تتعامل بها فرق هندسة الذكاء الاصطناعي الاحترافية مع الاستخراج المهيكل.
تعريف مخطط Pydantic أساسي
نموذج Pydantic هو فئة ترث من BaseModel، مع تعريف الحقول باستخدام تلميحات الأنواع في Python. ويمكن أن تكون أنواع الحقول بدائيات Python، أو نماذج Pydantic أخرى للتداخل، أو أنواعًا من الوحدة typing للقوائم والحقول الاختيارية والاتحادات.
from pydantic import BaseModel, Field
from typing import Optional, List
from enum import Enum
class Sentiment(str, Enum):
positive = 'positive'
negative = 'negative'
neutral = 'neutral'
class ReviewAnalysis(BaseModel):
sentiment: Sentiment
confidence: float = Field(ge=0.0, le=1.0, description='Confidence score 0-1')
key_themes: List[str] = Field(description='Main topics mentioned in the review')
summary: str = Field(max_length=200, description='One-sentence summary')
product_name: Optional[str] = Field(default=None, description='Product mentioned, if any')
would_recommend: Optional[bool] = None
# Pydantic validates types and constraints at instantiation
example = ReviewAnalysis(
sentiment=Sentiment.positive,
confidence=0.95,
key_themes=['fast delivery', 'good quality'],
summary='Customer loves the product and quick shipping.',
product_name='Wireless Headphones',
would_recommend=True
)
print(example.model_dump_json(indent=2))استخدام Pydantic مع المخرجات المهيكلة من OpenAI
مرّر فئة نموذج Pydantic مباشرةً إلى المَعلمة response_format في client.beta.chat.completions.parse(). وتحول SDK النموذج تلقائيًا إلى مخطط JSON، وترسله إلى API، ثم تفك تسلسل الاستجابة مجددًا إلى كائن Python ذي أنواع محددة.
import openai
from pydantic import BaseModel
from typing import List, Optional
from enum import Enum
client = openai.OpenAI()
class Sentiment(str, Enum):
positive = 'positive'
negative = 'negative'
neutral = 'neutral'
class ReviewAnalysis(BaseModel):
sentiment: Sentiment
confidence: float
key_themes: List[str]
summary: str
would_recommend: Optional[bool]
review_text = '''
I bought this laptop for my design work and I am blown away. It handles Photoshop
like a dream, the screen colors are beautiful, and it has not slowed down once in
three months. Battery life could be better but overall highly recommend!
'''
result = client.beta.chat.completions.parse(
model='gpt-4o-mini',
messages=[
{'role': 'system', 'content': 'Analyze the customer review and extract structured information.'},
{'role': 'user', 'content': review_text}
],
response_format=ReviewAnalysis
)
analysis = result.choices[0].message.parsed
print(f'Sentiment: {analysis.sentiment.value}')
print(f'Confidence: {analysis.confidence}')
print(f'Themes: {analysis.key_themes}')
print(f'Recommend: {analysis.would_recommend}')نماذج Pydantic المتداخلة
يمكن لمخططات Pydantic الإشارة إلى نماذج Pydantic أخرى، ما يتيح مخرجات مهيكلة متداخلة كيفما كان عمقها. وهذا مثالي لاستخراج البيانات الهرمية من مستندات مثل العقود والفواتير والسير الذاتية والسجلات الطبية.
from pydantic import BaseModel
from typing import List, Optional
class Address(BaseModel):
street: Optional[str]
city: str
country: str
postal_code: Optional[str]
class ContactInfo(BaseModel):
email: Optional[str]
phone: Optional[str]
address: Optional[Address]
class Person(BaseModel):
full_name: str
age: Optional[int]
job_title: Optional[str]
contact: ContactInfo
skills: List[str]
# When you pass Person to response_format, the API generates:
# {
# "full_name": "...",
# "contact": {
# "email": "...",
# "address": { "city": "...", "country": "..." }
# },
# "skills": ["...", "..."]
# }
print('Nested model defined - pass to response_format for extraction')التحقق من الحقول باستخدام أدوات التحقق في Pydantic
تتيح لك أدوات التحقق في Pydantic إضافة منطق تحقق مخصص يتجاوز مجرد التحقق من النوع. يمكنك التحقق من أن درجة الثقة تتراوح بين 0 و1، وأن السعر غير سالب، أو أن سلسلة التاريخ بالتنسيق الصحيح. وعندما يُرجع النموذج اللغوي الكبير قيمة تفشل في التحقق، يرفع Pydantic خطأ ValidationError يمكنك التقاطه ومعالجته.
from pydantic import BaseModel, Field, field_validator
from typing import Optional
import re
class ExtractedContact(BaseModel):
name: str
email: Optional[str] = None
phone: Optional[str] = None
confidence: float = Field(ge=0.0, le=1.0)
@field_validator('email')
@classmethod
def validate_email(cls, v):
if v is not None:
# Basic email format check
if not re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', v):
raise ValueError(f'Invalid email format: {v}')
return v
@field_validator('phone')
@classmethod
def normalize_phone(cls, v):
if v is not None:
# Remove non-digit characters for normalization
digits = re.sub(r'[^0-9+]', '', v)
return digits
return v
try:
contact = ExtractedContact(name='Alice', email='not-an-email', confidence=0.9)
except Exception as e:
print(f'Validation error: {e}')استخراج قوائم من الكائنات
من الأنماط الشائعة استخراج مثيلات متعددة للكيان نفسه من مستند — مثل جميع بنود الفاتورة، أو جميع عناصر الإجراءات من محضر اجتماع، أو جميع الكيانات من مقال إخباري. وللتعامل مع هذه الحالة بسلاسة، غلّف نموذجك في نموذج حاوية يحتوي على حقل قائمة.
import openai
from pydantic import BaseModel
from typing import List
client = openai.OpenAI()
class ActionItem(BaseModel):
task: str
assignee: str
due_date: str # or use datetime with proper parsing
priority: str # high / medium / low
class MeetingNotes(BaseModel):
meeting_title: str
action_items: List[ActionItem]
key_decisions: List[str]
meeting_transcript = '''
Q3 Planning Meeting - June 2025
Decision: Launch new feature in July.
Decision: Extend free trial to 30 days.
Action: Alice to finalize designs by June 30th - High priority.
Action: Bob to write API docs by July 5th - Medium priority.
Action: Carol to set up staging environment by June 28th - High priority.
'''
result = client.beta.chat.completions.parse(
model='gpt-4o-mini',
messages=[
{'role': 'system', 'content': 'Extract structured data from meeting notes.'},
{'role': 'user', 'content': meeting_transcript}
],
response_format=MeetingNotes
)
notes = result.choices[0].message.parsed
for item in notes.action_items:
print(f'[{item.priority.upper()}] {item.task} -> {item.assignee} by {item.due_date}')الحقول الاختيارية والقيم الافتراضية
المستندات الواقعية غير مكتملة. فقد لا تذكر السيرة الذاتية رقم الهاتف، وقد لا تحتوي الفاتورة على رقم فاتورة، وقد لا تذكر مراجعة المنتج اسم المنتج. صمّم نماذج Pydantic بحيث تتعامل بسلاسة مع البيانات المفقودة، باستخدام حقول Optional مع قيم افتراضية مناسبة.
يُخبر الحقل المعلَّم بالتعليق التوضيحي Optional[str] = None كلًا من Pydantic والنموذج اللغوي الكبير بأن هذا الحقل قد يكون غائبًا. وسيُرجع النموذج null في JSON للحقول التي يتعذر عليه استخراجها، ثم سيفك Pydantic تسلسلها إلى None في Python، ما يتيح لك التعامل معها بسهولة لاحقًا من دون استثناءات KeyError.
تحويل نماذج Pydantic إلى مخطط JSON
يُحوَّل نموذج Pydantic الذي تعرّفه تلقائيًا إلى مخطط JSON عند تمريره إلى API. ويمكنك فحص هذا المخطط لفهم ما سيفرضه API تحديدًا، وهو أمر مفيد لتصحيح الحالات التي لا يُرجع فيها النموذج البنية التي تتوقعها.
from pydantic import BaseModel, Field
from typing import List, Optional
import json
class ProductExtraction(BaseModel):
name: str = Field(description='Product name as mentioned in the text')
price_usd: Optional[float] = Field(default=None, description='Price in USD')
features: List[str] = Field(default_factory=list)
in_stock: bool = Field(description='Whether the product is currently available')
# See the JSON Schema that will be sent to the API
schema = ProductExtraction.model_json_schema()
print(json.dumps(schema, indent=2))
# This shows exactly what constraints the API will enforceالتعامل مع إخفاقات الاستخراج
حتى مع المخرجات المهيكلة، قد يفشل الاستخراج بطريقتين: قد يرفض النموذج الاستجابة (فيُرجع حالة رفض)، أو قد لا يحتوي المستند فعلًا على المعلومات المطلوبة، فيُرجع النموذج قيمًا فارغة للحقول المطلوبة — ما يؤدي إلى خطأ في التحقق من Pydantic، لأن الحقول المطلوبة لا يمكن أن تكون فارغة.
يتمثل النهج الأكثر أمانًا في جعل جميع الحقول اختيارية مع قيم افتراضية، وقبول القيم الفارغة للبيانات المفقودة، ثم تطبيق التحقق الخاص بمنطق العمل بعد الاستخراج. وبهذا تفصل بين مهمة الاستخراج (الحصول على البيانات من النص) ومهمة التحقق (التأكد من استيفاء البيانات لمتطلباتك).
import openai
from pydantic import BaseModel, ValidationError
from typing import Optional
client = openai.OpenAI()
class ContactExtraction(BaseModel):
name: Optional[str] = None
email: Optional[str] = None
phone: Optional[str] = None
try:
result = client.beta.chat.completions.parse(
model='gpt-4o-mini',
messages=[
{'role': 'system', 'content': 'Extract contact information.'},
{'role': 'user', 'content': 'I would like to discuss partnership opportunities.'}
],
response_format=ContactExtraction
)
msg = result.choices[0].message
if msg.refusal:
print('Refused:', msg.refusal)
else:
contact = msg.parsed
if not any([contact.name, contact.email, contact.phone]):
print('No contact information found in text')
else:
print(contact.model_dump())
except ValidationError as e:
print('Validation failed:', e)استخدام Pydantic مع مكتبة instructor
إن مكتبة instructor حزمة شائعة من جهات خارجية تعمل على تعديل عميل OpenAI لدعم الاستخراج القائم على Pydantic مع إعادة المحاولة تلقائيًا عند فشل التحقق. فإذا أرجع النموذج مخرجات تفشل في اجتياز تحقق Pydantic، تعيد instructor المحاولة تلقائيًا باستخدام مطالبة تتضمن خطأ التحقق، ما يمنح النموذج فرصة لتصحيح نفسه.
ويفيد ذلك بوجه خاص في مسارات الاستخراج الدفعية التي يتعذر فيها مراجعة كل نتيجة يدويًا، والتي تريد فيها أن يصحح النظام نفسه من دون تدخل بشري.
# pip install instructor
import instructor
import openai
from pydantic import BaseModel, Field
from typing import Optional
# Patch the OpenAI client with instructor
client = instructor.from_openai(openai.OpenAI())
class ProductInfo(BaseModel):
name: str
price_usd: float = Field(gt=0, description='Price must be positive')
brand: Optional[str] = None
# instructor automatically retries if Pydantic validation fails
product = client.chat.completions.create(
model='gpt-4o-mini',
messages=[
{'role': 'user', 'content': 'The Sony WH-1000XM5 headphones cost $279.99 at Best Buy.'}
],
response_model=ProductInfo, # instructor-specific parameter
max_retries=3
)
print(f'{product.name}: ${product.price_usd} by {product.brand}')الاتحادات المميَّزة والمخططات الديناميكية
يدعم Pydantic الاتحادات المميَّزة — وهو مخطط تعتمد بنيته على قيمة حقل مميِّز. ويفيد ذلك عندما تشترك أنواع مختلفة من المستندات في أساس مشترك، لكنها تحتوي على حقول إضافية مختلفة. فمثلًا، قد يحتوي تقرير المصروفات على إيصال رحلة جوية (يتضمن المغادرة والوصول) أو إيصال فندق (يتضمن تاريخي تسجيل الوصول والمغادرة).
وباستخدام أنواع Union مع حقل مميِّز من النوع Literal، يمكنك تعريف مخطط استخراج واحد يتعامل مع متغيرات متعددة من المستندات، مع اختيار النموذج للنمط الفرعي الصحيح استنادًا إلى محتوى المستند. ويتحقق Pydantic تلقائيًا من النمط الفرعي الصحيح بناءً على قيمة الحقل المميِّز.
from pydantic import BaseModel
from typing import Union, Literal, Optional
class FlightExpense(BaseModel):
expense_type: Literal['flight']
airline: str
departure_city: str
arrival_city: str
amount_usd: float
class HotelExpense(BaseModel):
expense_type: Literal['hotel']
hotel_name: str
check_in: str
check_out: str
amount_usd: float
class MealExpense(BaseModel):
expense_type: Literal['meal']
restaurant: Optional[str]
amount_usd: float
class ExpenseReport(BaseModel):
submitter: str
expenses: list[Union[FlightExpense, HotelExpense, MealExpense]]
total_usd: float
print('Discriminated union schema - model selects correct subtype per item')اختبار سريع
اختبر مدى استيعابك لمفاهيم هندسة الذكاء الاصطناعي التي تناولها هذا الدرس.
مراجعة الدرس
تعلّمت في هذا الدرس أن الفئات الفرعية من Pydantic BaseModel تعرّف مخططات استخراج ذات أنواع قوية تفرضها المخرجات المهيكلة من OpenAI على مستوى API، وأن النماذج المتداخلة والحقول الاختيارية وأنواع List تتعامل مع البنى المعقدة للمستندات الواقعية، وأن مكتبة instructor تضيف إعادة المحاولة تلقائيًا عند فشل التحقق لمسارات الاستخراج الدفعية المتينة. بعد ذلك، سنبني مسارًا متكاملًا لاستخراج المعلومات من مصادر النصوص غير المهيكلة.
تعلم Python مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 30
- الدروس
- 120
الأسئلة الشائعة
هل درس «المخرجات المنظّمة باستخدام Pydantic» مجاني؟
نعم — نص درس «المخرجات المنظّمة باستخدام Pydantic» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Engineering Academy، انتقل إلى CoddyKit PRO. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
ماذا ستتعلم في «المخرجات المنظّمة باستخدام Pydantic»؟
عرّفوا نماذج Pydantic كمخطط للمخرجات، ومرّروها إلى API عبر ميزة المخرجات المنظّمة الجديدة، وأزيلوا تسلسل الاستجابات تلقائيًا إلى كائنات Python ذات أنواع محددة. تتمرن على AI Engineering Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Engineering Academy؟
لا تُشترط خبرة سابقة. AI Engineering Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «المخرجات المنظّمة باستخدام Pydantic»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Engineering Academy هذا؟
نعم. كل درس في AI Engineering Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- وضع JSON وresponse_format
- المخرجات المنظّمة باستخدام Pydantic
- استخراج البيانات من النصوص غير المنظّمة
- التحقق من المخرجات الخاطئة وإعادة المحاولة