Descripción de la biblioteca de inteligencia artificial de Teams
La biblioteca de inteligencia artificial de Teams admite JavaScript y simplifica la creación de bots que pueden interactuar con Microsoft Teams. También facilita la migración de los bots existentes para usar características con tecnología de inteligencia artificial. Admite la migración de las funcionalidades de mensajería, extensión de mensaje y tarjetas adaptables al nuevo formato. También puede actualizar las aplicaciones de Teams existentes con estas características.
Anteriormente, usó botbuilder SDK para crear bots para Teams. La biblioteca de inteligencia artificial de Teams está diseñada para facilitar este proceso e incluye compatibilidad con la inteligencia artificial. Inicialmente, es posible que actualice el bot sin inteligencia artificial, pero después de actualizarlo, puede conectarse a la inteligencia artificial o a los modelos de lenguaje grande (LLM) disponibles en la biblioteca de inteligencia artificial.
Con la biblioteca de inteligencia artificial de Teams, puede centrarse en:
- Descripción del rol del controlador de actividad en la administración de conversaciones.
- Diseño de lógica de bot para respuestas inteligentes.
- Integración del procesamiento de lenguaje natural (NLP) para traducir intenciones de usuario a acciones.
Controladores de actividad
La biblioteca de inteligencia artificial de Teams admite los siguientes controladores de actividad:
- Envío o recepción de mensajes
- Funcionalidades de extensión de mensaje (ME)
- Funcionalidades de tarjetas adaptables
Debe usar la biblioteca de inteligencia artificial para aplicar scaffolding a los controladores de bot y tarjeta adaptable al archivo de origen. En las secciones posteriores, hemos usado los ejemplos de la biblioteca de inteligencia artificial para explicar cada funcionalidad y la ruta de acceso a la migración.
Envío o recepción de mensajes
Puede enviar y recibir mensajes mediante Bot Framework. La aplicación escucha mensajes de usuario, elimina el estado de la conversación tras la recepción y responde. También realiza un seguimiento del número de mensajes de una conversación y devuelve el mensaje del usuario con el recuento.
// Listen for user to say "/reset" and then delete conversation state
app.OnMessage("/reset", ActivityHandlers.ResetMessageHandler);
// Listen for ANY message to be received. MUST BE AFTER ANY OTHER MESSAGE HANDLERS
app.OnActivity(ActivityTypes.Message, ActivityHandlers.MessageHandler);
return app;
Extensiones de mensajería
En el SDK de TeamsActivityHandler
Bot Framework, configure el controlador de consultas extensiones de mensaje mediante la extensión de métodos de controlador. La aplicación escucha las acciones de búsqueda y las pulsaciones de elementos. Da formato a los resultados de búsqueda como tarjetas principales que muestran información del paquete y los muestra en la extensión de mensajería.
// Listen for search actions
app.MessageExtensions.OnQuery("searchCmd", activityHandlers.QueryHandler);
// Listen for item tap
app.MessageExtensions.OnSelectItem(activityHandlers.SelectItemHandler);
return app;
// Format search results in ActivityHandlers.cs
List<MessagingExtensionAttachment> attachments = packages.Select(package => new MessagingExtensionAttachment
{
ContentType = HeroCard.ContentType,
Content = new HeroCard
{
Title = package.Id,
Text = package.Description
},
Preview = new HeroCard
{
Title = package.Id,
Text = package.Description,
Tap = new CardAction
{
Type = "invoke",
Value = package
}
}.ToAttachment()
}).ToList();
// Return results as a list
return new MessagingExtensionResult
{
Type = "result",
AttachmentLayout = "list",
Attachments = attachments
};
Funcionalidades de tarjetas adaptables
Registre controladores de acciones de tarjeta adaptable mediante la app.adaptiveCards
propiedad . La aplicación escucha mensajes con static
o dynamic
palabras clave y devuelve una tarjeta adaptable mediante StaticMessageHandler()
o DynamicMessageHandler()
. También escucha las consultas de una tarjeta de búsqueda dinámica y los botones de envío.
// Listen for messages that trigger returning an adaptive card
app.OnMessage(new Regex(@"static", RegexOptions.IgnoreCase), activityHandlers.StaticMessageHandler);
app.OnMessage(new Regex(@"dynamic", RegexOptions.IgnoreCase), activityHandlers.DynamicMessageHandler);
// Listen for query from dynamic search card
app.AdaptiveCards.OnSearch("nugetpackages", activityHandlers.SearchHandler);
// Listen for submit buttons
app.AdaptiveCards.OnActionSubmit("StaticSubmit", activityHandlers.StaticSubmitHandler);
app.AdaptiveCards.OnActionSubmit("DynamicSubmit", activityHandlers.DynamicSubmitHandler);
// Listen for ANY message to be received. MUST BE AFTER ANY OTHER HANDLERS
app.OnActivity(ActivityTypes.Message, activityHandlers.MessageHandler);
return app;
Lógica del bot para controlar una acción
El bot responde a la entrada del usuario con la acción LightsOn
de encender las luces.
En el ejemplo siguiente se muestra cómo la biblioteca de inteligencia artificial de Teams permite administrar la lógica del bot para controlar una acción LightsOn
o LightsOff
conectarla al símbolo del sistema usado con OpenAI:
/ Create AI Model
if (!string.IsNullOrEmpty(config.OpenAI?.ApiKey))
{
builder.Services.AddSingleton<OpenAIModel>(sp => new(
new OpenAIModelOptions(config.OpenAI.ApiKey, "gpt-3.5-turbo")
{
LogRequests = true
},
sp.GetService<ILoggerFactory>()
));
}
else if (!string.IsNullOrEmpty(config.Azure?.OpenAIApiKey) && !string.IsNullOrEmpty(config.Azure.OpenAIEndpoint))
{
builder.Services.AddSingleton<OpenAIModel>(sp => new(
new AzureOpenAIModelOptions(
config.Azure.OpenAIApiKey,
"gpt-35-turbo",
config.Azure.OpenAIEndpoint
)
{
LogRequests = true
},
sp.GetService<ILoggerFactory>()
));
}
else
{
throw new Exception("please configure settings for either OpenAI or Azure");
}
// Create the bot as transient. In this case the ASP Controller is expecting an IBot.
builder.Services.AddTransient<IBot>(sp =>
{
// Create loggers
ILoggerFactory loggerFactory = sp.GetService<ILoggerFactory>()!;
// Create Prompt Manager
PromptManager prompts = new(new()
{
PromptFolder = "./Prompts"
});
// Adds function to be referenced in the prompt template
prompts.AddFunction("getLightStatus", async (context, memory, functions, tokenizer, args) =>
{
bool lightsOn = (bool)(memory.GetValue("conversation.lightsOn") ?? false);
return await Task.FromResult(lightsOn ? "on" : "off");
});
// Create ActionPlanner
ActionPlanner<AppState> planner = new(
options: new(
model: sp.GetService<OpenAIModel>()!,
prompts: prompts,
defaultPrompt: async (context, state, planner) =>
{
PromptTemplate template = prompts.GetPrompt("sequence");
return await Task.FromResult(template);
}
)
{ LogRepairs = true },
loggerFactory: loggerFactory
);
return new TeamsLightBot(new()
{
Storage = sp.GetService<IStorage>(),
AI = new(planner),
LoggerFactory = loggerFactory,
TurnStateFactory = () =>
{
return new AppState();
}
});
});
// LightBotActions defined in LightBotActions.cs
[Action("LightsOn")]
public async Task<string> LightsOn([ActionTurnContext] ITurnContext turnContext, [ActionTurnState] AppState turnState)
{
turnState.Conversation.LightsOn = true;
await turnContext.SendActivityAsync(MessageFactory.Text("[lights on]"));
return "the lights are now on";
}
[Action("LightsOff")]
public async Task<string> LightsOff([ActionTurnContext] ITurnContext turnContext, [ActionTurnState] AppState turnState)
{
turnState.Conversation.LightsOn = false;
await turnContext.SendActivityAsync(MessageFactory.Text("[lights off]"));
return "the lights are now off";
}
[Action("Pause")]
public async Task<string> LightsOff([ActionTurnContext] ITurnContext turnContext, [ActionParameters] Dictionary<string, object> args)
{
// Try to parse entities returned by the model.
// Expecting "time" to be a number of milliseconds to pause.
if (args.TryGetValue("time", out object? time))
{
if (time != null && time is string timeString)
{
if (int.TryParse(timeString, out int timeInt))
{
await turnContext.SendActivityAsync(MessageFactory.Text($"[pausing for {timeInt / 1000} seconds]"));
await Task.Delay(timeInt);
}
}
}
return "done pausing";
}
Consulta de extensión de mensaje
La biblioteca de inteligencia artificial de Teams proporciona una manera más intuitiva de crear controladores para comandos de consulta de extensión de mensaje, que funcionan junto con el SDK de Bot Framework de Teams existente.
A continuación se muestra un ejemplo de cómo puede estructurar el código para controlar una consulta de extensión de mensaje para el searchCmd
comando .
// Listen for search actions
app.MessageExtensions.OnQuery("searchCmd", activityHandlers.QueryHandler);
// Listen for item tap
app.MessageExtensions.OnSelectItem(activityHandlers.SelectItemHandler);
return app;
// Format search results
List<MessagingExtensionAttachment> attachments = packages.Select(package => new MessagingExtensionAttachment
{
ContentType = HeroCard.ContentType,
Content = new HeroCard
{
Title = package.Id,
Text = package.Description
},
Preview = new HeroCard
{
Title = package.Id,
Text = package.Description,
Tap = new CardAction
{
Type = "invoke",
Value = package
}
}.ToAttachment()
}).ToList();
return new MessagingExtensionResult
{
Type = "result",
AttachmentLayout = "list",
Attachments = attachments
};
Intenciones para acciones
Una interfaz sencilla para acciones y predicciones permite a los bots reaccionar con confianza. La presencia ambiental ayuda a los bots a aprender la intención, a usar mensajes basados en la lógica de negocios y a generar respuestas. Con la biblioteca de inteligencia artificial de Teams, el símbolo del sistema describe las acciones del bot y proporciona ejemplos.
El historial de conversaciones permite un diálogo natural, como agregar cereales a la lista de comestibles, seguido de agregar también café, lo que indica que se debe agregar café a la lista.
A continuación se muestra una conversación con una asistente de inteligencia artificial. La asistente de inteligencia artificial puede administrar listas y reconoce los siguientes comandos:
- HACER
<action> <optional entities>
- DECIR
<response>
Además, admiten las siguientes acciones:
addItem list="<list name>" item="<text>"
removeItem list="<list name>" item="<text>"
summarizeLists
Todas las entidades son parámetros necesarios para las acciones.
Nombres de lista actuales:
{{conversation.listNames}}
Examples: Human: remind me to buy milk AI: DO addItem list="groceries" item="milk" THEN SAY Ok I added milk to your groceries list Human: we already have milk AI: DO removeItem list="groceries" item="milk" THEN SAY Ok I removed milk from your groceries list Human: buy ingredients to make margaritas AI: DO addItem list="groceries" item="tequila" THEN DO addItem list="groceries" item="orange liqueur" THEN DO addItem list="groceries" item="lime juice" THEN SAY Ok I added tequila, orange liqueur, and lime juice to your groceries list Human: do we have milk AI: DO findItem list="groceries" item="milk" Human: what's in my grocery list AI: DO summarizeLists Human: what's the contents of all my lists? AI: DO summarizeLists Human: show me all lists but change the title to Beach Party AI: DO summarizeLists Human: show me all lists as a card and sort the lists alphabetically AI: DO summarizeLists
Historial de conversaciones:
{{conversation.(history}}
Consulta actual:
Human: {{activity.text}}
Nombres de lista actuales:
{{conversation.listNames}}
IA: la lógica del bot se simplifica para incluir controladores para acciones como
addItem
yremoveItem
. Esta distinción entre las acciones y los avisos actúa como una herramienta eficaz, ya que guía a la inteligencia artificial para ejecutar las acciones y los avisos.
[Action("AddItem")]
public string AddItem([ActionTurnState] ListState turnState, [ActionParameters] Dictionary<string, object> parameters)
{
ArgumentNullException.ThrowIfNull(turnState);
ArgumentNullException.ThrowIfNull(parameters);
string listName = GetParameterString(parameters, "list");
string item = GetParameterString(parameters, "item");
IList<string> items = GetItems(turnState, listName);
items.Add(item);
SetItems(turnState, listName, items);
return "item added. think about your next action";
}
[Action("RemoveItem")]
public async Task<string> RemoveItem([ActionTurnContext] ITurnContext turnContext, [ActionTurnState] ListState turnState, [ActionParameters] Dictionary<string, object> parameters)
{
ArgumentNullException.ThrowIfNull(turnContext);
ArgumentNullException.ThrowIfNull(turnState);
ArgumentNullException.ThrowIfNull(parameters);
string listName = GetParameterString(parameters, "list");
string item = GetParameterString(parameters, "item");
IList<string> items = GetItems(turnState, listName);
if (!items.Contains(item))
{
await turnContext.SendActivityAsync(ResponseBuilder.ItemNotFound(listName, item)).ConfigureAwait(false);
return "item not found. think about your next action";
}
items.Remove(item);
SetItems(turnState, listName, items);
return "item removed. think about your next action";
}