$catMANUAL||~26 分钟

AI 编程工具越来越强,但为什么我还是觉得难用?

advertisement

上个月我在 HN 上看到一条 81 分的帖子,标题叫 "Good Tools Are Invisible"。作者说好的工具应该是透明的——你用锤子钉钉子的时候不会想着锤子的设计哲学,你只会想着钉子钉进去了没有。

看完这条帖子我愣了好一会儿。因为我突然意识到,我现在用的 AI 编程工具,没有一个做到了"隐形"。

它们越来越聪明,能写更复杂的代码,能处理更大的项目,能自己修 bug、跑测试、提 PR。但你跟它们打交道的时候,那种"哎呀这玩意儿怎么这么难伺候"的感觉反而越来越强了。

今天想聊聊这件事。不是什么深刻的技术分析,就是一个用了半年多 AI 编程工具的普通开发者的一点碎碎念。

先说个翻车现场

上周我在搞一个 Next.js 项目,需要用 Cursor 改一个页面的布局。项目不大,前后就三个组件。我以为十几分钟就能搞定。

结果折腾了两个多小时。

问题是这样的:我给了 Cursor 一个很清晰的指令——"把侧边栏从固定宽度改成响应式,在小屏上折叠成汉堡菜单"。它确实改了,代码看起来也没问题。但我一跑起来,发现汉堡菜单的点击事件根本没绑定上。

我去看了它生成的代码,发现它改了 UI 组件,但忘了改事件处理的逻辑。我问它"汉堡菜单为什么点不动",它说"让我看看",然后改了一行代码。还是不行。我又问,它又改了一行。第三次还是不行。

第四次我直接去翻它改了什么,发现它改了一个根本不存在的函数。

最后我自己花了五分钟修好了。

这个过程不是第一次发生了。用 Claude Code 的时候也遇到过类似的情况——它能写出漂亮的代码,但经常忽略项目里已有的约定。用 Copilot 的时候也有过,它给你补的全是错的导入。

工具变强了,但"跟它沟通的成本"也在变高。

问题到底出在哪

我觉得核心矛盾是:AI 编程工具的能力增长太快,但交互范式没跟上。

什么意思呢?

现在的 AI 编程工具大概有三种形态:

第一种是 IDE 里的补全,比如 GitHub Copilot。你敲代码的时候它给你猜下一个词是什么。这个是最简单的,因为交互方式跟你平时写代码一模一样。你不需要学新东西,只需要习惯它的猜测准不准。

第二种是对话式编程,比如 Cursor 的 Composer 模式、Claude Code 的终端对话。你告诉它你要什么,它给你改代码或者生成文件。这个就复杂多了,因为你得学会"怎么跟 AI 说话"。指令写得好,它给你的是好东西。指令写得模糊,它给你的就是一堆需要你二次修改的半成品。

第三种是 Agent 模式,比如 OpenAI Codex、Cline、Aider。你给它一个任务,它自己去读代码、改文件、跑测试、提 PR,全程不用你管。这个听起来最酷,但也是目前最不靠谱的。

我基本上三种都用过,而且大部分时间都在用第三种。因为我想省事啊。但现实是,Agent 模式省下来的时间,经常不够我用来审查它干的活。

这里面有个很有意思的现象:工具越强大,你需要投入的精力反而越多。

Copilot 你只要打开 VS Code 就行,几乎零学习成本。Claude Code 你得学会写 CLAUDE.md,得知道怎么配置 MCP 服务器,得理解它的上下文窗口是怎么工作的。Cline 更夸张,你得装 Docker,得配 API key,还得搞明白 sandbox 是怎么回事。

每个工具都说自己"开箱即用"。但开箱之后你会发现,要想让它真正好用,你得花好几个小时做配置、调参数、写规则。

我踩过的几个坑

坑一:CLAUDE.md 写得越多,Claude Code 越笨

我第一次用 Claude Code 的时候,看到教程说"写一个 CLAUDE.md 告诉它项目规范"。我觉得这个想法不错,就写了一个长长的文件,里面包含了代码风格、目录结构、测试要求、命名规范,大概三百多行。

