efficient-api-usage
Cost and latency optimization for Anthropic API usage. Covers prompt caching, batch API, and when to combine them.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Cost and latency optimization for Anthropic API usage. Covers prompt caching, batch API, and when to combine them.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Write up research experiments and findings as an interactive, self-contained HTML report published as a claude.ai Artifact, with figures and data exploration. Use when creating a research report from experiment results.
How to write a comprehensive research report for your supervisor summarizing experiment findings, hypothesis tests, and data exploration. Use when you need to communicate results from multiple experiments with proper analysis, visualizations, and interactive data exploration.
How to send notifications to the human supervisor via ntfy.sh. Use when you need input, hit a blocker, or update them on your progress.
Standard experiment folder structure and templates. Reference for creating or validating experiment folders.
Read model outputs, samples, or log entries by eye and report specific observations about what's in them. Use when asked for a "qualitative" read/analysis, or when the goal is to understand WHAT is in the data rather than count patterns. Not for numerical summaries, metric computation, or classifier-driven sweeps.
How to evaluate research samples using structured JSON output from claude -p. Covers criteria writing, the core judging pattern, and practical examples.
| name | efficient-api-usage |
| description | Cost and latency optimization for Anthropic API usage. Covers prompt caching, batch API, and when to combine them. |
Caches the KV representations of prompt prefixes so repeated requests with shared context skip re-processing.
How it works:
cache_control breakpoint where the prefix is identicalcache_control at the boundary between stable context and variable content"ttl": "1h" for 1-hour duration (value must be a string: "5m" or "1h")Pricing (relative to base input cost):
Break-even: 5-min TTL pays off after 2 requests (1.25× + 0.1× = 1.35× vs 2× uncached). 1-hour TTL needs 3+ requests (2× + 0.2× = 2.2× vs 3× uncached). Pick 1h only when you expect the prefix to be reused enough times to amortize the doubled write cost.
Limits and silent failures:
cache_control breakpoints per request.cache_creation_input_tokens: 0.f"Today is {datetime.now()}")json.dumps(d) without sort_keys=True — Python dict iteration order can shift the bytesset or filtered conditionally)cache_read_input_tokens stays 0 across runs you expect to hit, diff the rendered request bodies — one of these is almost always the cause.Two modes:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": "<large stable context>",
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": "variable question"}],
)
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system="<large stable context>",
messages=[{"role": "user", "content": "variable question"}],
)
Verifying cache behavior — check response.usage:
cache_creation_input_tokens > 0 → cache miss, wrote to cachecache_read_input_tokens > 0 → cache hitProcesses requests asynchronously at 50% of standard pricing. Most batches complete in <1 hour, max 24 hours.
Limits: 100k requests or 256 MB per batch, whichever comes first.
When to use: any workload that doesn't need real-time responses — evals, bulk classification, data analysis, content generation.
With structured outputs (output_config.format.json_schema): all object types in the schema must have "additionalProperties": false. This is an API-level requirement (not batch-specific).
from anthropic.types.message_create_params import MessageCreateParamsNonStreaming
from anthropic.types.messages.batch_create_params import Request
batch = client.messages.batches.create(
requests=[
Request(
custom_id=f"request-{i}",
params=MessageCreateParamsNonStreaming(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": question}],
),
)
for i, question in enumerate(questions)
]
)
| Scenario | Real-time needed? | Shared prefix? | Strategy | Discount vs base |
|---|---|---|---|---|
| Chat / interactive | Yes | Yes (system prompt) | Prompt caching | ~90% on cached input |
| Chat / interactive | Yes | No | Standard API | None |
| Bulk eval / analysis | No | Yes | Batch + caching | 50% base + ~90% on cached input |
| Bulk eval / analysis | No | No | Batch only | 50% |
The discounts stack. Include identical cache_control blocks in every request within the batch.
Caveat: batch requests are processed concurrently and asynchronously, so cache hits are best-effort (typically 30-98% hit rate). To maximize hits:
shared_system = [
{
"type": "text",
"text": "<large shared context>",
"cache_control": {"type": "ephemeral", "ttl": "1h"},
}
]
batch = client.messages.batches.create(
requests=[
Request(
custom_id=f"request-{i}",
params=MessageCreateParamsNonStreaming(
model="claude-sonnet-4-6",
max_tokens=1024,
system=shared_system,
messages=[{"role": "user", "content": q}],
),
)
for i, q in enumerate(questions)
]
)