为了让 AI 写代码更稳,我们得忍受更难学的库吗
很多团队在推 AI 编程的时候,最头疼的不是 AI 写不出来,而是 AI 写出来的东西看着没问题,跑起来全是坑。我最近在思考一个很诡异的现象:有些库对人类来说学习曲线极陡,但 AI 极其擅长调用。这导致一个局面——如果一个库能让 Claude Code 或 Kiro 写得更可靠,即便它让开发者痛苦,我们是否也应该在项目选型时优先考虑它?
这种逻辑在 Effect 这个库身上体现得最明显。它号称是 AI 时代的可靠 TypeScript 方案。在传统的异步函数里,成功类型是明确的,但失败行为通常藏在注释里,或者干脆靠开发者的经验(Tribal Knowledge)去猜。而 Effect 把错误直接塞进了类型通道。
举个具体的例子,如果你在项目里定义了多种错误类型:
import { Data, Effect } from 'effect'
export class NotFoundError extends Data.TaggedError('NotFoundError') {}
export class RateLimitError extends Data.TaggedError('RateLimitError') {}
export class NetworkError extends Data.TaggedError('NetworkError') {}
当你写一个加载用户信息的函数时,Effect 强制你处理这些错误:
export const loadProfile = (scenario: Scenario) =>
Effect.gen(function* () {
if (scenario === 'not-found') {
return yield* new NotFoundError({ handle: 'agent-editor' })
}
if (scenario === 'rate-limited') {
return yield* new RateLimitError({ retryAfterSeconds: 30 })
}
if (scenario === 'offline') {
return yield* new NetworkError({ reason: 'The demo API is offline.' })
}
return profile
})
这时候最关键的细节来了:UI 层在处理错误时,如果 AI 在后端逻辑里偷偷加了一个 MaintenanceError 却忘了更新前端,assertNever 这种类型检查会直接在编译阶段把这个漏洞给揪出来。
整个反馈链路变成了:AI 修改程序 → Effect 更新类型通道 → TypeScript 扫描所有 UI 分支 → 发现缺失 → AI 立即修复。
这种闭环让 AI 的输出变得极其确定,但代价是,团队里如果不熟悉函数式编程的人,看到这种代码简直像在看天书。
类似的情况也发生在样式管理上,比如 StyleX。传统的 CSS 全局选择器是 AI 最容易搞混的地方,经常出现改了 A 页面结果 B 页面样式崩了的情况。StyleX 把样式定义在了一个强类型的 JS API 后面:
const styles = stylex.create({
result: {
borderRadius: '8px',
padding: '16px',
},
})
因为有了类型约束,AI 在写样式时不再是随缘地猜测类名,而是像调用接口一样调用样式。编译阶段就能拦截掉大部分低级错误,不用等到页面渲染出来才发现不对。
但在公司内部推行这种方案时,我发现了一个很矛盾的点:AI 确实把开发效率拉高了,但它同时也建立了一道“认知墙”。现在的状态是,AI 对这套技术栈的理解程度可能远超维护它的开发者。如果有一天 AI 没在身边,或者生成的代码出了一个极其隐蔽的逻辑 Bug,人类维护者可能需要花三倍的时间才能读懂这段代码在干什么。
我觉得未来的趋势可能是,我们会为了“AI 可维护性”而牺牲一定的“人类可读性”。如果一个库能给 AI 提供更精准的信号(比如强类型错误通道、确定的 API 边界),那么即便它需要开发者花一个月去啃文档,在公司规模化交付面前,这种交换也是划算的。因为能被编译器拦截的错误,比在生产环境被用户反馈的 Bug 成本低得多。
谁想花三个小时写 Prompt 适配库啊?赶紧给我来个能直接跑通的!
与其在 Prompt 里死磕怎么让 AI 听话,我宁愿花时间啃那个难搞的库