یکی از باگهای رایج در توسعهی سیستمهای مبتنی بر ایجنت (Agentic Systems) این است که مدلها گاهی بدون اجرای واقعی دستور یا بدون خواندن دقیق خروجی، ادعا میکنند کار انجام شده است. وقتی ایجنت به خروجی واقعی شل دسترسی نداشته باشد، حدس میزند و توهم نتایج تستها یا عملیاتها را به عنوان فکت تحویل میدهد.
در این درس یاد میگیرید چطور یک اجراکنندهی بازخورد (Feedback Runner) بسازید که دستورات شل را مهار کند، مقادیر stdout، stderr، کد خروج (Exit code) و مدتزمان اجرا را در رکوردهای ساختاریافتهی JSONL ذخیره کند و مانع از توهم ایجنت در ارزیابی موفقیت دستورات شود.
این ابزار به مدل اجازه میدهد در نوبت گفتوگوی (Turn) بعدی دقیقاً بداند چه اتفاقی افتاده و سیستم نیز در صورت خالی بودن بازخورد، جلوی پیشروی بیمورد حلقه را میگیرد.
ایجنتهایی که خروجی واقعی دستورات را نمیبینند، دست به حدس زدن میزنند. یک اجراکنندهی بازخورد (Feedback runner) خروجی استاندارد (stdout)، خطای استاندارد (stderr)، کد خروج (exit code) و زمان اجرا را در قالب یک رکورد ساختاریافته ذخیره میکند تا نوبت گفتوگوی (Turn) بعدی بتواند آن را بخواند. به این ترتیب ایجنت به جای پیشبینیهای خودش از واقعیت، بر اساس فکتها عمل میکند.
اهداف یادگیری
- تشخیص تفاوت بازخورد محیط اجرا (Runtime feedback) از تلهمتری پایشپذیری (Observability telemetry).
- ساخت یک اجراکنندهی بازخورد که دستورات شل را در بر میگیرد و رکوردهای ساختاریافته را ذخیره میکند.
- هرس (Truncation) خروجیهای حجیم به صورت قطعی (Deterministic) تا حلقهی ایجنت درون سهمیهی توکن (Token budget) بماند.
- جلوگیری از ادامهی حلقهی ایجنت در صورت در دسترس نبودن بازخورد.
صورت مسئله
ایجنت میگوید: «در حال اجرای تستها هستم.» پیام بعدی میگوید: «همهی تستها پاس شدند.» اما در واقعیت هیچ تستی اجرا نشده است. ایجنت خروجی را از خودش درآورده، یا دستور را اجرا کرده ولی نتیجه را نخوانده، یا نتیجه را خوانده اما خط مربوط به شکست را در سکوت هرس کرده است.
یک اجراکنندهی بازخورد این شکاف را برطرف میکند. تمام دستورات از این اجراکننده میگذرند. هر رکورد شامل دستور، stdout و stderr ثبتشده، کد خروج، مدتزمان واقعی اجرا و یک یادداشت تکخطی از طرف ایجنت است. ایجنت در نوبت گفتوگوی بعدی این رکورد را میخواند. گیت اعتبارسنجی (Verification gate) نیز در پایان تسک همین رکوردها را بررسی میکند.
مفهوم اصلی
چه مواردی داخل رکورد بازخورد قرار میگیرد
| فیلد | چرا اهمیت دارد |
|---|---|
command |
مقدار دقیق argv؛ بدون رفتارهای غیرمنتظرهی ناشی از بسط شل (Shell expansion) |
stdout_tail |
N خط آخر؛ هرس قطعی |
stderr_tail |
N خط آخر؛ تفکیکشده از stdout |
exit_code |
نشانهی صریح و بدون ابهام موفقیت |
duration_ms |
شناسایی پروبهای کند و فرایندهای مهارنشدنی |
started_at |
برچسب زمانی برای بازپخش (Replay) |
agent_note |
یادداشت یکخطی ایجنت دربارهی انتظاری که از خروجی داشت |
هرس کردن قطعی است
یک لاگ 50 مگابایتی حلقهی ایجنت را از پا درمیآورد. اجراکننده سر (Head) و ته لاگ را با نشانگر ...truncated N lines... هرس میکند؛ این کار قطعی است تا همان خروجی همیشه همان رکورد را تولید کند. اینجا خبری از نمونهبرداری تصادفی نیست؛ بخشهایی که ایجنت باید ببیند (خطای نهایی، خلاصهی پایانی) همیشه در انتهای خروجی جا دارند.
بازخورد در برابر تلهمتری
تلهمتری (فاز 14 · 23، قراردادهای معنایی OTel GenAI) برای اپراتورهای انسانی است که میخواهند اجراها را در طول زمان بررسی کنند. بازخورد برای نوبت گفتوگوی بعدی همین اجرا است. این دو فیلدهای مشترکی دارند، اما در فایلهای مجزایی با دورههای نگهداری (Retention) متفاوت ذخیره میشوند.
خودداری از پیشروی در نبود بازخورد
اگر اجراکننده قبل از ثبت کد خروج خطا دهد، رکورد با مقادیر exit_code: null و error: <reason> ذخیره میشود. حلقهی ایجنت بههیچوجه نباید با خروج null ادعای موفقیت کند. وقتی خروجی در کار نیست، پیشروی هم متوقف میشود.
پیادهسازی از صفر
فایل code/main.py این موارد را پیادهسازی میکند:
- تابع
run_with_feedback(command, agent_note)کهsubprocess.runرا در بر میگیرد، مقادیر stdout/stderr/exit/duration را ضبط میکند، خروجی را بهصورت قطعی هرس میکند و بهfeedback_record.jsonlمیافزاید. - یک بارگذار کوچک که فایل JSONL را بهصورت استریم به یک لیست پایتون تبدیل میکند.
- یک دمو که سه دستور (موفق، ناموفق، کند) را اجرا کرده و آخرین رکورد هر دستور را چاپ میکند.
آن را اجرا کنید:
python3 code/main.py
خروجی: سه رکورد بازخورد به feedback_record.jsonl اضافه میشود و آخرین رکورد هر کدام در همان خروجی چاپ میشود. فایل را در حین اجراهای مجدد پایش (Tail) کنید تا جمع شدن گامبهگام دادههای حلقه را ببینید.
الگوهای محیط عملیاتی در دنیای واقعی
سه الگو اجراکننده را آنقدر مقاوم میکنند که برای محیط عملیاتی (Production) آماده باشد.
پاکسازی هنگام نوشتن، نه هنگام خواندن. هر رکوردی که به stdout یا stderr دسترسی دارد ممکن است اطلاعات محرمانه (Secrets) را نشت دهد. اجراکننده قبل از نوشتن داده در JSONL، یک مرحله پاکسازی دادههای حساس (Redaction) اجرا میکند: حذف خطوط منطبق با ^Bearer ، password=، api[_-]?key=، AKIA[0-9A-Z]{16} (مربوط به AWS) و xox[baprs]- (مربوط به Slack). پاکسازی هنگام خواندن خطایی مرگبار است؛ چون مهاجم به همان فایل روی دیسک دسترسی پیدا میکند. الگوهای پاکسازی را هر سه ماه یکبار با قالبهای واقعی کلیدها در محیط اجرای عملیاتی ارزیابی و تطبیق دهید.
سیاست چرخش فایل، نه یک تکفایل. حجم feedback_record.jsonl را به 1 مگابایت برای هر فایل محدود کنید؛ در صورت پر شدن، آن را به .1 و .2 بچرخانید و فایل .5 را حذف کنید. حلقهی ایجنت فقط فایل فعلی را میخواند؛ بنابراین هزینهی محیط اجرا مهار میشود. مخزن ذخیرهی دستسازههای (CI artifact storage) تمام مجموعهی فایلهای چرخیدهشده را دریافت میکند. بدون این چرخش، فایل لاگ با هر بار فراخوانی بارگذار به گلوگاه تبدیل میشود.
شناسهی دستور والد برای زنجیرههای تلاش مجدد. هر رکورد یک command_id میگیرد؛ تلاشهای مجدد شامل parent_command_id هستند که به تلاش قبلی اشاره میکند. لیست «تلاشهای ناموفق» ارزیاب (فاز 14 · 40) و ممیزی گیت اعتبارسنجی، هر دو این زنجیره را دنبال میکنند. بدون این پیوند، تلاشهای مجدد مثل موفقیتهای مستقل به نظر میرسند و تاریخچهی شکستها از چشم ممیزی پنهان میماند.
استفاده از ابزارهای واقعی
الگوهای محیط عملیاتی:
- ابزار Claude Code Bash. این ابزار همین حالا هم مقادیر stdout، stderr، exit و duration را ثبت میکند. اجراکنندهی این درس، معادل مستقل از فریمورک آن برای هر محصول ایجنتی است.
- گرههای LangGraph. هر گرهی شل را در این اجراکننده بپیچید تا رکورد خارج از وضعیت گراف (Graph state) ماندگار شود.
- لاگهای CI. فایل JSONL را به مخزن ذخیرهی دستسازههای CI بفرستید؛ ارزیابها میتوانند بدون نیاز به اجرای مجدد نشست، هر دستوری را بازپخش کنند.
این اجراکننده یک لایهی نازک است که در هر بار مهاجرت میان فریمورکها دستنخورده میماند؛ چون مالکیت ساختار رکورد را خودش در دست دارد.
خروجی این درس
فایل outputs/skill-feedback-runner.md یک اسکریپت run_with_feedback.py مختص پروژه با سهمیهی هرس مناسب، یک نویسندهی JSONL متصل به محیط کاری و بارگذاری که ایجنت در هر نوبت گفتوگو میخواند، تولید میکند.
تمرینها
- فیلد
cwdرا به هر رکورد اضافه کنید تا اجرای یک دستور یکسان از دایرکتوریهای مختلف قابل تشخیص باشد. - یک مرحلهی
redactionاضافه کنید که خطوط منطبق با^Bearerیاpassword=را حذف کند. آن را روی یک رکورد آزمایشی بسنجید. - با چرخش لاگ به فایلهای
.1و.2، حجم کلیfeedback_record.jsonlرا روی 1 مگابایت محدود کنید. از سیاست چرخشی که چیدهاید دفاع کنید. - فیلد
parent_command_idرا اضافه کنید تا زنجیرههای تلاش مجدد مشخص شوند: کدام دستور ورودیِ مصرفشده توسط دستور بعدی را تولید کرده است. - فایل JSONL را به یک رابط متنی (TUI) کوچک وصل کنید که آخرین کد خروج غیرصفر را متمایز نشان دهد. هشت قابلیت کلیدی را فهرست کنید که این TUI باید نمایش دهد تا در فرایند بررسی واقعاً به کار بیاید.
اصطلاحات کلیدی
| اصطلاح | آنچه معمولاً میگویند | معنای دقیق فنی |
|---|---|---|
| Feedback record | «لاگ اجرا» | مدخل ساختاریافتهی JSONL شامل دستور، خروجی، خروج و مدتزمان |
| Tail truncation | «کوتاه کردن لاگ» | ثبت قطعی سر و ته خروجی تا رکوردها در سهمیهی توکن جا شوند |
| Refuse-on-null | «توقف به خاطر دادههای ناقص» | حلقه در صورت خالی (null) بودن exit_code نباید جلو برود |
| Agent note | «برچسب انتظار» | پیشبینی تکخطی که ایجنت قبل از خواندن نتیجه مینویسد |
| Telemetry split | «دو فایل لاگ» | بازخورد برای نوبت گفتوگوی بعدی، تلهمتری برای اپراتور |
برای مطالعهی بیشتر
- قراردادهای معنایی OpenTelemetry GenAI
- Anthropic، بسترهای آزمایشی کارآمد برای ایجنتهای بلندمدت
- Guardrails AI x MLflow — اعتبارسنجی قطعی ایمنی، دادههای حساس و کیفیت — الگوهای پاکسازی دادههای حساس به عنوان تستهای رگرسیون
- Aport.io، برترین گاردریلهای ایجنت هوش مصنوعی در 2026: مقایسهی مجوزهای پیش از اقدام — ثبت وضعیت قبل و بعد از اجرای ابزار
- Andrii Furmanets، ایجنتهای هوش مصنوعی در 2026: معماری کاربردی ابزارها، حافظه، ارزیابیها و گاردریلها — بسترهای پایشپذیری
- فاز 14 · 23 — قراردادهای معنایی OTel GenAI در بخش تلهمتری
- فاز 14 · 24 — پلتفرمهای پایشپذیری ایجنت (Langfuse، Phoenix، Opik)
- فاز 14 · 33 — قاعدهای که قبل از اعلام اتمام تسک، بازخورد واقعی را الزامی میکند
- فاز 14 · 38 — گیت اعتبارسنجی که فایل JSONL را میخواند
