Mobile / Web 软件开发者@Thoughtworks.com
- 在读:《盲人钟表匠》;《理性思考的艺术》
- 在玩:《塞尔达: 王国之泪》;《黑神话:悟空》;《博德之门 3》
- 在练:推 85KG * 7 * 5;蹲 135KG * 7 * 5;拉 120KG * 8 * 5
Mobile / Web 软件开发者@Thoughtworks.com
最近发现自己越来越像一个 TDD 工程师了,不是 Test-Driven Development,而是 Terminology-Driven Development。当需要实现一个功能时,我不再思考「怎么写代码」,而是思考「用什么术语」。 曾经有很长一段时间 Thoughtworks 社招 mobile 开发的面试题是会要求做一个朋友圈出来,除了考察项目结构设计,层级依赖是否清晰还有代码风格之外,最重要的考察是是否有实现图片的三级缓存。如果是现在拿到这个面试题,只需要知道三级缓存这个概念即可。在现在这个时间点,我不觉得有多少开发者独立实现的最终代码质量和可维护性会比 Claude 更好。 学编程的时候,总会看到「不要死记硬背,要理解原理」的描述。现在好了,连原理都不需要理解了,只需要知道「三级缓存」这个词汇即可。过去如果需要解决一个不熟悉领域的问题,除了要定位问题发现 root cause 之外,还需要根据解决方案的实现成本和可维护性来做决策,这需要对每个方案在当前系统中如何实现了然于胸才行。现在决策过程变成了定位问题,念出正确的术语即可交给 AI 实现。 术语即 API 仔细想想,这其实是个自然演进: 汇编时代:需要记住寄存器名称 Objective-C 时代:需要记住 MRC / ARC 内存管理 Swift 时代:需要记住语法糖 AI 时代:需要记住概念术语 每一层抽象都在让我们更接近「解决问题」本身,远离「如何解决问题」。现在的区别只是抽象层级更高了而已。 又想到一个比喻,就好像是中国人用成语来压缩信息。甲劝乙,现在对丙的喜欢可能是因为没太实际接触到丙,有可能只是自己想象中的喜欢。但如果甲乙都是中国人那可用上「叶公好龙」四个字,准确表达其含义和劝诫的立场。 AI 就是那个能够 decode 所有成语的人。
在 twitter 上发现 Wildcard 平台跑路了,开始找办法充值 Claude Code,调查之后发现靠谱不怕跑路的支付方案有两个: App Store 美区账号订阅 虚拟币平台发行的信用卡 有了保底方案就不慌了。恰巧 Kimi K2 发布,就研究了一下是否能搭配使用,一方面节约点钱,另一方面为可能的被平台封号做二手准备。 如果是 Claude Code + Kimi K2 设置一下环境变量即可: kimi() { export ANTHROPIC_AUTH_TOKEN=${KEY} export ANTHROPIC_BASE_URL=https://api.moonshot.cn/anthropic/ export ANTHROPIC_SMALL_FAST_MODEL="kimi-k2-turbo-preview" export ANTHROPIC_MODEL="kimi-k2-turbo-preview" claude --dangerously-skip-permissions $1 } 如果是使用 OpenCode + Kimi K2 则稍微多一点: 在 ~/.local/share/opencode/auth.json 中放置自己的 moonshot 平台生成的 key(要注意自己 key 是从 https://platform.moonshot.ai 还是 https://platform.moonshot.cn 生成的) { "moonshot": { "type": "api", "key": ${KEY} } } 在 ~/.config/opencode/opencode.json 中配置一下模型和 URL { "$schema": "https://opencode.ai/config.json", "theme": "opencode", "provider": { "moonshot": { "npm": "@ai-sdk/openai-compatible", "options": { "baseURL": "https://api.moonshot.cn/v1" // 如果是从 https://platform.moonshot.ai 生成的 key 记得改这里的 URL }, "models": { "kimi-k2-turbo-preview": {} } } }, "autoshare": false, "autoupdate": true } 配置好了之后就按照平常用 Claude Code Max 5x 的方式使用了一下 Open Code + Kimi K2,大概一上午用掉 30 块钱,代码生成和分析在我的 codebase 上体验上没有那么大的差别,或许因为按量计费,自己提供上下文给 AI 的时候还会二次检查一下,所以输出效果也比较好吧。 ...
自从开通了 Claude Code Max 5x 计划以来,开发方式已经发生了极大变化。在这里简单整理了一下自己的使用流程,其中的技巧也适用于 Gemini CLI 和 Open Code。 CLAUDE.md 如果有什么东西需要 Claude Code 在每轮对话中记住的话,就可以把它放进 CLAUDE.md 文件中。例如我有个项目用到了 SwiftData,在项目根目录下的 CLAUDE.md 中我就留下了这样的描述,提醒 Claude Code 在功能实现过程中不要把数据结构搞坏了,如果出现了它认为必要的改动,也应该设计好数据迁移的计划: When modifying any file containing import SwiftData, caution should be exercised. If it’s a “must-have” operation, think hard about how to migrate the data. 如果是各项目通用的注意事项,则可以在 ~/.claude/CLAUDE.md 中提及。比如我会让 Claude Code 不要生成 300 行以上的文件: Make sure the code related file you created or modified are no longer than 300 lines of code. ...
为了给客户的 app 做 reader app 的支持,首先需要把已有的注册流程全部干掉,然后用 External Link Account 来实现。刚开始分析需求的时候第一反应就是这活儿直接交给 AI Agent 来做简直完美,就是分析理解 user journey 然后删除对应路径上的各种依赖。但转念一想,似乎也没啥活儿不能交给 AI 了。 还花了大量时间投入在 side project 上,用 claude code 打磨一些交互上的细节。发现即使强如 opus 4,在找 UI 界面层级上,用透明组件实现的特殊交互时(前端惯用技巧,比如界面上看着是同一层级的元素,但为了交互的易用性,其层级关系会更复杂甚至反直觉,比如点击穿透和常见的 modal 展示),其理解能力也比较捉襟见肘。但提供了足够多的上下文之后,还是能很快完成任务。 chatGPT 的免费图生图额度也被我薅得差不多了,先后尝试过 grok,google AI studio 效果都不如 GPT image 1 模型,但又不想为了几张图片去订阅会员。最后在 v2ex 看到个卖 token 的,只花了 0.9 刀就搞定了两个 side project 的 app icon。 娱乐 《小骨》 ⭐️⭐️⭐️⭐️⭐️ RogueLike 游戏,几年前玩过二十小时。最近突然想再试试,没想到异常欢乐,周日玩了 12 小时。
在上周末花了 200 多条 alex message quote 修复 bug 依然失败的情况下,气不过跑去用 WildCard 开通了 Claude Code Max 5x。 此前因为 Claude 必须要1. 非中国区手机号注册,2. 非中国区信用卡付款,3. 非中国地区 IP 地址登入,三个条件同时满足才给用,就一直在找一些替代品。这次觉得与其花费很多时间研究 prompting 和 MCP 啥的以增强 AI agent 的能力,不如直接花钱买最好的模型来用。WildCard 提供了前两个条件的解决方案,可以申请 3 个手机号,提供订阅用的信用卡。缺点是需要开卡会员费(1 年 $9.9 和 2 年 $14.99 两种方式)和单笔充值 3.5% 的手续费。 开通了之后发现果然是好啊,只用了三轮对话,就解决了之前 alex 一整天都没有解决的问题。这下就沉迷进去了,而且得益于 claude code 的后台 agent 模式,并行又开了个 side project 的坑,这周在上面花了 44 小时。几乎一周都是 1、2 点才睡觉,这还是因为 Claude Code 5x 计划的使用限额强制暂停导致的,如果订阅了 20x 的计划,估计睡眠时间会更少。
本周的 Toggl 数据看起来相当健康。在总共记录的 43 小时中,工作稳定占据了 20.4 小时(47.3%),而个人项目达到了 10.7 小时(24.9%)。 个人项目时间的增长,并非完全源于自律,更多是工作项目因合同与发布日期的不确定性,带来了一段“时间真空”。我把这些时间空闲投入到了第一个 Vibe Coding 实验项目上,因此更清晰地触摸到了当前 AI 辅助编程的边界。 这个项目以摄像头为核心,而我很快发现,AI 难以对需要实时与物理世界交互的功能进行有效调试。对于摄像头前后翻转、镜像处理、人体识别这类问题,它似乎难以理解。其结果就是,我花费了整整 5 个小时,消耗了近 200 条 message 额度,却依然没能解决一个关键的人体识别难题。如果再选一次,我应该不会选择一个以摄像头为主的项目,作为探索 Vibe Coding 的起点。 这次痛苦的调试经历,也促使我快速迭代了与 AI 的协作模式,大致经历了三个版本: V1 - 直接指令式: 直接告诉 AI 我想要什么功能。这种方式很简单,但一旦 AI 的初步理解出现偏差,后续需要花费数倍的对话成本才能将其纠正,效率低下。 V2 - PRD 驱动式: 我开始使用更擅长规划的 Google Gemini Pro 对需求进行系统化分析,产出一份结构清晰的需求文档(PRD)。然后,我让 alex 基于这份 PRD 进行开发,显著提升了需求实现的准确性。 V3 - TDD 流程驱动式: 这是目前的最高阶版本。我编写了一份详细的“项目 Prompt”,其核心是为 AI 定义了一套严格的 TDD (测试(Test)或者说任务(Task)驱动开发) 工作流。从 Tasking 拆解任务开始,每一个 sub-task 都必须遵循“编写失败测试 -> 编写实现代码 -> 通过测试 -> 反思”的循环。这本质上是把我自己的开发方法论“注入”给了 AI。 ...
这周的 Toggl 数据呈现出一种值得警惕的模式。总记录时长高达 46 小时,表面上是忙碌且充实的一周,但仔细审视时间的流向,却发现了一些不平衡。 工作依然是时间投入的核心,占据了 43.1%。然而,真正反映个人成长和创造力的“个人项目” ,本周的投入锐减到了仅 5%。这是一个危险的信号。当被动的工作任务完全挤占了主动的个人创造时间,很容易陷入一种“为了工作而工作”的循环,从而失去对技术的热情和探索欲。这让我想起之前设立“写周记”这个行为的初衷——更好地感知时间。而现在,数据清晰地告诉我,我需要重新调整优先级,为那些能带来长期价值和满足感的事情,预留出更多的时间和精力。 本周在“消耗”上的投入相当可观。影音和游戏两项相加,总共消耗了总记录时长的近四分之一。虽然娱乐是必要的调剂,但当它在时间占比上开始与核心产出“分庭抗礼”时,就值得反思了。特别是当我发现“输入”类目(如读书、语言学习)的时间被严重压缩时,这种感觉尤为强烈。 看 Peter Steinberger 写的《Claude code is my computer》中我如何使用它一章,学到了可以用 Whipser flow 来和 Claude code(在我这里是 Google Gemini CLI)对话,然后让 claude code 来阅读他过去所有的文章并且基于他的写作风格来构建一篇新的文章。 在我的使用场景上衍生一下,就变成了: Google Gemini CLI 去 Toggl 读取了我上一周记录的数据。 分析我过去的周记所关注的数据侧重点,帮我产出一份具有洞察力的报告。 我会用 Whipser flow 和它产生一些对话。 根据对话,基于我写作风格来生成一篇新的周记。 很好玩!
最近工作闲暇有个习惯是在 twitter 上看最近 AI coding 相关的动态。这周看到 Peter Steinberger(PDFKit 创始人)举办了一次 vibe coding 的直播,总时长大概 3 个多小时,学到了不少相关实践。他也写了一篇文章来总结直播内容:The Future of Vibe Coding: Building with AI, Live and Unfiltered。 从他的直播中得到的收获是: 用 whisper flow 来进行语音输入,识别和样式的正确率都极高。自己用了一段时间发现中英混合输入的识别率也相当厉害。 用 Gemini 来生产一个结构化的规格文档,采取 Gemini 的原因主要是它上下文最大。然后新开一个对话再让 Gemini 来做同行评审(prompt: you are an AI tasked with implementing this spec in one go. Before you start, what questions do you have? What’s unclear? What’s missing for you to build this successfully?),会得到不错的反馈。 对于涉及可视化界面的开发任务,提供截图给 AI 的效果会很好。 在他的其他推文和博客中还对 Claude Code 赞誉有加,体验更甚于 Curosr 这样的 AI editor,可惜国内无法使用,眼馋啊… ...
之前体验了一下 alex 来 vibe coding 但没有付费,因为还在犹豫是订阅 cursor 还是 alex,等回过神来,发现 alex 已经从 20 USD 涨到了 30 USD 了。考虑到其开箱即用的 Xcode 整合体验确实很好,还是订阅了,但只要持续订阅 alex,每个月现在会额外付出 10 USD,多少有点难受。 但话说回来随着各家 IDE AI 的进化速度,似乎也没必要守着一个供应商来订阅。 娱乐 《白莲花度假村》 S3 ⭐️ ⭐️ ⭐️ ⭐️ 比起前两季来说稍逊一筹,主要问题是节奏太慢了,而且出现了 Lisa 和保安这条没有什么意义的线,占据了不时长。
端午节,本来计划是闲暇时间 vibe coding 完成一款 app 的初版。但不知道为何开始整理自己电脑里文件了。发现了自己大学写的日记的存档,当时觉得纸质的容易泄密且丢失,就拍照保存了一份丢 iCloud 了。 突然就想着要不把这些手写的日记照片给转成文字版存在 Day One 里好了。说干就干,最初的想法是直接 OCR 扫描一下就行,但简单试了一下就被自己潦草的字迹打败了。自己录入也不太可能,好几百篇得打到猴年马月。最后想到还是语音录入转文字吧,刚好知道了一个蛮厉害的语音转文字的 app,MacWhisper。试了一下免费版本,基本满足需求,但有个问题是转换出来的文字不带标点。需要购入 pro license(59 EUR),有点太贵了对我这种一次性需求来说。 然后想起来其实 iOS 自带的语言输入体验还不错,在 mac 上设置了一下,连击 ctrl 两次就可以唤起。且短文字录入效果很好,但太长了会出现吞句的现象。而且标点虽然会加,但错误比较多,不过胜在免费且系统级交互体验比较舒适,可以入侵到所有 app 的输入框里。 话说回来,之前辛苦从全拼转到了双拼,即使熟练使用了,这个速度完全也是完全比不上语音输入的,打字快的唯一优势只能是在办公室可以不影响他人吧。 双拼第三周速度刚到全拼的 60%,道长且阻啊。 速度 全拼 87 字/分 双拼第一天 17 字/分 双拼第三周 52 字/分
到了 618 购物,为了带娃的时候能带上纸巾,备用衣服和水杯等物,同时又不想在夏天背那么规整的双肩包,太热且笨拙,没办法追着娃到处跑。买了狐蝠工业的拉斐尔二代,配件包含: 混沌装备多功能内收纳模块 混沌装备水壶套 混沌装备肩带 头狼工业噤蝉透明收纳包 头狼工业弹夹收纳包 最后效果大概是这样子 但是当我把原先在双肩包的东西都挪到单肩包的时候,发现这个包已经有 ~1.25 KG(裸包 650g),开始为自己的肩膀感到担心了(事实上背了两周确实出现了肩颈酸痛的情况)。 娱乐 《最后的生还者》 S2 ⭐️ ⭐️ ⭐️ ⭐️ 略逊色于第一季,但第二集的名场面的处理要比游戏好不少。同时因为自己自己游戏只玩了一半,这一季(甚至下一季艾比篇)看起来会多了一些期待。 《白莲花度假村》 S2 ⭐️ ⭐️ ⭐️ ⭐️ ⭐️ 相当具有戏剧性,观感比第一季还要好很多。特别喜欢这一季对不同人物个性上缺点的展现和处理。 #proj-blog
这周对日常工作流中使用率占比相当重的 Raycast 进行了一些设置修改。 起因是 Raycast 订阅过期了,在订阅过期两周前收到邮件说现在续费就给 20% 优惠,但想了想没必要续费。Raycast 提供的 AI 功能我主要用来翻译,语法纠正和润色,chat 极少使用,尽管其启动成本和 chatGPT for mac 一样低。 学习双拼 chat 好办,直接切换到 chatGPT。可能是因为新鲜感,和 AI 聊天次数多了不少,突然萌生了应该提高自己打字速度以减少“使用 AI 解决问题”的心智启动成本和更强的“为 AI 提供充足上下文”的意愿。 说学就学,简单调查之后选择了小鹤双拼。想知道熟练使用双拼之后,打字速度能提升多少,所以还做了个全拼和双拼的速度测试对比。(测试地址 https://dazi.kukuw.com)  现在看起来惨不忍睹,双拼一分钟只能打 18 个字,希望两周后能和全拼差不多。 社区插件代替订阅 但「用预设 prompt 处理选中的文本后再填充到输入框」这活儿依然是 Raycast 最快。调查了一下发现可以用 Deepseek Quick Actions 和 Google Gemini 社区插件填自己的 key 来代替。 尝试了一下发现尽管 Gemini 的 Key 有免费版可以使用,且速度极快但失败率实在太高了。而 deepseek v3 速度虽然有点慢(和 raycast AI 差不多但不如 Gemini),但稳定且便宜,几天用了一百来次不过 2 毛钱。 产出 用 Alex for Xcode 以 vibe coding 的方式开启了一个 side project,非常好用!后面有空单独写一下。 ...
这周主要工作在重构上。之前有两个高度重合模块需求出来的时间间隔有点大,且过程中产品和开发沟通不足,导致两个模块实现过程中产生了不少冗余代码。 这种时候 code diff / PR review 经常发现,core contributor 们在重构议题上有很强的「技术卓越」倾向,同时当可扩展性和可维护性两个词搬出来时,很难从技术角度说是错的,然后大家陷入一轮又一轮的争论。 考虑到这两个特质在复杂业务项目中实现的成本,以及过往太多实现了高可复用模块但并未发挥作用的经历。个人感觉其实更好的做法先放下技术人视角,和干系人(老板)沟通,确认真实的验收标准,严格执行,交付,然后开始进入下一个任务。 把这个反馈循环牢记于心,一方面可以节约大量不必要的讨论精力和实现成本,另一方面也可以避免出现明明花费了大量时间精力,但老板不认可成果的情况出现。
近半年都在进行 redesign 相关的工作,除了 UI 从 UIKit 切换到 SwiftUI,还有网络层的切换,从 restful 切换到 GraphQL。因为六月份就要上线,现在就开始进行后端联调及各种功能的集成。即使团队已经很“敏捷”,有各种沟通对齐的会议,但到了这种时候也会发现有很多可以改进的事项: 跨功能模块的需求,因为沟通问题,到集成的时候才发现没有人负责 完成较快的模块,团队成员出现空转,等着集成,但集成的时候又发现其实有功能缺失 个人认为是因为很多团队成员都在远程办公导致线上对齐会议参与度不高造成的,但感觉很难让大家都在会议中全程投入精力去了解别人在干什么,一般都更新完自己的就,就开始做其他事情了。 产出 和设计师朋友喵喵聊了聊自己想到的几个 side project 的主意,其中一个被选中了。对方很快就做出了设计稿,希望可以在闲暇时间做一下试试看。 娱乐 《塞尔达:王国之泪》 通勤路地铁里就会打开玩一玩,40 分钟逛几个神庙探索一小块地区就会觉得很开心。 《搏击俱乐部》 ⭐️ ⭐️ ⭐️ ⭐️ ⭐️ 时隔数年再看一次,还是很喜欢。比如片尾插入的几帧 nice big cock 这个事儿,就感觉很酷。但以前主要是看像狮子一样的布拉德·皮特,现在是看爱德华·诺顿的表演。 《阳光灿烂的日子》 ⭐️ ⭐️ ⭐️ ⭐️ ⭐️ 小时候看觉得大院儿生活也太棒了,现在看感觉很燥热,而且发现姜文拍片很喜欢同一个事情给很多重复镜头,比如夏雨拿着望远镜转圈,在屋顶来回爬。在《让子弹飞》里也是,让马车拉着枪来回跑,重复镜头很多很多,个人感觉会容易累。不过宁静依然和记忆中一样好看。 《诡才之道》 ⭐️ ⭐️ 题材相当好,从鬼的视角来讲如何吓人的。比如闹鬼的时候,鬼是如何让灯光不停闪烁,是如何让人打不开原本可以打开的门的。但当设定讲完了之后,导演就想讲个青春期女生在鬼友帮助下如何成长的励志故事了,一下落得相当俗套。
本周工作产出主要是准备 showcase 及修复 iOS 15 UIHostingViewController 在 UINavigationController 层级下可能会出现 navigation bar 无法隐藏的问题。 输入 《盲人钟表匠》 当人们走在路上如果看到一块构造奇怪的石头,无论其构造如何诡异,依然会有概率相信这样一块石头是自然产物。但如果在路上捡到了一块钟表,则极难让人相信,这是自然产物,原因在于钟表的复杂性。那么相比起身体构造,钟表的精细程度显然不值一提,也就很难相信人是自然产物,而不是神刻意制造出来的。 《盲人钟表匠》 这本书就是讲进化论的自然选择,是如何反驳这个在达尔文出现之前,最有影响力的支持”上帝存在“的论证——「设计论证」。 娱乐 《辐射》 ⭐️ ⭐️ ⭐️ ⭐️ 剧情一般,没能把各种避难所的荒诞以及地面各势力的斗争体完全体现出来。但场景道具服装还原极佳!再玩一次辐射 4 是不可能了,但很期待新辐射。 《苦尽柑来遇见你》 本来对韩剧不太感兴趣,但时间线上看到太多人说好,开始看看。