结果呢?Claude Code 每次启动都要读这个文件,上下文窗口被占了一半。它有时候会记住某个奇怪的命名规范,但会忘记我刚在上一行写的需求。

后来我精简到了二十行,只保留最核心的三条规则,效果反而好了很多。

教训是:给 AI 的规则不是越多越好,是越精越好。 你给它一百条规则,它可能一条都执行不好。你给它三条最重要的,它反而能做好。

坑二:MCP 服务器配置得像在搭乐高

MCP(Model Context Protocol)这个概念本身挺好的——让 AI 工具能调用外部工具。但你真要配置起来,会发现它的设计有点反人类。

比如你要让 Claude Code 能访问你的数据库,你得:

  1. 装一个 MCP 服务器
  2. 写配置文件
  3. 在 Claude Code 的配置里指向这个服务器
  4. 如果服务器挂了,Claude Code 会默默失败,不会告诉你

最离谱的是,MCP 服务器的配置格式每个工具都不一样。Claude Code 用 JSON,Cline 用 YAML,Cursor 有自己的格式。你换个工具就得重新配一遍。

我有一次为了接一个自定义工具,折腾了两个小时。最后发现只是配置文件里少了一个引号。

坑三:sandbox 是个好想法,但实现得很粗糙

OpenAI Codex 和 Cline 都支持 sandbox 模式,就是让 AI 在一个隔离的环境里跑代码。这个想法很好——至少你的本地环境不会被搞乱。

但实际用起来问题一堆。sandbox 里的环境跟你本地的不一样,依赖版本对不上,环境变量没设对。我在 sandbox 里跑测试,本地能过的用例它报错了。反过来也一样。

最无语的是,sandbox 的启动速度很慢。每次让 AI 跑测试之前都要等一两分钟启动环境。对于一个本来想提速的工具来说,这反而拖慢了节奏。

坑四:AI 生成的代码质量很高,但代码质量不代表代码正确

这是我最深刻的教训。有一次我在做一个 API 接口,让 Claude Code 帮我写了一个完整的 CRUD 服务。代码写得漂亮极了——类型安全、错误处理、日志记录,一应俱全。我看了都觉得"这比我写得好"。

然后我跑了测试。全部通过。

然后我实际调了一下 API。发现它把用户 ID 的类型搞错了——数据库里是 string,它写成了 integer。测试没覆盖到这个点,因为测试数据是我自己造的,我用的就是 integer。

这个bug我找了半天才找到。不是因为代码难读,恰恰是因为代码太干净了,干净到让我放松了警惕。

教训是:AI 生成的代码,不管看起来多漂亮,你都得逐行 review。 这不是不信任它,而是信任的代价太高了。

坑五:上下文窗口不是越大越好

很多人觉得上下文窗口大是好事——能塞进更多信息嘛。但实际用起来我发现,窗口太大反而有问题。

比如你有一个 50 万 token 上下文窗口的模型,然后把整个项目的代码都塞进去。模型确实"看到"了所有代码,但它不一定知道哪些是重要的。

我做过一个实验:同样一个需求,我用小上下文窗口(只塞入相关文件)和大上下文窗口(塞入整个项目)分别让 Claude Code 来做。结果小窗口版本的准确率反而更高——因为它关注的信息更集中,没有被大量无关代码干扰。

当然这个结论不一定适用于所有场景。但对于中小型项目来说,"精准投喂"比"全部塞进去"效果更好。

不同场景下的真实体验

光说问题不够具体,我来聊聊我在不同场景下用 AI 编程工具的真实感受。

场景一:写一个新功能

这是 AI 编程工具最擅长的场景。你给它一个清晰的需求描述,它能把大部分工作做完。

比如我之前做了一个用户权限系统。我只告诉它"需要 admin、editor、viewer 三种角色,admin 能管理用户,editor 能编辑内容,viewer 只能查看"。它生成了完整的角色定义、权限检查函数、中间件,还有配套的测试。

我花了大概十分钟 review 代码,改了几个小问题,然后就上线了。整个过程比我从零手写快了三四倍。

这种情况下 AI 工具确实好用。因为它做的事情是"生成",而生成正是 AI 最擅长的事。

场景二:改一个现有功能

这个场景就没那么顺利了。改现有功能需要理解代码库的整体结构、模块之间的关系、历史的决策原因。而这些信息,AI 不一定知道。

举个例子:我有一个用户登录功能,用的是 JWT。后来我想改成 OAuth 2.0。我让 Claude Code 帮我改,它确实改了认证部分的代码,但没改到依赖认证的其他模块——比如缓存层、日志层、错误处理层。

最后我花了比预期多一倍的时间来修补它遗漏的部分。

结论:AI 工具适合从零生成,不适合大改现有代码。 小修小补还行,大范围重构的话,你自己动手可能更快。

场景三:Debug

这个场景最让人纠结。好的时候它确实能帮你快速定位问题,不好的时候它会把你的问题理解偏然后给你一个完全无关的答案。

我有一次遇到了一个 React 组件的渲染问题。组件在开发环境下正常工作,但生产环境下会闪烁。我跟 Claude Code 描述了问题,它首先怀疑是状态更新的问题,给我改了几行代码。我试了没用。它又说可能是 useEffect 的依赖项不对,又改了几行。还是没用。

最后我自己查了一下,发现是生产环境做了 tree-shaking,我把一个工具函数标记成了"unused",但实际上它是动态引用的。

Claude Code 给出的建议不能说完全错——状态更新和 useEffect 确实是常见的 React 问题。但它不知道我的项目结构,不知道 tree-shaking 的存在,所以它的建议对我来说没什么用。

场景四:写测试

这个场景出乎意料地好用。写测试本身就是一个"生成"任务——你给函数定义和输入输出,它生成对应的测试用例。

我之前给一个数据处理函数写测试,它一口气生成了边界情况、异常输入、正常流程、并发场景的测试用例。质量比我随便写的要高不少。

不过要注意一点:AI 生成的测试用例虽然覆盖面广,但有些测试场景可能是它"想象"出来的,不一定符合业务实际需求。所以测试写完之后,你还是得看一眼,确认测试的场景是有意义的。

为什么这些问题短期不会消失

说实话,我觉得这些问题不是 bug,是这个阶段的必然产物。

AI 编程工具现在处于一个尴尬的阶段:它们能做很多事,但还做不到"你说了就完事"。

原因有几个:

第一个是上下文窗口的问题。虽然现在的模型能处理百万级的 token,但在实际使用中,你不可能把整个代码库都塞进去。你得做筛选、做压缩、做 RAG。这些步骤本身就需要你投入精力去思考"什么信息是重要的"。

第二个是多文件修改的问题。写一个函数,AI 能搞定。改一个功能,涉及五个文件,AI 就容易出错。因为它不知道这些文件之间的关系——除非你把所有关系都告诉它。但告诉它的过程本身就很耗时。

第三个是工具链的碎片化。每个 AI 编程工具都有自己的配置方式、自己的协议、自己的生态。Cursor 有 Cursor 的 rules,Claude Code 有 CLAUDE.md,Cline 有自己的 MCP 配置。你没法一套配置走天下。

第四个是模型本身的不确定性。同样的指令,不同的模型可能给出完全不同的结果。同一个模型,同样的指令,两次运行的结果也可能不一样。这种不确定性让"可靠地使用 AI 编程工具"变得更加困难。

这三个(四个)问题叠加在一起,就是你感觉"工具越来越强,但用起来越来越累"的根本原因。

我能想到的几条实用建议

说完了问题,也说说我踩坑之后总结出的一些经验。不是什么高深的理论,就是实际用起来觉得好用的东西。

第一条:保持 CLAUDE.md 极简。 只写三条以内的核心规则。代码风格、目录结构、测试要求,挑最重要的写。其他的靠模型本身的常识就好。你给它太多约束,它反而会迷失。

