用 Claude Code + mattpocock-skills 全链路开发「长辈计算器」macOS 应用的复盘手记
我用 Claude Code 配合 mattpocock/skills 技能集,从零开发了一款 macOS 原生应用「长辈计算器」。项目本身并不复杂——四则运算、语音播报、计算历史,一个计算器而已。真正值得记录的,是它的开发过程:需求澄清、规格编写、任务拆分、TDD 实现、代码评审,五个环节全部由「人 + AI 智能体」协作完成,而 AI 在每个环节都承担了可独立交付的实质性工作。
这篇文章复盘这次实践,试图回答一个问题:当 AI 不再只是「帮你写代码」的工具,而是整条软件开发生命周期(SDLC)的参与者时,软件开发本身会发生什么变化?
我的核心结论是:AI 原生开发的关键不在「AI 能写多少代码」,而在于把软件开发中大量隐性的东西——需求理解、决策理由、测试接缝、验收标准——变成仓库里显式、可审查、可追踪的工件。这套流程的每个环节都在做同一件事:上下文工程(Context Engineering)。谁管理好了上下文,谁就管理好了 AI 开发的质量。
过去两年被称作「AI 编程」的实践,绝大多数是AI 辅助编程:人写代码,AI 补全片段、生成函数、修 bug。开发流程本身不变,AI 只是加快了打字速度。
AI 原生开发不同:它重新设计了软件开发生命周期本身。人不再逐行写代码,而是——
在这次实践中,这个分工具体化为一条有状态的流水线。
mattpocock-skills 把 AI 开发组织成一条流水线,五个环节首尾相接:
注意这条链路与传统流程的一个关键差异:文档不是过程的副产品,而是过程的主线。每个阶段结束时,产出物都不是「口头共识」,而是磁盘上可读、可 diff、可追溯的真实文件:CONTEXT.md、.scratch/elder-calculator/spec.md、issues/01…12.md,以及最终落进 git 的代码与测试。
grill-with-docs 的工作方式是一场结构化的苏格拉底式访谈:AI 不直接开写,而是一轮一轮「拷问」,直到人和 AI 对产品共享同一个理解。这次项目经历了 4 轮访谈、约 25 个决策点,覆盖:目标用户画像(60–80 岁、老花眼、手部灵活性、听力状况)、功能边界(要不要记忆功能)、界面语言(全中文)、技术栈(SwiftUI vs AppKit)、分发方式、适老手段、语音播报粒度与读法、计算语义(实体计算器式 vs 表达式式)、清除键防误触机制、历史记录形态、首次启动体验……
有两个机制值得单独拎出来:
其一,决策即时落档。「一个术语被敲定,它落地到 CONTEXT.md 的时机就是它被敲定的那一刻,而不是最后批量补交。」材料中 CONTEXT.md 更新了 3 次,每次都在一轮访谈结束后立即写入,术语表从最初 7 个条目增长为覆盖计算语义、千分位、分级清除、设置项、错误边界的完整领域模型。
其二,推荐 + 确认的低摩擦决策模式。每一轮,AI 都会给出推荐及理由,用户只需「都按推荐」或针对性修改。例如砍掉记忆功能(M+/M−)这一重要取舍,AI 的理由是:「历史记录已经覆盖『之前算的数字想再用』的场景,记忆键的隐式状态(屏幕上多一个 M 指示灯)对老人是纯负担。」访谈的深度靠 AI 的结构化提问保证,决策速度靠推荐机制保证——这是「人做决策、AI 提供决策支持」的典型形态。
「四轮下来,设计树的分支已经全部走完,frontier 已清空……如有任何一条想改,现在说是最便宜的时机。」 —— 访谈结束时 AI 输出的共识总结,请用户做最终确认
这句话点出了这套流程的核心价值:把错误扼杀在需求阶段,因为这是纠偏成本最低的时机。
to-spec 阶段有两个亮点。
亮点一:测试接缝(seam)设计被前置到规格阶段。seam 是 Michael Feathers 的术语:一个「无需在那个位置编辑代码就能改变行为」的地点。在写任何代码之前,AI 先和人确认「在哪里测试」——最终确定两个接缝:
理由很工程化:「接缝越少越好,这两个模块是真正独立的纯逻辑,其余都是它们的薄壳。」这个决策把「软件架构」从实现阶段提前到了规格阶段,并且用测试的视角来定义模块边界——先决定哪里可以被测试,再决定代码怎么组织。
亮点二:规格是行为契约,不是实现说明书。spec.md 包含:问题陈述(老年用户用系统计算器的具体痛点)、36 条用户故事(按「基本计算 / 看得清 / 听得见 / 错得起 / 回看核对 / 键盘与其他」六组组织)、实现决策(两个深模块 + 薄壳)、测试决策(只测外部行为,不测内部实现)、10 项明确的 Out of Scope。特别值得注意的是行为权威的单一来源:
「领域术语与全部交互共识的权威定义在根目录 CONTEXT.md……spec 与术语表冲突时以术语表为准并在实现前澄清。」
to-tickets 把 36 条用户故事拆成 12 张 ticket。关键原则是 ticket ≠ 用户故事:一张 ticket 会打包多条相关故事,每张是一个 tracer-bullet(曳光弹)垂直切片——贯穿引擎 → UI → 测试,独立可演示、可验证,尺寸控制在单个上下文窗口内。
ticket 03(四则运算与等号)就是一个例子:它一次性覆盖链式语义、运算符替换、出结果后开新笔、重复等号等十几条故事对应的引擎 + UI + 测试。
12 张票的依赖结构体现了明确的工程判断:
材料中有一段关于「为什么拆票」的论述,我认为是这套流程最深刻的设计思想:
/implement 是全自动的:读 spec、TDD 红绿循环、跑 code review、提交。「这个『频繁介入』恰恰是这套流程的设计意图,不是缺点。」
这句话颠覆了很多人对 AI 开发的直觉。我们总希望 AI 一口气干完,但上下文是有穷的,质量随上下文长度衰减。用会话边界换取上下文清醒,用检查点换取纠偏机会,是这套流程对「上下文工程」最具体的落实。
/implement 会自动调用 /tdd 和 /code-review。以 ticket 03(四则运算与等号)为例,实现过程是教科书式的 TDD:
code-review 的「双轴」设计是另一个亮点:一个审查轴对 Spec(规格),一个审查轴对 Standards(编码标准),两个审查子智能体并行运行。这次评审的结果很有说服力:
CONTEXT.md 的要求「屏幕上的数字带千分位」),已补测试修复——证明 review 不是走过场;值得注意的是,review 的结果不只是意见,还区分了「必须修」和「暂不做」,并为「暂不做」给出了未来的触发条件——这是成熟的工程判断,不是机械执行。
把这次实践提炼为可迁移的方法论,我认为有五个洞察值得强调:
这套流程的全部机制——CONTEXT.md 术语表、spec 的行为契约、ticket 的验收清单、每票全新会话——都是在管理上下文:给智能体提供正确的、结构化的、不过载的上下文。写代码的能力(Claude Code)现在是商品化的,管理上下文的能力才是差异化的。
CONTEXT.md、spec.md、issues 不是「文档化」的装饰,它们是流水线的工作产物。实践记录特别提醒:「这些工件是真实仓库里的真实文件,所以它们可以在你以为存在时缺席,也可能在不止一个人往里写的时候漂移。」这意味着文档要像代码一样对待:review、diff、版本管理。
「现在说是最便宜的时机」贯穿全程:需求阶段的约 25 个决策点每个都被显式确认;Out of Scope 明确列出 10 项「不做的事」(记忆功能、科学计算、结果复制、历史持久化、按键音效……)。很多项目死在需求模糊或范围蔓延,这套流程用结构化的方式消灭这两者。
用「在哪里测试」来定义模块边界,比用「怎么分层」更本质。两个接缝的选择(纯逻辑状态机 + 纯函数)让 23 个测试全部落在稳定、快速、不依赖 UI 的接缝上,UI 和语音播放交给手工验证——自动化测试的投入产出比因此被拉满。
用户全程只做了若干次「都按推荐」和几次启动 ticket,但每个决策点都被显式呈现并确认。AI 原生开发的理想分工是:AI 负责遍历可能性和执行,人负责确认方向和做取舍——人不是退出了开发,而是从执行层上升到了决策层。
CONTEXT.md,不要等最后批量补交。CONTEXT.md > spec.md > ticket > 测试。这次实践给我的最大感受是:AI 原生开发不是「让 AI 干活、人验收」的偷懒模式,而是一套更严格的工程纪律。它把传统开发中靠人脑记忆、靠会议口头对齐、靠隐式经验的东西——领域术语、决策理由、测试策略、验收标准——全部显式化、文件化、可追踪化。
当智能体承担了访谈、写作、拆解、编码、测试、评审这些执行性工作,人终于可以专注于它最擅长也最该做的事:判断什么是对的。
这也许就是「AI 原生」的真正含义:不是 AI 替代了工程师,而是工程师被重新定义——从「写代码的人」变成「定义问题、管理上下文、做决策的人」。下一次实践,真正值得设计的也许不是应用本身,而是这条流水线。
参考来源: