Lesson CH01-L04
静的型チェック
Pyrightとの組み合わせで Agent の入出力を型で守る。
- 読了目安
- 10 min
- Colab目安
- 16 min
- 合計
- 26 min
- 前提
- Reflection
関連: 公式ドキュメント
一行サマリ
Agent は ジェネリッククラス Agent[DepsT, OutputT]。deps_type= と output_type= を渡すと Pyright / mypy が型を自動推論 し、result.output の補完・agent.run(deps=...) の引数チェック・Tool / Validator の引数まで全部 IDE で間違いを赤線にできる。
ヒーロー: 型なし vs 型あり Agent
PydanticAI の Agent は型付きで設計されています。output_type と deps_type を渡すかどうかで、IDE 体験が大きく変わります。
概念: なぜ Agent に静的型が必要か
Agent はテキストを LLM に投げて返ってくる "ふわっとした" インタフェースです。だからこそ 境界面 (入出力 / 依存) を型で固める とコードが堅くなります。
具体的に効く 4 つの場面:
result.outputの補完 —output_type=Bookingと書けばresult.output.party_sizeのように Pydantic フィールドが補完されるagent.run(..., deps=...)の型一致 —deps_type=UserContextを宣言すれば、deps=DifferentType()を渡したら Pyright が赤線を出す- Tool / Validator の
RunContext[DepsT]—ctx.depsの中身が補完で出る - リファクタリング耐性 — Pydantic モデルにフィールド追加 → IDE が利用箇所をハイライト → 直す
これらは 実行しないと気付けないバグを書き始める前に潰せる、という型システム本来の効能を Agent コードでも享受するためのものです。
コード: 4 段階で型を効かせる
ステップ 0: 型なし (反例)
from pydantic_ai import Agent
agent = Agent('google-gla:gemini-3-flash-preview')
result = agent.run_sync('Mojito とは?')
# result.output は str として推論される (デフォルト)
print(result.output.upper()) # OK だが、構造化情報が一切無い
print(result.output.party_size) # ← 実行時 AttributeError、IDE は気付かないこれでは Agent から取れる情報が "テキスト 1 本" だけで、構造化されません。
ステップ 1: output_type で出力を型付け
from pydantic import BaseModel
from pydantic_ai import Agent
class Cocktail(BaseModel):
name: str
origin: str
abv_percent: float # アルコール度数
agent = Agent(
'google-gla:gemini-3-flash-preview',
output_type=Cocktail, # ← これを渡すだけで result.output: Cocktail と推論される
)
result = agent.run_sync('Mojito の情報を返してください')
# Pyright は result.output を Cocktail として認識する
print(result.output.name) # ✅ 補完が効く
print(result.output.abv_percent) # ✅ 補完が効く
print(result.output.party_size) # ❌ Pyright が "no attribute" の赤線を出すポイント: output_type= の引数は クラスそのもの を渡します。Pyright はそのクラスを OutputT として保持し、run_sync().output の型に伝播します。
ステップ 2: deps_type で依存も型付け
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
@dataclass
class CocktailDeps:
user_lang: str
is_minor: bool # 未成年フラグ
agent = Agent(
'google-gla:gemini-3-flash-preview',
deps_type=CocktailDeps,
output_type=Cocktail,
)
@agent.instructions
def lang_policy(ctx: RunContext[CocktailDeps]) -> str:
if ctx.deps.is_minor:
return 'ノンアルコール版を提案してください。'
return f'回答は {ctx.deps.user_lang} で。'
# Pyright は deps の型を CocktailDeps と知っている
result = agent.run_sync(
'Mojito の情報',
deps=CocktailDeps(user_lang='ja', is_minor=False), # ✅
)
# 違う型を渡したら IDE で赤線:
# result = agent.run_sync('...', deps={'lang': 'ja'}) # ❌ dict は CocktailDeps ではないポイント:
deps_type=を渡すと、agent.run(..., deps=...)の型が CocktailDeps に固定されるRunContext[CocktailDeps]の型注釈でctx.deps.user_langやctx.deps.is_minorが 補完されるdeps_typeを渡さない場合、deps=を渡すこと自体が型エラーになる (PydanticAI v0.x 時点)
ステップ 3: ジェネリック型を明示宣言する書き方
ステップ 2 と等価ですが、Agent の型を変数アノテーションで明示 する書き方もあります。テストで Mock Agent を渡したいときなどに役立ちます。
from pydantic_ai import Agent
agent: Agent[CocktailDeps, Cocktail] = Agent(
'google-gla:gemini-3-flash-preview',
deps_type=CocktailDeps,
output_type=Cocktail,
)Agent[CocktailDeps, Cocktail] の型パラメタは Agent[DepsT, OutputT] の順番です。これを覚えておくと、関数の引数で Agent を受けたいとき (テストやサービス層) に正確な型を書けます。
def run_cocktail_query(
agent: Agent[CocktailDeps, Cocktail],
query: str,
deps: CocktailDeps,
) -> Cocktail:
return agent.run_sync(query, deps=deps).outputPyright の最小セットアップ
ローカル開発で型チェックを効かせるには:
# プロジェクトに入れる場合
pip install pyright
# 1 ファイルだけチェック
pyright my_agent.py
# 監視モードで保存ごとに再チェック
pyright --watchVS Code を使うなら Pylance 拡張 を入れるだけで Pyright が IDE に統合されます。pyrightconfig.json で strict モードを有効化すると、型注釈漏れも警告できます。
{
"include": ["src"],
"typeCheckingMode": "strict",
"reportMissingTypeStubs": false
}どんなときに型を "省く" 選択をするか
型を全部書くのが正解ではありません。次のような状況では deps_type / output_type 省略も妥当です。
| 状況 | 推奨 |
|---|---|
| 1 行のスクリプト・REPL でテキスト応答だけ欲しい | 型なしで十分 |
| Colab セルで挙動確認しているだけ | 型なし or output_type だけ |
| 業務ロジックに組み込む / 複数人で触る | deps_type + output_type 両方を必ず付ける |
| LLM 応答を後段の関数に渡す | output_type 必須 (型不一致を IDE で検出) |
| Agent 自体を関数引数で受ける | Agent[DepsT, OutputT] を関数シグネチャに書く |
まとめ
Agent[DepsT, OutputT]はジェネリッククラス。deps_type=/output_type=を渡せば Pyright が型を自動推論する- 効く場面は 4 つ:
result.outputの補完 /deps=の型一致 /RunContext[DepsT]のctx.deps補完 / リファクタリング耐性 - 関数引数で Agent を受けるときは
Agent[DepsT, OutputT]をシグネチャに書く - スクリプト用途なら型省略も OK。業務コード・複数人開発では両方必須
これで Ch1「Core: Agents」全 4 レッスンが完了です。次の Ch2「Dependencies」 からは、Agent に外部リソース (DB / HTTP クライアント / 設定) を安全に注入する DI のパターンと、TestModel と組み合わせたユニットテストを扱います。
Colab で実際に動かす
本レッスンの内容を Google Colab 上で実行できるノートブックを用意しています。下のボタンから自分のColab環境に開けます (要 Google アカウント / GOOGLE_API_KEY)。
notebooks/ch01/04-static-type-check.ipynb