فاز 19 · درس 1

ساخت ایجنت کدنویسی ترمینال: از رابط متنی تا ثبت Pull Request

نوع
پروژه‌ی پایانی
زمان
حدود 11 دقیقه
زبان‌ها
TypeScript / Bun (harness), Python (eval scripts)
پیش‌نیاز
فاز 11 (مهندسی مدل‌های زبانی)، فاز 13 (ابزارها و پروتکل‌ها)، فاز 14 (ایجنت‌ها)، فاز 15 (سیستم‌های خودکار)، فاز 17 (زیرساخت)
ترمینال مدرن تاریک روی میز کار مهندسی که پنجره‌های تفکیک‌شده وظایف، استریم ابزار و شاخه‌های گیت را نمایش می‌دهد
فهرست مطالب
  1. صورت مسئله
  2. مفاهیم پایه
  3. معماری
  4. استک فناوری
  5. مراحل ساخت
  6. نحوه‌ی استفاده
  7. تحویل نهایی پروژه
  8. تمرین‌ها
  9. اصطلاحات کلیدی
  10. برای مطالعه‌ی بیشتر

سیستم‌هایی مثل Claude Code،‏ Cursor و OpenCode معماری ابزارهای مهندسی نرم‌افزار را تغییر داده‌اند. در ظاهر این ابزارها تنها یک رابط خط فرمان متصل به مدل زبانی به نظر می‌رسند، اما در عمل دشواری اصلی در پیاده‌سازی حلقه‌ی پایدار ابزارها، ایزوله‌سازی فرایندها در ساندباکس و مهار هزینه‌های سرسام‌آور توکن‌ها در اجراهای چندنوبتی است. با ساخت یک ایجنت از صفر، یاد می‌گیرید چطور خطاهای واقعی سیستم‌عامل و پر شدن پنجره‌ی بافتار را به جای سپردن کورکورانه به مدل، در سطح کد مهار کنید.

اگر برای دسترسی به مدل‌های پیشرو مانند Claude یا GPT به درگاه‌های ابری خارجی دسترسی مستقیم ندارید، می‌توانید از ارائه‌دهندگان سازگار با رابط برنامه‌نویسی OpenAI یا گیت‌وی‌های واسط برای اتصال به OpenRouter استفاده کنید؛ زیرا کدهای این پروژه روی انتزاع استاندارد ارتباط با مدل نوشته می‌شوند. همچنین اجرای مدل‌های باز کدنویسی نظیر Qwen با ابزارهایی مثل vLLM روی زیرساخت محلی گزینه‌ای کاملاً عملی برای آزمودن این معماری است.

در پایان این پروژه، ایجنتی مستقل خواهید داشت که با دستور خط فرمان شروع به کار می‌کند، وضعیت برنامه را گام‌به‌گام در محیطی ایزوله پیش می‌برد و در نهایت کدهای بررسی‌شده را در قالب یک Pull Request استاندارد روی گیت‌هاب تحویل می‌دهد.

تا سال 2026، ساختار استاندارد ایجنت‌های برنامه‌نویسی تثبیت شده است: یک بستر آزمایشی (harness) مبتنی بر رابط کاربری متنی (TUI)، برنامه‌ریزی دارای وضعیت (stateful plan)، سطح ابزار ساندباکس‌شده، و حلقه‌ای که برنامه‌ریزی می‌کند، دست به عمل می‌زند، مشاهده می‌کند و در صورت بروز خطا به حالت عادی بازمی‌گردد. از دور که نگاه کنید، Claude Code،‏ Cursor 3 و OpenCode همگی ساختار یکسانی دارند. در این پروژه‌ی پایانی، چنین سیستمی را از صفر تا صد می‌سازید؛ ورودی CLI تحویل می‌گیرد و در خروجی یک pull request تحویل می‌دهد. سپس عملکرد آن را در برابر mini-swe-agent و Live-SWE-agent روی بنچمارک SWE-bench Pro می‌سنجید. در این مسیر متوجه خواهید شد چرا بخش دشوار کار فراخوانی مدل نیست، بلکه حلقه‌ی ابزار، ساندباکس (محیط ایزوله)، و مهار سقف هزینه در یک اجرای 50 نوبتی است.

