用 Copilot CLI 推进个人网站重构
作者记录了通过十一次开发会话,使用 GitHub Copilot CLI 推进旧版 ASP.NET Core Razor Pages 网站现代化的过程。实践从 Plan 模式分析仓库与需求开始,探索让 Agent 直接调查和修改代码的完整项目协作方式。
AI 深度解读
一个已有的 ASP.NET Core Razor Pages 个人网站,经过 11 次开发会话,迁移到了 Astro。作者让 GitHub Copilot CLI 从调查仓库一路参与到实现、验证和部署,最终得到一个无需持续运行应用服务器的静态站点。
这份案例最有用的地方,是把 coding agent 放进完整项目后暴露的问题讲清楚了:AI 可以扩大技术选型范围,也会提前推进、误解设计、写出验证不到需求的测试。项目完成了,但作者没有据此宣称 AI 更快或更便宜。
为什么一次网站改版会从 .NET 转向 Astro
作者原本长期使用 .NET,按惯性很可能继续选择熟悉的技术栈。这次,他先让 Copilot CLI 在 Plan 模式下检查现有应用,再根据新需求评估方案:产品页面、持续增长的文章归档、英语和德语内容、响应式设计,以及简单的部署方式。
Copilot 推荐了作者没用过的 Astro。这个建议成立的关键,是网站唯一依赖服务端的功能只有联系表单。作者决定用工作邮箱和 LinkedIn 链接替代它,网站随之失去了保留后端的主要理由。
先删掉不再需要的服务端需求,静态架构才成为合理选择。
作者仍然可以保留 ASP.NET Core,也可以直接写 HTML。Astro 的吸引力在于,它能提供可复用的页面结构和 Markdown 内容组织,又不需要持续运行应用服务器。对一个文章会不断增加的网站,这比逐页维护 HTML 更符合作者的需要。
这里有个容易被忽略的先后关系:并不是 AI 推荐了 Astro,需求才被证明适合 Astro;而是作者重新审视联系表单,接受了功能上的取舍,才决定采用这个方案。Copilot 扩大了备选范围,最终选择仍由人完成。
让 agent 动手之前,先把需求和工作规则分开
选定架构后,Copilot 继续调查仓库和依赖,判断哪些可以复用、修改或移除。过程中,作者至少两次需要纠正方向:一次是调查尚未完成,Copilot 就开始推进实现规划;另一次是它打算删除并重建调查文档,而作者需要保留已有发现、继续更新。
这两件事都不严重,却说明审查不能只看最终方案。执行路径同样可能损失信息,或者跳过必要的调查。
作者把约束拆进两个文件:
docs/modernization/product-discovery.md记录网站要做成什么,包括产品需求。.github/copilot-instructions.md记录 Copilot 应当怎样工作,包括工程约定、验证要求和审批边界。
前者帮助判断功能是否做对,后者约束实现过程。规则也会随实际遇到的问题继续修订。
具体执行时,作者在 Plan、Interactive、Autopilot 三种模式之间切换:开放问题交给 Plan;还在熟悉 agent 行为时,用 Interactive 保持更多控制;范围明确、验收标准清楚的任务,再交给 Autopilot。后期会话还尝试了以 Claude Sonnet 作为底层模型,但原文没有比较模型表现。
允许 agent 编辑文件、运行检查,不等于把需求和验收权交给它。
设计迭代很能说明这一点。最初的报纸风格原型能够运行,却不符合作者希望呈现的产品型个人网站。

作者随后提供具体设计参考,并解释自己看重哪些特点,再继续调整导航、内容和视觉细节。相比反复追加抽象形容词,这给了 Copilot 更明确的方向。

不过,原文展示的是作者对设计方向的接受,没有提供用户测试或转化数据,不能据此认定后一个版本对所有访客都更有效。
页面能打开,距离可以上线还有多远
迁移包含共享布局、导航、内容组织、本地化、响应式样式、持久化主题偏好、法律页面和文章归档。作者按页面和功能逐步实现、逐项审查,而不是等整个网站生成完再一次验收。
部署阶段又多了一层检查:构建究竟会把什么发布出去?
Astro 在构建时生成静态 HTML、CSS、JavaScript 和其他资源,因此 GitHub Pages 与 Azure Static Web Apps 都是可选项。作者选择后者,部分原因是想探索这个平台,并没有证明它优于 GitHub Pages。
这里也要分清职责:GitHub 存放源码,GitHub Actions 执行验证和部署,生成的网站由 Azure 托管。使用 GitHub 管理项目,并不代表网站部署在 GitHub Pages。
仓库内容与公开产物也需要分别检查。旧 ASP.NET Core 文件保留过久,给 Copilot 增加了无关上下文;仓库里的说明、脚本、草稿等开发文件,则需要确认没有进入公开输出。原文没有报告这些文件已经泄露,而是强调发布前必须验证边界。
自动化检查覆盖了路由、链接、本地化和生成文件;布局与交互仍要通过浏览器审查。更关键的问题出现在最后的独立复核:作者先让 Copilot 对照需求和工程标准检查实现,又请 OpenAI Codex 单独做只读审查。
复核发现了一些值得调查的自动化验证、本地化和部署防护问题,没有确认严重的应用缺陷。但其中一个发现很有分量:部分测试虽然通过,却没有真正验证它声称覆盖的需求。作者再让 Copilot 修正问题、重跑验证,并请求再次独立审查。
检查通过,只能证明检查条件得到满足;检查条件本身也需要被审查。
作者还考虑过增加一个专门质疑假设的 rubber-duck agent,但最终优先处理已有具体发现,避免继续堆叠可能重叠的宽泛审查。
我的判断
这份案例最值得借鉴的是责任划分:AI 参与调查、实现和验证,人负责架构取舍、设计方向与最终验收。把需求文档、仓库规则、阶段性审查接起来,比单独讨论哪句提示词更有效,更接近实际项目的工作方式。
但它的适用前提很明确。站点能够静态化,依赖作者接受取消联系表单。一般团队如果必须保留服务端业务,就不能照搬这次选型。迁移到 Astro 也不是 AI 编程的必然结果,保留熟悉的 ASP.NET Core 同样可能合理。
独立审查带来了具体发现,这是有价值的证据;但原文没有给出完整测试样例、问题数量或不同审查方式的对照,不能继续推导成「多用一个模型就能保证质量」。比模型数量更值得关心的,是审查是否真的核对需求、实现与测试之间的关系。
成本结论也应保持克制。作者从 GitHub Copilot Pro 起步,中途多次提高预算,却没有提供金额、总工时或人工开发基线。11 次开发会话证明项目完成了,无法证明效率或费用更优。长会话里难以查找早期决策、比较多个 agent 输出,也说明终端工作流仍有管理成本。
能拿来做什么
- 改造内容型网站前,先列清真正需要服务端的功能,再决定是否采用静态架构。可以让 AI 提出备选方案,但要求每个建议对应具体需求和取舍。
- 把产品需求与 agent 工作规则分别保存。需求变更时更新前者,出现跳步调查、覆盖历史记录等问题时补充后者,让后续会话有明确依据。
- 把导航、本地化、主题偏好等拆成可独立验收的任务。涉及视觉方向时提供具体参考,并通过浏览器逐页检查,减少整站完成后才发现方向不对的返工。
- 上线前同时检查构建产物和测试的有效性。请独立审查者核对「测试到底验证了什么」,再处理具体发现、重跑验证,而不是只收集一份全绿结果。