用一句话提需求,20 次交互迭代,把「火山方舟 Coding Plan 额度监控」从 CLI 做到 macOS 菜单栏应用,再开源上线。这篇文章复盘完整流程、关键技巧,并给出「如果重新开始,一次到位的提示词」。

一、起点:一句话

最初的需求只有一句话:

写一个火山方舟 Coding Plan 的剩余额度实时查看工具,以及查看有哪些模型、费率是怎么样的。先搜一下有没有官方工具或开源实现。

这个「先搜一下」很关键——AI Coding 的第一原则是别重复造轮子。搜索发现官方有 Ark CLI,但它是命令行工具、要自己装 Go 环境;开源社区有 dashboard 类实现但都是网页版。都没有「macOS 菜单栏常驻 + 多账户」形态,于是决定自己做。

二、全流程:20 次交互,13 个主题

整个项目不是一次生成的,而是渐进式演进:工具 → 桌面端 → 修 Bug → 产品化 → 开源发布。完整时间线如下:

#

交互

内容

结果

1

一句话需求

CLI 工具 + 模型/费率,先调研

Python CLI(签名自检通过)

2

升级桌面端

macOS 菜单栏,右键配置、多账户

SwiftUI + AppKit 混构雏形

3

咨询 AK/SK

哪里获取密钥

IAM 密钥管理页 + 最小权限建议

4

Bug 反馈

余额显示 0,与网页不一致

换 API:GetAFPUsage → GetCodingPlanUsage

5–7

连续「不展示」

数据刷新成功但界面空白

换架构:MenuBarExtra → NSStatusItem

8

产品化重设计

圆形剩余指示、左键详情、右键菜单、退出

当前交互形态定稿

9

开源发布

README / workflow / 官网 / 截图

三套 CI + Pages 官网

10

截图占位

占位符先行,用户补图

流程解耦

11

Logo 全链路

SVG → PNG → icns → favicon

品牌完整

12

发布 Release

打 tag 触发构建

v1.0.0

13

Bug 修复

关闭设置窗口应用退出

生命周期修复,v1.0.1

14

截图同步 + 收尾

图片上线上线

官网截图区更新

规律:真正消耗时间的不是「写代码」,而是「对齐预期」——用户说不清 → AI 做错方向 → 反馈 → 修正。每轮对话都在收敛产品形态,最终沉淀为一个完整可用的开源项目。

三、关键技巧盘点

1. 先调研,再动手

搜索官方 Ark CLI 与开源实现,确定接口与形态差异,避免重复造轮子。

2. 源码级交叉验证

余额为 0 的根因,是克隆了官方 ark-cli 的 Go 源码逐行比对才定位的:Coding Plan 个人版应调用 GetCodingPlanUsage(百分比额度),而 GetAFPUsage 只适用于 Agent Plan。顺带确认了 Level 枚举映射:session/5h → 近5小时、weekly → 近一周、monthly → 近一月。

3. HMAC-SHA256 签名踩坑

火山引擎签名链要求用上一步 HMAC 的原始摘要字节作为下一步密钥(不是 hex 字符串)。用官方文档示例数据写了 selftest,一次通过。

4. 分层诊断法

「刷新成功但界面不展示」连报三轮,靠日志把问题切成两层:

  • API 拉取层:日志确认 5h=51.8%、周=38.8%、月=32.9%,数据完全正常

  • UI 渲染层:根因是 SwiftUI MenuBarExtra 的 label 闭包不响应 @Published 变化

定位后不做修补,直接换架构——AppKit NSStatusItem + NSPopover + NSHostingController,问题根除。

5. 环境变量调试开关

CB_SHOW_POPOVER / CB_KEEP_POPOVER / CB_SHOW_SETTINGS 三个开关,让弹窗、设置窗口可以脚本化打开,为后续自动化截图铺路。

6. 开源全链路 CI

三套 workflow 覆盖完整交付:

  • build.yml:macOS 构建 + 打包上传 artifact

  • pages.yml:docs/ 部署 GitHub Pages 官网

  • release.yml:打 tag 自动构建 zip 并发布 Release

7. 避坑:secret scanning 与 Pages 启用

  • 官方文档示例密钥被 GitHub 识别为泄密 → 拆字面量 + amend 重写提交

  • Pages 未启用时 GITHUB_TOKEN 无权限 → 用账号 token 调 API 开启,workflow 加 enablement: true

8. macOS 应用生命周期

菜单栏常驻应用关闭设置窗口后应用退出——SwiftUI 默认「最后窗口关闭即退出」,覆写 applicationShouldTerminateAfterLastWindowClosed 返回 false 解决。

四、如果重新开始:一次到位的提示词

把 20 轮交互积累的约束全部写进一句话,直接生成最终形态:

做一个 macOS 菜单栏应用「Coding Balance」:实时监控火山方舟 Coding Plan 剩余额度(5h/周/月),菜单栏圆形进度环+百分比(绿≥50%橙20-50%红<20%),左键详情弹窗(5h 大圆环+周/月明细+重置时间),右键菜单(刷新/管理账户/退出),多账户切换,60s 自动刷新,AK/SK 仅存本机。

数据直连火山官方管控面 API:GetCodingPlanUsage(Coding Plan 百分比,host=open.volcengineapi.com)、GetAFPUsage(Agent Plan AFP 绝对值)、GetPersonalPlan,按官方《签名方法》实现 HMAC-SHA256(派生密钥必须用上一步原始摘要字节)。

同步提供 Python CLI。开源到 GitHub:README、MIT License、三套 CI(macOS 构建 + Pages 官网 + Tag 触发 Release)、极简额度环 Logo、三张截图。

技术红线:菜单栏必须用 AppKit NSStatusItem(SwiftUI MenuBarExtra 的 label 不响应状态刷新,禁用);关闭设置窗口应用不得退出(覆写 applicationShouldTerminateAfterLastWindowClosed)。

这段提示词的含金量,正是前 20 轮踩坑换来的「约束清单」——把最容易出错的三处(签名派生、菜单栏渲染、应用生命周期)直接钉死在需求里。

五、成果

一句话需求 + 20 轮对话 + 8 类关键技巧 = 一个正在被真实使用的开源工具。这就是 2026 年 AI Coding 的典型工作流:AI 负责把想法编译成代码,人负责把预期讲清楚。