بعد عامين من استخدام GitHub Copilot وCursor وClaude لكتابة آلاف الأسطر، اكتشفنا أين يفشل الذكاء الاصطناعي في الكود الحقيقي — ولماذا لا يزال يحتاج لمهندس بشري لتصحيح أخطائه الخفية.
في آخر مشروع عملت عليه، طلب مني المدير كتابة موديول كامل لمعالجة البيانات المالية باستخدام Python. قررت التجربة: سأكتب نصف الكود بنفسي والنصف الآخر باستخدام Claude 3.5 Sonnet. النتيجة؟ الكود الذي كتبه الذكاء الاصطناعي كان يعمل — لكن بعد 3 ساعات من التصحيح اليدوي. لماذا؟ لأن Claude أضاف تعليقاً يقول "Handle edge cases later" وترك دالة غير مكتملة تتعامل مع التواريخ في القرن القادم. المشكلة ليست في أن الذكاء الاصطناعي لا يفهم البرمجة، بل في أنه يفهمها بطريقة سطحية جداً، مثل طالب حفظ الكود دون فهم السياق الحقيقي للمشكلة.
الضجيج حول قدرة الذكاء الاصطناعي على كتابة كود كامل دون تدخل بشري وصل إلى ذروته بعد إطلاق GitHub Copilot X وDevin. لكن الحقيقة التي لا يتحدث عنها أحد هي أن الكود الذي ينتجه الذكاء الاصطناعي يمر بمراحل تصحيح وتعديل تفوق في بعض الأحيان الوقت الذي يستغرقه المطور لكتابته من الصفر. في استبيان أجرته Stack Overflow عام 2024، قال 68% من المطورين أنهم يستخدمون أدوات الذكاء الاصطناعي لكتابة الكود، لكن 72% منهم أكدوا أنهم يضطرون لتعديل أكثر من 30% من الكود الناتج قبل اعتماده في الإنتاج. الأرقام لا تكذب: الذكاء الاصطناعي مساعد جيد، لكنه ليس مبرمجاً حقيقياً بعد.
عندما تطلب من نموذج لغة كبير (LLM) كتابة دالة في JavaScript، فهو لا يفكر كما يفكر المبرمج البشري. بدلاً من تحليل المشكلة منطقيا، يقوم النموذج بتوليد الكود بناءً على الأنماط الأكثر شيوعاً في البيانات التي تدرب عليها. مثلاً، إذا طلبت منه كتابة دالة لحساب المتوسط الحسابي، سيولد كوداً مثل هذا:
// Generated by AI - looks correct, but is it?
function calculateAverage(numbers) {
if (!Array.isArray(numbers)) {
throw new Error('Input must be an array');
}
const sum = numbers.reduce((acc, num) => acc + num, 0);
return sum / numbers.length;
}الكود يبدو صحيحاً، لكنه يفشل في حالات مهمة: ماذا لو كانت المصفوفة فارغة؟ ماذا لو احتوت على قيم غير رقمية؟ الذكاء الاصطناعي غالباً ما يغفل هذه التفاصيل لأنه يعتمد على الأنماط الأكثر تكراراً في الكود الذي تدرب عليه، وليس على الفهم العميق للمشكلة. في مشروع حقيقي، هذه الدالة ستسبب خطأ runtime عندما يحاول المستخدم حساب متوسط مصفوفة فارغة، وهو سيناريو شائع في تطبيقات تحليل البيانات.
المشكلة الأكبر هي أن الذكاء الاصطناعي لا يفهم السياق الأوسع للكود. مثلاً، إذا كنت تعمل على نظام إدارة مستشفيات، وطلبت منه كتابة دالة لحجز موعد، قد يولد كوداً يتحقق من توفر الطبيب في الوقت المحدد، لكنه قد يغفل التحقق من أن المريض ليس لديه موعد متداخل في نفس الوقت. هذا النوع من الأخطاء لا يظهر في الاختبارات البسيطة، لكنه يظهر في الإنتاج عندما يتعامل النظام مع آلاف المستخدمين في وقت واحد. في تجربتي مع أحد العملاء، تسبب كود مشابه في حجز مزدوج لنفس الطبيب، مما أدى إلى إلغاء عشرات المواعيد يدوياً.
هناك فئة من الأخطاء البرمجية لا يستطيع الذكاء الاصطناعي اكتشافها لأنها تتطلب فهم السياق التجاري والتقني معاً. مثلاً، في نظام دفع إلكتروني، قد يكتب الذكاء الاصطناعي دالة لتحويل العملات، لكنه قد يستخدم سعر الصرف الثابت بدلاً من السعر اللحظي من API خارجي. هذا الخطأ لن يظهر في الاختبارات المحلية، لكنه سيكلف الشركة آلاف الدولارات إذا تم استخدامه في الإنتاج.
أحد الأمثلة الواقعية التي واجهتها كان في مشروع لتطبيق توصيل طعام. طلبت من Cursor كتابة دالة لحساب وقت التوصيل بناءً على المسافة والازدحام المروري. الكود الناتج كان:
# AI-generated delivery time calculation
import math
def calculate_delivery_time(distance_km, traffic_level):
base_time = distance_km * 5 # 5 minutes per km
traffic_factor = {
'low': 1.0,
'medium': 1.3,
'high': 1.8
}.get(traffic_level, 1.0)
return math.ceil(base_time * traffic_factor)الكود يبدو منطقياً، لكنه يفشل في حالات مهمة: ماذا لو كانت المسافة صفر كيلومتر؟ ماذا لو كانت قيمة traffic_level غير متوقعة مثل 'very_high'؟ بالإضافة إلى ذلك، الكود لا يأخذ في الاعتبار أن وقت التوصيل يجب ألا يقل عن 15 دقيقة حتى لو كانت المسافة قصيرة جداً. هذه التفاصيل الصغيرة هي ما يميز الكود الجيد عن الكود الذي يعمل فقط في السيناريوهات المثالية. في الإنتاج، هذا الكود تسبب في عرض أوقات توصيل غير واقعية، مما أدى إلى شكاوى العملاء وإلغاء الطلبات.
الذكاء الاصطناعي جيد في كتابة الكود البسيط، لكنه غالباً ما يفشل في التعامل مع المشكلات المعقدة مثل إدارة الذاكرة أو تحسين الأداء. مثلاً، في Node.js، قد يكتب الذكاء الاصطناعي دالة تستخدم Promises لكنها لا تعالج الأخطاء بشكل صحيح، مما يؤدي إلى تسرب الذاكرة (Memory Leak) بمرور الوقت. إليك مثال:
// AI-generated code with potential memory leak
const fs = require('fs').promises;
async function readFiles(files) {
const results = [];
for (const file of files) {
const data = await fs.readFile(file, 'utf8');
results.push(data);
}
return results;
}هذا الكود يبدو صحيحاً، لكنه يعاني من مشكلة كبيرة: إذا كانت قائمة الملفات كبيرة جداً، سيتم تحميل كل محتوى الملفات في الذاكرة دفعة واحدة، مما قد يؤدي إلى استهلاك كل الذاكرة المتاحة وتجميد السيرفر. الحل الصحيح هو استخدام Stream أو معالجة الملفات على دفعات صغيرة، لكن الذكاء الاصطناعي غالباً ما يغفل هذه التفاصيل لأنه لا يفهم السياق الأوسع لتطبيقك. في أحد المشاريع، تسبب كود مشابه في توقف السيرفر بعد معالجة 100 ملف فقط، مما اضطرنا لإعادة كتابة الدالة بالكامل باستخدام Streams.
رغم كل هذه المشاكل، لا يمكن إنكار أن الذكاء الاصطناعي أداة قوية في أيدي المطورين المحترفين. لكنه ليس بديلاً عنهم، بل أداة لتسريع العمل وتقليل المهام المتكررة. مثلاً، في كتابة اختبارات الوحدة (Unit Tests)، يمكن للذكاء الاصطناعي توليد اختبارات أساسية بسرعة، مما يوفر وقت المطور للتركيز على كتابة الاختبارات الأكثر تعقيداً. في تجربتي مع فريق تطوير في شركة ناشئة، استخدمنا GitHub Copilot لكتابة اختبارات لـ 200 دالة في يوم واحد، وهو ما كان سيستغرق أسبوعاً كاملاً لو قمنا به يدوياً.
الذكاء الاصطناعي أيضاً مفيد جداً في كتابة الكود المتكرر أو النمطي، مثل التعامل مع قواعد البيانات أو كتابة دوال CRUD الأساسية. مثلاً، في مشروع Django، يمكن للذكاء الاصطناعي توليد موديل كامل مع الـ Serializers والـ Views في دقائق، مما يوفر وقت المطور للتركيز على منطق العمل المعقد. لكن حتى هنا، يجب مراجعة الكود الناتج بعناية، لأن الذكاء الاصطناعي قد يستخدم مكتبات قديمة أو طرق غير آمنة.
طلبت من Claude كتابة API بسيط لإدارة المهام باستخدام FastAPI. الكود الناتج كان:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List
app = FastAPI()
tasks = []
class Task(BaseModel):
id: int
title: str
completed: bool
@app.get("/tasks", respList[Task])
async def get_tasks():
return tasks
@app.post("/tasks", response_model=Task)
async def create_task(task: Task):
tasks.append(task)
return task
@app.get("/tasks/{task_id}", response_model=Task)
async def get_task(task_id: int):
for task in tasks:
if task.id == task_id:
return task
raise HTTPException(status_code=404, detail="Task not found")الكود يعمل، لكنه يحتوي على عدة مشاكل: أولاً، البيانات تختفي عند إعادة تشغيل السيرفر لأننا نستخدم قائمة في الذاكرة بدلاً من قاعدة بيانات. ثانياً، لا يوجد تحقق من تكرار الـ ID عند إنشاء مهمة جديدة. ثالثاً، لا يوجد مصادقة أو صلاحيات. هذه المشاكل ليست واضحة في الكود البسيط، لكنها ستظهر في الإنتاج عندما يحاول المستخدمون الحقيقيون استخدام النظام. الحل هو أن يستخدم المطور الذكاء الاصطناعي كمساعد لكتابة الهيكل الأساسي، ثم يعدله ليتلاءم مع متطلبات المشروع الحقيقية.
الجواب القصير هو: لا، ليس في المستقبل القريب. الذكاء الاصطناعي جيد في كتابة الكود بناءً على الأنماط التي تعلمها، لكنه لا يفهم السياق الحقيقي للمشكلة كما يفهمها المطور البشري. مثلاً، في مشروع لتطبيق طبي، طلبت من الذكاء الاصطناعي كتابة دالة لحساب جرعة الدواء بناءً على وزن المريض. الكود الناتج كان:
def calculate_dose(weight_kg, drug_dose_per_kg):
return weight_kg * drug_dose_per_kgالكود يبدو صحيحاً، لكنه لا يأخذ في الاعتبار أن بعض الأدوية لها حد أقصى للجرعة اليومية، أو أن بعض المرضى لديهم حساسية لمكونات معينة. هذه التفاصيل لا يمكن للذكاء الاصطناعي معرفتها إلا إذا تم تزويده بكل السياق المطلوب، وهو ما يتطلب وقتاً وجهداً أكبر من كتابة الكود من الصفر. في النهاية، قررنا كتابة الدالة يدوياً بعد أن تسبب الكود الذي ولده الذكاء الاصطناعي في خطأ طبي كاد يكلف الشركة دعوى قضائية.
المشكلة الأكبر هي أن الذكاء الاصطناعي لا يفهم العواقب الحقيقية لأخطائه. المطور البشري يعرف أن خطأ بسيط في نظام دفع إلكتروني قد يؤدي إلى خسارة ملايين الدولارات، بينما الذكاء الاصطناعي يكتب الكود دون فهم هذه العواقب. في أحد المشاريع التي عملت عليها، كتب الذكاء الاصطناعي دالة لتحويل العملات استخدمت سعر الصرف الثابت بدلاً من السعر اللحظي من API خارجي. الخطأ لم يظهر في الاختبارات، لكنه تسبب في خسارة 50 ألف دولار للشركة قبل اكتشافه.
الذكاء الاصطناعي أداة قوية، لكن استخدامها بفعالية يتطلب فهم حدودها وكيفية تجاوزها. أولاً، استخدم الذكاء الاصطناعي لكتابة الهيكل الأساسي للكود، ثم راجع وعدل الكود الناتج بعناية. مثلاً، إذا طلبت من الذكاء الاصطناعي كتابة دالة في Python، اطلب منه أيضاً كتابة اختبارات الوحدة لهذه الدالة، ثم راجع الاختبارات للتأكد من أنها تغطي جميع السيناريوهات الممكنة.
ثانياً، لا تعتمد على الذكاء الاصطناعي في كتابة الكود المعقد أو الذي يتطلب فهم السياق التجاري. بدلاً من ذلك، استخدمه لكتابة الكود المتكرر أو النمطي، مثل التعامل مع قواعد البيانات أو كتابة دوال CRUD الأساسية. في تجربتي، أفضل استخدام للذكاء الاصطناعي هو توليد الكود الذي أعرف بالضبط كيف يجب أن يبدو، ثم تعديله قليلاً ليناسب احتياجات المشروع.
في مشروع حديث، طلبت من Cursor كتابة دالة في TypeScript للتحقق من صحة عنوان بريد إلكتروني. الكود الناتج كان:
function validateEmail(email: string): boolean {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(email);
}الكود يعمل، لكنه لا يتحقق من بعض الحالات الهامة مثل العناوين التي تحتوي على مسافات أو الرموز غير المسموح بها. بعد مراجعة، قمت بتعديل الدالة لتصبح:
function validateEmail(email: string): boolean {
if (!email || email.length > 254) return false;
const parts = email.split('@');
if (parts.length !== 2) return false;
const [localPart, domain] = parts;
if (localPart.length > 64 || domain.length > 255) return false;
const re = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
return re.test(email);
}التعديلات تضمنت التحقق من طول البريد الإلكتروني، تقسيمه إلى جزأين والتحقق من طول كل جزء، واستخدام تعبير منتظم أكثر دقة. هذه التفاصيل الصغيرة هي ما يميز الكود الجيد عن الكود الذي يعمل فقط في السيناريوهات المثالية. الذكاء الاصطناعي لم يكن ليفكر في هذه التفاصيل لأنه لا يفهم السياق الأوسع لاستخدام الدالة في تطبيق حقيقي.
بعد عامين من الاستخدام اليومي لأدوات الذكاء الاصطناعي في كتابة الكود، خلاصة تجربتي هي: الذكاء الاصطناعي أداة رائعة لتسريع العمل وتقليل المهام المتكررة، لكنه ليس بديلاً للمطور البشري. يمكنه كتابة الكود بسرعة، لكنه لا يفهم السياق الحقيقي للمشكلة كما يفهمها المطور. الكود الذي ينتجه الذكاء الاصطناعي غالباً ما يحتوي على أخطاء خفية تتطلب مراجعة وتعديلاً يدوياً قبل اعتماده في الإنتاج.
استخدم الذكاء الاصطناعي لكتابة الهيكل الأساسي للكود، ثم راجع وعدل الكود الناتج بعناية. لا تعتمد عليه في كتابة الكود المعقد أو الذي يتطلب فهم السياق التجاري. بدلاً من ذلك، استخدمه لكتابة الكود المتكرر أو النمطي، مثل التعامل مع قواعد البيانات أو كتابة دوال CRUD الأساسية. وفي النهاية، تذكر دائماً: الذكاء الاصطناعي مساعد جيد، لكنه ليس مبرمجاً حقيقياً — بعد.