> For the complete documentation index, see [llms.txt](https://unsloth.ai/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unsloth.ai/docs/zh/ji-cheng/jiang-python-sdk-lian-jie-dao-unsloth.md).

# 将 Python SDK 连接到 Unsloth

Unsloth 在同一个基础 URL 上提供三种兼容 OpenAI 的接口：Chat Completions、Responses 和 Anthropic Messages，因此所有主流 Python SDK 都可以直接对接它。 \
\
你只需要修改 `base_url` 和 `api_key`  在客户端上；其他所有内容（流式传输、工具调用、视觉、结构化输出）都按 SDK 文档中的方式运行。本页涵盖大多数开发者首先会用到的两个 SDK：官方的 **OpenAI Python SDK** 和官方的 **Anthropic Python SDK**.

{% hint style="info" %}
如果你不确定该使用哪个 URL / key / 模型名，请先阅读 API 概览。它会带你了解如何启动、加载模型，以及创建一个 `sk-unsloth-…` 密钥。
{% endhint %}

### 🔑 前提条件

在运行下面任何示例之前，你需要：

* **Unsloth 在本地运行** 并已加载模型（注意端口：通常是 `8000` 或 `8888`).
* **一个 `sk-unsloth-…` API 密钥** 通过 **Settings → API**.
* **A model name.** 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": "给我两个关于巴黎的事实"}
    ],
)
print(response.choices[0].message.content)
```

<figure><img src="/files/b25c83bed55a3a2fbe0b174082537730e922d66e" 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/7c0d4d294d3a4f095f7579d9fcebe50b358517dd" 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/ba97778dc258b749b3399352b3ce68e9ffcef919" 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/7c20113057a2ae6cafb2b75dbf87da0c19deca2b" 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/bb2ebf08a4dce7fb07e8f7e2002003f33f9df992" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/fd2243da7fe17c1c222835ec902327cf5166c648" 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/3e68ee298728c5ef0eedf658691fd33fdc748621" 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": "用三种语言打招呼。"}
    ],
)
print(message.content[0].text)
```

<figure><img src="/files/8c92f6d9c5690fab7679b1d83c74a12dee962d03" alt=""><figcaption></figcaption></figure>

#### 流式传输

该 SDK 提供了一个上下文管理器，会输出文本增量：

```python
with client.messages.stream(
    model="default",
    max_tokens=1024,
    messages=[{"role": "user", "content": "用两句话解释 LoRA。"}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
```

#### 图像（视觉）

Anthropic 风格的图像内容使用一个 `source` 带有 base64 数据的 block：

```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/bc4742f79526760202866ac1b5c04b4af1454eb9" 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/6f32b32383bfc3aa91a69c46f3c732880b2df72d" 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/d7f50915a4473553530f9e612ae5753514a7e2a0" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/90b989d3055866e60ebde785a4c13fb92b89c6b3" 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": "选择一个国家：日本、埃及或秘鲁。用一句话解释原因。",
        },
    ],
    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("国家：", parsed["country"])
print("原因：", parsed["reason"])
````

其中 `strict: True` 该标志会告诉 Unsloth 在解码过程中强制执行该 schema，而不是依赖模型自行遵守。 `additionalProperties: False` 和 `required` 在标准 JSON Schema 中的作用一样。

终端输出大致如下：

<figure><img src="/files/bedb8a1a458eb63057ae0b0ebf2fc5d9020d93ae" 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("国家：", parsed\["country"]) print("原因：", parsed\["reason"])

### 🧪 选择 SDK

两个 SDK 都可以对接 Unsloth。正确的选择取决于你技术栈的其他部分：

* 使用 **OpenAI SDK** 如果你的代码已经依赖 OpenAI Python 包，且你希望使用 OpenAI 风格的 `tools` / `tool_choice`，或者你计划调用 Responses API。
* 使用 **Anthropic SDK** 如果你的代码已经依赖 Anthropic 包，且你更喜欢 Anthropic 的 `input_schema` 工具格式，或者你想要 Anthropic 原生的流式事件类型。

你可以在同一个项目中同时使用二者。Unsloth 会在同一个端口上提供它们，因此一个单独的 `sk-unsloth-…` 密钥即可同时认证二者。

### ❔ 故障排查

**`401 Unauthorized`**  其中 `UNSLOTH_STUDIO_API_KEY` 环境变量未设置，或者密钥错误。重新导出并用以下命令确认： `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 概览页面。

### 可选：设置服务器默认值

当使用 `unsloth run` 命令时，你可以在通过 Python SDK 连接之前配置默认的服务器行为。

```bash
# 使用自定义默认值启动服务器
unsloth run \
  --model unsloth/Qwen3-1.7B-GGUF \
  --reasoning off \
  --temp 0.6 \
  -p 8888
```

使用 `--reasoning off` 可关闭思考，或 `--reasoning on` 对支持推理的模型开启它。

```bash
# 在你的本地网络中公开 API
unsloth run \
  --model unsloth/Qwen3-1.7B-GGUF \
  -H 0.0.0.0 \
  -p 8888
```

这会将服务器启动在 `0.0.0.0:8888`，允许本地网络上的其他设备连接。

当请求未指定自己的生成参数时，这些设置会成为服务器默认值。

请求级别的值，例如 `temperature`, `top_p`, `max_tokens`、以及 `stream` 仍然可以覆盖该请求的默认值。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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/zh/ji-cheng/jiang-python-sdk-lian-jie-dao-unsloth.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.
