两个 Prompt 套路:让 AI 代码少踩一半坑

时间:2026-07-04 08:52:42 来源:互联网

向AI提出需求后,它生成代码并运行通过。审查时逻辑看似合理,测试也顺利过关,于是代码被部署上线。但用户反馈不久后问题频发,这背后隐藏着AI编程的常见陷阱。

两个 Prompt 套路,让 AI 代码少踩一半坑

你给AI一个需求,它写出了代码,跑通了。你看了一眼,逻辑说得过去,测试也过了,就上线了。

两个 Prompt 套路,让 AI 代码少踩一半坑

然后用户反馈出问题了。

它改好了一个地方,埋了三个新坑。你盯着日志与代码一脸茫然:这地方明明是它写的,我也看了,怎么上线就炸?

如果这个场景你经历过,你不是一个人。

AI写代码最大的坑,不是它写不出来,而是它写出来后你误以为正确。你能看懂每一行代码在干什么,但你看不到它跳过了什么——那些被训练数据平均化掉的边界情况,那些看起来合理但其实不该这么做设计选择,那些在训练数据里出现频率太低所以被模型忽略掉了极端场景。

下面这两个Prompt套路,一个管生成方案对不对,一个管验证代码稳不稳。加在Prompt里成本几乎为零,但省下来的半夜debug时间很实在。

套路一:在 Prompt 末尾加七个字

方法简单到让人怀疑:在你提给AI的任何需求后面,加一句——

从第一性原理出发。

就这样。七个字。

为什么这七个字有效

AI默认工作方式叫类比推理。你让它写一个数据过滤器,它在训练数据里搜到几千个数据过滤器的实现,找一个最像的改一改给你。代码能跑,逻辑也说得过去,但它跳过了最关键一步:你确定这件事应该用过滤器来解决吗?

类比推理快,但它有一个致命缺陷:如果你提的问题本身就有偏差,AI会在一个有偏差的方向上给你一个看起来没问题的答案。就像你问怎么让马车跑得更快,类比推理的AI会告诉你换更好的马、减重、改装轮子,唯独不会告诉你应该发明汽车。

第一性原理做的事刚好相反:不参考现有方案,回到最根本事实重新推演。

它不是让AI更聪明,而是让AI先停下来想清楚这个问题的本质是什么,再动手。

一个真实的例子

AIHOT是一个AI资讯聚合项目,从海外信源抓取内容。某天抓取功能挂了,开发者把报错甩给AI,AI第一反应是修那个报错的函数,哪里报错修哪里,几分钟改好。

跑了一下午,又挂了。

换了个姿势:把整个需求重新描述一遍,末尾加上从第一性原理出发。AI这次没有直接修报错,而是从更底层往回推:这个抓取功能依赖的流量路由逻辑,是四月份写的,当时的设计假设,比如信源响应格式、网络拓扑,现在已经不成立了。

于是问题从修一个报错的函数变成了重构一层路由逻辑。不是换个更大的创可贴,是把伤口清创、重新缝合。

不加 vs 加了,AI 给出的方案差多远

假设你让AI写一个消息队列的消费者。不加这七个字,它给你一个教科书式的while-true-poll循环:

while True:messages = queue.receive_messages(MaxNumberOfMessages=10)for msg in messages:process(msg)queue.delete_message(msg)

能跑。但消息量翻十倍的时候,消费者来不及处理,消息越堆越多,内存吃满,OOM。这个方案的本质是不管来多少消息,我每次只取十条,它没考虑如果消息来得比我处理得快怎么办。

加了从第一性原理出发,AI会重新推演消费消息这件事的终极目标:不是为了消费而消费,是为了在延迟可接受的前提下不丢数据、不爆内存。方案变了:

