次の方法で共有


アップグレード ガイド: ジェネリックを使用した TypedDict としてのチャット オプション

このガイドは、Microsoft Agent Framework のバージョン Options で導入された新しい TypedDict ベースの システムに Python コードをアップグレードするのに役立ちます。 これは、型の安全性、IDE オートコンプリート、ランタイムの拡張性が向上した 破壊的変更 です。

変更の概要

このリリースでは、チャット クライアントとチャット エージェントにオプションを渡す方法の主要なリファクタリングが導入されています。

以前の動作方法

以前は、オプションは、get_response()get_streaming_response()、エージェント コンストラクターなどのメソッドでrun()として渡されていました。

# Options were individual keyword arguments
response = await client.get_response(
    "Hello!",
    model_id="gpt-4",
    temperature=0.7,
    max_tokens=1000,
)

# For provider-specific options not in the base set, you used additional_properties
response = await client.get_response(
    "Hello!",
    model_id="gpt-4",
    additional_properties={"reasoning_effort": "medium"},
)

今すぐ動作する方法

ほとんどのオプションは、型指定されたディクショナリとして単一の options パラメーターを介して渡されるようになりました。

# Most options go in a single typed dict
response = await client.get_response(
    "Hello!",
    options={
        "model_id": "gpt-4",
        "temperature": 0.7,
        "max_tokens": 1000,
        "reasoning_effort": "medium",  # Provider-specific options included directly
    },
)

メモ:エージェントの場合、instructionsおよびtoolsパラメーターは、Agent.__init__()およびclient.as_agent()の直接キーワード引数として引き続き使用できます。 agent.run()の場合、キーワード引数として使用できるのはtoolsだけです。

# Agent creation accepts both tools and instructions as keyword arguments
agent = Agent(
    chat_client=client,
    tools=[my_function],
    instructions="You are a helpful assistant.",
    default_options={"model_id": "gpt-4", "temperature": 0.7},
)

# agent.run() only accepts tools as a keyword argument
response = await agent.run(
    "Hello!",
    tools=[another_function],  # Can override tools per-run
)

主要な変更点

  1. 統合オプション パラメーター: ほとんどのキーワード引数 (model_idtemperatureなど) は、1 つの options dict を介して渡されるようになりました
  2. エージェント作成の例外: instructionstools は、 Agent.__init__() および as_agent() に直接のキーワード引数として利用可能なままです。
  3. エージェント実行の例外: tools は直接キーワード引数として使用できます。 agent.run()
  4. TypedDict ベースのオプション: オプションは、型セーフの TypedDict クラスとして定義されます
  5. ジェネリック型のサポート: チャット クライアントとエージェントは、実行時のオーバーロードを許可するために、プロバイダー固有のオプションのジェネリックをサポートします
  6. プロバイダー固有のオプション: 各プロバイダーには、独自の既定の TypedDict (例: OpenAIChatOptionsOllamaChatOptions) があります。
  7. 追加プロパティはもうありません: プロバイダー固有のパラメーターが、第一級の型付けされたフィールドになりました

メリット

  • 型の安全性: IDE オートコンプリートとすべてのオプションの型チェック
  • プロバイダーの柔軟性: 1 日目のプロバイダー固有パラメーターのサポート
  • クリーナー コード: 一貫性のある dict ベースのパラメーターの受け渡し
  • 簡単な拡張機能: 特殊なユース ケース (推論モデルやその他の API バックエンドなど) のカスタム オプションを作成する

移行ガイド

1. キーワード引数をオプション Dict に変換する

最も一般的な変更は、個々のキーワード引数を options ディクショナリに変換することです。

以前 (キーワード引数):

from agent_framework.openai import OpenAIChatClient

client = OpenAIChatClient()

# Options passed as individual keyword arguments
response = await client.get_response(
    "Hello!",
    model_id="gpt-4",
    temperature=0.7,
    max_tokens=1000,
)

# Streaming also used keyword arguments
async for chunk in client.get_streaming_response(
    "Tell me a story",
    model_id="gpt-4",
    temperature=0.9,
):
    print(chunk.text, end="")

(オプション辞書の後):

from agent_framework.openai import OpenAIChatClient

client = OpenAIChatClient()

# All options now go in a single 'options' parameter
response = await client.get_response(
    "Hello!",
    options={
        "model_id": "gpt-4",
        "temperature": 0.7,
        "max_tokens": 1000,
    },
)

# Same pattern for streaming
async for chunk in client.get_streaming_response(
    "Tell me a story",
    options={
        "model_id": "gpt-4",
        "temperature": 0.9,
    },
):
    print(chunk.text, end="")

