إخراج JSON

لربط نموذج بشيفرة برمجية، يلزم إخراج قابل للاستغلال آليًا. يفرض وضع JSON على النموذج ألا ينتج سوى كائن JSON صالح.

تفعيل وضع JSON#

أضيفوا response_format واطلبوا صراحةً JSON في الإدخال : كلاهما ضروري :

import json
from openai import OpenAI

client = OpenAI(api_key="zir_ai_...", base_url="https://api.cloudzir.com/v1")

reponse = client.chat.completions.create(
    model="mina-low",
    response_format={"type": "json_object"},
    messages=[
        {
            "role": "system",
            "content": (
                "Tu extrais des informations de commandes. Réponds UNIQUEMENT en JSON, "
                'avec ce format exact : {"client": string, "produits": [{"nom": string, '
                '"quantite": number}], "total_da": number}'
            ),
        },
        {
            "role": "user",
            "content": "Bonjour, ici client-demo. Je voudrais 3 claviers et 2 souris, "
                       "j'ai payé 15 400 DA.",
        },
    ],
)

donnees = json.loads(reponse.choices[0].message.content)
print(donnees["client"], donnees["total_da"])

النتيجة#

{
  "client": "client-demo",
  "produits": [
    {"nom": "clavier", "quantite": 3},
    {"nom": "souris", "quantite": 2}
  ],
  "total_da": 15400
}
الإدخال يبقى ضروريًا

يطلب response_format من المحرك JSON صالحًا نحويًا، وليس المخطط الذي تنتظرونه. صفوا دائمًا البنية الدقيقة في رسالة النظام، مع مثال.

ممارسات جيدة#

  • أظهروا مثالًا كاملًا للإخراج المتوقَع في إدخال النظام : هذا ما يعزز موثوقية الصيغة أكثر من أي شيء آخر.
  • سمّوا الحقول بالإنجليزية أو بدون علامات تشكيل : غموض أقل عند التوليد.
  • خصصوا حقل «غير معروف» بدل ترك النموذج يخترع : {"total_da": null} أفيد من رقم مُهلوَس.
  • امنحوا max_tokens كافيًا : JSON مقطوع هو JSON غير صالح (finish_reason: "length" يُنبّهكم بذلك).
  • تحققوا في الشيفرة؛ لا تثقوا أبدًا بشكل أعمى.

التحقق من البنية#

from pydantic import BaseModel, ValidationError

class Produit(BaseModel):
    nom: str
    quantite: int

class Commande(BaseModel):
    client: str
    produits: list[Produit]
    total_da: float | None = None

try:
    commande = Commande.model_validate_json(reponse.choices[0].message.content)
except ValidationError as exc:
    # Une relance en signalant l'erreur suffit presque toujours
    print("Schéma invalide :", exc)

إعادة محاولة تلقائية عند بنية غير صالحة#

def extraire(client, messages, schema_modele, essais=2):
    for tentative in range(essais + 1):
        r = client.chat.completions.create(
            model="mina-low",
            response_format={"type": "json_object"},
            messages=messages,
        )
        contenu = r.choices[0].message.content
        try:
            return schema_modele.model_validate_json(contenu)
        except Exception as exc:
            if tentative == essais:
                raise
            messages = messages + [
                {"role": "assistant", "content": contenu},
                {"role": "user", "content": f"Ce JSON est invalide : {exc}. Renvoie UNIQUEMENT le JSON corrigé."},
            ]

بديل: استدعاء الأدوات#

حين تكون البنية حرجة فعلًا، يكون استدعاء أداة بـparameters من نوع JSON Schema أكثر إلزامًا من وضع JSON : يجب على النموذج ملء معاملات مُصنَّفة (typed) بدل تحرير كائن بحرية.

القيود الحالية#

  • {"type": "json_schema"} (الإخراج المُهيكَل الصارم من OpenAI) غير مدعوم بعد : يُرفض الطلب بالرمز 400. استخدموا json_object مع التحقق، أو استدعاء أداة.
  • ينطبق وضع JSON على الاستجابة النهائية ؛ في البث المباشر، لا يكتمل JSON إلا في نهاية التدفق.

الإعدادات

استجابة API