دانيلا (⁦Dayfing⁩)
العودة إلى المقالات
2,002 كلمة9 د

إيقاف Assistants API في 26 أغسطس 2026: دليل الانتقال إلى Responses API

أوقفت OpenAI‏ Assistants API رسمياً في 26 أغسطس 2026، ولم تعد متاحة. يجب على التطبيقات العاملة نقل التوليد وحالة المحادثة والأدوات وتدفقات البيانات إلى Responses API. المسار الآمن هو حصر كل Assistant وThread وRun وأداة، ثم إعادة بناء السلوك في إعداد Responses، واستيراد السجل الذي يحتفظ به تطبيقك، واختبار الردود والآثار الجانبية قبل تحويل حركة المرور. يؤكد دليل OpenAI الرسمي لترحيل Assistants تاريخ الإيقاف وجدول مطابقة الكائنات.

ما الذي يتغير بعد إيقاف 26 أغسطس 2026

هذه هجرة لنقاط النهاية والكائنات، وليست مجرد إعادة تسمية لنموذج. بعد الإيقاف لا يمكن اعتبار استدعاءات موارد Assistants القديمة تحذيراً مؤقتاً. يحتاج الكود الذي ينشئ أو يقرأ /v1/assistants أو /v1/threads أو /v1/threads/messages أو /v1/threads/runs إلى مسار بديل. لا تبدأ تكاملاً جديداً على API القديم، ولا تبنِ مسار تراجع يفترض أن الكائنات القديمة ستظل قابلة للاستعلام.

جدول المطابقة المنشور حالياً من OpenAI هو:

Assistants API منصة Responses المعنى العملي
Assistant Prompt أو إعداد الطلب احتفظ بالنموذج والتعليمات وتعريفات الأدوات وقواعد الإخراج في إعداد قابل للإصدار. يسمح الدليل الحالي بإنشاء Prompt من Assistant في لوحة التحكم، لكنه يحذر أيضاً من إهمال كائنات Prompt القابلة لإعادة الاستخدام.
Thread Conversation أو سجل التطبيق تخزن Conversation عناصر تشمل الرسائل واستدعاءات الأدوات ونتائجها. ويمكنك تخزين الحالة في قاعدة بياناتك وإرسال العناصر المطلوبة.
Run Response يستقبل طلب Responses عناصر إدخال ويعيد عناصر إخراج. لم يعد كائن Run المنفصل وحلقة الاستطلاع التجريد الأساسي.
Run step Item عالج العناصر المكتوبة النوع مثل message وfunction_call وfunction_call_output وreasoning، ولا تفترض أن كل نتيجة رسالة.

اقرأ دليل الترحيل إلى Responses API مع دليل الإيقاف. يصف الدليل Responses API بأنه الخيار الموصى به للمشاريع الجديدة، ويشرح الفروق عن Chat Completions وأشكال الإدخال والإخراج.

النموذج الذهني الجديد

كان Assistant في السابق حزمة إعدادات دائمة على الخادم. كان Thread يحتفظ بالرسائل، وكان Run ينفذ Assistant على ذلك Thread. تفصل Responses هذه المسؤوليات. يحدد الطلب النموذج والتعليمات والمدخلات والأدوات. والنتيجة Response مكتوبة النوع يحتوي output فيها على قائمة مرتبة من العناصر.

يمنح هذا التصميم تطبيقك ملكية واضحة للتنسيق. يقرر كودك كيفية تعريف المستخدم، وكمية السجل التي ترسلها، واستدعاءات الأدوات المسموحة، وطريقة تفويض الوسائط، وآلية إعادة المحاولة، ومتى يحتاج الإجراء إلى موافقة بشرية. ما زالت OpenAI توفر خيارات للحالة، لكنها اختيارات صريحة وليست دورة حياة مخفية لـ Assistant.

