DEV Community

Cover image for كيفية إضافة إفصاح الذكاء الاصطناعي إلى واجهة برمجة التطبيقات الخاصة بك؟
Yusuf Khalidd
Yusuf Khalidd

Posted on Originally published at apidog.com

كيفية إضافة إفصاح الذكاء الاصطناعي إلى واجهة برمجة التطبيقات الخاصة بك؟

تحتوي واجهة الدردشة لديك على شارة صغيرة تقول: «تم إنشاؤها بواسطة الذكاء الاصطناعي» أسفل كل رد. هذا مفيد للمستخدم داخل الواجهة، لكنه لا يساعد فريقًا شريكًا يستدعي نقطة النهاية /summarize من مهمة دفعية، ثم يخزن المخرجات في قاعدة بيانات ويعرضها في تقرير للعملاء. الإفصاح الذي يعيش في الواجهة فقط يختفي فور مغادرة البيانات لها.

جرّب Apidog اليوم

هذه هي الفجوة في كثير من تطبيقات إفصاح الذكاء الاصطناعي: يُعامل الإفصاح كقرار واجهة مستخدم، لذلك يتوقف عند حدود الواجهة الأمامية. أما المستهلكون الآليون فلا يحصلون على أي إشارة، رغم أنهم الأكثر حاجة إليها لأنهم لا يستطيعون استنتاج أن الاستجابة جاءت من نموذج.

منذ 2 أغسطس 2026، جعلت المادة 50 من قانون الاتحاد الأوروبي للذكاء الاصطناعي هذا الأمر عمليًا لفرق كثيرة. يضع مزودو النماذج مثل Anthropic علامات على مخرجاتهم على مستوى النموذج، لكن مسؤولية إخبار الأشخاص بأنهم يتعاملون مع الذكاء الاصطناعي تقع على عاتق ناشر النظام. إذا كانت API الخاصة بك تقع بين النموذج والمستهلك النهائي، فهي تحدد ما إذا كان المتصلون بك قادرين على الامتثال أم لا.

الحل هو نقل الإفصاح إلى عقد API: حدّد ما يجب أن تُرجعه API، وأين يوضع، وكيف توثقه، وكيف تختبره كي لا يختفي مع إعادة الهيكلة التالية. يغطي Apidog التصميم والتوثيق والاختبار في مكان واحد.

ما الذي يجب أن يتضمنه الرد؟

أضف ثلاث فئات من المعلومات إلى كل استجابة قد تحتوي على مخرجات نموذج:

  1. هل تم إنشاء المحتوى بالذكاء الاصطناعي؟
  2. بأي مزود وأي نموذج؟
  3. ما حالة المصدر أو الإثباتات التي تحققت منها؟

بدلًا من قيمة منطقية بسيطة مثل:

{
  "ai_generated": true
}
Enter fullscreen mode Exit fullscreen mode

استخدم تعدادًا يصف درجة مشاركة النموذج:

{
  "generation": "synthetic"
}
Enter fullscreen mode Exit fullscreen mode

القيم المقترحة:

  • synthetic: أنشأ النموذج المحتوى دون تأليف بشري.
  • assisted: ألّف إنسان المحتوى أو ساهم فيه، ثم عدّله النموذج أو ترجمه أو لخّصه.
  • human: لا توجد مشاركة لنموذج في المحتوى.

هذا التفريق مهم: تعديل Claude لمسودة بشرية ليس مماثلًا لكتابة Claude للمحتوى بالكامل، كما أن استثناءات المادة 50 تتعامل مع هذه الحالات بشكل مختلف.

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

وأبقِ حالة المصدر منفصلة عن حالة التوليد. عبارة «أنشأنا هذا المحتوى» حقيقة تتحكم بها منصتك، بينما «تحققنا من بيان C2PA» نتيجة عملية تحقق منفصلة.

استخدم شكل استجابة ثابتًا مثل التالي:

{
  "id": "sum_4f81a2",
  "content": "The incident affected two regions for 41 minutes...",
  "ai": {
    "generation": "synthetic",
    "vendor": "anthropic",
    "model": "claude-opus-5",
    "human_review": false,
    "generated_at": "2026-08-11T09:14:22Z"
  },
  "provenance": {
    "status": "unchecked",
    "standard": null
  }
}
Enter fullscreen mode Exit fullscreen mode

هناك تفصيلان مهمان في هذا العقد:

  • أضف human_review لأن المادة 50(4) تعتمد على وجود مراجعة بشرية أو رقابة تحريرية مع مسؤولية تحريرية محددة. إذا كان نظامك يسجل أن شخصًا وافق على المسودة، فأعد هذه الحقيقة في الاستجابة كي يستطيع المتصل اتخاذ قرار الإفصاح المناسب.
  • لا تختزل provenance.status إلى قيمة منطقية. حالات مثل verified وabsent وinvalid وunchecked تحمل معاني مختلفة. تعطل خدمة التحقق ليس مماثلًا لعدم وجود مصدر أو لفشل التحقق.

الرؤوس أم المحتوى؟

استخدم كليهما، لكن لأغراض مختلفة.

المحتوى هو مصدر الحقيقة الدائم.

يُخزن JSON ويُسجل ويُعاد تشغيله ويُمرر إلى مراحل لاحقة. إذا احتفظ المتصل بجسم الاستجابة فقط، فيجب أن يجد الإفصاح فيه.

الرؤوس مفيدة للطبقات المحيطة.

يمكن لوكيل أو بوابة أو طبقة تسجيل لا تحلل JSON أن تقرأ رأسًا وتوجه الطلب أو تسجله. كما أن الرؤوس هي الخيار العملي للاستجابات غير JSON، مثل النص العادي أو البيانات الثنائية.

HTTP/1.1 200 OK
Content-Type: application/json
X-AI-Generated: synthetic
X-AI-Model: anthropic/claude-opus-5
Enter fullscreen mode Exit fullscreen mode

اتبع قاعدتين:

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

في الاستجابات المتدفقة، أرسل الإفصاح في رؤوس الاستجابة أو في الحدث الأول. لا ينبغي للمتصل الذي يبدأ بعرض أول رمز مميز أن ينتظر نهاية البث ليعرف طبيعة المحتوى.

إذا كنت بحاجة إلى مراجعة أساسيات تصميم الرؤوس، اقرأ: ما هي رؤوس HTTP.

ضعه في مواصفات OpenAPI

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

components:
  schemas:
    AiDisclosure:
      type: object
      required: [generation]
      properties:
        generation:
          type: string
          enum: [synthetic, assisted, human]
          description: >
            synthetic = produced by a model with no human authoring.
            assisted = a human authored the content and a model edited,
            translated, or summarised it.
            human = no model involvement.
        vendor:
          type: string
          example: anthropic
        model:
          type: string
          example: claude-opus-5
        human_review:
          type: boolean
          description: >
            True when a person reviewed the output before it was returned
            and an identifiable party holds editorial responsibility.
        generated_at:
          type: string
          format: date-time
Enter fullscreen mode Exit fullscreen mode

ثم أشر إلى هذا المخطط من مخطط الاستجابة:

components:
  schemas:
    SummarizeResponse:
      type: object
      required: [id, content, ai, provenance]
      properties:
        id:
          type: string
        content:
          type: string
        ai:
          $ref: '#/components/schemas/AiDisclosure'
        provenance:
          type: object
          required: [status]
          properties:
            status:
              type: string
              enum: [verified, absent, invalid, unchecked]
            standard:
              type: [string, "null"]
Enter fullscreen mode Exit fullscreen mode

اجعل ai خاصية مطلوبة في كل استجابة يمكن أن تتضمن مخرجات نموذج. الحقل الاختياري يجبر المتصلين على كتابة منطق دفاعي، وكثير منهم لن يفعل ذلك.