そのクライアントに適さないオプションを渡すと、IDE で型エラーが発生します。

2. プロバイダー専用のオプションの使用(追加プロパティは不要)

以前は、キーワード引数の基本セットに含まれていないプロバイダー固有のパラメーターを渡すには、 additional_properties パラメーターを使用する必要がありました。

(additional_propertiesを使用する前):

from agent_framework.openai import OpenAIChatClient

client = OpenAIChatClient()
response = await client.get_response(
    "What is 2 + 2?",
    model_id="gpt-4",
    temperature=0.7,
    additional_properties={
        "reasoning_effort": "medium",  # No type checking or autocomplete
    },
)

(TypedDict を使った直接指定の後):

from agent_framework.openai import OpenAIChatClient

# Provider-specific options are now first-class citizens with full type support
client = OpenAIChatClient()
response = await client.get_response(
    "What is 2 + 2?",
    options={
        "model_id": "gpt-4",
        "temperature": 0.7,
        "reasoning_effort": "medium",  # Type checking or autocomplete
    },
)

After (新しいパラメーターのカスタム サブクラス化):

または、まだ Agent Framework の一部ではないパラメーターである場合 (新しいパラメーター、または OpenAI 互換バックエンドのカスタムであるため) である場合は、オプションをサブクラス化し、汎用サポートを使用できるようになりました。

from typing import Literal
from agent_framework.openai import OpenAIChatOptions, OpenAIChatClient

class MyCustomOpenAIChatOptions(OpenAIChatOptions, total=False):
    """Custom OpenAI chat options with additional parameters."""

    # New or custom parameters
    custom_param: str

# Use with the client
client = OpenAIChatClient[MyCustomOpenAIChatOptions]()
response = await client.get_response(
    "Hello!",
    options={
        "model_id": "gpt-4",
        "temperature": 0.7,
        "custom_param": "my_value",  # IDE autocomplete works!
    },
)

主な利点は、プロバイダー固有のほとんどのパラメーターが型指定されたオプション ディクショナリの一部になり、次のことが可能になったことです。

  • 利用可能なすべてのオプションに対するIDE オートコンプリート
  • 無効なキーまたは値をキャッチするための型チェック
  • 既知のプロバイダー パラメーターにはadditional_propertiesは必要ありません
  • カスタムまたは新しいパラメーターの簡単な拡張機能

3. エージェントの構成を更新する

エージェントの初期化メソッドと実行メソッドは、同じパターンに従います。

以前は(コンストラクター内のキーワード引数と実行):

from agent_framework import Agent
from agent_framework.openai import OpenAIChatClient

client = OpenAIChatClient()

# Default options as keyword arguments on constructor
agent = Agent(
    chat_client=client,
    name="assistant",
    model_id="gpt-4",
    temperature=0.7,
)

# Run also took keyword arguments
response = await agent.run(
    "Hello!",
    max_tokens=1000,
)

After:

from agent_framework import Agent
from agent_framework.openai import OpenAIChatClient, OpenAIChatOptions

client = OpenAIChatClient()
agent = Agent(
    chat_client=client,
    name="assistant",
    default_options={ # <- type checkers will verify this dict
        "model_id": "gpt-4",
        "temperature": 0.7,
    },
)

response = await agent.run("Hello!", options={ # <- and this dict too
    "max_tokens": 1000,
})

プロバイダー固有のオプション

各プロバイダーには、オプションに対して独自の TypedDict が用意されています。これらは既定で有効になっています。 これにより、完全なタイプ セーフでプロバイダー固有のパラメーターを使用できます。

OpenAI の例:

from agent_framework.openai import OpenAIChatClient

client = OpenAIChatClient()
response = await client.get_response(
    "Hello!",
    options={
        "model_id": "gpt-4",
        "temperature": 0.7,
        "reasoning_effort": "medium",
    },
)

ただし、次の内容を明示的にすることもできます。

from agent_framework_anthropic import AnthropicClient, AnthropicChatOptions

client = AnthropicClient[AnthropicChatOptions]()
response = await client.get_response(
    "Hello!",
    options={
        "model_id": "claude-3-opus-20240229",
        "max_tokens": 1000,
    },
)

5. 特殊化されたモデルのカスタム オプションの作成

新しいシステムの強力な機能の 1 つは、特殊化されたモデルのカスタム TypedDict オプションを作成する機能です。 これは、OpenAI を使用した推論モデルなど、一意のパラメーターを持つモデルに特に役立ちます。

from typing import Literal
from agent_framework.openai import OpenAIChatOptions, OpenAIChatClient

