Delen via


Upgradehandleiding: Chatopties als TypedDict met Generics

Deze handleiding helpt u bij het upgraden van uw Python-code naar het nieuwe op TypedDict gebaseerde Options systeem dat is geïntroduceerd in versie 1.0.0b260114 van het Microsoft Agent Framework. Dit is een belangrijke wijziging die zorgt voor verbeterde typeveiligheid, IDE automatisch aanvullen en runtime-uitbreidbaarheid.

Overzicht van wijzigingen

Deze release introduceert een belangrijke herstructurering van de wijze waarop opties worden doorgegeven aan chatclients en chatagents.

Hoe het eerder werkte

Eerder werden opties doorgegeven als directe trefwoordargumenten voor methoden zoals get_response(), get_streaming_response(), run()en agentconstructors:

# 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"},
)

Hoe het nu werkt

De meeste opties worden nu doorgegeven via één options parameter als een getypte woordenlijst:

# 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
    },
)

Opmerking: Voor agents blijven de instructions en tools parameters beschikbaar als directe trefwoordargumenten op ChatAgent.__init__() en client.as_agent(). Voor agent.run() is alleen tools beschikbaar als een trefwoordargument:

# Agent creation accepts both tools and instructions as keyword arguments
agent = ChatAgent(
    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
)

Belangrijke wijzigingen

  1. Parameter voor geconsolideerde opties: de meeste trefwoordargumenten (model_id, temperatureenzovoort) worden nu doorgegeven via één options dict
  2. Uitzondering voor het maken van agents: instructions en tools blijven beschikbaar als directe trefwoordargumenten op ChatAgent.__init__() en create_agent()
  3. Uitzondering voor agentuitvoering: tools blijft beschikbaar als een direct trefwoordargument op agent.run()
  4. Op TypedDict gebaseerde opties: Opties worden gedefinieerd als TypedDict klassen voor typeveiligheid
  5. Algemene typeondersteuning: Chatclients en agents ondersteunen generics voor providerspecifieke opties, om runtime-overbelastingen toe te staan
  6. Providerspecifieke opties: elke provider heeft een eigen standaardTypedDict (bijvoorbeeld OpenAIChatOptions, OllamaChatOptions)
  7. Geen additional_properties meer: Providerspecifieke parameters zijn nu eersteklas getypte velden

Voordelen

  • Type Veiligheid: IDE-autocompletion en typecontrole voor alle opties
  • Flexibiliteit van provider: ondersteuning voor providerspecifieke parameters op dag één
  • Cleaner Code: Consistent gebruik van dict-gebaseerde parameterdoorgifte
  • Eenvoudigere extensie: aangepaste opties maken voor gespecialiseerde use cases (bijvoorbeeld redeneringsmodellen of andere API-back-ends)

Migratiehandleiding

1. Trefwoordargumenten converteren naar Opties Dict

De meest voorkomende wijziging is het converteren van afzonderlijke trefwoordargumenten naar de options woordenlijst.

Voor (trefwoordargumenten):

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="")

Na (opties woordenboek):

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="")

Als u opties doorgeeft die niet geschikt zijn voor die client, krijgt u een typefout in uw IDE.

2. Provider-Specific opties gebruiken (geen additional_properties meer)

Voorheen moest u de additional_properties parameter gebruiken om providerspecifieke parameters door te geven die geen deel uitmaakten van de basisset met trefwoordargumenten:

Voordat (additional_properties gebruikt):

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
    },
)

Na (directe opties met 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
    },
)

Na (aangepaste subklasse maken voor nieuwe parameters):

Of als het een parameter is die nog geen deel uitmaakt van Agent Framework (omdat deze nieuw is of omdat deze is aangepast voor een openAI-compatibele back-end), kunt u nu de opties subklassen en de algemene ondersteuning gebruiken:

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!
    },
)

Het belangrijkste voordeel is dat de meeste providerspecifieke parameters nu deel uitmaken van de woordenlijst met getypte opties, zodat u:

  • IDE automatisch aanvullen voor alle beschikbare opties
  • Typecontrole om ongeldige sleutels of waarden te vangen
  • Geen additional_properties nodig voor bekende providerparameters
  • Eenvoudige extensie voor aangepaste of nieuwe parameters

3. ChatAgent-configuratie bijwerken

De initialisatie- en uitvoeringsmethoden van ChatAgent volgen hetzelfde patroon:

Vóór (trefwoordargumenten op constructor en uitvoeren):

from agent_framework import ChatAgent
from agent_framework.openai import OpenAIChatClient

client = OpenAIChatClient()

# Default options as keyword arguments on constructor
agent = ChatAgent(
    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 ChatAgent
from agent_framework.openai import OpenAIChatClient, OpenAIChatOptions

client = OpenAIChatClient()
agent = ChatAgent(
    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,
})

4. Aanbiederspecifieke Opties

Elke provider heeft nu een eigen TypedDict voor opties. Deze zijn standaard ingeschakeld. Hiermee kunt u providerspecifieke parameters gebruiken met volledige typeveiligheid:

OpenAI-voorbeeld:

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",
    },
)

Maar u kunt het ook expliciet maken:

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. Aangepaste opties maken voor gespecialiseerde modellen

