Azure Bot Framework SDK para SDK de agentes de Microsoft 365 guía de migración para Python

En este artículo se describen los cambios necesarios para migrar desde Bot Framework SDK para Python a la SDK de agentes de Microsoft 365 para Python.

Tip

Trate este trabajo como un esfuerzo de modernización, no solo un intercambio de paquetes. El SDK de Agentes favorece patrones más simples y sin opinión (async/await, inyección de dependencias, logging estándar) y elimina características heredadas. Mantenga solo lo que realmente necesita el bot y evite llevar a cabo la complejidad de las plantillas antiguas.

Prerrequisitos

  • Python versión 3.10 o posterior (3.11+ recomendado, admite hasta 3.14)
  • Proyecto de Bot Framework SDK existente
  • recurso de Azure Bot Service

Recursos de Azure

Los recursos Azure existentes permanecen sin cambios durante esta migración. Siga usando el registro del bot de Azure actual (id. de aplicación y secreto). Referencias esos valores en la nueva estructura de configuración descrita más adelante. Muchas soluciones también incluyen configuraciones de aplicaciones heredadas como APP_ID, APP_PASSWORD, y APP_TENANT_ID. Estas entradas son inofensivas durante la migración, pero la SDK de agentes de Microsoft 365 ya no las usa. Puedes eliminar estos ajustes después de validar la nueva configuración.

Primeros pasos

Empiece por actualizar las dependencias del paquete. Los siguientes cambios no cubren todos los espacios de nombres que necesite tocar, pero controlan la mayoría de las sustituciones de paquetes.

Actualizar las dependencias del paquete

SDK de Bot Framework SDK de agentes
botbuilder-core microsoft-agents-hosting-core
botbuilder-schema microsoft-agents-activity
botbuilder-azure microsoft-agents-storage-blob y microsoft-agents-storage-cosmos
botbuilder-integration-aiohttp microsoft-agents-hosting-aiohttp

Si el bot se integra con Microsoft Teams, incluya el paquete de extensión de Teams microsoft-agents-hosting-teams para las características principales de Teams.

Para la autenticación, añade microsoft-agents-authentication-msal para gestionar la autenticación basada en MSAL.

Actualice su requirements.txt o el archivo de dependencias equivalente para sustituir los paquetes de Bot Framework por sus equivalentes del SDK de Agents. Usa pip install -r requirements.txt tu gestor de paquetes preferido para instalar las nuevas dependencias.

El SDK de Agentes impone estándares de calidad del código utilizando black para el formateo y flake8 para el linting. Considera añadir estas herramientas a tus dependencias de desarrollo.

Actualizar importaciones

Important

El SDK de Agentes utiliza subrayos en las rutas de importación (microsoft_agents) en lugar de puntos (microsoft.agents). Este cambio afecta a todas las importaciones.

Después, actualiza las importaciones. El enfoque más sencillo es buscar y reemplazar el texto exacto a nivel de proyecto.

Importación de Bot Framework Importación del SDK de los agentes
from botbuilder.core import ... from microsoft_agents.hosting.core import ...
from botbuilder.schema import ... from microsoft_agents.activity import ...
from botbuilder.integration.aiohttp import ... from microsoft_agents.hosting.aiohttp import ...
from botbuilder.core.teams import ... from microsoft_agents.hosting.teams import ...

Renombramiento de tipos y clases

Algunos tipos y clases tienen nombres diferentes en el SDK de Agentes. Utiliza los siguientes mapeos para guiar tus cambios.

Bot Framework SDK de agentes
BotState AgentState
BotFrameworkAdapter CloudAdapter
BotFrameworkHttpClient AgentHttpClient
OAuthPromptSettings.connection_name OAuthPromptSettings.azure_bot_oauth_connection_name

Cambios de clase de actividad

La Activity clase en el SDK de Agentes incluye validación integrada mediante Pydantic. Puedes analizar y validar actividades desde JSON o diccionarios usando Activity.model_validate().

