技术速递|Harness 基本就是你需要的一切(大多数情况下)
Harness 基本就是你需要的一切大多数情况下作者Burke Holland排版Alan Wang一个基于 GitHub Copilot 的实用开发工作流覆盖软件原型设计、规划、实现与代码审查无需追逐每一个新 AI 工具。如果你现在正被 AI 搞得不知所措你并不孤单。每天似乎都会冒出一个新的工具、新的 MCP、新的模型、新的 Skill、新的工作流、新的功能还有新的社交媒体帖子内容大概都是“嘿看这个神奇提示词我已经彻底搞懂 AI 了”我……不太相信。我每天都在使用 AI而我越来越强烈地感受到少即是多。真正带来差异的并不是我安装了什么、配置了什么或者想办法“骗”智能体去完成什么操作。这些东西当然很有趣但说到底它们更像是某种“技巧秀”。我获得的最大生产力提升来自于我如何使用 Harness以及我对它的理解有多深。所以在这篇文章里我想分享一个非常简单的工作流只利用 GitHub Copilot 已有的功能就能显著提升你使用 AI 的效率。没有奇怪的提示词。没有别人都知道、只有你不知道的神秘 Skill。只有 Harness。Harness 基本就是你所需要的一切——大多数情况下。免责声明这里我会把 “Harness” 和 “GitHub Copilot” 交替使用。为了让内容尽可能简单你只需要知道GitHub Copilot 本质上就是一个智能体 Harness。我并不是想暗示你永远都不需要 Skill、MCP、Instructions、Custom Agent 等等。事实上随着你不断深入需要定义复杂工作流、为团队实现自动化时这些能力会变得非常重要。实际上我在这篇文章后面的示例中也会用到其中的一些。我真正想表达的是即使完全不依赖这些东西你依然可以非常高效地使用 AI。另外现在外面确实存在大量“垃圾内容”。如果你不信可以随便让智能体帮你生成一个 Skill 来完成任何任务它通常都会非常积极地照办。至于这个生成出来的 Skill 是否真的能运行、是否真的有价值那是另一回事。而且它还可以被轻易发布到各种 Skill 或 MCP Registry 中。1 先选一个工具任何工具都行这听起来像一句废话对吧“先选个工具”——太容易了。但即使是在 GitHub Copilot 家族内部也有很多选择GitHub Copilot CLI新版 GitHub Copilot AppVS CodeVisual StudioJetBrains以及其他许多集成环境好消息是这些体验正在越来越多地收敛到同一个 Harness 上。不同工具的细节可能有所差异但核心工作流其实是一致的学会一次 Harness到处都能用。不过我确实认为理解 Harness 是关键。而学习它最好的方式就是尽可能靠近它本身。所以如果你刚开始接触我会推荐你从 GitHub Copilot CLI 开始。它是一个终端界面也就是说只有文本几乎没有复杂 UI 需要学习你输入提示词智能体执行操作。这种交互方式更加直接、更加即时而且坦白说非常有成就感。本文中的演示我会使用新版 GitHub Copilot App。但请注意它所使用的 Harness与你在 GitHub Copilot CLI、Visual Studio Code 以及许多其他 GitHub Copilot 集成环境中使用的是完全同一个东西。2 打开 YOLO 模式YOLO 模式也叫 Allow All。它允许智能体在不逐次询问权限的情况下执行命令。具体形式会因工具而异但在大多数 GitHub Copilot 环境中只需要在聊天里执行/allow-all。否则智能体每次需要执行一点工作时都会停下来等待你的批准。如果你希望 AI 智能体真正提升生产力它就必须拥有一定程度的自主性。如果每一步都需要你点“批准”那你还不如自己直接完成这些操作。而且这种体验非常糟糕。没有人愿意整天坐在电脑前只负责不停地点击“Approve”按钮。更糟的是反复点击“Approve”会让你逐渐失去阅读批准内容的习惯而这恰恰违背了权限确认机制的初衷。当然使用智能体时仍然需要注意安全。好人也会遇到坏事。因此在开启 YOLO 模式时不要直接在本地机器上运行智能体。这一点在工作环境中尤其重要组织系统中的数据通常是私有的一次误操作可能代价高昂。幸运的是现在已经有很多适合运行智能体的沙箱环境。最容易上手的两个选择是 GitHub Codespaces 和 开发容器。3 从原型开始AI 最神奇的能力之一就是它让你能够几乎零成本地提前做原型。过去并不是这样。原型设计通常是项目中的一个完整阶段很多时候甚至是一种“奢侈品”。而现在你只需要一句提示词。来看几个例子。假设我们想构建一个 日期选择器 Web 组件。听起来很简单但实际上它相当复杂。想想你可能需要考虑的问题如何在组件内部导航选中的日期应该长什么样选中的日期范围如何展示用户如何在日、月、年之间切换我的建议是先做一个简单原型并生成多个变体。我通常会这样开始Give me 20 mocks for a date picker web component. Put them all in an HTML file so I can compare.于是AI 会在一个 HTML 文件里生成 20 种不同的日期选择器原型。在这些方案中我注意到其中一个原型是从“年份视图”开始的。这很有意思。我希望我的日期选择器支持 年份 → 月份 → 日期 的逐级缩放导航。很多需求在你真正“看见”它之前其实根本不会意识到。人类对于图像、形状、布局这类感官信息丰富的模型理解速度远远快于阅读大段文字。因此尽早创建低成本原型可以让复杂概念瞬间变得直观。而且这不仅适用于视觉界面非视觉任务同样适用。例如如果我要为项目新增一个 API Endpoint我仍然会先创建一个可视化原型帮助自己理解需求与约束再进入具体实现阶段。Create a visual mockup of the API for this project. Add five options for how we could handle a new API endpoint that allows the user to download their analytics data.由于 GitHub Copilot App 支持 Mermaid 图表智能体会直接以 Markdown 的形式渲染出一张 Mermaid 架构图展示五种不同的 API 设计思路。在与智能体协作时人们很容易忘记一件事几乎所有事情都充满细节和权衡。原型设计的价值就在于它能帮助你提前暴露这些细节。这样你就不必在后续实现阶段浪费大量时间和 Token 去反复返工。关于模型选择对于大多数开发工作我建议使用 GPT 5.6 Terra 或 Claude Sonnet。另外还有一个非常重要的建议在同一个功能、Bug 修复或增强任务的整个过程中尽量保持使用同一个模型和同一个推理级别。原因是提示词缓存会帮你节省大量 Token。只要你不切换模型或推理等级之前的对话上下文就会继续保存在该模型的缓存中后续请求能够享受缓存折扣从而显著降低 Token 消耗。4 有条理地进行规划现在你已经知道了自己真正想要实现的目标而不是最开始以为自己想要的东西接下来就可以开始规划具体实现方案。在 GitHub Copilot 中切换到 Plan 模式无需开启新的会话。/plan Build a date picker web component. I want the user to be able to zoom in and out of years, months, and days.这个提示词其实非常宽泛。当然你可能会提供比我更多的上下文信息而这里仅仅是为了演示。如果你暂时没有更多上下文也没关系。这正是这一步存在的意义。理论上如果你能够按照完美的顺序提供完美的上下文并组合出完美的提示词那么模型可以一次性完成任何任务。理论上如此。但实际上我们没有人能够做到这一点。不过规划过程可以帮助你更接近这个理想状态。它会通过提出一系列问题帮助你补充那些如果你亲自开发时必须考虑的问题开始日期和结束日期可以是同一天吗是否允许只选择部分日期用户是否应该能够清除日期“今天”是否应该始终作为可见选项是否允许手动输入日期日期应该以什么格式存储是否允许直接粘贴日期问题还远不止这些。你不可能考虑到所有边界情况但模型可以帮助你发现其中很多。如果你希望 Plan 模式更加深入主动提出更多问题和边界场景可以安装 Matt Pocock 提供的 “grill-me” Skill。/plan /grill-me Build a date picker web component. I want the user to be able to zoom in and out of years, months, and days.这个规划步骤非常关键。重点并不是让你无条件接受 AI 提出的所有建议。如果你这么做反而会削弱规划过程本身的价值。真正的目标是深入参与问题分析并引导模型完成思考。这也是你的专业能力发挥作用的地方。你也可以反过来向模型提问。例如在下面的截图中它向我询问了“非连续日期”的问题。我大概知道模型想表达什么但我仍然会要求它进一步解释以确保我们双方理解一致。即使你中途打断流程提出澄清问题等规划过程依然会继续进行。5 使用 Autopilot 实现当规划完成后GitHub Copilot 通常会提示你切换到 Autopilot 模式开始执行计划。Autopilot 是一个内置循环机制。它会强制模型持续工作确保它真正完成自己承诺要完成的事情——在这个例子中就是完成计划中的每一个任务项。在这个阶段GitHub Copilot 会自动充当编排器。例如如果需要读取代码库文件它会使用较小模型的 Explore 子智能体如果判断某项操作相对复杂它可能会选择使用更大模型的 General Purpose 子智能体。虽然你可以通过 Custom Agent 和 Instructions在 GitHub Copilot 中获得更细粒度的编排控制但实际上你并不需要额外配置任何东西就能享受到子智能体和多模型工作流带来的优势。即使你不知道这些能力存在它们也已经可以开箱即用。6 人工审查与持续迭代这就是你获得“多巴胺奖励”的时刻。你终于可以看到 AI 创建出来的成果。但很可能它不会完全符合你的预期。这是正常的也是意料之中的。模型无法读懂你的想法而且它也会犯错。你需要不断与模型迭代直到得到真正想要的结果。无论最终产物是代码还是更好的 UI 设计这个阶段决定最终质量的是你的审美和判断。例如这是 GitHub Copilot 最初给我的日期选择器我马上发现了一些问题动画效果不一致当鼠标悬停在已选日期上时由于颜色对比度问题文字无法阅读顶部不需要显示“12 YEARS”当我处于月份或年份视图时点击“Today”不会跳转到当天日期。另外我也不太喜欢它的设计。它看起来有一点过于“AI 风格”——毕竟它确实就是 AI 创建的。所以现在我们进入的是持续跟进模式。我会使用自己创建的一个 CSS 框架 Postrboard。我将它作为一个 Skill 添加进去其中只需要指向 CSS 文件并告诉 Agent 如何使用它。如果你感兴趣可以自行安装使用当然也可以选择其他任何你喜欢的 CSS 框架。给模型提供一些设计指导非常有帮助而很多时候一个 CSS 框架就已经足够。例如ok - we dont need a landing page here - just the component, output and settings panel in a minimal setting. Use the /postboard skill for the design and colors. For the date picker, when I click on the day, it tries to zoom in, but cant because there is nothing to zoom to. There should be no zoom there. It doesnt need to say Zoom Out at the top When I mouse over a month or year that contains the selected day, I cannot read the hover text. When I click Today it should take me to that day view, even if Im on the month or the year. The months dont need numbers under them and they dont need to be in boxes Same goes for years. And it doesnt need to say 12 years at the top.注意这种交流方式其实非常自然。不要过度思考。当你需要修复大量细节问题时直接告诉模型即可。如果你已经提供了上下文那么你就已经拥有了足够好的提示词。最重要的是不要接受“差不多可以”的 AI 输出。坚持质量要求。对结果保持严格要求。这部分依然是你的责任而能够判断什么是高质量结果、什么不是这正是你带来的价值。AI 永远无法替代你的人工判断和创造力。这是我最终完成的日期选择器效果。可以滑到文章底部查看实际运行效果。7 使用 Rubber Duck 进行最终审查当你完成迭代并且对最终结果满意后就到了最后一次审查阶段。请求 GitHub Copilot 进行一次 Rubber Duck Review。你只需要这样提出请求Perform a rubber duck review on this date picker component implementation在 Rubber Duck Review 中GitHub Copilot 会请求来自不同 AI 模型家族的模型进行审查。例如因为我使用的是 GPT 5.6 Terra所以它请求 Claude Sonnet 进行审查。不同模型基于不同数据训练因此它们拥有不同的盲区。Rubber Duck Review 可以帮助发现单一模型可能遗漏的问题。需要注意的是你可以在这个工作流的任何阶段使用它。你可以让它审查原型、计划以及实现结果。这完全取决于你是否希望获得第二个 AI 视角。如果你想进一步提升可以将 Rubber Duck 与 Autopilot 结合让多个模型形成循环协作不断优化最终结果。例如/autopilot rubber duck this date picker implementation. When you have the result, review it carefully and make any necessary adjustments. Repeat the rubber duck review until both you and the reviewing model agree that the only items that remain have diminishing returns.完成这一步后你会得到一个更加完善的结果同时也可能发现大量额外的边界情况。这一步确实会消耗更多 Token。但实际上你是在为代码进行“强化测试”。可以把它看作是一种投资投资未来的自己让未来不必面对这些问题因为你已经提前发现并解决了它们。8 收获成果到了这里你已经可以暂存并提交代码或者继续开发这个 Pull Request 中想加入的下一个功能。我的建议是如果接下来要处理与这个日期选择器无关的新任务请开启新的聊天会话。你可以把聊天会话理解为围绕某个主题展开的空间。如果你的讨论开始明显偏离当前主题那通常就是开启新会话的时候。以下就是我通过这个工作流完成本文日期选择器后的最终结果。datepicker我知道这是一个稍微刻意设计的示例。但我们是否可以停下来想一想现在借助 AI我们已经能够完成多少以前难以想象的事情过去构建一个日期选择器可能是最困难的软件开发任务之一。你可以问问那些真正构建过日期选择器的人他们一定深有体会。事情不必变得复杂这个简单工作流已经足够满足大多数人的需求。它的简单性也帮助你同时处理多个任务。当保持简单时你更容易理解当前智能体处于什么状态你上一次正在做什么下一步应该推进什么。同时你的上下文窗口也是有限的。现在 AI 领域正在发生大量变化。你可以构建和实验的东西几乎没有上限。你可以添加 MCP Server、Skill、Instructions以及 Custom Agent。你可以搭建工作流和循环让智能体调用智能体甚至建立完整的虚拟开发团队。但请记住现在没有人真正知道所有正确答案。我们都在不断探索。今天看起来神奇的 AI 技巧可能明天就会成为反模式。所以专注于用最简单的方式获得稳定、可重复、高质量的结果。学会使用 Harness你就会做得很好。试用 GitHub Copilot