فازهای تمرین‌شده: P0 · P5 · P7 · P10 · P11 · P13 · P14 · P15 · P17 · P18
مدت زمان: 35 ساعت

صورت مسئله

ایجنت‌های برنامه‌نویسی در سال 2026 به اصلی‌ترین شاخه‌ی کاربردی هوش مصنوعی تبدیل شدند. سیستم‌هایی مانند Claude Code محصول Anthropic، نسخه‌ی Cursor 3 به همراه Composer 2 و Agent Tabs، ابزار Amp از Sourcegraph، پروژه‌ی OpenCode (با 112 هزار ستاره)، Factory Droids و Google Jules همگی نسخه‌های مختلفی از یک معماری واحد را عرضه می‌کنند: یک بستر ترمینال، بستری از ابزارها با مجوزهای مشخص، یک ساندباکس، و حلقه‌ی «برنامه‌ریزی، اقدام، مشاهده» که حول یک مدل پیشرو (frontier model) ساخته شده است. مرز رقابت بسیار باریک است — Live-SWE-agent با Opus 4.5 به نرخ قبولی (pass rate) ‏79.2% روی SWE-bench Verified رسید — اما ظرافت‌های مهندسیِ کار دامنه‌ی وسیعی دارد. بیشتر حالت‌های شکست (failure modes) ناشی از اشتباهات مدل نیستند؛ بلکه از ناپایداری حلقه‌ی ابزار، مسمومیت بافتار (context poisoning)، هزینه‌ی نجومی توکن‌ها و عملیات مخرب روی فایل‌سیستم سرچشمه می‌گیرند.

نمی‌توانید این ایجنت‌ها را صرفاً از بیرون تحلیل کنید. باید یکی از آن‌ها را خودتان بسازید؛ ببینید چطور حلقه‌ی ایجنت در نوبت 47 پس از بازگرداندن 8 مگابایت خروجی از ripgrep از کار می‌افتد، و بعد لایه‌ی هرس (truncation) داده‌ها را بازطراحی کنید. هدف این پروژه‌ی پایانی دقیقاً همین است.

مفاهیم پایه

این بستر چهار بخش اصلی دارد: بخش Plan یک شیء وضعیت شبیه به TodoWrite را نگه می‌دارد که مدل در هر نوبت آن را بازنویسی می‌کند. بخش Act فراخوانی ابزارها (tool calls) را ارسال و اجرا می‌کند (خواندن، ویرایش، اجرا، جست‌وجو، git). بخش Observe خروجی‌های stdout / stderr و کدهای خروج را ثبت، هرس و خلاصه‌سازی می‌کند و نتیجه را به مدل بازمی‌گرداند. بخش Recover خطاهای ابزار را بدون پر کردن پنجره‌ی بافتار (context window) یا افتادن در حلقه‌های بی‌نهایت مدیریت می‌کند. در الگوهای سال 2026، یک بخش دیگر هم اضافه شده است: هوک‌ها (Hooks)؛ شامل PreToolUse،‏ PostToolUse،‏ SessionStart،‏ SessionEnd،‏ UserPromptSubmit،‏ Notification،‏ Stop و PreCompact — نقاط توسعه‌ی قابل تنظیمی که اپراتور در آن‌ها سیاست‌ها، تله‌متری و گاردریل‌ها (سازوکارهای ایمنی) را تزریق می‌کند.

ساندباکس بر پایه‌ی E2B یا Daytona است. هر وظیفه (task) داخل یک devcontainer تازه اجرا می‌شود که یک ورک‌تری (worktree) گیت با دسترسی خواندن و نوشتن روی آن سوار شده است. بستر ایجنت هرگز با فایل‌سیستم سیستم میزبان درگیر نمی‌شود. ورک‌تری چه در صورت موفقیت و چه شکست، در پایان حذف خواهد شد. کنترل هزینه در سه لایه اعمال می‌شود: سقف توکن در هر نوبت، سهمیه‌ی دلاری برای هر نشست (session)، و سقف قطعی برای تعداد نوبت‌ها (معمولاً 50 نوبت). لایه‌ی پایش‌پذیری نیز بر پایه‌ی اسپن‌های (spans) پلتفرم OpenTelemetry و قراردادهای معنایی (semantic conventions) مربوط به GenAI بنا شده و داده‌ها را به نمونه‌ای خودمیزبان (self-hosted) از Langfuse می‌فرستد.