توجد ثلاث استراتيجيات مفيدة للحالة:

  1. استخدم طلباً بلا حالة وأرسل قائمة محدودة من عناصر الإدخال في كل دور. هكذا تتحكم قاعدة بياناتك في الاحتفاظ والاختصار.
  2. اربط الأدوار باستخدام previous_response_id. يشرح دليل حالة المحادثة هذا النمط. هو مناسب للتدفقات القصيرة، لكن رموز الإدخال السابقة تظل محسوبة في الفوترة ويجب أن يطابق التخزين سياستك.
  3. أنشئ كائناً من Conversations API وأرسل معرّفه إلى Responses. تملك Conversation معرفاً دائماً ويمكن استخدامها عبر الجلسات والأجهزة والمهام. تبقى عناصرها حتى الحذف، ولذلك فالمعرف إشارة إلى حالة محتفظ بها وليس مفتاح خصوصية.

اختر استراتيجية واحدة لكل تدفق في المنتج. لا تخلط سجلاً أعيد بناؤه محلياً مع Conversation وسلسلة previous_response_id من دون مصدر حقيقة واضح. قد تغير الأدوار المكررة سلوك النموذج، وترفع التكلفة، وتصعّب تنفيذ طلبات الحذف.

افحص الاعتماديات قبل تعديل الكود

أنشئ سجل ترحيل لكل Assistant ID ولكل مسار جلسة في الإنتاج. سجّل النموذج والتعليمات والقيم الافتراضية ومخططات الأدوات وvector stores والملفات واستخدام Code Interpreter وتنسيق الرد والبيانات الوصفية وتوقعات الاحتفاظ وأي كود يستطلع حالة Run. ابحث في الخادم ومهام الخلفية والبرامج الإدارية ولوحات التحكم والاختبارات ومستهلكي التحليلات. لا تثبت استجابة نصية ناجحة أن file search أو الإخراج المنظم أو البث أو الدالة ذات الأثر الجانبي ما زالت تعمل بالطريقة نفسها.

افصل السلوك عن البيانات المخزنة. يمكن إعادة إنشاء التعليمات وتعريفات الأدوات من الإعداد. أما رسائل Threads والملفات المرفوعة فهي أصول بيانات تحتاج إلى تصدير أو نسخة يملكها التطبيق. إذا لم يحتفظ نظامك برسائل المستخدم خارج Threads، فقرر أولاً كيفية معالجة تلك السجلات. يذكر الدليل اللاحق للإيقاف أن جلب رسائل Thread القديمة لم يعد يعمل، ويوصي باستخدام الرسائل التي حفظها التطبيق.

أعد بناء الطلب الأساسي

في التفاعل النصي استبدل تسلسل beta Thread وRun باستدعاء Responses واحد. يقبل الحقل input سلسلة أو قائمة عناصر شبيهة بالرسائل. استخدم instructions للسلوك الثابت على مستوى النظام، واجعل نص المستخدم داخل input. اقرأ النص العادي عبر response.output_text، لكن افحص response.output عندما تكون الأدوات أو العناصر غير النصية ممكنة.

from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-5.6",
    instructions="أجب بوضوح واستشهد بالسجلات المقدمة.",
    input=[{"role": "user", "content": "لخص حالة الطلب."}],
    store=False,
)

print(response.output_text)

نقطة النهاية الجديدة هي /v1/responses، وطريقة SDK هي client.responses.create. لا تنقل المفتاح messages أو المسار choices[0].message.content أو حلقة الاستطلاع من Runs كما هي. إذا أردت حفظ Responses فاجعل ذلك قراراً مقصوداً. توضح وثائق ضوابط البيانات حالياً أن حالة تطبيق Responses تحتفظ بها OpenAI مدة 30 يوماً افتراضياً أو عندما تكون store تساوي true، مع الاستثناءات المدرجة.

اسم النموذج في المثال ليس ضماناً للترحيل. تحقق من النموذج وقدراته في كتالوج النماذج الحالي، وثبّت snapshot عندما تكون قابلية إعادة الإنتاج مهمة، وأجرِ اختباراتك الخاصة للجودة والكمون.

احتفظ بالسجل بطريقة صحيحة

