「AIエージェントキャッチアップ #15 - PydanticAI」を開催しました

ジェネラティブエージェンツの大嶋です。

「AIエージェントキャッチアップ #15 - PydanticAI」という勉強会を開催しました。

generative-agents.connpass.com

アーカイブ動画はこちらです。

youtube.com

PydanticAI

今回は、Pydanticによるエージェントフレームワーク「PydanticAI」について、公式ドキュメントを読んだり動かしたりしてみました。

GitHubリポジトリはこちらです。

github.com

今回のポイント

PydanticAIの概要

PydanticAIは、Pydanticをベースとしたエージェントフレームワークです。

WebフレームワークにおいてPydanticに基づいたFastAPIが便利であるように、エージェントフレームワークもPydanticに基づいて構築してみた、といったコンセプトのようです。

2024年12月時点で、Early Betaであり破壊的変更の可能性があると明示されているため、本格的な開発での使用には注意が必要です。

基本的な使い方

PydanticAIの基本的な使い方は公式ドキュメントに書かれています。

ai.pydantic.dev

以下のように、Agentやtoolを定義して「agent.run」などとして実行するというものです。

support_agent = Agent(  
    'openai:gpt-4o',  
    deps_type=SupportDependencies,
    result_type=SupportResult,  
    system_prompt=(  
        'You are a support agent in our bank, give the '
        'customer support and judge the risk level of their query.'
    ),
)
        :
@support_agent.tool  
async def customer_balance(
    ctx: RunContext[SupportDependencies], include_pending: bool
) -> float:
        :
    result = await support_agent.run('What is my balance?', deps=deps)  

このようにエージェントを定義してあとは「run」などとしてお任せで動いてもらう方式のフレームワークはとても多いです。 (AutoGen、crewAI、OpenAI Swarmなどなど)

そんな中でPydanticAIの特徴的だと思った点を3つ紹介します。

  • result_typeの設定
  • Dependency Injectionのしくみ
  • Pydantic Logfireとの連携

result_typeの設定

まずはresult_typeについてです。

PydanticAIでは、以下のようにPydanticのBaseModelを継承したクラスをAgentの出力として設定できます。

class SupportResult(BaseModel):  
    support_advice: str = Field(description='Advice returned to the customer')
    block_card: bool = Field(description="Whether to block the customer's card")
    risk: int = Field(description='Risk level of query', ge=0, le=10)
        :
support_agent = Agent(  
        :
    result_type=SupportResult,  
        :
)

LangChainのwith_structured_outputのような機能ですね。

LangGraphのcreate_react_agentではwith_structured_outputを簡単に設定するような機能はなく、他のフレームワークでもあまり見ないので、この機能は特徴的だと思いました。

ちなみに、PydanticAIの内部実装としてはFunction callingのツールにresult_typeで指定した型のツールを追加しているようでした。

        if result_tools:
            tools += [self._map_tool_definition(r) for r in result_tools]

https://github.com/pydantic/pydantic-ai/blob/718c9a0a5489f734af7ddf57f6cd23669ee97117/pydantic_ai_slim/pydantic_ai/models/openai.py#L114-L115

Dependency Injectionのしくみ

PydanticAIの特徴の2つ目は、Dependency Injectionのしくみがあることです。

deps_typeとしてAgentの依存関係の型を定義しておいて、runするときに依存関係を与える、というものです。

support_agent = Agent(  
        :
    deps_type=SupportDependencies,
        :
)
        :
    result = await support_agent.run('What is my balance?', deps=deps)  

PydanticAIはFastAPIにインスパイアされているとのことなので、そこから着想を得てこの機能を入れているのかもしれません。

Pydantic Logfireとの連携

PydanticAIの特徴の3つ目は、Pydantic Logfireとの連携です。

Pydantic Logfireは、Pydanticが提供するObservabilityのプラットフォームです。 OpenTelemetryに基づいているとのことです。

Pydantic Logfire自体はLLMアプリケーションに特化したプラットフォームではないようですが、PydanticAIとは簡単に連携できるようになっています。

Logfireに登録して、uv run logfire authuv run logfire projects newのように認証とプロジェクトの作成を実施して、以下のコードを追加します。

import logfire
logfire.configure()

その後コードを実行すると、以下のようにLogfireにトレースが記録されました。

LLMに特化したトレースツールではないため、プロンプトを確認したいといった用途での見やすさは少し低めだと感じましたが、トレースツールと簡単に連携できること自体は嬉しいですね。

次回のご案内

以上、今回は「PydanticAI」をキャッチアップしました。

次回は「AIエージェントキャッチアップ #16 - Open Canvas (LangChain)」ということで、OpenAIの「Canvas」にインスパイアされたLangChainの「Open Canvas」がテーマです!

generative-agents.connpass.com

ご興味・お時間ある方はぜひご参加ください!

また、その次の回以降のテーマも募集しているので、気になるエージェントのOSSなどあれば教えてください!