AI Engineering Academy · درس

حلقة تنفيذ الشيفرة

صمّموا حلقة الكتابة-التنفيذ-الملاحظة، حيث يولّد الوكيل الشيفرة، وينفذها مشغّل معزول، ثم يلتقط stdout وstderr ويعيدهما كملاحظات، ويصلح الوكيل الأخطاء.

الدرس 1 من 413 خطوة

حلقة تنفيذ الشيفرة درس مجاني في AI Engineering Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Engineering Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.

وكلاء التعليمات البرمجية: كتابة التعليمات البرمجية وتشغيلها

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

حلقة الكتابة والتنفيذ والملاحظة

تتمثل نواة وكيل تنفيذ التعليمات البرمجية في حلقة تتكون من ثلاث خطوات: الكتابة — ينشئ LLM تعليمات برمجية بلغة Python لحل الخطوة الحالية من المهمة. التنفيذ — تُشغّل التعليمات البرمجية في بيئة معزولة، وتُلتقط مخرجات stdout وstderr. الملاحظة — تُعاد مخرجات التنفيذ إلى LLM كملاحظة جديدة، ويستخدمها ليقرر ما سيكتبه بعد ذلك. تستمر هذه الحلقة حتى تكتمل المهمة أو يتم بلوغ حد التكرارات.

def code_execution_loop(task: str, max_iterations=10):
    messages = [
        {'role': 'system', 'content': 'You are a Python coding agent. Write code to solve tasks step by step.'},
        {'role': 'user', 'content': task}
    ]
    
    for i in range(max_iterations):
        # WRITE: LLM generates code
        response = llm.complete(messages)
        code = extract_code_block(response)
        
        if not code:
            return response  # LLM gave a final answer without code
        
        # EXECUTE: run the code
        output, error = execute_safely(code)
        
        # OBSERVE: feed output back
        observation = f'Output:\n{output}' if not error else f'Error:\n{error}'
        messages.append({'role': 'assistant', 'content': response})
        messages.append({'role': 'user', 'content': observation})
    
    return 'Max iterations reached'

استخراج كتل التعليمات البرمجية من مخرجات LLM

عادةً ما يضع LLM التعليمات البرمجية التي ينشئها داخل كتل تعليمات برمجية محاطة بعلامات Markdown: ```python ... ```. يجب أن تتمكن حلقة التنفيذ لديكم من استخراج التعليمات البرمجية من هذه الكتل بشكل موثوق قبل تشغيلها. استخدموا تعبيرًا نمطيًا أو محللًا بسيطًا للعثور على الكتل المحاطة بعلامات، وتعاملوا مع الحالات الخاصة مثل علامات backticks المتداخلة، ووجود عدة كتل تعليمات برمجية في استجابة واحدة، أو وجود تعليمات برمجية من دون محدد لغة.

import re

def extract_code_block(response: str) -> str | None:
    # Match ```python ... ``` or ``` ... ```
    pattern = r'```(?:python)?\n(.*?)```'
    matches = re.findall(pattern, response, re.DOTALL)
    if not matches:
        return None
    # Return the LAST code block (often the most complete version)
    return matches[-1].strip()

# Test
sample_response = '''I will calculate the sum:\n\n```python\nnumbers = [1, 2, 3, 4, 5]\nprint(sum(numbers))\n```'''
code = extract_code_block(sample_response)
print(repr(code))  # 'numbers = [1, 2, 3, 4, 5]\nprint(sum(numbers))'

التقاط stdout وstderr

عند تنفيذ التعليمات البرمجية التي ينشئها الوكيل، يجب التقاط كل من stdout (المخرجات العادية) وstderr (رسائل الخطأ وتتبع الاستدعاءات) لإعادتهما إلى LLM. ويُعد استخدام وحدة subprocess في Python أبسط نهج لذلك: شغّلوا التعليمات البرمجية كعملية منفصلة والتقطوا كلا الدفقين. عيّنوا مهلة زمنية لمنع التعليمات البرمجية العالقة من حظر الوكيل.

import subprocess
import tempfile
import os

def execute_code(code: str, timeout_seconds=30) -> tuple[str, str]:
    # Write code to a temp file
    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
        f.write(code)
        tmp_path = f.name
    
    try:
        result = subprocess.run(
            ['python', tmp_path],
            capture_output=True,
            text=True,
            timeout=timeout_seconds
        )
        stdout = result.stdout[:5000]  # cap output length
        stderr = result.stderr[:2000]  # cap error length
        return stdout, stderr
    except subprocess.TimeoutExpired:
        return '', f'TimeoutError: code exceeded {timeout_seconds}s limit'
    finally:
        os.unlink(tmp_path)  # always clean up temp file

