PydanticAI ビジュアルガイド

Lesson CH01-L02

Dynamic Instructions

依存値や時刻に応じてシステムプロンプトを差し替える。

読了目安
11 min
Colab目安
18 min
合計
29 min
前提
Static Instructions

一行サマリ

@agent.instructions デコレータで関数を登録すると、毎回の run ごとに instructions を組み立て直せる。現在時刻・ユーザー固有値・DI で渡したオブジェクトなど「実行時にしか分からない情報」を system message に流し込めるようになる。

ヒーロー: Static と Dynamic の関係

Static Instructions (前レッスン) と Dynamic Instructions は 排他ではなく合算 されます。Agent を作るときの固定文字列 + 関数で生成した文字列の 両方 が、毎回の run で system message として LLM に渡されます。

図を読み込み中…
図1. Static + Dynamic は run のたびに合成される

概念: なぜ動的が必要か

Static Instructions はコードを書く時点で確定する固定文字列でした。しかし実用シナリオでは、「コード時点では決められない情報」 を毎回の run に流し込みたいことがあります。

代表例:

  • 現在時刻 — 「今日は 2026 年 5 月 10 日です。これを基準に答えてください」
  • ユーザー固有情報 — 「ユーザー名は 山田さん。敬称は『さん』を使う」
  • 状況依存の制約 — 「現在 メンテナンスモードのため、注文関連の質問は受け付けない」
  • データソースの状態 — 「現時点で DB には 1,234 件の商品があります」

これらを Static instructions にハードコードできず、また Tool (Ch3) を使って LLM に取りに行かせるほどでもないとき、Dynamic Instructions が "出すだけで効く" 最適な層 になります。

コード: 3 つの代表パターン

パターン 1: 現在時刻を毎回注入する

最も単純で効くのが「現在時刻」です。LLM 自体は内部に時刻概念を持たないので、外から教える必要があります。

from datetime import datetime
from zoneinfo import ZoneInfo
from pydantic_ai import Agent
 
agent = Agent(
    'google-gla:gemini-3-flash-preview',
    instructions='あなたは予約サポート担当です。日本語で簡潔に答えてください。',
)
 
@agent.instructions
def current_time() -> str:
    now = datetime.now(ZoneInfo('Asia/Tokyo'))
    return f'現在時刻 (JST): {now.strftime("%Y-%m-%d %H:%M")}。日付計算ではこの時刻を基準にしてください。'
 
# 毎回の run で current_time() が呼ばれ、戻り値が system message に追加される
print(agent.run_sync('明日の予約は?').output)

ポイント:

  • @agent.instructions関数を登録するデコレータ。関数本体は run ごとに毎回呼ばれる
  • 戻り値 str がそのまま system message に 追記 される
  • Static instructions (Agent コンストラクタの引数) と 共存 する

パターン 2: 引数なしの軽量な関数を複数登録

@agent.instructions何個でも重ねて貼れます。役割ごとに小さく分割するとテストしやすくなります。

import os
from pydantic_ai import Agent
 
agent = Agent(
    'google-gla:gemini-3-flash-preview',
    instructions='あなたは社内 Help Desk です。',
)
 
@agent.instructions
def env_label() -> str:
    env = os.getenv('APP_ENV', 'dev')
    return f'現在の環境: {env}'
 
@agent.instructions
def language_policy() -> str:
    return '日本語で答え、専門用語には括弧書きで英語を併記してください。'
 
print(agent.run_sync('VPN が繋がりません').output)

Agent の Static instructions に「あなたは社内 Help Desk です」、Dynamic 2 件で「環境ラベル」と「言語ポリシー」を 責務ごとに分離 しました。実プロジェクトでは「機能フラグの状態」「現在のユーザー権限」など、運用上 ON/OFF したい指示をこのレイヤーで切り替えるとメンテナンスしやすくなります。

パターン 3: RunContext 経由で DI から値を取る

Ch2「Dependencies」で詳しく扱いますが、@agent.instructions の関数に RunContext[DepsT] を引数として受けると、agent.run(..., deps=...) で渡したオブジェクトを参照できます。

from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
 
@dataclass
class UserContext:
    user_name: str
    plan: str  # 'free' | 'pro' | 'enterprise'
 
agent = Agent(
    'google-gla:gemini-3-flash-preview',
    deps_type=UserContext,
    instructions='あなたはサポート担当です。',
)
 
@agent.instructions
def personalize(ctx: RunContext[UserContext]) -> str:
    u = ctx.deps
    return (
        f'呼びかけは「{u.user_name} さん」を使ってください。\n'
        f'現在のプラン: {u.plan}。'
        f'{"高度な機能の質問にも詳しく答えてください。" if u.plan == "enterprise" else ""}'
    )
 
# run のたびに deps を変えられる
result = agent.run_sync('ログインできません', deps=UserContext('山田', 'enterprise'))
print(result.output)

ポイント:

  • 関数の 第 1 引数を RunContext[YourDepsType] にすると、PydanticAI が自動で渡してくれる
  • deps_type= を Agent 作成時に宣言しておくのが必須 (型安全のため)
  • 1 つの Agent インスタンスでユーザー A 用 / B 用と deps を差し替えるだけ で出し分けできる
図を読み込み中…
図2. Dynamic Instructions が呼ばれるタイミング (run 1 回ぶん)

いつ Dynamic Instructions を使うか — 判断軸

状況選ぶべき道具
ハードコードできる固定指示Static instructions (前レッスン)
run ごとに変わる軽い文脈 (時刻 / ユーザー名 / 環境)@agent.instructions (本レッスン)
LLM に「自分で取りに行ってもらう」情報 (天気・在庫・社内 DB)Function Tool (Ch3)
run のたびに 大量の 構造化データを読ませるTool で取得 → 結果を返す (Ch3)

「外から渡す軽い文脈」 vs 「LLM に取りに行かせる重い情報」の境界を意識すると設計が散らかりません。

まとめ

  • @agent.instructions デコレータで関数を登録すると、run のたびに instructions を組み立て直せる
  • Static + 複数の Dynamic は 合算 されて 1 つの system message になる
  • 軽い文脈 (時刻 / ユーザー名 / 環境フラグ) は Dynamic、重い情報取得は Tool (Ch3) に振り分ける
  • 関数は 純関数 + 軽い処理 で書く。重い I/O や副作用は別レイヤーへ

次レッスンでは Reflection — Agent が自身の出力を内省して再修正する output_validator と再試行のしくみ — を扱います。

Colab で実際に動かす

本レッスンの内容を Google Colab 上で実行できるノートブックを用意しています。下のボタンから自分のColab環境に開けます (要 Google アカウント / GOOGLE_API_KEY)。

Open in Colab

notebooks/ch01/02-dynamic-instructions.ipynb