# Python SDKをUnslothに接続

Unsloth は、同じベース URL 上で OpenAI 互換の 3 つの方言を提供します。Chat Completions、Responses、Anthropic Messages に対応しているため、主要な Python SDK はどれもこれに対して動作します。\
\
変更するのは次のものだけです `base_url` と `api_key`  をクライアント側で変更します。それ以外のすべて（ストリーミング、ツール呼び出し、ビジョン、構造化出力）は、SDK のドキュメントに記載されているとおりに動作します。このページでは、多くの開発者が最初に使う 2 つの SDK を扱います。公式の **OpenAI Python SDK** と公式の **Anthropic Python SDK**.

{% hint style="info" %}
どの URL / キー / モデル名を使えばよいかわからない場合は、まず API 概要を読んでください。開始方法、モデルの読み込み方法、そして `sk-unsloth-…` キー。
{% endhint %}

### 🔑 前提条件

以下のスニペットを実行する前に、次のものが必要です:

* **Unsloth がローカルで実行されていること** モデルが読み込まれている状態で（ポートに注意: 通常は `8000` または `8888`).
* **1 つの `sk-unsloth-…` API キー** で作成された **設定 → API**.
* **モデル名。** Unsloth 内の GGUF モデル名（例: `qwen-local`, `unsloth/Qwen3.6-27B-GGUF`）。忘れた場合は、次を実行してください:

  ```bash
  curl http://localhost:8888/v1/models -H "Authorization: Bearer sk-unsloth-…"
  ```

  そして `id` フィールドをコピーします。

コードに貼り付けなくて済むように、キーを環境変数として設定してください:

```bash
export UNSLOTH_STUDIO_AUTH_TOKEN=sk-unsloth-xxxxxxxxxxxx
```

#### 🤖 OpenAI SDK

Unsloth の `/v1/chat/completions` エンドポイントは、OpenAI Python SDK のドロップインとして使えます。クライアントは Unsloth を他の OpenAI 互換プロバイダーと同じように扱います。

**1. SDK をインストールします:**

```bash
pip install openai
```

**2. クライアントを作成し、** Unsloth を向くように設定します:

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8888/v1",              # あなたの unsloth のポート + /v1
    api_key=os.environ["UNSLOTH_STUDIO_AUTH_TOKEN"],     # あなたの sk-unsloth-… キー
)
```

#### 基本的なチャット補完

```python
response = client.chat.completions.create(
    model="default",                               # unsloth でモデルに付けた名前、または default
    messages=[
        {"role": "user", "content": "パリについて 2 つの事実を教えて"}
    ],
)
print(response.choices[0].message.content)
```

<figure><img src="/files/012867ddd668cfd33718609f5f885239e5b81a50" alt=""><figcaption></figcaption></figure>

#### ストリーミング

設定します `stream=True` そして返されたジェネレーターを反復処理します:

```python
stream = client.chat.completions.create(
    model="qwen-local",
    messages=[{"role": "user", "content": "ローカルで実行される LLM について俳句を書いてください。"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices:
        delta = chunk.choices[0].delta.content
        if delta:
            print(delta, end="", flush=True)
```

<figure><img src="/files/5aa642c57b363507893746cea587535db0e01048" alt=""><figcaption></figcaption></figure>

#### 画像（ビジョン）

画像を `image_url` コンテンツパートとして添付します。Unsloth は HTTP(S) URL または `data:` base64 URI:

```python
import base64
from pathlib import Path

img_b64 = base64.b64encode(Path("test.jpg").read_bytes()).decode()

response = client.chat.completions.create(
    model="default",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url": f"data:image/jpeg;base64,{img_b64}"},
                },
                {"type": "text", "text": "この画像には何が写っていますか？"},
            ],
        }
    ],
)
print(response.choices[0].message.content)
```

{% hint style="info" %}
読み込まれたモデルはマルチモーダルである必要があります。テキスト専用モデルを読み込んだ場合、ビジョンリクエスト自体は構造的には成功しますが、モデルは画像を「見る」ことができません。
{% endhint %}

<figure><img src="/files/998d4fc1ac5337df1cc0264011a3d6ccf65dd2c2" alt=""><figcaption></figcaption></figure>

#### 関数呼び出し（OpenAI ツール）

OpenAI スタイルの `tools` と（任意で） `tool_choice` を渡すと、Unsloth はそれらをバックエンドへ転送します。クライアントは各ツール呼び出しを実行し、次のターンでその結果を返す責任を負います:

```python
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "都市の現在の天気を取得する",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "都市名。例: 'Paris'"},
                },
                "required": ["city"],
            },
        },
    }
]

response = client.chat.completions.create(
    model="default",
    messages=[{"role": "user", "content": "今のパースの天気は？"}],
    tools=tools,
    tool_choice="auto",
)

