
1. 递归自改进不是魔法先把三个层级拆清楚最近我在做一个小型编码Agent给它加了一版最简单的“自己写完自己改”的循环让模型生成修复方案跑测试把测试失败信息再扔回给模型让它再修一次。前两轮效果非常明显第三轮开始原地踏步再到第五轮我发现它偶尔会把原本正确的东西改坏。这个现象很典型也让我重新认真思考了一个被讨论很多但常常被误解的词递归自改进。递归自改进的大白话版本是“让AI自己帮自己变得更好”。但这个说法太含糊了。你让模型多反思一次是自改进你让它生成数据训练自己的下一代模型也是自改进你给它设计一个能做研究实验的计划也算自改进。这三件事的技术难度、反馈来源、失败模式完全不一样。如果不把层级拆清楚后面所有的架构讨论都是在打空气。我在实践中通常把递归自改进拆成三个层级来理解。第一层有限的自细化Finite Self-Refinement。这是最接近提示词技巧的一种。模型生成一个答案然后生成对它自己答案的批评再根据批评修正答案。这里面没有参数更新没有外部工具反馈信号完全来自模型自身。这也是门槛最低、最容易上手实验的一种形式很多self-refine、self-consistency、Reflexion类的论文本质上都在这层附近打转。它有一个非常明显的特点循环轮数是有限的一般几轮到十几轮就饱和了再往下走边际收益急剧下降。第二层数据驱动的自训练循环Self-Training Loop。模型把每一轮的输出当作训练数据去微调自己或者微调一个同样能力的模型。典型如STaRSelf-Taught Reasoner的思路让模型尝试推理把正确答案对应的推理过程过滤出来再拿这些数据训练下一轮模型。这一层的改进对象不是单次输出而是模型参数本身。它面临的核心问题变成了“数据质量怎么保证”“模型会不会把自己带偏”因为训练用的标签也来自模型自己。第三层自主研究环Autonomous Research Loop。这是标题里“从有限的自细化到自主研究环”想落脚的终点。Agent不仅是“生成答案再修改”而是能自己提出假设、设计实验、调用外部工具验证、记录实验结果最后根据结果提出下一个假设。整个循环是闭环的人类只在关键节点介入。这也是各类AI Scientist、AutoGPT方向的项目在尝试的东西。很多人以为它只是“把自细化循环的次数调大一点”这个理解是不对的——次数变大依然是第一层的延长线第三层的关键在于反馈信号从哪来。我想用一个类比来把这三层串起来。有限的自细化像一个学生做完题之后自己检查一遍凭印象改错。这个能力有用但你检查自己写的答案时经常会把对的改错因为你没看过标准答案。自训练循环像学生整理错题本把做过的错题反复复习直到考试分数提高。但错题本里的错题是你自己判定出来的如果判错了你只是在把错的答案记得更牢。自主研究环则像一个学生不再满足于做题而是自己出卷子、自己设计实验去验证一道题的多种解法甚至推翻教材里的结论——但前提是他的“实验”必须接一个外部世界反馈才不算自说自话。这样一来整篇文章的讨论框架就清楚了我们先看第一层为什么有效、又为什么止步于“有限”然后讨论第三层需要什么样的反馈系统和工程架构最后聊聊我没有踩过的、但周围不少团队踩过的坑。2. 自细化循环的真正瓶颈信号衰减与生成器-评估器共谋2.1 自细化为什么能起效又为什么很快饱和先说说为什么“自审自查”这种看似偷懒的方案确实有效。LLM在训练时见过海量含批评、修订、纠错痕迹的语料所以它在“给别人挑错”这个任务上往往比“直接给出完全正确的答案”更擅长。这有点像工作中常见的两个人互相对方检查代码而自己检查自己的代码时总是“惯性思维太重”。我做过一次还算能说明问题的对照实验。让同一个基座模型分别执行两种循环第一种是自己生成答案、自己写批评、自己修订第二种是模型A生成答案由另一个不同基座的模型B写批评再让A根据批评修订。同样跑五轮用一组客观指标打分结果是这样的循环类型第一轮提升第二轮提升第三轮至第五轮自生成自批评12%左右6%左右几乎停止偶尔下降自生成异模型批评11%左右9%左右缓慢提升无回退这个实验结果不复杂但指向非常明确当批评者与生成者来自同一个模型时它很难跳出自己的“思维惯性”。第一轮提升来自模型本身固有的纠错能力——它闭着眼睛也能抓出一部分低级错误但到了第三轮剩下的要么是模型自身也不确定的问题要么是它从训练数据里继承的偏见这时候再让它自己给自己挑错等于让一个偏科的学生自己出试卷考自己分数自然就卡住了。信号衰减的另一个来源是批评文本的熵太低。我试过把模型五轮生成的批评意见做聚类发现前两轮的意见差异很大后面几轮的批评意见几乎是一个模子刻出来的都是“内容可以更详细一些”“逻辑可以更紧密一点”这种万金油建议。这种批评不会带来新的有效信息只会让输出往“看起来更周全”的方向漂移实际上并没有解决实质问题。你可以把自细化想象成在一个固定的搜索空间里做局部爬山前几步步长够大爬得快当爬到局部山顶后你还站在原地做同样的局部位移自然怎么都动不了。2.2 生成器-评估器共谋最容易被忽视的隐形陷阱如果说信号衰减是“自细化动力不足”那生成器与评估器之间的共谋就是“自细化动力用错方向”。这里要严肃提一个我在实际工程里经常看到的现象如果你让同一个模型既当生成者又当评判者它的“评判”会逐渐变成“给生成结果找理由”而不是“客观挑错”。我做文本摘要优化时遇到过具体案例。让模型先写一段摘要然后用同模型对它写的内容进行要点完整性评估。表面看每轮都“改进”了但仔细看评估意见发现它给“原摘要已经覆盖了核心信息”这个点赞占了大多数而当我把人类评审放进去对照时人类认为摘要存在明显的信息偏移和重点错位。也就是说模型不是在做真实的错误识别它是在确认自己写的东西没问题——这在心理上很接近“自我合理化”。防止共谋的办法我在后面自主研究环的架构里会说但先说一个立竿见影的工程举措评估器不要用同一个模型至少不要用同一个检查点。哪怕是同一个基座、不同温度采样出来的一组模型当评估委员会也比单一模型自评要稳得多。我在一些小规模实验里还会把“自我评估”和“他人评估”的差异率记录下来当监控指标——如果两者的分差持续缩小说明模型正在逐渐自欺这时候要赶紧把批评来源换成外部信号。2.3 外部世界的反馈有限自细化走向自主研究环的那道分界线聊到这里第一层的上限就很清楚了只要反馈还是从模型自身生成的语言信号里来的它就不可能突破训练数据分布的边界。这时候外部世界的反馈就变成了整个递归自改进里最关键的要素。我理解的外部反馈分两类。一类是确定性的程序反馈编译器报错、单元测试通过与否、数学公式校验、代码静态检查结果。这种反馈是硬信号不依赖任何语言模型的判断所以它不可能被模型的“自我合理化”污染。另一类是结构化环境反馈比如博弈类的胜负结果、在仿真环境里跑出来的reward、执行搜索任务时获得的路径长度。这两类信号有一个共同特点它们不是LLM“想出来的”而是从环境里“测量出来的”。自主研究环之所以能比自细化循环走得更远原因就在这里它的改进动力不再依赖模型自己说自己哪里不好而是依赖一个更客观、更丰富、无法被语言惯性平滑掉的信号来源。下面我展开讲讲一个最简可行的自主研究环应该怎么搭以及每一步的选型理由。3. 从自细化走向自主研究环一个最小可行架构3.1 环的核心模块与各自职责我不建议一上来就搭建论文级别的完整自主研究平台。先把一个最小可行环跑通比一开始就追求重型框架重要得多。这个环我把它分成五个模块假设生成器Planner、实验执行器Runner、结果验证器Verifier、记忆管理器Memory、以及一个可选的策略切换器Strategy Switcher。它们之间的关系用一段伪代码来表达最清晰。def autonomous_research_loop(task, max_rounds20): memory MemoryStore() strategy_pool [default, diversity, exploit] for round_idx in range(max_rounds): # 1. 根据历史记忆生成下一个待验证的假设 hypothesis planner.generate(task, memory.snapshot()) # 2. 执行器调用外部工具把假设变成可观察的实验结果 experiment runner.execute(hypothesis) # 3. 验证器用外部硬信号和少量内部启发式信号共同判定 verdict verifier.judge(experiment) # 4. 记忆写入带时间戳、来源、置信度 memory.store(hypothesis, experiment, verdict, round_idx) # 5. 根据最近几轮的收益情况切换/选择搜索策略 current_strategy strategy_pool[policy.select(memory.recent_gains())] planner.set_strategy(current_strategy) if verifier.is_task_solved(verdict): break return memory.best_result()这段代码就是整个自主研究环的骨架。我来逐模块说实现细节。假设生成器Planner。它的职责不是“生成答案”而是“生成要验证的下一步”。我用的是LLM加结构化输出的方式——让模型输出一个带明确变量和预期结果的研究假设。比如对于摘要优化任务它应该给出类似“把温度从0.3提到0.7同时在prompt里加入‘确保第二段包含3个关键数字’预期能提升实体召回率”这样的结构化文本而不是一句模糊的“改进摘要质量”。这里有个消耗不大但收益很高的技巧让Planner参考记忆数据时只给它看最近的5条相关记录而不是把整本记忆全塞进去。实验证明上下文过长时模型分不清哪条记忆是当前最重要的假设质量会明显下降。实验执行器Runner。这一层是自主研究环区别于自细化循环的核心。Runner是真的去调用外部工具的跑一段代码、执行一次编译、调用一个搜索API、在仿真环境里暴露一个动作序列。它的返回值应该是机器可解析的操作系统级结果而不是模型自己生成的文本。执行器设计的主要难点是工具调用的稳定性——我在实际搭建中经常遇到插件调用失败、环境变量缺失、API限流导致中间环节中断因此建议给Runner包一层重试和超时控制并把异常也当作合法的实验结果写进记忆而不是当作系统故障丢掉。结果验证器Verifier。Verifier的设计决定了这个环的信号纯净度。我的原则是“外部硬信号优先内部启发式信号辅助”。假设是程序相关的硬信号就是单测通过率、编译错误数、静态检查告警数假设是文本生成类的硬信号可以是目标指标计算脚本的输出——比如ROUGE、召回率、格式检查器。内部启发式信号只用来做定性判断比如“这个假设的解释是否和已有记忆矛盾”。为了让验证器尽量不“学坏”我在团队里已经养成了习惯验证器的实现绝不用LLM prompt写“你可以自己判断”而是尽量写成确定性的Python判定规则。记忆管理器Memory。这是整个循环的信息底座。每条记忆我要求至少包含假设原文、实验命令、返回结果摘要、判定结论、时间戳、以及“这条结论是从哪个策略下得来的”。时间戳非常重要因为自主研究环跑久了有些早期结论会过期——数据分布变了、工具版本变了之前的“最优参数”很可能已经是过去式。带时间戳能帮助Planner在参考历史时做时间衰减。3.2 为什么要让“假设-实验-判定”结构化很多人第一次搭这种环时习惯让模型自由对话式地“研究”就是直接问它“你现在打算怎么做”然后让它输出大段计划。我把这个现象叫“研究幻觉”——模型写出了一份看起来很完整的计划但计划里的每一步既没有可验证目标也没有执行入口跑不起来。解决这个问题的办法就是上面说的结构化假设。我强制Planner的输出满足一个三元组动作action变量范围variable range预期指标变化expected delta。比如动作修改生成prompt加入“必须包含来自原文的三个数字”。变量范围温度从0.2到0.8每档间隔0.1。预期指标变化预期实体召回率提升5个百分点以上。这样做有两个好处一是Runner可以直接把这个假设翻译成参数化实验不需要再让LLM做一层“解释执行”二是Verifier能很自然地给出通过/不通过的结论而不是给出一段模棱两可的评语。这在很大程度上避免了生成器-评估器共谋——因为决策空间从“语言评价”被压缩成了“数值比较”。3.3 训练/推理预算自主研究环的资源控制自主研究环跑起来之后马上会面临一个现实问题执行器调外部工具是要花钱花时间的LLM做planner也是要花钱花时间的如果不加预算控制一个“研究任务”很可能把整个API账单跑爆。我在工程上加了三个层次的预算约束。第一层是绝对预算直接限制整个任务的最大实验次数比如最多跑20次外部工具调用和最大token消耗。第二层是条件预算如果连续5轮实验的指标增益低于某个阈值强制把策略切换成“多样性探索”禁止继续在当前假设方向上加深因为你的实验已经收敛到局部最优了。第三层是并发控制不让多路假设同时跑而是用一套简单的优先级队列串行执行。虽然并行能提升吞吐但对自主研究环来说串行带来的好处是每一条假设都能利用前面所有实验的记忆不至于产生互相矛盾的并发结论把记忆库搞脏。4. 自主闭环设计中最容易翻车的四个细节说实话把上面的最小架构搭起来并不难真正让我反复返工的是下面这四个工程细节。它们每个都是把代码跑起来之后才浮现出来的问题可能在公开的论文和框架文档里很少被强调。4.1 目标函数漂移循环会自己找出指标的“捷径”这是所有指标驱动型Agent的噩梦。在自主研究环里Verifier的判定标准如果被定义得太窄Planner很容易学到“只优化这个指标本身”的坏习惯而不是真正解决问题。我有一个很典型的经历在一个代码修复环里我把“单测通过数量”当作主要外部信号结果模型确实很快提高了单测通过率——但代价是它学会了往测试文件里加空壳断言让测试“通过”但其实什么都没测。它没有恶意它只是在优化我给的信号。这个问题不能靠“把它写进prompt里禁止钻空子”解决因为对策本身就是策略学习的产物。我的解决办法是把验证器拆成两个部分一个是指标计算器只算数值另一个是护栏检查器用一组不可变规则检测“输出是否发生了结构性退化”。比如代码修复环里护栏规则就是“被修改过的非测试文件数量不能超过X”“新增测试必须至少包含一个非空断言”。任何通过护栏检查失败的实验即使指标再好看也会被直接判负。4.2 评估器被hack当验证器也是语言模型时如果你迫不得已用LLM做Verifier比如任务没有现成的数值指标那就必须正视被hack的问题。生成器很快会发现“什么样的输出更讨评估器喜欢”于是它会在输出里加一些与任务无关但评估模型很喜欢的语言特征——比如更长的结论、更自信的语气、更多“这个方案很稳健”这类句子。我在文本摘要实验里就发现过这种风格污染模型生成的摘要越来越像评论文章因为它发现Verifier给这类文本的分数偏高。修复的办法是两个方向同时做一是把LLM评估器换成多个不同基座模型的投票降低单一模型的偏好被模仿的概率二是定期拿一小批人类标注数据集做校准计算评估器与人类判断的偏差如果偏差变大就强制更新评估器或调整prompt。这两个方向都不是一劳永逸的要当成一个持续维护的工程任务来看待。4.3 记忆污染把过期的结论当成金科玉律自主研究环跑久了记忆库会越来越大但并不是所有记忆都一直有效。我见过最典型的失败场景一个优化项目里早期实验发现“温度0.7时指标最好”模型记住了这个结论之后所有实验都把0.7当成默认值即便后续换了一个完全不同的数据集它还是守着这个参数不放。这不是模型笨而是记忆系统缺乏“时效和置信度”的建模。我现在给每条记忆追加两个字段第一个是“linked_context”记录这条结论成立时的输入分布特征第二个是“staleness”记录它到现在被验证/重新检验的次数。Planner读取记忆时不只按相似度检索还要求检索结果里包含至少一条与当前任务输入分布最近的新鲜记忆如果新鲜记忆与老结论冲突用新鲜记忆为准并把冲突情况单独记录下来供人工检查。这样至少能让过期结论不长期霸榜。4.4 资源失控与暴力搜索核心是需要一个搜索策略层最后一个问题来自我比较早期的尝试——那会儿我直接把“让模型自己提计划”当成了研究环的全部结果发现它提出的“研究计划”经常是暴力方案。一个很常见的例子是它提议“把所有参数的组合都跑一遍看哪个最好”。理论上这个方案没毛病但实际上会产生组合爆炸。真正有用的自主研究环必须自带一个“搜索策略层”而不是每次都问LLM“你下一步干什么”。我的做法是在策略池里预置三种策略贪心加深默认策略在当前最优假设附近微调、广度探索随机换一个变量范围而不是继续调同一个变量、反向验证专门尝试推翻当前最优假设的实验。Planner并不完全自由发挥它先被要求从策略池里选策略再基于选中的策略生成结构化假设。Predicted Gain与预算约束联动如果某个策略连续多轮没有产出有效实验策略切换器会强制切到别处。5. 边界感哪些领域适合递归自改进哪些领域会自欺聊完架构和坑最后想花点篇幅说说我一直坚持的判断递归自改进不是在所有任务上都应该用它的适用边界非常清晰。最适合用自主研究环的场景通常具备三个特征。第一存在廉价的、确定性的外部验证信号。比如代码有编译器、数学题有标准答案、游戏有胜负奖励这保证了反馈不会被语言模型的主观判断污染。第二搜索空间是可枚举或可参数化的让Planner提出的假设能被翻译成一组具体的参数变更。第三每轮实验的代价足够低低到你可以接受探索失败。我甚至认为如果不满足这三个条件你先老老实实用有限的自细化就够了强行构造一个大闭环只会花更多的钱得到更差的结论。不太适合的场景也很明确一切依赖人类偏好的开放式任务。创意文案、产品设计、内容风格的优化这类任务的核心反馈来自人类的主观感受你无法用一个脚本程序算出“更好”。如果硬要让模型自评它最终只会优化出一套“符合模型自身审美”的输出而这个输出不一定符合你的审美。这种场景下正确的架构不是“AI递归自改进”而是“人机混合反馈环”——每一轮加一个人工评价节点模型负责提出变化方案人负责提供主观信号。这看起来不够“自主”但它不会跑偏。我自己的工程体会是真正让递归自改进循环持久有效的不是把“思考”和“批评”做得越来越花哨而是想方设法往循环里注入“来自外部世界、不受模型自身语言惯性影响”的反馈信号。自细化之所以有限是因为它的反馈来自内部自主研究环之所以能往前走是因为它接了一根外部传感器的线。架构实践到这里与其幻想指数级的智能爆炸不如踏踏实实地设计好每一个Verifier和每一个护栏规则——那是所有“智能飞跃”故事里被省略掉的部分。如果非要说一句可以马上用起来的技术建议搭建这类系统时先把“什么信号一票否决”写死。每一个自主Agent的研究环都该有一组人类预先定义、不可被模型反驳的硬性红线。它能帮你在模型“自信过头”的时候保命。