Issue #150

AI 想放弃了,人没有

Cover for Weekly Issue 150

Photo by Or Hakim on Unsplash

最近,Linus Torvalds 在调试一个 Intel Xe GPU 驱动问题时,经历了一场被他自己称为“debug session from hell”的漫长排查。最终的修复简单得有些不可思议:把一处 round_up() 改成 round_down()。但为了找到这一行代码,他前后添加了 24 个调试 patch,启动了 18 次 kernel。其中大量繁琐工作,都是在 AI 的帮助下完成的。

这个故事最有意思的地方并不是“AI 帮 Linus 修复了 Linux Kernel Bug”,而是 AI 在过程中数次想要放弃。它曾明确告诉 Linus,这个问题“impossible and unsolvable”,建议停止继续调查。Linus 没有接受这个判断。在他的坚持下,AI 虽然数次认为问题已经无法解决,却仍然忠实地执行新的任务,最终和他一起找到了那个只需要修改一行代码的原因。

这其实很好地展现了现阶段人与 AI 之间一种颇为微妙的关系。随着 Agent 能力不断增强,我们已经可以把越来越完整的工作交给 AI:阅读代码、提出假设、编写调试工具、执行验证,甚至根据新的结果不断调整下一步行动。过去需要开发者亲自完成的大量重复劳动正在被压缩,人也因此逐渐从具体的执行过程中抽离出来。

但这并不意味着人的作用正在以同样的速度缩小。恰恰相反,当 AI 开始参与分析、提出建议,甚至给出“这个问题无法解决”这样的判断时,人真正需要承担的职责反而变得更加清晰:决定什么值得做,判断什么时候应该相信 AI,又在什么时候拒绝它的结论。

尽管并非所有人类的坚持都会获得类似本次的圆满结果,但有时候,再坚持一下的理由,至少不应该被 AI 的一句“不可能”轻易抹去。

原创

从使用 AI 到委托 AI:我的一些思考

当一项工作已经有明确目标、边界和验收要求时,怎样把它真正交给 AI?Agent 能完成的工作越复杂,这个问题就越突出。模型的输出存在波动;上下文变长后,目标和规则可能逐渐淡化;拆进多个上下文,又会带来信息损失和交接偏移。让另一个模型复核,也不意味着结果一定会自然收敛。这些问题最终指向同一个词:可委托性。

本文是我对 AI 可委托性的一些思考:执行范围是否稳定,结果能否被信任,投入是否可以预期,以及什么时候需要人介入。相比追求某一次执行的最好结果,我更关心如何通过明确边界、验收标准、外置的权威记录以及合理的人机分工,让 Agent 在更长、更复杂的任务中保持稳定,并让失败能够被发现和纠正。文章最后也结合我目前使用的 Task-Driven 工作流,展示这些原则如何落实到实际的 AI 开发过程中。

近期推荐

认识 Swift 包注册表 (What is a package registry?)

Swift Package Index 加入 Apple 后,双方宣布将共同建设一个面向 Swift 社区的 package registry。但 package registry 与我们已经使用多年的 SwiftPM,以及用于发现和评估包的 Package Index,究竟有什么区别?⁠Dave Verwer 从 SwiftPM 当前基于 Git 的依赖方式讲起:传统依赖需要从 Git 仓库获取源码并 checkout 对应版本,而 registry 可以通过 package ID 直接分发已经发布的源码 archive,无需携带 Git history,同时发布后的版本也具有不可变性。

不过,registry 的意义并不只是让 package 下载变得更轻量。更重要的是,registry 还引入了一套正式的 package publishing 模型,并进一步涉及开发者身份、package scope 所有权、版本发布以及软件供应链安全等问题。这篇文章既是一篇对 Package Registry 工作方式的简明介绍,也为理解 Apple 与 Swift Package Index 接下来准备建设的 Swift 包生态基础设施提供了很好的背景。


如何正确处理 CoreBluetooth 超时与 Task Cancellation

withCheckedThrowingContinuation 将 CoreBluetooth 的 delegate API 封装成 async/await 并不困难,真正麻烦的是之后的异常路径:如果 callback 迟迟没有返回怎么办?Task 被取消后,底层蓝牙操作是否仍在继续?当正常结果、超时和取消几乎同时发生时,又该由谁来 resume continuation?

ilawsonlu 围绕这些实际问题,介绍了如何为 CoreBluetooth 的异步封装建立更完整的 timeout 与 cancellation 机制,并明确区分「取消 Swift Task」与「取消底层操作」,同时通过开源库 ArcBLEKit 展示了将传统 delegate API 封装成更健壮的 Swift Concurrency API 的思路。


详解 CloudKit:Apple 生态的后端服务 (What Is CloudKit? Apple’s Backend Explained)

