> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sambanova.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Instructor

[Instructor](https://python.useinstructor.com/) は、SambaNova モデルによる構造化出力の生成を可能にするツールです。LLM の応答を JSON、XML、カスタムデータスキーマなどのあらかじめ定義された形式で出力させることができ、応答の一貫性を確保しつつ、パースや下流システムへの統合を容易にします。この機能は、API、自動化パイプライン、AI 駆動型アプリケーションなど、信頼性と予測可能性の高い出力が求められる場面で特に有用です。

## 前提条件

* [SambaCloud アカウント](https://cloud.sambanova.ai/?utm_source=instructor\&utm_medium=external\&utm_campaign=cloud_signup)
* [SambaNova API キー](https://cloud.sambanova.ai/apis?utm_source=instructor\&utm_medium=external\&utm_campaign=cloud_signup)
* Python 3.10 以上
* Pydantic v2。Instructor は `pydantic>=2.8` を必要とするため、`class Config` や `.dict()` のような Pydantic v1 の構文は本ページの例では動作しません
* 選択したモードに対応するモデル。[モードの選択](#モードの選択) をご参照ください
* Pydantic の知識があると理解しやすいですが、必須ではありません

<Note>
  Instructor のパッケージメタデータは Python 3.9 対応をうたっていますが、実際には 3.9 では動作しません。3.9 ではインストール自体は成功し、その後 `instructor.from_openai()` が `TypeError: Unable to evaluate type annotation 'str | Path'` で失敗します。これは、Instructor 自身のモジュールが `|` によるユニオン型構文を使用しており、Pydantic が実行時にその型アノテーションを評価するためです。macOS には 3.9 が同梱されており、`python` ではなく `python3` として公開されています。`python3 --version` でバージョンを確認し、必要に応じて [pyenv](https://github.com/pyenv/pyenv)、[uv](https://docs.astral.sh/uv/)、または `brew install python@3.12` で対応バージョンをインストールしてください。
</Note>

## インストール

仮想環境を作成して有効化し、Instructor をインストールします。

```bash theme={}
python3 -m venv .venv
source .venv/bin/activate
python --version
pip install instructor
```

Instructor は `openai` と `pydantic` に依存しているため、extra の指定は不要です。

次に API キーを設定します。本ページの例では、環境変数 `SAMBANOVA_API_KEY` から API キーを読み取ります。

```bash theme={}
export SAMBANOVA_API_KEY="your-sambanova-api-key"
```

<Note>
  本ページの例は `instructor` 1.15.4、`openai` 2.48.0、`pydantic` 2.13.4 で動作確認済みです。Instructor は 1.11 で一部のインポートパスを変更したため、これより古いリリースにピン留めする場合は、対応する名前を [Instructor のドキュメント](https://python.useinstructor.com/)でご確認ください。
</Note>

## 基本的な利用方法

以下のコードは、SambaCloud API と Instructor を使用して、`Meta-Llama-3.3-70B-Instruct` モデルから構造化出力を生成する例です。Pydantic を使って `User` スキーマを定義し、モデルに `name` (string) と `age` (integer) を含む応答を返すよう要求しています。Instructor が応答の検証とパースを行い、構造化された Python オブジェクトを生成します。

```python theme={}
from openai import OpenAI
import instructor
import os
from pydantic import BaseModel

client = instructor.from_openai(
    OpenAI(
        base_url="https://api.sambanova.ai/v1",
        api_key=os.environ["SAMBANOVA_API_KEY"]
    )
)

class User(BaseModel):
    name: str
    age: int

user = client.chat.completions.create(
    model="Meta-Llama-3.3-70B-Instruct",
    messages=[
        {"role": "user", "content": "Ivan is 28"},
    ],
    response_model=User,
)
print(user)
# > User(name='Ivan', age=28)
```

## モードの選択

`instructor.from_openai()` は、Instructor がモデルに構造化データを*どのように*要求するかを制御する `mode` 引数を受け取ります。上の例では指定していないため、デフォルトの `Mode.TOOLS` が使用されます。選択するモードは、使用するモデルが対応しているものと一致している必要があり、誤ったモードの選択が、本ページの例が失敗する最も一般的な原因です。

| モード | Instructor によるデータの要求方法 | モデル要件 |
| :- | :- | :- |
| `Mode.TOOLS` (デフォルト) | Pydantic スキーマをツール定義として送信し、返ってきたツール呼び出しを読み取ります | Function calling (関数呼び出し) |
| `Mode.JSON_SCHEMA` | スキーマを `response_format={"type": "json_schema", ...}` として送信します | JSON スキーマ対応 |
| `Mode.JSON` | `response_format={"type": "json_object"}` を送信し、スキーマをシステムメッセージに含めます | JSON モード |
| `Mode.MD_JSON` | Markdown コードブロック内の JSON を返すよう通常のテキストでモデルに依頼し、そこからパースします | 任意のチャットモデル |

本ページ全体で使用している `Meta-Llama-3.3-70B-Instruct` は Function calling に対応しているため、デフォルトの `Mode.TOOLS` が追加設定なしで動作します。Function calling、JSON スキーマ、JSON モードに対応する SambaCloud モデルの全一覧は [Function calling と JSON モード](/docs/ja/features/function-calling) を、最新のモデル ID とコンテキスト長は [SambaCloud モデル](/docs/ja/models/sambacloud-models) をご参照ください。

モードを明示的に指定するには、`Mode` をインポートして渡します。

```python theme={}
import instructor
from instructor import Mode
from openai import OpenAI
import os

client = instructor.from_openai(
    OpenAI(
        base_url="https://api.sambanova.ai/v1",
        api_key=os.environ["SAMBANOVA_API_KEY"]
    ),
    mode=Mode.JSON,
)
```

<Warning>
  デフォルトの `Mode.TOOLS` のまま Function calling に対応していないモデルに切り替えると、リクエストが API エラーを返すか、モデルがツールを呼び出さずに文章で回答します。その場合、Instructor は試行回数を使い切るまで再試行を繰り返し、`InstructorRetryException` を送出します。こうしたモデルでは、代わりに `Mode.JSON` または `Mode.MD_JSON` を使用してください。現在 SambaCloud で提供されているモデルのうち、`gemma-4-31B-it` は Function calling 対応モデルとして掲載されていません。
</Warning>

## 非同期での利用

以下のコードも同様に、SambaCloud API と Instructor を使用して構造化出力を強制します。結果は非同期で取得・出力され、`User(name='Ivan', age=28)` と表示されます。

```python theme={}
from openai import AsyncOpenAI
import instructor
import asyncio
import os
from pydantic import BaseModel

client = instructor.from_openai(
    AsyncOpenAI(
        base_url="https://api.sambanova.ai/v1",
        api_key=os.environ["SAMBANOVA_API_KEY"]
    )
)

class User(BaseModel):
    name: str
    age: int

async def get_user():
    user = await client.chat.completions.create(
        model="Meta-Llama-3.3-70B-Instruct",
        messages=[
            {"role": "user", "content": "Ivan is 28"},
        ],
        response_model=User,
    )
    return user

user = asyncio.run(get_user())
print(user)
# > User(name='Ivan', age=28)
```

<Note>
  Jupyter などのノートブック内では、ノートブック自体がすでにイベントループを実行しているため、`asyncio.run()` は `RuntimeError: asyncio.run() cannot be called from a running event loop` で失敗します。ノートブックのセルでは、代わりに `user = await get_user()` を使用してください。
</Note>

## ネストしたスキーマの抽出

実際の抽出タスクが 2 フィールドのモデルで収まることはほとんどありません。以下の例は、生のメールからサポートチケットを抽出するもので、本番環境で Instructor を信頼性高く使うためのポイントを示しています。

* `Field(description=...)` は、各フィールドの意味をモデルに伝えます。これは、抽出精度を高めるうえで単体では最も効果的な方法です。
* `Enum` は、フィールドの値を固定の選択肢に制約します。
* デフォルト値付きの `Optional[str]` を使うと、見つからない値をモデルがでっち上げる代わりに省略できるようになります。
* `field_validator` は、Pydantic の型では表現できないルールを強制します。バリデーターが例外を送出すると、Instructor はそのエラーをモデルに返して再試行します。

```python theme={}
import instructor
import os
from enum import Enum
from openai import OpenAI
from pydantic import BaseModel, Field, field_validator
from typing import Optional

client = instructor.from_openai(
    OpenAI(
        base_url="https://api.sambanova.ai/v1",
        api_key=os.environ["SAMBANOVA_API_KEY"]
    )
)

class Priority(str, Enum):
    low = "low"
    medium = "medium"
    high = "high"

class Customer(BaseModel):
    name: str = Field(description="Full name of the person who wrote the message.")
    email: Optional[str] = Field(
        default=None, description="Email address, or null if not stated."
    )

class SupportTicket(BaseModel):
    customer: Customer
    priority: Priority = Field(description="How urgent the request is.")
    summary: str = Field(description="One sentence describing the problem.")
    tags: list[str] = Field(
        default_factory=list, description="Up to three short topic tags."
    )

    @field_validator("tags")
    @classmethod
    def at_most_three_tags(cls, value: list[str]) -> list[str]:
        if len(value) > 3:
            raise ValueError("Return at most three tags.")
        return value

email = """
From: Dana Whitfield <dana.w@example.com>
Our production dashboard has been down since 3am and the whole team is blocked.
"""

ticket = client.chat.completions.create(
    model="Meta-Llama-3.3-70B-Instruct",
    messages=[{"role": "user", "content": email}],
    response_model=SupportTicket,
    max_retries=3,
)
print(ticket.model_dump_json(indent=2))
```

## 検証エラーへの対処

モデルがスキーマを満たさない出力を返したとき、Instructor は壊れた出力をそのまま渡しません。検証エラーを会話に追記してモデルに再度問い合わせ、これを最大 `max_retries` 回繰り返します。`client.chat.completions.create()` の `max_retries` のデフォルトは `3` です。

すべての試行が失敗すると、Instructor は `InstructorRetryException` を送出します。この例外をキャッチすれば、モデルが実際に何を生成したのかを、推測ではなく確認できます。

```python theme={}
from instructor.core import InstructorRetryException

try:
    ticket = client.chat.completions.create(
        model="Meta-Llama-3.3-70B-Instruct",
        messages=[{"role": "user", "content": email}],
        response_model=SupportTicket,
        max_retries=3,
    )
except InstructorRetryException as exc:
    print(f"Gave up after {exc.n_attempts} attempts")
    print(f"Total token usage: {exc.total_usage}")
    for attempt in exc.failed_attempts:
        print(f"Attempt {attempt.attempt_number} failed: {attempt.exception}")
    print(f"Last raw completion: {exc.last_completion}")
```

<Note>
  例外は `instructor.core` からインポートしてください。従来の `instructor.exceptions` パスも引き続き動作しますが、Instructor 1.11 以降は `DeprecationWarning` が出力されます。
</Note>

再試行しても収束しない場合は、以下を順に試してください。

1. **失敗したフィールドの `Field(description=...)` を追加・明確化します。** 曖昧なフィールド名が最も一般的な原因です。
2. **スキーマを緩めます。** 元のテキストに値が本当に含まれていない可能性があるなら、そのフィールドを `Optional` にします。見つけられない値をモデルに強制すると、再試行が確実に発生します。
3. **`max_retries` を増やします。** 失敗が構造的ではなく散発的な場合に有効です。
4. **モデルを切り替えます。** より大きなモデルほど、深くネストしたスキーマを確実に処理できます。[SambaCloud モデル](/docs/ja/models/sambacloud-models) をご参照ください。
5. **モードを切り替えます。** モデルが Function calling に対応していない場合、`Mode.TOOLS` は何度再試行しても成功しません。[モードの選択](#モードの選択) をご参照ください。

## 次のステップ

* メール分類ツールの作成方法を解説した[サンプルノートブック](https://github.com/sambanova/integrations/blob/main/instructor/email_classification.ipynb)をご覧ください。
* [Function calling と JSON モード](/docs/ja/features/function-calling) で、Instructor と SambaCloud ネイティブのアプローチを比較してください。
* [SambaCloud モデル](/docs/ja/models/sambacloud-models) で利用可能なモデル ID をご確認ください。

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

<AccordionGroup>
  <Accordion title="InstructorRetryException: max retries exceeded">
    すべての試行でモデルの出力が Pydantic の検証に失敗しました。Instructor は自動的に再試行し (`max_retries` のデフォルトは `3`)、最後の試行が失敗した時点でこの例外を送出するため、根本原因である検証エラーはトレースバックのさらに下に表示されます。モデルが各フィールドの期待値を理解できるようスキーマに `Field(description=...)` を追加する、`max_retries` を増やす、より高性能なモデルを試す、のいずれかを行ってください。失敗した各試行を確認する方法は [検証エラーへの対処](#検証エラーへの対処) をご参照ください。
  </Accordion>

  <Accordion title="モデルがオブジェクトを返さず文章で回答する">
    モードとモデルが一致していません。`instructor.from_openai()` のデフォルトは `Mode.TOOLS` で、モデルが Function calling に対応している必要があります。対応していない場合、モデルは会話調で応答し、検証が毎回失敗して `InstructorRetryException` になります。`Mode.JSON` または `Mode.MD_JSON` に切り替えるか、Function calling に対応するモデルを選択してください。[モードの選択](#モードの選択) をご参照ください。
  </Accordion>

  <Accordion title="KeyError: SAMBANOVA_API_KEY">
    実行前にキーをエクスポートしてください: `export SAMBANOVA_API_KEY="your-key"`。`echo $SAMBANOVA_API_KEY` で確認できます。
  </Accordion>

  <Accordion title="ModuleNotFoundError: No module named 'instructor'">
    `pip install instructor` でインストールしてください。すでにインストール済みの場合は、仮想環境が有効になっていません。`source .venv/bin/activate` を実行し、プロンプトに `(.venv)` が表示されることを確認してください。
  </Accordion>

  <Accordion title="TypeError: Unable to evaluate type annotation 'str | Path'">
    Python 3.9 を使用しています。Instructor は 3.9 にもインストールできますが、Instructor 自身のモジュールが 3.10 以上を必要とする `|` ユニオン構文を使用しており、Pydantic がそのアノテーションを実行時に評価します。`import instructor` は成功するため、失敗はインストール時ではなく `instructor.from_openai()` の時点で発生します。Python 3.10 以上で環境を作り直してください。
  </Accordion>

  <Accordion title="ValidationError: Input should be 'low', 'medium' or 'high'">
    モデルが `Enum` の範囲外の値を返しました。許可される値と、それぞれをいつ使うべきかを明記した `Field(description=...)` を追加してください。Instructor は自動的に再試行するため、これがエラーとして表面化するのは、すべての試行が失敗した場合のみです。
  </Accordion>
</AccordionGroup>
