◆ مهندسی هوش مصنوعی با Codex

ماژول ۱ · هفته ۱ تا ۳ · حدود ۷ ساعت

#ماژول ۱. مهندسی کانتکست با Codex

بخشی از صفحه اصلی دوره. حدود ۷ ساعت: ۲٫۵ ساعت خواندن، ۴٫۵ ساعت کار عملی. بررسی‌شده با Codex CLI 0.167.1 و مستندات Codex در ۱۱ نوامبر ۲۰۲۶.

#شروع سریع (۱۵ دقیقه)

قبل از اینکه بقیه صفحه را بخوانی، این بخش را انجام بده. آخرش دو عدد پایه داری که آخر ماژول خودت را با آن‌ها مقایسه می‌کنی.

ریپو sentinel را که در ماژول ۰ ساختی لازم داری. همه دستورها را از ریشه همین ریپو اجرا کن.

۱. ایجنت واقعاً از این ریپو چه می‌داند؟ پنج سؤال از آن بپرس، از همان سؤال‌هایی که یک هم‌تیمی تازه‌وارد هم باید جوابشان را بداند. با codex exec یک نوبت غیرتعاملی در سندباکس read-only اجرا می‌شود و --ephemeral هم نمی‌گذارد فایل session ذخیره شود:

bash
cd sentinel
codex exec --ephemeral "Answer from what you can find in this repo. One short line each.
Say 'unknown' if the repo does not say.
1. Which command or commands must pass before a change counts as done?
2. Which folder must you never edit?
3. What exact JSON shape must the scanner print with --json?
4. Which label id marks a container that explicitly runs as UID 0?
5. Is code in src/ allowed to read fixtures/labels.json?"

جواب‌ها را با کلید پایین مقایسه کن و برای هر جواب درست یک امتیاز بده. احتمالاً نمره‌ات پایین می‌شود. شاید Codex دستور npm run scan را از package.json پیدا کند، یا شناسه برچسب را مستقیم از labels.json بخواند. همین دومی مشکلی است که در این ماژول حلش می‌کنی.

کلید جواب‌ها (بعد از نمره دادن باز کن)
  1. باید npm run build بی‌خطا تمام شود و npm run --silent scan -- --json یک JSON معتبر با همان شکلی که قرارش را گذاشته‌اید چاپ کند.
  2. پوشه fixtures/.
  3. یک آبجکت JSON. کلیدهایش مسیر فایل نسبت به fixtures/ است، مثلاً k8s/k01-privileged.yaml، و هر مقدار آرایه‌ای از شناسه‌های برچسب است. برای فایل تمیز مقدار [] است.
  4. شناسه runs-as-root.
  5. نه. برچسب‌ها کلید جواب‌اند و اسکنری که آن‌ها را بخواند تقلب کرده.

هیچ‌کدام از این‌ها هنوز جایی نوشته نشده، جز همان شناسه برچسب داخل labels.json. مشکل دقیقاً همین است.

۲. قبل از اینکه چیزی تایپ کنی، ایجنت چقدر کانتکست خوانده است؟ خروجی codex debug prompt-input همان ورودی‌ای است که مدل اول session می‌بیند، به شکل JSON. این اسکریپت کوچک را به اسم scripts/context-size.mjs در sentinel ذخیره کن، چون در کل این ماژول بارها سراغش می‌آیی:

js
#!/usr/bin/env node
// Usage: codex debug prompt-input "hi" | node scripts/context-size.mjs
// Prints the size of each block Codex puts in front of the model at session start.
import { readFileSync } from "node:fs";

const items = JSON.parse(readFileSync(0, "utf8"));
let total = 0;
for (const item of items) {
  const text = (item.content ?? []).map((c) => c.text ?? "").join("");
  total += text.length;
  const first = text.trimStart().split("\n")[0].slice(0, 70);
  console.log(String(text.length).padStart(7), (item.role ?? item.type).padEnd(9), first);
}
console.log(String(total).padStart(7), "characters in total (characters, not tokens)");
bash
codex debug prompt-input "hi" | node scripts/context-size.mjs

در خروجی چند بلوک می‌بینی. اولی بزرگ است و با «You are Codex…» شروع می‌شود. این دستورالعمل‌های داخلی خود Codex است. بعد یک بلوک <skills_instructions> می‌آید، یک بلوک درباره کار چندایجنتی و یک بلوک user. اگر AGENTS.md خوانده شود، بلوک آن با # AGENTS.md instructions for … شروع می‌شود.

عددهای پایه‌ات را اینجا بنویس:

  • تاریخ:
  • نمره سؤال‌ها:
  • اندازه بلوک AGENTS.md:
  • اندازه بلوک skills:
  • کل کاراکترها در شروع session:
  • نمره اولین تسک ماژول ۰ (از آنجا کپی کن):

آخر این ماژول نمره سؤال‌ها باید ۵ از ۵ شود. تسک ماژول ۰ را هم از یک برنچ تمیز دوباره اجرا می‌کنی و این بار نمره‌اش باید از ماژول ۰ بهتر باشد.

#چرا مهم است

در ماژول ۰ یک پرامپت یک‌پاراگرافی به Codex دادی و شمردی چند بار مجبور شدی وسط کار دخالت کنی. هر کدام از آن دخالت‌ها به خاطر کانتکستی بود که ایجنت نداشت. یا دستوری را نمی‌شناخت، یا قانونی را نمی‌دید، یا مجبور بود فرمت خروجی را حدس بزند. دو راه داری. یا این کانتکست را در هر پرامپت دوباره تایپ می‌کنی، یا یک بار جایی می‌گذاری که Codex هر بار خودش بخواند.

کل این ماژول درباره راه دوم است و اسمش را گذاشته‌اند مهندسی کانتکست. Codex اول کار چند چیز ثابت را می‌خواند، مثل فایل‌های دستورالعمل، فهرست skillها و تعریف ابزارها. بعد هر چه جلوتر می‌رود چیزهای دیگری هم اضافه می‌شود: فایل‌هایی که باز می‌کند، خروجی دستورها، متن کامل skillها و نتیجه MCP. همه این‌ها باید در یک پنجره محدود جا شوند. هر چه چیزهای به‌دردبخور بیشتر و حرف اضافه کمتر باشد، ایجنت کمتر حدس می‌زند.

برای تو که کارت امنیت است، قضیه یک طرف دیگر هم دارد. همان قواعدی که کانتکست را برای تو جمع می‌کند، برای مهاجم هم کار می‌کند. اگر ریپویی را کلون کنی که AGENTS.md یا skill دارد، Codex آن‌ها را درست مثل فایل‌های خودت می‌خواند. در همین ماژول می‌بینی که حتی وقتی پوشه را trust نکرده‌ای هم خوانده می‌شوند. ماژول ۲ این‌ها را قفل می‌کند، ولی قبلش باید دقیق بدانی چه چیزی از کجا و کی خوانده می‌شود.

#تصویر کلی