Además, la Activity clase centraliza las operaciones relacionadas con las cargas útiles de actividad. Los métodos que antes eran estáticos en TurnContext son ahora métodos de instancia en Activity:

Método Estático de Bot Framework Método de instancia del SDK de agentes
TurnContext.apply_conversation_reference() activity.apply_conversation_reference()
TurnContext.get_conversation_reference() activity.get_conversation_reference()
TurnContext.get_reply_conversation_reference() activity.get_reply_conversation_reference()
TurnContext.remove_recipient_mention() activity.remove_recipient_mention()
TurnContext.get_mentions() activity.get_mentions()
TurnContext.remove_mention_text() activity.remove_mention_text()

Actualice las referencias comunes turn_state . Reemplace los siguientes usos en consecuencia.

Bot Framework SDK de agentes
turn_context.turn_state.get(ConnectorClient) turn_context.services.get(ConnectorClient)
turn_context.turn_state.get(UserTokenClient) turn_context.services.get(UserTokenClient)
turn_context.turn_state turn_context.services

Configuración

El SDK de Agentes utiliza variables de entorno con una convención jerárquica de nombres para la configuración.

Variables de entorno

Crea o actualiza tu .env archivo con la siguiente estructura:

# Required for Azure Bot Service
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID=your-app-id
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET=your-app-secret
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID=your-tenant-id

# Optional - for local debugging
PORT=3978

Nota de migración: actualice los nombres de las variables de entorno como se muestra en la tabla siguiente:

SDK de Bot Framework SDK de agentes
APP_ID o MICROSOFT_APP_ID CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID
APP_PASSWORD o MICROSOFT_APP_PASSWORD CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET
APP_TENANT_ID o MICROSOFT_APP_TENANT_ID CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID

La configuración del SDK de Agentes utiliza dobles subrayos (__) para representar jerarquías de configuración anidadas. Este patrón permite una gestión flexible de configuración en diferentes entornos de despliegue.

Arranque e inicialización

La inicialización varía en el SDK de Agentes. El SDK de Bot Framework generalmente se utiliza aiohttp con la configuración manual de un adaptador. Usando el SDK de Agentes, puedes utilizar las utilidades integradas del servidor para una configuración más sencilla.

Configuración del servidor

Enfoque del SDK del Bot Framework

from aiohttp import web
from botbuilder.core import BotFrameworkAdapter, BotFrameworkAdapterSettings
from botbuilder.schema import Activity

# Configure adapter
SETTINGS = BotFrameworkAdapterSettings(
    app_id=os.environ.get("APP_ID", ""),
    app_password=os.environ.get("APP_PASSWORD", "")
)
ADAPTER = BotFrameworkAdapter(SETTINGS)

# Bot instance
BOT = MyBot()

async def messages(req: web.Request) -> web.Response:
    if "application/json" in req.headers["Content-Type"]:
        body = await req.json()
    else:
        return web.Response(status=415)

    activity = Activity().deserialize(body)
    auth_header = req.headers["Authorization"] if "Authorization" in req.headers else ""

    response = await ADAPTER.process_activity(activity, auth_header, BOT.on_turn)
    if response:
        return web.json_response(data=response.body, status=response.status)
    return web.Response(status=201)

APP = web.Application()
APP.router.add_post("/api/messages", messages)

if __name__ == "__main__":
    web.run_app(APP, host="localhost", port=3978)

Enfoque del SDK de agentes (patrón decorador)

El enfoque recomendado utiliza el AgentApplication con decoradores para un estilo más moderno y declarativo:

import re
from os import environ
from dotenv import load_dotenv

from microsoft_agents.hosting.aiohttp import CloudAdapter
from microsoft_agents.hosting.core import (
    Authorization,
    AgentApplication,
    TurnState,
    TurnContext,
    MemoryStorage,
)
from microsoft_agents.authentication.msal import MsalConnectionManager
from microsoft_agents.activity import load_configuration_from_env

