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.
Importante
Los complementos MCP y API se admiten como acciones dentro de los agentes declarativos. No están habilitadas como experiencias independientes en Microsoft 365 Copilot.
Los complementos de API son acciones personalizadas para agentes declarativos que conectan una API REST con una especificación OpenAPI a Microsoft 365 Copilot. En esta guía se muestra cómo agregar un complemento de API a un agente declarativo mediante TypeSpec y el kit de herramientas de agentes de Microsoft 365.
Requisitos previos
- Requisitos especificados en Requisitos para las opciones de extensibilidad de Copilot
- Una API de REST existente (este tutorial usa la API de marcador de posición JSON)
- Visual Studio Code
- Kit de herramientas de agentes de Microsoft 365
- Un agente creado con Microsoft 365 Agents Toolkit y TypeSpec para Microsoft 365 Copilot
Sugerencia
Para obtener los mejores resultados, asegúrese de que la API que está generando sigue las directrices detalladas en Cómo hacer que un documento OpenAPI sea eficaz para ampliar Copilot.
Configurar el proyecto del complemento de API en VS Code
En este artículo se presupone que ya tiene un proyecto de agente declarativo que se creó con el Kit de herramientas de agentes de Microsoft 365 y TypeSpec. Para agregar un complemento de API a ese proyecto, defina sus operaciones de API de REST en TypeSpec y, a continuación, aprovisione el agente. En las secciones siguientes se explica cada operación.
- Si aún no tiene un proyecto de agente, cree uno siguiendo Crear un agente declarativo. Cuando se le solicite, seleccione Empezar con TypeSpec para Microsoft 365 Copilot.
- Abra el proyecto del agente en Visual Studio Code y abra el
main.tsparchivo en la raíz del proyecto. - Defina el complemento de API mediante la adición de operaciones a
main.tspcomo se muestra en las secciones siguientes. Cuando haya terminado, aprovisione el agente como se describe en Aprovisionar y probar las acciones personalizadas.
Agregar una GET operación
Para iniciar, agregue una GET operación para enumerar todos los elementos de publicación. Abra el main.tsp archivo y agregue un nuevo espacio PostsAPI de nombres en el espacio de MyAgent nombres con el siguiente contenido.
// Omitted for brevity
namespace MyAgent {
// Omitted for brevity
@service
@server("https://jsonplaceholder.typicode.com")
@actions(#{
nameForHuman: "Posts APIs",
descriptionForHuman: "Manage blog post items with the JSON Placeholder API.",
descriptionForModel: "Read, create, update and delete blog post items with the JSON Placeholder API."
})
namespace PostsAPI {
/**
* List all blog post items.
*/
@route("/posts")
@get op listPosts(): PostItem[];
/**
* Structure of a blog post item.
*/
model PostItem {
/**
* The ID of the user who created the post.
*/
userId: integer;
/**
* The ID of the post.
*/
@visibility(Lifecycle.Read)
id: integer;
/**
* The title of the post.
*/
title: string;
/**
* The body of the post.
*/
body: string;
}
}
// Omitted for brevity
}
Este código define el PostItem modelo y la API GET /postsde REST.
Agregar una GET operación con un parámetro de consulta
La GET operación del ejemplo anterior no toma parámetros. Para habilitar el filtrado por identificador de usuario, actualice la GET operación con un parámetro de consulta opcional para filtrar los resultados por identificador de usuario.
Abra el main.tsp archivo y reemplace la operación existente listPosts con el siguiente contenido.
/**
* List all blog post items.
* @param userId The ID of the user who created the post. If not provided, all posts will be returned.
*/
@route("/posts")
@get op listPosts(@query userId?: integer): PostItem[];
El @query userId? parámetro agregado actualiza listPosts la API REST a GET /posts?userId={userId}.
Agregar una tarjeta adaptativa a una GET operación
Agregar una tarjeta adaptativa a la operación cambia la listPosts forma en que se representan las citas en la respuesta generada.
Cree un archivo llamado post-card.json en el directorio appPackage y agregue el siguiente contenido.
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5",
"body": [
{
"type": "Container",
"$data": "${$root}",
"items": [
{
"type": "TextBlock",
"text": "**${if(title, title, 'N/A')}**",
"wrap": true
},
{
"type": "TextBlock",
"text": "${if(body, body, 'N/A')}",
"wrap": true
}
]
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "Read More",
"url": "https://www.bing.com/search?q=https://jsonplaceholder.typicode.com/posts/${id}"
}
]
}
Abre el main.tsp archivo y agrega el @card decorador a la listPosts operación, como se muestra en el siguiente fragmento de código.
/**
* List all blog post items.
* @param userId The ID of the user who created the post. If not provided, all posts will be returned.
*/
@route("/posts")
@card(#{ dataPath: "$", file: "post-card.json", properties: #{ title: "$.title" } })
@get op listPosts(@query userId?: integer): PostItem[];
Agregar una POST operación
Abra el main.tsp archivo y, dentro del PostsAPI espacio de nombres, agregue el siguiente contenido.
/**
* Create a new blog post item.
* @param post The post item to create.
*/
@route("/posts")
@post op createPost(@body post: PostItem): PostItem;
Este código define la API POST /postsREST , que crea una nueva entrada de blog.
Agregar una PATCH operación
Abra el main.tsp archivo y, dentro del PostsAPI espacio de nombres, agregue el siguiente contenido.
/**
* Updates a blog post item.
* @param id The ID of the post to update.
* @param post The updated post item.
*/
@route("/posts/{id}")
@patch op updatePost(@path id: integer, @body post: PostItem): PostItem;
Este código define la API PATCH /posts/{id}REST , que actualiza una entrada de blog existente.
Agregar una DELETE operación
Abra el main.tsp archivo y, dentro del PostsAPI espacio de nombres, agregue el siguiente contenido.
/**
* Deletes a blog post item.
* @param id The ID of the post to delete.
*/
@route("/posts/{id}")
@delete op deletePost(@path id: integer): void;
Este código define la API DELETE /posts/{id}REST , que elimina una entrada de blog existente.
Aprovisionar y probar las acciones personalizadas
Use el panel Ciclo de vida del Kit de herramientas de agentes de Microsoft 365 para aprovisionar a su agente y su complemento de API y, a continuación, pruebe las acciones personalizadas en Microsoft 365 Copilot.
- Seleccione el icono del Kit de herramientas de agentes de Microsoft 365 en la barra de actividades izquierda.
- En el panel Ciclo de vida , seleccione Aprovisionar.
- Espere a que se complete el aprovisionamiento y, a continuación, ábralo https://m365.cloud.microsoft/ en el explorador.
- Seleccione su agente de la lista de agentes.
- Pruebe el agente con las siguientes indicaciones o pruebe las suyas propias.
Probar la operación GET
Mensaje: "Enumera todas las entradas de blog y represéntalas como una tabla".
Mensaje: "Enumera todas las entradas de blog del usuario con id. 1 y represéntalas como una tabla".
Probar la operación POST
Mensaje: "Cree una nueva entrada de blog con el ID de usuario 1, el título 'Nueva entrada' y el cuerpo 'Esta es una nueva entrada'".
Probar la operación PATCH
Mensaje: "Actualiza la entrada de blog con el ID 30 y actualiza el título a 'Título actualizado' y el cuerpo a 'Cuerpo actualizado'".
Probar la operación DELETE
Mensaje: "Eliminar la entrada de blog con el identificador 50".
Ejemplo de un archivo completo main.tsp
A continuación se muestra un ejemplo de un archivo completo main.tsp con , POSTGET, PATCH, y DELETE las operaciones agregadas.
import "@typespec/http";
import "@typespec/openapi3";
import "@microsoft/typespec-m365-copilot";
using TypeSpec.Http;
using TypeSpec.M365.Copilot.Actions;
using TypeSpec.M365.Copilot.Agents;
@agent(
"My Posts Agent",
"Declarative agent focusing on blog posts management."
)
@instructions("""
You should help users with blog posts management.
You can read, create, update and delete blog post items.
You can also search for blog posts by user ID.
""")
@conversationStarter(#{
title: "List Blog Posts",
text: "List all blog posts and render them as a table."
})
@conversationStarter(#{
title: "Lists a user's blog posts",
text: "List all blog posts for the user with ID 1 and render them as a table."
})
@conversationStarter(#{
title: "Delete a blog post",
text: "Delete the blog post with ID 50."
})
@conversationStarter(#{
title: "Update a blog post",
text: "Update the blog post with ID 30 and update the title to 'Updated Title' and body to 'Updated Body'."
})
@conversationStarter(#{
title: "Create a blog post",
text: "Create a new blog post with user ID 1, title 'New Post' and body 'This is a new post'."
})
@conversationStarter(#{
title: "Get a blog post",
text: "Get all the details about the blog post with ID 10."
})
namespace MyAgent {
@service
@server("https://jsonplaceholder.typicode.com")
@actions(#{
nameForHuman: "Posts APIs",
descriptionForHuman: "Manage blog post items on JSON Placeholder APIs.",
descriptionForModel: "Read, create, update and delete blog post items on the JSON Placeholder APIs."
})
namespace PostsAPI {
/**
* List all blog post items.
* @param userId The ID of the user who created the post. If not provided, all posts will be returned.
*/
@route("/posts")
@card(#{ dataPath: "$", file: "post-card.json", properties: #{ title: "$.title" } })
@get op listPosts(@query userId?: integer): PostItem[];
/**
* Get a blog post item by ID.
*/
@route("/posts/{id}")
@card(#{ dataPath: "$", file: "post-card.json", properties: #{ title: "$.title" } })
@get op getPost(@path id: integer): PostItem;
/**
* Create a new blog post item.
* @param post The post item to create.
*/
@route("/posts")
@post op createPost(@body post: PostItem): PostItem;
/**
* Updates a blog post item.
* @param id The ID of the post to update.
* @param post The updated post item.
*/
@route("/posts/{id}")
@patch op updatePost(@path id: integer, @body post: PostItem): PostItem;
/**
* Deletes a blog post item.
* @param id The ID of the post to delete.
*/
@route("/posts/{id}")
@delete op deletePost(@path id: integer): void;
model PostItem {
/**
* The ID of the user who created the post.
*/
userId: integer;
/**
* The ID of the post.
*/
@visibility(Lifecycle.Read)
id: integer;
/**
* The title of the post.
*/
title: string;
/**
* The body of the post.
*/
body: string;
}
}
}