flowchart TB
  subgraph Start["شروع session (ثابت)"]
    SYS["دستورالعمل‌های داخلی"]
    G["~/.codex/AGENTS.md"] --> R["فایل AGENTS.md ریشه"] --> N["فایل AGENTS.md هر پوشه<br/>تا cwd"]
    SK["فهرست skillها:<br/>نام + توضیح<br/>(حدود ۲٪ پنجره)"]
    TL["تعریف ابزارها<br/>و ابزارهای MCP"]
  end
  subgraph Work["حین کار (رشد می‌کند)"]
    F["فایل‌ها و<br/>خروجی دستورها"]
    SB["متن کامل SKILL.md<br/>وقتی استفاده شود"]
    MCP["نتیجه MCP"]
    SUB["خلاصه subagentها"]
  end
  Start --> WIN["یک پنجره کانتکست"]
  Work --> WIN
  WIN -- "پر شد؟" --> C["دستور /compact<br/>یا فشرده‌سازی خودکار"]
  SUBA["هر subagent<br/>با پنجره جدا"] -. "فقط خلاصه" .-> SUB

جعبه بالا را از قبل خودت تعیین می‌کنی و هزینه‌اش را در هر نوبت می‌دهی، چه به کار بیاید چه نه. فایل‌های AGENTS.md از ریشه تا پوشه‌ای که Codex را در آن باز کرده‌ای پشت هم چسبانده می‌شوند. پس فایل‌های عمیق‌تر دیرتر می‌آیند و حرف آخر را آن‌ها می‌زنند. هر skill تا وقتی Codex سراغش نرود فقط به اندازه نام و توضیحش جا می‌گیرد. جعبه پایین حین کار بزرگ می‌شود و بیشتر کانتکست همان‌جا مصرف می‌شود. برای اینکه این رشد به پنجره خودت نرسد، راه اصلی subagent است. خواندن‌های پرحجم را در thread خودش انجام می‌دهد و فقط خلاصه را برمی‌گرداند.

#مفهوم ۱. کانتکست بودجه است

مدل همه چیزهای داخل پنجره را به یک اندازه خوب نمی‌خواند. پژوهش Chroma به افت کیفیت با پر شدن پنجره می‌گوید context rot و مستندات subagent در Codex هم همین اصطلاح را به کار می‌برد. راهنمای Anthropic درباره مهندسی کانتکست می‌گوید هدف این است که برای هر تسک «کوچک‌ترین مجموعه ممکن از توکن‌های پرسیگنال» را پیدا کنی. حرف اصلی این ماژول همین است. هر خطی که به AGENTS.md اضافه می‌کنی، در هر نوبت و هر session و برای همیشه هزینه دارد.

جدول پایین اندازه بلوک‌های شروع یک session را در ۱۱ نوامبر ۲۰۲۶ نشان می‌دهد. اندازه‌ها را با اسکریپت شروع سریع گرفتم، با CLI 0.167.1 و در یک ریپو تقریباً خالی که یک skill داشت:

بلوک اندازه با چه کنترلش می‌کنی
دستورالعمل‌های داخلی Codex حدود ۲۱٬۸۰۰ کاراکتر هیچ. برای هر نسخه ثابت است
دستورالعمل و فهرست skillها حدود ۱۱٬۶۰۰ کاراکتر همان skillهایی که وجود دارند، کلید skills.max_context_tokens و [skills.bundled] enabled = false
دستورالعمل چندایجنتی حدود ۲٬۷۰۰ کاراکتر تنظیم [agents] enabled = false ابزارهای subagent را خاموش می‌کند
فایل‌های AGENTS.md و اطلاعات محیط با فایل‌های تو بزرگ می‌شود همان چیزی که می‌نویسی، و project_doc_max_bytes
تعریف ابزارها (shell، ابزارهای MCP) در prompt-input نشان داده نمی‌شود سرورهای MCP که اضافه می‌کنی، و enabled_tools

یعنی هر session از همان اول چند ده هزار کاراکتر مصرف کرده، و یک AGENTS.md سی‌کیلوبایتی هم مجانی نیست. ولی چیزی که از همه سریع‌تر بزرگ می‌شود اصلاً کانفیگ نیست. خروجی دستورها و فایل‌هایی است که حین کار خوانده می‌شود. برای همین /compact، subagentها و کوتاه نگه داشتن خروجی ابزارها از پرامپت‌نویسی ماهرانه مهم‌ترند.

#مفهوم ۲. فایل AGENTS.md: قانون‌هایی که ایجنت همیشه می‌بیند

در هر اجرا، Codex فقط یک بار و همان اول کار زنجیره دستورالعمل‌ها را می‌سازد. طبق مستندات این‌طور:

مرحله کاری که Codex می‌کند
سراسری در ~/.codex (یا $CODEX_HOME) اگر AGENTS.override.md باشد همان را می‌خواند، وگرنه AGENTS.md را. فقط اولین فایلی که خالی نباشد
پروژه از ریشه پروژه (ریشه Git) تا پوشه‌ای که الان در آن هستی پایین می‌رود. در هر پوشه اول دنبال AGENTS.override.md می‌گردد، بعد AGENTS.md و بعد نام‌های project_doc_fallback_filenames، و اولین را برمی‌دارد. از هر پوشه حداکثر یک فایل
ادغام فایل‌ها را از ریشه تا پایین‌ترین پوشه با یک خط خالی پشت هم می‌چسباند. متن عمیق‌تر دیرتر می‌آید و حرف آخر را می‌زند
سقف وقتی جمع به project_doc_max_bytes برسد (پیش‌فرض ۳۲ کیلوبایت) دیگر فایلی اضافه نمی‌کند. فایل خالی هم حساب نمی‌شود
تازه‌سازی فقط اول کار خوانده می‌شود. بعد از هر ویرایش Codex را دوباره باز کن

سه چیز در این قواعد هست که خیلی‌ها را غافلگیر می‌کند:

  • پوشه‌های پایین‌تر از cwd خوانده نمی‌شوند. اگر Codex را در ریشه ریپو باز کنی، src/AGENTS.md اصلاً خوانده نمی‌شود، حتی وقتی Codex دارد فایل‌های src/ را ویرایش می‌کند. فایل‌های تودرتو فقط وقتی اثر دارند که Codex را در همان پوشه باز کنی، یا با codex --cd src.
  • سقف بی‌صدا متن را می‌بُرد. در یک تست مقدار project_doc_max_bytes=40 گذاشتم. فایل ریشه وسط کلمه بریده شد و فایل تودرتو کلاً حذف شد، بدون هیچ هشداری. پس فایل ریشه اگر طولانی باشد جای فایل‌های دقیق‌تر را می‌گیرد.
  • فایل override جای فایل اصلی را می‌گیرد و به آن اضافه نمی‌شود. در هر پوشه اگر AGENTS.override.md باشد، AGENTS.md کنار گذاشته می‌شود. برای یک تغییر موقت سراسری، ~/.codex/AGENTS.override.md بساز و بعد از کار پاکش کن.

