别再跟 AI 死磕 prompt 了,我写了个 Loop 让它自己改到满意为止

我昨天凌晨两点还在跟 Deepseek 较劲。就为了一篇奶龙按摩椅的小红书广告文案,我改了八版 prompt,从 "写个爆款文案" 到 "标题必须带数字,正文不超过 300 字,结尾要有行动号召,要像小红书博主那样说话",结果它要么标题不带数字,要么写了 400 多字,要么结尾就是 "快来购买吧" 这种干巴巴的话。

我盯着屏幕,手指悬在回车上面,突然觉得特别荒谬。我这是在干嘛?不就是生成、检查、不满意、调整 prompt、再生成吗?这不就是个循环吗?我一个写代码的,为什么要自己当这个循环的人肉执行器?

就在这个时候,我刷到了那条 OpenClaw 开源项目创始人彼得·斯坦伯格发布的 780 万浏览的推文。

原来我一直在做最笨的事

说实话,看到这句话的时候我愣了一下。我一直以为用好 AI 的关键是写好 prompt,是把话说清楚,是用各种技巧让 AI 理解我的需求。结果人家开源大佬说,别写 prompt 了,写 Loop。

我翻了翻评论区,发现 Claude Code 的作者也在下面附和,说他现在也不写 prompt 了,只写 Loop。

我突然反应过来,我每天和 AI 的交互,本质上就是一个手动的循环。我给 AI 一个指令,它输出结果,我检查结果是否符合要求,如果不符合,我就修改指令,再让它输出一次。这个过程,除了 "检查" 这一步需要人的判断,其他都是机械重复的。

那为什么不把这个检查也交给 AI 呢?

Loop 到底是什么?说穿了就是三件事

我之前对 Loop 的理解,就是 for 循环、while 循环,就是重复执行一段代码。直到我看到这张图,才突然把这个概念想透了。

任何一个有用的 Loop,都必须回答这三个问题:

1. 从哪里开始?

2. 重复做什么?

3. 什么时候停止?

就这么简单。你炒菜的时候,从洗锅开始,重复 "炒一下、尝一口、加点盐" 的动作,直到味道合适了就停。你写报告的时候,从第一页开始,重复 "写一段、读一遍、改一改" 的动作,直到领导满意了就停。

缺了第三个问题,就是死循环。程序会一直跑下去,直到内存溢出或者你的 API 额度烧光。

我之前的手动循环,停止条件就是 "我满意了" 或者 "我累了"。现在我要做的,就是把这个停止条件变成代码能理解的规则。

原来大模型自己就是这么学会的

更有意思的是,我们现在用的所有大模型,本身就是用 Loop 训练出来的。

你看,AI 训练的逻辑,也是一个完美的 Loop:

  • 给模型看一批数据
  • 计算它的预测和正确答案差了多少
  • 根据这个差值调整模型的参数
  • 再拿一批新的数据,重复上面的步骤

万亿次这样的循环之后,AI 就学会了对话、写作、写代码。

那我们用 AI 的时候,为什么不用同样的逻辑呢?让 AI 自己生成,自己检查,自己调整,直到满足我们的要求。

我写了个能跑的最小 Demo

说干就干,我花了半小时搭了个最简单的项目结构。

因为 Deepseek 的 API 兼容 OpenAI 的格式,所以我直接用了 openai 这个包,省得自己写请求了。

javascript 复制代码
    import { OpenAI } from 'openai';
    import dotenv from 'dotenv';

    dotenv.config();

    const client = new OpenAI({
      apiKey: process.env.DEEPSEEK_API_KEY,
      baseURL: process.env.DEEPSEEK_API_BASE_URL,
    });

    // 注意这三个参数,坑了我半小时
    const limit = {
        maxRound: 5,    // 最多循环5轮,防止死循环
        maxToken: 2000, // 最多消耗2000token,防止烧钱
        sameStop: 2     // 连续2次输出相同内容就停止,防止AI摆烂
    }

    const task = {
        desc: "奶龙按摩椅广告文案",
        rules: ["标题带数字", "正文 < 300 字", "大爆款", "结局有行动号召"]
    }

    let round = 0, totalToken = 0, sameCount = 0, lastText = "";

    // 循环的停止条件,三个满足任意一个就停
    function needStop(){ 
        return round >= limit.maxRound || totalToken >= limit.maxToken || sameCount >= limit.sameStop;
    }

    // 生成文案
    async function gen() {
        const res = await client.chat.completions.create({
            model: process.env.DEEPSEEK_API_MODEL,
            messages: [
                {
                    role: "user",
                    content: `假如你是一位小红书资深广告文案博主,写一篇${task.desc},严格遵守:${task.rules.join('、')},只输出文案`
                }
            ]
        });
        console.log(`消耗token: ${res.usage.total_tokens}` , `\n生成内容:\n${res.choices[0].message.content}`);
        return {
            text: res.choices[0].message.content.trim(),
            token: res.usage.total_tokens
        };
    }

    // 检查文案是否符合要求
    async function check(text) {
        const res = await client.chat.completions.create({
            model: process.env.DEEPSEEK_API_MODEL,
            messages: [
                {
                    role: "user",
                    content: `请检查文案是否符合要求:${text}
                    严格遵守:${task.rules.join('、')}
                    仅输出 JSON {pass: 布尔, fail: 数组}`
                }
            ]
        });
        return JSON.parse(res.choices[0].message.content.trim());
    }

    // 主循环
    async function runLoop() {
        console.log('AI Loop 开始运行');
        while(!needStop()){
            round++;
            console.log(`\n===== 第 ${round} 轮 =====`);
            
            const { text, token } = await gen();
            totalToken += token;
            
            // 检查是否连续输出相同内容
            sameCount = text === lastText ? sameCount + 1 : 0;
            lastText = text;

            const { pass, fail } = await check(text);
            if(pass){
                console.log(`\n✅ 文案符合要求,通过检查!`);
                console.log(`最终文案:\n${text}`);
                return;
            }
            console.log(`❌ 文案不符合要求,问题:${fail.join('、')}`);
        }
        console.log(`\n⚠️ 触发刹车机制强制停止,最后一次生成的文案:\n${lastText}`);
    }

    runLoop();