第二条:大改动拆成小步骤。 不要一次性让 AI 改十个文件。先改一个,跑测试,确认没问题,再继续。虽然慢一点,但出了问题你知道是哪一步导致的。

第三条:定期清理 MCP 配置。 你装的那些 MCP 服务器,有多少是真正在用的?我之前装了七八个,最后发现常用的就两个。其他的不仅浪费配置时间,还会让 Claude Code 启动变慢。

第四条:给 AI 写注释。 这听起来很奇怪,但有用。在项目里加一些简单的注释,说明关键的设计决策和模块之间的关系。AI 读代码的时候能看到这些注释,理解会更准确。

第五条:接受"AI 不是万能的"这个事实。 这是最重要的一条。AI 编程工具确实能帮你提高效率,但它不会替代你思考。你还是要懂代码、懂架构、懂测试。不然你根本不知道它改的对不对。

第六条:为不同类型的任务选择合适的工具。 Copilot 适合补全代码,Claude Code 适合写新功能,Cline 适合跑测试和部署。不要指望一个工具解决所有问题。

第七条:保留你的"原始代码"备份。 AI 改代码之前,先 git commit 一下。这样如果它改坏了,你可以一键回退。这个习惯我用了半年,救了我无数次。

几款主流工具的 UX 对比

聊完了通用问题,我也说说我实际用过的几款工具的体验差异。每家都有各自的痛点,没有哪家是完美的。

Cursor

Cursor 最大的优势是"就在编辑器里"。你不需要切换窗口,不需要开终端,直接在 VS Code 的基础上加了一层 AI。这个体验是顺滑的。

但它的弱点也很明显。Composer 模式虽然能让你在多文件之间切换,但当你需要改的东西比较多的时候,它经常会改到你不该改的地方。我有一次让它改一个页面的样式,结果它顺手把我另一个页面的布局也给改了。

还有一个让我头疼的问题是 Cursor 的快捷键经常跟 VS Code 的冲突。特别是 Cmd+K 和 Cmd+L,你习惯了 VS Code 的操作,换了 Cursor 之后手指经常自己按错。

Claude Code

Claude Code 的优势是"聪明"。它理解代码的能力确实比 Copilot 强很多,你给它一个复杂的需求,它能给出相对准确的方案。

但它的配置过程真的很折磨人。CLAUDE.md 怎么写、MCP 服务器怎么配、context window 怎么管理,每一步都需要你花时间去摸索。而且这些配置不是一劳永逸的——项目结构一变,配置可能就得跟着改。

另外 Claude Code 的终端交互方式对新手不太友好。你得习惯在终端里打字跟它对话,这对习惯了图形界面的人来说有点别扭。

Cline

Cline 的亮点是"能自己跑"。你给它一个任务,它能自己读代码、改文件、跑测试、提交 git commit。这个自动化程度是目前最高的。

但代价就是你需要花大量时间 review 它干的活。因为它改的东西太多了,你不可能每一行都仔细看。最后往往是"大致看了一下就上线了",然后出问题再来修。

sandbox 也是个双刃剑。好处是不污染本地环境,坏处是环境不一致导致测试不可靠。

GitHub Copilot

Copilot 是最简单的,也是最弱的。简单到你几乎不需要学习成本,弱到你只能用来补全代码片段。

但它有个优点是"稳定"。你给同样的上下文,它基本每次都会给出相似的结果。不像 Claude Code 那样有时候聪明有时候犯蠢。

对于日常写代码来说,Copilot 的补全速度和质量其实已经够用了。你不需要让它帮你架构设计或者重构代码,它就是个聪明的自动补全。

一个稍微乐观一点的展望

虽然上面说了这么多问题,但我还是觉得 AI 编程工具的未来是好的。

原因很简单:现在的问题,是因为这个领域还在早期。

