文章总结: 本文分享了作者在AI编程领域的实战经验,重点探讨了从需求文档到代码交付的全流程优化方案。针对AI编码中规则遵守难、验收效率低等痛点,提出了通过测试框架约束行为、集成测试自主验收、小步迭代开发三大核心策略,强调将规则转化为代码级强制约束而非依赖提示词,最终实现AI开发代码的可直接交付。 综合评分: 85 文章分类: 安全开发,AI安全,安全工具,安全运营,其他
我的 AI Coding 最佳实践
原创
lcvv lcvv
Kv2的万事屋
2026年3月24日 20:06 湖南
在小说阅读器读本章
去阅读
前言
很久没发文章了,一方面是确实没有啥好的技术点能够分享,另一方面也是没有时间。但是最近在开发中高强度的使用了各种 AI 编码方式,遇到问题不少,踩了相当多的坑,我认为还是有一定价值的,发出来仅供参考,如有不对还望师傅们不吝赐教。
应该很多人像我一样,应该都没有预料到 AI 的发展会如此迅速,短短几年就几乎改变了我的全部工作方式。现在我基本上可以说,AI 的能力已经能干好 99% 场景的工作——请注意我这里说的是干好,而不是干完,最终能不能干好,完全看你怎么用她。不论是直接编写能够上线的后端代码,还是代码审计,还是渗透测试,我几乎想不到 AI 干不好的工作。
我怎么用 AI
主题是 AICoding,所以主要还是围绕编码这个事情来展开。从最开始接触 AI 至今,我使用 AI 的方式有过这么几次大的转变:
- • 只是一个搜索引擎:在最开始,几乎只把 AI 当个搜索引擎用,查查命令备忘录,有点大材小用
- • 写单元测试,写局部代码:开始让 AI 干点实事,但还是比较克制,只敢让它写一些非核心的代码
- • 分步骤,让 AI 分层逐步实现整个模块,人工 review:胆子大了,开始让 AI 写核心逻辑,但每一步都要我盯着看
- • 提供需求文档,AI 直接交付:彻底放手,扔一个需求文档过去,让它自己干
有这么容易吗?
当然没这么简单。从需求文档到直接交付,中间隔着十万八千里。但是有了现在各种 AICoding 工具的辅助,相信大家对于 AI 能够干完这个事已经不会有任何质疑了,唯一的问题是这个事能干成什么样。
不论你给任何一个 AICoding 工具需求文档,相信最终他都会告诉你:”所有开发已经全部完成!”,然后自信满满地开始跑程序、测试接口、验证结果。
然后这个时候问题就来了:
- • 能编译吗?
- • 开发的代码符合现在的代码结构吗?
- • 代码仓库现有代码能力用到了吗?
- • 接口通了吗?
- • 接口符合规范吗?
- • 最终的数据处理逻辑正确吗?
当我尝试放手让 AI 主导一个功能模块的开发,我发现我的全部精力都需要花费在无穷无尽的 Review、测试,还有对一些垃圾代码的骂娘中。说好的解放双手呢?
然后常规的解决方案是:那就定义 AGENTS.md 或者写 rule 吧,或者写 skills 吧,我告诉 AI 应该怎么做,他肯定能办好吧?
然后问题就变成了:
- • 我明明说了这个地方不要这样做,为啥 AI 还这么干啊?
- • 我明明说了要用这个模块,为啥 AI 还不这么用啊?
更致命的是,这是不可复现的。当你定义好规则之后,你直接去问,AI 永远会按照你的规则来,但是当你放手安排他干一个大任务的时候,你永远也不知道什么时候他就变了,永远也不知道在什么时候你的规则丢失了。
然后我的 AGENTS.md 越写越长,禁止要求越写越多,但是依然改变不了 AI 在一个你不知道的时刻会违反规则。
在无数次试错之后,我知道了:光靠提示词,是一个死局。
那咋办呢?
不能在提示词中像一个没完没了的老妈子告诉他,这不能干那也不能干,而是应该有一套框架体系让他没有办法犯错,或者让他在犯错的时候知道这个是错误的。
这个结论是自然而然的。很多 AICoding 工具都内置了关于这个理念的一些功能:比如引入 review 的 Agents 角色,在干净的上下文中检查代码质量;在执行命令、编写文件的环节提供 LSP 检查或者 hook 能力,在每次 AI 的交互中实时反馈问题;或者有 skills 引入 TDD 的开发理念,确保基于测试用例,通过测试用例确保交付效果。
像 CodeLeash 这个项目就做得很好,它通过 pre-tool-use hooks 在 AI 执行操作前进行拦截,本质上也是这个思路——把规则变成代码,而不是停留在提示词层面。
但是依然不够。即便引入了这些能力:
- • 测试用例倒是都通过了,但怎么全是 mock 啊,而且 API 返回的结果还是不对啊
- • 这个功能在其他地方实现了啊,你这不要重复写啊
- • 这个鉴权逻辑框架已经做完了,你不需要重复实现啊
- • 这块代码应该是通过工具自动生成的,你为什么要手动创建啊
很容易能够察觉到,这里有两个核心问题。
AI 不知道自己错了
AI 直接改了自动生成的 DAO 文件。你告诉他”不要改”,他嘴上答应,实际还是改。这就像你告诉小孩”不要碰那个杯子”,他转头就碰了——不是他不听话,是他真的控制不住自己。
需要一种强制的规则来限制。我通过 OpenCode 插件,在 Hook 对应的操作中,AI 执行操作时进行拦截:
// 禁止修改自动生成的目录
if (filePath.startsWith("server/internal/dao")) {
throw new Error("禁止直接修改 dao 目录中的文件,只能通过 make 命令生成")
}
AI 想改?直接报错,想改都改不了。这才是真正的约束——不是告诉 AI “不要这样做”,而是让 AI 根本做不到。
另外,代码中存在最佳实践,但是 AI 的视角是看不到的。比如某个目录下的代码有特定的编码规范,AI 不知道,写出来的代码风格千奇百怪。这就需要一种触发式的提示词,能够及时提示。
我通过分类 AGENTS.md 的方式实现:只有编辑某一个块代码,才会触发的提示词,确保你的提示词在 AI 变更逻辑的上下文中。比如编辑 dao 目录的文件时,自动触发”这个目录的文件是自动生成的,禁止手动修改”的提示。此时 AI 还在干这个活,上下文还没丢,通常会照办的。
AI 没办法自己验收
问题出在验收这里。为什么不能让 AI 来验收呢?我最终需要的并不是 AI 的代码,而是 AI 代码实现的效果——接口能不能正常返回数据,业务逻辑对不对。
这并不是单元测试能够解决的问题。单元测试全是 mock,mock 的数据当然对,但真实接口返回啥谁知道?所以集成测试才是 AICoding 的救命良药。必须要提供给 AI 能够自主进行集成测试的能力,只要集成测试通过,剩下的只是代码质量的问题,交给 reviewAgents,他能够解决全部的问题。
所以新的问题来了:AI 能自己做集成测试吗?
如果不建设框架,纯靠 AI 自己,很难。一个完整的集成测试用例依赖外部环境——数据库要启动、服务要跑起来、测试数据要准备、跑完还得清理。这些事情让 AI 自己搞定,不现实。所以需要一个测试框架,能够让 AI 自主的创建完整的测试环境,自主的编写集成测试用例,验证最终效果。
这其实就是在造一个”验证闭环”。社区里有人管这个叫 self-verification,也有人叫 autonomous testing,核心都是让 AI 能自己跑、自己看结果、自己判断对不对。我把它落地成了一个具体可用的测试框架,而不是停留在概念层面。
我的解法
首先要给 AI 能够自主构建测试环境的能力:
环境管理:
dev-env-init 创建外部环境(启动 Docker 容器)
dev-env-clean 清理外部环境(停止并删除所有容器)
dev-env-show 显示环境信息(端口、密码、健康状态)
配置生成:
dev-gen-config 生成基于测试环境的 config 配置
测试相关:
dev-test 运行指定测试(使用: make dev-test TEST=TestXXX)
dev-test-all 运行所有测试
dev-test-cover 运行测试并生成覆盖率报告
一套命令,环境自己建、数据库自己初始化、配置自己生成。AI 只需要执行 make dev-env-init 和 make dev-test,剩下的全自动。
然后通过最终的 HTTP 请求断言提供高可读性的集成测试用例,确保高效验收,从无止境的代码 review 中脱离出来:
func TestLoginAndGetMenuSimplified(t *testing.T) {
env := &INTestEnv{
Prepare: func(t *testing.T, info *TestInfo) {},
}
tests := []INTestStep{
{
Name: "场景1: 登录并获取菜单",
TestFunc: NewTestFunc(
WithLogin("", ""),
WithRequest(
"/admin/menu/list",
"GET",
nil,
VerifyCode(0, "获取菜单列表"),
VerifyNotEmpty("data.list", "菜单列表不能为空"),
VerifyLengthMin("data.list", 10, "菜单数量验证"),
),
),
},
}
defer env.InitTestInfo(t)()
for _, tt := range tests {
t.Run(tt.Name, func(t *testing.T) {
env.Reset(t)
tt.TestFunc(t, env.info)
})
}
}
你看,测试用例写得很直白:登录,发请求,验证返回码、验证数据不为空、验证数据长度。AI 写这样的测试用例毫无压力,跑起来也能直接验证真实接口。
小步迭代
测试框架搭建好之后,剩下的事情基本上是顺理成章。但 AI 有一个很不好的习惯:AI 写代码是一次写完,恨不得把所有接口全部写好再一起测。而人写代码通常是基于功能,先写关联代码,写一个测一个。
所以如果不做提示,AI 会先把全部测试用例写完,然后再写实现。这就导致在全部代码开发完后,几乎跑不完测试用例——因为太多了,而且一旦出错,不知道是哪个接口的问题。有时候甚至已经写好的功能,在写新功能的时候反而会改出问题。
这只需要制定一个规约就能解决:要求 AI 一次只干一件事,一次只写一个接口,一次只实现最小的依赖。
第一轮:只写创建接口的测试 → 测试失败 → 写创建接口的代码 → 测试通过 第二轮:写查询接口的测试 → 测试失败 → 写查询接口的代码 → 测试通过 第三轮:…
这个思路其实跟 OpenCode 的 Ralph Loop、以及社区里讨论的 Incremental Development Pattern 是同一个方向——让 AI 一次只干一件事,干完验证了再干下一件。不同的是,我这边把小步迭代和集成测试框架绑在了一起,每一步都能跑真实的接口验证,而不是靠 AI 自己判断”做完了没有”。
这样原本定位问题这种高认知负担的任务,直接变成了”确认当前步骤”这个低认知负担的任务。测试失败了?那肯定是刚才写的这个接口有问题,改就完了。
而且顺带的交付验收也解决了——搞定一个接口,就可以跑测试验收。不用等到最后才集中验收,风险分散到每一步。
总结
AI 确实是新时代最牛逼的产物。本次案例主要聚焦在让 AI 开发出可直接交付的代码这个议题,但是其核心是让 AI 能够自主验收。这个方式可以用在几乎所有使用 AI 的场景中——比如代码审计,让 AI 自己跑扫描、自己验证结果、自己出报告。
这个下回有空我再细聊,感谢阅读。
Reference
- • CodeLeash – 通过 pre-tool-use hooks 约束 AI 行为
- • Ralph Loop – OpenCode 内置的迭代开发循环机制
- • Incremental Development Pattern – Anthropic 官方推荐的增量开发模式
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Kv2的万事屋 lcvv lcvv《我的 AI Coding 最佳实践》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论