为什么你的 AI 写代码漏洞百出?因为你根本没学会跟它说话

“AI 编程工具的本质不是替你写代码,而是替你打字。”

“它的打字速度很快——但它不知道你要打什么字,除非你告诉它。”

很蠢。但很真实。

我翻开自己的 Git 提交历史一查,这仓库没有年代,歪歪斜斜的每行代码上都写着 “AI 辅助” 几个字。我横竖睡不着,仔细看了半夜,才从字缝里看出字来——

满本都写着两个字:乱说话。

够了。真的够了。大抵每个用 AI 编程的人,都要经历这个阶段的。别急,慢慢来。

但经历过的人都知道,那种感觉有多糟。你满怀期待地给了一个指令,AI 吐出一堆看似能用实则漏洞百出的代码。你信了。你上线了。然后出事了。

凌晨两点被报警叫醒,看着监控面板上全红的错误率,手抖着点了两个小时回滚——每个用过 AI 编程的人迟早都会遇到一次。


一、你以为自己在对话,其实在自言自语

半年前我用 Claude Code,第一句话是:

“帮我写个用户登录系统。”

它给了我一个。能用,但不带密码哈希,不带 session 管理,不带任何安全考量——因为我的提示词里,一个字都没提这些。

说白了,那种代码上生产就是灾难。准确说,不是”就是”,是”早晚是”——时间问题而已。

我当时还纳闷:AI 不是应该很聪明吗?怎么连个 bcrypt 都想不到?

后来我明白了:不是它想不到,是我不配让它想到。

你给一句”帮我写个登录”,它真就只写个登录。密码明文存库,SQL 注入大开。谁的责任?我自己。

AI 编程和微信聊天是两回事。你跟朋友说”帮我写个登录”,朋友知道你大概要什么。但 AI 没有常识,它只有你给它的上下文。你给多少,它做多少——不多不少。

我花了半年、踩了几百个坑之后,总结出了一套 提示词结构。每天都在用的实战模板。


二、差的提示词 vs 好的提示词

先看反面教材。以下全部出自我自己的历史记录,每一条都是血的教训。

差的提示词 vs 好的提示词

反面案例 1:太抽象

❌ “做一个 API 接口”

产出结果:没有鉴权、没有参数校验、没有错误处理、没有 Swagger 文档的接口。

❌ “优化一下性能”

产出结果:在已经 O(1) 的地方加了个缓存,真正的 O(n²) 查询原地不动。我没告诉它哪个地方慢,它怎么知道?白费功夫。

反面案例 2:一次塞太多

❌ “帮我重构认证模块改成 JWT,同时数据库从 MySQL 迁到 PostgreSQL,顺便把日志系统也换了”

产出结果:四件事都做了一半。认证模块能用但没刷新 Token,迁移脚本漏了三个表,日志系统改了但配置文件没更新。生产环境直接炸了。回滚花了两个小时。蠢透了。

我的教训:AI 不是外包团队,是一次性工兵。一次只能干一件事。

正面案例:结构化提示词

我后来摸索出来的格式,四个字:角色 + 任务 + 约束 + 输出。

:::callout info ✅ 结构化提示词示例
角色:你是一个资深后端工程师,用 Go 实现用户注册接口
任务:1. 接收 username、email、password
2. 对密码进行 bcrypt 哈希
3. 写入 users 表,返回用户 ID
约束:使用 GORM 操作数据库 | email 必须有唯一索引 | 密码长度小于 8 位返回明确错误 | 不要创建新模型,用已有的 User struct
输出:只需要 handler 函数和必要的单元测试 :::

差距大到不敢相信。后来才明白,问题是我太懒——懒得说清楚、懒得给上下文、懒得告诉它不要干什么。


三、万能提示词模板

模板 A:写新功能

:::callout primary [角色] 你是一个有 10 年经验的 {语言/框架} 工程师
[上下文] 技术栈:{关键依赖和版本} | 相关文件:{贴关键代码或文件路径}
[任务] 实现 {具体功能}:1. {子任务 1} 2. {子任务 2} 3. {子任务 3}
[约束] {不要用的技术/模式} | {必须遵守的规范} | {边界条件处理}
[输出] 只输出 {函数/组件/配置} 代码 | 包含错误处理和日志 | 附带 2-3 个测试用例 :::

