SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor

آموزش اتصال به Claude API و اجرای اولین برنامه روی VPS

با این راهنما یک ابزار تحلیل لاگ با Python روی Ubuntu 24.04 بسازید. یاد بگیرید چگونه کلید API را ایمن کنید، استریمینگ را پیاده‌سازی کرده و هزینه‌های مصرفی را کنترل کنید.

آنچه می‌سازید

یک ابزار خط فرمان روی یک VPS تازه با سیستم‌عامل Ubuntu 24.04 که پیام خطا یا بخشی از لاگ را به آن pipe می‌کنید و در مقابل، یک تشخیص به زبان ساده دریافت می‌کنید: journalctl -u nginx -n 50 | explain. این ابزار حدود 60 خط کد Python است و تمام مواردی که یک برنامه واقعی مبتنی بر Claude API به آن نیاز دارد را تمرین می‌کند: یک کلید که به‌درستی ذخیره شده، یک virtualenv، ساختار پاسخ‌های SDK، استریمینگ، زنجیره استثناهای تایپ‌شده و یک unit در systemd تا بدون دخالت شما اجرا شود.

من این پروژه را آگاهانه انتخاب کردم. اکثر آموزش‌های «اولین برنامه API» شما را وادار به ساخت چت‌باتی می‌کنند که دیگر هرگز آن را باز نخواهید کرد. یک تحلیلگر لاگ از همان روز اول روی سرور برای شما کار می‌کند و شما را مجبور می‌کند دو موردی را که مبتدیان واقعاً در آن اشتباه می‌کنند، یاد بگیرید: خواندن صحیح شیء پاسخ و کنترل هزینه‌ها. این API بر اساس توکن صورت‌حساب صادر می‌کند و هیچ سقفی جز آنچه شما تعیین می‌کنید ندارد؛ بنابراین کنترل هزینه در اینجا یک ورودی طراحی است، نه یک فکر ثانویه. این همان انضباطی است که وقتی به مرحله اجرای Claude Code روی همین VPS در tmux می‌رسید، اهمیت پیدا می‌کند.

دریافت کلید API از کنسول

دسترسی به API در کنسول Anthropic به آدرس platform.claude.com مدیریت می‌شود. ثبت‌نام کنید و سپس یک کلید در مسیر Settings → API Keys ایجاد نمایید (مستندات مستقیماً به platform.claude.com/settings/keys لینک شده‌اند). کنسول از شما می‌خواهد که نامی برای کلید انتخاب کنید، یک تاریخ انقضا تعیین نمایید و آن را به خودتان یا یک service account متصل کنید؛ Anthropic توصیه می‌کند برای سرویس‌های عملیاتی (production) و هر چیزی که به‌صورت اشتراکی استفاده می‌شود، از کلیدهای service account استفاده کنید. این کلید فقط یک‌بار نمایش داده می‌شود، با sk-ant- شروع می‌شود و دیگر قابل بازیابی نیست؛ بلافاصله آن را کپی کنید یا در غیر این صورت، کلید را حذف و دوباره صادر نمایید.

در مورد هزینه‌ها: تا اکتبر 2026 هیچ سطح رایگان دائمی برای API وجود ندارد. مستندات قیمت‌گذاری Anthropic بیان می‌کند که کاربران جدید مقدار کمی اعتبار رایگان برای تست دریافت می‌کنند؛ مقدار دقیق آن همان چیزی است که کنسول هنگام ثبت‌نام به شما نشان می‌دهد و پس از اتمام آن، باید پیش از ارسال درخواست‌ها، حساب خود را شارژ کنید. این موضوع از اشتراک claude.ai جداست و کلید API دسترسی به اپلیکیشن چت را به شما نمی‌دهد. طرح Pro شامل اعتبار API نمی‌شود، اما طرح‌های Max و Team شامل آن هستند: تا اکتبر 2026، در طرح Max 5x مبلغ 100 دلار در ماه و در طرح Max 20x مبلغ 200 دلار در ماه (طرح Team شامل 20 دلار برای هر صندلی Standard و 100 دلار برای هر صندلی Premium با سقف 500 دلار است) که با متصل کردن یک سازمان در کنسول از طریق تنظیمات صورت‌حساب claude.ai فعال می‌شود. اعتبار استفاده‌نشده در پایان هر دوره صورت‌حساب منقضی می‌شود و شامل Claude Code نمی‌شود؛ جزئیات در نحوه عملکرد اعتبارات ماهانه API در طرح‌های Max و Team آمده است. اگر در حال سبک‌سنگین کردن اشتراک در برابر API هستید، این مبادله موضوعی جداگانه است: کدام طرح Claude واقعاً مورد نیاز شماست.

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

