🦞 一只用 AI Agent 搭副业产线的程序员
你有没有遇到过这种情况——Agent 生成的代码跑不起来,它自己不知道,还一脸自信地说「代码已完成」?
我遇到过。Agent 生成了一段 Go 代码,var 声明了一个变量但没 import 对应的包,连编译都过不去。但它交付的时候那叫一个自信。
AI 对自己的输出有一种天然的「盲目自信」。它不会像人一样写完代码后背上冒冷汗——「等等,我刚才写的那个对不对?」
自我反思就是给 Agent 加上这个「冒冷汗」的能力。
为什么 AI 不会自己纠错
LLM 生成文本时,每个 token 都是基于前面的 token 预测的。一旦前面写错了,后面的内容会基于错误继续写——它不会「回头检查」,只会「往前走」。
自我反思打破了这种单向性:生成 → 停下来 → 用自己的输出当输入 → 重新审视。
三种反思模式
| 模式 | 机制 | 成本 | 效果 |
|---|---|---|---|
| 内省式 | 同一个 Agent 审查自己的输出 | 低(1 次额外调用) | 中等 |
| 角色扮演 | 同一个 Agent 切换到 Critic 角色审查 | 中(1 次 + Prompt 切换) | 好 |
| 独立审查 | 独立 Critic Agent 审查 | 高(1 个独立 Agent) | 最好 |
独立审查效果最好——因为上一篇讲了,同一个人批自己卷子有确认偏差。但对于日常任务,角色扮演模式性价比最高。
完整实现
packagemainimport("bytes""encoding/json""fmt""io""net/http""os""strings""time")typeMessagestruct{Rolestring`json:"role"`Contentstring`json:"content"`}typeSelfReflectiveAgentstruct{apiKeystringmaxReflectionsint// 最大反思次数}funcNewSelfReflectiveAgent(apiKeystring)*SelfReflectiveAgent{return&SelfReflectiveAgent{apiKey:apiKey,maxReflections:3,}}func(a*SelfReflectiveAgent)callLLM(messages[]Message,temperaturefloat64)string{body,_:=json.Marshal(map[string]interface{}{"model":"deepseek-v4-pro","messages":messages,"temperature":temperature,})req,_:=http.NewRequest("POST","https://api.deepseek.com/anthropic/v1/chat/completions",bytes.NewReader(body))req.Header.Set("Authorization","Bearer "+a.apiKey)req.Header.Set("Content-Type","application/json")client:=&http.Client{Timeout:60*time.Second}resp,err:=client.Do(req)iferr!=nil{returnfmt.Sprintf("调用失败: %v",err)}deferresp.Body.Close()data,_:=io.ReadAll(resp.Body)varresultstruct{Choices[]struct{Messagestruct{Contentstring`json:"content"`}`json:"message"`}`json:"choices"`}json.Unmarshal(data,&result)iflen(result.Choices)>0{returnresult.Choices[0].Message.Content}return""}// ──────────── 核心:反思循环 ────────────typeReflectionResultstruct{FinalOutputstring`json:"final_output"`Iterationsint`json:"iterations"`IssuesFound[]string`json:"issues_found"`Improvements[]string`json:"improvements"`}// GenerateWithReflection 生成 → 反思 → 修正 → 再反思func(a*SelfReflectiveAgent)GenerateWithReflection(taskstring,qualityCriteriastring,)ReflectionResult{reflection:=ReflectionResult{}// 第 1 轮:初始生成fmt.Println("📝 第 1 轮:生成初始输出...")initialOutput:=a.callLLM([]Message{{Role:"system",Content:"你是一个 Go 代码生成专家。生成完整可编译的代码。"},{Role:"user",Content:task},},0.2)currentOutput:=initialOutput// 第 2-N 轮:反思 + 修正循环fori:=0;i<a.maxReflections;i++{fmt.Printf("🔍 第 %d 轮反思:审查输出...\n",i+2)// 反思:找问题reviewResult:=a.review(currentOutput,task,qualityCriteria)if!reviewResult.HasIssues{fmt.Println("✅ 未发现问题,输出通过审查")break}fmt.Printf("⚠️ 发现 %d 个问题:\n",len(reviewResult.Issues))for_,issue:=rangereviewResult.Issues{fmt.Printf(" - %s\n",issue)reflection.IssuesFound=append(reflection.IssuesFound,issue)}// 修正:根据审查意见改进fmt.Println("🔧 修正中...")improvedOutput:=a.revise(currentOutput,reviewResult.Issues)reflection.Improvements=append(reflection.Improvements,fmt.Sprintf("第%d轮修正了%d个问题",i+1,len(reviewResult.Issues)))currentOutput=improvedOutput}reflection.FinalOutput=currentOutput reflection.Iterations=len(reflection.IssuesFound)returnreflection}// ──────────── 反思 Prompt ────────────typeReviewResultstruct{HasIssuesboolIssues[]string}func(a*SelfReflectiveAgent)review(output,task,criteriastring)ReviewResult{reviewPrompt:=fmt.Sprintf(`你是严格的代码审查员。按以下标准审查输出: 质量标准: %s 原始任务: %s 待审查的输出: %s 审查时回答: 1. 输出是否符合质量标准?(逐条检查) 2. 有没有编译错误、逻辑错误、边界条件遗漏? 3. 代码是否完整可运行?(检查 import、package 声明) 如果发现问题,用以下格式列出: ISSUE: [问题描述] ISSUE: [问题描述] ... 如果完全没有问题,回复:NO_ISSUES`,criteria,task,truncateForReview(output,2000))result:=a.callLLM([]Message{{Role:"user",Content:reviewPrompt},},0.0)ifstrings.Contains(result,"NO_ISSUES"){returnReviewResult{HasIssues:false}}varissues[]stringfor_,line:=rangestrings.Split(result,"\n"){ifstrings.HasPrefix(strings.TrimSpace(line),"ISSUE:"){issues=append(issues,strings.TrimPrefix(strings.TrimSpace(line),"ISSUE: "))}}returnReviewResult{HasIssues:len(issues)>0,Issues:issues}}func(a*SelfReflectiveAgent)revise(outputstring,issues[]string)string{issuesList:=strings.Join(issues,"\n- ")revisePrompt:=fmt.Sprintf(`修复以下输出中的问题。 原始输出: %s 发现的问题: - %s 请输出修正后的完整代码。不要解释修改了什么。`,output,issuesList)returna.callLLM([]Message{{Role:"system",Content:"你是代码修复专家。输出修正后的完整代码,不要包含解释性文字。"},{Role:"user",Content:revisePrompt},},0.1)}functruncateForReview(sstring,maxLenint)string{iflen(s)>maxLen{returns[:maxLen]+"\n...(输出超过长度限制,已截断)"}returns}// ──────────── 对比实验 ────────────funcmain(){agent:=NewSelfReflectiveAgent(os.Getenv("DEEPSEEK_API_KEY"))task:=`用 Go 写一个函数 CalculateDiscount,功能: 用户等级分为 normal/vip/super-vip normal 不打折 vip 打 9 折 super-vip 打 8 折 满 1000 元额外打 95 折(折上折) 输入:等级(string)和消费金额(float64) 输出:折扣后金额`qualityCriteria:=`1. 代码必须包含 package 和正确的 import 2. 必须处理无效的用户等级(返回错误) 3. 必须处理负金额(返回错误) 4. 所有计算必须使用浮点,不丢失精度 5. 函数签名必须包含 error 返回值`// ── 不加反思 ──fmt.Println("===== 不加反思:直接生成 =====")noReflectionOutput:=agent.callLLM([]Message{{Role:"system",Content:"你是 Go 代码生成专家。"},{Role:"user",Content:task},},0.2)fmt.Println(noReflectionOutput)// ── 加反思 ──fmt.Println("\n===== 加反思:生成→审查→修正 =====")result:=agent.GenerateWithReflection(task,qualityCriteria)fmt.Println("\n===== 最终输出 =====")fmt.Println(result.FinalOutput)fmt.Printf("\n共进行 %d 轮迭代,发现并修复了以下问题:\n",result.Iterations)for_,issue:=rangeresult.IssuesFound{fmt.Printf(" ❌ %s\n",issue)}}实测数据
我对同一个任务(上面的折扣计算函数),不加反思和加反思各跑了 5 次,统计结果:
| 指标 | 不加反思 | 加反思 |
|---|---|---|
| 编译通过率 | 3/5(60%) | 5/5(100%) |
| 错误处理完整 | 1/5(20%) | 5/5(100%) |
| 边界条件正确 | 2/5(40%) | 4/5(80%) |
| 平均 token 消耗 | 350 | 950 |
加反思的 token 消耗多了近 3 倍,但换取的是 100% 编译通过率和接近 100% 的错误处理完整性。
值得吗?取决于场景。如果输出会直接部署到生产环境——值的。如果只是草稿——不值得。
什么时候用反思
| 场景 | 用反思? | 理由 |
|---|---|---|
| API 响应生成 | 不推荐 | 太慢,用户等不起 |
| 代码提交前检查 | 强烈推荐 | 编译错误是硬伤 |
| 文章/报告撰写 | 推荐 | 事实错误和逻辑漏洞很常见 |
| 数据处理脚本 | 推荐 | 数据错了很难发现 |
| 聊天回复 | 不需要 | 过度设计 |
一个实用的阈值:如果输出错误会导致大于 1 小时的修复时间——加反思。
反思的三种 Prompt 模式
1. 通用审查:
"检查输出中的事实错误、逻辑漏洞和遗漏"2. 逐条核对:
"逐条确认以下要求是否满足:1.XXX 2.XXX 3.XXX"3. 反向检查:
"如果你是这段代码的使用者,你会对哪些地方不满意?"第三种特别有用——让 AI 从「作者」视角切换到「用户」视角,往往能发现意料之外的问题。
总结
自我反思不是让 Agent 变聪明,是让它多了一次检查的机会。
人写代码要 review,Agent 写代码也要 review。区别在于——人的 review 靠同事,Agent 的 review 可以自己做。
下一篇我们给 Agent 加上最后一道防线——Human-in-the-Loop,人机协作的正确姿势。
关注我,别错过。
🦞 一只用 AI Agent 搭副业产线的程序员
全平台同名:虾哥不加班
需要定制 AI 工具?来聊聊 → lob_ai源码:GitHub - lobster-bujiaban