class OpenAIReasoningChatOptions(OpenAIChatOptions, total=False):
    """Chat options for OpenAI reasoning models (o1, o3, o4-mini, etc.)."""

    # Reasoning-specific parameters
    reasoning_effort: Literal["none", "minimal", "low", "medium", "high", "xhigh"]

    # Unsupported parameters for reasoning models (override with None)
    temperature: None
    top_p: None
    frequency_penalty: None
    presence_penalty: None
    logit_bias: None
    logprobs: None
    top_logprobs: None
    stop: None


# Use with the client
client = OpenAIChatClient[OpenAIReasoningChatOptions]()
response = await client.get_response(
    "What is 2 + 2?",
    options={
        "model_id": "o3",
        "max_tokens": 100,
        "allow_multiple_tool_calls": True,
        "reasoning_effort": "medium",  # IDE autocomplete works!
        # "temperature": 0.7,  # Would raise a type error, because the value is not None
    },
)

6. チャット エージェントとオプション

汎用セットアップは、チャット エージェントにも拡張されています。

from agent_framework import Agent
from agent_framework.openai import OpenAIChatClient

agent = Agent(
    chat_client=OpenAIChatClient[OpenAIReasoningChatOptions](),
    default_options={
        "model_id": "o3",
        "max_tokens": 100,
        "allow_multiple_tool_calls": True,
        "reasoning_effort": "medium",
    },
)

クライアントとエージェントの両方でジェネリックを指定できるため、これも有効です。

from agent_framework import Agent
from agent_framework.openai import OpenAIChatClient

agent = Agent[OpenAIReasoningChatOptions](
    chat_client=OpenAIChatClient(),
    default_options={
        "model_id": "o3",
        "max_tokens": 100,
        "allow_multiple_tool_calls": True,
        "reasoning_effort": "medium",
    },
)

6. カスタム チャット クライアントの実装を更新する

BaseChatClientを拡張してカスタム チャット クライアントを実装した場合は、内部メソッドを更新します。

Before:

from agent_framework import BaseChatClient, Message, ChatOptions, ChatResponse

class MyCustomClient(BaseChatClient):
    async def _inner_get_response(
        self,
        *,
        messages: MutableSequence[Message],
        chat_options: ChatOptions,
        **kwargs: Any,
    ) -> ChatResponse:
        # Access options via class attributes
        model = chat_options.model_id
        temp = chat_options.temperature
        # ...

After:

from typing import Generic
from agent_framework import BaseChatClient, Message, ChatOptions, ChatResponse

# Define your provider's options TypedDict
class MyCustomChatOptions(ChatOptions, total=False):
    my_custom_param: str

# This requires the TypeVar from Python 3.13+ or from typing_extensions, so for Python 3.13+:
from typing import TypeVar

TOptions = TypeVar("TOptions", bound=TypedDict, default=MyCustomChatOptions, covariant=True)

class MyCustomClient(BaseChatClient[TOptions], Generic[TOptions]):
    async def _inner_get_response(
        self,
        *,
        messages: MutableSequence[Message],
        options: dict[str, Any],  # Note: parameter renamed and just a dict
        **kwargs: Any,
    ) -> ChatResponse:
        # Access options via dict access
        model = options.get("model_id")
        temp = options.get("temperature")
        # ...

一般的な移行パターン

パターン 1: 単純なパラメーターの更新

# Before - keyword arguments
await client.get_response("Hello", temperature=0.7)

# After - options dict
await client.get_response("Hello", options={"temperature": 0.7})

パターン 2: 複数のパラメーター

# Before - multiple keyword arguments
await client.get_response(
    "Hello",
    model_id="gpt-4",
    temperature=0.7,
    max_tokens=1000,
)

# After - all in options dict
await client.get_response(
    "Hello",
    options={
        "model_id": "gpt-4",
        "temperature": 0.7,
        "max_tokens": 1000,
    },
)

パターン 3: ツールを使用してクライアントをチャットする

チャットクライアントの場合、tools はオプション辞書に入ります。

# Before - tools as keyword argument on chat client
await client.get_response(
    "What's the weather?",
    model_id="gpt-4",
    tools=[my_function],
    tool_choice="auto",
)

# After - tools in options dict for chat clients
await client.get_response(
    "What's the weather?",
    options={
        "model_id": "gpt-4",
        "tools": [my_function],
        "tool_choice": "auto",
    },
)

パターン 4: ツールと命令を含むエージェント

エージェントを作成する場合、 toolsinstructions はキーワード引数として残すことができます。 run()では、toolsのみが使用できます。

