【译】构建前先计划:带你了解 Visual Studio 中的 Plan Agent

📅 2026/7/31 10:28:10
【译】构建前先计划:带你了解 Visual Studio 中的 Plan Agent
【译】构建前先计划带你了解 Visual Studio 中的 Plan Agent在软件开发的世界里我们常常陷入“先写代码再想架构”的陷阱。这种“即兴编程”虽然看似高效但在大型项目中往往导致技术债务的积累、重构成本的飙升甚至项目失败。Visual Studio 作为微软的旗舰级 IDE在最新版本中引入了一个名为Plan Agent的强大工具旨在改变这一现状——它帮助开发者在编写一行代码之前先制定清晰、可执行的计划。本文将带你深入理解 Plan Agent 的核心概念并通过实战代码示例展示其如何重塑你的开发工作流。## 什么是 Plan AgentPlan Agent 是 Visual Studio 2022版本 17.8中集成的一个 AI 驱动的规划引擎。它利用大型语言模型LLM和代码分析技术在你开始编码之前自动生成一个结构化的实现计划。这个计划包括-架构草图数据流、模块依赖关系。-任务分解将复杂功能拆解为可独立实现的子任务。-边界条件输入验证、异常处理、性能约束。-测试策略建议的单元测试和集成测试用例。简而言之Plan Agent 就像是你的“编程向导”它强迫你先思考“如何做”再动手“做”。## Plan Agent 的核心工作流Plan Agent 的使用非常简单通常遵循以下步骤1.输入意图在 Visual Studio 的“AI 助手”面板或通过右键菜单中用自然语言描述你想实现的功能。2.生成计划Agent 分析你的项目上下文代码库、依赖、配置生成一份 Markdown 格式的计划文档。3.审阅与调整你可以直接编辑计划添加或删除任务或调整优先级。4.执行计划将计划中的每一步转换为代码Agent 可以自动生成代码骨架甚至完成完整的实现。## 实战演示构建一个简单的任务管理器为了更直观地感受 Plan Agent 的能力我们通过一个实际项目来演示。假设我们要在现有的 ASP.NET Core Web API 项目中添加一个“任务管理”模块支持创建、查看和删除任务。### 步骤 1输入意图在 Visual Studio 中打开你的项目在解决方案资源管理器中右键单击Controllers文件夹选择“AI 助手 → 生成计划”。在弹出的对话框中输入我想为任务管理添加一个 RESTful API支持- 创建任务POST /api/tasks- 获取所有任务GET /api/tasks- 删除任务DELETE /api/tasks/{id}任务模型包含 Id, Title, Description, IsCompleted, CreatedAt 字段。使用 Entity Framework Core 存储到 SQLite 数据库。### 步骤 2Agent 生成的计划几秒钟后Plan Agent 返回了如下计划简化版## 计划任务管理 API### 阶段 1数据层- [ ] 创建 TaskItem 实体类含字段、数据注解- [ ] 创建 AppDbContext 并配置 DbSet- [ ] 执行 EF Core 迁移### 阶段 2服务层- [ ] 创建 ITaskService 接口- [ ] 实现 TaskService包含 CRUD 逻辑- [ ] 添加输入验证空标题、日期范围### 阶段 3控制器层- [ ] 创建 TasksController- [ ] 实现 POST、GET、DELETE 端点- [ ] 添加全局异常处理### 阶段 4测试- [ ] 编写单元测试使用 Moq 模拟服务层- [ ] 编写集成测试使用 TestContainers### 步骤 3审阅并执行我们可以直接批准这个计划。点击“开始执行”Agent 会逐个生成代码文件。下面是两个关键的代码示例。## 代码示例 1数据层与实体定义Agent 自动生成了Models/TaskItem.cs和Data/AppDbContext.cs。以下是带有注释的代码csharp// Models/TaskItem.csusing System.ComponentModel.DataAnnotations;namespace TaskManager.Models{ /// summary /// 任务实体模型对应数据库中的 Tasks 表 /// /summary public class TaskItem { [Key] public int Id { get; set; } [Required(ErrorMessage 任务标题不能为空)] [StringLength(200, MinimumLength 1, ErrorMessage 标题长度必须在1-200字符之间)] public string Title { get; set; } string.Empty; [StringLength(2000, ErrorMessage 描述不能超过2000字符)] public string? Description { get; set; } /// summary /// 任务是否已完成默认为 false /// /summary public bool IsCompleted { get; set; } false; /// summary /// 创建时间由数据库自动生成 /// /summary [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreatedAt { get; set; } DateTime.UtcNow; }}csharp// Data/AppDbContext.csusing Microsoft.EntityFrameworkCore;using TaskManager.Models;namespace TaskManager.Data{ public class AppDbContext : DbContext { public AppDbContext(DbContextOptionsAppDbContext options) : base(options) { } /// summary /// 任务集合映射到 Tasks 表 /// /summary public DbSetTaskItem Tasks { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置实体与表名的映射 modelBuilder.EntityTaskItem(entity { entity.ToTable(Tasks); entity.HasKey(e e.Id); entity.Property(e e.Title).IsRequired().HasMaxLength(200); entity.Property(e e.Description).HasMaxLength(2000); entity.Property(e e.CreatedAt).HasDefaultValueSql(GETUTCDATE()); }); } }}## 代码示例 2服务层与控制器实现接下来Agent 生成了业务逻辑和 API 端点。以下是Services/TaskService.cs和Controllers/TasksController.cs的关键部分csharp// Services/TaskService.csusing Microsoft.EntityFrameworkCore;using TaskManager.Data;using TaskManager.Models;namespace TaskManager.Services{ /// summary /// 任务服务封装所有与任务相关的业务逻辑 /// /summary public class TaskService : ITaskService { private readonly AppDbContext _context; public TaskService(AppDbContext context) { _context context; } /// summary /// 创建新任务 /// /summary public async TaskTaskItem CreateTaskAsync(TaskItem task) { // 验证标题不能为空由实体注解保证此处做二次检查 if (string.IsNullOrWhiteSpace(task.Title)) throw new ArgumentException(任务标题不能为空); // 设置初始状态 task.CreatedAt DateTime.UtcNow; task.IsCompleted false; // 保存到数据库 _context.Tasks.Add(task); await _context.SaveChangesAsync(); return task; } /// summary /// 获取所有任务按创建时间降序排列 /// /summary public async TaskListTaskItem GetAllTasksAsync() { return await _context.Tasks .OrderByDescending(t t.CreatedAt) .ToListAsync(); } /// summary /// 删除指定任务 /// /summary public async Taskbool DeleteTaskAsync(int id) { var task await _context.Tasks.FindAsync(id); if (task null) return false; // 任务不存在 _context.Tasks.Remove(task); await _context.SaveChangesAsync(); return true; } }}csharp// Controllers/TasksController.csusing Microsoft.AspNetCore.Mvc;using TaskManager.Models;using TaskManager.Services;namespace TaskManager.Controllers{ [ApiController] [Route(api/[controller])] public class TasksController : ControllerBase { private readonly ITaskService _taskService; public TasksController(ITaskService taskService) { _taskService taskService; } /// summary /// POST /api/tasks - 创建新任务 /// /summary [HttpPost] public async TaskActionResultTaskItem CreateTask([FromBody] TaskItem task) { try { var createdTask await _taskService.CreateTaskAsync(task); // 返回 201 Created 状态码并附带新创建的资源位置 return CreatedAtAction(nameof(GetAllTasks), new { id createdTask.Id }, createdTask); } catch (ArgumentException ex) { return BadRequest(new { error ex.Message }); } } /// summary /// GET /api/tasks - 获取所有任务 /// /summary [HttpGet] public async TaskActionResultListTaskItem GetAllTasks() { var tasks await _taskService.GetAllTasksAsync(); return Ok(tasks); } /// summary /// DELETE /api/tasks/{id} - 删除指定任务 /// /summary [HttpDelete({id})] public async TaskActionResult DeleteTask(int id) { var deleted await _taskService.DeleteTaskAsync(id); if (!deleted) return NotFound(new { error $任务 ID {id} 不存在 }); return NoContent(); // 204 No Content 表示删除成功 } }}## Plan Agent 的进阶用法除了生成基础代码Plan Agent 还能处理更复杂的场景。例如-重构计划当你需要重构一个庞大类时Agent 会分析代码耦合度生成“提取接口”、“拆分模块”的分步计划。-性能优化输入“优化此查询的性能”Agent 会建议添加索引、使用延迟加载或缓存策略。-安全审计输入“检查此端点是否存在 SQL 注入风险”Agent 会扫描参数绑定并生成修复计划。## 总结Visual Studio 的 Plan Agent 不仅仅是一个代码生成器它更是一种“计划驱动开发”方法论的具体工具。通过强制开发者在编码前先制定计划它减少了返工、提高了代码一致性并让团队协作更加透明。从实战角度看Plan Agent 能够1.加速原型开发从自然语言到可运行代码只需几分钟。2.减少错误自动处理边界条件和异常。3.促进文档化生成的计划本身就是一份清晰的开发文档。然而它并非万能。Agent 生成的计划需要人工审阅尤其是涉及复杂业务逻辑或特定领域规则时。但作为起点它无疑大幅降低了“从零开始”的认知负荷。下次当你面对一个新功能时不妨先打开 Plan Agent让它帮你画出蓝图——毕竟好的建筑始于好的设计好的代码始于好的计划。