کلید را خارج از .bashrc نگه دارید

واکنش غریزی، استفاده از export ANTHROPIC_API_KEY=sk-ant-... در ~/.bashrc است. این کار را نکنید. سه مشکل مجزا وجود دارد:

  • هر پردازشی آن را به ارث می‌برد. متغیر محیطی که در shell ورود شما export شده باشد، به هر چیزی که اجرا می‌کنید سرایت می‌کند؛ از برنامه وب گرفته تا گزارش‌گر کرش که محیط خود را در گزارش باگ می‌ریزد، یا صفحه phpinfo() که ممکن است کسی فعال گذاشته باشد. سطح در معرض قرارگیری کلید، به «هر چیزی که این کاربر اجرا می‌کند» تبدیل می‌شود.
  • تایپ کردن آن در ~/.bash_history ثبت می‌شود. اگر یک بار دستور export را دستی اجرا کنید، کلید شما برای همیشه در یک فایل متنی ساده باقی می‌ماند و در تمام نسخه‌های پشتیبان از دایرکتوری home شما همگام‌سازی می‌شود.
  • هنگام نیاز systemd، کلید در دسترس نیست. سرویس‌ها فایل .bashrc شما را نمی‌خوانند، بنابراین این الگو دقیقاً زمانی شکست می‌خورد که اسکریپت را به یک unit تبدیل می‌کنید؛ معمولاً به شکل یک خطای 401 مرموز در ساعت 6 صبح.

الگوی صحیح در سرور، استفاده از یک فایل محیطی اختصاصی با مجوزهای 600 است که فقط توسط پردازشی که به آن نیاز دارد بارگذاری می‌شود:

sudo mkdir -p /opt/explain
sudo install -m 600 -o root -g root /dev/null /etc/claude-explain.env
printf 'ANTHROPIC_API_KEY=sk-ant-YOUR-KEY-HERE\n' | sudo tee /etc/claude-explain.env >/dev/null

اگر می‌خواهید کلید از فایل‌های swap ویرایشگر دور بماند، به جای ویرایشگر از tee در دستور printf استفاده کنید؛ در هر صورت، با ls -l /etc/claude-explain.env تأیید کنید که فایل دارای مجوز -rw------- است و مالک آن root می‌باشد. shellهای تعاملی کلید را در هر بار فراخوانی از طریق یک wrapper (در زیر) دریافت می‌کنند و systemd آن را از طریق EnvironmentFile= می‌گیرد. root فایل را پیش از کاهش سطح دسترسی (drop privileges) می‌خواند، بنابراین کاربر سرویس هرگز نیازی به دسترسی خواندن آن ندارد. کلید هرگز در کد، در git، در خروجی ps یا در تاریخچه shell ظاهر نمی‌شود.

نصب SDK در یک venv

سیستم‌عامل Ubuntu 24.04 همراه با Python 3.12 عرضه می‌شود که اجرای PEP 668 را اعمال می‌کند؛ بنابراین اجرای یک pip install anthropic ساده روی مفسر سیستم با خطای error: externally-managed-environment مواجه می‌شود. این خطا نشان‌دهنده عملکرد صحیح سیستم‌عامل است؛ از یک virtualenv استفاده کنید:

sudo apt update && sudo apt install -y python3-venv
sudo python3 -m venv /opt/explain/venv
sudo /opt/explain/venv/bin/pip install anthropic

در محیط سرور نیازی به تشریفات فعال‌سازی (activation) نیست: فراخوانی مستقیم /opt/explain/venv/bin/python همیشه از بسته‌های موجود در venv استفاده می‌کند.

اولین فراخوانی و خواندن صحیح پاسخ

import anthropic

client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY from the environment

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1000,
    messages=[{"role": "user", "content": "Explain what a systemd unit file is in three sentences."}],
)

for block in response.content:
    if block.type == "text":
        print(block.text)

دو مورد در آن دوازده خط، بخش عمده‌ای از مدل ذهنی این API را تشکیل می‌دهند. نخست، anthropic.Anthropic() بدون هیچ آرگومانی، کلید را از محیط (environment) می‌خواند؛ هرگز آن را به صورت یک رشته متنی (string literal) ارسال نکنید. دوم، response.content یک لیست از بلوک‌های محتوا است، نه یک رشته. اگر آن را مستقیماً چاپ کنید، خروجی کلاسیکِ تازه‌کارها را دریافت می‌کنید:

[TextBlock(citations=None, text='A systemd unit file is...', type='text')]

این یک باگ نیست؛ بلکه repr (نمایش شیء) است. پاسخ‌ها می‌توانند شامل چندین نوع بلوک باشند (متن، فراخوانی ابزار، تفکر)، بنابراین باید روی لیست پیمایش کنید و پیش از دسترسی به .text، مقدار block.type == "text" را بررسی کنید. در Opus 5.5 این موضوع از همان اولین فراخوانی اهمیت دارد: قابلیت تفکر همیشه فعال است، بنابراین مگر اینکه مدل در یک درخواست ساده از تفکر صرف‌نظر کند، لیست با یک بلوک thinking شروع می‌شود که متن آن به‌صورت پیش‌فرض خالی است و response.content[0].text پاسخ نهایی شما نیست. این حلقه را از همان روز اول پیاده‌سازی کنید تا یک دسته کامل از سردرگمی‌های مربوط به «چاپ خروجی نامفهوم» هرگز رخ ندهد.

از شناسه مدل دقیق claude-opus-5-5 استفاده کنید. از نسل 4.6 به بعد، شناسه‌های مدل بدون تاریخ هستند و شناسه بدون تاریخ همان snapshot ثابت‌شده است؛ بنابراین در برابر عادت ذهنی (یا پست‌های وبلاگی قدیمی) که به شما می‌گوید یک پسوند تاریخ به مدل فعلی اضافه کنید، مقاومت کنید؛ این کار منجر به خطای 404 می‌شود که در ادامه به آن پرداخته شده است. مدل‌های قدیمی‌تر برعکس عمل می‌کنند: شناسه استاندارد Haiku 4.5 همان claude-haiku-4-5-20251001 تاریخ‌دار است.

ابزار اصلی: توضیح

در اینجا برنامه کامل، ورودی از stdin، خروجی تشخیص جریان‌یافته (streamed) و مدیریت خطاها آمده است:

#!/usr/bin/env python3
"""explain: pipe an error or log excerpt in, get a diagnosis out."""
import sys
import anthropic

MODEL = "claude-opus-5-5"

def main() -> int:
    text = sys.stdin.read().strip()
    if not text:
        print("usage: journalctl -u nginx -n 50 | explain", file=sys.stderr)
        return 1

    client = anthropic.Anthropic()
    try:
        with client.messages.stream(
            model=MODEL,
            max_tokens=4096,
            system=(
                "You are a senior Linux sysadmin. The user pipes you server "
                "logs or error output. Name the most likely cause outright, "
                "then give the commands to confirm and fix it. Be terse."
            ),
            messages=[{"role": "user", "content": text}],
        ) as stream:
            for chunk in stream.text_stream:
                print(chunk, end="", flush=True)
        print()
    except anthropic.RateLimitError as e:
        retry_after = e.response.headers.get("retry-after", "60")
        print(f"rate limited; retry in {retry_after}s", file=sys.stderr)
        return 2
    except anthropic.APIStatusError as e:
        print(f"API error {e.status_code}: {e.message}", file=sys.stderr)
        return 2
    except anthropic.APIConnectionError:
        print("network error reaching the API", file=sys.stderr)
        return 2
    return 0

