Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Esta guía le ayuda a actualizar el código de Python al nuevo sistema basado en Options TypedDict introducido en la versión 1.0.0b260114 de Microsoft Agent Framework. Se trata de un cambio rompedor que proporciona una mejorada seguridad de tipos, autocompletar del IDE y extensibilidad en tiempo de ejecución.
Información general sobre los cambios
En esta versión se presenta una refactorización importante de cómo se pasan las opciones a los clientes de chat y a los agentes de chat.
Cómo funcionó antes
Anteriormente, las opciones se pasaron como argumentos de palabra clave directos en métodos como get_response(), get_streaming_response(), run(), y constructores de agentes:
# 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"},
)
Cómo funciona ahora
La mayoría de las opciones ahora se pasan a través de un único options parámetro tipado como un diccionario.
# 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
},
)
Nota: Para Agentes,
instructionsytoolspermanecen disponibles como argumentos por palabra clave enChatAgent.__init__()yclient.as_agent(). Paraagent.run(), solotoolsestá disponible como argumento de palabra clave:# 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 )
Cambios principales
-
Parámetro de opciones consolidadas: la mayoría de los argumentos de palabra clave (
model_id,temperature, etc.) ahora se pasan a través de un únicooptionsdict -
Excepción para la creación del agente:
instructionsytoolspermanecen disponibles como argumentos de palabra clave directa enChatAgent.__init__()ycreate_agent() -
Excepción para la ejecución del agente:
toolspermanece disponible como argumento de palabra clave directa enagent.run() -
Opciones basadas en TypedDict: las opciones se definen como
TypedDictclases para la seguridad de tipos - Compatibilidad con tipos genéricos: los clientes de chat y los agentes admiten genéricos para opciones específicas del proveedor, para permitir sobrecargas en tiempo de ejecución
-
Opciones específicas del proveedor: cada proveedor tiene su propio TypedDict predeterminado (por ejemplo,
OpenAIChatOptions,OllamaChatOptions) - No más additional_properties: los parámetros específicos del proveedor ahora son campos de tipo de primera categoría
Ventajas
- Seguridad de Tipos: Autocompletado de IDE y verificación de tipos para todas las opciones
- Flexibilidad del proveedor: compatibilidad con parámetros específicos del proveedor el día uno
- Código más limpio: paso coherente de parámetros basados en dict
- Extensión más sencilla: cree opciones personalizadas para casos de uso especializados (por ejemplo, modelos de razonamiento u otros back-end de API).
Guía de migración
1. Convertir argumentos de palabra clave en Opciones Dict
El cambio más común consiste en convertir los argumentos individuales de palabra clave en el diccionario options.
Antes (argumentos de palabra clave):
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="")
Después (opciones del diccionario):
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="")
Si pasa opciones que no son adecuadas para el cliente, obtendrá un error de tipo en el IDE.
2. Usar opciones específicas del proveedor (no más propiedades_adicionales)
Anteriormente, para pasar parámetros específicos del proveedor que no formaban parte del conjunto base de argumentos de palabra clave, tenía que usar el additional_properties parámetro :
Antes (mediante 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
},
)
Después (opciones directas con 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
},
)
Después (subclasing personalizado para nuevos parámetros):
O bien, si es un parámetro que aún no forma parte de Agent Framework (porque es nuevo o porque es personalizado para un back-end compatible con OpenAI), ahora puede subclase las opciones y usar la compatibilidad genérica:
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!
},
)
La ventaja principal es que la mayoría de los parámetros específicos del proveedor ahora forman parte del diccionario de opciones con tipo, lo que le ofrece:
- La función de autocompletar del IDE para todas las opciones disponibles
- Comprobación de tipos para detectar claves o valores no válidos
- No se necesitan propiedades_adicionales para parámetros de proveedor conocidos
- Extensión sencilla para parámetros personalizados o nuevos
3. Actualizar la configuración de ChatAgent
La inicialización y ejecución de ChatAgent siguen el mismo patrón:
Antes (argumentos de palabra clave en constructor y ejecución):
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. Opciones específicas del proveedor
Cada proveedor ahora tiene su propio TypedDict para las opciones, estos están habilitados de forma predeterminada. Esto le permite usar parámetros específicos del proveedor con seguridad de tipo completo:
Ejemplo de 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",
},
)
Pero también puede hacer que sea explícito:
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. Crear opciones personalizadas para modelos especializados
Una característica eficaz del nuevo sistema es la capacidad de crear opciones de TypedDict personalizadas para modelos especializados. Esto es especialmente útil para los modelos que tienen parámetros únicos, como los modelos de razonamiento con 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. Chat agents with Options (Agentes de chat con opciones)
La configuración genérica también se ha ampliado a los agentes de chat:
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",
},
)
y puede especificar el genérico en el cliente y en el agente, por lo que esto también es válido:
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. Actualizar implementaciones de cliente de chat personalizadas
Si ha implementado un cliente de chat personalizado mediante la extensión de BaseChatClient, actualice los métodos internos:
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")
# ...
Patrones comunes de migración
Patrón 1: Actualización de parámetro simple
# Before - keyword arguments
await client.get_response("Hello", temperature=0.7)
# After - options dict
await client.get_response("Hello", options={"temperature": 0.7})
Patrón 2: Varios parámetros
# 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,
},
)
Patrón 3: Cliente de chat con herramientas
En el caso de los clientes de chat, tools ahora se ubica en el diccionario de opciones.
# 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",
},
)
Patrón 4: Agente con herramientas e instrucciones
Para la creación del agente, tools y instructions pueden permanecer como argumentos de palabra clave. Para run(), solo tools está disponible:
# 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",
},
)
Patrón 5: Parámetros Específicos del Proveedor
# 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}
Resumen de cambios importantes
| Aspecto | Antes | Después |
|---|---|---|
| Opciones de cliente de chat | Argumentos de palabra clave individuales (temperature=0.7) |
Diccionario único options (options={"temperature": 0.7}) |
| Herramientas de cliente de chat |
tools=[...] argumento de palabra clave |
options={"tools": [...]} |
Creación tools de agente y instructions |
Argumentos de palabra clave | Still keyword arguments (sin cambios) |
Agente run()tools |
Argumento de palabra clave | Argumento de palabra clave Still (sin cambios) |
Agente run()instructions |
Argumento de palabra clave | Movido a options={"instructions": ...} |
| Opciones específicas del proveedor | additional_properties={...} |
Incluido directamente en options dict |
| Opciones predeterminadas del agente | Argumentos de palabra clave en el constructor | default_options={...} |
| Opciones de ejecución del agente | Argumentos de palabra clave en run() |
Parámetro options={...} |
| Escritura de cliente | OpenAIChatClient() |
OpenAIChatClient[CustomOptions]() (opcional) |
| Agente escribiendo | ChatAgent(...) |
ChatAgent[CustomOptions](...) (opcional) |
Prueba de tu migración
Actualizaciones de ChatClient
- Busque todas las llamadas a
get_response()yget_streaming_response()que usen argumentos de palabra clave comomodel_id=,temperature=,tools=, , etc. - Mover todos los argumentos de palabra clave a un
options={...}diccionario - Mover los
additional_propertiesvalores directamente aloptionsdict
Actualizaciones de ChatAgent
- Búsqueda de todos los
ChatAgentconstructores yrun()llamadas que usan argumentos de palabra clave - Mover argumentos de palabra clave en constructores a
default_options={...} - Mover los argumentos de palabras clave de
run()aoptions={...} -
Excepción:
toolsyinstructionspueden permanecer como argumentos de palabra clave enChatAgent.__init__()ycreate_agent() -
Excepción:
toolspuede permanecer como argumento de palabra clave enrun()
Actualizaciones de cliente de chat personalizadas
- Actualice las firmas de método
_inner_get_response()y_inner_get_streaming_response(): cambie el parámetrochat_options: ChatOptionsaoptions: dict[str, Any]. - Actualice el acceso de atributos (por ejemplo,
chat_options.model_id) a acceso de diccionario (por ejemplo,options.get("model_id")) - (Opcional) Si usa parámetros no estándar: defina un TypedDict personalizado.
- Adición de parámetros de tipo genérico a la clase de cliente
Para todos
-
Ejecutar comprobador de tipos: use
mypyopyrightpara detectar errores de tipo. - Prueba de un extremo a otro: ejecute la aplicación para comprobar la funcionalidad.
Compatibilidad con IDE
El nuevo sistema basado en TypedDict proporciona una excelente compatibilidad con ide:
- Autocompletar: obtener sugerencias para todas las opciones disponibles
- Comprobación de tipos: detectar teclas de opción no válidas durante el desarrollo
- Documentación: Mantenga el puntero sobre las claves para ver descripciones
- Específico del proveedor: las opciones de cada proveedor muestran solo parámetros relevantes.
Pasos siguientes
Para ver los diccionarios tipados en acción en el caso de utilizar los modelos de razonamiento de OpenAI con la API de completado de chat, puede explorar este ejemplo.
Después de completar la migración:
- Exploración de opciones específicas del proveedor en la documentación de api
- Revisión de ejemplos actualizados
- Más información sobre la creación de clientes de chat personalizados
Para obtener ayuda adicional, consulte la documentación de Agent Framework o póngase en contacto con la comunidad.