I am LAZY bones?
AN ancient AND boring SITE

分类: 'AI' 的归档

每日一辨 DailyDiff

最近上架了一个新 App:DailyDiff(每日一辨)。做它的初衷很简单:一是我自己想把英语再往上提一提,二是儿子也在学英语,我想给他(也给自己)找一个每天花几分钟、细水长流的练法。

市面上背单词的软件很多,但它们解决的基本都是”认识”:看见 soldier 知道是战士,看见 warrior 也知道是战士。可这两个词的区别是什么、什么场合该用哪个——这种”掌握”层面的功夫,几乎没有软件管。而”认识一个单词”和”掌握一个单词”之间恰恰隔着一条鸿沟,它决定了你的英语是只能读,还是真的能用。所以我做了一个专门练这个的 App。

每天一道题,它长什么样

玩法抄了 Wordle 的作业:每天全球所有人拿到同一道题——一对容易混淆的英语近义词,各配一张黑白线稿插图。你用英语写出这两个词在含义、语气、用法上的区别,一两句话就行,然后 AI 给你批改。

批改是这个 App 的核心。不是给个分就完事,而是从五个维度(准确性、覆盖度、语言、清晰度、洞察)各打一个 0–100 的分,每个维度都附一句针对你这次答案的点评——指出你答到位的地方、漏掉的要点,像一对一外教改作业。五个分数汇总成总分和等级,从 D 到 SSS。SSS 很难拿:不光要总分 95 以上,还要求最低的那个维度也不低于 90,纯靠某一项拉平均分是蒙不到的。

批改完揭晓标准答案,对照着学。之后就是熟悉的套路:每日连击打卡、日历一格格点亮,还能导出一张成绩卡分享——卡上只有词对、插图、等级和雷达图,刻意不含答案,朋友看到照样能去玩。

题库目前 200 道,四百张插图全是 AI 生成的黑白线稿,风格统一得像一个插画师画的。

技术上几个有意思的决定

作为技术博客,还是得聊聊后端。整个服务端就是一个 Cloudflare Worker,配 D1(题库和用户数据)和 R2(插图),没有一台服务器要运维,账单基本可以忽略——独立开发选这套栈真的省心。

我之前的服务,都是部署在自己的home lab上的,这也是一次全套采用cloudflare的技术方案,发觉这个赛博菩萨果然名不虚传,免费额度够用不说,wrangler的开发体验还非常棒!

几个细节自认为做得还算讲究:

1. 评分标准(rubric)永远不下发到客户端。客户端只上传题目 ID 和你写的答案,评分要点由服务端按 ID 查表后喂给模型。否则抓个包就能看到得分点,这游戏就没法玩了。

2. 总分和等级不信任模型自己报的数。LLM 的算术是出了名的不可靠,让它算五个维度的加权和,隔三差五给你算错一个。所以模型只负责逐维度打分和写点评,加总、定级在代码里重算。

3. 匿名用户不用注册就能玩,每天免费批改一次。防滥用靠的不是强制登录,而是 Apple 的 App Attest——让苹果证明请求来自真机上的正版 App,机器人和脚本过不来。这套东西的原理和服务端验证的坑,我之前单独写过一篇《Apple App Attest 简介》,感兴趣可以看看。

4. 批改额度是”先预扣、失败退还”。最早的实现是先只读检查额度、批改成功了再扣,看起来很稳妥——但批改一次要跑上一两分钟,这个窗口里并发发请求,每个请求检查时都显示”还有额度”,就都放行了,白烧 token。改成预扣制之后,靠 D1 单写者的串行化保证并发下最多放行额度上限那么多个请求,批改失败再把额度退回去。

免费与收费

说说钱的事,明码标价:每天的题目永远免费,匿名一天能批改 1 次,登录后 2 次。Pro 订阅(月付或年付)解锁 200 道历史题库、研读模式(先看标准答案再作答)和每天 15 次批改。订阅收入拿去付 AI 推理的账单——每一次批改都是真金白银的 API 调用,所以免费额度给得抠门,请理解哈哈。