چه بنویسی. چیزهایی که ایجنت به‌راحتی پیدا نمی‌کند، یا معمولاً اشتباه حدس می‌زند:

  • دستورهای دقیق build و تست و اجرا، و اینکه کار کی «تمام» حساب می‌شود؛
  • ساختار ریپو: تغییرها کجا می‌روند، کدام فایل‌ها تولیدی‌اند و به چه چیزی نباید دست زد؛
  • قانون‌های سخت مثل «هرگز fixtures/ را ویرایش نکن»، با دلیلش در چند کلمه؛
  • واژگان: نام‌ها و فرمت‌هایی که بقیه کد به آن‌ها وابسته است، مثل شناسه‌های برچسب و شکل خروجی sentinel.

چه ننویسی. چیزی که ایجنت در چند ثانیه از خود کد می‌فهمد لازم نیست. راهنمای سبک طولانی هم لازم نیست، چون کار linter است. روال‌هایی که فقط گاهی لازم می‌شوند هم جایشان در skill است (مفهوم ۳). به گزارش InfoQ، تیمی در OpenAI که یک محصول بزرگ را با Codex ساخت، دانش پروژه را در یک پوشه docs مرتب نگه داشت، با نقشه‌ها و planها و مشخصات طراحی، و همان را مرجع اصلی ایجنت‌ها کرد. برای sentinel یعنی اگر مستندات بلند لازم شد، AGENTS.md فقط به آن اشاره کند و همه را در خودش جا ندهد.

ببین چه چیزی خوانده شد. مستندات پیشنهاد می‌کند از خود Codex بپرسی: codex --ask-for-approval never "Summarize the current instructions.". ولی ابزاری که الان داری دقیق‌تر است:

bash
codex debug prompt-input "hi" | node scripts/context-size.mjs        # from the repo root
codex debug prompt-input "hi" | grep -c 'AGENTS.md instructions'      # 1 when files loaded
cd fixtures && codex debug prompt-input "hi" | grep -o 'Review mode'   # nested file, see the full example

#مفهوم ۳. skillها: روال‌هایی که فقط وقت نیاز خوانده می‌شوند

هر skill یک پوشه است با یک فایل SKILL.md، و اگر لازم باشد پوشه‌های scripts/، references/ و assets/. فرانت‌متر فایل باید name و description داشته باشد. فرمت skillها همان استاندارد باز agent skills است (agentskills.io).

ایده اصلی‌اش progressive disclosure است. ایجنت اول کار فقط نام، توضیح و مسیر هر skill را فهرست می‌کند. متن کامل SKILL.md را وقتی می‌خواند که تصمیم بگیرد از آن استفاده کند. پس یک چک‌لیست بازبینی سه‌کیلوبایتی، تا وقتی لازمش نداری، تقریباً به اندازه یک خط جا می‌گیرد. سقف این فهرست اولیه ۲٪ پنجره کانتکست مدل است، و اگر اندازه پنجره معلوم نباشد ۸٬۰۰۰ کاراکتر. اگر skill زیادی نصب کنی، Codex اول توضیح‌ها را کوتاه می‌کند و ممکن است بعضی را با یک هشدار کنار بگذارد. با کلید skills.max_context_tokens می‌توانی این سقف را تا ۱۰٬۰۰۰ توکن تغییر بدهی.

فایل AGENTS.md skill
بارگذاری همیشه، کامل نام و توضیح همیشه، متن فقط وقتی استفاده شود
مناسب برای دستورها، ساختار، قانون‌های سخت، واژگان روال‌ها، چک‌لیست‌ها، کارهای چندمرحله‌ای، اسکریپت‌های کمکی
فعال‌سازی لازم نیست، همیشه هست با $skill-name یا /skills، یا خودکار وقتی تسک با توضیح جور باشد
دامنه هر پوشه در مسیر تا cwd پوشه .agents/skills در هر پوشه از cwd تا ریشه ریپو، به‌علاوه ~/.agents/skills، /etc/codex/skills و skillهای همراه Codex

جاهایی که Codex می‌گردد:

دامنه مسیر
ریپو پوشه .agents/skills/ در cwd و هر پوشه بالاتر تا ریشه ریپو
کاربر مسیر ~/.agents/skills/
ادمین مسیر /etc/codex/skills/
سیستم همراه Codex: skill-creator و skill-installer

توضیح را طوری بنویس که درست تشخیص داده شود. Codex فقط از روی توضیح تصمیم می‌گیرد کی خودش skill را صدا بزند. پس اول بگو skill چه کار می‌کند و کی باید استفاده شود، و بعد بگو کی نباید. اگر توضیح‌ها برای جا شدن در بودجه کوتاه شوند، کلمه‌های اول می‌مانند. اگر نمی‌خواهی skill هیچ‌وقت خودکار صدا زده شود، فایل agents/openai.yaml را با policy: allow_implicit_invocation: false اضافه کن. صدا زدن دستی با $skill-name باز هم کار می‌کند.

خاموش کردن skillها. در ~/.codex/config.toml یک [[skills.config]] بگذار با enabled = false، و با path یک فایل را مشخص کن یا با name همه skillهای آن اسم را. در .codex/config.toml یک پروژه trustشده هم می‌توانی با [skills.bundled] enabled = false skillهای سیستمی همراه Codex را پنهان کنی. در تست من این کار در هر session حدود ۱٬۷۰۰ کاراکتر کم کرد.

#مفهوم ۴. پروتکل MCP: ابزار از بیرون

با Model Context Protocol، یا همان MCP، Codex می‌تواند ابزارهای یک پروسه دیگر (stdio) یا یک سرور (streamable HTTP) را صدا بزند. برای sentinel به‌دردبخورترینش جست‌وجوی مستندات است. APIهای Kubernetes و Node مدام عوض می‌شوند و چیزی که مدل یادش است از مستندات فعلی قدیمی‌تر است.

سرور را می‌توانی با CLI اضافه کنی یا دستی در کانفیگ بنویسی:

bash
codex mcp add context7 -- npx -y @upstash/[email protected]    # stdio
codex mcp add <name> --url https://example.com/mcp               # streamable HTTP
codex mcp list

کلیدهایی که از نظر امنیتی مهم‌اند:

کلید کارش
کلید enabled_tools و disabled_tools فهرست ابزارهای مجاز و ممنوع سرور. فهرست ممنوع بعد از فهرست مجاز اعمال می‌شود
کلید default_tools_approval_mode یکی از auto، prompt، writes یا approve. با prompt قبل از هر صدا زدن از تو می‌پرسد. با writes فقط برای ابزارهایی می‌پرسد که read-only علامت نخورده‌اند
کلید tools.<name>.approval_mode استثنا برای یک ابزار
کلید startup_timeout_sec و tool_timeout_sec پیش‌فرض ۱۰ و ۶۰ ثانیه
کلید required با مقدار true اگر سرور بالا نیاید کل اجرا متوقف می‌شود، در codex exec هم
کلید enabled با مقدار false سرور خاموش می‌شود بدون اینکه پاکش کنی
کلید env_vars و bearer_token_env_var سکرت را با اسمش از محیط خودت بفرست و هیچ‌وقت مستقیم در کانفیگ ننویس