معالجة الأخطاء بذكاء

عندما تنتج التعليمات البرمجية خطأً، تُعاد رسالة الخطأ (تتبع الاستدعاءات، ونوع الاستثناء، ورقم السطر) إلى LLM كملاحظة. ثم يحلل LLM الخطأ ويكتب تعليمات برمجية مصححة. ولمساعدة LLM على تصحيح الأخطاء بفاعلية، أدرجوا نص الخطأ الكامل في الملاحظة، وأدرجوا سطر التعليمات البرمجية الذي تسبب في الخطأ، واطلبوا صراحةً من LLM إصلاحه قبل المحاولة مرة أخرى.

def format_error_observation(code: str, error: str) -> str:
    lines = code.split('\n')
    
    # Extract line number from traceback if available
    line_match = re.search(r'line (\d+)', error)
    error_context = ''
    if line_match:
        line_num = int(line_match.group(1))
        if 1 <= line_num <= len(lines):
            error_context = f'\nFailing line: {lines[line_num - 1].strip()}'
    
    return f'''Execution failed with error:{error_context}\n\n{error}\n\nPlease analyze the error and write corrected code.'''

# Usage in loop
output, err = execute_code(code)
if err:
    observation = format_error_observation(code, err)
else:
    observation = f'Output:\n{output}\n\nContinue with the next step or provide the final answer.'

اكتشاف اكتمال المهمة

يجب أن تعرف حلقة تنفيذ التعليمات البرمجية متى ينبغي التوقف. تشمل إشارات الاكتمال الشائعة: أن يعيد LLM استجابة بلا كتلة تعليمات برمجية (إجابة بلغة طبيعية فقط)، أو أن يكتب LLM علامة خاصة مثل # TASK_COMPLETE، أو أن تنتج التعليمات البرمجية ملف مخرجات طُلب من الوكيل إنشاؤه، أو أن تؤكد دالة تحقق استيفاء المخرجات لمعايير النجاح. طبّقوا دائمًا حدًا للتكرارات كإجراء احتياطي.

COMPLETION_MARKERS = ['TASK COMPLETE', 'FINAL ANSWER:', 'DONE:']

def is_task_complete(response: str, code: str | None, output: str, success_fn=None) -> bool:
    # Check for explicit completion markers
    for marker in COMPLETION_MARKERS:
        if marker in response.upper():
            return True
    
    # No code generated - LLM is done
    if code is None:
        return True
    
    # Custom success function (e.g., check output file exists)
    if success_fn and success_fn(output):
        return True
    
    return False

# Example success function
def report_was_generated(output: str) -> bool:
    import os
    return os.path.exists('analysis_report.pdf')

تمرير البيانات بين التكرارات

يتمثل أحد تحديات حلقات تنفيذ التعليمات البرمجية في استمرارية الحالة بين التكرارات. إذ تُشغّل كل كتلة تعليمات برمجية في عملية Python جديدة، ولذلك لا تكون المتغيرات المعرّفة في تكرار متاحة في التكرار التالي. وتشمل الحلول: كتابة البيانات الوسيطة في ملفات، أو استخدام عملية مستمرة تُحقن فيها التعليمات البرمجية عبر exec()، أو توجيه LLM صراحةً إلى إعادة تعريف المتغيرات اللازمة في بداية كل كتلة تعليمات برمجية.

# Strategy 1: Save to files between iterations
# Iteration 1: LLM writes
'''
import pandas as pd
df = pd.read_csv('data.csv')
df_cleaned = df.dropna()
df_cleaned.to_parquet('cleaned.parquet')  # save for next iteration
print('Cleaned rows:', len(df_cleaned))
'''

# Iteration 2: LLM reads previous output
'''
import pandas as pd
df = pd.read_parquet('cleaned.parquet')  # reload from file
result = df.groupby('category').sum()
result.to_csv('result.csv')
print(result.head())
'''

تنظيم مطالبة النظام

يجب أن تعلّم مطالبة النظام الخاصة بوكيل تنفيذ التعليمات البرمجية LLM كيفية استخدام الحلقة بفاعلية. وتشمل العناصر الأساسية التي ينبغي تضمينها: كيفية كتابة كتل تعليمات برمجية قابلة للتنفيذ بلغة Python، وكيفية التحقق من المخرجات الوسيطة قبل المتابعة، وكيفية الإشارة إلى اكتمال المهمة، والمكتبات المتاحة في البيئة المعزولة، ومسارات الملفات التي يُسمح للوكيل بالقراءة منها والكتابة إليها.

