你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本教程介绍如何通过 OpenAPI 公开 ASP.NET Core 应用的功能,将其作为工具添加到 Foundry 代理服务,并在代理场中使用自然语言与应用交互。
如果 Web 应用程序已有有用的功能(如购物、酒店预订或数据管理),则可以轻松地在 Foundry 代理服务中向 AI 代理提供这些功能。 只需将 OpenAPI 架构添加到应用,即可在代理响应用户的提示时了解和使用应用的功能。 这意味着你的应用可以执行的任何作,AI 代理也可以执行,除了为应用创建 OpenAPI 终结点之外,也只需付出最少的努力。 本教程从简单的 to-do 列表应用开始。 最后,你将能够通过对话式 AI 通过代理创建、更新和管理任务。
- 将 OpenAPI 功能添加到 Web 应用。
- 确保 OpenAPI 架构与 Foundry 代理服务兼容。
- 在 Foundry 代理服务中将应用注册为 OpenAPI 工具。
- 在智能体操场中测试智能体。
先决条件
本教程假定你使用的是教程中使用的示例 :将 ASP.NET Core 和 Azure SQL 数据库应用部署到 Azure 应用服务。
至少,在 GitHub Codespaces 中打开 示例应用程序 ,并通过运行 azd up来部署应用。
将 OpenAPI 功能添加到 Web 应用
小窍门
可以通过在代理模式下告诉 GitHub Copilot 进行以下所有更改:
I'd like to add OpenAPI functionality to all the methods in Controllers/TodosController.cs, but I don't want to change the existing functionality with MVC. Please also generate the server URL and operation ID in the schema.
在 codespace 终端中,将 NuGet Swashbuckle 包添加到项目:
dotnet add package Swashbuckle.AspNetCore --version 6.5.0 dotnet add package Swashbuckle.AspNetCore.Annotations --version 6.5.0在 Controllers/TodosController.cs中,添加以下 API 方法。 若要使其与 Foundry 代理服务兼容,必须在属性中
OperationId指定SwaggerOperation属性(请参阅如何将 Foundry 代理服务与 OpenAPI 指定工具:先决条件配合使用)。// GET: api/todos [HttpGet("api/todos")] [SwaggerOperation(Summary = "Gets all Todo items", OperationId = "GetTodos")] [ProducesResponseType(typeof(IEnumerable<Todo>), 200)] public async Task<ActionResult<IEnumerable<Todo>>> GetTodos() { return await _context.Todo.ToListAsync(); } // GET: api/todos/5 [HttpGet("api/todos/{id}")] [SwaggerOperation(Summary = "Gets a Todo item by ID", OperationId = "GetTodoById")] [ProducesResponseType(typeof(Todo), 200)] [ProducesResponseType(404)] public async Task<ActionResult<Todo>> GetTodo(int id) { var todo = await _context.Todo.FindAsync(id); if (todo == null) { return NotFound(); } return todo; } // POST: api/todos [HttpPost("api/todos")] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [SwaggerOperation(Summary = "Creates a new todo item.", Description = "Creates a new todo item and returns it.", OperationId = "CreateTodo")] public async Task<IActionResult> CreateTodo([FromBody] Todo todo) { if (!ModelState.IsValid) { return BadRequest(ModelState); } _context.Add(todo); await _context.SaveChangesAsync(); return CreatedAtAction(nameof(GetTodo), new { id = todo.ID }, todo); } // PUT: api/todos/{id} [HttpPut("api/todos/{id}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [SwaggerOperation(Summary = "Updates a todo item.", Description = "Updates an existing todo item by ID.", OperationId = "UpdateTodo")] public async Task<IActionResult> UpdateTodo(int id, [FromBody] Todo todo) { // Use the id from the URL fragment only, ignore mismatching check if (!TodoExists(id)) { return NotFound(); } todo.ID = id; _context.Entry(todo).State = EntityState.Modified; await _context.SaveChangesAsync(); return NoContent(); } // DELETE: api/todos/{id} [HttpDelete("api/todos/{id}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] [SwaggerOperation(Summary = "Deletes a todo item.", Description = "Deletes a todo item by ID.", OperationId = "DeleteTodo")] public async Task<IActionResult> DeleteTodo(int id) { var todo = await _context.Todo.FindAsync(id); if (todo == null) { return NotFound(); } _context.Todo.Remove(todo); await _context.SaveChangesAsync(); return NoContent(); }在 Controllers/TodosController.cs 顶部,添加以下 using 指令:
using Microsoft.AspNetCore.Http; using Swashbuckle.AspNetCore.Annotations;此代码复制了现有控制器的功能,这是不必要的,但为了简单起见,你将保留它。 最佳实践是将应用程序逻辑移动到服务类中,然后从 MVC动作和 API 方法中调用这些服务方法。
在 Program.cs中,注册 Swagger 生成器服务。 这将为 API 启用 OpenAPI 文档,这使 Foundry 代理服务能够了解 API。 请务必指定服务器 URL。 Foundry 代理服务需要包含服务器 URL 的架构。
builder.Services.AddSwaggerGen(c => { c.EnableAnnotations(); var websiteHostname = Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME"); if (!string.IsNullOrEmpty(websiteHostname)) { c.AddServer(new Microsoft.OpenApi.Models.OpenApiServer { Url = $"https://{websiteHostname}" }); } });在 Program.cs中,启用 Swagger 中间件。 此中间件在运行时提供生成的 OpenAPI 文档,使其可通过浏览器访问。
app.UseSwagger(); app.UseSwaggerUI();在 codespace 终端中,使用
dotnet run.. 运行应用程序。选择“在浏览器中打开”。
通过将
/swagger/index.html添加到 URL 导航到 Swagger UI。通过在 Swagger UI 中试用 API 操作,确认 API 操作是否正常工作。
返回 codespace 终端,通过提交更改(GitHub Actions 方法)或运行
azd up(Azure 开发人员 CLI 方法)来部署更改。部署更改后,导航到
https://<your-app's-url>/swagger/v1/swagger.json并复制架构以供以后使用。
在 Microsoft Foundry 中创建代理
按照以下步骤在 Foundry 门户中创建代理 :快速入门:创建新代理。
请注意 可以使用的模型和可用的区域。
按照《如何使用 OpenAPI 规范工具》的步骤,选择新代理并使用 OpenAPI 3.0 指定的工具添加一个动作。
在 “定义架构 ”页中,粘贴之前复制的架构。 检查并保存操作。
小窍门
在本教程中,OpenAPI 工具配置为在不进行身份验证的情况下匿名调用应用。 对于生产方案,应使用托管标识身份验证保护该工具。 有关分步说明,请参阅 为 Foundry Agent Service 配置安全的 OpenAPI 终结点。
测试代理
如果代理测试区还没有在 Foundry 门户中打开,请选择代理,然后选择在测试区试用。
在 “说明”中,提供一些简单的说明,例如 “请使用 todosApp 工具来帮助管理任务”。
使用以下提示语与智能助手聊天:
- 向我显示所有任务。
- 创建一个名为“拿出三个生菜笑话”的任务。
- 将其改为“想出三个敲门笑话。”
安全最佳做法
在 Azure 应用服务中通过 OpenAPI 公开 API 时,请遵循以下安全最佳做法:
- 身份验证和授权:使用 Microsoft Entra 身份验证保护 OpenAPI 终结点。 有关分步说明,请参阅 Foundry 代理服务的安全 OpenAPI 端点。 还可以 使用 Microsoft Entra ID 保护 Azure API 管理 背后的终结点,并确保只有经过授权的用户或代理才能访问这些工具。
-
验证输入数据:示例代码在方法中
ModelState.IsValid检查CreateTodo,这可确保传入的数据与模型的验证属性匹配。 有关详细信息,请参阅 ASP.NET Core 中的模型验证。 - 使用 HTTPS: 此示例依赖于 Azure 应用服务,该服务默认强制实施 HTTPS,并提供免费的 TLS/SSL 证书来加密传输中的数据。
- 限制 CORS: 仅将跨域资源共享(CORS)限制为受信任的域。 有关详细信息,请参阅 “启用 CORS”。
- 应用速率限制: 使用 API 管理 或自定义中间件防止滥用和拒绝服务攻击。
- 隐藏敏感终结点: 避免在 OpenAPI 架构中公开内部或管理员 API。
- 查看 OpenAPI 架构: 确保 OpenAPI 架构不会泄露敏感信息(例如内部 URL、机密或实现详细信息)。
- 保持依赖项更新: 定期更新 NuGet 包并监视安全公告。
- 监视和记录活动: 启用日志记录和监视访问以检测可疑活动。
- 使用托管标识: 调用其他 Azure 服务时,请使用托管标识而不是硬编码凭据。
有关详细信息,请参阅 保护应用服务应用 和 REST API 安全性的最佳做法。
后续步骤
现在,你已启用应用服务应用,使其可以作为 Foundry 代理服务的工具,并在代理沙盒中通过自然语言与应用的 API 进行交互。 在这里,可以在 Foundry 门户中继续将功能添加到代理,使用 Microsoft Foundry SDK 或 REST API 将其集成到自己的应用程序中,或将其部署为更大的解决方案的一部分。 在 Microsoft Foundry 中创建的代理可以在云中运行、集成到聊天机器人中或嵌入在 Web 和移动应用中。
若要执行下一步,了解如何直接在 Azure 应用服务中运行代理,请参阅以下教程: