Python から Jev を使うなら、公式 SDK の typesafe-sdk が最短です。インストールして API キーを環境変数に入れれば、10行ほどで判定が返ります。
1. インストール
pip install typesafe-sdk
# または
uv add typesafe-sdk
パッケージ名は typesafe-sdk、import するときは typesafe_sdk です。PyPI には typesafe という無関係なライブラリがあるので、名前を間違えないでください。
2. API キー
TypeSafe のコンソールでキーを発行し、環境変数 TYPESAFE_API_KEY に入れます。コードに直接書かないでください。
export TYPESAFE_API_KEY="…"
クライアントはこの環境変数を自動で読み、モデルは既定で jev-latest を使います。
3. 最初の判定
TypeSafeClient を作り、判定したい内容(state)と質問(questions)を system_one に渡します。質問は Noul・Choice・Score のクラスで組み立てます。
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 が入ります。ログに残しておくと、モデルが更新されたあとで結果を追えます(料金と制限)。
説明の要らない選択肢は None
Choice の criteria は「選択肢 → 説明」の辞書です。名前だけで意味が通る選択肢は、説明を None にできます。どれにも当てはまらない入力が来得るなら、上の例の other のような逃げ道を入れます(質問タイプの書き方)。
非同期で使う
Web サーバーや、多数のリクエストを並行して送る処理では AsyncTypeSafeClient を使います。
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 で判定してコードで合計します。公式が示している書き方です。
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)
エラー本文の形は REST API の使い方 に実例を載せています。
次に読むもの
- 質問の書き方と選び方 → 3つの質問タイプ
stateに何を入れるか → state の設計- やらせてはいけないこと → Jev が苦手なこと
よくある質問
パッケージ名は 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
- 一次情報 TypeSafe Python SDK
- 一次情報 PyPI: typesafe-sdk
- 一次情報 typesafe-sdk-python