CODE_AGENT_SYSTEM_PROMPT = '''
You are a Python code execution agent. Solve tasks by writing and running code.

Rules:
1. Write ALL code inside ```python ... ``` blocks.
2. Write small, testable code blocks - do not try to do everything in one block.
3. When you see execution output, analyze it and decide whether to continue or fix errors.
4. Available libraries: pandas, numpy, matplotlib, requests, json, os, pathlib.
5. You can read/write files only in /workspace/ directory.
6. When the task is fully complete, say TASK COMPLETE and summarize the result.
7. If you are stuck after 3 attempts at the same error, say ESCALATE and explain the problem.
'''

اقتطاع المخرجات وإدارة الرموز

قد تنتج التعليمات البرمجية التي ينشئها الوكيل مخرجات ضخمة: مثل مطبوعات DataFrame، والقوائم الطويلة، والسجلات المطولة. تؤدي إعادة المخرجات كاملةً إلى LLM إلى هدر الرموز، وقد تتسبب في تجاوز نافذة السياق. احرصوا دائمًا على اقتطاع مخرجات التنفيذ قبل إضافتها إلى المحادثة. ويُعد الافتراضي الجيد اقتطاعها إلى 2000-5000 حرف، مع إضافة ملاحظة تفيد باقتطاع المخرجات حتى يعرف LLM أنه قد يكون هناك المزيد لاستكشافه.

MAX_OUTPUT_CHARS = 3000

def format_observation(stdout: str, stderr: str) -> str:
    if stderr:
        # Errors take priority - show full error
        return f'Error:\n{stderr[:MAX_OUTPUT_CHARS]}'
    
    if len(stdout) > MAX_OUTPUT_CHARS:
        truncated = stdout[:MAX_OUTPUT_CHARS]
        remaining = len(stdout) - MAX_OUTPUT_CHARS
        return f'{truncated}\n... [output truncated, {remaining} more characters]'
    
    return f'Output:\n{stdout}' if stdout else 'Code executed successfully (no output)'

حلقة التعليمات البرمجية عمليًا

قد يشغّل وكيل حقيقي لتنفيذ التعليمات البرمجية مخصص لتحليل البيانات ما بين 5 و15 تكرارًا من أجل: تحميل ملف CSV، واستكشاف بنيته، وتنظيف البيانات، وحساب الإحصاءات، وإنشاء مخطط، وإنتاج تقرير موجز. يبني كل تكرار على التكرار السابق، مع تكييف LLM لنهجه استنادًا إلى قيم البيانات وأشكالها الفعلية التي يكتشفها أثناء التشغيل. وهذا التكيّف الديناميكي هو ما يجعل وكلاء التعليمات البرمجية فعالين للغاية في المهام الاستكشافية.

اعتبارات الأمان في حلقات التعليمات البرمجية

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

تحقق سريع

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

مراجعة الدرس

تعلمتم في هذا الدرس أن حلقة الكتابة والتنفيذ والملاحظة هي النمط الأساسي لوكلاء تنفيذ التعليمات البرمجية، وأن stdout وstderr الناتجين عن التنفيذ يُعادان كملاحظات توجّه إنشاء LLM للتعليمات البرمجية التالية، وأن اقتطاع المخرجات وحدود التكرارات آليتان أساسيتان للأمان. بعد ذلك، سنستكشف عزل تنفيذ التعليمات البرمجية باستخدام Docker وRestrictedPython.

البدء مجانًا

تعلم Python مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
30
الدروس
120

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

هل درس «حلقة تنفيذ الشيفرة» مجاني؟

نعم — نص درس «حلقة تنفيذ الشيفرة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Engineering Academy، انتقل إلى CoddyKit PRO. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.

ماذا ستتعلم في «حلقة تنفيذ الشيفرة»؟

صمّموا حلقة الكتابة-التنفيذ-الملاحظة، حيث يولّد الوكيل الشيفرة، وينفذها مشغّل معزول، ثم يلتقط stdout وstderr ويعيدهما كملاحظات، ويصلح الوكيل الأخطاء. تتمرن على AI Engineering Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ AI Engineering Academy؟

لا تُشترط خبرة سابقة. AI Engineering Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «حلقة تنفيذ الشيفرة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس AI Engineering Academy هذا؟

نعم. كل درس في AI Engineering Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. حلقة تنفيذ الشيفرة
  2. العزل باستخدام Docker وRestrictedPython
  3. إدارة الحالة عبر خطوات التنفيذ
  4. بناء وكيل لتحليل البيانات
← العودة إلى AI Engineering Academy