Coding Agent 正在改变我们编写软件的方式,也在悄悄重塑我们评价框架与工具的标准。
随着 AI Coding 的普及,不少人开始倾向一种观点:UIKit 这样的命令式框架,可能比 SwiftUI 更适合 Coding Agent。理由很直观——UIKit 的逻辑直接明确:创建对象、设置属性、加入层级、建立约束,每一步都有具体操作的实体;而 SwiftUI 把大量实现细节收束在声明式语法之后,状态、环境、身份、布局与渲染共同决定了最终结果。一旦呈现效果偏离预期,Agent 只能对着黑盒,从有限的外部现象去反推内部究竟发生了什么。
由此得出的结论似乎很顺理成章:AI 更擅长处理贴近实现细节的底层 API,而非高度抽象的框架。
但我认为,问题其实并不在抽象本身,而在于抽象之后我们漏掉了另一半工作:观察与验证。当抽象隐藏了底层细节,我们必须在新的层级上,补齐能够固定并验证意图的手段。
AI 真的更喜欢 UIKit 吗?
假设我们需要根据登录状态切换界面。SwiftUI 可以非常直接地表达这一意图:
if session.isAuthenticated {
ContentView()
} else {
LoginView()
}
开发者描述的是希望得到什么,而不是达成这一结果所需的具体操作。
在命令式 UI 框架中,实现同样的需求,往往需要开发者自行管理视图或控制器的创建、替换与生命周期,并显式响应状态变化。
对 Coding Agent 而言,命令式代码并不天然更简单。只是 UIKit 里的 UIView、frame、约束、视图层级和 CALayer 都是具体的实体对象,一旦出了问题,排查和干预的手段相当丰富。
而在 SwiftUI 中,一段声明大致会经历以下环节(概念示意,并非严格的执行顺序):
View Declaration
↓
State / Observation
↓
Environment
↓
Identity
↓
Transaction
↓
Layout
↓
Rendering
SwiftUI 将开发者从这些细节中解放了出来。代价在于,在 SwiftUI 当前的抽象层级上,我们并不总能获得足够透明的运行时信息。底层信息一旦不再可见,原先建立在底层之上的观察和验证手段也就跟着失效了。
我们常说抽象是为了“隐藏复杂度”,但这其实不是抽象的本质。抽象真正做的,是让我们能够在更高的语义层级上理解、表达和操作问题。隐藏了底层实现之后,可观察性与可验证性也必须在新的抽象层上重新建立。
这并不是 AI 出现之后才有的困境,只是 Coding Agent 把它放大了。“UIKit 更适合 Agent”的说法在当下并非全无道理,它确实反映了 SwiftUI 在验证手段上的不足,但把账直接算在“抽象”头上,并不公允。
AI 需要稳定的模型
SwiftUI 的修饰符顺序(modifier order)是个很好的切入点。
初接触 SwiftUI 时,很多开发者会把修饰符顺序理解为零散的经验规则:这个必须放前面,那个只能放后面,一旦调换顺序效果全变。如果最终沉淀下来的只是几十条死记硬背的规则,那么无论是人还是 Agent,都会陷入疲于应对特例的泥潭。
但如果继续往里看一层,一部分修饰符顺序其实可以还原为变换顺序(transformation order),并借助矩阵组合来理解。
在 Modifier Order Is Matrix Order 一文中,Mihaela Mihaljević Jakić 从矩阵变换的角度,重新解释了 offset、rotationEffect 和 scaleEffect 的组合顺序:最靠近视图的修饰符最先作用于内容,这与 Core Graphics 中的矩阵组合规律完全一致,只是阅读方向相反。看似零散的经验法则,由此变成了一套能够推导的规则体系。
大量经验规则
↓
变换模型(Transformation Model)
↓
可推导的结果
这正是构建 AI 友好型抽象的关键一步:不是去拉低抽象层级,而是让抽象本身形成清晰、稳定、尽可能可推导的语义模型。Agent 记住规则并不难,但一个能够严密推导的模型,远比塞满上下文的特例经验更可靠。
不过,推导模型只能告诉 Agent 事情“应该”如何运作,关键在于 Agent 该如何确认自己真正做对了。
Mihaela 的文章本身就给出了答案的雏形。她没有停留在矩阵推导上,而是用 ImageRenderer 实际渲染了多组修饰符链,逐像素测量输出并比对理论值。正是这种实测比对,揪出了代数模型漏掉的一条隐性规则:offset 会提前把偏移量对齐到像素网格,而后续的 scaleEffect 会顺带把这个舍入误差一并放大。这种微小的视觉偏差,单纯凭肉眼或理论推理几乎察觉不到。推导模型给出了预期,而末端的实测验证,才真正把理论外的盲区暴露了出来。
从概率判断到确定性证据
通过文档清晰描述模型,已经能帮 Agent 更好地推理。但要确认实现是否符合预期,我们还需要把模型与可执行的检查连接起来。
如果验证过程依然完全交给另一个概率模型,无非是用新的不确定性去背书旧的不确定性。对 Coding Agent 来说,稀缺的不是又一次概率推测,而是能对具体问题给出确定回答的客观证据。这些证据未必能证明整个系统的终极正确,但至少能让一部分代码不再停留在“看起来好像没问题”。
传统的编译器、校验器、单元测试与快照,正是这套流程里的确定性锚点。
这些工具验证的层次并不相同。编译器与静态校验器检查的是规则契约:API 是否合法、依赖关系是否成立;测试与快照则是在声明期望的结果,固定我们对意图的具体表达。比如“根据登录状态切换界面”落实为测试用例,就是未登录时断言登录页,登录后断言内容页,退出后回到登录页。有了这些明确期望,Agent 才有逐项核对的依据。
规则需要提炼,期望需要明确写下,这些都不是工具能凭空替我们决定的。但只要表达清楚,工具就能在覆盖范围内,精确指出实现是否发生了偏离。意图因业务而异,只能由人来定义;规则却往往通用,可以沉淀复用。因此,比起无休止地往 Prompt 里塞知识,更长远的路径是把通用知识固化为可执行的工具。
从 Knowledge 到 Tool
SwiftFairy 是一个很有代表性的尝试。
它没有试图把大量 SwiftUI 避坑指南全塞进 Agent 的上下文,而是把这些经验组织在外部工具中:工具在本地静态解析代码与声明,构建局部引用图,再去匹配声明式的问题模式,最后把发现、解释和修复方案返回给 Agent。
这一检查过程完全脱离了 LLM。在相同的代码上下文下,检查结果是可重复、确定性的。专家知识由此变成了可调用的评估器(evaluator),Agent 不必靠硬记规则来保证代码质量,它可以在生成后调用工具获取具体反馈,再按指导进行修正。更重要的是,SwiftFairy 并没有要求开发者退回 UIKit,它是在 SwiftUI 自身的语义层级上去做结构性校验。
InnoDI 则是另一个维度的例子。作为 Swift 依赖注入框架,它的设计在 AI 时代展现出了独特的价值。
与 Point-Free 的 swift-dependencies 这种依靠上下文隐式传播的方案相比,InnoDI 初看甚至略显繁琐:
@DIContainer
struct AppContainer {
@Input var baseURL: String
@Provide(.shared, APIClient.self, with: [\Self.baseURL])
var apiClient: APIClient
}
它把手工的多层 initializer 装配,抽象成了对依赖图(dependency graph)的显式声明。对人类开发者来说,这套 DSL 未必比直接手写构造器直观,也带来了额外的理解成本。
但它的价值恰恰在于构建了闭环的验证能力:宏展开时检查局部错误,构建插件在编译前校验跨文件的依赖图,命令行工具则负责全局分析。实现细节被抽象掉的同时,验证能力在新的抽象层上重新建立了闭环。
配合配套的 Agent Skill,Agent 可以按需查找 API 规则,宏与构建插件则为生成结果提供确定性的编译反馈。对 Agent 而言,一个抽象好不好用,不仅在于写起来是否简短,更在于关系清不清晰、约束能不能被机器检查,以及出错时能否给出明确的诊断。
抽象与验证应该共同上移
回到 UIKit 与 SwiftUI 的对比。
SwiftUI 当前面临的痛点,很大程度上在于抽象不断上移,与之匹配的观察和验证手段却没有同步跟上。当结果偏离预期时,使用者很容易陷入面对黑盒的无力感。
如果两者能够协同上移,局面就会完全不同。
SwiftUI 不需要退回 UIKit。它需要的,是属于自身层级的检查、诊断与验证能力。Self._printChanges()、Xcode 中的 SwiftUI Instrument 都在朝这个方向努力,但距离一套能被 Agent 直接调度、输出结构化反馈的工具链,依然有不小的距离。
因此,要判断一个框架或工具是否对 AI 友好,核心或许在于这几个过去不太被强调的维度:
- 是否具备稳定、可推导的语义模型;
- 是否提供了与抽象层级相匹配的可观察性;
- 它的关键规则与约束能否被确定性工具验证。
当框架的使用者不再只是人
过去几十年,框架与 API 的设计默认是面向人类开发者的。developer ergonomics 关注的是直觉、简洁、低心智负担和顺畅的学习曲线。
这些标准依然重要。但当 Coding Agent 逐渐成为代码的重要编写者与维护者,我们势必要引入新的权衡维度:Agent ergonomics。
两者并不一定冲突。只是在某些场景下,为了换取全局的可验证性与确定性,我们可能需要让渡一部分传统开发中“随手写”的随意性;而这种向严谨结构妥协的成本,在 Agent 介入之后,往往能被自动化工具大幅摊平。
清晰的语义、稳定的模型、强类型、准确的诊断与确定性的校验,本就是优秀软件工程一贯追求的品质。AI 的到来,只是赋予了它们更紧迫的现实意义。
BTW:不妨检查一下你正在使用或编写的 Skill。如果它的主要价值只是向模型补充公网已有的通用知识,那么随着底模能力的增强,这部分价值会迅速贬值;真正难以替代的,始终是项目特有的上下文约束与决策逻辑。
Skill 里的文档,更应该充当面向 LLM 的“胶水语言”:它不只是灌输知识,而是引导模型去找到并调用正确的工具,把人的意图连接到可以被观察、验证和修正的闭环反馈中。更难被模型能力取代的 Skill,往往在于它如何将具体的约束,扎实地接入 Tool 与 Feedback Loop 之中。