معماری

  user CLI  ->  harness (Bun + Ink TUI)
                  |
                  v
           plan / act / observe loop  <--->  Claude Sonnet 4.7 / GPT-5.4-Codex / Gemini 3 Pro
                  |                          (via OpenRouter, model-agnostic)
                  v
           tool dispatcher (MCP StreamableHTTP client)
                  |
     +------------+------------+----------+
     v            v            v          v
  read/edit    ripgrep     tree-sitter   git/run
     |            |            |          |
     +------------+------------+----------+
                  |
                  v
           E2B / Daytona sandbox  (worktree isolated)
                  |
                  v
           hooks: Pre/Post, Session, Prompt, Compact
                  |
                  v
           OpenTelemetry -> Langfuse (spans, tokens, $)
                  |
                  v
           PR via GitHub app

استک فناوری

  • محیط اجرای (runtime) بستر: Bun 1.2 به همراه Ink 5 (پیاده‌سازی React در ترمینال)
  • دسترسی به مدل‌ها: رابط برنامه‌نویسی یکپارچه‌ی OpenRouter با مدل‌های Claude Sonnet 4.7،‏ GPT-5.4-Codex،‏ Gemini 3 Pro و Opus 4.5 (برای دشوارترین وظایف)
  • بستر انتقال (transport) ابزار: پروتکل Model Context Protocol با قابلیت StreamableHTTP (نسخه‌ی بازنگری‌شده‌ی MCP در سال 2026)
  • ساندباکس: ساندباکس‌های E2B (کتابخانه‌ی JS) یا devcontainerهای Daytona
  • جست‌وجوی کد: زیرفرایند ripgrep و پارسرهای tree-sitter برای 17 زبان (کامپایل‌شده از پیش)
  • جداسازی: دستور git worktree add برای هر وظیفه و پاک‌سازی پس از موفقیت یا شکست
  • بستر ارزیابی: زیرمجموعه‌ی تأییدشده‌ی SWE-bench Pro به همراه Terminal-Bench 2.0 و مجموعه‌ی آزمون 30تایی مستقل خودتان
  • پایش‌پذیری: کیت توسعه‌ی OpenTelemetry با قراردادهای معنایی gen_ai.* و ارسال به نمونه‌ی خودمیزبان Langfuse
  • ثبت PR: برنامه‌ی GitHub App با توکن دارای دسترسی دقیق، با دامنه‌ی محدود به همان مخزن هدف
چرخه‌ی نوبت‌های ایجنتهر دور = یک نوبت گفت‌وگو
AGENT TURN CIRCUITThe harness runs a plan, act, observe, recover circuit, and every lap burns one turn of the 50-turn budget. PreToolUse and PostToolUse hooks fire as each tool call crosses the edge, and an oversized observation, like 8MB of ripgrep output, is truncated before it re-enters the context window.برنامه‌ریزیاقداممشاهدهبازیابیPreToolUsePostToolUseنوبت 47 / 50مشاهده:خروجی استاندارد 8MB، کوتاه شده پیش از ورود مجدد
بستر آزمایشی یک چرخه‌ی برنامه‌ریزی، اقدام، مشاهده و بازیابی را اجرا می‌کند و هر دور، یک نوبت از سهمیه‌ی 50 نوبتی را می‌سوزاند. قلاب‌های PreToolUse و PostToolUse هنگام عبور هر فراخوانی ابزار از مرز فعال می‌شوند و مشاهدات حجیم، مانند خروجی 8 مگابایتی ripgrep، قبل از ورود مجدد به پنجره‌ی بافتار کوتاه می‌گردند.