if __name__ == "__main__":
    sys.exit(main())

آن را با نام /opt/explain/explain.py ذخیره کنید، سپس یک wrapper اضافه کنید که کلید را برای استفاده تعاملی بارگذاری می‌کند:

sudo tee /usr/local/bin/explain >/dev/null <<'EOF'
#!/bin/sh
set -a; . /etc/claude-explain.env; set +a
exec /opt/explain/venv/bin/python /opt/explain/explain.py "$@"
EOF
sudo chmod 755 /usr/local/bin/explain

(این wrapper باید از طریق sudo اجرا شود یا فایل env باید متعلق به گروهی باشد که کاربر مدیر شما در آن عضو است؛ یکی را آگاهانه انتخاب کنید و از تغییر مجوز فایل به 644 خودداری کنید.)

چرا استریمینگ (streaming). ابزار client.messages.stream توکن‌ها را به محض رسیدن چاپ می‌کند و به جای سکوت تا پایان تولید کامل، آن‌ها را نمایش می‌دهد. این کار از بروز timeout در HTTP برای خروجی‌های طولانی جلوگیری می‌کند؛ SDK در واقع مقادیر بسیار بزرگ max_tokens را در فراخوانی‌های غیر استریمینگ دقیقاً به همین دلیل رد می‌کند. ابزار text_stream فقط متن پاسخ را ارائه می‌دهد و با نمایش تفکر پیش‌فرض در Opus 5.5، هیچ متن تفکری استریم نمی‌شود، بنابراین خروجی تمیز باقی می‌ماند. اگر بعداً به شیء کامل نیاز دارید، stream.get_final_message() را در داخل بلوک with فراخوانی کنید.

چرا این ترتیب استثناها. SDK استثناهای تایپ‌شده را به ترتیب از خاص‌ترین به عمومی‌ترین پرتاب می‌کند: RateLimitError یک خطای 429 است و حاوی هدر retry-after است که به شما می‌گوید چقدر باید منتظر بمانید؛ APIStatusError سایر پاسخ‌های غیر 2xx را پوشش می‌دهد (برای مشکلات سمت سرور، e.status_code >= 500 را بررسی کنید)؛ APIConnectionError به این معنی است که درخواست اصلاً پاسخی دریافت نکرده است. و پیش از آنکه یک حلقه بازتلاش (retry loop) بسازید: SDK به‌طور پیش‌فرض خطاهای 429 و 5xx را خودش بازتلاش می‌کند، که به‌صورت پیش‌فرض دو بار با عقب‌نشینی نمایی (exponential backoff) انجام می‌شود (max_retries در کلاینت). زمانی که except شما اجرا می‌شود، بازتلاش‌ها تمام شده‌اند، بنابراین اقدام درست در یک CLI گزارش خطا و خروج است، نه خوابیدن و ارسال مجدد درخواست.

کنترل هزینه‌ها

این موضوع به دلیل آنکه API هیچ سقف ماهانه‌ای فراتر از آنچه شما پیکربندی می‌کنید ندارد، شایسته یک بخش مجزا است؛ هر اشتباه در اینجا به‌طور خاموش انباشته می‌شود.

