شعار ConstructiCat
CodeBust.
تصفح القسم ▾

انحراف الاصطلاحات.

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

##العلامات والأعراض

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

  • كتابة دالة مساعدة جديدة بشكل مدمج (inline) على الرغم من وجود أداة مساعدة مجربة ومختبرة بالفعل (مثل utils/date.ts، lib/apiClient، أو نوع Result مشترك).
  • ظهور مكتبة أو واجهة برمجة تطبيقات (API) مختلفة عن المعيار المعتمد في المستودع (مثل استخدام axios في تطبيق تم توحيده على مغلف fetch؛ أو استخدام moment حيث يستخدم المستودع date-fns).
  • انحراف التسمية، وتخطيط الملفات، وأسلوب معالجة الأخطاء — استخدام camelCase في وحدة مبنية بأسلوب snake_case، أو استخدام throw new Error("...") خام حيث يعيد كل شيء آخر خطأً محدد النوع، أو تسجيل أخطاء مخصص بـ try/catch بدلاً من المسجل المشترك.
  • كل متطلب جديد يحصل على كتلته البرمجية الخاصة المصممة خصيصاً له بدلاً من إعادة استخدام نموذج مجرد (ما تسميه Ox Security "الإفراط في التخصيص"، والذي يظهر في 80-90% من أكواد الذكاء الاصطناعي).
  • علامة مميزة: تتضاعف الكتل المكررة. رصدت GitClear قفزة بمقدار 8 أضعاف في كتل النسخ المكررة المكونة من 5 سطور أو أكثر في عام 2024، مع تجاوز السطور المنسوخة/الملصقة للسطور المنقولة (المعاد هيكلتها) لأول مرة.
// الأسلوب المتبع (موجود بالفعل في المستودع)
import { apiClient } from "@/lib/apiClient";   // يغلف المصادقة وإعادة المحاولة ورابط URL الأساسي
import { formatDate } from "@/utils/date";      // على مستوى التطبيق، ويدعم اللغات والمنطقة

// التعديل المولد بالذكاء الاصطناعي — ينحرف عن كليهما
import axios from "axios";                       // ليس نمط التبعية المتبع في المشروع
async function getUser(id: string) {
  try {
    const res = await axios.get(`https://api.example.com/users/${id}`); // رابط URL أساسي مكتوب بشكل مباشر
    return { ...res.data, joined: new Date(res.data.joined).toLocaleDateString() }; // يعيد اختراع formatDate
  } catch (e) {
    console.log("error", e);                     // ليس المسجل المشترك؛ ويقوم ببلع (تجاهل) الخطأ
  }
}

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

##أسباب المشكلة

لماذا تنتجها النماذج؟

  • الارتداد إلى متوسط التدريب. يتم تدريب نماذج اللغات الكبيرة على مجموعة بيانات ضخمة تمثل متوسط كود الإنترنت، وليس مستودعك الخاص. عندما لا يتم توجيهها، فإنها تطلق الأسلوب الأكثر شيوعاً إحصائياً (مثل axios، moment، console.log)، وليس الأسلوب المتبع لديك — إذ تُعتبر اصطلاحاتك مجرد إشارة ضئيلة خارجة عن التوزيع مقارنة بالمتوسط العالمي.
  • الاتساق الذاتي للرمز التالي على حساب نطاق المستودع. من الأسهل محلياً إكمال كتلة قائمة بذاتها (مثل كتابة منسق تاريخ مدمج) بدلاً من "معرفة" وجود @/utils/date واستيراد معرف لم يره النموذج قط. تتطلب إعادة الاستخدام سياقاً للمستودع لا يمتلكه النموذج؛ بينما تتطلب إعادة الاختراع الذاكرة المؤقتة الحالية فقط.
  • سياق مستودع محدود أو مفقود. عادة ما تكون الدالة المساعدة المعتمدة، وإعدادات أداة الفحص (lint)، ووثائق ADR التي تنص على "استخدام مغلف fetch" خارج نص الأمر الموجه (prompt). لا يمكن للنموذج اتباع اصطلاح لم يُعرض عليه قط. كما أن جزءاً كبيراً من الاصطلاحات يكون ضمنياً — أنماط يمتصها البشر من خلال قراءة قاعدة الكود ولا يراها الوكيل أبداً ما لم تُدوَّن.
  • التملق / التركيز الحرفي على المهمة. عندما يُطلب من النموذج "إضافة دالة getUser"، فإنه يفعل ذلك بالضبط ولن يتطوع ليقول "في الواقع لدينا عميل برمجي (client) بالفعل لهذا الغرض". فهو يبحث عن إكمال المهمة المذكورة، وليس ملاءمة النظام. إن "الهوس بالحلول المألوفة" الذي أشارت إليه Ox Security (في 80-90% من العينات) هو نفس القوة: حيث يتبع اصطلاحاً تقليدياً عاماً بدلاً من تقييم اصطلاحات المشروع الخاصة.
  • تاريخ انتهاء التدريب (Training-cutoff staleness). إذا هاجر المستودع إلى مكتبة أو نمط أحدث بعد تاريخ انتهاء تدريب النموذج، فإن النموذج يعيد بثقة تقديم الإصدار الذي تدرب عليه.