مراحل ساخت

  1. رابط کاربری متنی و حلقه‌ی فرمان. با Ink یک پروژه‌ی Bun بسازید. دستور agent run <repo> "<task>" را دریافت کنید. صفحه‌ی ترمینال را به سه بخش تقسیم کنید: قاب برنامه‌ریزی (بالا)، استریم فراخوانی ابزارها (وسط)، و سهمیه‌ی توکن (پایین). با زدن کلیدهای Ctrl-C قابلیت لغو را اضافه کنید تا قبل از خروج، هوک SessionEnd اجرا شود.

  2. وضعیت برنامه‌ریزی. یک اسکیمای ابزار (tool schema) تایپ‌شده برای TodoWrite تعریف کنید (آیتم‌های در انتظار / در حال انجام / انجام‌شده به همراه یادداشت). مدل باید در هر نوبت کل وضعیت را در قالب یک فراخوانی ابزار بازنویسی کند؛ اجازه ندهید مدل وضعیت را به‌صورت گام‌به‌گام و افزایشی تغییر دهد. برنامه‌ی کاری را در فایل .agent/state.json ذخیره کنید تا در صورت کرش، امکان ادامه‌ی کار وجود داشته باشد.

  3. سطح ابزار. شش ابزار تعریف کنید: read_file،‏ edit_file (با پیش‌نمایش diff)،‏ ripgrep،‏ tree_sitter_symbols،‏ run_shell (با محدودیت زمانی timeout) و git (شامل status / diff / commit / push). این ابزارها را روی MCP StreamableHTTP ارائه دهید تا بستر به بستر انتقال خاصی وابسته نباشد. همه‌ی ابزارها باید خروجی هرس‌شده برگردانند (سقف 4 هزار توکن برای هر فراخوانی).

  4. پوشش ساندباکس. برای هر وظیفه یک ساندباکس E2B بسازید. با دستور git worktree add -b agent/$TASK_ID یک branch تازه ایجاد کنید. تمام فراخوانی‌های ابزار باید درون ساندباکس اجرا شوند. فایل‌سیستم میزبان نباید به هیچ عنوان در دسترس باشد.

  5. هوک‌ها. هر هشت نوع هوک مربوط به سال 2026 را پیاده‌سازی کنید. حداقل چهار هوک با کد اختصاصی کاربر بنویسید: الف) هوک PreToolUse به‌عنوان محافظ در برابر دستورات مخرب برای مسدودسازی rm -rf در خارج از ورک‌تری، ب) هوک PostToolUse برای محاسبه‌ی توکن‌ها، ج) هوک SessionStart برای مقداردهی اولیه‌ی بودجه، د) هوک Stop برای ثبت بسته‌ی نهایی ردگیری محاسبات (trace).

  6. حلقه‌ی ارزیابی. زیرمجموعه‌ای شامل 30 ایشو از بخش Python بنچمارک SWE-bench Pro را دریافت کنید. بستر خود را روی تک‌تک آن‌ها اجرا کنید. نتایج را با mini-swe-agent (خط مبنای حداقلی) از نظر معیارهای pass@1، تعداد نوبت به ازای هر وظیفه و هزینه‌ی دلاری مقایسه کنید. خروجی را در فایل eval/results.jsonl بنویسید.

  7. کنترل هزینه. سقف‌های غیرقابل عبور تعیین کنید: 50 نوبت، پنجره‌ی بافتار 200 هزار توکنی، و 5 دلار به ازای هر وظیفه. هوک PreCompact باید با رسیدن به مرز 150 هزار توکن، نوبت‌های قدیمی‌تر را در قالب یک بلوک «وضعیت پیشین» خلاصه‌سازی کند تا بدون از دست رفتن برنامه، فضا برای مشاهدات جدید باز شود.

  8. ثبت PR. در صورت موفقیت، آخرین مرحله اجرای git push به همراه ارسال یک درخواست به API گیت‌هاب است تا یک PR باز شود که متن آن شامل برنامه و خلاصه‌ی diff باشد.

نحوه‌ی استفاده

$ agent run ./my-repo "Fix the race condition in worker.rs"
[plan]  1 locate worker.rs and enumerate mutex uses
        2 identify shared state under contention
        3 propose fix, verify tests