max_tokens سقف هزینه شما برای هر فراخوانی است. توکن‌های خروجی جهت گران‌قیمت هزینه‌ها هستند؛ در مدل Opus 5.5، قیمت آن‌ها پنج برابر قیمت ورودی است و max_tokens یک سقف سخت برای تعداد توکن‌هایی است که مدل می‌تواند تولید کند. یک پرامپت خارج از کنترل نمی‌تواند بیش از مقداری که مجاز دانسته‌اید، هزینه خروجی ایجاد کند. در مدل‌های 5.5، این سقف شامل توکن‌های تفکر (thinking) نیز می‌شود: توکن‌های تفکر جزو max_tokens محسوب شده و با نرخ خروجی محاسبه می‌شوند، حتی اگر متن تفکر به شما بازگردانده نشود. اندازه آن را متناسب با کار انتخاب کنید: 4,096 توکن برای تشخیص یک لاگ مختصر، فضای کافی برای تفکر در ابتدای آن باقی می‌گذارد؛ یک وظیفه دسته‌بندی به مقدار بسیار کمتری نیاز دارد. اگر پاسخ‌ها با stop_reason: "max_tokens" کوتاه می‌شوند، یعنی اندازه را خیلی محدود در نظر گرفته‌اید؛ آن را آگاهانه افزایش دهید (یا تنظیمات تلاش مدل را کاهش دهید تا کمتر فکر کند) و از انتخاب مقادیر بسیار بزرگ به عنوان پیش‌فرض خودداری کنید.

پیش از ارسال، شمارش کنید. ورودی نیز هزینه دارد و لاگ‌ها حجیم هستند. این API یک endpoint شمارش دارد که استفاده از آن رایگان است (این endpoint محدودیت نرخ خاص خود را دارد که از ایجاد پیام جداست):

count = client.messages.count_tokens(
    model="claude-opus-5-5",
    messages=[{"role": "user", "content": big_log_text}],
)
print(count.input_tokens)

از آن برای جلوگیری از ارسال تصادفی یک لاگ 2 گیگابایتی از طریق ابزار استفاده کنید و مدلی را که واقعاً قصد فراخوانی آن را دارید، به آن پاس دهید: Claude 4.7 و مدل‌های جدیدتر از tokenizer جدیدتری استفاده می‌کنند که برای متن یکسان، تقریباً 30 درصد توکن بیشتری نسبت به مدل‌های قدیمی‌تر Claude تولید می‌کند. برای این کار از tiktoken استفاده نکنید؛ این tokenizer متعلق به OpenAI است، نه Claude، بنابراین شمارش‌های آن با آنچه برایش صورت‌حساب دریافت می‌کنید، مطابقت نخواهد داشت.

مدل را بر اساس وظیفه انتخاب کنید، نه وفاداری. تا اکتبر 2026، مدل Opus 5.5 (claude-opus-5-5) با قیمت 4 دلار به ازای هر میلیون توکن ورودی و 20 دلار به ازای هر میلیون توکن خروجی اجرا می‌شود؛ Haiku 5.5 (claude-haiku-5-5) برای پرامپت‌های تا 100,000 توکن با قیمت 0.10/0.50 دلار (و بالاتر از آن 0.50/2.50 دلار) با کانتکست 1M در دسترس است؛ Sonnet 5.5 (claude-sonnet-5-5) با قیمت 2/10 دلار در میان این دو قرار دارد. به طور مشخص: یک قطعه لاگ 2,000 توکنی با پاسخ 500 توکنی، روی Opus حدود 0.018 دلار و روی Haiku حدود 0.00045 دلار هزینه دارد، به علاوه هر میزان تفکری که مدل انجام می‌دهد و به عنوان خروجی محاسبه می‌شود. در حالی که کیفیت خروجی را ارزیابی می‌کنید با Opus شروع کنید، سپس همان پرامپت‌ها را روی Haiku امتحان کنید؛ برای تبدیل‌های ساده و با حجم بالا، اغلب تفاوت عملکرد با یک‌چهلم قیمت به ازای هر توکن، قابل تشخیص نیست. پیش از hard-code کردن هر یک از این مقادیر در بودجه، اعداد فعلی را در صفحه قیمت‌گذاری تأیید کنید.

