Skip to content
إعلاناتمدة القراءة 9 دقيقة

التعليق التوضيحي لوكلاء البرمجة: تقييم تتبعات Claude Code وAider وSWE-Agent

يصيّر Potato تتبعات وكلاء البرمجة في صورة diffs وكتل طرفية، مع مخططات لمكافأة العملية ومراجعة الأكواد، ومحوّلات لـ Claude Code وAider وSWE-Agent.

Potato Team

صار Potato يعلّق على جلسات وكلاء البرمجة مباشرةً. يُصيَّر التتبع في صورة diffs موحّدة، وكتل طرفية داكنة، وقراءات ملفات مرقّمة الأسطر، وشجرة بكل الملفات التي مسّها الوكيل. وتأتي معه ثلاثة محوّلات لصيغ وكلاء البرمجة (claude_code وaider وswe_agent_trajectory) إلى جانب صيغ التتبع الاثنتي عشرة الأخرى التي يقرؤها Potato أصلاً، ومخططا تعليق بُنيا لهذه البيانات: process_reward لصحة كل خطوة، وcode_review لمراجعة الـ diffs على نمط GitHub.

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

أمران ينبغي التحقق منهما قبل التخطيط لدراسة

لا تحتوي نصوص جلسات Claude Code على نص تفكير النموذج. تحتفظ الملفات بكتلة thinking وتوقيعها وتُسقط محتواها، وقد قيس ذلك على 6393 كتلة في 40 جلسة محلية لم يكن في أي منها نص. ويذكر التتبع المحوَّل عدد هذه الكتل، فتظهر الفجوة بدل أن تبقى صامتة. وإذا احتاج المعلّقون إلى الاستدلال للحكم على الخطوات، فالتقطه مباشرةً أثناء التشغيل باستخدام claude -p --output-format stream-json أو Agent SDK بدل قراءته لاحقاً من القرص.

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

عرض التتبع

تُصيَّر تتبعات البرمجة عبر نوع العرض coding_trace، الذي يُعلن عنه في instance_display إلى جانب كل ما ينبغي أن يراه المعلّق. يفصل Potato بين ما يُعرض وما يُسأل عنه، ولذلك يعمل عرض التتبع نفسه مع أي مخطط تعليق:

yaml
instance_display:
  layout:
    direction: vertical
    gap: 16px
  fields:
    - key: task_description
      type: text
      label: "Task"
    - key: structured_turns
      type: coding_trace
      label: "Agent Session"
      display_options:
        show_file_tree: true
        diff_view: unified
        collapse_long_outputs: true
        max_output_lines: 50
        terminal_theme: dark
        show_step_numbers: true
        show_reasoning: true

يُصيَّر كل استدعاء أداة بحسب ما فعلته الأداة، فيقرأ المعلّق الـ diff بوصفه diff لا نصاً مهرَّباً:

الأداةالتصيير
Readكتلة كود بأرقام الأسطر
Edit، Replacediff موحّد بأسطر حمراء وخضراء
Write، Createكتلة كود لملف جديد، خضراء بالكامل
Bash، Terminal، Shellكتلة طرفية داكنة مع محث $
Grep، Glob، Search، Findكتلة كود بنتائج البحث
أي أداة أخرىالمدخلات والمخرجات بتنسيق JSON

عرض تتبع وكيل البرمجة مع تصيير الـ diff وشجرة الملفاتتتبع برمجة مع diffs موحّدة ومخرجات الطرفية وشريط شجرة الملفات الجانبي

الإعداد collapse_long_outputs مع max_output_lines: 50 هو ما يحدد إن كان التتبع مقروءاً. فتشغيلة واحدة لـ pytest قد تطبع مئات الأسطر، والمعلّق الذي يضطر إلى التمرير عبرها في كل خطوة يتوقف عن قراءة الخطوات.

صيغة البيانات

تحافظ صيغة structured_turns على بنية استدعاءات الأدوات التي يحتاج إليها العرض. يحمل كل دور في المحادثة الجهةَ المتحدثة (role)، والمحتوى النصي، وقائمة باستدعاءات الأدوات:

json
{
  "id": "session_001",
  "task_description": "Fix the authentication bypass in login.py",
  "model": "claude-sonnet-4-20250514",
  "structured_turns": [
    {
      "role": "assistant",
      "content": "I'll investigate the auth issue.",
      "tool_calls": [
        {
          "tool": "Read",
          "input": {"file_path": "src/auth/login.py"},
          "output": "def login(user, password):\n    if user.role == 'admin':\n        return True",
          "output_type": "code",
          "language": "python"
        },
        {
          "tool": "Bash",
          "input": {"command": "pytest tests/test_auth.py -v"},
          "output": "4 passed",
          "output_type": "terminal"
        }
      ]
    }
  ]
}