你看现在的 AI 编程工具,基本上还是在"教 AI 怎么干活"的阶段。你得写规则、配环境、调参数。这跟二十年前刚用 Git 的时候有点像——那时候你得背一堆命令,git reset --hardgit rebase -igit cherry-pick,每个参数都有微妙的区别。

现在大家用 Git 已经习以为常了,很少有人会觉得 Git 难用。不是因为 Git 变简单了,而是因为周围的工具和环境都适应了它。VS Code 内置了 Git 操作,GitHub 做了图形化封装,各种 GUI 工具把命令行包装成了按钮。

AI 编程工具也会走到这一步。也许不是现在,也许不是明年,但迟早会有一个时刻,你打开编辑器,AI 就已经在那里了,你不需要配置任何东西,它就知道你的项目结构、你的代码风格、你的测试框架。

到那个时候,"Good Tools Are Invisible"就不再是一句口号,而是现实。

我还注意到一个趋势:越来越多的工具开始互相兼容。比如 MCP 协议本身就是为了统一 AI 工具的外部接口。虽然现在的实现还很粗糙,但方向是对的。如果有一天所有 AI 编程工具都用同一套配置格式,那"开箱即用"才真正有意义。

另外我观察到一些新工具在 UX 设计上做了不少创新。比如有的工具开始用"渐进式披露"的思路——刚上手的时候只暴露最简单的功能,等你用熟了再解锁高级选项。这个思路挺好的,至少不会一上来就把用户吓跑。

还有一些工具开始做"项目模板",你创建一个新项目的时候,它会自动根据你的技术栈推荐合适的 AI 配置。虽然这些模板的质量参差不齐,但至少方向是对的——让用户不用从零开始配置。

最后说几句

这篇文章写到这里,我突然想到一个有意思的事情:我在写这段文字的时候,用的是普通的文本编辑器,没有 AI 辅助。写完之后我又用 Claude Code 帮我润色了一遍,它改了几个句子,把一些啰嗦的表达精简了。

改完之后我读了一遍,发现有些改动其实不太好——它把我原来有意为之的口语化表达给"修正"成了更正式的书面语。我最后还是把那些改动撤回了。

这件事让我意识到,AI 编程工具最好的状态可能不是"替你做",而是"辅助你做"。 它给你建议,你来做决定。它帮你省掉重复劳动,但不剥夺你的判断权。

这个状态现在还没完全到来,但我相信它在来的路上。

后面打算再折腾一下 AI 编程工具的自动化工作流,看看能不能把配置过程也简化掉。有啥问题评论区聊。

常见问题

Q: 那你现在还用 AI 编程工具吗?

用。当然用。虽然上面说了这么多问题,但我没有完全弃用任何一个工具。

只是用法变了。以前我什么都交给 AI 做,现在我更多是把 AI 当成一个"高级助手"——它帮我做重复性的工作,我做关键的决策。

比如写一个新的 API 接口,我会让 AI 生成基础代码,然后我自己加业务逻辑。跑测试的时候让 AI 帮我写测试用例,但测试数据我自己造。改 bug 的时候让 AI 先分析一下可能的原因,但最终的修复方案我自己定。

这样既能利用 AI 的效率,又能保证质量。

Q: 你觉得 AI 编程工具什么时候才能真正"好用"?

这个问题很难回答。我觉得"好用"是一个相对的概念——不同的人有不同的标准。

对我这种有几年开发经验的人来说,可能现在的工具已经够用了。但对于一个刚入门的开发者来说,这些工具可能还是太复杂了。

我估计至少还要两三年,等工具链成熟、配置标准化、模型更稳定之后,AI 编程工具才能真正做到"开箱即用"。

Q: 你有没有推荐的学习路线?

如果你刚开始接触 AI 编程工具,我建议从 Copilot 开始。它的学习成本最低,你只需要装个插件就能用。

等你觉得 Copilot 不够用了,再试试 Cursor 或者 Claude Code。这两个工具的功能更强,但配置也更复杂。

Cline 和 OpenAI Codex 适合有一定经验的人用,因为它们需要你理解 sandbox、MCP、git 工作流这些东西。