قبل از اضافه کردن هر سرور سه چیز را بدان:

  • اسکیمای همه ابزارها در هر نوبت در پنجره است. سروری که ۳۰ ابزار دارد کانتکست مصرف می‌کند، حتی اگر هیچ‌وقت یکی از آن‌ها را صدا نزنی. با enabled_tools فقط همان‌هایی را نگه دار که لازم داری.
  • نسخه را pin کن. اگر npx -y some-mcp را بدون نسخه بنویسی، هر بار که Codex باز شود آخرین نسخه منتشرشده با دسترسی‌های خودت اجرا می‌شود. مثل دستور بالا نسخه را ثابت کن.
  • قانون‌های شبکه سندباکس روی ترافیک MCP اثری ندارند. در ماژول ۲ می‌بینی که allowlist شبکه فقط برای دستورهاست و سرورهای MCP را شامل نمی‌شود. هر سرور را کدی حساب کن که با دسترسی‌های خودت اجرا می‌شود. سرورهایی که در .codex/config.toml یک ریپو تعریف شده‌اند فقط وقتی خوانده می‌شوند که پروژه trust شده باشد. قبل از اینکه trust وجود داشته باشد، CVE-2025-61260 دقیقاً از همین حفره استفاده کرد.

سرور Context7 مال Upstash است و در نسخه 4.6.0 دو ابزار دارد. با resolve-library-id اسمی مثل «kubernetes» به شناسه کتابخانه تبدیل می‌شود و با query-docs مستندات همان شناسه را می‌گیری. بدون API key هم کار می‌کند، فقط سقف درخواستش پایین‌تر است. مستندات Codex یک سرور راه‌دور هم برای مستندات توسعه‌دهندگان OpenAI معرفی می‌کند، در https://developers.openai.com/mcp. وقتی در ماژول ۵ به Agents SDK برسی، آن سرور انتخاب بهتری است.

#مفهوم ۵. subagentها: نویز را بیرون از پنجره نگه دار

هر subagent یک thread جداگانه است که Codex برای یک تکه از کار راه می‌اندازد. در کانتکست خودش فایل می‌خواند، دستور اجرا می‌کند و فکر می‌کند، و آخر سر فقط خلاصه‌اش برمی‌گردد. مستندات subagent می‌گوید دو مشکل را حل می‌کند. یکی context pollution است، یعنی اطلاعات مفید زیر لاگ و خروجی جست‌وجو گم می‌شود. دیگری همان context rot است.

چند نکته از مستندات نسخه‌های فعلی که روی نحوه استفاده‌ات اثر دارد:

  • سه ایجنت آماده همراه Codex می‌آید: default، worker برای پیاده‌سازی و رفع باگ، و explorer برای جست‌وجوی سنگین در کد.
  • ایجنت وقتی subagent می‌سازد که خودت بخواهی، مثلاً «برای هر مورد یک ایجنت بساز»، یا یک دستورالعمل در AGENTS.md یا یک skill این را خواسته باشد. اگر reasoning effort را روی ultra بگذاری، ممکن است خودش هم کار را تقسیم کند.
  • هر subagent جداگانه مدل و ابزار مصرف می‌کند، پس اجرای چندایجنتی توکن بیشتری از یک ایجنت تنها می‌خورد. روی پلن Plus این از سقف پنج‌ساعته‌ات کم می‌شود.
  • هر subagent تنظیمات سندباکس و approval والدش را به ارث می‌برد، حتی تغییرهایی که با /permissions یا --yolo داده‌ای. فایل ایجنت سفارشی نمی‌تواند sandbox_mode، approval_policy، model_provider یا mcp_servers را عوض کند. پس اگر در دستورالعمل یک ایجنت سفارشی بنویسی «فایل ویرایش نکن»، فقط خواهش کرده‌ای. سندباکس read-only نساخته‌ای.
  • با /subagents بین threadها جابه‌جا می‌شوی. اگر درخواست approval از یک thread پس‌زمینه آمد، قبل از جواب دادن کلید o را بزن تا آن thread باز شود.

ایجنت‌های سفارشی فایل‌های TOML هستند. مال خودت در ~/.codex/agents/ است و مال پروژه در .codex/agents/، که فقط در پروژه trustشده خوانده می‌شود. هر فایل باید name، description و developer_instructions داشته باشد و می‌تواند model، model_reasoning_effort، model_reasoning_summary و model_verbosity را هم تعیین کند. اگر می‌خواهی توانایی‌ای را از ایجنت بگیری، در فایلش یکی از features.shell_tool، features.apps، features.plugins، features.memories یا features.request_permissions_tool را false کن. دقت کن که Codex ایجنت را با فیلد name می‌شناسد و اسم فایل مهم نیست.

پیش‌فرض‌های سراسری در کانفیگ زیر [agents] هستند: default_subagent_model، default_subagent_reasoning_effort، max_concurrent_threads_per_session و enabled. مستندات برای ایجنت‌های سریع و محدود gpt-6-luna را پیشنهاد می‌کند و برای کارهای سنگین gpt-6.1-sol را.

کارهای موازی که خواندن زیادی دارند جای subagent است، مثل گشتن در کد، بازبینی یا دسته‌بندی خروجی تست. ولی اگر چند ایجنت هم‌زمان فایل بنویسند، مراقب باش. فایل‌های مشترک را ویرایش می‌کنند و کارشان با هم تداخل پیدا می‌کند.

#مفهوم ۶. هدایت session با plan و goal و compact

با این دستورها تعیین می‌کنی حین session چه چیزی وارد پنجره شود. توضیح هر دستور در جدول همان جمله خود مستندات CLI 0.167.1 است. مستندات بیشتر از این درباره رفتار داخلی plan و goal چیزی نمی‌گوید، پس خودت ببین چه می‌کنند و یادداشت کن.

دستور توضیح مستندات کی استفاده کنی
دستور /plan «Switch to plan mode and optionally send a prompt.» قبل از هر تغییر چندمرحله‌ای. ایجنت قبل از ویرایش اول بررسی می‌کند و راه‌حل پیشنهاد می‌دهد. درست کردن plan خیلی ارزان‌تر از درست کردن کد است
دستور /goal «Set, edit, pause, resume, view, or clear a task goal.» بعد از plan، برای تعیین خط پایان. راهنمای پرامپت‌نویسی می‌گوید بعد از plan با آن «یک هدف ماندگار» تعیین کن. قابلیت goals باید روشن باشد، که در 0.167.1 به‌طور پیش‌فرض روشن است
دستور /compact «Summarize the visible chat to free tokens.» وقتی /status نشان می‌دهد پنجره دارد پر می‌شود، یا قبل از اینکه در همان session سراغ یک زیرتسک دیگر بروی
دستور /status «Display session configuration and token usage.» برای اینکه ببینی پنجره چقدر پر شده
دستور /side «Start an ephemeral side chat.» برای یک سؤال کوتاه که نباید در thread اصلی بماند
دستورهای /fork و /new انشعاب از چت، یا شروع چت تازه در همان session معمولاً یک پنجره تازه از compact کردن یک چت طولانی و شلوغ بهتر است
دستور /init «Generate an AGENTS.md scaffold in the current directory.» برای اینکه پیش‌نویس خودش را با چیزی که دستی نوشته‌ای مقایسه کنی

