Context Engineering: چرا agent شما در نوبت 40 کمهوشتر میشود
جابجایی یک واقعیت به سه خط پایینتر در prompt با 2.6٪ از window، retrieval را از 84٪ به 19٪ رساند. مشکل window نبود.
در این صفحه
در اینجا یک prompt داریم که 288 بار با greedy decoding به همان مدل فرستاده شده است. طول آن 853 token است. شامل فهرستی از بیستوپنج ticket پشتیبانی است — شهر، صف، اولویت، مالک، داخلی — و یک پرسش: Marta Ferreira درباره ticket خود به تماس برگشتی نیاز دارد. داخلی خط مستقیم برای آن ticket چیست؟
فهرست هر بار یکسان است. مدل هر بار یکسان است. تنها چیزی که تغییر میکند این است که پاسخ در کدامیک از بیستوپنج خط قرار دارد.
| جایگاه پاسخ | hitها | نرخ retrieval | بازه 95٪ |
|---|---|---|---|
| 1 از 25 | 27/32 | 84٪ | 68–93٪ |
| 4 از 25 | 6/32 | 19٪ | 9–35٪ |
| 7 از 25 | 6/32 | 19٪ | 9–35٪ |
| 10 از 25 | 9/32 | 28٪ | 16–45٪ |
| 13 از 25 | 8/32 | 25٪ | 13–42٪ |
| 16 از 25 | 6/32 | 19٪ | 9–35٪ |
| 19 از 25 | 6/32 | 19٪ | 9–35٪ |
| 22 از 25 | 3/32 | 9٪ | 3–24٪ |
| 25 از 25 | 7/32 | 22٪ | 11–39٪ |
سیودو آزمایش برای هر ردیف، در هر آزمایش یک ticket متفاوت، و بازههای Wilson از فصل 4، چون هفده از بیست چیزی را از چیز دیگری متمایز نمیکند.
جایگاه اول در 84٪ مواقع پاسخ داده میشود. هر جایگاه دیگر بین 9٪ و 28٪ مینشیند و بازههای هر هشت مورد با هم همپوشانی دارند، پس خوانش صادقانه این است: اول، و بعد همه چیزهای دیگر. Liu و همکاران یک U پیدا کردند — بالا در دو سر، پایین در میانه — و بازوی تازگی اینجا آشکارا حاضر نیست: 22٪ در آخرین جایگاه داخل پراکندگی جایگاههای میانی است. چیزی که داخل هیچ پراکندگیای نیست، سقوط از جایگاه 1 به جایگاه 4 است. سه خط.
context window این مدل 32,768 token است. prompt از 853 تای آنها استفاده میکند، 2.6٪. هیچچیز overflow نشد، هیچچیز truncate نشد، هیچ حدی به پایان نرسید، هیچ هشداری ظاهر نشد. مدل دیگر خطی را که به آن داده شده بود پیدا نکرد، چون آن خط سه جایگاه در یک فهرست بیستوپنجتایی پایینتر رفت.
فصل 16 قیمت context window را حساب کرد و در پایان هشدار داد که داشتن یک میلیون token همان استفاده کردن از آنها نیست، و به اینجا اشاره کرد. اینجا همانجاست.
نمایش جزئیات
این فصل از فصلهای قبلی چه میخواهد.
- فصل 9 self-attention و هزینه آن را استخراج کرد. هر token به هر token دیگر attention میدهد، پس تعداد رابطههای دوتایی با مربع طول رشد میکند. این واقعیت پایینتر استفاده میشود، نه اینکه دوباره استخراج شود.
- فصل 16 پنج سطل token قابلصورتحساب را شمرد و نشان داد که قبض یک مکالمه بهشکل درجهدو رشد میکند. این فصل درباره کاری است که بدون شکستن agent باید با آن بکنید.
- فصل 18 کاتالوگ ابزارها را ساخت و اندازه گرفت که بیست ابزار به انتخاب آسیب نزد اما prompt را شش برابر کرد. اینجا قبض آنهاست.
- فصل 19 retrieval را ساخت. retrieval درستبهموقع در ادامه، همان فصل است که روی تاریخچه خود agent اعمال شده؛ chunking دوباره توضیح داده نمیشود.
- فصل 23 harness را ساخت. هرچیزی در این فصل یک policy است که داخل حلقه آن اجرا میشود، و به همین دلیل TypeScript است: artifact یک سرویس ماندگارِ نگهدارنده state است، نه notebookای که tensor نگه دارد.
دو کار با نامهای شبیه هم
لینک به بخش: دو کار با نامهای شبیه همAnthropic در سپتامبر 2025 خط مرز را کشید و این دو جمله باید کنار هم باشند. prompt engineering یعنی «روشهایی برای نوشتن و سازماندهی دستورالعملهای LLM برای نتایج بهینه». Context engineering یعنی «مجموعه راهبردها برای گزینش و نگهداری مجموعه بهینه tokenها (اطلاعات) هنگام inference در LLM، شامل همه اطلاعات دیگری که ممکن است بیرون از promptها در آنجا قرار بگیرد».1
تفاوت عملیاتی در چه زمانی و بهدست چه کسی است. prompt یکبار، بهدست انسان، نوشته و بازبینی میشود. context در هر call، بهدست کدی که کسی به آن نگاه نمیکند، از موادی که هیچکس دستی ننوشته، ساخته میشود: چهل نوبت تاریخچه، شش نتیجه ابزار، چهار passage بازیابیشده، پروفایل کاربر، دوازده schema در JSON. فصل 15 اندازه گرفت دستورهای بهتر چه چیزی میخرند. این فصل درباره نود درصد دیگر tokenهاست، که خودشان از راه میرسند.
همان سند منبعی را نام میبرد که همهشان خرج میکنند: مدلها «یک attention budget دارند که هنگام parse کردن حجمهای بزرگ context از آن خرج میکنند. هر token جدیدی که معرفی میشود، این بودجه را تا حدی تخلیه میکند». و نشانه را هم نام میبرد: «هرچه تعداد tokenها در context window افزایش مییابد، توانایی مدل برای recall دقیق اطلاعات از آن context کاهش پیدا میکند» — context rot.1
آن جمله آخر ادعایی درباره رفتار است، یعنی میشود آن را بررسی کرد، و جدول بالای این صفحه همان بررسی است.
آن جدول چگونه ساخته شد
لینک به بخش: آن جدول چگونه ساخته شدچهل خط در برابر endpoint محلی از فصل 22 — یک سرور کوچک Python که Qwen2.5-0.5B-Instruct را روی CPU نگه میدارد و شکل chat-completions را صحبت میکند، تا حلقه TypeScript بماند و tensorها آن سوی port بمانند.
const DEPTHS = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1];
for (const d of DEPTHS) {
const slot = Math.round(d * (N - 1));
let hits = 0, other = 0;
for (let t = 0; t < TRIALS; t++) {
const recs = buildRecords(N, 1000 + t); // 25 unique tickets
const gold = recs[Math.floor(rng(7 + t)() * N)]; // a different one each trial
const rest = recs.filter((x) => x.ticket !== gold.ticket).slice(0, N - 1);
const lines = [...rest.slice(0, slot).map((x) => x.line),
gold.line,
...rest.slice(slot).map((x) => x.line)];
const r = await complete(prompt(lines, ask(gold.owner)), { maxTokens: 12 });
const said = /\d{4}/.exec(r.text)?.[0];
if (said === String(gold.ext)) hits++;
else if (said && recs.some((x) => String(x.ext) === said)) other++;
}
}شمارنده other همان چیزی است که یک نتیجه ناامیدکننده را به نتیجهای مفید تبدیل میکند: وقتی مدل اشتباه میکند، گم شده یا مطمئن است؟
پاسخ، مطمئن است. در هشت جایگاه غیر اول، 136 مورد از 205 پاسخ اشتباه، داخلی یک ticket دیگر بود — یک عدد چهاررقمی واقعی، با قالب درست، خواندهشده از خط اشتباه. در جایگاه 1 فقط یکی از پنج خطا چنین بود؛ در جایگاه 7، بیستویک مورد از بیستوشش.
همین تمایز در production مهم است. مدلی که میگوید نمیتوانم پیدایش کنم باگی است که متوجهش میشوید؛ مدلی که شماره ردیف کناری را برمیگرداند باگی است که ship میکنید، چون روی صفحه این دو یکسان به نظر میرسند. این همان شکستی است که فصل 19 citationهای قابلراستیآزمایی را علیه آن ساخت، با این تفاوت که از داخل prompt میآید نه از index.
فقط کجا نیست. چقدر هم هست.
لینک به بخش: فقط کجا نیست. چقدر هم هست.جایگاه یک محور است. طول محور دیگر است، و آزمودنش آسانتر: پاسخ را در میانه نگه دارید و فهرست را بزرگ کنید.
| رکوردها | prompt tokenها | hitها | نرخ | بازه 95٪ | خط اشتباه | هیچکدام |
|---|---|---|---|---|---|---|
| 1 | 97 | 18/20 | 90٪ | 70–97٪ | 0 | 2 |
| 3 | 159 | 11/20 | 55٪ | 34–74٪ | 9 | 0 |
| 8 | 315 | 3/20 | 15٪ | 5–36٪ | 17 | 0 |
| 20 | 695 | 2/20 | 10٪ | 3–30٪ | 16 | 2 |
| 40 | 1,324 | 3/20 | 15٪ | 5–36٪ | 15 | 2 |
| 80 | 2,587 | 1/20 | 5٪ | 1–24٪ | 18 | 1 |
| 140 | 4,477 | 2/20 | 10٪ | 3–30٪ | 18 | 0 |
یک رکورد و 97 token: 90٪. سه رکورد و 159 token: 55٪. هشت رکورد و 315 token: 15٪، و از آنجا تا 140 رکورد و 4,477 token پایین و تقریباً ثابت میماند. کل فروپاشی بین خط اول و هشتم یک فهرست رخ میدهد.
ستون آخر همه چیزهایی است که نه داخلی درستاند و نه داخلی رکوردی دیگر؛ وقتی فقط یک رکورد روی صفحه است، پاسخ اشتباه فقط همانجا میتواند بیفتد. دو خطا در یک رکورد ارزش گزارش کردن دارند، نه گرد کردن و حذف شدن، چون هیچکدام refusal نبود: یکی به فهرستی که تنها خطش 5805 بود، پاسخ 5806 داد. با 97 token و فقط یک candidate، این مدل هنوز در بیست بار، دو بار یک رقم را اشتباه کپی میکند، و این کفِ چیزی است که هرچیز دیگر نسبت به آن سنجیده میشود.
دو نتیجه دنبال میشود. context بزرگتر حق فرستادن بیشتر را میخرد، نه قطعیت خوانده شدن را: این مدل یک window با 32,768 token دارد و دامنه کاریاش، روی این کار، چند صد token است. و هیچ threshold، هیچ cliff، هیچ وضعیت «context full» وجود ندارد — افت از رکورد سوم در جریان است و تا هشتم کامل میشود، در یک درصد window. هرچه limit مربوط به context باشد، آن چیزی نیست که این را حکمرانی میکند.
معمولاً دو سازوکار پیشنهاد میشود. اولی همان حساب فصل 9 است، که Anthropic با همان واژههایی بیان میکند که این دوره به کار میبرد: مدلها «بر پایه معماری transformer هستند، که به هر token امکان میدهد در سراسر context کامل به هر token دیگر attention بدهد. نتیجه، n² رابطه دوتایی برای n token است».1 attention روی دنبالهای طولانیتر همان عملیات اعمالشده به مواد بیشتر نیست؛ یک بودجه ثابت از جرم احتمال است که میان رقیبهای بیشتر پخش میشود. دومی training است: مدلها دنبالههای کوتاه را بسیار بیشتر از دنبالههای بلند میبینند، پس الگوهای positional دوربرد کمتمرینترین بخش شبکهاند. این یک استدلال است، نه یک اندازهگیری، و این فصل نمیتواند آن را فیصله دهد.
آنچه فیصله یافته شکل ماجراست، و از 2023 چنین بوده است. Liu و همکاران پرسشپاسخ چندسندی و key-value retrieval را در خانوادهها و اندازههای مختلف مدل آزمودند و دریافتند که «عملکرد اغلب وقتی اطلاعات مرتبط در آغاز یا پایان input context رخ میدهد بیشینه است، و وقتی مدلها باید به اطلاعات مرتبط در میانه contextهای بلند دسترسی پیدا کنند بهطور معنادار افت میکند، حتی برای مدلهایی که صراحتاً long-context هستند».2 فصل 15 قانون جایگاه خود را از آن مقاله گرفت؛ فصل 19 از آن دلیل اینکه بیست chunk بازیابیشده میتواند بدتر از چهار تا امتیاز بگیرد را برداشت. شکل عملی این واقعیت تنها جملهای است که اینجا باید براساسش عمل کنید: اندازهگیری این موضوع روی مدل خودتان و با داده خودتان پنج دقیقه طول میکشد، و هیچ منحنی منتشرشدهای جای منحنی شما را نمیگیرد.
هیچکس نمیداند در window او چیست
لینک به بخش: هیچکس نمیداند در window او چیستاز یک تیم بپرسید چه چیزی context مربوط به agentشان را پر میکند و یک تخمین میگیرید، چون هیچ API پاسخ را برنمیگرداند: response به شما prompt_tokens میدهد، یک عدد برای همهاش.
میتوانید breakdown را با چهار شمارش و سه تفریق بازسازی کنید — کل prompt رندرشده، همان بدون tool definitionها، system message تنها با آنها و بدون آنها، و همه چیز با حذف tool resultها:
async function buckets(messages: Msg[]) {
const sys = messages.slice(0, 1);
const withoutResults = messages.filter((m) => m.role !== "tool");
const [total, sysWithTools, sysNoTools, noResults] = await Promise.all([
countPrompt(messages, CATALOGUE), // everything
countPrompt(sys, CATALOGUE), // system + scaffolding + schemas
countPrompt(sys), // system + scaffolding
countPrompt(withoutResults, CATALOGUE), // everything but tool output
]);
return {
system: sysNoTools,
tools: sysWithTools - sysNoTools,
toolResults: total - noResults,
conversation: total - sysWithTools - (total - noResults),
total,
};
}countPrompt پیش از tokenizing، chat template خود مدل را اعمال میکند، و این از چیزی که به نظر میرسد مهمتر است: متن شما آن چیزی نیست که شمرده میشود. role markerها، پیشدرآمد tool calling و رندر schema همگی tokenهایی هستند که برایشان پول میدهید و هرگز تایپ نکردهاید. فصل 7 یک tokenizer ساخت و فصل 16 با js-tiktoken شمارش کرد؛ اینجا شمارش از همان مدلی میآید که prompt را خواهد خواند، و این تنها شماری است که دقیقاً درست است.
حالا یک agent واقعی را از آن عبور دهید: چهل نوبت از بررسی یک incident، دوازده ابزار، و یک محیط عملیاتی ساختگی که log dumpها و سریهای metric واقعگرایانه برمیگرداند.
| turn | system | tool definitionها | conversation | tool resultها | کل prompt | input صورتحسابشده در این turn |
|---|---|---|---|---|---|---|
| 1 | 85 | 1,817 | 155 | 490 | 2,547 | 4,370 |
| 2 | 85 | 1,817 | 282 | 529 | 2,713 | 5,275 |
| 5 | 85 | 1,817 | 647 | 1,870 | 4,419 | 8,093 |
| 10 | 85 | 1,817 | 946 | 2,141 | 4,989 | 4,951 |
| 20 | 85 | 1,817 | 1,500 | 2,943 | 6,345 | 6,316 |
| 30 | 85 | 1,817 | 2,187 | 4,000 | 8,089 | 8,059 |
| 40 | 85 | 1,817 | 3,053 | 5,677 | 10,632 | 21,090 |
ردیف اول را در برابر آخرین ردیف بخوانید.
در turn 1، prompt برابر 2,547 token است و 71٪ آن tool definitionهاست. system prompt سه درصد است. آنچه کاربر تایپ کرده 6٪ است. agent هنوز هیچ کاری نکرده و همین حالا 1,817 token از JSON schema را حمل میکند.
تا turn 40، prompt برابر 10,632 token است و سهمها وارونه شدهاند: definitionها 17٪، conversation بیستونه درصد، tool resultها 53٪. output ابزار در turn 5 از definitionها پیشی گرفت؛ conversation تا turn 25 از آنها پیشی نگرفت، پس در شصت درصد اول session کاتالوگ ابزارها از هرچیزی که گفته شده بود بزرگتر بود.
بعد کل. در 57 model call، اجرا 370,291 input token برای context نهایی 10,632 صورتحساب شد — prompt آخر تقریباً سیوپنج بار پرداخت شده، همان درجهدوی فصل 16 با multiplier مربوط به agent روی آن. از آن 370,291، 103,569، یا 28٪ همه چیزِ صورتحسابشده، دوازده tool definition بودند، که در هر call عیناً و byte-identical دوباره فرستاده شدند.
یک tool definition چقدر هزینه دارد
لینک به بخش: یک tool definition چقدر هزینه داردکاتالوگ ابزار بزرگترین هزینه ثابت در یک agent است و نامرئی است، چون هرگز آن را نمیبینید: شما آرایهای از objectها را پاس میدهید و provider آن را برایتان داخل prompt رندر میکند. روی همان دوازده ابزار اندازهگیری شد:
system prompt + chat scaffolding, no tools: 85 tokens
all twelve definitions: 1,817 tokens
of which fixed tool-calling scaffolding: 126 tokens
three tools instead of twelve: 605 tokens
same twelve, one-sentence descriptions,
no parameter prose: 1,291 tokens (-29 %)به ازای هر ابزار، هزینه marginal از 80 token برای get_current_time شروع میشود، که یک string میگیرد، تا 263 برای search_tickets، که چهار parameter با یک enum و برای هرکدام یک جمله راهنما میگیرد. این همان نرخ تبدیلی است که پشت توصیه مرکزی فصل 18 قرار دارد که description همان API است: یک description خوب برای باقی عمر agent، در هر request حدود صد token هزینه دارد. سه پیامد.
ابزاری که استفاده نمیکنید هم صورتحساب میشود. agent از دوازده ابزار، هفت تا را call کرد. پنج تای دیگر در هرکدام از 57 request، 697 token هزینه داشتند — در مجموع 39,729، بیش از یکدهم همه چیزی که اجرا بابت آن صورتحساب شد، برای قابلیتهایی که هرگز لمس نکرد. یکی از آن پنج مورد تیزترین جزئیات trace را حمل میکند: مدل سه بار تلاش کرد read_log را call کند، که وجود ندارد. ابزاری که میخواست search_logs بود، دومین definition گران در کاتالوگ با 237 token. مدل 57 بار هزینه آن definition را پرداخت، هرگز از آن استفاده نکرد، و هرگز نامش را پیدا نکرد.
کوتاه کردن نثر ارزانترین بهینهسازی موجود است، و یک trade-off است. کوتاه کردن descriptionها به یک جمله و حذف documentation مربوط به parameterها، 526 token در هر call ذخیره کرد، 29 درصد، بدون دستزدن به یک خط منطق — و باعث شد مدل ابزارها را بدتر call کند، همان چیزی که فصل 18 اندازه گرفت. نکته این است که هر دو سوی آن trade-off حالا در یک واحدند.
در مقیاسی، اصلاً فرستادن definitionها دیگر منطقی نیست. Anthropic در نوامبر 2025 برایش عدد گذاشت: مجموعه بزرگی از serverهای متصل یعنی پردازش «صدها هزار token» از definitionها پیش از اینکه request خوانده شود، و جایگزین کردن آن با اجرای code — یعنی agent فقط definitionهایی را کشف و load کند که نیاز دارد — «token usage را از 150,000 token به 2,000 token کاهش میدهد، صرفهجویی زمانی و هزینهای 98.7٪».3 همان ایده بقیه این فصل، اعمالشده به schemaها بهجای history: index را نگه دارید، entry را on demand resolve کنید.
شکستن عمدی آن
لینک به بخش: شکستن عمدی آندو چیز در آن transcript چهلنوبتی کاشته شد. در turn 2، پیش از هر کار واقعی، کاربر یک قانون ثابت اعلام میکند: هر ticketی که باز میکنی باید زیر شماره کارمندی من، 4417، ثبت شود. در turn 19، وسط incident، یک واقعیت: shard آسیبدیده pay-shard-7 است، تأییدشده توسط تیم payments. در turn 40 کاربر از agent میخواهد incident ticket را باز کند، که به هر دو نیاز دارد. هر probe در شش عبارتبندی متفاوت پرسیده و از شش نمرهگذاری میشود — greedy decoding deterministic است، پس یک call یک بله یا نه تکرارناپذیر میدهد و شش تا یک نرخ میدهد.
سپس transcript زیر هفت context policy replay میشود. عمداً replay میشود نه re-run: پیامها، tool callها و tool resultها در هر هفت مورد byte-identical هستند، پس تنها متغیر این است که هر policy چه چیزی را برای نگهداشتن انتخاب کرد. فصل 16 نشان داد چرا sliding window از نظر اقتصادی حرکت بدی است، چون prefix قابل cache را نابود میکند. اینجا میبینید با رفتار چه میکند:
| context policy | input tokenها در 40 turn | prompt در turn 40 | قانون turn 2 | واقعیت turn 19 |
|---|---|---|---|---|
| full history | 370,291 | 10,632 | 6/6 | 5/6 |
| sliding window، آخرین 12 message | 157,578 | 2,922 | 5/6 | 0/6 |
| حذف tool resultهای قدیمیتر از 4 turn | 243,445 | 6,311 | 6/6 | 3/6 |
| compaction هر 6 turn | 195,515 | 3,220 | 6/6 | 0/6 |
| compaction بههمراه یادداشتهای نوشتهشده توسط مدل | 200,849 | 3,286 | 6/6 | 0/6 |
| pin کردن turnهای خود کاربر، در ابتدا | 168,550 | 3,559 | 6/6 | 5/6 |
| pin کردن turnهای خود کاربر، در انتها | 168,835 | 3,564 | 6/6 | 6/6 |
| کنترل: دو turn و هیچچیز دیگر | — | 1,981 | 6/6 | 6/6 |
ردیفهای compaction شامل هزینه compact کردن هم هستند: 18,581 input token برای هفت summary و 3,392 دیگر برای note-taker. ردیف کنترل آنجاست تا صفر بهعنوان صفر خوانده شود — با فقط همان دو پیام در promptی 1,981-token، این مدل هر دو probe را کامل پاسخ میدهد، پس هیچ ردیفی به این دلیل نیست که کار زیادی سخت بوده.
full history به خاطر میسپارد، و گرانترین چیز روی جدول است: 370,291 input token برای sessionای که محتوای durable آن دو جمله است.
این به پرسشی پاسخ میدهد که آغاز متن باز گذاشت. چرا یک transcript با 10,632 token واقعیتی را نگه میدارد که یک فهرست 853-token از دست میدهد؟ چون طول متغیر اشتباهی است. فهرست بیستوپنج داخلی چهاررقمی را در بیستوپنج جمله یکسان نگه میدارد — بیستوچهار decoy تقریباً کامل برای همان چیزی که میخواهید. transcript دقیقاً یک شماره کارمندی و یک نام shard دارد. Context rot پیش از آنکه حجم باشد، interference است، و به همین دلیل 136 مورد از 205 پاسخ اشتباه بالا مقدار یک همسایه بود. پرسش مفید درباره window این نیست که چقدر بلند است؛ این است که چند چیز داخلش شبیه پاسخاند.
sliding window پنجاهوهفت درصد ارزانتر است و incident را از دست داده. شماره کارمندی فقط چون agent آن را در turnهای اخیر تکرار کرده بود زنده میماند. shard که یکبار در turn 19 گفته شد، در آخرین دوازده message نیست — و مدل هم این را نمیگوید. شش بار که از آن پرسیده شد پاسخ داد «shard پرداخت آسیبدیده shard 4417 است»، بهسمت شماره کارمندی دست دراز کرد، تنها identifier دیگر باقیمانده در window آن، و دو بار «pool»، که از string pool_exhausted در یک log line برداشته شده بود.
compaction ارزان است و همان fact را از دست داد. هفت summary، نوشتهشده توسط مدل زیر دستور صریح برای نگهداشتن identifierها، عددها، دستورهای ثابت و پرسشهای باز، و pay-shard-7 در هیچیک از مواردی که مهم بود نبود؛ شش حدس shard 1، pay_shard_1 و pool بودند. compaction با صدای بلند fail نمیشود. یک session روان، پذیرفتنی و بسیار کوتاهتر تولید میکند که بیسروصدا یک خط را انداخته است.
سه ردیف روی واقعیت turn 19 امتیاز 0/6 گرفتند — sliding window، compaction و compaction با note. هجده پاسخ اشتباه میان آنها، و حتی یکی از آنها «نمیدانم» نبود.
بعد ردیفی که باید خجالتآور باشد. نگهداشتن چهل message خود کاربر بهصورت verbatim، بهعلاوه چهار turn آخر بهطور کامل و هیچچیز دیگر، 168,550 token هزینه دارد — 54٪ کمتر از full history — و هر دو probe را بهاندازه full history یا بهتر پاسخ میدهد. نه summariser، نه note-taker، نه مدل دوم: فقط یک filter روی role === "user". کلمات کاربر ارزانترین tokenهای پرارزش در window یک agent هستند، و بیشتر طراحیها آنها را همراه با بقیه چیزها دور میاندازند.
دو ردیف آخر همان جدول آغازیناند، داخل agent. همان block pinشده، جابهجا از system message به انتهای prompt: 5/6 به 6/6 تبدیل میشود. روی شش آزمایش این تفاوت معنادار نیست و چنین هم عرضه نمیشود — فقط یادآوری میکند که کجا پارامتری است که چه بدانید چه ندانید، دارید تنظیمش میکنید.
چهار راه برای خرج کردن window کمتر
لینک به بخش: چهار راه برای خرج کردن window کمترچهار راهبرد زیر متعلق به Anthropic هستند، به همان ترتیب، هرچند فقط سه مورد آخر فهرست long-horizon آن است.1 هر چهار مورد variationهایی روی یک دستورند: چیزی را که میتوانید fetch کنید حمل نکنید، و چیزی را که میتوانید فشرده حمل کنید raw حمل نکنید.
retrieval درستبهموقع
لینک به بخش: retrieval درستبهموقعمحتوا را از پیش load نکنید. identifierها را نگه دارید — یک file path، یک query، یک ticket number، یک tool name و argumentهایش — و هنگام نیاز resolveشان کنید. بزرگترین bucket در agent بالا output ابزاری است که یکبار خوانده شد، یکبار استفاده شد و بعد سی turn دیگر حمل شد. جایگزینی هر result قدیمیتر از چهار turn با stubای که بگوید چه بوده و چگونه میتوان آن را برگرداند، شش خط است:
const elide: Policy = (h) => [SYSTEM, ...h.flatMap((turn, ti) =>
turn.map((m) => (ti < h.length - 4 && m.role === "tool"
? { role: "tool", name: m.name,
content: `[${m.name} result from turn ${ti + 1}, ${m.content.length} chars, ` +
`elided; call ${m.name} again with the same arguments to re-read it]` }
: m)))];این فصل 19 است با corpusی که با گذشته خود agent جایگزین شده. machinery مربوط به retrieval همین حالا هم آنجاست — همان کاتالوگ ابزار است.
Compaction
لینک به بخش: Compactionوقتی transcript از thresholdی عبور کرد، قدیمیترین بخش آن را با summary نوشتهشده توسط مدل جایگزین کنید و ادامه دهید. promptی که summary را مینویسد کل طراحی است، و همانجاست که compaction برده یا باخته میشود: identifierها، عددها، دستورهای ثابت و پرسشهای باز را نگه دار؛ تعارفات و tool outputی را که میتوانی دوباره fetch کنی حذف کن.
compaction ذاتاً lossy است، چیزی که از دست میدهد به نمایندگی از شما توسط یک مدل انتخاب میشود، و وقتی مدل اشتباه انتخاب میکند هیچچیز error نمیدهد. رایگان هم نیست: هر compaction یک call اضافه است که input آن همان چیزی است که دارد compact میشود.
یادداشتبرداری ساختاریافته
لینک به بخش: یادداشتبرداری ساختاریافتهیک store کوچک بیرون از context نگه دارید و در هر turn آن را کامل دوباره inject کنید. برخلاف summary، append-only و addressable است: قانونی که در turn 2 نوشته شده در turn 400 همچنان verbatim آنجاست. نسخه اندازهگیریشده اینجا بعد از هر user message از مدل میپرسد آیا چیزی durable در آن هست:
const r = await complete([
{ role: "system", content:
"You keep a durable note file for a support session. Given one user message, " +
"output one short note ONLY if it states a standing rule, an identifier or a fact " +
"that must survive the rest of the session. Otherwise output exactly NONE." },
{ role: "user", content: `Turn ${i + 1}: ${user}` },
], { maxTokens: 40 });
if (!/^none\b/i.test(r.text.trim())) notes.push(`turn ${i + 1}: ${r.text.trim()}`);این راهبرد بالاترین سقف را اینجا دارد، و همان است که در اندازهگیری fail شد. در چهل user message، note-taker سه note نگه داشت و هیچیک از دو مورد مهم را نه: یک خط توصیه runbook، اعلام اینکه session در حال پایان است، و Europe/Madrid اکنون 13:45 است — زمانی که خودش اختراع کرده بود، چون ابزاری که داشت paraphrase میکرد 09:52 UTC برگردانده بود. note-taker یک مدل است، و هرچیزی در این فصل درباره آن هم صدق میکند.
Sub-agentها
لینک به بخش: Sub-agentهابه یک کار متمرکز window خودش را بدهید — system prompt خودش، کاتالوگ کوچک خودش، هیچکدام از history والد — و بهجای transcript یک پاسخ کوتاه برگردانید. فصل 23 یکی را پشت tool schema گذاشت و قبض را برای اینجا باقی گذاشت؛ قبض این است که پاسخ فرزند تنها بخشی از window فرزند است که والد هرگز بابتش پول میدهد.
sub-agent در جدول بالا نیست چون چهل turn اجرا نمیشود: یکبار اجرا میشود، در windowی که کسی برایش scope کرده. با دادن system prompt، turnهای 17 تا 19 و هیچچیز دیگر — 2,737 token — probe مربوط به shard را 6/6 پاسخ داد، بهتر از هر policy در جدول، و probe مربوط به کارمند را 0/6، چون آن شماره در سه turnی که به آن داده شده بود نبود.
این یعنی sub-agentها در دو عدد: یک window تمیز intelligence نیست، scope است، و scoping از پیش توسط کدی انجام میشود که همین حالا هم باید بداند کدام turnها مهماند. یک چیز دیگر در آن پاسخها ارزش نگهداشتن دارد. این تنها policy بود که بهجای اختراع کردن، پاسخ داد «None available». مدلی با context کوچک و coherent میداند چه چیزی را ندارد؛ مدلی با context بزرگ و noisy نمیداند.
سه حافظه
لینک به بخش: سه حافظهتقریباً هر گفتوگوی گیجکننده درباره memory مربوط به agent، سه سازوکار است که یک کلمه پوشیدهاند. lifetime، owner و failure modeهای متفاوتی دارند، و سیستمی که آنها را در یک جا نگه میدارد مشکلی دارد که هنوز متوجهش نشده است.
| conversation history | retrieval | persistent user memory | |
|---|---|---|---|
| نگه میدارد | آنچه در این session گفته شد | سندهایی که مالکشان هستید | واقعیتهایی درباره یک شخص |
| زندگی میکند | یک session | تا re-index شدن | در همه sessionها، برای همیشه |
| نوشته میشود توسط | حلقه، خودکار | ingestion pipeline | مدل، عمداً |
| وارد prompt میشود | کامل، در هر call | چهار passage، وقتی query match میشود | کامل، در هر call |
| fail میشود با | رشد کردن تا وقتی rot شود | retrieval مربوط به chunk اشتباه | به خاطر سپردن چیزی اشتباه درباره شما |
| ساختهشده در | فصل 23 | فصل 19 | این فصل |
چارچوب دانشگاهی از CoALA میآید، که language agentها را حول «مولفههای memory ماژولار» سازمان میدهد و working memory را از storeهای episodic، semantic و procedural جدا میکند.4 MemGPT همین ایده را literal میگیرد، با قرض گرفتن virtual memory از operating systemها: یک لایه سریع داخل window، یک لایه کند بیرون آن، و خود مدل که داده را با function callها میانشان جابهجا میکند.5 هر دو پرسشی را تحمیل میکنند که product در هر صورت باید پاسخ دهد — نه چقدر میتوانم نگه دارم، بلکه این به کدام store تعلق دارد، و کی expire میشود.
آزمون عملی برای هر fact یک پرسش است: فردا چه چیزی هنوز باید true باشد؟ یک tool result از turn 12، هیچچیز. summary مربوط به session، تا پایان session. اینکه شماره کارمندی کاربر 4417 است، تا وقتی شغلش را عوض کند. سه پاسخ، سه store.
بعد به کجا میرود
لینک به بخش: بعد به کجا میرودحالا میتوانید اندازه بگیرید در یک window چه هست، تصمیم بگیرید چه چیزی در آن بماند، و تفاوت agentی را که چیزی را فراموش کرده با agentی که آن را حمل میکرده اما نگاه نکرده تشخیص دهید.
آخرین مورد از چهار راهبرد، همان است که اینجا جا نمیشود. sub-agent یک context policy نیست، agent دوم است، و لحظهای که دو تا باشند باید تصمیم بگیرید چه چیزی میانشان پاس داده میشود و کدام در charge است. فصل 25 همین است: پنج الگوی orchestration و اینکه نام هرکدام واقعاً از کجا آمده، دو توپولوژیای که با هم قاطی میشوند — پرسیدن از sub-agent و گرفتن پاسخ در برابر تحویل دادن conversation به آن و پس نگرفتنش — و یافته اندازهگیریشده که روی کاری که قیمتگذاری میکند، آرایش سادهتر میبرد — و بعد آزمونی برای اینکه چه زمانی دیگر نمیبرد.
همچنین دقیقاً همان چیزی را inherit میکند که این فصل همین حالا اندازه گرفت. sub-agent یک summary برمیگرداند. summary یک compaction است که شما ننوشتهاید، تولیدشده توسط مدلی که window آن را نمیبینید، و والد راهی ندارد که good one را از confident wrong one تشخیص دهد — همان تمایزی که بالای این صفحه 84٪ را از 19٪ جدا کرد، و هجده fact گمشده را به هجده مورد اختراعی تبدیل کرد. پس: وقتی sub-agent اشتباه میکند، parent دقیقاً چه چیزی را میتواند نگاه کند؟
منابع و روش
لینک به بخش: منابع و روشهر عدد اینجا روی همین ماشین تولید شد و هیچکدام تخمین نیست. مدل Qwen2.5-0.5B-Instruct در float32 روی CPU با greedy decoding است، که over loopback توسط endpoint کوچک Python سرو میشود؛ endpointی که شکل chat-completions را صحبت میکند و route شمارش token را expose میکند — همان seam فصل 14 فصل 14، tensorها سمت Python و حلقه سمت TypeScript — پس هر count، tokenizer خود همان مدل است که روی chat template خودش اعمال شده. جدول position شامل 288 call است، نه جایگاه در سیودو آزمایش با یک ticket متفاوت در هر آزمایش؛ جدول length شامل 140 call است؛ agent run شامل 57 model call طی 43 دقیقه wall clock است؛ جدول policy همان یک transcript است که زیر هفت policy replay شده. بازهها Wilson هستند، از فصل 4. هیچ paid APIای call نشد، و به همین دلیل در فصل حتی یک price هم نیست: token countها دقیقاند و rateهایی که در آنها ضرب میکنید متعلق به فصل 16 هستند.
ارجاعات
لینک به بخش: ارجاعات-
Anthropic، Effective context engineering for AI agents، 29 سپتامبر 2025،
anthropic.com/engineering/effective-context-engineering-for-ai-agents، خواندهشده در 7 سپتامبر 2026. منبع دو definition نقلشده در ابتدا، «attention budget» و گزاره اینکه هر token جدید آن را تخلیه میکند، توصیف context rot، framing مربوط به رابطههای دوتایی n²، و راهبردهایی که ستون فقرات این فصل هستند. سه مورد از آنها فهرست long-horizon آن است — compaction، structured note-taking و multi-agent architectureها؛ just-in-time retrieval زودتر در همان article، زیر context retrieval و agentic search میآید، و اینجا با آنها گروهبندی شده است. ↩ ↩2 ↩3 ↩4 -
Liu, N. F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F. and Liang, P. Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172 (v1 ژوئیه 2023، v3 نوامبر 2023). در فصلهای 15، 16 و 19 cite شده و اینجا اندازهگیری شده است. جمله نقلشده از abstract است؛ دو task مقاله multi-document question answering و key-value retrieval هستند، و یافته آن مبنی بر اینکه اثر در مدلهایی که صراحتاً long-context هستند هم persist میکند همان بخشی است که برای تصمیم product مهم است. ↩
-
Anthropic، Code execution with MCP: building more efficient agents، 4 نوامبر 2025،
anthropic.com/engineering/code-execution-with-mcp، خواندهشده در 7 سپتامبر 2026. منبع کاهش 150,000 به 2,000 token و عدد 98.7٪، و مشاهده اینکه tool definitionهایی که upfront load میشوند پیش از خوانده شدن request، context را اشغال میکنند. ↩ -
Sumers, T. R., Yao, S., Narasimhan, K. and Griffiths, T. L. Cognitive Architectures for Language Agents. arXiv:2309.02427 (2023). language agentها را حول «modular memory components, a structured action space to interact with internal memory and external environments, and a generalized decision-making process to choose actions» سازمان میدهد، و memory را به working، episodic، semantic و procedural تقسیم میکند. فصل 22 از taxonomy آن برای learning agent استفاده کرد؛ جدول سهstore بالا سایه عملی آن است. ↩
-
Packer, C., Wooders, S., Lin, K., Fang, V., Patil, S. G., Stoica, I. and Gonzalez, J. E. MemGPT: Towards LLMs as Operating Systems. arXiv:2310.08560 (اکتبر 2023). «virtual context management, a technique drawing inspiration from hierarchical memory systems in traditional operating systems» را پیشنهاد میکند، با خود مدل که داده را میان یک لایه سریع داخل window و یک لایه کند بیرون آن جابهجا میکند. روشنترین بیان از اینکه چرا window یک cache است نه memory. ↩