# Load environment variables
load_dotenv()
agents_sdk_config = load_configuration_from_env(environ)

# Initialize core components
STORAGE = MemoryStorage()
CONNECTION_MANAGER = MsalConnectionManager(**agents_sdk_config)
ADAPTER = CloudAdapter(connection_manager=CONNECTION_MANAGER)
AUTHORIZATION = Authorization(STORAGE, CONNECTION_MANAGER, **agents_sdk_config)

# Create agent application
AGENT_APP = AgentApplication[TurnState](
    storage=STORAGE,
    adapter=ADAPTER,
    authorization=AUTHORIZATION,
    **agents_sdk_config
)

# Register handlers using decorators
@AGENT_APP.conversation_update("membersAdded")
async def on_members_added(context: TurnContext, _state: TurnState):
    await context.send_activity("Welcome!")
    return True

@AGENT_APP.activity("message")
async def on_message(context: TurnContext, _state: TurnState):
    await context.send_activity(f"You said: {context.activity.text}")

El SDK de Agentes permite load_configuration_from_env() cargar automáticamente la configuración desde variables de entorno, eliminando el análisis manual de configuración. El patrón decorador permite registrar manejadores de forma declarativa sin herencia explícita basada en clases.

Autenticación y seguridad

El SDK del Bot Framework incluía la validación JSON Web Token (JWT) en el adaptador. El SDK de Agentes separa las preocupaciones de autenticación, así que puedes configurar el middleware de autenticación explícitamente.

Para entornos de producción, asegúrate de que la validación JWT esté habilitada mediante la CloudAdapter configuración. El adaptador valida automáticamente las solicitudes entrantes utilizando la configuración de autenticación MSAL.

Para el desarrollo local con el Bot Framework Emulator, puedes usar credenciales vacías en tu archivo .env:

# Only for local development with Emulator
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__ANONYMOUS_ALLOWED=True

Gestión de actividades

La mayoría de los bots creados con Bot Framework SDK se basan en la ActivityHandler clase base.

El SDK de Agentes proporciona un ActivityHandler compatible que mantiene una interfaz de API similar para facilitar la migración.

Diferencias clave

Cambios en la firma del método del controlador

Los gestores de SDK del Marco de Bots suelen usar parámetros posicionales, mientras que los gestores de SDK de Agentes mantienen el mismo patrón con TurnContext como parámetro principal.

Métodos adicionales en el SDK de Agentes

Método Description
on_message_delete() Controla las actividades de eliminación de mensajes
on_message_update() Controla las actividades de actualización de mensajes
on_sign_in_invoke() Controla las actividades de invocación de inicio de sesión

Métodos ausentes en el SDK de Agentes

Método Motivo
on_command_activity() No se admiten actividades de comando
on_command_result_activity() No se admiten las actividades relacionadas con los resultados de los comandos

Ejemplo de migración

SDK de Bot Framework

from botbuilder.core import ActivityHandler, TurnContext
from botbuilder.schema import ChannelAccount

class MyBot(ActivityHandler):
    async def on_message_activity(self, turn_context: TurnContext):
        await turn_context.send_activity(f"You said: {turn_context.activity.text}")

    async def on_members_added_activity(
        self,
        members_added: list[ChannelAccount],
        turn_context: TurnContext
    ):
        for member in members_added:
            if member.id != turn_context.activity.recipient.id:
                await turn_context.send_activity("Welcome!")

SDK de agentes

from microsoft_agents.hosting.core import AgentApplication, TurnState, TurnContext

# AGENT_APP is initialized as shown in the Startup and initialization section

@AGENT_APP.activity("message")
async def on_message(context: TurnContext, _state: TurnState):
    await context.send_activity(f"You said: {context.activity.text}")

@AGENT_APP.conversation_update("membersAdded")
async def on_members_added(context: TurnContext, _state: TurnState):
    for member in context.activity.members_added:
        if member.id != context.activity.recipient.id:
            await context.send_activity("Welcome!")
    return True