يقبل output_type القيم code أو diff أو terminal أو generic، ويستنتجه Potato من الأداة وامتداد الملف إذا تركته. حدّده صراحةً حين لا تكون مخرجات الأداة كما يوحي اسمها.

تحويل التتبعات التي لديك

يقرأ المحوّل صيغة واحدة ويكتب ملف JSONL الذي يحمّله Potato. ثلاث من صيغه خاصة بوكلاء البرمجة:

bash
# Claude Code, or any Anthropic Messages API transcript
python -m potato.trace_converter -i traces.json -f claude_code -o data/traces.jsonl
 
# Aider chat history with SEARCH/REPLACE blocks
python -m potato.trace_converter -i chat.md -f aider -o data/traces.jsonl
 
# SWE-Agent trajectories
python -m potato.trace_converter -i trajectory.json -f swe_agent_trajectory -o data/traces.jsonl
 
# Mixed directory, format detected per file
python -m potato.trace_converter -i traces.json --auto-detect -o data/traces.jsonl

يقرأ محوّل claude_code نصوص جلسات Claude Code نفسها، كما يقرأ شكل Messages API الخام. يكتب Claude Code ملف JSONL واحداً لكل جلسة في ~/.claude/projects/<slugified-working-directory>/<session-id>.jsonl، ويحوّل المحوّل الجلسة الواحدة إلى تتبع واحد بدل تتبع لكل سطر:

bash
python -m potato.trace_converter \
  -i ~/.claude/projects/-home-me-myrepo/3c853f0f-....jsonl \
  --auto-detect -o data/session.jsonl

يتبع المحوّل سلسلة parentUuid ولا يحتفظ إلا بالمسار الباقي، فتُسقط المحاولات التي أُرجعت إلى الوراء وتُعدّ بدل أن يُعلَّق عليها كأنها حدثت. وتذهب رسائل الـ sidechain إلى sidechain_runs، خارج الأدوار الرئيسية. وتُسقط أوامر الشرطة المائلة لأنها حديث الـ CLI مع نفسها. والشكل المخزَّن على القرص ملك للـ CLI وليس لواجهة API منشورة، فتعامل مع القارئ على أنه يبذل أفضل جهد ممكن عبر الترقيات. فهو يتجاهل أنواع السجلات التي لا يعرفها، ويرفع خطأً بدل أن يعيد تتبعاً فارغاً حين يتعذر تحليل الملف.

التعليق لمكافأة العملية

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

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

yaml
annotation_schemes:
  - annotation_type: process_reward
    name: step_rewards
    description: "Click the first step where the agent makes a mistake."
    steps_key: structured_turns
    mode: first_error

في وضع per_step يُحكم على كل خطوة منفردة. وهذا يكلّف المعلّقين وقتاً أطول وينتج الإشارة التي لا يستطيع first_error إنتاجها، لأن التتالي يفترض أن الخطأ لا يمكن التعافي منه، والوكلاء الحقيقيون يتعافون. فعّل allow_neutral معه فتتبع الوسوم اصطلاح PRM800K بالقيم +1 و0 و-1، حيث تُسجَّل الخطوة غير الضارة فعلاً محايدةً بدل أن تُدفع إلى أحد القطبين:

yaml
  - annotation_type: process_reward
    name: step_rewards
    description: "Label each step as correct, neutral, or incorrect."
    steps_key: structured_turns
    step_text_key: content
    mode: per_step
    allow_neutral: true

أضف أيّاً من المخططين إلى التهيئة أعلاه. مع تفعيل allow_neutral تبقى الخطوة غير الموسومة null، فيميّز التصدير بين حكم محايد مقصود وخطوة لم يصل إليها المعلّق قط. ولا ينطبق allow_neutral إلا على per_step، ويُعطَّل قسراً في first_error الذي لا مكان فيه لحكم محايد.

التعليق لمراجعة الأكواد

يأتي مخطط code_review بمراجعة طلبات السحب إلى مخرجات الوكلاء. ينقر المعلّقون على سطر في الـ diff لإرفاق تعليق مصنَّف، ويقيّمون كل ملف، ويصدرون حكماً:

yaml
  - annotation_type: code_review
    name: review
    description: "Review the agent's code changes."
    comment_categories: [bug, style, suggestion, security]
    verdict_options: [approve, request_changes, comment_only]
    file_rating_dimensions: [correctness, quality]

أضف هذا المخطط إلى التهيئة أعلاه. يُقيَّم كل بُعد من أبعاد تقييم الملفات من 1 إلى 5. والقيم الافتراضية معقولة لأعمال المراجعة العامة، فاستبدلها حين يكون تصنيفك هو جوهر الدراسة، كما في مراجعة أمنية يجب فيها أن يكون bug وsecurity فئتين منفصلتين بتعريفين منفصلين في التعليمات.