模板 B:修 Bug

:::callout warning [上下文] 文件:{路径} | 出错行:{行号} | 错误:{完整堆栈}
[任务] 分析并修复这个 bug
[约束] 不要改动 {不能改的部分} | 修复后兼容 {需要兼容的场景}
[输出] 解释 bug 根因 | 给出修复代码 :::

模板 C:代码审查

:::callout danger [角色] 你是一个严格的代码审查者
[上下文] 以下是我刚刚写的 {功能} 代码:{贴代码}
[任务] 从正确性、安全性、性能、可读性四个角度审查
[输出] 按严重程度排序:P0: {问题} → {建议} | P1: {问题} → {建议} :::

这个模板帮我抓到了不少自己看不到的问题。有一次认证逻辑有越权漏洞,自己看了三遍没发现,AI 两秒钟揪出来了——那种后怕的感觉,就像走在路上突然发现脚下是个没有盖的下水道。


四、Claude Code 的专属技巧

深夜改 AI 写的烂代码

技巧 1:用 CLAUDE.md 锁定项目上下文

项目根目录放一个 CLAUDE.md 文件,把技术栈、编码规范、禁忌写进去。每次启动自动读取——不需要每次都重复说同样的约束。

我的 CLAUDE.md 节选:

:::callout info CLAUDE.md 节选
技术栈:Go 1.21, Gin, GORM, PostgreSQL
规范:所有公开函数必须有 godoc 注释 | 错误使用 fmt.Errorf 包装,保留原始上下文 | 数据库操作在 service 层,不要放 handler
禁忌:不要引入新的第三方依赖 | 不要修改 migration 文件 :::

技巧 2:用 hooks 自动化重复动作

.claude/settings.json 里配 PostToolUse hooks:

:::callout tip PostToolUse hooks 配置

{ "hooks": { "PostToolUse": [<br>
  { "matcher": "Edit|Write", "hooks": [<br>
    { "type": "command", "command": "gofmt -w ./path/to/file && go vet ./path/to/file" }<br>
  ]}<br>
]}}<br>

:::

每次 Claude Code 改完代码自动跑格式化和静态检查——省下了”跑一下 lint 看看”的口水。

技巧 3:用 skills 加载领域知识

把架构决策、业务逻辑写成 skill 文件,提到”新建一个订单表”时,它不会凭空捏造字段,而是参照 skill 里的规范生成。


五、最常犯的五个错误

错误 修正
不给上下文 贴关键代码或说明技术栈
指令模糊 说清楚”内存”还是”响应时间”
一次太多 拆成三步,每步验证再下一步
不指定输出格式 明确说”只输出 diff”
不让它提问 加一句”不确定的地方先问我”

你让 AI 闭嘴干活,它就闭着眼睛干活。

有一次我让它”优化一下性能”,它在只跑一次的初始化函数里加了一整个 Redis 缓存层。真正的慢查询?纹丝不动。气吗?气。但问题不在它,在我。

别信任。给指令。给约束。给上下文。就这么干。


六、说句难听的

我见过太多同行抱怨”AI 写代码不行”、”AI 就是个玩具”。抱怨完了继续用,继续出问题。

真服了。现实就是:问题在自己身上。

AI 编程工具的本质,不是”替你写代码”,而是”替你打字”。

提示词写得好,AI 是你的 10x 工程师。提示词写得烂,AI 是个听话但笨的实习生。你让它往东 100 米它走 10 米就停了——因为你没说清楚是 100 米。

AI 不是来替代程序员的,是来帮程序员省时间的。

但前提是,你得先学会跟它说话。

半年前我觉得 AI 万能。三个月前觉得 AI 拉胯。现在我觉得——AI 就是一面镜子。你蠢它就蠢,你清醒它就清醒。

写了这篇。不是为了炫耀,是为了提醒。别犯同样的错误。


2026-04-30


关于码孖AI

码孖AI,专注 AI 工程化落地。

关注我,持续更新实战踩坑指南。

:::callout tip 觉得有用? 点个「在看」,分享给同样在 AI 落地路上挣扎的朋友。 :::