برای هر کاری که عجله‌ای ندارد، از دسته‌ها (Batches) استفاده کنید. API دسته‌ها، درخواست‌ها را به صورت ناهمگام با 50 درصد قیمت استاندارد پردازش می‌کند و اکثر دسته‌ها در کمتر از یک ساعت تکمیل می‌شوند. خلاصه‌های شبانه، backfillها، دسته‌بندی‌های انبوه و هر کاری که نیاز به انتظار انسان ندارد، در این دسته قرار می‌گیرند.

کش کردن پرامپت برای کانتکست‌های تکراری. اگر هر فراخوانی، همان پرامپت سیستمی بزرگ یا runbook را دوباره ارسال می‌کند، آن را قابل کش (cacheable) علامت‌گذاری کنید:

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1000,
    system=[{
        "type": "text",
        "text": RUNBOOK_TEXT,  # the same 30K tokens on every call
        "cache_control": {"type": "ephemeral"},
    }],
    messages=[{"role": "user", "content": question}],
)
print(response.usage.cache_read_input_tokens)  # non-zero from the second call on

هزینه نوشتن در کش 1.25 برابر قیمت ورودی با TTL پنج دقیقه‌ای است و هزینه خواندن از کش در Opus 5.5 و Sonnet 5.5 برابر 0.05 برابر قیمت ورودی (و در اکثر مدل‌های دیگر 0.1 برابر) است، بنابراین دومین فراخوانی در این بازه زمانی، هزینه اولین فراخوانی را جبران می‌کند. دو نکته وجود دارد: پیشوند کش‌شده باید از حداقل تعیین‌شده برای هر مدل عبور کند (512 توکن در Opus 5.5)، بنابراین یک پرامپت سیستمی بسیار کوتاه اصلاً کش نخواهد شد. همچنین اگر cache_read_input_tokens در فراخوانی‌های یکسان صفر باقی بماند، یعنی چیزی در پیشوند شما در هر درخواست تغییر می‌کند (معمولاً یک timestamp عامل این اتفاق است).

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

اجرای آن تحت systemd

پاداش رعایت نظم در استفاده از فایل‌های environment: یک تایمر که هر روز صبح خطاهای دیروز را خلاصه می‌کند.

# /etc/systemd/system/log-digest.service
[Unit]
Description=Daily error-log digest via the Claude API

[Service]
Type=oneshot
User=explain
Group=systemd-journal
EnvironmentFile=/etc/claude-explain.env
ExecStart=/bin/sh -c 'journalctl -p err --since yesterday | /opt/explain/venv/bin/python /opt/explain/explain.py >> /var/log/log-digest.txt'
# /etc/systemd/system/log-digest.timer
[Unit]
Description=Run the log digest every morning

[Timer]
OnCalendar=06:15
Persistent=true

[Install]
WantedBy=timers.target
sudo useradd -r -s /usr/sbin/nologin explain
sudo touch /var/log/log-digest.txt && sudo chown explain /var/log/log-digest.txt
sudo systemctl daemon-reload
sudo systemctl enable --now log-digest.timer
sudo systemctl start log-digest.service   # test it once, right now

دقت کنید که EnvironmentFile= چه مزیتی برای شما دارد: systemd فایل متعلق به root با مجوز 600 را پیش از تغییر سطح دسترسی به کاربر غیرمجاز explain می‌خواند؛ بنابراین پردازش متغیر را دریافت می‌کند، در حالی که کاربر نمی‌تواند فایل کلید را بخواند. گروه systemd-journal دسترسی به لاگ‌ها را فراهم می‌کند. با یک systemctl start دستی تست کنید و journalctl -u log-digest.service را بخوانید؛ برای پیدا کردن یک غلط تایپی تا ساعت 06:15 منتظر نمانید. هنگامی که این الگو از یک shell pipeline فراتر رفت، همین رویکردِ قرار دادن کلید در فایل env، مستقیماً در گردش‌کارهای n8n مبتنی بر Claude روی همان سرور قابل استفاده است.

حالت‌های شکست و پیام‌های مرتبط

خطای 401 با وجود کلید معتبر. استثنای دریافتی به این صورت است:

anthropic.AuthenticationError: Error code: 401 - {'type': 'error', 'error': {'type': 'authentication_error', 'message': 'invalid x-api-key'}, 'request_id': 'req_011CSHoEeqs5C35K2UUqR7Fy'}

اگر کلید در shell شما کار می‌کند اما سرویس خطای 401 می‌دهد، یعنی سرویس کلید را دریافت نکرده است. به یاد داشته باشید که systemd فایل .bashrc را نمی‌خواند؛ بررسی کنید که EnvironmentFile= به مسیر درستی اشاره داشته باشد. دلایل دیگر: وجود کوتیشن در فایل env (ANTHROPIC_API_KEY="sk-ant-..."، در حالی که systemd کوتیشن‌ها را حذف می‌کند، اما . file در wrapper شل شما ممکن است آن‌ها را در مقدار نهایی نگه دارد)، وجود فاصله (whitespace) در انتهای رشته، کلیدی که هفته گذشته در Console ابطال کرده‌اید، یا کلیدی که به تاریخ انقضای تعیین‌شده در زمان ساخت رسیده است.

خطای 404 به دلیل غلط تایپی در مدل. رایج‌ترین حالت این است که به یک مدل که فرمت تاریخ‌دار ندارد، پسوند تاریخ اضافه کنید:

anthropic.NotFoundError: Error code: 404 - {'type': 'error', 'error': {'type': 'not_found_error', 'message': 'model: claude-opus-5-5-20260922'}, 'request_id': 'req_011CSJqymAvNw4bT3qmDdMbA'}

شناسه‌های نسل فعلی دقیقاً همان‌طور که نوشته شده‌اند معتبر هستند، مانند claude-opus-5-5، claude-sonnet-5-5، claude-haiku-5-5، claude-fable-5-1. مدل‌های پیش از نسل 4.6 استثنا هستند: claude-haiku-4-5 یک نام مستعار (alias) برای شناسه تاریخ‌دار claude-haiku-4-5-20251001 است و هر دو فرمت کار می‌کنند. شناسه‌ها را از مستندات مدل‌ها کپی کنید و هرگز از حفظ یا از آموزش‌های قدیمی استفاده نکنید.

خطای 429 با عنوان rate_limit_error. رشته نوع خطا rate_limit_error است و پاسخ شامل هدر retry-after است که تعداد ثانیه‌های انتظار را مشخص می‌کند. SDK پیش از آنکه شما استثنا را مشاهده کنید، دو بار با مکانیزم backoff تلاش مجدد کرده است؛ بنابراین خطاهای 429 مداوم به این معنی است که نرخ درخواست شما واقعاً از سطح (tier) مجاز فراتر رفته است. کارها را دسته‌بندی (batch) کنید یا در طول زمان پخش کنید؛ حلقه تلاش مجدد (retry loop) را فشرده‌تر نکنید.

خروجی به جای متن، شیء (object) را چاپ می‌کند. خروجی شبیه [TextBlock(citations=None, text='...', type='text')] است. شما به جای پیمایش بلوک‌ها و خواندن .text از بلوک‌هایی که block.type == "text" دارند، مستقیماً response.content را چاپ کرده‌اید. تمام نمونه‌های SDK در بالا این کار را به درستی انجام می‌دهند؛ حلقه را کپی کنید.

خطای error: externally-managed-environment. شما دستور pip install را روی پایتون سیستمی Ubuntu 24.04 اجرا کرده‌اید. از venv استفاده کنید و هرگز روی سروری که برایتان اهمیت دارد، --break-system-packages را اجرا نکنید.

پاسخ‌های ناقص (Truncated). خطای response.stop_reason == "max_tokens" به این معنی است که مدل در میانه پردازش به سقف خروجی شما رسیده است. این رفتار مطابق طراحی است؛ سقف خروجی را آگاهانه افزایش دهید و به یاد داشته باشید که در مدل‌های 5.5، بخش تفکر (thinking) نیز از همان سقف استفاده می‌کند.