اگر در config reference دنبال کلیدهای مرتبط می‌گردی، این‌ها را جست‌وجو کن: plan_mode_reasoning_effort که reasoning effort را در plan mode تعیین می‌کند، model_auto_compact_token_limit و tool_output_token_limit. روی PreCompact و PostCompact هم می‌شود hook گذاشت (ماژول ۲).

پرامپت خوب هنوز مهم است. راهنمای پرامپت‌نویسی OpenAI می‌گوید به Codex بگو تغییر را چطور وریفای کند. برای باگ هم یک دستور بازتولید بده و بخواه بعد از رفع باگ دوباره اجرایش کند. اگر یک «شرط تمام شدن» در AGENTS.md بنویسی، این کار پیش‌فرض می‌شود و لازم نیست هر بار تایپش کنی.

#مثال کامل: بسته کانتکست برای sentinel

حالا تسک ماژول ۰ را از صفر دوباره اجرا می‌کنی، این بار با کانتکست. یک برنچ از اولین کامیت بساز تا کدی که Codex در ماژول ۰ نوشت در آن نباشد:

bash
cd sentinel
git switch -c m1-context "$(git rev-list --max-parents=0 HEAD)"
ls            # only fixtures/ should be here
mkdir -p scripts .agents/skills/k8s-review .codex/agents

اسکریپت scripts/context-size.mjs را هم از شروع سریع به این برنچ کپی کن.

۱. فایل AGENTS.md ریشه. حدود ۲٫۵ کیلوبایت است و فقط چیزهایی را می‌گوید که ایجنت خودش نمی‌تواند بفهمد: دستورها و شرط تمام شدن، جای تغییرها، قانون‌های سخت و واژگان.

markdown
# sentinel

A small TypeScript CLI that reviews Kubernetes manifests (and later JavaScript code)
for security problems with simple rules. Node 22, no framework.

## Commands
- Install: `npm install`
- Build: `npm run build`
- Scan: `npm run --silent scan -- --json` (prints the JSON contract below, nothing else)
- Done check: a change is done only when `npm run build` passes and
  `npm run --silent scan -- --json` prints valid JSON in the shape below.

## Layout
- `src/`: scanner code. Changes go here, plus `package.json` and `tsconfig.json`.
- `fixtures/k8s/`, `fixtures/js/`: test inputs with known problems. Read only.
- `fixtures/labels.json`: the expected answers. See hard rules.
- `scripts/`: the owner's measurement scripts. Do not edit them.
  Do not run `scripts/score-k8s.mjs`.

## Hard rules
- Never edit, move or delete anything under `fixtures/`. It is the ground truth for evals.
- Never read `fixtures/labels.json` and never put a fixture file name in `src/`.
  Rules must work on any manifest, not on these files.
- Allowed dependencies: `typescript`, `@types/node`, `yaml`. Ask before adding others.
- The scanner makes no network calls.

## Scanner output contract
`npm run --silent scan -- --json` prints one JSON object. Keys are paths relative to
`fixtures/` for every file under `fixtures/k8s/`. Values are arrays of label ids from
the table below, `[]` when the file is clean.

```json
{ "k8s/example-a.yaml": ["runs-as-root"], "k8s/example-b.yaml": [] }
```

## Label ids (use exactly these strings)
| id | Flag when |
|---|---|
| `privileged-container` | a container has `securityContext.privileged: true` |
| `hostpath-mount` | the pod has any `hostPath` volume |
| `secret-in-plain-env` | an env var whose name contains SECRET, PASSWORD, TOKEN or KEY has a literal `value:` (not `valueFrom`) |
| `mutable-image-tag` | an image uses `:latest` or has no tag at all (version tags and digests are fine) |
| `runs-as-root` | `runAsUser: 0` is set on the pod or a container |
| `rbac-wildcard` | a Role or ClusterRole rule has `"*"` in apiGroups, resources or verbs |
| `host-network` | the pod has `hostNetwork: true` |
| `host-pid` | the pod has `hostPID: true` |

JavaScript label ids, for later modules: `command-injection`, `code-injection-eval`,
`ssrf`, `jwt-not-verified`.

Out of scope as labels: missing resource limits, missing digests on version tags,
missing NetworkPolicies. Do not report these as label ids.

جدول برچسب‌ها کلید جواب نیست، مشخصات است. می‌گوید هر برچسب یعنی چه، تا دو نفر که بازبینی می‌کنند به یک نتیجه برسند. یک تیم واقعی هم همین را می‌نویسد، و در ماژول ۳ برای نمره دادن به مدل دقیقاً همین را لازم داری.

۲. فایل تودرتو برای session بازبینی. این را به اسم fixtures/AGENTS.md ذخیره کن. فقط وقتی خوانده می‌شود که Codex را داخل fixtures/ باز کنی، پس مثل یک سوئیچ «حالت بازبینی» کار می‌کند:

markdown
# Review mode

You started Codex inside fixtures/. You are reviewing, not building.
- Do not edit any file.
- Do not open labels.json.
- For each file you are asked about, answer with label ids from the root AGENTS.md
  table and one line of evidence (the YAML path), or "clean".

هر دو حالت را چک کن. خروجی cd fixtures && codex debug prompt-input "hi" | grep -o 'Review mode' باید Review mode باشد، و اگر همین را از ریشه ریپو اجرا کنی نباید چیزی چاپ شود.

۳. فایل skill. این را به اسم .agents/skills/k8s-review/SKILL.md ذخیره کن. روال بازبینی اینجا می‌ماند، چون جایش در AGENTS.md نیست که در هر نوبت خوانده شود:

markdown
---
name: k8s-review
description: Review Kubernetes YAML manifests for security problems and report sentinel label ids with evidence. Use when asked to review, audit or label a manifest, or to check scanner output for fixtures/k8s. Not for JavaScript files and not for writing scanner code.
---

# k8s-review

## Steps
1. For each manifest, find every pod spec: `spec` for a Pod, `spec.template.spec` for
   a Deployment, DaemonSet, StatefulSet or Job, `spec.jobTemplate.spec.template.spec`
   for a CronJob. RBAC and NetworkPolicy objects have no pod spec.
2. Check every container and the pod spec against the checklist below.
3. Report one line per file:
   `<path>: <label ids, or clean> | <evidence as YAML paths>`
4. Put anything outside the checklist under a final "Notes" line, not as a label.
5. Do not edit files. Do not open fixtures/labels.json.