然后在.env 文件里填上你的 Deepseek API 密钥和模型就可以跑了。

我踩过的那些坑,你别再踩了

说实话,这个 demo 我写了三遍才跑顺。

第一版我只加了 maxRound,结果有一次 AI 生成的内容一直不合格,循环到第五次就停了,输出的还是一堆垃圾。我当时就想,不行,万一 AI 前五次都没做好,第六次突然开窍了呢?但如果不加 maxRound,万一死循环了怎么办?

后来我想到了加 maxToken,根据你的预算来设置,比如我设置的 2000token,大概也就几毛钱,就算死循环了也损失不大。

最坑的是 sameStop 这个参数。我之前没加这个,结果有一次 AI 连续三次输出一模一样的内容,它自己还觉得没问题,一直在那循环。我看着控制台刷刷刷地跳 token,赶紧把进程杀了。后来才明白,AI 有时候会摆烂,当它觉得自己怎么都满足不了你的要求的时候,就会输出同样的内容敷衍你。这时候就必须有个机制来检测这种情况,及时停止。

一定要设置这三个停止条件!一定要设置这三个停止条件!一定要设置这三个停止条件!不然你早上起来可能会收到一张几百块的 API 账单。

这个方法到底好在哪?又有什么问题?

我跑了几次这个脚本,效果超出我的预期。以前我要花十几分钟反复改 prompt,现在我只需要写好任务描述和检查规则,然后去喝杯咖啡,回来就能拿到符合要求的文案。

它最大的优势就是把你从重复的劳动中解放出来。你不用再盯着屏幕等 AI 输出,不用再一字一句地检查,不用再绞尽脑汁想怎么把 prompt 写得更清楚。你只需要告诉 AI"什么是合格的",剩下的交给循环。

但它也不是没有缺点。最明显的就是 token 消耗高。因为每一轮都要调用两次 API,一次生成,一次检查。我这个 demo 跑一轮大概要消耗 300-500token,跑 5 轮就是 1500-2500token。虽然 Deepseek 的价格很便宜,但如果是更复杂的任务,token 消耗会非常可观。

所以这个方法更适合那些有明确规则、可以量化检查的任务。比如写广告文案、生成测试用例、格式化数据、检查代码规范等等。如果是需要非常有创意、没有明确标准的任务,比如写小说、画插画,这个方法就不太适用了。

最后说几句我真正的收获

昨天晚上写完这个脚本,我躺在床上想了很久。

以前我总觉得,AI 是一个工具,我给它一个指令,它给我一个结果。如果结果不好,那就是我的指令写得不好。所以我一直在研究怎么写更好的 prompt,怎么用更精准的语言描述我的需求。

但现在我明白了,AI 不是一个一次性的工具,它是一个可以迭代的系统。我们不应该追求一次就得到完美的结果,而应该设计一个循环,让 AI 在这个循环里不断地自我修正,直到满足我们的要求。

这大概就是那条推文真正想告诉我们的道理。

如果你也写过这种 AI Loop,或者有更好的停止条件设计,欢迎在评论区告诉我,我也想学习一下。

相关推荐
悟空码字1 小时前
【高德开放平台skill】从拍脑袋到看数据,我是如何把一个“选址直觉“做成 AI Skill 的
aigc·openai·ai编程
runnerdancer1 小时前
Agent如何加载执行Skill的脚本
前端·agent
血小溅2 小时前
三大 AI 编码框架深度对比:GSD vs OpenSpec vs Superpowers
人工智能·后端
Gatlin2 小时前
当你告诉AI“帮我搞定这件事”——AI Agent正在改变规则
aigc
nuIl2 小时前
实现一个 Coding Agent(7):Skills
前端·agent·cursor
nuIl3 小时前
实现一个 Coding Agent(8):会话持久化与多会话
前端·agent·cursor
武子康5 小时前
调查研究-186 LangChain 和 LangGraph 的区别:从快速构建 Agent 到生产级工作流编排
人工智能·langchain·llm
武子康5 小时前
调查研究-185 CodeGraph 调研:给 AI 编程 Agent 一张代码库地图,少一点反复 grep(2026)
人工智能·openai·claude
沉默王二6 小时前
面试结束后,我反问:“就面个实习至于上这么大强度吗?”面试官:“你对 RAG、Agent、MCP、Skill 理解得很到位,所以要求高一点。”
面试·agent·ai编程