来玩

App Store 搜「DailyDiff」或「每日一辨」,或者直接点这个链接。中英文界面都有,今天的题不用注册就能做。

如果你试了之后觉得 AI 批改哪次明显不靠谱,或者有任何建议,欢迎邮件 support@dailydiff.vip 或者直接在下面留言——独立开发,每一条反馈我都会看。

顺便说一句,今天的题你打算拿几分?我至今没拿到过自己 App 里的 SSS。

就此,完毕。

fastlane——App Store Connect CLI(非官方)

我的打鼾监测 App NightSnore 支持 7 种语言(简中、英、日、韩、德、法、阿拉伯语)。这带来一个每次发版都要经历的痛苦环节:在 App Store Connect 后台,把 What’s New(新功能介绍)逐个语言粘贴进去——切语言、粘贴、保存,再切下一个,七遍。要是 Promotional Text(推广文本)也更新了,那就是十四遍。发布过APP的朋友,肯定对此就深有体会了。

这次发 2.3.0 的时候我终于忍不住了:这玩意儿就没有 CLI 能自动化吗?

还真有,而且就是 fastlane。有意思的是,fastlane 我其实早就装了——之前一直拿它给 App Store 截图加设备边框(frameit),我一直以为它就是个截图美化工具,哈哈。这次才发现,截图加框只是它十八般武艺里最不起眼的一样。

fastlane 到底是什么

fastlane 的定位是”把 iOS/Android 发布流程的每个环节都变成可脚本化的命令”。它其实是一整套工具的集合,每个工具管一段:

1. deliver:上传元数据(What’s New、描述、关键词、截图)到 App Store Connect,本文主角。
2. snapshot:跑 UI 测试自动截图,能覆盖每种语言 × 每种设备尺寸。
3. frameit:给截图加设备边框,我之前唯一用过的那个。
4. gym / pilot:打包上传、TestFlight 分发和测试员管理。
5. match / cert / sigh:证书和描述文件的团队共享管理。
6. precheck:上传前扫描文案里的审核高危词。

单人开发、Xcode 自动签名的话,match 这类团队工具基本用不上;但 deliver 对多语言 App 来说是刚需级的效率工具。

deliver:把 ASC 表单变成本地文件

deliver 的思路很直接:ASC 后台的每个表单字段,对应本地一个文本文件,目录按语言组织:

一个很贴心的设计是:目录里有什么文件,它就只上传什么。我只放了 release_notes.txt 和 promotional_text.txt,那么描述、关键词、截图这些都不会被碰。配置文件 Deliverfile 里再把二进制和截图明确跳过:

搭一条 What’s New 流水线