هذا يوفر فائدتين مباشرتين:

  • تعرض الوثائق المُنشأة معنى الحقل لكل مستهلك.
  • يكشف التحقق من المواصفات أي تغيير يحذف الحقل أو يجعله اختياريًا.

راجع كيفية التحقق من مواصفات OpenAPI لإعداد التحقق، واستخدم OpenAPI diff لمنع التغييرات الجذرية في CI لاكتشاف التغييرات التي تضعف العقد بصمت.

المسارات التي ينساها الناس

غالبًا لا يختفي الإفصاح في المسار السعيد، بل في المسارات الثانوية. راجع هذه الحالات صراحةً:

1. الاستجابات المخزنة مؤقتًا

إذا خزنت المحتوى قبل إرفاق الإفصاح، فقد تعيد طبقة التخزين المؤقت مخرجات بلا تسمية طوال مدة TTL.

التنفيذ الصحيح: خزّن الاستجابة الكاملة، أو أنشئ كائن الإفصاح قبل كتابة أي استجابة إلى التخزين المؤقت.

2. الاستجابات الجزئية والأخطاء

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

3. الدُفعات وخطافات الويب

غالبًا ما تستخدم عمليات التسليم غير المتزامنة مخططًا أبسط ينشئه مسار برمجي مختلف. هذه من أكثر الأماكن التي يختفي فيها الحقل.

4. مسارات التراجع

عند فشل النموذج الأساسي والانتقال إلى نموذج احتياطي، يجب أن تعكس قيمة model النموذج الذي استُدعي فعليًا. لا تستخدم سلسلة ثابتة داخل كتلة الإفصاح.

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

اختبره كضمان

حقل الإفصاح وعد لمستهلكي API. والوعد غير المختبر هو مجرد توثيق.

ابدأ بهذه التأكيدات الخمسة:

1. الحقل موجود في كل مسار مدعوم بالذكاء الاصطناعي

const body = pm.response.json();

pm.test("response carries AI disclosure", function () {
  pm.expect(body).to.have.property("ai");
  pm.expect(body.ai.generation).to.be.oneOf([
    "synthetic",
    "assisted",
    "human"
  ]);
});
Enter fullscreen mode Exit fullscreen mode

2. الرأس يطابق المحتوى

const body = pm.response.json();

pm.test("header and body agree", function () {
  pm.expect(pm.response.headers.get("X-AI-Generated"))
    .to.eql(body.ai.generation);
});
Enter fullscreen mode Exit fullscreen mode

3. النموذج المبلغ عنه يطابق النموذج المستدعى

هذا الاختبار يكشف التراجعات الصامتة. يعتمد ما إذا كانت المخرجات موسومة بعلامة مائية في المرحلة الأولية على معرف النموذج، ولهذا تصبح معرفة النموذج المستخدم تفصيل امتثال لا مجرد تفصيل أداء. راجع العلامة المائية لـ API من Claude.

4. المسار المخزن مؤقتًا ما زال يفصح

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

5. مسار الخطأ ما زال يفصح

افرض مهلة زمنية أو فشلًا في خدمة تابعة، ثم تحقق من أن غلاف الخطأ أو الاستجابة الجزئية ما زال يحمل ai.

اجمع الاختبارات في سيناريو واحد، وأضف تحقق المخطط مقابل تعريف OpenAPI، ثم شغّله باستخدام apidog-cli في CI:

apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
  -t "$DISCLOSURE_SCENARIO_ID" \
  -e "$APIDOG_ENV_ID" \
  -r cli,html
Enter fullscreen mode Exit fullscreen mode

عندما يفشل تأكيد، تُرجع الأداة رمز خروج غير صفري. بهذا يفشل البناء عند حذف الحقل بدلًا من شحن التغيير إلى الإنتاج.

راجع أتمتة اختبارات API في GitHub Actions لإعداد البايبلاين، وتأكيدات API لأنماط التأكيد العامة. يمكنك أيضًا تنزيل Apidog لبناء السيناريو مقابل نقاط النهاية الخاصة بك.