هنگامی که اولین برنامه شما کار کرد، ساخت یک عامل هوش مصنوعی با Claude همان فراخوانی‌های API را به عاملی تبدیل می‌کند که از ابزارها استفاده می‌کند.

FAQ

هزینه تست API مدل Claude چقدر است؟

برای ابزاری در این سطح، هزینه بسیار ناچیز است. تا اکتبر 2026، مدل Opus 5.5 به ازای هر یک میلیون توکن ورودی 4 دلار و به ازای هر یک میلیون توکن خروجی 20 دلار هزینه دارد. بنابراین، تحلیل یک لاگ معمولی که شامل چند هزار توکن ورودی و چند صد توکن خروجی است، پیش از محاسبه توکن‌های تفکر (که به عنوان خروجی محاسبه می‌شوند)، حدود دو سنت هزینه دارد. این هزینه برای مدل Haiku 5.5 (با نرخ 0.10 دلار برای ورودی و 0.50 دلار برای خروجی) بسیار کمتر از یک دهم سنت است. هزینه یک ماه گزارش‌گیری روزانه، کمتر از قیمت یک فنجان قهوه است. ریسک اصلی، قیمت هر درخواست نیست، بلکه حلقه‌های بی‌نهایت و max_tokens نامحدود است؛ به همین دلیل در این راهنما هر دو مورد به‌طور صریح محدود شده‌اند.

آیا API مدل Claude سطح رایگان دارد؟

تا اکتبر 2026، هیچ سطح رایگان دائمی وجود ندارد. طبق مستندات قیمت‌گذاری Anthropic، کاربران جدید مقدار کمی اعتبار رایگان برای تست API دریافت می‌کنند که یک فرصت آزمایشی یک‌باره است. مقدار دقیق این اعتبار هنگام ثبت‌نام در Console نمایش داده می‌شود و پس از آن باید حساب خود را شارژ کنید. مشترکین Max و Team استثنا هستند: طرح‌های آن‌ها شامل اعتبار ماهانه API است که در بالا ذکر شد. اگر هدف شما هزینه نهایی صفر برای هر درخواست است و نه کیفیت پیشرو، جایگزین آن میزبانی مدل‌های open-weight با استفاده از Ollama است که در آن به جای توکن، هزینه را با مصرف RAM می‌پردازید.

چگونه API key خود را روی سرور امن نگه دارم؟

هرگز آن را در کد، در git، یا خروجی .bashrc قرار ندهید و در پوسته‌ای (shell) که تاریخچه دستورات آن را ذخیره می‌کند، تایپ نکنید. آن را در فایلی با مالکیت root و دسترسی 600 ذخیره کنید. برای هر پردازش آن را بارگذاری کنید؛ از یک اسکریپت wrapper برای استفاده تعاملی، از EnvironmentFile= برای systemd استفاده کنید و برای هر سرور یا پروژه یک کلید مجزا در نظر بگیرید تا در صورت نشت کلید، ابطال آن محدود به همان بخش باشد و نه کل سیستم. اگر کلید به هر طریقی در سایت‌های اشتراک متن یا git commit قرار گرفت، بلافاصله آن را در Console ابطال کنید؛ حذف commit به معنای امن شدن کلید نیست.

با کدام مدل Claude شروع کنم؟

زمانی که در حال ارزیابی کیفیت خروجی‌ها برای توسعه هستید و می‌خواهید ایده را با بالاترین کیفیت بسنجید، با claude-opus-5-5 شروع کنید؛ در حجم کاری سرگرمی، تفاوت هزینه تنها چند سنت است. پس از نهایی شدن prompt، ورودی‌های واقعی خود را با claude-haiku-5-5 تست کنید؛ برای خلاصه‌سازی، دسته‌بندی و اولویت‌بندی لاگ‌ها، این مدل اغلب با یک چهلم قیمت هر توکن، کیفیت کافی را ارائه می‌دهد. مهاجرت به Haiku یا Sonnet را بر اساس اندازه‌گیری و نیاز انجام دهید، نه به صورت پیش‌فرض.