La migración es mayormente sencilla, con los principales cambios en las declaraciones de importación. La mayoría de los bots existentes basados en ActivityHandler funcionan con modificaciones mínimas.

Administración de estados

ConversationState, UserStatey PrivateConversationState son compatibles con algunas diferencias. Los patrones de gestión del estado central son similares al SDK del Bot Framework.

Debes registrar los objetos de estado y guardarlos explícitamente tras las modificaciones.

from microsoft_agents.hosting.core import (
    AgentApplication,
    TurnState,
    TurnContext,
    ConversationState,
    UserState,
    MemoryStorage,
)

# Initialize storage and state
STORAGE = MemoryStorage()
conversation_state = ConversationState(STORAGE)
user_state = UserState(STORAGE)
count_property = conversation_state.create_property("conversation_data")

# AGENT_APP is initialized as shown in the Startup and initialization section

@AGENT_APP.activity("message")
async def on_message(context: TurnContext, _state: TurnState):
    # Access state
    conversation_data = await count_property.get(context, {})

    # Modify state
    conversation_data["count"] = conversation_data.get("count", 0) + 1
    await count_property.set(context, conversation_data)

    await context.send_activity(f"Message count: {conversation_data['count']}")

    # Save state changes
    await conversation_state.save_changes(context)
    await user_state.save_changes(context)

Opciones de almacenamiento

El SDK de Agentes proporciona implementaciones de almacenamiento para diferentes backends:

# Memory storage (development only)
from microsoft_agents.hosting.core import MemoryStorage
storage = MemoryStorage()

# Azure Blob Storage
from microsoft_agents.storage.blob import BlobStorage
storage = BlobStorage(
    connection_string="your-connection-string",
    container_name="bot-state"
)

# Azure Cosmos DB
from microsoft_agents.storage.cosmos import CosmosDbPartitionedStorage
storage = CosmosDbPartitionedStorage(
    cosmos_client_options={
        "url": "your-cosmos-url",
        "key": "your-cosmos-key"
    },
    database_id="bot-db",
    container_id="bot-state"
)

Registro

El SDK de Agentes usa el módulo estándar logging de Python. Configura el registro en tu archivo principal de aplicación.

import logging

# Configure logging for Agents SDK
ms_agents_logger = logging.getLogger("microsoft_agents")
console_handler = logging.StreamHandler()
console_handler.setFormatter(
    logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
)
ms_agents_logger.addHandler(console_handler)
ms_agents_logger.setLevel(logging.INFO)

Niveles de registro

  • DEPURACIÓN: Seguimiento detallado del estado local
  • INFO: Gestión de actividades, llamadas a la API y solicitudes hacia o desde entidades externas
  • ADVERTENCIA: Eventos inesperados que causan posibles problemas
  • ERROR: Errores observados, ya sea detectados o no

Patrones comunes de migración

Bot de eco simple

Bot simple de echo en Bot Framework SDK

from botbuilder.core import ActivityHandler, TurnContext

class EchoBot(ActivityHandler):
    async def on_message_activity(self, turn_context: TurnContext):
        await turn_context.send_activity(f"Echo: {turn_context.activity.text}")

Bot de eco simple en el SDK de Agentes

from microsoft_agents.hosting.core import AgentApplication, TurnState, TurnContext

# AGENT_APP is initialized as shown in the Startup and initialization section

@AGENT_APP.activity("message")
async def on_message(context: TurnContext, _state: TurnState):
    await context.send_activity(f"Echo: {context.activity.text}")

Gestión de estado con contador

from microsoft_agents.hosting.core import (
    AgentApplication,
    TurnState,
    TurnContext,
    ConversationState,
    MemoryStorage,
)

# Initialize storage and state
STORAGE = MemoryStorage()
conversation_state = ConversationState(STORAGE)
count_property = conversation_state.create_property("count")