CloudKit 是 Apple 生态中非常重要、却常常被低估的一块基础设施。从简单的跨设备数据同步,到共享数据和公共数据库,它让开发者无需自行搭建服务器,就能依托 iCloud 为 App 提供一套与 Apple 平台深度集成的后端能力。尤其随着 SwiftData 和 Core Data 都能够直接接入 CloudKit,许多开发者实际上已经在使用它,只是不一定需要直接面对 CloudKit API。

Sean Allen 从 backend 的基本需求出发,系统介绍了 CloudKit 的 private、shared 和 public database,以及 Container、Record、Schema 等核心概念,并比较了 SwiftData、Core Data 和直接使用 CloudKit API 三种接入方式。文章并没有回避它的边界,包括对 Apple 生态和 iCloud 的依赖、schema migration、跨平台能力以及复杂服务端逻辑的限制。


重新认识 OCR:它是空间地图,而非纯文本 (OCR Doesn’t Give You Text. It Gives You a Map)

Vision OCR 返回的并不是一段已经组织好的文本,而是一组带有 bounding box 的 observations:数组顺序不代表阅读顺序、单词边界并不存在,字段之间的关系也不能简单通过前后位置判断。⁠Wesley Matlock 在开发唱片封套扫描功能时,一天内连续遇到了四个看似不同、实则来自同一错误假设的 Bug。本文通过这些真实案例展示了如何利用坐标计算阅读顺序、根据间距恢复单词边界,并通过空间邻近关系关联字段。更值得借鉴的是作者的测试方式:将真实图片暴露出的 bounding box 保存为 fixture,用纯几何数据固定每一项布局假设,同时保留真实照片作为端到端测试。正如标题所说,OCR 给你的不是文本,而是一张「地图」,真正的文本结构需要从空间关系中重新构建。


独立应用零成本推广的 6 个策略 (6 ways to promote your app without spending a penny)

对于独立开发者来说,写完 App 往往只是第一步,如何让更多人知道它可能更加困难。由 ⁠Paul Hudson 创建的 Kickstart 在这篇文章中整理了六种几乎不需要资金投入的推广方式:向 Indie App Showcase 等渠道投稿、通过 Kickstart Exchange 与其他独立开发者交叉推广、参与目标用户所在的社区、建立自己的邮件列表、Build in Public,以及持续优化 App Store 产品页面。

另外,MacStories 的 Federico Viticci 正在为年度 iOS 27 Review 寻找值得关注的新 App 和 App 更新。如果你正在准备 iOS 27 版本,可以通过 DM 或邮件 viticci@macstories.net 向他推荐自己的作品。 ⁠

工具

Amethyst Vein:跨平台、SwiftData 风格 API 的开源本地持久化框架

Mia Koring 开发的 Amethyst Vein 是一个本地优先的 Swift ORM,采用 SQLite 与 SQLCipher 作为存储基础,API 则明显借鉴了 SwiftData。它试图把 SwiftData 风格的 @Model、@Query、关系和迁移 API 带到 Apple、Linux、Android 与 Windows。项目采用显式版本化迁移、Identity Map 和字段级同步,并同时支持 SwiftUI 与 SwiftCrossUI。


DynamicNotch:帮助开发者为 macOS 构建精致的刘海与屏幕边缘交互

Govi 开发的 DynamicNotch 是一个专为开发者打造的 macOS Swift Package,用于创建贴附于屏幕边缘的 SwiftUI 界面,可呈现录音状态、媒体控制、构建进度、操作确认,以及类似 Dynamic Island 的紧凑视图。

它能妥善处理安全区域、多显示器和 MacBook 实体刘海,支持上下左右四个方向,也可以在紧凑与展开状态之间切换。DynamicNotch 的实现比较克制,只负责几何、裁剪、定位与窗口呈现,并未将手势、通知、状态管理等产品逻辑强加给使用者。


SwiftTUI:用 SwiftUI 的方式构建终端界面

Adam Zethraeus 开发的 SwiftTUI 是一个面向 Swift 开发者的终端用户界面框架。它将 SwiftUI 的声明式编程模型带进终端:开发者可以使用 View@State@Observable、布局容器、焦点、手势与动画构建交互界面,由框架负责布局、输入处理和局部刷新。

SwiftTUI 的有趣之处,不只是“用 Swift 写 TUI”。同一套视图代码还可以运行于 macOS、Linux 和 Windows 终端,并进一步部署到浏览器、WASI,以及原生 SwiftUI 容器;官网提供的计数器就是一个真实的 SwiftTUI 应用,经 WebAssembly 编译后直接运行在网页中。

相关周报

订阅 Fatbobman 周报

每周精选 Swift 与 SwiftUI 开发技巧,加入众多开发者的行列。

立即订阅