tool_call = response.choices[0].message.tool_calls[0]
print(tool_call.function.name, tool_call.function.arguments)
```

<figure><img src="/files/fa79eb120191e848f9f03d9d50a626ecc18c4790" alt=""><figcaption></figcaption></figure>

#### Unsloth のサーバー側ツール（省略記法）

OpenAI スタイルのクライアント側ツールに加えて、Unsloth は **Python**, **bash**、および **ウェブ検索** をサーバー側で実行し、その結果を自動的にストリームで返すことができます。 `extra_body` パラメーターを使って有効化すると、フィールドはそのまま Unsloth に渡されます:

```python
stream = client.chat.completions.create(
    model="default",
    messages=[{"role": "user", "content": "123 * 456 は何ですか？ Python を使って計算してください。"}],
    stream=True,
    extra_body={
        "enable_tools": True,
        "enabled_tools": ["python", "web_search"],
        "session_id": "my-session",
    },
)
for chunk in stream:
    if chunk.choices:
        delta = chunk.choices[0].delta.content
        if delta:
            print(delta, end="", flush=True)
```

<figure><img src="/files/445309a3e703114c915053551824e25aa7b24fce" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/2758798df66209fa1bef9fed31cbe469c65adf38" alt=""><figcaption></figcaption></figure>

この `session_id` は任意です。呼び出し間でツールの状態（例: Python カーネル）を保持するために使います。

{% hint style="info" %}
`enabled_tools` は現在、次をサポートしています `"python"`, `"bash"`、および `"web_search"`。ツールの結果は `tool_result` イベントとしてストリームで返されるため、モデルは次のターンでそれらを見ることができます。
{% endhint %}

**モデル一覧**

```python
models = client.models.list()
for m in models.data:
    print(m.id)
```

<figure><img src="/files/ec74b1d9ae419354fd7a6350f5e48786d684ecb9" alt=""><figcaption></figcaption></figure>

#### 🧠 Anthropic SDK

Unsloth の `/v1/messages` エンドポイントは、Anthropic Python SDK のドロップインとして使えます。

**1. SDK をインストールします:**

```bash
pip install anthropic
```

**2. クライアントを作成し、** Unsloth を向くように設定します:

```python
import os
from anthropic import Anthropic

client = Anthropic(
    base_url="http://localhost:8888",                 # あなたの unsloth のポート（ここには /v1 を付けません - SDK が追加します）
    api_key="dummy",                                  # 空でない適当な値
    default_headers={"Authorization": "Bearer {os.environ['UNSLOTH_STUDIO_AUTH_TOKEN']}"} # あなたの sk-unsloth-… キー
)
```

#### 基本的なメッセージ

```python
message = client.messages.create(
    model="default",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "3 つの言語でこんにちはと言って。"}
    ],
)
print(message.content[0].text)
```

<figure><img src="/files/db95db8d6491662984479b312a9706f2055477b0" alt=""><figcaption></figcaption></figure>

#### ストリーミング

SDK はテキスト差分を生成するコンテキストマネージャーを提供します:

```python
with client.messages.stream(
    model="default",
    max_tokens=1024,
    messages=[{"role": "user", "content": "LoRA を 2 文で説明してください。"}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
```

#### 画像（ビジョン）

Anthropic スタイルの画像コンテンツでは、 `source` ブロックと base64 データを使用します:

```python
import base64
from pathlib import Path

img_b64 = base64.standard_b64encode(Path("photo.jpg").read_bytes()).decode()

message = client.messages.create(
    model="default",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/jpeg",
                        "data": img_b64,
                    },
                },
                {"type": "text", "text": "この画像には何が写っていますか？"},
            ],
        }
    ],
)
print(message.content[0].text)
```

<figure><img src="/files/73325815d89d5982e7c93357750621f8deedf5e4" alt=""><figcaption></figcaption></figure>

#### ツール呼び出し（Anthropic ツール）

Anthropic スタイルの `tools` を `input_schema` 付きで渡すと、Unsloth はそれらをネイティブに転送します:

```python
tools = [
    {
        "name": "get_weather",
        "description": "都市の現在の天気を取得する",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "都市名。例: 'Tokyo'"},
            },
            "required": ["city"],
        },
    }
]

message = client.messages.create(
    model="default",
    max_tokens=1024,
    tools=tools,
    tool_choice={"type": "auto"},
    messages=[{"role": "user", "content": "東京の天気は？"}],
)

for block in message.content:
    if block.type == "tool_use":
        print(block.name, block.input)
