# Anthropic Agent SDK

> Run the Claude Agent SDK and the anthropic SDK's tool runner against sference's /v1/messages surface, on open models.

Source: https://sference.com/docs/agents/anthropic-agent-sdk

sference serves the Anthropic Messages API at `POST /v1/messages`, so the `anthropic` Python and TypeScript SDKs — and the Claude Agent SDK built on them — work with a base-URL change. Your agent loop then runs on open models with the same code.

## Install

```bash
pip install -U anthropic
```

## Point the client at sference

```python
import os
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.sference.com",
    api_key=os.environ["SFERENCE_API_KEY"],   # sent as x-api-key
)
```

`Authorization: Bearer` works too — pass `auth_token` instead of `api_key` if you prefer.

```python
message = client.messages.create(
    model="moonshotai/Kimi-K3",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Explain prefix caching."}],
)
print(message.content[0].text)
```

Model names are sference catalog ids. There are no `claude-*` aliases — a Claude model name returns `400`.

## Tool use

Anthropic's tool schema is served natively:

```python
tools = [{
    "name": "get_weather",
    "description": "Return the current weather for a city.",
    "input_schema": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"],
    },
}]

message = client.messages.create(
    model="zai-org/GLM-5.3",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "What is the weather in Ljubljana?"}],
)

for block in message.content:
    if block.type == "tool_use":
        result = get_weather(**block.input)
        # append the assistant turn and the tool_result, then call again
```

## Extended thinking

Reasoning models stream `thinking` blocks that clients render normally, but `signature` is always empty — multi-turn thinking continuity is best-effort. See [Extended thinking](https://sference.com/docs/api/messages#extended-thinking).

```python
message = client.messages.create(
    model="moonshotai/Kimi-K3",
    max_tokens=4096,
    thinking={"type": "enabled", "budget_tokens": 2048},
    messages=[{"role": "user", "content": "Plan a migration."}],
)
```

## Streaming

```python
with client.messages.stream(
    model="zai-org/GLM-5.3",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Write a haiku about GPUs."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
```

The SSE event sequence matches `api.anthropic.com`; the full list is on the [Anthropic Messages API](https://sference.com/docs/api/messages) page.

## The Claude Agent SDK

The Claude Agent SDK drives Claude Code's agent loop. Point it at sference and the loop runs on open models:

```bash
export ANTHROPIC_BASE_URL="https://api.sference.com"
export ANTHROPIC_AUTH_TOKEN="$SFERENCE_API_KEY"
export ANTHROPIC_MODEL="moonshotai/Kimi-K3"
```

For the CLI-level equivalent with hybrid routing — sference models in the `/model` picker, real Claude models passing through — use the launcher:

```bash
sference launch claude
```

See [Claude Code](https://sference.com/docs/sference-code/claude-code) for proxy mode, model recommendations, and known limits.

## Cost control

`/v1/messages` is **realtime only** — flex, background, and batch live on the OpenAI-shaped endpoints. Two levers still apply:

- **`prompt_cache_key` is not available on `/v1/messages`.** Prefix caching is automatic; hits appear as `cache_read_input_tokens` in the usage block. Keep the stable part of the prompt first so it can be reused. See [Prompt caching](https://sference.com/docs/guides/prompt-caching).
- **`max_queue_wait_s` is accepted** — bound the wait and fail over to another provider. See [Max queue wait](https://sference.com/docs/guides/max-queue-wait).
- **For long background steps, use the OpenAI-shaped surfaces.** A research or summarization step that nobody waits on can run on `/v1/responses` with `background: true` at 0.5 × list, while the interactive turn stays on `/v1/messages`.

## Known limits

| Limit | Effect |
| --- | --- |
| Empty thinking `signature` | Multi-turn thinking history degrades; nothing to verify |
| No `redacted_thinking` | Anthropic's encrypted thinking blocks are never produced |
| `budget_tokens`, `thinking: adaptive`, `effort`, `display` | Accepted and ignored; bound output with `max_tokens` |
| No prompt-caching controls | `cache_control` blocks are ignored; prefix caching is automatic |
| No server-side tools | Web search, code execution, and computer use are Anthropic-hosted and unavailable |
| Realtime only | No `service_tier: "flex"`, no background execution on `/v1/messages` |

The complete compatibility surface is on the [Anthropic Messages API](https://sference.com/docs/api/messages) page.

- [Anthropic Messages API](https://sference.com/docs/api/messages): Every supported field, block type, and streaming event.
- [Claude Code](https://sference.com/docs/sference-code/claude-code): One-command launch with hybrid routing.
- [Agent SDKs](https://sference.com/docs/agents): Compare frameworks and per-step window choices.