تعليق مراجعة الأكواد بتعليقات مضمّنة على الـ diffتعليقات مضمّنة على الـ diff، وتقييمات لكل ملف، والحكم العام

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

تهيئة كاملة

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

yaml
annotation_task_name: "Coding Agent Trace Evaluation"
task_description: "Judge whether the agent completed the task and review its changes."
 
data_files:
  - data/traces.jsonl
 
item_properties:
  id_key: id
  text_key: task_description
 
port: 8000
output_annotation_dir: annotation_output/coding-agent-eval/
export_annotation_format: jsonl
 
instance_display:
  layout:
    direction: vertical
    gap: 16px
  fields:
    - key: task_description
      type: text
      label: "Task"
    - key: structured_turns
      type: coding_trace
      label: "Agent Session"
      display_options:
        show_file_tree: true
        diff_view: unified
        collapse_long_outputs: true
        max_output_lines: 50
        terminal_theme: dark
        show_step_numbers: true
 
annotation_schemes:
  - annotation_type: radio
    name: task_success
    description: "Did the agent complete the task?"
    labels:
      - name: success
        tooltip: "Completed correctly with no issues"
      - name: partial
        tooltip: "Completed with minor issues"
      - name: failure
        tooltip: "Not completed, or completed incorrectly"
    sequential_key_binding: true
 
  - annotation_type: process_reward
    name: step_rewards
    description: "Click the first step where the agent makes a mistake."
    steps_key: structured_turns
    mode: first_error
 
  - annotation_type: code_review
    name: review
    description: "Review the agent's code changes."
    comment_categories: [bug, style, suggestion, security]
    verdict_options: [approve, request_changes, comment_only]
    file_rating_dimensions: [correctness, quality]
 
  - annotation_type: text
    name: notes
    description: "Anything else worth recording about this trace"
    placeholder: "Optional"
 
num_annotators_per_item: 3
 
user_config:
  allow_all_users: false
  users:
    - annotator1
    - annotator2

ثبّت Potato، وحوّل تتبعاتك، وشغّل الخادم:

bash
pip install potato-annotation
python -m potato.trace_converter -i ./my_traces.json --auto-detect -o data/traces.jsonl
potato start config.yaml -p 8000

يتضمن المستودع نسخة عاملة من هذا المشروع في examples/agent-traces/coding-agent-evaluation/، وهي أسرع طريقة لرؤية العرض قبل أن تحوّل أي شيء من بياناتك. شغّل تلك التهيئة، واقرأ تتبعاً واحداً كما سيقرؤه المعلّق، وستعرف خلال دقائق إن كانت دقة الخطوات التي تنوي وسمها هي الدقة التي يعرضها العرض.

التصدير للتدريب

تخرج التعليقات عبر مُصدِّر تقييم البرمجة، الذي يكتب ملفاً واحداً لكل نوع من المخرجات:

bash
python -m potato.export -c config.yaml -f coding_eval -o exports/ \
  --option types=prm,preference,swebench,code_review
النوعالملفما يغذّيه
prmprm_training_data.jsonlتدريب نموذج مكافأة العملية
preferencepreference_pairs.jsonlDPO أو RLHF، من تعليقات المقارنة الزوجية
swebenchswebench_results.jsonlتقييم متوافق مع SWE-bench
code_reviewcode_reviews.jsonlبيانات مراجعة منظمة

يحتاج نوع preference إلى تعليقات مقارنة زوجية يُبنى منها، فالدراسة التي لا تجمع إلا مكافآت العملية تنتج الأنواع الثلاثة الأخرى. قرّر أيّ الأربعة تريد قبل تصميم المخططات، لأن إضافة مقارنة زوجية بعد انتهاء العمل تعني التعليق على كل تتبع مرة ثانية في مقابل تتبع آخر.

مشاهدة وكيل وهو يعمل

التتبعات المسجّلة نصف الصورة. يشغّل live_coding_agent وكيلاً داخل صفحة التعليق، حيث يشاهده المعلّقون وهو يعمل، ويتدخلون، ويتراجعون، ويعيدون التشغيل بتعليمات مختلفة، مع واجهة خلفية من Ollama أو Anthropic أو Claude SDK في دليل عمل معزول. وتشرح وثائق وكيل البرمجة المباشر الواجهات الخلفية وأوضاع العزل.

إذا كان فريقك يقيّم وكلاء البرمجة ووجد شيئاً لا يغطيه هذا الإعداد، فافتح issue في مستودع GitHub. المحوّل الجديد ملف واحد تقريباً في potato/trace_converter/converters/، فالصيغة التي لا يقرؤها Potato بعد مساهمة ممكنة وليست عائقاً.