وثّقه حيث يبحث المتصلون

اكتب التوثيق في مكانين.

في مرجع API

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

في صفحة سياسة قصيرة

أنشئ صفحة واحدة تتضمن:

  • نقاط النهاية التي قد تعيد مخرجات نموذج.
  • النماذج التي تستخدمها.
  • متى تحدث المراجعة البشرية وما معناها.
  • ما الذي تضمنه المنصة وما الذي لا تضمنه.
  • إصدار السياسة وتاريخ تحديثها.

اربط الصفحة من مرجع API.

كن واضحًا بشأن القيود. إذا مررت مخرجات Claude، فقد يحمل النص علامة مائية مدمجة لا يمكنك التحقق منها بنفسك ولم تفتح Anthropic آلية الكشف عنها. اذكر هذا بدل الإيحاء بامتلاك قدرة تحقق غير متاحة لديك. راجع كيفية اكتشاف العلامة المائية لـ Claude.

تساعد الوثائق التفاعلية بشكل خاص هنا، لأن المتصل يرى حقل الإفصاح ضمن استجابة حية بدل الاعتماد على جدول ثابت. راجع استضافة وثائق API تفاعلية مع وحدة تحكم تجريبية.

الأسئلة الشائعة

هل رأس X-AI-Generated معيار قياسي؟

لا. لا يوجد رأس HTTP قياسي معتمد للإفصاح عن الذكاء الاصطناعي. اختر اسمًا، وثّقه، واستخدمه باستمرار، واعتبره جزءًا من عقد API.

هل يجب أن يكون الإفصاح في الرأس أم في المحتوى؟

كلاهما. المحتوى هو ما يُخزن ويُمرر، بينما تخدم الرؤوس الوكلاء والبوابات والسجلات والاستجابات غير JSON. وثّق مصدر الحقيقة الأساسي إذا اختلفا.

هل يجب أن أفعل ذلك قانونيًا؟

يعتمد ذلك على دورك والمحتوى. تختلف التزامات المادة 50 بين مزودي الخدمات والناشرين، وتتناول المادة 50(4) الصور والفيديوهات المزيفة والنصوص المتعلقة بالمصلحة العامة مع استثناء للرقابة التحريرية البشرية. راجع المادة 50 من قانون الذكاء الاصطناعي للاتحاد الأوروبي لمطوري API. القرار القانوني يعود لمستشارك، أما التنفيذ التقني فهو مسؤوليتك.

مزودي يضع علامة مائية على مخرجاته بالفعل، أليس ذلك كافيًا؟

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

ماذا عن الاستجابات المتدفقة؟

ضع الإفصاح في رؤوس الاستجابة أو في الحدث الأول. يبدأ المتصلون العرض فور وصول الرموز المميزة، ولا ينبغي أن ينتظروا نهاية البث.

كيف أتعامل مع محتوى عدّله إنسان بعد الإنشاء؟

استخدم assisted وhuman_review. تتضمن المادة 50(4) استثناءً للمحتوى الذي يخضع لمراجعة بشرية مع مسؤولية تحريرية، لذلك يستحق تسجيل هذه المعلومات بدقة أكثر من قيمة منطقية واحدة.

هل يجب أن أحدد إصدارًا لهذا الحقل؟

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

الخلاصة

يفشل الإفصاح عن الذكاء الاصطناعي عندما يكون ميزة واجهة مستخدم فقط، وينجح عندما يكون عقد API.

نفّذ ذلك كالتالي:

  1. أضف حقل ai مطلوبًا إلى الاستجابة.
  2. اعكس قيمته في رؤوس HTTP.
  3. عرّف المخطط مرة واحدة في OpenAPI.
  4. استخدمه في المسارات الناجحة، والمخزنة مؤقتًا، والجزئية، والخاطئة، والدفعية، والاحتياطية.
  5. اختبر وجوده واتساقه في CI.

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

Top comments (0)