Een krachtige functie van het nieuwe systeem is de mogelijkheid om aangepaste TypedDict-opties te maken voor gespecialiseerde modellen. Dit is met name handig voor modellen met unieke parameters, zoals redeneringsmodellen met 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. Chatagents met opties

De algemene configuratie is ook uitgebreid voor Chat Agents.

from agent_framework import ChatAgent
from agent_framework.openai import OpenAIChatClient

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

en u kunt de generieke op zowel de cliënt als de agent specificeren, dus dit is ook toegestaan:

from agent_framework import ChatAgent
from agent_framework.openai import OpenAIChatClient

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

6. Aangepaste chatclient-implementaties bijwerken

Als u een aangepaste chatclient hebt geïmplementeerd door deze uit te breiden BaseChatClient, werkt u de interne methoden bij:

Before:

from agent_framework import BaseChatClient, ChatMessage, ChatOptions, ChatResponse

class MyCustomClient(BaseChatClient):
    async def _inner_get_response(
        self,
        *,
        messages: MutableSequence[ChatMessage],
        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, ChatMessage, 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[ChatMessage],
        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")
        # ...

Algemene migratiepatronen

Patroon 1: Eenvoudige parameterupdate

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

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

Patroon 2: Meerdere parameters

# 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,
    },
)

Patroon 3: Chatclient met hulpprogramma's

Voor chatclients komt tools nu in de opties-lijst.

# 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",
    },
)

Patroon 4: Agent met hulpprogramma's en instructies

Voor het aanmaken van een agent kunnen tools en instructions als trefwoordargument blijven. run() Alleen toolsbeschikbaar voor:

# Before
agent = ChatAgent(
    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 = ChatAgent(
    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",
    },
)

Patroon 5: Provider-specifieke Parameters

# 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}

Overzicht van belangrijke wijzigingen

Kenmerk Voordat Na
Chatclientopties Argumenten voor afzonderlijke trefwoorden (temperature=0.7) Eén options woordenboek (options={"temperature": 0.7})
Chatclienthulpprogramma's tools=[...] trefwoordargument options={"tools": [...]}
Agent maken tools en instructions Trefwoordargumenten Nog steeds trefwoordargumenten (ongewijzigd)
Agent run()tools Trefwoordargument Nog steeds trefwoordargument (ongewijzigd)
Agent run()instructions Trefwoordargument Verplaatst naar options={"instructions": ...}
Providerspecifieke opties additional_properties={...} Rechtstreeks opgenomen in options woordenboek
Standaardopties voor agent Trefwoordargumenten voor constructor default_options={...}
Opties voor agentuitvoering Trefwoordargumenten op run() options={...}-parameter
Typen door cliënt OpenAIChatClient() OpenAIChatClient[CustomOptions]() (optioneel)
Agent is aan het typen ChatAgent(...) ChatAgent[CustomOptions](...) (optioneel)

Uw migratie testen

ChatClient-updates

  1. Zoek alle aanroepen naar get_response() en get_streaming_response() die trefwoordargumenten gebruiken, zoals model_id=, temperature=, tools=enzovoort.
  2. Alle trefwoordargumenten naar een options={...} woordenlijst verplaatsen
  3. Plaats alle additional_properties waarden rechtstreeks in de options dict.

ChatAgent-updates

  1. Zoek alle ChatAgent constructors en run() aanroepen die trefwoordargumenten gebruiken
  2. Trefwoordargumenten op constructors verplaatsen naar default_options={...}
  3. Verplaats trefwoordargumenten van run() naar options={...}
  4. Uitzondering: tools en instructions kan blijven als trefwoordargumenten op ChatAgent.__init__() en create_agent()
  5. Uitzondering: tools kan blijven als een trefwoordargument op run()

Aangepaste Chatclientupdates

  1. Werk de _inner_get_response() en _inner_get_streaming_response() methodesignaturen bij: wijzig de chat_options: ChatOptions-parameter in options: dict[str, Any]
  2. Attribuuttoegang (bijvoorbeeld chat_options.model_id) bijwerken naar toegang tot een woordenboek (bijvoorbeeld options.get("model_id"))
  3. (Optioneel) Als u niet-standaardparameters gebruikt: een aangepast TypedDict definiëren
  4. Algemene typeparameters toevoegen aan uw clientklasse

Voor iedereen

  1. Typecontrole uitvoeren: gebruik mypy of pyright om typefouten op te sporen
  2. End-to-end testen: voer uw toepassing uit om de functionaliteit te controleren

IDE-ondersteuning

Het nieuwe op TypedDict gebaseerde systeem biedt uitstekende IDE-ondersteuning:

  • Automatisch aanvullen: Suggesties ophalen voor alle beschikbare opties
  • Typecontrole: Ongeldige optiesleutels opsporen tijdens de ontwikkeling
  • Documentatie: Beweeg de muisaanwijzer over sleutels om beschrijvingen weer te geven
  • Providerspecifiek: de opties van elke provider geven alleen relevante parameters weer

Volgende stappen

Bekijk dit voorbeeld om de getypte dicts in actie te zien voor het gebruik van OpenAI Reasoning Models met de Chat Completion API.

Nadat de migratie is voltooid:

  1. Providerspecifieke opties verkennen in de API-documentatie
  2. Bijgewerkte voorbeelden bekijken
  3. Meer informatie over het maken van aangepaste chatclients

Raadpleeg de documentatie van Agent Framework of neem contact op met de community voor aanvullende hulp.