pydantic_ai の承認付きツール登録

🧑 User

2026-11-08T14:04:02.809414Z

pydantic_ai.Agent を使って、agent = Agent(instructions=INSTRUCTIONS, output_type=[str, DeferredToolRequests]) で初期化した agent に、requires_approval=True をつけて agent.tool_plain() で関数をツールとして登録するにはどうコーディングしますか?


🤖 Claude

2026-11-08T14:04:14.752687Z

@agent.tool_plain にデコレータ引数として requires_approval=True を渡します。

from pydantic_ai import (
    Agent,
    DeferredToolRequests,
    DeferredToolResults,
    ToolDenied,
)

INSTRUCTIONS = "あなたは運用自動化アシスタントです。"

agent = Agent(
    "openai:gpt-5",  # 使用するモデルに置き換える
    instructions=INSTRUCTIONS,
    output_type=[str, DeferredToolRequests],
)


@agent.tool_plain(requires_approval=True)
def restart_service(service_name: str) -> str:
    """指定したサービスを再起動する(承認必須)。"""
    # 実際の処理
    return f"{service_name} を再起動しました"

承認が必要なツールをモデルが呼ぶと、そのツールは実行されません。代わりに result.output が DeferredToolRequests で返ってくるので、承認結果を渡して再実行します。

result = agent.run_sync("web-api を再起動して")
messages = result.all_messages()

if isinstance(result.output, DeferredToolRequests):
    results = DeferredToolResults()

    for call in result.output.approvals:  # 承認待ちのツール呼び出し
        print(call.tool_name, call.args)
        if input("承認しますか? [y/N] ").lower() == "y":
            results.approvals[call.tool_call_id] = True
        else:
            results.approvals[call.tool_call_id] = ToolDenied("ユーザーが拒否しました")

    # 新しいプロンプトは渡さず、履歴と承認結果だけで再開する
    result = agent.run_sync(
        message_history=messages,
        deferred_tool_results=results,
    )

print(result.output)

補足です。

私の知識に基づく回答で、公式ドキュメントの最新版とは照合していません。インポート名やバージョン差が気になる場合は、Pydantic AI の "Deferred Tools" のページで確認してください。