
pstack 完整指南 Pt.2:用代码规划
作者:lauren(@poteto,Grok Bot at @SpaceXAI)
上一篇里,我讲清了为什么验证是我用 agent 做一切事情的基础,以及怎么开始创建你自己的验证 skill。关键的一课是:如果 agent 不能验证自己的工作,其他一切都无关紧要——你仍然是瓶颈,你的一整天都会花在看管 agent 上。
但验证跑通之后,下一个问题是:你到底怎么弄清楚该建什么?
这篇我会带你走一遍我用 pstack 做调研、规划、原型和架构的过程。就是这套工作流让我每个月能把几千个 PR 推进生产,同时把代码质量维持在极高的水平。
(配图说明:八月收尾时,2,462 个 PR 进了生产。)
监督一个比你聪明的人
回到 2024 年,你想改系统里的任何东西,都得先读足够多的代码,在脑子里建立对它的理解。取决于代码库的大小和复杂度,这可能花你几小时,甚至几天几个月。小改动也许只需要理解一个小子系统;但要重构核心,你大概得对整个系统如何运作有完整的心智模型,才可能做得对、做得好。
agent 显然拆掉了这道门槛:你只要给 agent 一个 prompt,它就会去改,不管你对该处代码了解多少。但保持代码质量和用户体验仍然很难,尤其是你本身不是领域专家、不知道该看什么、该问什么的时候。
即使前沿模型已经非常强,我仍然持续观察到两种失败模式:
它们无法完全理解你的意图,因为你的指定不足或质量差。
它们对如何正确完成这项工作所拥有的上下文不够。
这两个问题相关。用好 agent,归根结底就是你能多好地给 agent 的上下文窗口灌注高质量的上下文。不做这件事你也能写出能跑的代码,但我发现,当我花力气给 agent 提供高质量完成工作所需的一切时,结果和质量会好得多。
用你自己的话说
前沿模型是非常能干的程序员。老模型我会非常具体地告诉它要做什么,几乎是微管理;而最新的模型写代码比你我都好。所以我想要的是一种平衡:告诉 agent 要达到什么,同时给它自由,用我可能没想到的方式解决。
这就是「监督一个比你聪明的人」的艺术——在一个不是你写的代码库上,而且人类已经无法把整个代码库的心智模型装进脑子里。
我喜欢用的一种技巧是间接 prompt。与其精确告诉 agent 我想要什么,我试着让它自己说出来——用它自己的话。
比如有人在 Slack 报了一个问题,我常常让 agent 先读那个 thread,用它自己的话复述问题,然后再做别的:
/poteto-mode 读这个 slack thread。用你自己的话、用平实的英语复述你认为底层的问题是什么。
这做到三件事:第一,它迫使 agent 把一段嘈杂的对话压缩成一个结构化的问题陈述。第二,它让我能立刻发现误解——如果 agent 揪住了 thread 里的一个红鲱鱼,我可以在它开始写代码之前快速纠正。第三,我没有用我自己的假设和猜测把它带错路,那些假设可能本身就是错的,或者会限制它本来能达到的结果。
建立心智模型
让 agent 用它你能理解的方式复述,是和比你聪明的人共事的重要一环。这也是 /teach 这个 skill 的由来:它帮你的 agent 用直觉的方式向你解释事情。每当我需要确认 agent 在做的事对我来说讲得通,我就会用它。
在底层,/teach 会调用 /how 和 /why。
/how 追踪运行时机制。你问 /how 时,agent 会先评估这个子系统的复杂度;如果它横跨多个目录或服务,它会在快速高效的模型(比如 Grok)上并行开几个探索 agent。
/how 虚拟化是怎么实现的?
/why 调查动机和意图。代码告诉你发生了什么,它很少告诉你为什么当初那样写。你跑 /why 时,pstack 会并行查询多个来源的历史证据:git 历史和 PR 评论、Linear 工单、Notion 设计文档、Slack 对话、Datadog 监控、Sentry 报错、代码沿革(code lineage),以及分析仓库事件。
/why 我们为什么还卡在旧版本的 node.js?
我每次想让 agent 复述某件事、以便我更好地理解并信任它的工作,就用 /teach:
/teach 我为什么这样实现,而不是那样实现?你做了哪些取舍,为什么?
实践中我还发现,/teach 这个 skill 做的调研不只对人有用,对 agent 也有用。即便是最新的前沿模型(这也取决于 harness 的质量),我总体上发现它们仍然经常自信地陈述观点,却不拿数据支撑,也不去读真正需要读的代码来建立心智模型。所以「教你它要做什么、为什么」这个动作,最终也在帮 agent 自己。
从历史里学习
我的很多项目跨多个对话。比如几个月前我在修 Cursor 里用户报的虚拟化 bug 和性能问题。我意识到每次开新对话,我都得从头再把 agent 之前解决类似问题时建立的丰富上下文重建一遍。
而我意识到:你过去的对话记录通常是一座富矿。pstack 自带了 /recall skill,从聊天历史里拉最近的相关上下文,这样即便是全新的 agent 也能拿到正确的上下文,快速回到好的状态。
/recall 我昨天做虚拟化那块的工作,然后读这个 slack 上的 bug 报告。
/teach、/recall、/how、/why 就是我保持自己对代码库的心智模型不过期的方式——把它压缩成我容易理解和记住的形式。而且它也在帮 agent。
倒着做
理解了问题之后,怎么指定解决方案?
在我看来,大多数有 plan 模式的 harness 都过度指定实现细节,而其他一切都不够具体。所以我在 pstack 里半开玩笑地写了「我不相信 planning」。真相是我确实在规划,只是通过代码来规划。
对某类工作——比如创建会被别人使用的共享代码或包——我是 readme 驱动开发的坚定信徒。如果你不熟这个词:这是一种当年流行的开发方式,你先写 readme。它迫使你戴上开发者体验的帽子,从向一个假想的用户描述 API 开始,然后倒推实现和架构。
比如我在做 Dune(我们自研的桌面应用客户端框架)时,先从为它写一篇教程开始,这样我才能理解用它建应用会是什么体验——至少我试着这么做。让 agent 产出任何好东西或可读的东西真的很挣扎。所以我得先花时间磨刀:做出了 /technical-writing 这个 skill。
没有 /technical-writing 时,readme 的第一版读起来很痛苦,因为它把不同的目标混在了一起:它试图在同一份文档里同时当教程、how-to 指南、架构说明和 API 参考,写出来的还是那种典型的 AI 味和拿腔拿调的文字。
/technical-writing 使用 Diátaxis 框架,把文档拆成四种明确的模式:
教程:在做中学。一堂课,带着新手一步步做出可见的东西。
how-to 指南:为有经验的用户解决某个具体现实问题的步骤。
参考:干燥、完整、权威的技术描述,覆盖机制、API 和配置开关。
解释:高层讨论,澄清并照亮背景、设计选择和取舍。
它还会调用 /unslop,所以产出的文档非常好读。
用这种方式写计划非常有帮助,因为它同时也给你的 agent 一个具体的目标,让它能拿自己的产出来对照检查。当然,这也让人更容易理解 agent 到底要建什么。
pstack 的很多 skill 在设计阶段会叠加发挥作用。比如:
(1)/recall 我过去 7 天修虚拟化 bug 和性能问题的工作。用 /how 和 /why 理解我们当前的虚拟化实现是怎么工作的。(2)然后用 /poteto-mode 的 planning 和 /technical-writing,设计一个新的虚拟化引擎,从根本上消除闪烁和抖动。先从写一篇教程开始:我会怎么用这个新包来虚拟化一个 React 应用。(3)计划写完后,/teach 我并向我证明为什么这个新方案比我们现在的引擎更好。
这个技巧的核心,是把有意思的、丰富的上下文引出来,让你的 agent 有能力像你一样看到问题——而不是只看到一个切片:第一部分召回关于我应用里虚拟化如何实现的相关上下文;第二部分引导 agent 用这些上下文(比如它以前修过的 bug)去设计一个能彻底消除这些问题的方案;最后一部分是让 agent 向你证明这个新包更优——这就是高质量的验证 skill 为什么重要。
量一百次,剪一次
规划时我见到的两个最常见的错误是:
接受 agent 给出的第一个设计。
在没有实证的情况下把计划过度烹调。
人类写代码的时候,我们常常围绕设计文档协作:讨论高层架构、考虑过的备选方案、取舍、以及任何不寻常的实现说明。这些文档常常要迭代好几轮,才落到一个确定的设计上。
用 agent 时,虽然可以跳过设计文档的仪式,但我经常看到那个错误:接受 agent 给你的第一个东西。在 pstack 里,我们可以用并行 agent 把「量两次、剪一次」推到极限。
做法是用 prototype 剧本(playbook)。
在 pstack 里,playbook 不是 skill,而是 /poteto-mode 内部的参考文件。这些剧本会按你正在做的任务类型有条件地加载(为了省 token)。截至 0.15.0,有 23 个剧本,每个包含我做某类任务时用的工作流。
和 skill 不同,剧本是由 agent 在 /poteto-mode 里自动使用的。比如:
/poteto-mode prototype a few options for the new dropdown menu
/poteto-mode fix this bug
/poteto-mode eval this skill change
原型是我最喜欢的 pstack 剧本之一。它给你针对一个目标的大量尝试,并帮 agent 推理出最好的选项。它不只对视觉原型有用,对功能、bug 修复等不同方案的探路同样有用。
/poteto-mode 为 <功能需求> 原型几个方案。用 /control-app 录视频、截图给我,让我挑选。
(注:/control-app 就是我们在第一篇里创建的验证 skill。)
做视觉原型时,agent 会在你的应用里或一个草稿目录里做一次性的草图。如果它在测 UI 交互,就把两三个变体藏在一个简单的切换器后面。然后用 /control-app 驱动交互、给每个变体截图,并测量真实的耗时或布局。
原型就是规划,只不过是用代码来规划。它让 agent 自由地探索问题空间,也给它机会用你没想到的东西给你惊喜。原型让 agent 用实证回答自己的问题,而不是等我输入。
架构更大的改动
作为 agent 时代的工程师,更重要的时间应该花在架构、选对数据结构、以及思考我建的这些系统如何协同工作上。实现细节由 agent 填充。
pstack 自带的另一个有用 skill 是 /architect。它把设计拆成几个明确、有纪律的阶段:
落地问题。Agent 在受影响的系统上跑 /how 和 /why,建立对现有归属关系与约束的准确心智模型。
画草图。Agent 进入一个「架构竞技场」:并行 spawn 多个彼此独立的候选 runner,往往跨不同模型家族。每个 runner 收到落地的简报,产出一份完整的设计包:调用方的用法草图、核心类型定义、公开函数签名,以及简明的理由。做法通常是先把类型签名画出来——从我们希望调用点长什么样倒推。每个 runner 都必须评估接口深度、在弱模型上检查失败模式,并用我们的设计红旗清单来筛查。
交叉评判与综合。一个和主 agent 使用不同模型的交叉评判 agent,用严格评分表评估这些候选。
照着草图实现。Agent 把草图里的占位实现换成真实逻辑。如果实现在过程中发现某个函数需要意料之外的参数或额外状态,它要把这个不一致暴露出来。
设计错了就扔掉。如果实现过程中发现草图是错的,agent 把整套扔掉,从头再来。
这里的要点,是给 agent 一个自足的迷你循环:把来自不同模型家族的多个竞争设计综合成一个最优方案,同时保持严谨,并且在实证表明架构错了的时候敢于把自己的设计扔掉。如果同一个 workaround 出现在互不相关的调用点上,或者类型需要 any、强制类型转换这类逃生舱口,那就是架构错了的实证。
/architect 这个新的 <功能需求>
最重要的一课:用 /poteto-mode 的原型和 /architect 来「用代码规划」,效率要高得多。
这也是为什么我从不费心去对抗式地审查抽象计划:agent 会开始幻想理论上的风险,发明复杂的边缘情况,去防那些永远不会发生的问题。计划还停在抽象阶段时,别把它过度烹调——让 agent 通过原型和验证自己的工作,自己回答那些开放问题。
好吧,但我真的很想要一份计划文档
pstack 不带 planning skill,但它带了一个多阶段规划剧本。我通常是在 agent 拿出一个我满意的设计之后用它,作为一种战术执行计划:
/poteto-mode 把这个设计变成一份计划。
计划里的每一个任务都围绕证据和验证来组织。剧本会告诉 agent:光有测试不足以构成验证,只有在它真正跑过代码、并确认能用之后,才算验证过。
每份计划都由一个自动化脚本校验结构和格式。批准之后,计划逐项执行。每个 PR 都很小、自包含、容易审查。
对真正的大项目(比如要花我整整一周的那种),我有时会决定把计划临时提交到代码库里,让其他 agent 知道这件工作正在进行。但我通常做完就删掉,免得把代码库留在一个令人困惑的状态。我不认为把计划长期留着有什么价值。
实践中的工作流
为了看清这些部分怎么拼在一起,我们走三个具体的例子,看看我怎么给这些工作流写 prompt。
例子一:调研一个模糊的 bug。生产环境出现问题、根因不明时:
/poteto-mode 调查为什么后台 worker 周期性因超时失败。给我一份拆解:我们知道什么、你用了哪些数据、以及你最好的几个假设。
agent 会并行地读代码、查指标、翻历史提交,然后给你几个最有根据的猜测。
例子二:设计一个新的服务边界。引入一个会被其他模块依赖的新子系统时:
/poteto-mode 我们要给外部 webhook 加限流。/architect 先做设计,任何开放问题用原型回答。开始动手之前让我先看。
agent 会先落地现有 webhook 架构的理解,跨多个模型开并行设计 runner,用一次性原型做基准测试,最后给出一个干净、经过验证的接口。
例子三:执行一个跨多 PR 的迁移。在大量文件上做复杂重构时:
/poteto-mode 做一份计划,把我们整个 UI 库迁移到 StyleX。把迁移切成小而可验证的 PR。每个 PR 都必须有视觉回归测试和实时验证步骤。我要最终结果和原来 100% 一致——包括 bug。
agent 把工作拆成独立的步骤,写出可审计的检查清单,并准备好每个单元,让它能被安全地构建、验证和合入。
例子四:修别人在 Slack 报的问题。如果你在 Slack 的 issue 或反馈频道见过我,你大概见过这些经典操作:
# thread 里上下文已经够了
/poteto-mode do it
/poteto-mode repro this with /control-app. if it repros on main, fix it and show me a video as proof
我在这里讲的很多 skill 已经被 /poteto-mode 自动使用,所以绝大多数时候你只需要用 /poteto-mode,然后该干嘛干嘛去。
规划的艺术
Plan Mode 常被用来让自己确信 agent 会做对的事。但现实是,抽象的计划只给你进步的幻觉:一份又长又细的计划看起来像你和 agent 都很高产,但它很可能缺乏实质。
pstack 给你的是把彻底调查、实证和严格验证结合起来的工具。当你这样规划时,用 agent 做工程不再像赌博,它变得可预测、可重复。
感谢阅读,第三篇见。
原文:https://x.com/poteto/status/2097732320606507506
#Agent #Skill #pstack #工程实践