إذا كان تطبيقك يملك النص الكامل، فطبّعه إلى عناصر إدخال Responses. يصبح نص المستخدم input_text، ونص المساعد output_text، وتصبح الصورة input_image مع عنوانها أو مرجع الملف. حافظ على الترتيب الزمني وعلى أزواج استدعاء الأداة ونتيجتها المطلوبة لفهم دور سابق.

ينشئ المثال التالي Conversation دائمة من سجل يملكه التطبيق، ثم يرسل دوراً جديداً:

from openai import OpenAI

client = OpenAI()

conversation = client.conversations.create(
    items=[
        {
            "role": "user",
            "content": [{"type": "input_text", "text": "رقم طلبي 1842."}],
        },
        {
            "role": "assistant",
            "content": [{"type": "output_text", "text": "يمكنني فحص الطلب 1842."}],
        },
    ]
)

response = client.responses.create(
    model="gpt-5.6",
    conversation=conversation.id,
    input=[{"role": "user", "content": "هل أصبح جاهزاً للشحن؟"}],
)

print(response.output_text)

بعد الإيقاف لا تحاول الترحيل باستدعاء threads.messages.list. صدّر البيانات أثناء إتاحة نقطة النهاية القديمة فقط إذا كنت تعمل في بيئة سابقة للإيقاف. في نظام لاحق استخدم السجلات التي احتفظ بها تطبيقك. قبل الاستيراد طابق هوية المستخدم وطلبات الحذف والقواعد الإقليمية والمرفقات والطوابع الزمنية. لا تقبل Conversation ID من عميل غير موثوق من دون التحقق من ملكيته للمستخدم المصادق عليه.

انقل الأدوات واستدعاءات الدوال

تُعرّف أدوات Responses داخل الطلب. توثق صفحة استخدام الأدوات أدوات مثل web search وfile search وcomputer use وCode Interpreter وتوليد الصور وMCP البعيد. ما زالت الدوال المخصصة تحتاج إلى تنفيذ في التطبيق. يستطيع النموذج طلب دالة، لكنه لا يستطيع تفويض عمليتك التجارية أو تنفيذها بنفسه.

أصبحت حلقة التحكم صريحة. أرسل الطلب الأول، وافحص response.output بحثاً عن عناصر function_call، وتحقق من كل دالة مسموحة ونفذها، ثم أضف عناصر إخراج النموذج وعناصر function_call_output وأرسل الطلب التالي. مع نماذج الاستدلال احتفظ بعناصر reasoning التي تعود مع الاستدعاء، وفق دليل استدعاء الدوال.

import json
from openai import OpenAI

client = OpenAI()

tools = [
    {
        "type": "function",
        "name": "lookup_order",
        "description": "إرجاع حالة طلب يملكه المستخدم المصادق عليه.",
        "parameters": {
            "type": "object",
            "properties": {
                "order_id": {"type": "string"},
            },
            "required": ["order_id"],
            "additionalProperties": False,
        },
        "strict": True,
    }
]

input_items = [{"role": "user", "content": "أين طلبي 1842؟"}]

response = client.responses.create(
    model="gpt-5.6",
    tools=tools,
    input=input_items,
)

input_items += response.output
for item in response.output:
    if item.type == "function_call" and item.name == "lookup_order":
        arguments = json.loads(item.arguments)
        result = {"order_id": arguments["order_id"], "status": "packed"}
        input_items.append(
            {
                "type": "function_call_output",
                "call_id": item.call_id,
                "output": json.dumps(result),
            }
        )

response = client.responses.create(
    model="gpt-5.6",
    tools=tools,
    input=input_items,
)

print(response.output_text)

يساعد الوضع الصارم في اتباع المخطط، لكنه لا يمنح الصلاحيات. تحقق في كود التطبيق من المستخدم وملكية الطلب والنطاقات والقيم المحددة وحالة العمل. استخدم idempotency أو معاملة للعمليات التي تحصّل المال أو تحذف أو تنشر أو ترسل. أعد خطأ أداة منظماً عند فشل التنفيذ بدلاً من ادعاء نجاح العملية. ضع حداً أقصى لأدوار الأدوات، وسجّل كل استدعاء ونتيجة وقرار موافقة بعد إخفاء القيم الحساسة.

تختلف تعريفات دوال Responses عن الغلاف القديم لدوال Chat Completions. انقل المخطط عمداً واختبر الوسائط غير الصحيحة والدوال المجهولة والاستدعاءات المكررة والمتوازية والمهلات ونتيجة أداة تحتوي نصاً غير موثوق.

حافظ على الإخراج المنظم

إذا كان Assistant القديم يستخدم JSON mode أو مخطط رد، فانقله إلى إعداد Responses text.format بدلاً من نسخ response_format كما هو. يشرح دليل structured outputs شكل المخطط الحالي ومساعدات SDK. تحقق من النتيجة بعد تحليلها قبل إدخالها إلى قاعدة بيانات أو واجهة أو أداة أخرى. يمكن لوثيقة JSON صحيحة أن تحتوي مع ذلك رقم طلب غير صحيح أو تعليمة خطرة أو قراراً تجارياً ناقصاً.

اجعل المخطط صغيراً ونسخه مع Prompt أو إعداد الطلب. عرّف الحقول المطلوبة، واستخدم additionalProperties=false عندما يفرض الوضع الصارم ذلك، واختبر الرفض والردود غير المكتملة وتطور المخطط. لا تعتبر وجود كائن JSON دليلاً على نجاح العملية.

الأمان والبيانات بعد الترحيل

يغيّر الترحيل حدود الحالة، لذلك راجعه كتغيير في بنية الأمان. أبقِ مفاتيح API على خادم موثوق، وصادق على كل جلسة، واربط Conversation أو السجل المحلي بهوية المستخدم على الخادم. لا تضع أسراراً أو رموز تفويض أو استعلامات غير مقيدة لقاعدة البيانات داخل التعليمات أو أوصاف الأدوات.

استخدم أقل مجموعة أدوات لازمة لكل طلب. افصل دوال القراءة عن الكتابة، واطلب تأكيداً صريحاً للإجراءات المؤثرة، ونفذ التفويض مستقلاً عن إخراج النموذج. اعتبر الملفات المسترجعة وصفحات الويب وردود MCP البعيد مدخلات غير موثوقة. تملك خوادم MCP البعيدة سياسات احتفاظ خاصة بها، وقد تحتوي حاويات Code Interpreter المستضافة حالة مؤقتة أثناء التشغيل. يعرض دليل ضوابط البيانات هذه القيود لكل نقطة نهاية.

قرر لكل تدفق هل يحتاج إلى store أو Conversation أو سجل يملكه التطبيق. تقول الوثائق الحالية إن بيانات API لا تستخدم لتدريب نماذج OpenAI من دون موافقة صريحة، لكن ذلك لا يلغي مراجعة الاحتفاظ والوصول والحذف والمعالجة الإقليمية والموردين. لا يمثل store=false سياسة حذف شاملة ولا يجعل Conversation مؤقتة.

حدّد المدخلات والمخرجات، واستخدم الاعتدال عند الحاجة، ونظّم مراجعة بشرية للقرارات عالية التأثير. توصي أفضل ممارسات الأمان لدى OpenAI باختبار عدائي ضد prompt injection، وبالاعتدال والرقابة البشرية. سجّل معرّفات الطلب وأنواع الأحداث، لكن أخفِ محتوى المستخدم وبيانات الاعتماد ووسائط الدوال ونتائج الأدوات وفق سياستك.

أخطاء الترحيل الشائعة

نقطة النهاية القديمة تعيد خطأ

بعد 26 أغسطس 2026 تمثل الطلبات إلى Assistants عيباً في الترحيل. احذف مسار العميل القديم بدلاً من إعادة المحاولة. إذا كان worker في الخلفية ما زال يستطلع Run ID، فانشر worker لـ Responses واستبدل thread_id وrun_id بمعرّفات الجلسة وResponse.

الرد فارغ أو يفشل المحلل

إخراج Responses قائمة غير متجانسة من العناصر. يناسب output_text النص العادي، لكن استدعاء أداة أو رفض أو رد غير مكتمل يحتاج إلى فحص الحالة وأنواع العناصر. لا تفترض أن العنصر الأول رسالة.