# Before
agent = Agent(
    chat_client=client,
    name="assistant",
    tools=[my_function],
    instructions="You are helpful.",
    model_id="gpt-4",
)

# After - tools and instructions stay as keyword args on creation
agent = Agent(
    chat_client=client,
    name="assistant",
    tools=[my_function],  # Still a keyword argument!
    instructions="You are helpful.",  # Still a keyword argument!
    default_options={"model_id": "gpt-4"},
)

# For run(), only tools is available as keyword argument
response = await agent.run(
    "Hello!",
    tools=[another_function],  # Can override tools
    options={"max_tokens": 100},
)
# Before - using additional_properties
await client.get_response(
    "Solve this problem",
    model_id="o3",
    additional_properties={"reasoning_effort": "high"},
)

# After - directly in options
await client.get_response(
    "Solve this problem",
    options={
        "model_id": "o3",
        "reasoning_effort": "high",
    },
)

パターン 5: プロバイダー固有のパラメーター

# Define reusable options
my_options: OpenAIChatOptions = {
    "model_id": "gpt-4",
    "temperature": 0.7,
}

# Use with different messages
await client.get_response("Hello", options=my_options)
await client.get_response("Goodbye", options=my_options)

# Extend options using dict merge
extended_options = {**my_options, "max_tokens": 500}

重大な変更の概要

特徴 以前は クリック後
チャット クライアント のオプション 個々のキーワード引数 (temperature=0.7) シングル options ディクテーション (options={"temperature": 0.7})
チャット クライアント ツール tools=[...] キーワード引数 options={"tools": [...]}
エージェントの作成 toolsinstructions キーワード引数 依然としてキーワード引数 (変更なし)
エージェント run()tools キーワード引数 Still キーワード引数 (変更なし)
エージェント run()instructions キーワード引数 options={"instructions": ...} に移動しました
プロバイダー固有のオプション additional_properties={...} options dict に直接含まれる
エージェントの既定のオプション コンストラクターのキーワード引数 default_options={...}
エージェントの実行オプション run()におけるキーワード引数 options={...} パラメーター
クライアントの入力 OpenAIChatClient() OpenAIChatClient[CustomOptions]() (任意)
エージェントが入力中 Agent(...) Agent[CustomOptions](...) (任意)

移行のテスト

ChatClient の更新

  1. get_response()get_streaming_response()model_id=などのキーワード引数を使用するtemperature=tools=のすべての呼び出しを検索します。
  2. すべてのキーワード引数を options={...} ディクショナリに移動する
  3. additional_properties値をoptions dict に直接移動する

エージェントの更新

  1. キーワード引数を使用するすべての Agent コンストラクターと run() 呼び出しを検索する
  2. キーワード引数をコンストラクターに移動してください default_options={...}
  3. run()からキーワード引数をoptions={...}に移動
  4. 例外: toolsinstructions は、Agent.__init__() および as_agent() でキーワード引数として残すことができます。
  5. 例外: tools はキーワード引数として残すことができます run()

カスタム チャット クライアントの更新

  1. _inner_get_response()メソッドシグネチャおよび_inner_get_streaming_response()メソッドシグネチャを更新し、chat_options: ChatOptionsパラメータをoptions: dict[str, Any]に変更します。
  2. 属性アクセス ( chat_options.model_id など) を dict アクセスに更新する (例: options.get("model_id"))
  3. (省略可能) 標準以外のパラメーターを使用する場合: カスタム TypedDict を定義する
  4. クライアント クラスにジェネリック型パラメーターを追加する

すべての人へ

  1. 型チェッカーの実行: mypy または pyright を使用して型エラーをキャッチする
  2. エンドツーエンドのテスト: アプリケーションを実行して機能を確認する

IDE のサポート

新しい TypedDict ベースのシステムは、優れた IDE サポートを提供します。

  • オートコンプリート: 使用可能なすべてのオプションの候補を取得する
  • 型チェック: 開発時に無効なオプション キーをキャッチする
  • ドキュメント: キーをポイントして説明を表示する
  • プロバイダー固有: 各プロバイダーのオプションには、関連するパラメーターのみが表示されます

次のステップ

チャット完了 API で OpenAI 推論モデルを使用する場合に、型指定されたディクテーションが動作することを確認するには、このサンプルを調べる

移行が完了したら、次の手順を実行します。

  1. API ドキュメントでプロバイダー固有のオプションを確認する
  2. 更新されたサンプルを確認する
  3. カスタム チャット クライアントの作成について説明します

その他のヘルプについては、 Agent Framework のドキュメント を参照するか、コミュニティにお問い合わせください。