@apicity/anthropic

中文文档
0.27.0发布于 2026/11/06MITTypeScriptES Module近 30 天下载 4601

Anthropic / Claude provider for messages, batches, models, files, and admin APIs.

原始使用文档
文档目录11 节
  1. Installation
  2. Quick Start
  3. Real-world example: multi-turn TypeScript review with syste…
  4. API Reference
  5. files
  6. messages
  7. models
  8. oauth
  9. skills
  10. Middleware
  11. License

@apicity/anthropic

npm dependencies TypeScript

Anthropic / Claude provider for messages, batches, models, files, and admin APIs.

Runtime dependencies:

  • zod@^4.6.6 — request schemas attached to every POST endpoint as .schema

Installation

npm install @apicity/anthropic
# or
pnpm add @apicity/anthropic

Quick Start

import { createAnthropic } from "@apicity/anthropic";

const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY! });

Real-world example: multi-turn TypeScript review with system prompt + few-shot priming

The single biggest knob the Anthropic Messages API gives you is the messages array itself: every prior turn is grist for the next one. Pair that with a strict system prompt to lock the output format and one priming exchange to demonstrate the format, and you get a deterministic-looking single-line bug reviewer out of claude-sonnet-4-6 without any tools, no JSON-mode, no fine-tune. Every token, model id, and content block below is mined from tests/recordings/anthropic_2966493235/messages-code-review_891889396/, the HAR replayed by tests/integration/anthropic-messages-code-review.test.ts — recorded straight against https://api.anthropic.com/v1/messages with the typed @apicity/anthropic client.

import { createAnthropic } from "@apicity/anthropic";
import type {
  AnthropicMessageResponse,
  AnthropicTextBlock,
} from "@apicity/anthropic";

const anthropic = createAnthropic({
  apiKey: process.env.ANTHROPIC_API_KEY!,
});

// 1. The `system` field is a hard contract for response shape — Claude
//    treats it as higher-priority instruction than anything in
//    `messages`. Spelling out the exact line format here ("BUG: <one
//    sentence>", no preamble, no Markdown) is what stops the model
//    from wrapping the answer in "Sure! Here's the bug:" or fenced
//    code, which it does by default.
//
// 2. The `messages` array is a *transcript*, not a single prompt. The
//    one-shot user→assistant pair below primes the format on a known
//    bug (off-by-one in a loop bound) so the third turn answers in
//    the same shape on a code snippet the model has not seen before.
//    This is few-shot prompting; no fine-tuning required.
const result: AnthropicMessageResponse = await anthropic.v1.messages({
  model: "claude-sonnet-4-6",
  max_tokens: 256,
  system:
    "You are a senior TypeScript reviewer. Reply with exactly one line " +
    "in the form: 'BUG: <one-sentence summary>'. No preamble, no code, " +
    "no Markdown.",
  messages: [
    {
      role: "user",
      content:
        "Review this:\n```ts\nfunction firstNonEmpty(xs: string[]): string {\n" +
        "  for (let i = 0; i <= xs.length; i++) {\n" +
        "    if (xs[i]) return xs[i];\n" +
        "  }\n  return '';\n}\n```",
    },
    {
      role: "assistant",
      content:
        "BUG: The loop condition `i <= xs.length` reads one past the " +
        "last index, so `xs[xs.length]` is dereferenced as undefined.",
    },
    {
      role: "user",
      content:
        "Now review this one the same way:\n```ts\n" +
        "async function readAll(stream: ReadableStream<Uint8Array>): " +
        "Promise<Uint8Array> {\n" +
        "  const reader = stream.getReader();\n" +
        "  const chunks: Uint8Array[] = [];\n" +
        "  while (true) {\n" +
        "    const { done, value } = await reader.read();\n" +
        "    if (done) break;\n    chunks.push(value);\n  }\n" +
        "  return Buffer.concat(chunks);\n}\n```",
    },
  ],
});