总之,别一上来就追求"全自动"。先让 AI 帮你写个小函数,感受一下它的水平,再慢慢扩展使用范围。

Q: 你觉得 AI 编程工具会影响程序员的工作吗?

会的。而且已经在影响了。

我注意到一个趋势:初级程序员花在"写代码"上的时间在减少,花在"审查 AI 生成的代码"上的时间在增加。这意味着编程的核心技能正在从"怎么写代码"转向"怎么判断代码写得好不好"。

这个转变对很多人来说可能不太适应。但我觉得这是一个好事——毕竟,判断代码质量的能力比写代码本身更重要。

Q: 你怎么看待"AI 会取代程序员"这个说法?

我觉得这种说法太夸张了。AI 确实能帮你写代码,但它不能帮你理解业务需求、设计系统架构、做技术选型。这些事情还是需要人来做的。

而且即使 AI 能写代码,它写的代码也需要人来维护。如果 AI 生成了一堆代码,但没有人理解这些代码在做什么,那出了问题谁来修?

所以我的判断是:AI 不会取代程序员,但会用 AI 的程序员会取代不会用 AI 的程序员。

Q: 有没有什么具体的配置技巧能让 AI 编程工具更好用?

有的。我在实践中摸索出几个比较实用的技巧。

第一个是写一个"项目说明书"。就是一个简短的文档,说明这个项目用了什么技术栈、目录结构是什么样的、有什么需要注意的坑。把这个文件放在项目根目录,让 AI 工具在每次对话之前先读它。

比如我现在的 Next.js 项目里有一个 PROJECT.md:

markdown
1
# 项目说明
2
 
3
## 技术栈
4
- Next.js 14 (App Router)
5
- TypeScript
6
- Tailwind CSS
7
- Prisma ORM
8
- PostgreSQL
9
 
10
## 目录结构
11
- src/app/ — 页面组件
12
- src/components/ — 可复用组件
13
- src/lib/ — 工具函数和数据库连接
14
- src/types/ — TypeScript 类型定义
15
 
16
## 注意事项
17
- 所有 API 路由都在 src/app/api/ 下
18
- 数据库迁移用 `npx prisma migrate dev`
19
- 生产环境构建用 `next build`

有了这个文件,Claude Code 每次启动都能快速了解项目概况,不需要我重复说明。

第二个技巧是用 .gitignore 来排除不必要的文件。有时候 AI 工具会把 node_modules、.next 这些目录也读进去,白白占用上下文窗口。在配置里加上排除规则,效果立竿见影。

第三个是善用 git blame。AI 改代码之后,你可以用 git blame 看一下某一行是谁写的、什么时候改的。如果某段代码是三个月前写的,而且标注了"TODO: 需要重构",那 AI 在改相关代码的时候就会更谨慎。

Q: 你觉得这篇文章的观点会不会太悲观了?

有可能。说实话我写这篇文章的时候确实花了比较多篇幅讲问题。但我觉得有必要让大家看到 AI 编程工具的另一面——不是"它能帮你做什么",而是"它目前还做不好什么"。

这并不是悲观,而是务实。知道工具的局限性,才能用好它。

我自己用的时候也经常纠结:这个功能让 AI 做还是自己做?一般来说我的判断标准是——如果这个功能不涉及核心业务逻辑,就让 AI 做。如果涉及,我自己来。

比如写一个用户注册页面,AI 来做完全没问题。但写支付流程,我还是会自己写核心逻辑,让 AI 帮忙写测试和边界处理。

说到底,AI 编程工具现在更像是一个"实习生"——它能帮你做很多事,但你得盯着它干活,关键时刻还得你自己上。

而且说实话,这个"实习生"有时候还挺让人头疼的。它可能上午还帮你写了一段漂亮的代码,下午就把你上午改的 bug 又写回来了。

所以与其说 AI 编程工具是"助手",不如说它是一个需要频繁 code review 的同事。

advertisement