while True:queue_depth = queue.get_queue_depth()batch_size = min(max(10, queue_depth // 10), 100)messages = queue.receive_messages(MaxNumberOfMessages=batch_size)with ThreadPoolExecutor(max_workers=batch_size) as executor:futures = [executor.submit(process, msg) for msg in messages]for f in as_completed(futures, timeout=30):...

它自己加了背压感知和动态批次调整,积压越多,批次越大,处理越快,压力小了自动缩回默认值。这不是什么高深技术,但你没提,类比推理的AI不会主动加,因为它见过的几千个消息队列示例里,大部分都是固定批次的简单写法。

这七个字什么时候最管用

不是所有场景都需要第一性原理。写一个简单的CRUD接口、配一个Nginx路由,类比推理就足够了,不需要重新发明轮子。

但下面三种情况值得加:

  1. 你在修一个反复出现的bug。AI修了三次还出问题,说明它只在表面修修补补,没有找根因。
  2. 你要做一个设计决策。选数据结构、定模块边界、设计API,这些事如果方向错了,后面改的代价很大。
  3. 你也不确定最优方案是什么。需求模糊的时候,类比推理会给你一个别人都这么做的方案。第一性原理至少能让你看清楚这个方案的前提假设是什么。

套路二:让 AI 攻击自己的代码

功能写完了,测试跑过了,Code Review也过了。

这时候你再跟AI说一句:

开启多Agent对抗式审查这段代码。站在恶意用户和极端场景的角度,找出所有可能导致系统崩溃或数据异常的漏洞。

正常开发的时候,你的大脑处于建设模式,想着功能怎么实现、逻辑怎么走通、正常路径怎么覆盖。你不会去想如果发布时间是2038年会怎样,也不会去想如果用户上传了一个50MB的纯文本但所有内容都在一行里、HTML清洗函数要遍历多少DOM节点。

对抗式审查逼AI切到攻击模式。它不再是帮你写代码的助手,而是你的对手,它要找到你代码里所有能被搞崩的地方。

两个大概率你没想到的 bug

还是AIHOT项目的真实案例。开发者用Claude Code开启了约40个Agent做对抗式审查,跑出来的问题列表让整个团队出了一身冷汗。挑两个最典型的:

OOM死循环。从某些海外站点抓到的内容文件特别大,worker进程处理到一半被系统的OOM killer杀掉。原来的代码逻辑是A任务失败了就重试,worker被杀掉之后,调度器自动拉起一个新的worker。新worker拿到同一个A任务,读同一份超大文件,又被OOM killer杀掉,然后又被拉起,一个死循环。

正常开发的时候,你在乎的是重试逻辑对不对,你不会去想如果导致失败的原因是资源不足,重试是在帮倒忙。但对抗式审查的Agent上来就问了一句:如果单条消息的处理所需内存超过worker的内存上限,你的重试机制会发生什么?

未来时间污染。某海外信源的服务器配置错了时区,返回的文章发布时间是明天中午十二点。爬虫收到之后不做任何校验,直接按信源给的时间写入数据库。结果用户的信息流排序逻辑是按发布时间倒序,于是那几篇来自未来的文章,永远排在所有人的信息流最顶端。

对抗式审查的Agent问了开发团队自己从没想过的问题:如果外部数据源的任何字段值落在合理范围之外,你的代码会怎么样?

这些bug有一个共同特征:上线前很难被发现,但一旦触发,影响很大。而且它们不是某个人写错了代码导致的,是整个设计里根本就没有考虑过这条路径。

传统测试 vs 对抗式审查

测试方式 能发现的bug 发现不了的bug
单元测试 逻辑错误、边界值 跨模块交互问题、资源竞争
集成测试 接口不匹配、数据格式错误 极端输入、资源耗尽、时序异常
人工Code Review 代码风格、明显逻辑漏洞 隐蔽的边界条件、组合爆炸
对抗式审查 恶意输入、资源泄漏、外部数据污染、死循环条件 业务逻辑本身的合理性

对抗式审查补的不是测试的短板,它补的是你能想到的测试用例之外的那个世界。

传统测试验证的是我想到的可能出问题的场景,对抗式审查探索的是我根本没想到的场景。这是两种完全不同的思维,所以两种都需要。

两个套路怎么搭

第一性原理管生成:AI动手写代码之前,先让它想清楚这件事的本质是什么。方向对了,方案不会差太远。

对抗式审查管验证:代码写完之后,让AI换个角色,找那些正常思维路径上根本不会去想的漏洞。逻辑对了,还要扛得住边界攻击。

一个在前,一个在后。前一个避免做错事,后一个避免做漏事。两个加起来,就是一个足够轻量但仍然有效的质量闭环。

注意一个坑

对抗式审查跑出来的结果,不能全信,也不能全改。

它有时候会为了找问题而找问题,把一个发生概率无限接近零的边界条件,描述得像是随时会炸。你需要自己做判断:这个问题发生的概率多大?发生了影响多大?修它的成本多大?

优先级排一下,先改那些高概率高影响的。剩下的记在TODO里,写明触发条件,下个迭代再看。

另外一个教训:每次改完核心功能就跑一次对抗式审查,别攒到上线前一天。那时候发现问题属于灵魂拷问,半夜改代码上线,还是带着已知的坑上线?

两个都很难受。

一个额外的应用场景

前面说的是代码。但这两个套路其实不止于写代码。

写技术方案的时候,加一句从第一性原理出发,AI会帮你追问这个方案到底要解决什么问题,而不是堆砌别人的架构。写完方案再让它做对抗式审查,如果你是评审人,你会质疑哪些点,能提前暴露很多逻辑漏洞。

做商业分析、写项目复盘、甚至做个人决策,这两个套路都能用。本质上是让AI先退一步想清楚本质,再换个角度找盲点,这套思维方式,比任何具体的Prompt模板都值钱。

总结

两个句子,记住就行:

问方案,加一句从第一性原理出发。问安全,加一句对抗式审查。

试一次,成本为零。不好用,你就当多打了几个字。