## Checklist
| Label id | Where to look |
|---|---|
| privileged-container | containers[].securityContext.privileged == true |
| hostpath-mount | volumes[].hostPath present |
| secret-in-plain-env | containers[].env[] where name matches SECRET, PASSWORD, TOKEN or KEY and `value` is set |
| mutable-image-tag | containers[].image ends in `:latest` or has no `:` tag and no `@sha256:` |
| runs-as-root | securityContext.runAsUser == 0 at pod or container level |
| rbac-wildcard | kind Role or ClusterRole, any rules[] with "*" in apiGroups, resources or verbs |
| host-network | spec.hostNetwork == true |
| host-pid | spec.hostPID == true |

Remember initContainers and ephemeralContainers count as containers.

۴. یک سرور MCP مستندات و یک subagent بررسی‌کننده. این را به اسم .codex/config.toml ذخیره کن. فقط به این خاطر خوانده می‌شود که sentinel را در ماژول ۰ trust کردی:

toml
# sentinel/.codex/config.toml  (project layer: loads only in a trusted project)
[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/[email protected]"]          # pinned, not "latest"
enabled_tools = ["resolve-library-id", "query-docs"]
default_tools_approval_mode = "prompt"                 # ask before each call
startup_timeout_sec = 20

[agents]
max_concurrent_threads_per_session = 3

بعد ایجنت سفارشی را در .codex/agents/fixture-auditor.toml بساز. این ایجنت نظر دوم است و هیچ‌وقت برچسب‌ها را نمی‌بیند. مانیفست‌ها را با همان skill بازبینی می‌کند تا بتوانی نتیجه‌اش را با خروجی اسکنر مقایسه کنی:

toml
name = "fixture_auditor"
description = "Read-only reviewer. Use to review files in fixtures/k8s with the k8s-review skill and report label ids with evidence, so the main thread can compare them with the scanner output."
model = "gpt-6-luna"
model_reasoning_effort = "high"
developer_instructions = """
You review Kubernetes manifests. You never edit files.
Use the k8s-review skill and report one line per file in the format it gives.
Never open fixtures/labels.json or anything under scripts/.
Return only the per-file lines and the Notes line. No summary.
"""

۵. اسکریپت نمره‌دهی خودت. این را به اسم scripts/score-k8s.mjs ذخیره کن. این اسکریپت مال توست و Codex نباید از آن استفاده کند. خروجی JSON اسکنر را با برچسب‌ها مقایسه می‌کند و چک می‌کند اسکنر تقلب نکرده باشد.

js
#!/usr/bin/env node
// Usage: npm run --silent scan -- --json | node scripts/score-k8s.mjs
// Compares the scanner's JSON with fixtures/labels.json for the 8 k8s files.
// This is YOUR script. AGENTS.md tells Codex not to run it, because it prints the answers.
import { readFileSync, readdirSync } from "node:fs";

const labels = JSON.parse(readFileSync("fixtures/labels.json", "utf8"));
const files = Object.keys(labels).filter((f) => f.startsWith("k8s/"));

let out;
try {
  out = JSON.parse(readFileSync(0, "utf8"));
} catch {
  console.log(`score 0/${files.length} (scanner output is not JSON)`);
  process.exit(1);
}

let correct = 0;
for (const f of files) {
  const want = [...labels[f]].sort().join(",");
  const got = Array.isArray(out[f]) ? [...out[f]].sort().join(",") : "<missing>";
  if (want === got) correct++;
  console.log(`${want === got ? "ok  " : "MISS"} ${f}  want [${want}]  got [${got}]`);
}

// A scanner that knows the fixture names or reads the labels is cheating.
const src = readdirSync("src", { recursive: true })
  .filter((f) => /\.(ts|js|mjs|cjs)$/.test(f))
  .map((f) => readFileSync(`src/${f}`, "utf8"))
  .join("\n");
const gamed = /labels\.json|k0[1-8]-/.test(src);
console.log(`score ${correct}/${files.length}${gamed ? "  INVALID: src/ mentions labels.json or a fixture name" : ""}`);

۶. بسته را چک کن، بعد کامیتش کن.

bash
codex doctor                                              # config line: ✓ config loaded
codex debug prompt-input "hi" | node scripts/context-size.mjs
codex debug prompt-input "hi" | grep -o 'k8s-review: [^.]*'       # skill is listed
codex debug prompt-input "hi" | grep -o 'fixture_auditor: [^.]*'  # custom agent is listed
git add -A && git commit -qm "Module 1 context pack" && git tag m1-start

قبل از این کامیت، فایل‌های scripts/m0-task.txt و scripts/m1-eval.sh را هم از بخش eval پایین ذخیره کن تا داخل تگ m1-start باشند. اسکریپت eval قبل از هر اجرا ریپو را به همین تگ برمی‌گرداند.

اندازه جدید بلوک AGENTS.md و جمع کل را در بخش تمرین بنویس. بعد سؤال‌های شروع سریع را دوباره اجرا کن. این بار باید جواب همه درست باشد.

#مثال کامل: دوباره تسک ماژول ۰

همان تسک را با همان کلمه‌ها اجرا می‌کنی، فقط این بار با کانتکست جدید. در ریشه ریپو codex را باز کن، یا پنل VS Code را، و دخالت‌ها و approvalها و دقیقه‌ها را دقیقاً مثل ماژول ۰ بشمار.

  1. اول /plan را تایپ کن، بعد پرامپت ماژول ۰ را بچسبان:
text
Create a TypeScript CLI in src/ that reads every file under fixtures/k8s and prints,
for each one, a list of security problems found with simple rules (no AI).
Use Node 22, no framework. Add npm scripts "build" and "scan". Don't touch fixtures/.
  1. قبل از اینکه plan را قبول کنی، بخوانش. باید به قرارداد JSON، شناسه‌های برچسب AGENTS.md و شرط تمام شدن اشاره کرده باشد. اگر می‌خواهد labels.json را باز کند، بگو نه و این را یک دخالت حساب کن.

  2. خط پایان را تعیین کن:

text
/goal npm run build passes and npm run --silent scan -- --json prints the AGENTS.md JSON contract for every file in fixtures/k8s
  1. بگذار کارش را بکند. وقتی گفت تمام شد، این را بفرست تا یک ایجنت دیگر کارش را بررسی کند. خودت به هیچ چیز دست نزن.
text
Spawn fixture_auditor on fixtures/k8s, wait for it, and list every file where its labels differ from the scanner output.
  1. وقتی کار تمام شد، خودت بیرون از Codex نمره بده:
bash
npm run --silent scan -- --json | node scripts/score-k8s.mjs
  1. با /status ببین پنجره چقدر پر شده. اگر /compact زدی، یادداشت کن کی.

نتیجه را روی برنچ m1-context کامیت کن تا eval پایین پاکش نکند: git add -A && git commit -qm "Module 1 re-run".

#مثال کامل: یک eval کوچک، با و بدون AGENTS.md

با یک بار اجرا چیزی ثابت نمی‌شود. خروجی مدل قطعی نیست و یک نتیجه خوب ممکن است شانسی باشد. پس همان تسک را سه بار با AGENTS.md و سه بار بدون آن اجرا کن، همه از یک نقطه شروع و بدون اینکه خودت دخالت کنی، و بعد نتیجه‌ها را مقایسه کن.

با codex exec می‌شود اجراها را عیناً تکرار کرد. در حالت «بدون» از -c project_doc_max_bytes=0 استفاده می‌شود. در تست من این گزینه فایل‌های AGENTS.md پروژه را از پرامپت حذف کرد و بقیه چیزها را سر جایش نگه داشت، یعنی skill و سرور MCP و ایجنت سفارشی را. پس این eval فقط اثر AGENTS.md را می‌سنجد. فایل scripts/m0-task.txt همان چهار خط متن تسک بالاست. هر دو فایل باید در کامیت m1-start باشند (مرحله ۶ بسته کانتکست). اگر یادت رفت، روی یک برنچ از m1-start اضافه‌شان کن، کامیت کن و با git tag -f m1-start تگ را به همان کامیت ببر.

اسکریپت scripts/m1-eval.sh این است:

bash
#!/usr/bin/env bash
# Usage: scripts/m1-eval.sh with|without <run-number>
# Resets the working tree to tag m1-start, runs the module 0 task once with
# codex exec (no human), then scores the result. Appends to eval-results/m1.csv.
set -euo pipefail
mode=${1:?with|without}; run=${2:?run number}

git diff --quiet && git diff --cached --quiet || { echo "Commit or stash first."; exit 1; }
git switch -q --detach m1-start
git clean -fdq -e node_modules -e eval-results     # wipes the previous run's src/

extra=()
[ "$mode" = without ] && extra=(-c project_doc_max_bytes=0)

start=$(date +%s)
codex exec --ephemeral --sandbox workspace-write \
  -c sandbox_workspace_write.network_access=true \
  ${extra[@]+"${extra[@]}"} \
  "$(cat scripts/m0-task.txt)" > /dev/null 2>&1 || true
mins=$(( ($(date +%s) - start) / 60 ))

if npm run --silent build > /dev/null 2>&1; then
  score=$(npm run --silent scan -- --json 2> /dev/null | node scripts/score-k8s.mjs | tail -1)
else
  score="score 0/8 (build failed)"
fi

mkdir -p eval-results
echo "$mode,$run,$mins,$score" | tee -a eval-results/m1.csv
git switch -q m1-context

بعد:

bash
chmod +x scripts/m1-eval.sh
for i in 1 2 3; do scripts/m1-eval.sh with "$i"; scripts/m1-eval.sh without "$i"; done
cat eval-results/m1.csv

چند نکته درباره اینکه این اسکریپت چرا این‌طور نوشته شده:

  • ترکیب --sandbox workspace-write با شبکه روشن باعث می‌شود npm install بدون تأیید تو اجرا شود. برای ریپویی که خودت نوشته‌ای اشکالی ندارد. ماژول ۲ این را با allowlist دامنه عوض می‌کند. آنجا می‌بینی که دادن --sandbox پروفایل‌های دسترسی را خاموش می‌کند، پس این اسکریپت فقط برای ماژول ۱ است.
  • اسکریپت کدی را که Codex نوشته اجرا می‌کند، یعنی npm run build و scan را، آن هم بیرون از هر سندباکسی و روی سیستم خودت. این همان اعتمادی است که در ماژول ۰ به ریپوی خودت کردی. ولی خود اسکریپت عمداً npm install را اجرا نمی‌کند تا اگر مدل یک اسکریپت postinstall نوشته باشد، هیچ‌وقت بیرون از سندباکس اجرا نشود.
  • اجراهای «با» و «بدون» یکی‌درمیان انجام می‌شوند تا اثر ساعت روز بین هر دو حالت پخش شود.
  • اجراهای «بدون» معمولاً فقط سر فرمت نمره نمی‌گیرند، چون قرارداد JSON را نمی‌دانند. این ناعادلانه نیست و خودش یک یافته واقعی است، چون قرارداد هم بخشی از کانتکست است. اگر می‌خواهی کیفیت ruleها را جدا ببینی، خروجی «بدون» را دستی بخوان و بنویس، فرمت به کنار، چند فایل را درست تشخیص داده.
  • شش بار اجرای یک تسک build بخش قابل‌توجهی از سقف پنج‌ساعته پلن Plus را مصرف می‌کند. اول /status را ببین و بعد همه را یک‌جا اجرا کن.

در ماژول ۳ این را به یک eval درست‌وحسابی تبدیل می‌کنی، با اجراهای بیشتر، precision و recall برای هر برچسب، و مقایسه pass@k با pass^k.

#تمرین

بعد از بسته: بلوک AGENTS.md · کل در شروع · نمره سؤال‌ها

عددهای اجرای دوباره: دخالت‌ها · approvalها · دقیقه‌ها · نمره · پر بودن پنجره در پایان (از /status)

کاری که /plan و /goal کردند و انتظارش را نداشتی:

نمره‌های eval با AGENTS.md: · بدون آن:

کار وقتی تمام است که اجرای دوباره از نمره ماژول ۰ بهتر شده باشد، یا دقیق بتوانی بگویی چرا نشده. eval هم باید فرق AGENTS.md را در سه اجرا نشان بدهد، نه فقط در یکی.

#خودت را بسنج

قبل از اینکه هر سؤال را باز کنی، جوابش را در ذهنت یا روی کاغذ بده.

۱. قانون‌ها را در `src/AGENTS.md` گذاشته‌ای و Codex را در ریشه ریپو باز می‌کنی. ایجنت فایل‌های `src/` را ویرایش می‌کند. آیا قانون‌ها رعایت می‌شوند؟

نه. ایجنت از ریشه پروژه فقط تا پوشه‌ای که در آن باز شده پایین می‌رود و پایین‌تر را نمی‌خواند. فایل src/AGENTS.md فقط وقتی خوانده می‌شود که Codex را در src/ باز کنی، یا با codex --cd src. قانون‌هایی که همیشه باید رعایت شوند جایشان در فایل ریشه است.

۲. فایل `AGENTS.md` ریشه‌ات به ۴۰ کیلوبایت رسیده. چه اتفاقی می‌افتد؟

مقدار پیش‌فرض project_doc_max_bytes برابر ۳۲ کیلوبایت است. ایجنت وقتی به سقف برسد دیگر متنی اضافه نمی‌کند. پس آخر فایل ریشه بریده می‌شود و همه فایل‌های عمیق‌تر هم کنار گذاشته می‌شوند، بدون هیچ هشداری. یا کوتاهش کن، یا روال‌ها را به skill ببر، یا سقف را بالا ببر و قبول کن که هر session هزینه‌اش را می‌دهد.

۳. چرا چک‌لیست k8s یک skill است و جزو `AGENTS.md` نیست؟

به خاطر progressive disclosure. هر skill تا وقتی استفاده نشود فقط به اندازه نام و توضیحش جا می‌گیرد و متنش هر وقت لازم شد خوانده می‌شود. ولی AGENTS.md در هر نوبت از هر session کامل خوانده می‌شود، حتی در sessionهایی که موضوعشان چیز دیگری است. پس دستورها و قانون‌ها و واژگان در AGENTS.md می‌روند و روال‌ها در skill.

۴. یک ریپوی ناشناس را کلون می‌کنی و وقتی Codex می‌پرسد trust می‌کنی یا نه، می‌گویی نه. کدام بخش از کانتکست ریپو باز هم به مدل می‌رسد؟

فایل‌های AGENTS.md و فهرست .agents/skills/ آن. در چک پوشه trustنشده دیدی که این‌ها خوانده می‌شوند. تأیید trust فقط روی پوشه .codex/ اثر دارد، یعنی کانفیگ پروژه و سرورهای MCP داخلش، hookها، ruleها و ایجنت‌های سفارشی. پس قبل از اجرای Codex در ریپویی که خودت ننوشته‌ای، AGENTS.md و skillهایش را بخوان.

۵. در فایل یک ایجنت سفارشی نوشته `sandbox_mode = "read-only"` و «هرگز فایل ویرایش نکن». آیا آن subagent واقعاً read-only است؟

نه. هر subagent تنظیمات سندباکس و approval را از session والد به ارث می‌برد و فایل ایجنت سفارشی نمی‌تواند sandbox_mode یا approval_policy را عوض کند. آن جمله فقط یک خواهش است که مدل معمولاً رعایتش می‌کند، ولی جلوی چیزی را نمی‌گیرد. سندباکس را باید روی session والد تنظیم کنی.

۶. برچسب‌ها همین‌جا در ریپو هستند. پس چرا `AGENTS.md` ریپوی `sentinel` خواندن `labels.json` را ممنوع می‌کند؟

چون برچسب‌ها کلید جواب eval هستند. اسکنری که آن‌ها را بخواند یا اسم فایل‌های fixture را hard-code کند، ۸ از ۸ می‌گیرد بدون اینکه واقعاً چیزی تشخیص بدهد. برای همین اسکریپت نمره‌دهی src/ را چک می‌کند. در ماژول ۲ یک کنترل فنی هم برایش می‌گذاری، چون دستورالعمل جای کنترل را نمی‌گیرد.

۷. سه اجرای «با» نمره ۸، ۵ و ۸ گرفته‌اند. اجرای ماژول ۰ خودت ۴ گرفته بود. چه ادعایی می‌توانی بکنی؟

اینکه با AGENTS.md تسک معمولاً موفق می‌شود، ولی از سه اجرا یکی هنوز شکست خورد. اگر فقط یک بار اجرا کرده بودی، بسته به شانس نتیجه یا «عالی» به نظر می‌رسید یا «کمی بهتر». برای همین ماژول ۳ مقدار pass@k را که یعنی دست‌کم یک موفقیت در k تلاش، جدا از pass^k می‌شمارد که یعنی موفقیت در هر k تلاش. ایجنتی که بدون نظارت اجرا می‌کنی باید در دومی خوب باشد.

۸. یک سرور MCP با ۲۵ ابزار اضافه می‌کنی و فقط از دوتایش استفاده می‌کنی. هزینه‌اش چیست؟

تعریف همه ابزارها در هر نوبت جزو کانتکست است، پس همیشه هزینه هر ۲۵ تا را می‌دهی. هر ابزار اضافه هم یک گزینه دیگر است که مدل ممکن است اشتباهی صدایش بزند. با enabled_tools فقط همان دو تا را نگه دار و نسخه سرور را pin کن.

#چه یاد گرفتم

#کجا به کار بردم

#مرور

#منابع

به همین ترتیب بخوان. همه در ۱۱ نوامبر ۲۰۲۶ بررسی شدند.

  1. مستندات Codex، بخش Custom instructions with AGENTS.md: ترتیب پیدا کردن فایل‌ها، سقف اندازه، override و راه چک کردن اینکه چه چیزی خوانده شد. https://learn.chatgpt.com/docs/agent-configuration/agents-md.md

  2. مستندات Codex، بخش Build skills: progressive disclosure، مسیرها، بودجه ۲٪ و فایل openai.yaml. https://learn.chatgpt.com/docs/build-skills.md

  3. مستندات Codex، بخش Subagents: چرا به کار می‌آیند، ارث بردن دسترسی‌ها، اسکیمای ایجنت سفارشی و مثال‌ها. https://learn.chatgpt.com/docs/agent-configuration/subagents.md

  4. مستندات Codex، بخش Model Context Protocol: اضافه کردن سرور، حالت‌های approval، فیلتر ابزارها. https://learn.chatgpt.com/docs/extend/mcp.md

  5. مستندات Codex، فهرست slash commandها در CLI: دستورهای /plan، /goal، /compact، /status و بقیه. https://learn.chatgpt.com/docs/developer-commands.md?surface=cli

  6. مستندات Codex، بخش Prompting: اول plan، وریفای کردن داخل پرامپت. https://learn.chatgpt.com/docs/prompting.md

  7. مستندات Codex، بخش Config reference: کلیدهای project_doc_max_bytes، skills.max_context_tokens و model_auto_compact_token_limit را اینجا پیدا کن. https://learn.chatgpt.com/docs/config-file/config-reference.md

  8. مقاله Anthropic با عنوان Effective context engineering for AI agents: روشن‌ترین توضیحی که درباره کانتکست به‌عنوان بودجه منتشر شده. https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents

  9. پژوهش Chroma با عنوان Context rot: نشان می‌دهد کانتکست بیشتر همیشه بهتر نیست. https://www.trychroma.com/research/context-rot

  10. مقاله Manus درباره مهندسی کانتکست: الگوهای عملی مثل prefix ثابت، استفاده از فایل به‌عنوان حافظه و جلوی چشم مدل نگه داشتن خطاها. https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus

  11. گزارش InfoQ از harness engineering در OpenAI (منبع دست دوم): یک پوشه docs مرتب به‌عنوان مرجع اصلی ایجنت‌ها. https://www.infoq.com/news/2026/02/openai-harness-engineering-codex

  12. پژوهش Backslash Security درباره injection در AGENTS.md (پژوهش یک شرکت امنیتی، ژوئیه ۲۰۲۶): چرا فایل‌های دستورالعمل هم جزو زنجیره تأمین‌اند. https://backslash.security/blog/openai-codex-injection-in-agents-md-exfiltrating-credentials

  13. فایل README پروژه Context7 از Upstash: اسم ابزارها و گزینه‌های سرور مستندات. https://github.com/upstash/context7

  14. مشخصات Agent skills: فرمت بازی که skillهای Codex بر اساس آن نوشته می‌شوند. https://agentskills.io/specification

آخرین بررسی: ۱۱ نوامبر ۲۰۲۶، با Codex CLI 0.167.1. اندازه‌های کانتکست، تست بریده شدن متن و تست پوشه trustنشده را روی سیستم خودم با codex debug prompt-input اجرا کردم.