// 3. `content` is always an array of typed blocks, never a single
//    string. This is the same shape Claude returns when there are
//    `tool_use`, `thinking`, or `image` blocks in the response —
//    treating it uniformly here means tool-using and thinking
//    workflows drop in without restructuring the read path.
const text = result.content
  .filter((b): b is AnthropicTextBlock => b.type === "text")
  .map((b) => b.text)
  .join("")
  .trim();

console.log(text);
// → "BUG: The reader is never released via `reader.releaseLock()`
//    (especially on error), leaving the stream permanently locked."

console.log(
  `model=${result.model} stop=${result.stop_reason} ` +
    `in=${result.usage.input_tokens} out=${result.usage.output_tokens}`,
);
// → "model=claude-sonnet-4-6 stop=end_turn in=268 out=33"

Notes

  • The system prompt is treated as a soft-but-strong constraint on every turn, not just the first — Claude re-applies it as the conversation lengthens, so the format won't drift after 10 turns the way a single user-message instruction will. Pass it as a string for short rules; pass it as [{ type: "text", text, cache_control: { type: "ephemeral" } }] to mark it as cacheable when you reuse the same long system prompt across many requests.
  • Few-shot priming via a fake assistant turn is the cheapest reliable way to lock output formatting without tools or structured-output APIs. Claude does not distinguish between turns it actually generated and turns you wrote — both are equally authoritative context. Keep priming turns short and exact; if yours doesn't match the system rule character-for-character (e.g. a trailing period the system says shouldn't be there), the model will hedge.
  • result.content is a (AnthropicTextBlock | AnthropicToolUseBlock | AnthropicThinkingBlock | …)[] discriminated union. Filter on b.type === "text" before reading .text; on b.type === "tool_use" before reading .input; on b.type === "thinking" before reading .thinking. Claude can interleave them in one response — e.g. a leading text block, then a thinking block, then a tool_use — so always iterate, never assume content[0].
  • usage.input_tokens includes the entire transcript on every turn, so a 10-turn conversation pays for the system prompt + 10 turns of history every time. To amortize a long system prompt (>1024 tokens) across many calls, mark it cache_control: ephemeral and watch usage.cache_read_input_tokens rise on calls 2–N.
  • Errors throw AnthropicError with status, the parsed body, and the upstream errorType ("authentication_error", "rate_limit_error", "overloaded_error", …). Wrap with withRetry from @apicity/anthropic for 429 and 529 overloaded_error, which Claude returns under sustained load. Pair with withFallback to roll over to claude-haiku-4-5 for non-critical paths.
  • Point the same call at a Claude-compatible gateway by passing baseURL (and a fetch wrapper if the backend uses a different auth header than x-api-key) to createAnthropic. The factory's request shape is upstream-faithful, so anything that speaks the Anthropic Messages wire format — Bedrock proxies, third-party gateways, local mocks — works without touching call sites.

API Reference

24 endpoints across 5 groups. Each method mirrors an upstream URL path.

files

DELETE anthropic.v1.files.del