```

<figure><img src="/files/4308dd60aa7c2b71daebbdedcf7a1fbb898913c8" alt=""><figcaption></figcaption></figure>

#### Unsloth のサーバー側ツール（省略記法）

同じ `enable_tools` / `enabled_tools` / `session_id` 省略記法が `/v1/messages` そのまま渡す `extra_body`:

```python
with client.messages.stream(
    model="default",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Python 3.13 の機能を検索して要約してください。"}],
    extra_body={
        "enable_tools": True,
        "enabled_tools": ["web_search", "python"],
        "session_id": "my-session",
    },
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
```

<figure><img src="/files/ad29237e24c0d86332355b4beb915f48a71b0eb3" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/f7b1a2366de47fb27859e4e557e4a42c2ffb198d" alt=""><figcaption></figcaption></figure>

Unsloth はカスタム `tool_result` SSE イベントを、各ツール呼び出しの出力に対するモデル視点として発行します。Anthropic SDK はこれらをそのままイベントストリームに通します。

#### JSON デコード（`response_format`)

Unsloth は OpenAI スタイルの構造化出力を `response_format`でサポートしています。JSON Schema を渡すと、モデルはそれに一致する JSON を生成するよう制約されます。

````python
import json
import os
import re
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8888/v1",
    api_key=os.environ["UNSLOTH_STUDIO_AUTH_TOKEN"],
)

response = client.chat.completions.create(
    model="default",
    stream=False,
    temperature=0.0,
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": "国を 1 つ選んでください: Japan、Egypt、または Peru。理由を 1 文で説明してください。",
        },
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "country_pick",
            "schema": {
                "type": "object",
                "properties": {
                    "country": {"type": "string", "enum": ["Japan", "Egypt", "Peru"]},
                    "reason":  {"type": "string"},
                },
                "required": ["country", "reason"],
                "additionalProperties": False,
            },
            "strict": True,
        },
    },
)

raw = response.choices[0].message.content
# Gemma 4 が JSON の周りに付ける markdown フェンスを取り除いてから、パースします。
cleaned = re.sub(r"^```(?:json)?\s*", "", raw)
cleaned = re.sub(r"\s*```$", "", cleaned)
parsed = json.loads(cleaned)

print(json.dumps(parsed, indent=2))
print()
print("country:", parsed["country"] )
print("reason :", parsed["reason"] )
````

この `strict: True` フラグは、モデルが自力で従うことに頼るのではなく、デコード中に Unsloth がスキーマを強制するよう指示します。 `additionalProperties: False` と `required` は標準の JSON Schema と同様に機能します。

端末の出力はおおよそ次のようになります:

<figure><img src="/files/66a0ec61980b75db7c197b27c2277781bd7cb8b4" alt=""><figcaption></figcaption></figure>

## Gemma 4 が JSON の周りに付ける markdown フェンスを取り除いてから、パースします。

cleaned = re.sub(r"^`(?:json)?\s*", "", raw) cleaned = re.sub(r"\s*`$", "", cleaned) parsed = json.loads(cleaned)

print(json.dumps(parsed, indent=2)) print() print("country:", parsed\["country"]) print("reason :", parsed\["reason"] )

### 🧪 SDK の選び方

どちらの SDK も Unsloth に対して動作します。適切な選択は、スタックの残りの部分によって決まります:

* 次を使用してください **OpenAI SDK** コードがすでに OpenAI Python パッケージに依存している場合、OpenAI スタイルの `tools` / `tool_choice`、または Responses API を呼び出す予定がある場合。
* 次を使用してください **Anthropic SDK** コードがすでに Anthropic パッケージに依存している場合、Anthropic の `input_schema` ツール形式を好む場合、または Anthropic ネイティブのストリーミングイベント型を使いたい場合。

同じプロジェクトで両方を使うこともできます。Unsloth は同じポートでそれらを提供するため、1 つの `sk-unsloth-…` キーで両方を認証できます。

### ❔ トラブルシューティング

**`401 Unauthorized`**  この `UNSLOTH_STUDIO_API_KEY` 環境変数が設定されていないか、キーが間違っています。再度 export して、次で確認してください `echo $UNSLOTH_STUDIO_API_KEY`.

**`404 Not Found` OpenAI SDK からの** 次を確認してください `base_url` 次で終わっていること `/v1`。OpenAI SDK はエンドポイントパスをベース URL にそのまま追加します。

**`404 Not Found` Anthropic SDK からの** 次を確認してください `base_url` 次が **ない** 次で終わっている `/v1`。Anthropic SDK は `/v1/messages` 自分で追加します。

**`extra_body` フィールドが Unsloth に届いていません** 最近の `openai` / `anthropic` SDK を使っていることを確認してください。古いバージョンは未知のフィールドを黙って破棄します。次でアップグレードしてください `pip install -U openai anthropic`.

**ストリーミングが「固まった」あとに一度に全部出力される** 出力を包んでいるものがバッファリングしています。スクリプトでは、 `print(..., flush=True)`; ノートブックでは通常問題ありません。プロキシの背後では、プロキシ側でレスポンスのバッファリングを無効にしてください。

エンドポイントレベルの問題（ポート違い、モデルが読み込まれない、接続切れなど）については、API 概要ページを参照してください。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unsloth.ai/docs/jp/tong-he/python-sdkwounslothni.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