我的 App Store 文案一直维护在仓库的 AppStore/*.md 里(七个语言各一个文件),每次发版往里追加一段”## What’s New (X.Y.Z)”。这个 Markdown 就是唯一数据源,所以流水线只需要一个提取脚本:从 md 里抠出指定版本的段落,写到 deliver 要的 metadata 目录去。再包一个 fastlane lane 串起来:

提取脚本里顺手做了两层校验:七个语言缺任何一个对应版本的段落就直接报错(强制多语言同步,防漏),超过 ASC 的字符上限(What’s New 4000 字符、Promotional Text 170 字符)也直接拦下。以后发版就是一条命令:

从跑命令到 ASC 七个语言全部填好,9 秒。之前手动粘贴至少十分钟,还得祈祷别粘串了语言。

API Key,和一个专门坑你的格式问题

deliver 走的是 App Store Connect API,需要一个 API 密钥:ASC 后台”用户和访问 → 集成 → App Store Connect API”里创建一个团队密钥,角色选 App Manager,会得到一个 .p8 私钥文件(只能下载一次)加 Key ID 和 Issuer ID。

然后我就结结实实踩了个坑。deliver 支持用一个 JSON 文件传密钥,我很自然地写成了指向 .p8 文件路径的形式,结果:

查了才知道:fastlane 的 Fastfile 里有个 app_store_connect_api_key 这个 action,它支持 key_filepath 参数指向 .p8 文件;但 deliver 的 api_key_path 参数指向的 JSON 文件,只认内联的 key 字段——你得把 .p8 的 PEM 内容整个塞进 JSON 字符串里(换行转成 \n)。同一个工具链里两种密钥写法长得几乎一样但互不兼容,这不纯纯挖坑嘛。正确格式长这样:

这个文件含私钥,务必进 .gitignore,待遇跟你的其他 secrets 一样。

踩坑与注意事项

1. deliver 只能写”可编辑状态”的版本(准备提交、被拒等),已在审核中或已上架的版本改不了。所以要在上传 build 之后、点提交审核之前跑它;版本还没建也没关系,deliver 会自动创建。

2. locale 代码不都带地区后缀:日语是 ja 不是 ja-JP,韩语是 ko,但英语是 en-US、德语是 de-DE。写映射表的时候留意。

3. metadata 目录里有什么就传什么,这既是特性也是风险:目录里残留一个过期的 description.txt,就会把线上描述覆盖掉。我的做法是 metadata 目录整个 gitignore,每次由脚本从 md 重新生成,保证它永远是纯派生产物。

用 skill 操作,vibe coding 更顺畅

还有一层我觉得比工具本身更有意思:这整条流水线,从功能开发、写七语言文案,到搭 fastlane、踩坑、修好,都是在 Claude Code 里完成的。搭好之后我顺手让它把整个发版流程沉淀成一个项目 skill——仓库里的一个 .claude/skills/release/SKILL.md 文件,把九个步骤写成清单:bump 版本号 → 编译验证 → 七语言 What’s New / Promotional Text → commit → xcodebuild 归档上传 → 打 tag → fastlane 同步 ASC 表单,连”deliver 的 JSON 只认内联 key”这种坑位说明都写在里面。

下次发版,我只需要说一句 /release 2.4.0,AI 就照着清单把整条链路跑完,唯一剩下的手动操作是去 ASC 点提交审核。skill 跟着仓库走,clone 下来就有,等于把发版的”部落知识”固化成了可执行的文档。对 vibe coding 来说这很关键:写代码交给 AI 大家都会了,但发布环节往往还是人肉在各个后台之间点来点去——把这段也纳入对话式工作流,从开发到上架才算真正闭环。

下一个目标

尝到甜头之后我看了一圈 fastlane 工具箱,对我这种多语言独立开发场景,下一个最值得上的是 snapshot:七个语言的商店截图现在还是手动截的,每次界面大改就是一下午。snapshot 跑 UI 测试自动出全语言截图,再接上我已经会用的 frameit 加框、deliver 上传,理论上截图这条线也能变成一条命令。挖个坑,做完再写。

发布流程自动化这件事,本质上是把”每次发版都要凭记忆和手感重复一遍的操作”变成”写一次、以后白嫖”的脚本。对独立开发者来说,省的那十几分钟是小事,真正值钱的是不再需要担心”这次是不是又漏了哪个语言”——机器不会漏。

就此,完毕。

OpenClaw分享

以下PPT和内容,来源是我跟一群爱学习的朋友一起学时下大火的OpenClaw小龙虾,我给大家做了个小分享。

PPT几乎是OpenClaw输出的内容,下面的会议总结也是GPT根据会议录屏总结的。

需要注意的是,我其实没有将小龙虾玩得很深,因为我从心底里是不信任AI的,也就不敢给它太多权限。所以内容也都比较浅,请见谅。

OpenClaw 会议总结

这次分享的核心,不是在介绍一个“聊天机器人”,而是在介绍一套可自托管、可扩展、可执行任务的个人 AI 基础设施。分享者把 OpenClaw 定位为“装进手机里的 AI 助手”:用户通过 WhatsApp、Telegram 等聊天入口发出请求,背后由部署在自己电脑或服务器上的 OpenClaw 网关完成会话管理、记忆注入、工具调用和本地执行,再把结果返回到聊天端。PPT 对这一定位和整体链路描述得很清楚。

点击查看全文 »