محادثة متعددة الخطوات

واجهة برمجة تطبيقات CloudZIR عديمة الحالة : لا تحتفظ بأي ذاكرة بين طلبين. لإجراء محادثة، أنتم من يعيد إرسال التاريخ في كل استدعاء.

المبدأ#

يحتوي كل استدعاء على القائمة الكاملة للرسائل المتبادلة حتى الآن. يقرأ النموذج هذه القائمة وينتج الرسالة التالية :

Tour 1  → [system, user₁]                              → assistant₁
Tour 2  → [system, user₁, assistant₁, user₂]           → assistant₂
Tour 3  → [system, user₁, assistant₁, user₂, ...]      → assistant₃

مثال كامل#

from openai import OpenAI

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

messages = [{"role": "system", "content": "Tu es un assistant concis, en français."}]

def demander(texte: str) -> str:
    messages.append({"role": "user", "content": texte})
    reponse = client.chat.completions.create(model="mina-low", messages=messages)
    contenu = reponse.choices[0].message.content
    # ÉTAPE CLÉ : on remet la réponse dans l'historique
    messages.append({"role": "assistant", "content": contenu})
    return contenu

print(demander("Quelle est la capitale de l'Algérie ?"))
print(demander("Et sa population ?"))   # « sa » = celle d'Alger : le contexte est conservé
النسيان الأكثر شيوعًا

عدم إعادة إدراج رد المساعد في messages. يفقد النموذج حينها الخيط ويكرر نفسه : كل جولة تبدو له وكأنها الأولى.

الأدوار#

الدورالاستخدام
systemتعليمات دائمة : النبرة، اللغة، النطاق، القواعد. توضع أولًا.
userما يقوله المستخدم النهائي.
assistantما ردّ به النموذج (يُعاد إرساله كما هو).
toolنتيجة أداة نفّذتموها (استدعاء الأدوات).

يُقبَل developer كمرادف لـsystem.

التحكم في الطول (والتكلفة)#

يُعاد فوترة التاريخ في كل جولة. ثلاث استراتيجيات، من الأبسط إلى الأدق :

1. نافذة متحركة#

MAX_TOURS = 12

def tronquer(messages: list[dict]) -> list[dict]:
    """Garde le message système + les N derniers messages."""
    systeme = [m for m in messages[:1] if m["role"] == "system"]
    reste = messages[len(systeme):]
    return systeme + reste[-MAX_TOURS * 2:]

2. ملخص الجولات القديمة#

def compacter(client, messages: list[dict]) -> list[dict]:
    """Remplace les vieux échanges par un résumé - moins cher que de tout garder."""
    systeme, anciens, recents = messages[:1], messages[1:-8], messages[-8:]
    if len(anciens) < 6:
        return messages
    resume = client.chat.completions.create(
        model="mina-flash",           # le résumé n'a pas besoin du gros modèle
        messages=[
            {"role": "system", "content": "Résume ces échanges en 5 points factuels."},
            {"role": "user", "content": str(anciens)},
        ],
        max_tokens=300,
    ).choices[0].message.content
    return systeme + [{"role": "system", "content": f"Résumé des échanges précédents : {resume}"}] + recents

3. التحقق قبل الإرسال#

إذا تجاوز السياق المُقدَّر نافذة النموذج، تجيب واجهة API بالرمز 400 مع رسالة صريحة. توقعوا ذلك بتقريب «الأحرف ÷ 4» الموصوف في الرمز واستخدامه، واختاروا نموذجًا بنافذة أوسع عند الحاجة (mina-full يصل إلى 256 000 رمز ؛ انظروا النماذج والأسعار).

حفظ محادثة#

خزّنوا قائمة messages في قاعدتكم (سطر لكل رسالة، مع معرّف المحادثة) وأعيدوا تحميلها في الجولة التالية. لا تخزّنوا أبدًا مفتاح API في المتصفح : يجب أن ينطلق الاستدعاء من خادمكم.

الخصوصية

لا تستخدم CloudZIR محتوى إدخالاتكم لتدريب النماذج. في استدعاءات المحادثة المتزامنة، تمرّر مسارات واجهة API الرسائل والصور إلى المحرك دون تسجيلها في قاعدة بيانات الواجهة؛ وتُسجّل بيانات الاستخدام اللازمة للفوترة والدعم. تُخزَّن الملفات المرفوعة عبر API الملفات بشكل منفصل، وتحذفها DELETE /v1/files/{file_id}؛ ولا تُطبّق عليها مدة انتهاء تلقائية. انظروا أيضًا التخزين المؤقت للسياق و الأسئلة الشائعة.

الإعدادات

استجابة API