[tool]  ripgrep mutex.*lock -t rust           (44 matches, truncated)
[tool]  read_file src/worker.rs 120..180
[tool]  edit_file src/worker.rs (+8 -3)
[tool]  run_shell cargo test worker::          (passed)
[plan]  1 done · 2 done · 3 done
[done]  PR opened: #482   turns=9   tokens=38k   cost=$0.41

تحویل نهایی پروژه

مهارت نهایی حاصل از این پروژه در فایل outputs/skill-terminal-coding-agent.md قرار می‌گیرد. این مهارت با گرفتن مسیر یک مخزن و توضیحات یک وظیفه، حلقه‌ی کامل برنامه‌ریزی، اقدام و مشاهده را درون یک ساندباکس اجرا می‌کند و در نهایت نشانی PR به همراه بسته‌ی ردگیری محاسبات را تحویل می‌دهد. شیوه‌نامه‌ی نمره‌دهی (rubric) این پروژه‌ی پایانی به شرح زیر است:

وزن معیار نحوه‌ی ارزیابی
25 معیار pass@1 در SWE-bench Pro نسبت به خط مبنا مقایسه‌ی بستر شما با mini-swe-agent روی 30 وظیفه‌ی متناظر در پایتون
20 شفافیت معماری تفکیک لایه‌های برنامه‌ریزی/اقدام/مشاهده، سطح هوک‌ها، اسکیمای ابزار — با بازبینی بر اساس ساختار Live-SWE-agent
20 ایمنی آزمون‌های فرار از ساندباکس (sandbox escape)، اعلان‌های تأیید دسترسی، و قبولی محافظ دستورات مخرب در برابر آزمون تیم قرمز (red-team)
20 پایش‌پذیری کامل بودن ردگیری محاسبات (پوشش 100 درصدی فراخوانی‌های ابزار با اسپن‌ها) و محاسبه‌ی مصرف توکن در هر نوبت
15 تجربه‌ی توسعه‌دهنده راه‌اندازی اولیه (cold-start) زیر 2 ثانیه، ادامه‌ی برنامه پس از کرش، لغو تمیز با Ctrl-C در میانه‌ی اجرای ابزار
100

تمرین‌ها

  1. مدل پشتیبان را از Claude Sonnet 4.7 به Qwen3-Coder-30B که روی vLLM اجرا می‌شود تغییر دهید. دو معیار pass@1 و هزینه‌ی دلاری به ازای هر وظیفه را مقایسه کنید. نقاط ضعف این مدل متن‌باز را گزارش دهید.

  2. یک زیرایجنت reviewer اضافه کنید که پیش از باز شدن PR، تغییرات (diff) را بررسی کند و امکان درخواست یک حلقه‌ی بازنگری (revision loop) داشته باشد. بسنجید که آیا هشدارهای مثبت کاذب این بازبینی باعث افت نرخ قبولی SWE-bench نسبت به خط مبنای تک‌ایجنتی می‌شود یا خیر (راهنمایی: معمولاً بله).

  3. ساندباکس را زیر بار محک بزنید: وظیفه‌ای بنویسید که تلاش کند با دستور curl به یک آدرس خارجی وصل شود، و وظیفه‌ی دیگری که بخواهد فایلی خارج از ورک‌تری بنویسد. مطمئن شوید که هوک PreToolUse جلوی هر دو را می‌گیرد و این تلاش‌ها را لاگ می‌کند.

  4. خلاصه‌سازی در PreCompact را با مدلی سبک‌تر (Haiku 4.5) پیاده‌سازی کنید. بسنجید که با فشرده‌سازی سه‌برابری، چه مقدار از دقت برنامه از دست می‌رود.

  5. بستر انتقال را از MCP StreamableHTTP به stdio تغییر دهید. تأخیر راه‌اندازی اولیه و تأخیر هر فراخوانی را بنچمارک کنید. گزینه‌ی برتر را برای استفاده‌ی صرفاً محلی انتخاب کنید.

اصطلاحات کلیدی

