# Python SDK（typesafe-sdk）で Jev に最初の判定をさせる

公式 Python SDK の typesafe-sdk で Jev を呼ぶ手順。インストール、API キーの設定、3種類の質問、答えの取り出し方、非同期クライアント、再試行の既定動作を実行結果つきで説明する。

- 正規URL: https://jevguide.jp/guides/python-sdk-quickstart/
- 公開: 2026-09-21T00:00:00.000Z
- 更新: 2026-09-21T00:00:00.000Z
- 最終確認: 2026-09-21T00:00:00.000Z
- 検証環境: typesafe-sdk 0.7.0 / Python 3.14 / jev-1.13.0（2026-09-21 に実行）

Python から Jev を使うなら、公式 SDK の **`typesafe-sdk`** が最短です。インストールして API キーを環境変数に入れれば、10行ほどで判定が返ります。

## 1. インストール

```bash
pip install typesafe-sdk
# または
uv add typesafe-sdk
```

パッケージ名は **`typesafe-sdk`**、import するときは **`typesafe_sdk`** です。PyPI には `typesafe` という無関係なライブラリがあるので、名前を間違えないでください。

## 2. API キー

[TypeSafe のコンソール](https://console.typesafe.ai/keys)でキーを発行し、環境変数 `TYPESAFE_API_KEY` に入れます。コードに直接書かないでください。

```bash
export TYPESAFE_API_KEY="…"
```

クライアントはこの環境変数を自動で読み、モデルは既定で `jev-latest` を使います。

## 3. 最初の判定

`TypeSafeClient` を作り、判定したい内容（`state`）と質問（`questions`）を `system_one` に渡します。質問は `Noul`・`Choice`・`Score` のクラスで組み立てます。

```python
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

with TypeSafeClient() as client:
    r = client.system_one(
        state={"message": "助けてください！3日前から入金がずっと失敗しています。"},
        questions={
            "is_urgent": Noul(instructions="Does `message` convey urgency?"),
            "department": Choice(
                instructions="Which team should handle `message`?",
                criteria={
                    "billing": "Payments, invoicing, refunds",
                    "technical": "Bugs, outages, integrations",
                    "other": None,
                },
            ),
            "frustration": Score(
                instructions="How frustrated is the customer?",
                criteria=["Calm", "Frustrated", "Very angry"],
            ),
        },
    )

print(r.model)                                  # jev-1.13.0
print(r.nouls["is_urgent"].noul)                # 0.96
print(r.choices["department"].choice)           # billing
print(r.choices["department"].confidence)       # 0.92
print(r.choices["department"].probabilities)    # {'billing': 0.95, 'other': 0.0, 'technical': 0.05}
print(r.scores["frustration"].score)            # 1.05
print(r.usage)                                  # input_tokens=415 output_tokens=73
```

コメントの値は、2026-09-21 に実際に返ってきたものです。

## 答えの取り出し方は2通り

| 書き方 | 向いている場面 |
| --- | --- |
| `r.nouls["…"]` / `r.choices["…"]` / `r.scores["…"]` | 型が分かっている。`.noul` `.choice` `.score` に補完が効く |
| `r.answers["…"]` | 質問のキーで一律に取り出したい |

`r.model` には、エイリアスではなく**実際に答えたバージョン ID** が入ります。ログに残しておくと、モデルが更新されたあとで結果を追えます（[料金と制限](/guides/pricing-and-limits/)）。

## 説明の要らない選択肢は None

Choice の `criteria` は「選択肢 → 説明」の辞書です。名前だけで意味が通る選択肢は、説明を `None` にできます。どれにも当てはまらない入力が来得るなら、上の例の `other` のような逃げ道を入れます（[質問タイプの書き方](/guides/question-types/)）。

## 非同期で使う

Web サーバーや、多数のリクエストを並行して送る処理では `AsyncTypeSafeClient` を使います。

```python
import asyncio
from typesafe_sdk import AsyncTypeSafeClient, Noul


async def main() -> None:
    async with AsyncTypeSafeClient() as client:
        r = await client.system_one(
            state={"document": "I was charged twice. Please fix this ASAP."},
            questions={"billing": Noul(instructions="Is this ticket about billing?")},
        )
    print(r.nouls["billing"].noul)


asyncio.run(main())
```

非同期の例は公式ドキュメントの形をそのまま示したもので、**このサイトで実行したのは同期クライアントだけ**です。

## 1件ずつ判定して数える

Jev は数えるのが苦手です。「条件に合うものは何件か」は、1件ずつ Noul で判定してコードで合計します。公式が示している書き方です。

```python
items = ["typesafe", "apple", "california", "banana", "likes", "calibration", "orange", "vertex"]

with TypeSafeClient(model="jev-1.13.0") as client:
    r = client.system_one(
        {"items": items},
        {f"item_{i}": Noul(instructions=f"Is `items[{i}]` the name of a fruit?") for i in range(len(items))},
    )

count = sum(r.nouls[f"item_{i}"].noul > 0.5 for i in range(len(items)))
```

実行すると、`apple` 0.99、`banana` 0.99、`orange` 0.98、それ以外は 0.01〜0.02 で、`count` は 3 になりました。8件を1回のリクエストで判定しています。

`TypeSafeClient(model=…)` でバージョンを固定できます。しきい値（ここでは 0.5）は用途に合わせて決めます。

## エラーと再試行

- `429`（レート制限）と `529`（過負荷）は、SDK が既定で間隔を空けて再試行します
- `401`（キーの誤り）や `422`（リクエストの形が不正）は再試行しても変わらないので、例外になります
- 回数・対象のステータス・待ち方は `RetryPolicy` で変えられます（[公式の Retries](https://docs.typesafe.ai/sdk/python/api/retries)）

エラー本文の形は [REST API の使い方](/guides/rest-api/) に実例を載せています。

## 次に読むもの

- 質問の書き方と選び方 → [3つの質問タイプ](/guides/question-types/)
- `state` に何を入れるか → [state の設計](/guides/designing-state/)
- やらせてはいけないこと → [Jev が苦手なこと](/guides/limitations/)

## よくある質問

### パッケージ名は typesafe ですか？

いいえ、typesafe-sdk です。PyPI には typesafe という名前の無関係なライブラリがあります。インストールは pip install typesafe-sdk、import は typesafe_sdk です。

### 必要な Python のバージョンは？

公式のクイックスタートには Python 3.10 以上とあります。このページの実行結果は Python 3.14 でのものです。

### 429 が返ったときの再試行は自分で書く必要がありますか？

既定では不要です。公式 SDK は 429 と 529 に対して間隔を空けた再試行を行い、retry-after ヘッダがあれば従う、と公式ドキュメントに書かれています。回数や対象は RetryPolicy で変えられます。

## 出典

- [Quick start](https://docs.typesafe.ai/introduction/quickstart)
- [TypeSafe Python SDK](https://docs.typesafe.ai/sdk/python)
- [PyPI: typesafe-sdk](https://pypi.org/project/typesafe-sdk/)
- [typesafe-sdk-python](https://github.com/typesafe-ai/typesafe-sdk-python)

---
typesafe.ai とは無関係の非公式ガイドです。