# AGENT_APP is initialized as shown in the Startup and initialization section

@AGENT_APP.activity("message")
async def on_message(context: TurnContext, _state: TurnState):
    count = await count_property.get(context, 0)
    count += 1
    await count_property.set(context, count)

    await context.send_activity(f"Message count: {count}")
    await conversation_state.save_changes(context)

Bot de Teams

from microsoft_agents.hosting.core import AgentApplication, TurnState, TurnContext

# AGENT_APP is initialized as shown in the Startup and initialization section
# Include microsoft-agents-hosting-teams in your dependencies for Teams support

@AGENT_APP.conversation_update("membersAdded")
async def on_members_added(context: TurnContext, _state: TurnState):
    for member in context.activity.members_added:
        await context.send_activity(f"Welcome to the team, {member.name}!")
    return True

@AGENT_APP.activity("message")
async def on_message(context: TurnContext, _state: TurnState):
    # Remove mentions
    text = context.activity.remove_mention_text(context.activity.recipient.id)
    await context.send_activity(f"You said: {text}")

Solución de problemas y sugerencias

Las siguientes sugerencias pueden ayudarle a tener más éxito.

Errores de importación

Si encuentras errores de importación, asegúrate de usar subrayos (microsoft_agents) en lugar de puntos (microsoft.agents) en todas las sentencias de importación. Este error es el problema de migración más común.

Patrones asincrónicos y await

Todos los métodos de bot deben ser async y deben usar await para operaciones asincrónicas. Asegúrate de que todas las llamadas a send_activity, operaciones de estado y operaciones de diálogo usen await.

Sugerencias de tipo

El SDK de Agentes utiliza ampliamente las sugerencias de tipo de Python. Considera añadir anotaciones de tipo a tu código para el bot para mejorar el soporte del IDE y la detección de errores.

from microsoft_agents.hosting.core import TurnContext

async def on_message_activity(self, turn_context: TurnContext) -> None:
    await turn_context.send_activity("Hello")

Validación de configuración

Si su bot no se inicia debido a errores de configuración, compruebe que los nombres de las variables de entorno utilicen la notación correcta con doble guion bajo (__) y de que ha establecido todos los valores requeridos.

Errores 401 locales durante el proceso de depuración

Si detectas errores 401 durante la depuración local usando el Bot Framework Emulator, verifica que tus credenciales estén correctamente configuradas en el .env archivo o utiliza la configuración de autenticación del emulador.

compatibilidad con versiones de Python

Asegúrese de que usa Python 3.10 o superior. El SDK de agentes usa características modernas de Python que no están disponibles en versiones anteriores.

Lista de comprobación para la migración

Analizar y planificar: Identificar cualquier característica obsoleta y decidir el alcance de la migración frente a la reconstrucción. ✓ Actualizar la versión de Python: Actualice a Python 3.10 o superior (recomendado 3.11+). ✓ Reemplazar paquetes: Eliminar botbuilder-*; agregar microsoft-agents-* (hosting-core, activity, hosting-aiohttp, authentication-msal, proveedores de almacenamiento, hosting-teams). ✓ Actualizar importaciones: Aplicar buscar/reemplazar según las tablas anteriores; Cambia todo microsoft.agents por microsoft_agents. ✓ Actualizar tipos y clases: Corregir APIs renombradas y mover TurnContext métodos estáticos a Activity métodos de instancia. ✓ Actualizar configuración: cree un archivo .env con nombres jerárquicos (doble guion bajo). ✓ Inicialización de actualización: Usar CloudAdapter con MsalAuth.from_environment() y AgentsHttpMiddleware. ✓ Configurar logging: Configurar la captura de logs en Python para el microsoft_agents logger. ✓ Compilar y probar localmente: Usar el Bot Framework Emulator con credenciales; Valida los escenarios principales. ✓ Deploy y monitor: actualizar variables de entorno en Azure para que coincidan con la nueva configuración y supervisar los registros después del lanzamiento.