کنترل هزینه عامل هوش مصنوعی روی VPS همیشهروشن
عامل بدون ناظر هر حلقه را بیصدا اجرا میکند. با سقف توکن %%C3%%، محدودیت تکرار حلقه، کش پرامپت و ثبت اعداد مصرف هر پاسخ از افزایش هزینه جلوگیری کنید.
چگونه یک عامل هوش مصنوعی همیشهروشن را از تحمیل هزینههای سنگین بازداریم
کنترل هزینه عامل هوش مصنوعی روی یک VPS (سرور خصوصی مجازی) به سقفهایی مربوط میشود که پیش از شروع به کار عامل تعیین میکنید، زیرا هیچکس در حین اجرا، مصرف را نظارت نمیکند. هر پاسخ را با max_tokens محدود کنید، تعداد تکرار حلقه را در کد خودتان مقید سازید، بخشی از پرامپت که هرگز تغییر نمیکند را کش کنید، و اعداد مصرف هر پاسخ را ثبت کنید تا ببینید کدام کار هزینه میبرد. اجاره سرور یک قیمت ثابت ماهانه است. هزینه API مدل بر اساس هر توکن محاسبه میشود، و یک حلقه بدون نظارت در مصرف بیصدای توکنها بسیار خوب عمل میکند.
این مطلب، عاملی را فرض میگیرد که از پیش وجود دارد و از روی دستگاهی که متعلق به شماست، Messages API را فراخوانی میکند. ساخت یک عامل هوش مصنوعی با کلود روی یک VPS خود سازوکار را پوشش میدهد.
چرا یک عامل بدون نظارت، شکل هزینهای متفاوتی دارد
یک نشست تعاملی، یک انسان درون خود دارد. وقتی مدل مسیر اشتباهی میرود یا یک لاگ 40,000 خطی را میخواند، فرد ناظر آن را متوقف میکند. یک عامل بدون نظارت چنین ترمزی ندارد: تا پایان حلقه اجرا میشود، سپس یک زمانسنج دوباره آن را شروع میکند.
تناوب، ضریبی است که افراد نادیده میگیرند. یک کار با زمانبندی پنجدقیقهای، 288 بار در روز و حدود 8,640 بار در ماه اجرا میشود. هزینهای که یک اجرا دارد، همان عددی است که ضرب میکنید. بسیاری از عاملهای «همیشه روشن» نیازی به روشن بودن ندارند. آنها باید در عرض چند دقیقه پاسخ دهند، که این یک زمانبندی است.
یک عامل همچنین هزینه چیزهایی را میپردازد که یک پنجره چت نمیپردازد.
- تعاریف ابزار در هر درخواست همراه میشوند. اعلان سیستمی استفاده از ابزار، روی Claude Opus 4.8 با
tool_choiceازautoیاnone، 290 توکن و باanyیاtool، 410 توکن هزینه دارد. ابزار bash نیز 325 توکن دیگر اضافه میکند. هر سرور MCP که متصل میکنید، طرحوارههای خود را به آن وزن اضافه میکند، MCP همان پروتکل زمینه مدل است. - نتایج ابزار، توکن ورودی هستند. فرمانی که 8,000 خط چاپ میکند، 8,000 خط را وارد درخواست بعدی و هر درخواست پس از آن در همان نوبت میکند.
- صفحات واکشیشده، توکن ورودی هستند. یک صفحه وب متوسط 10 کیلوبایتی تقریباً 2,500 توکن و یک PDF تحقیقاتی 500 کیلوبایتی تقریباً 125,000 توکن است.
max_content_tokensفقط موارد متنی را کوتاه میکند، زیرا «برای محتوای متنی اعمال میشود، نه برای محتوای باینری مانند PDFها». در عوض، یک PDF را باmax_usesوallowed_domainsمحدود کنید. - جستجوی وب به ازای هر جستجو قیمتگذاری میشود، به ازای هر 1,000 جستجو 10 دلار، صرفنظر از تعداد نتایج برگشتی. جستجویی که با خطا مواجه شود، هزینهای ندارد.
هیچکدام از اینها برای یک بار گران نیست. همه اینها برای 8,640 بار گران است.
سقفهای سخت و سقفهای نرم مسائل متفاوتی را حل میکنند
max_tokens اعمال میشود. این یک سقف سخت برای خروجی کل یک درخواست است، شامل متن تفکر و پاسخ با هم. کلود هرگز فراتر از آن تولید نمیکند و مدل نمیتواند این عدد را ببیند. رسیدن به آن باعث stop_reason: "max_tokens" و یک پاسخ ناقص میشود. نکتهای که برای عاملها مهم است: هر درخواست در یک حلقهٔ استفاده از ابزار max_tokens خود را دارد، بنابراین یک پاسخ را محدود میکند نه کل وظیفه را. ده فراخوانی ابزار با 4,000 توکن، یک سقف 40,000 توکنی برای نوبت است.
بودجهٔ وظیفه مشورتی است. task_budget درون output_config قرار میگیرد و به مدل میگوید چه تعداد توکن برای کل حلقهٔ عاملی در اختیار دارد، با احتساب تفکر، فراخوانیهای ابزار، نتایج ابزار و خروجی.
resp = client.beta.messages.create(
model="claude-opus-4-8",
max_tokens=4096,
betas=["task-budgets-2026-03-13"],
output_config={"task_budget": {"type": "tokens", "total": 64000}},
messages=messages,
)"بودجههای وظیفه یک راهنمایی نرم هستند، نه یک سقف سخت." کلود ممکن است در میانهٔ یک اقدام از آن فراتر رود و محدودیت اعمالشده بر خروجی همچنان max_tokens است. "شمارش معکوس فقط برای مدل قابل مشاهده است" و پاسخها هیچ فیلدی برای بودجهٔ باقیمانده ندارند. حداقل task_budget.total پذیرفتهشده 20,000 توکن است و مقدار کمتر خطای 400 برمیگرداند. بودجهای که برای کار بسیار کوچک باشد رفتاری شبیه به رد کردن ایجاد میکند، بنابراین مدل دامنهٔ وظیفه را کاهش میدهد یا زود متوقف میشود.
یک جزئیات به جای صرفهجویی در هزینه، هزینه ایجاد میکند. اگر کلاینت شما task_budget.remaining را در هر درخواست بعدی کاهش دهد، مقدار تغییرکرده هر پیشوند کششدهای که شامل آن باشد را بیاعتبار میکند. آن را یک بار، در اولین درخواست تنظیم کنید.
بودجههای وظیفه روی Claude Fable 5، Claude Opus 4.8 و Claude Opus 4.7 در مرحلهٔ بتا هستند. Claude Sonnet 5 و Claude Haiku 4.5 به عنوان Not supported فهرست شدهاند و بودجههای وظیفه برای Claude Code اعمال نمیشوند، بنابراین یک نشست Claude Code جدا شده در tmux به بهداشت نشست متکی است.
سقف سوم در کنسول کلود قرار دارد: به عامل فضای کاری خودش را بدهید، سپس یک محدودیت هزینهٔ ماهانه و محدودیتهای نرخ در دقیقه روی آن تنظیم کنید. "شما نمیتوانید روی فضای کاری پیشفرض محدودیت تنظیم کنید" و "محدودیتهای سطح سازمان همیشه اعمال میشوند، حتی اگر مجموع محدودیتهای فضای کاری بیشتر شود". اعلانهای هزینه اضافه کنید تا یک آستانه پیش از آنکه سقف عمل کند به شما هشدار دهد.
انتخاب مدل بهازای هر کار و اینکه تلاش واقعاً چه چیزی را تغییر میدهد
انتخاب مدل تصمیمی است که بهازای هر کار گرفته میشود. تا ژوئیه 2026، بهازای هر میلیون توکن، ورودی و سپس خروجی: Claude Fable 5 با 10 و 50 دلار، Claude Opus 4.8 و Opus 4.7 با 5 و 25 دلار، Claude Sonnet 5 با 3 و 15 دلار، Claude Haiku 4.5 با 1 و 5 دلار. Sonnet 5 در حال حاضر زیر قیمت رسمی خود قرار دارد، زیرا «قیمتگذاری مقدماتی 2/10 دلار بهازای هر میلیون توکن ورودی/خروجی تا 31 اوت 2026 معتبر است». مرحلهای که فقط خطوط لاگ را طبقهبندی میکند نیازی به Opus ندارد.
تلاش اهرم دوم است. output_config.effort مقادیر low, medium, high, xhigh و max را میپذیرد و مقدار پیشفرض high است، بنابراین تنظیم صریح high همانند حذف آن است. تلاش پایینتر چیزی فراتر از طول استدلال را کاهش میدهد: مستندات میگوید که این کار باعث میشود Claude فراخوانیهای ابزاری کمتری انجام دهد و عملیاتها را در یکدیگر ادغام کند. در یک عامل، این صرفهجویی بزرگتری است، زیرا یک فراخوانی ابزاری حذفشده، یک درخواست کامل است که هرگز رخ نمیدهد.
دام این است که تلاش با کش مقابله میکند. تغییر مقدار بین درخواستها، کشسازی پرامپت را بیاعتبار میکند. در مثال مستند، درخواست 2 مقدار cache_read_input_tokens: 3546 را گزارش کرد؛ درخواست 3، با تغییر تلاش از بالا به متوسط، cache_creation_input_tokens برابر با 3546 و cache_read_input_tokens برابر با 0 را گزارش کرد. بنابراین تلاش را در بین بارهای کاری مختلف تغییر دهید، هرگز در داخل یک مکالمه کششده. برای هدایت عمق بدون شکستن کش، این کار را در پرامپت انجام دهید: خطی مانند «مستقیماً پاسخ بده بدون تأمل.» در جدیدترین پیام کاربر، نقاط شکست قبلی را دستنخورده باقی میگذارد.
توکنهای تفکر با نرخهای خروجی صورتحساب میشوند و در سقف max_tokens محاسبه میگردند، به همین دلیل است که یک پاسخ کوتاهشده اغلب به معنای آن است که تفکر بودجه را بلعیده است. برای مشاهده عدد، usage.output_tokens_details.thinking_tokens را بخوانید. چه چیزی واقعاً صورتحساب توکن کلود را پر میکند کنتور را باز میکند.
پیشوند پایدار را کش کنید و از خراب شدن تصادفی آن جلوگیری کنید
هزینهٔ یک نوشتن کش 1.25 برابر قیمت پایهٔ ورودی برای کش پنجدقیقهای و 2 برابر برای کش یکساعته است. هزینهٔ یک خواندن کش 0.1 برابر است، بنابراین «کش کردن پس از تنها یک بار خواندن برای مدت 5 دقیقه (نوشتن 1.25x)، یا پس از دو بار خواندن برای مدت 1 ساعت (نوشتن 2x) جواب میدهد».
یک خط توضیح میدهد که چرا این برای یک عامل همیشهروشن مناسب است: «هر بار که محتوای کششده استفاده میشود، کش بدون هزینهٔ اضافی تازهسازی میشود». یک کار که هر دو دقیقه یکبار روی کش پنجدقیقهای اجرا میشود، پیشوند خود را تمام روز با یک نوشتن گرم نگه میدارد.
سه راه برای از دست دادن کش بدون اینکه متوجه شوید.
پیشوندی که تغییر میکند. «پیشوندهای کش به ترتیب زیر ایجاد میشوند: tools, system, سپس messages.» هر تغییر بایتی که زودتر در این ترتیب رخ دهد، همهٔ موارد بعد از آن را بیاعتبار میکند، و ویرایش تعاریف ابزار کل کش را بیاعتبار میکند. آسیب کلاسیکی که خود فرد وارد میکند، یک برچسب زمان یا شناسهٔ اجرا در اعلان سیستم است: آنگاه هر درخواست پیشوند متفاوتی دارد، یک ورودی تازه با 1.25x مینویسد، و چیزی بازخوانی نمیکند. نشانهٔ آن usage.cache_read_input_tokens برابر با 0 در فراخوانیهای بهظاهر یکسان است. متن متغیر را به جدیدترین پیام کاربر منتقل کنید.
پیشوندی که خیلی کوتاه است. هر مدل یک حداقل طول قابل کش شدن دارد، و زیر آن مقدار، درخواست بدون کش شدن پردازش میشود و «هیچ خطایی برگردانده نمیشود». این ارقام شامل 1,024 توکن در Claude Opus 4.8 و Claude Sonnet 5، و 4,096 توکن در Claude Haiku 4.5 است، بنابراین انتقال یک کار از Sonnet به Haiku میتواند کش شدن را بیصدا خاموش کند.
مکالمهای که از پنجرهٔ بازگشت به عقب فراتر میرود. «پنجرهٔ بازگشت به عقب 20 بلوک است.» سیستم حداکثر 20 موقعیت را برای هر نقطهٔ شکست بررسی میکند، سپس متوقف میشود. در مثال مستندشده، یک نوبت شامل 35 بلوک با یک نقطهٔ شکست روی بلوک 35، بلوکهای 35 تا 16 را بررسی میکند، و ورودی نوبت قبلی در بلوک 15 خارج از پنجره قرار میگیرد، بنابراین هیچ تطابقی وجود ندارد. عاملی که در هر نوبت چندین بلوک استفاده از ابزار و نتیجهٔ ابزار اضافه میکند، در دو یا سه نوبت از 20 عبور میکند. شما برای هر درخواست چهار نقطهٔ شکست دارید، بنابراین یکی را صرف پیامهای اخیر کنید.
هر چیزی که میتواند منتظر بماند را به Batches API بفرستید
"تمام مصرف با 50٪ قیمتهای استاندارد API محاسبه میشود"، هم برای ورودی و هم برای خروجی. پردازش دستهای ناهمگام است، "و بیشتر دستهها در کمتر از 1 ساعت تکمیل میشوند"، با ارائه نتایج زمانی که هر درخواست تمام شده باشد یا پس از 24 ساعت، هرکدام زودتر فرا برسد. این یک وضعیت معمول است، نه تضمینشده.
processing_status را بررسی کنید تا زمانی که وضعیت ended را نشان دهد. درخواستهایی که errored, canceled یا expired برمیگردانند، هزینهای ندارند. یک نکته احتیاطی اگر به سقف هزینه متکی هستید: "دستهها ممکن است کمی از محدودیت هزینه تعیینشده برای Workspace شما فراتر بروند."
تخفیفها تجمیع میشوند، و از آنجا که یک دسته ممکن است بیش از پنج دقیقه طول بکشد، مستندات، کش یکساعته را برای دستههایی که context مشترک دارند توصیه میکند. پس کار را تقسیم کنید: هر چیزی که یک شخص یا یک webhook منتظر آن است در مسیر زنده باقی میماند، و یک خلاصه شبانه یا طبقهبندی لاگهای دیروز با نصف قیمت به یک دسته میرود.
هر فیلد مصرفی پاسخ را در ذخیرهگاه خودتان ثبت کنید
نمیتوانید هزینهای را که هرگز ثبت نکردهاید به حساب بیاورید. هر پاسخ به شما میگوید چه هزینهای داشته است.
u = resp.usage
row = {
"job": job_name,
"model": resp.model,
"uncached_input": u.input_tokens,
"cache_write": u.cache_creation_input_tokens,
"cache_read": u.cache_read_input_tokens,
"output": u.output_tokens,
"stop_reason": resp.stop_reason,
}برای هر فراخوانی API یک ردیف به یک فایل JSON-lines اضافه کنید و آن را با نام کار خود برچسبگذاری کنید. یک هفته بعد میتوانید بگویید کدام کار واقعاً هزینه داشته و کدام فقط مشغول به نظر میرسیده است. مراقب cache_read باشید: یک ستون پر از صفر رایجترین باگ هزینه در یک عامل خودمیزبان است.
یکی از فیلدها بهراحتی اشتباه خوانده میشود. input_tokens فقط توکنهای پس از آخرین نقطهٔ شکست کش را میشمارد، بنابراین اندازهٔ واقعی پرامپت total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens است. عاملی که روی یک پرامپت بزرگ input_tokens: 400 گزارش میدهد ارزان نیست: بقیه از کش تأمین شده است.
پیش از ارسال بشمارید. شمارش توکن رایگان است و محدودیتهای نرخ آن از ایجاد پیام جداست، بنابراین از count_tokens استفاده کنید تا یک پیوست بیشازحد بزرگ را رد کنید، بهجای آنکه برای کشف آن پول بپردازید. نتیجه یک تخمین است، بنابراین برای هر مدل دوباره اندازهگیری کنید و هرگز شمارشی را که از توکنایزر فروشندهای دیگر به دست آمده دوباره استفاده نکنید. مدلهای Claude Opus 4.7 و Opus بعدی، Claude Fable 5 و Claude Sonnet 5 از یک توکنایزر جدیدتر استفاده میکنند که «برای همان متن تقریباً 30٪ توکن بیشتر تولید میکند». مدلهای Claude Sonnet 4.6 و قدیمیتر، از جمله Claude Haiku 4.5، از توکنایزر قبلی استفاده میکنند.
برای دریافت نمای معتبر، Admin API مصرف را در https://api.anthropic.com/v1/organizations/usage_report/messages و هزینه را در https://api.anthropic.com/v1/organizations/cost_report گزارش میدهد. هر دو یک کلید ادمین (sk-ant-admin01-...) را بهعنوان x-api-key: $ANTHROPIC_ADMIN_KEY همراه با anthropic-version: 2023-06-01 میگیرند و bucket_width=1d، group_by[]=model و api_key_ids[]= را میپذیرند. یک محدودیت: «Admin API برای حسابهای فردی در دسترس نیست.»
آن پارامتر آخر یک ترفند ارزان برای انتساب است: به هر کار کلید API خودش را بدهید، با api_key_ids[] فیلتر کنید و گزارش را با group_by[]=api_key_id بهتفکیک هر کلید تقسیم کنید. فیلتر بهصورت جمع است، بُعد گروهبندی بهصورت مفرد. کلیدها را بهجای کد، در محیط نگه دارید، همانطور که نخستین اپلیکیشن Claude API روی یک VPS با آنها رفتار میکند.
حلقه را محدود کنید، چون هیچ چیز دیگری این کار را نمیکند
تعداد تکرار محدود در اینجا اختیاری نیست. حلقه متعلق به شماست، پس شمارنده هم متعلق به شماست:
for step in range(MAX_STEPS): # MAX_STEPS = 12, never "while True"
resp = client.messages.create(...)
if resp.stop_reason != "tool_use":
break
else:
log.warning("job %s hit MAX_STEPS=%d, giving up", job_name, MAX_STEPS)هیچیک از سقفهای بالا این کار را برایتان انجام نمیدهند: max_tokens یک پاسخ را محدود میکند، و مدل فقط از یک بودجه وظیفه مطلع میشود.
یک ترمز دوم بیرون از فرآیند قرار دهید. کار را بهجای یک فرآیند دائمی، از یک زمانبند systemd اجرا کنید و RuntimeMaxSec= را روی واحد سرویس آن تنظیم کنید. با RuntimeMaxSec=600, یک اجرای هنگکرده پس از ده دقیقه متوقف میشود، بهجای آنکه تا زمانی که شما متوجه شوید به چرخش ادامه دهد. اجرای یک برنامه بهعنوان سرویس و زمانبند systemd خود فایلهای واحد را پوشش میدهد. آنچه را که یک اجرا انجام داده است با journalctl -u triage-agent.service --since "1 hour ago" بخوانید.
تلاشهای مجدد را نیز محدود کنید، زیرا یک کنترلکننده که برای همیشه تلاش مجدد میکند، هزینه هر تلاش را محاسبه میکند. یک خطای 429 یا 500 سزاوار چند تلاش با افزایش تأخیر است. یک خطای 400 سزاوار هیچ تلاشی نیست، زیرا همان درخواست به همان شکل شکست میخورد.
کنترل هزینهٔ عامل هوش مصنوعی با خواندن اعداد خودتان آغاز میشود
هیچکس نمیتواند به شما بگوید هزینهٔ یک عامل همیشهروشن چقدر است، زیرا هزینه برابر است با توکنهای هر اجرا ضربدر تعداد اجراها در روز، و هر دو بخش متعلق به خود شماست. یک بار اجرایش کنید، ردیف مصرفی که ثبت کردهاید را بخوانید، و در زمانبندی خود ضرب کنید. گزارش هزینه را دو روز بعد با همان محاسبات مقایسه کنید. وقتی این دو با هم اختلاف دارند، شکاف ایجادشده تقریباً همیشه ناشی از یک کش خراب یا یک حلقه است که بیش از حد فرض شما اجرا شده است.
این مطلب یک کلید API را مفروض میگیرد، زیرا عامل برنامهٔ خود شماست که Messages API را فراخوانی میکند. برای کار تعاملی خودتان، کدام طرح Claude با شیوهٔ کاری شما سازگار است بخش اشتراک را پوشش میدهد. تمام قیمتها و محدودیتهای اینجا در ژوئیهٔ 2026 با مستندات Anthropic تطبیق داده شدهاند، بنابراین پیش از تدوین بودجه، صفحهٔ قیمتگذاری را دوباره بخوانید.
FAQ
هزینه اجرای یک عامل هوش مصنوعی همیشه-روشن روی یک VPS چقدر است؟
دو صورتحساب وجود دارد و فقط یکی از آنها قابل پیشبینی است. سرور یک قیمت ثابت ماهانه دارد. API مدل بر اساس هر توکن محاسبه میشود، بنابراین هزینه برابر است با مصرف یک اجرا ضرب در تعداد دفعات اجرا. Anthropic هیچ رقمی برای یک عامل همیشه-روشن خودمیزبان منتشر نکرده است، بنابراین هر عدد نقلقولشدهای را یک حدس در نظر بگیرید. usage را از یک اجرای واقعی ثبت کنید و در برنامهتان ضرب کنید.
تفاوت بین max_tokens و بودجه وظیفه چیست؟
max_tokens اجباری است و برای مدل نامرئی. این پارامتر خروجی یک درخواست، شامل تفکر را محدود میکند و رسیدن به آن باعث stop_reason: "max_tokens" میشود. بودجه وظیفه برعکس است: عدد به مدل گفته میشود و حلقه عاملی را بر اساس آن تنظیم میکند، اما «بودجههای وظیفه یک راهنمایی نرم هستند، نه یک سقف سخت» و محدودیت اجباری همچنان max_tokens است.
چرا cache_read_input_tokens برای عامل من همیشه صفر است؟
زیرا پیشوند بین فراخوانیها تغییر میکند، یا برای کش شدن بسیار کوتاه است. علت معمول یک برچسب زمانی یا یک شناسه اجرا است که در اعلان سیستم درج میشود: کش بر اساس پیشوند کلیدگذاری میشود، بنابراین هر تغییر بایتی همه چیز بعد از آن را بیاعتبار میکند. تغییر تعاریف ابزار یا مقدار effort نیز همین کار را میکند. در غیر این صورت، علت اندازه است، زیرا اعلانهای کوتاهتر کش نمیشوند و هیچ خطایی برگردانده نمیشود.
چگونه از یک عامل هوش مصنوعی جلوگیری کنم که تا ابد در حلقه بیفتد؟
تکرارها را در کد حلقه خود بشمارید و در یک حداکثر ثابت متوقف کنید، زیرا max_tokens یک پاسخ را محدود میکند و یک عامل پاسخهای زیادی تولید میکند. یک محدودیت ساعت-دیواری خارج از فرآیند اضافه کنید: کار را از یک زمانسنج systemd با تنظیم RuntimeMaxSec= شروع کنید، تا یک اجرای قفلشده طبق برنامه متوقف شود. تلاشهای مجدد را نیز محدود کنید، زیرا یک حلقه تلاش مجدد برای هر اقدام هزینه در بر دارد.
آیا میتوانم یک محدودیت هزینه روی یک کلید API کلود تنظیم کنم؟
محدودیت هزینه مستندشده به ازای هر فضای کاری است نه هر کلید، بنابراین به عامل یک فضای کاری اختصاصی بدهید و هزینه ماهانه آن را در آنجا محدود کنید. «شما نمیتوانید روی فضای کاری پیشفرض محدودیت تنظیم کنید». اعلانهای هزینه اضافه کنید تا یک آستانه ابتدا به شما هشدار دهد. برای انتساب، به هر کار کلید خودش را بدهید، سپس گزارش مصرف را با group_by[]=api_key_id گروهبندی کنید.