DELETE https://api.anthropic.com/v1/files/{fileId}

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.delete.v1.files.del({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

GET anthropic.v1.files.content

GET https://api.anthropic.com/v1/files/{fileId}/content

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.files.content({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

GET anthropic.v1.files.list

GET https://api.anthropic.com/v1/files

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.files.list({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

GET anthropic.v1.files.retrieve

GET https://api.anthropic.com/v1/files/{fileId}

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.files.retrieve({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

POST anthropic.v1.files

POST https://api.anthropic.com/v1/files

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.post.v1.files({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

messages

DELETE anthropic.v1.messages.batches.del

DELETE https://api.anthropic.com/v1/messages/batches/{batchId}

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.delete.v1.messages.batches.del({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

GET anthropic.v1.messages.batches.list

GET https://api.anthropic.com/v1/messages/batches

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.messages.batches.list({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

GET anthropic.v1.messages.batches.results

GET https://api.anthropic.com/v1/messages/batches/{batchId}/results

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.messages.batches.results({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

GET anthropic.v1.messages.batches.retrieve

GET https://api.anthropic.com/v1/messages/batches/{batchId}

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.messages.batches.retrieve({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

POST anthropic.post.stream.v1.messages

POST https://api.anthropic.com/v1/messages

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.post.stream.v1.messages({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

POST anthropic.v1.messages.batches.cancel

POST https://api.anthropic.com/v1/messages/batches/{batchId}/cancel

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.post.v1.messages.batches.cancel({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

POST anthropic.v1.messages

POST https://api.anthropic.com/v1/messages

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.v1.messages({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

POST anthropic.v1.messages.batches

POST https://api.anthropic.com/v1/messages/batches

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.v1.messages.batches({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

POST anthropic.v1.messages.countTokens

POST https://api.anthropic.com/v1/messages/count_tokens

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.v1.messages.countTokens({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

models

GET anthropic.v1.models.list

GET https://api.anthropic.com/v1/models

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.models.list({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

GET anthropic.v1.models.retrieve

GET https://api.anthropic.com/v1/models/{modelId}

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.models.retrieve({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

oauth

GET anthropic.api.oauth.usage

GET https://api.anthropic.com/api/oauth/usage

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.api.oauth.usage();

Source: packages/provider/anthropic/src/anthropic.ts

skills

DELETE anthropic.v1.skills.del

DELETE https://api.anthropic.com/v1/skills/{skillId}

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.delete.v1.skills.del({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

DELETE anthropic.v1.skills.versions.del

DELETE https://api.anthropic.com/v1/skills/{skillId}/versions/{version}

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.delete.v1.skills.versions.del({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

GET anthropic.v1.skills.list

GET https://api.anthropic.com/v1/skills

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.skills.list({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

GET anthropic.v1.skills.retrieve

GET https://api.anthropic.com/v1/skills/{skillId}

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.skills.retrieve({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

GET anthropic.v1.skills.versions.list

GET https://api.anthropic.com/v1/skills/{skillId}/versions

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.get.v1.skills.versions.list({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

POST anthropic.v1.skills.create

POST https://api.anthropic.com/v1/skills

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.post.v1.skills.create({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

POST anthropic.v1.skills.versions.create

POST https://api.anthropic.com/v1/skills/{skillId}/versions

Cost tier: expensive

Upstream docs ↗

const res = await anthropic.post.v1.skills.versions.create({ /* ... */ });

Source: packages/provider/anthropic/src/anthropic.ts

Middleware

import { createAnthropic, withRetry } from "@apicity/anthropic";

const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY! });
const listModels = withRetry(anthropic.get.v1.models.list, { retries: 3 });

Part of the apicity monorepo.

License

MIT — see LICENSE.

版本与发布记录

@apicity/anthropic 共发布 90 个版本,首次发布于 2026/05/10;过去 12 个月发布了 90 个版本。

版本发布日期距今
0.27.0latest2026/11/06今天
0.26.02026/11/051 天前
0.25.02026/11/033 天前
0.24.12026/11/024 天前
0.24.02026/11/014 天前
0.23.12026/11/015 天前

关于 @apicity/anthropic 的常见问题

@apicity/anthropic 是什么?

Anthropic / Claude provider for messages, batches, models, files, and admin APIs.

如何安装 @apicity/anthropic?

在项目目录运行 npm install @apicity/anthropic,或使用 pnpm add / yarn add / bun add。

@apicity/anthropic 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@apicity/anthropic 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@apicity/anthropic 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@apicity/anthropic 可以商用吗?

@apicity/anthropic 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@apicity/anthropic 的下载量有多少?

根据 npm 官方下载统计,@apicity/anthropic 在 2026/10/06 – 2026/11/04 这 30 天内被下载 4,601 次,日均约 153 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@apicity/anthropic 还在维护吗?

最新版本 0.27.0 发布于 2026/11/06(今天);至今共发布 90 个版本,其中过去 12 个月发布了 90 个;首次发布于 2026/05/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。