لماذا تسبب ضرراً؟

  • قابلية الصيانة والعبء الإدراكي. كل خيار منحرف هو طريقة إضافية للقيام بالشيء نفسه. يجب على القراء الاحتفاظ بنماذج متعددة لـ "كيفية تنسيق التواريخ" في رؤوسهم؛ مما يفقد قاعدة الكود مصدر الحقيقة الوحيد.
  • الصحة عند التعديل. ينحرف المنطق المكرر/المعاد اختراعه بصمت — فالخطأ الذي يتم إصلاحه في المساعد المشترك لا يتم إصلاحه في نسخة الذكاء الاصطناعي. وفقاً لبيانات GitClear لعام 2025، انخفضت الأسطر المرتبطة بإعادة الهيكلة (الأسطر "المنقولة") من 25% من الأسطر المعدلة في 2021 إلى أقل من 10% في 2024، بينما ارتفعت الأسطر المنسوخة/الملصقة من 8.3% إلى 12.3% (GitClear 2025)؛ ويربط ملخص DevClass للتقرير ذلك بأن المساعدين جعلوا إدراج كتلة جديدة أرخص من إعادة استخدام كتلة موجودة (DevClass).
  • الأمان. تجاوز عمليات التحقق أو المصادقة أو بناء الاستعلامات المعاد اختراعها المسار المشترك والمحصن (رابط URL أساسي مكتوب مباشرة، أخطاء متجاهلة، استعلامات SQL نصية عشوائية). تشبّه OX أدوات الذكاء الاصطناعي بـ"جيش من المطورين المبتدئين الموهوبين لكن عديمي الخبرة": سريعة وعملية، لكن دون حكم معماري (OX Security).
  • عبء المراجعة وتراكم الديون التقنية. لا يتم التقاط الانحراف بواسطة الاختبارات (لأن الكود يعمل)، لذلك يستقر في مرحلة المراجعة أو لا يُكتشف على الإطلاق، متراكماً ليتحول إلى تفتت على مستوى البنية حيث يتوزع السلوك المترابط عبر ملفات متعددة دون أي تماسك حقيقي. ويصنف Zhu وTsantalis وRigby رائحة معمارية ذات صلة في الكود الذي تكتبه نماذج اللغة الكبيرة والوكلاء يسمونها "Modular Mirage" (arXiv 2605.02741).

##المعالجة

تكتيكات صياغة الأوامر وسير العمل

  • اعرض الاصطلاحات. ضع القواعد حيث يقرأها الوكيل البرمجي — مثل ملف CLAUDE.md/AGENTS.md/ملف القواعد الذي يسرد العميل البرمجي المعتمد، والمسجل، ونوع الخطأ، والتسمية، مع توجيه "استخدم X وليس Y". ما لا يستطيع النموذج رؤيته، لا يمكنه اتباعه.
  • أشر إلى الكود المرجعي. "استخدم @/lib/apiClient و @/utils/date؛ لا تضف مكتبات HTTP جديدة. طابق معالجة الأخطاء في services/orders.ts". قدم أمثلة قليلة لأسلوب المستودع عن طريق لصق ملف نموذج واحد.
  • اسأل قبل أن يكتب. "ما هي الدوال المساعدة/النماذج المجردة الحالية التي تغطي هذا؟ أعد استخدامها؛ ولا تضف كوداً جديداً إلا إذا لم يكن أي منها مناسباً". هذا يحول إعادة الاختراع إلى إعادة استخدام مسبقة.
  • اجعل أداة الفحص هي الحارس. اطلب من الوكيل البرمجي تشغيل المنسق (formatter)، وأداة الفحص (linter)، وفاحص الأنواع (type-checker) وإصلاح جميع النتائج قبل تقديم الكود. نصيحة Factory هي ميكنة إشارات الجودة (الفحص/التنسيق/فحص الأنواع/الاختبار) بحيث يعمل الوكيل البرمجي على تحسين الكود نحوها بدلاً من الانحراف.
  • راجع من أجل الملاءمة، وليس الوظيفة فقط. افحص التغييرات للبحث عن استيراد مكتبات غير معتمدة؛ وابحث عن المنطق الذي كان ينبغي أن يستدعي الدالة المساعدة المشتركة؛ وشغّل مكتشف النسخ واللصق على طلب السحب (PR).

إعادة الهيكلة — حدد الحركات الكلاسيكية: أزل الكود المكرر باستبدال النسخة المضمنة باستدعاء الدالة المساعدة الموجودة، واستبدال الخوارزمية، واستخراج الدالة إذا لم يكن التجريد المناسب موجوداً بعد.

// قبل — منحرف، يعيد اختراع منطق العميل والتاريخ، رابط URL مكتوب مباشرة، خطأ متجاهل
import axios from "axios";
async function getUser(id: string) {
  try {
    const res = await axios.get(`https://api.example.com/users/${id}`);
    return { ...res.data, joined: new Date(res.data.joined).toLocaleDateString() };
  } catch (e) {
    console.log("error", e);
  }
}

// بعد — يعيد استخدام الاصطلاحات المعتمدة
import { apiClient } from "@/lib/apiClient";
import { formatDate } from "@/utils/date";

async function getUser(id: string) {
  const user = await apiClient.get<User>(`/users/${id}`); // رابط URL الأساسي، المصادقة، إعادة المحاولة، ومعالجة الأخطاء محددة النوع هنا
  return { ...user, joined: formatDate(user.joined) };
}

إذا ظهرت نفس الكتلة المنحرفة في عدة طلبات سحب (PRs)، فهذه إشارة إلى أن الاصطلاح غير قابل للاكتشاف — أصلح السبب الجذري بتوثيقه في ملف القواعد و/أو كشفه من خلال نقطة إدخال واحدة واضحة، بدلاً من إعادة مراجعة كل حالة على حدة.

##أدوات الكشف