يكرر النموذج السياق أو ترتفع التكلفة

اختر استراتيجية حالة وقاعدة اختصار. لا يجعل previous_response_id رموز الإدخال السابقة مجانية، كما أن نسخ السجل نفسه في Conversation وinput يكرر السياق. قِس رموز الإدخال والإخراج في staging باستخدام محادثات طويلة واقعية.

تُنفّذ الدالة مرتين

قد تعيد إعادة المحاولة والاستدعاءات المتوازية ومهلات الشبكة وإعادة الاتصال استدعاء الدالة. امنح كل عملية ذات أثر جانبي مفتاح idempotency مبنياً على call ID والمستخدم المصادق عليه، وتحقق من المعاملة التجارية قبل التطبيق. لا يثبت رد النموذج الناجح أن الدالة نفذت مرة واحدة.

تختفي الملفات أو نتائج البحث القديمة

احصر vector stores ومعرّفات الملفات ومدة الصلاحية والأذونات بشكل منفصل عن سجل Thread. أعد إنشاء مسار الاسترجاع المدعوم، وتحقق من وصول كل مستأجر، واختبر الاستشهادات والنتائج الفارغة. لا يعني تحويل إعداد Assistant نسخ ملفاته.

قائمة فحص الترحيل

نفّذ الخطوات بالترتيب لكل تدفق إنتاج:

  1. سجّل اعتماديات Assistant وThread وRun والملفات وvector stores والأدوات وPrompt والبيانات الوصفية القديمة.
  2. ضع التعليمات الظاهرة للمستخدم ومخططات الأدوات في إعداد خاضع للإصدار.
  3. اختر نموذج Responses وتحقق من أدواته ومدخلاته متعددة الوسائط وإخراجه المنظم وتوافره الإقليمي.
  4. اختر استراتيجية حالة واحدة: عناصر بلا حالة أو previous_response_id أو Conversations.
  5. طابق messages مع input، وchoices مع output، واستخراج النص مع output_text.
  6. أعد كتابة تعريفات الدوال ونفّذ حلقة أدوات صريحة ومحدودة.
  7. أعد إنشاء file search وCode Interpreter وweb search وMCP وstreaming والإخراج المنظم كل واحدة على حدة.
  8. استورد السجل الذي يملكه التطبيق فقط، مع حفظ الترتيب والهوية والمرفقات والاستدعاءات ودلالات الحذف.
  9. أضف التفويض وحدود الإدخال والاعتدال وidempotency والسجلات المقنّعة وموافقة الإنسان للآثار الجانبية.
  10. شغّل محادثات مرجعية ومدخلات عدائية وأخطاء أدوات وإعادات ومحاولات رفض وسياقات طويلة وجلسات متزامنة.
  11. قارن الردود والاستشهادات وآثار الأدوات والرموز والكمون والأخطاء وسلوك الاحتفاظ.
  12. أطلق التغيير خلف feature flag، وأوقف workers القديمة، وراقب أخطاء Responses، واحتفظ بمسار تراجع لا يعتمد على API المتوقف.
  13. احذف كود Assistant القديم والمفاتيح بعد التحقق من التصدير وسجلات التدقيق وإجراءات الدعم فقط.

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

كيف تعرف أن الترحيل اكتمل

يكتمل الترحيل عندما لا يعتمد أي مسار إنتاج على موارد Assistants، ويملك كل مستخدم مالكاً واضحاً للحالة، ويكون كل استدعاء أداة مفوضاً ومحمياً من التكرار، ويغطي الاختبار عقد إخراج Responses. احتفظ بسجل الترحيل مع snapshots النماذج وإصدارات Prompt أو إعداد الطلب وإصدارات المخطط وقرارات الاحتفاظ وحالات الفشل المرصودة. راجعه عند تغير Responses API أو النموذج المختار، لأن إزالة المسار القديم لا تلغي الحاجة إلى التقييم المستمر.

مقالات أخرى