다음을 통해 공유


업그레이드 가이드: 제네릭을 사용하는 TypedDict로서의 채팅 옵션

이 가이드는 Microsoft 에이전트 프레임워크 버전 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
    },
)

참고:에이전트의 경우, instructionstools 매개 변수를 ChatAgent.__init__()에서 직접 키워드 인수로 사용할 수 있습니다client.as_agent(). 의 경우 agent.run()키워드 인수로만 tools 사용할 수 있습니다.

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

주요 변경 내용

  1. 통합 옵션 매개 변수: 대부분의 키워드 인수(model_idtemperature)는 이제 단일 options 받아쓰기를 통해 전달됩니다.
  2. 에이전트 생성 예외: instructionstoolsChatAgent.__init__()create_agent()에서 직접 키워드 인수로 계속 사용할 수 있습니다.
  3. 에이전트 실행에 대한 예외: toolsagent.run()에서 계속해서 직접 키워드 인수로 이용 가능합니다.
  4. TypedDict 기반 옵션: 옵션은 형식 안전을 위한 클래스로 TypedDict 정의됩니다.
  5. 제네릭 형식 지원: 채팅 클라이언트 및 에이전트는 공급자별 옵션에 대한 제네릭을 지원하여 런타임 오버로드를 허용합니다.
  6. 공급자별 옵션: 각 공급자에는 고유한 기본 TypedDict(예: OpenAIChatOptions, OllamaChatOptions) 가 있습니다.
  7. 더 이상 additional_properties 없음: 공급자별 매개 변수가 이제 첫 번째 클래스 형식 필드입니다.

혜택

  • 형식 안전성: 모든 옵션에 대한 IDE 자동 완성 및 형식 검사
  • 공급자 유연성: 첫날 공급자별 매개 변수 지원
  • 클리너 코드: 일관된 dict 기반 매개 변수 전달
  • 더 쉬운 확장: 특수한 사용 사례에 대한 사용자 지정 옵션 만들기(예: 추론 모델 또는 기타 API 백 엔드)

마이그레이션 가이드

1. 키워드 인수를 Options 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. Provider-Specific 옵션 사용(더 이상 additional_properties 없음)

이전에는 키워드 인수의 기본 집합에 속하지 않은 공급자별 매개 변수를 전달하려면 매개 변수를 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
    },
)

이후(새 매개 변수에 대한 사용자 지정 서브클래싱):

또는 에이전트 프레임워크의 일부가 아닌 매개 변수인 경우(새 항목이거나 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. ChatAgent 구성 업데이트

ChatAgent 초기화 및 실행 메서드는 동일한 패턴을 따릅니다.

이전(생성자 및 실행에 대한 키워드 인수):

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. 공급자별 옵션

이제 각 공급자에는 옵션에 대한 고유한 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. 특수 모델에 대한 사용자 지정 옵션 만들기

새 시스템의 강력한 기능 중 하나는 특수 모델에 대한 사용자 지정 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 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",
    },
)

클라이언트와 에이전트 모두에서 제네릭을 지정할 수 있으므로 이 값도 유효합니다.

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. 사용자 지정 채팅 클라이언트 구현 업데이트

확장하여 사용자 지정 채팅 클라이언트를 BaseChatClient구현한 경우 내부 메서드를 업데이트합니다.

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")
        # ...

일반적인 마이그레이션 패턴

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

패턴 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 키워드 인수 Still 키워드 인수 (변경되지 않음)
에이전트 run()tools Keyword 인수 Still 키워드 인수 (변경되지 않음)
에이전트 run()instructions Keyword 인수 다음으로 이동됨 options={"instructions": ...}
공급자별 옵션 additional_properties={...} 사전에서 options 직접 포함된다.
에이전트 기본 옵션 생성자의 키워드 인수 default_options={...}
에이전트 실행 옵션 키워드 인수 run() options={...} 매개 변수
클라이언트 입력 OpenAIChatClient() OpenAIChatClient[CustomOptions]()(선택 사항)
에이전트가 입력 중입니다. ChatAgent(...) ChatAgent[CustomOptions](...)(선택 사항)

마이그레이션 테스트

ChatClient 업데이트

  1. get_response()get_streaming_response()에 대한 모든 호출을 찾아 model_id=, temperature=, tools= 등의 키워드 인수를 사용하는지 확인합니다.
  2. 모든 키워드 인수를 options={...} 사전으로 이동하십시오.
  3. additional_properties 값을 options 사전으로 직접 이동하십시오.

ChatAgent 업데이트

  1. 키워드 인수를 사용하는 모든 ChatAgent 생성자 및 run() 호출 찾기
  2. 생성자의 키워드 인수를 default_options={...}로 이동하십시오.
  3. 키워드 인수를 run()에서 options={...}로 이동하십시오
  4. 예외: toolsinstructionsChatAgent.__init__()create_agent()에서 키워드 인수로 유지될 수 있습니다.
  5. 예외: tools 에서 키워드 인수로 남아 있을 수 있습니다. run()

사용자 지정 채팅 클라이언트 업데이트

  1. _inner_get_response()_inner_get_streaming_response() 메서드 서명 업데이트: 매개 변수를 chat_options: ChatOptions에서 options: dict[str, Any]로 변경
  2. 특성 액세스(예: chat_options.model_id)를 딕트 액세스(예: options.get("model_id"))로 업데이트
  3. (선택 사항) 비표준 매개 변수를 사용하는 경우: 사용자 지정 TypedDict 정의
  4. 클라이언트 클래스에 제네릭 형식 매개 변수 추가

모두를 위해

  1. 형식 검사 실행: mypy 또는 pyright을 사용하여 형식 오류를 탐지하십시오.
  2. 엔드 투 엔드 테스트: 애플리케이션을 실행하여 기능 확인

IDE 지원

새로운 TypedDict 기반 시스템은 뛰어난 IDE 지원을 제공합니다.

  • 자동 완성: 사용 가능한 모든 옵션에 대한 제안 가져오기
  • 형식 검사: 개발 시 잘못된 옵션 키를 발견합니다.
  • 설명서: 키를 마우스로 가리켜 설명을 확인합니다.
  • 공급자별: 각 공급자의 옵션은 관련 매개 변수만 표시합니다.

다음 단계

채팅 완료 API와 함께 OpenAI 추론 모델을 사용하는 경우의 실행 중인 입력된 받아쓰기를 보려면 이 샘플을 탐색합니다.

마이그레이션을 완료한 후:

  1. API 설명서에서 공급자별 옵션 살펴보기
  2. 업데이트된 샘플 검토
  3. 사용자 지정 채팅 클라이언트를 만드는 방법에 대해 알아보기

추가 도움말은 Agent Framework 설명서를 참조하거나 커뮤니티에 문의하세요.