اصطلاح برداشتی که رایج است معنای واقعی آن در عمل
بستر آزمایشی (Harness) «همان حلقه‌ی ایجنت» کدهایی که مدل را در بر می‌گیرند و فراخوانی ابزارها، مدیریت وضعیت برنامه‌ریزی و اجرای سهمیه‌ها را انجام می‌دهند
هوک (Hook) «شنونده‌ی رویدادهای ایجنت» اسکریپتی نوشته‌ی کاربر که بستر آزمایشی آن را در یکی از هشت رویداد چرخه‌ی حیات اجرا می‌کند
ورک‌تری (Worktree) «ساندباکس گیت» یک شاخه‌ی متصل به مخزن git در مسیری مجزا؛ بدون دستکاری clone اصلی می‌توان آن را حذف کرد
TodoWrite «وضعیت برنامه» فهرستی تایپ‌شده از وظایف در انتظار/در حال انجام/انجام‌شده که مدل در هر نوبت آن را بازنویسی می‌کند
StreamableHTTP «بستر انتقال MCP» بازنگری سال 2026 پروتکل MCP: اتصال پایدار HTTP با استریمینگ دوطرفه که جایگزین SSE شده است
سقف توکن (Token ceiling) «سهمیه‌ی بافتار» حد مجاز مجموع توکن‌های ورودی و خروجی در هر نوبت یا نشست که فشردگی یا پایان کار را کلید می‌زند
pass@1 «نرخ قبولی در اولین تلاش» کسری از وظایف SWE-bench که در اولین تلاش و بدون تلاش مجدد یا نگاه کردن به داده‌های آزمون حل می‌شوند

برای مطالعه‌ی بیشتر

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درسایجنت‌های برنامه‌نویسی ترمینال سال 2026 از کدام ساختار حلقه استفاده می‌کنند؟
  2. پیش از درسچرا بستر آزمایشی هر وظیفه را درون ساندباکس E2B یا Daytona اجرا می‌کند؟
  3. حین درسکدام قلاب توکار جایگاه طبیعی برای مسدود کردن دستورات شل مخرب پیش از اجرا است؟
  4. حین درسپروژه‌ی نهایی نتیجه‌ی هر ابزار را به حدود 4k توکن محدود می‌کند. این کار عمدتاً از کدام حالت شکست جلوگیری می‌کند؟
  5. حین درسقلاب PreCompact در مرز 150k توکن چه کاری انجام می‌دهد؟
  6. پس از درسپروژه‌ی نهایی بستر آزمایشی خود را با کدام خط مبنا روی زیرمجموعه‌ی 30 مسئله‌ای SWE-bench Pro مقایسه می‌کند؟
  7. پس از درسخروجی پروژه بر اساس کدام مجموعه‌ی معیاری سنجیده می‌شود؟

سؤالات متداول

چرا مدل‌ها هنگام اجرای طولانی در ایجنت‌های کدنویسی با کرش یا خطا مواجه می‌شوند؟

اغلب شکست‌ها ناشی از خطای درونی مدل نیست؛ بلکه ناپایداری حلقه‌ی ابزار، مسمومیت بافتار بر اثر خروجی‌های حجیم ابزارهایی مثل ripgrep و پر شدن سقف توکن‌ها عامل اصلی از کار افتادن ایجنت هستند.

کاربرد هوک‌ها (Hooks) در معماری ایجنت‌های مدرن چیست؟

هوک‌ها نقاط اتصالی در چرخه‌ی حیات ایجنت هستند که امکان تزریق سیاست‌های امنیتی (مثل مسدود کردن rm -rf)، محاسبه‌ی دقیق مصرف توکن و خلاصه‌سازی بافتار را پیش از پر شدن پنجره‌ی متن فراهم می‌کنند.

چرا در این معماری از ساندباکس و Git Worktree استفاده می‌شود؟

برای جلوگیری از اعمال تغییرات مخرب روی فایل‌سیستم میزبان؛ هر وظیفه داخل محیط ایزوله E2B یا Daytona با یک شاخه‌ی موقت worktree اجرا شده و پس از پایان کار به‌طور کامل پاک‌سازی می‌شود.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.