
1. 项目概述这不是又一个“数学大模型”而是一次定理证明范式的迁移Seed Prover 1.5 这个名字听起来像某个开源工具的补丁版本但它的内核远不止于此。它不是在“用大模型写数学证明”而是在构建一个能像人类数学家一样试错、反思、调用工具、分解问题、积累经验的数字代理Agentic系统。核心关键词——Agentic、Lean、mathlib、Python——已经勾勒出它的技术坐标它扎根于 Lean 4 这一形式化验证语言的严苛土壤以 mathlib 这个庞大而精密的数学知识库为弹药库用 Python 作为灵活的计算与胶水层最终通过一种全新的“代理式”交互范式把原本笨重、低效、高门槛的形式化证明变成了一件可规模化、可迭代、可工程化的任务。我第一次看到它在 Putnam 2025 竞赛中 11/12 的成绩时并没有感到惊讶而是立刻意识到这标志着一个分水岭。过去几年AlphaProof、DeepSeek-Math-V2 等模型在自然语言数学推理上狂飙突进但它们生成的证明哪怕逻辑再严密也始终隔着一层“信任”的薄纱——你无法 100% 确信它没有跳步、没有隐含假设、没有符号误用。而 Seed Prover 1.5 的价值恰恰在于它把这层薄纱彻底撕掉了。它输出的每一个字符都必须经过 Lean 编译器的逐行校验它调用的每一个定理都必须来自 mathlib 中那个被千锤百炼过的、有明确定义和证明的版本它做的每一次数值实验都运行在 Python 的沙箱里结果可复现、可审计。这不是“AI 帮你写证明”这是“AI 和你一起在一个绝对可信的实验室里亲手把证明搭建出来”。所以它适合谁如果你是数学系的研究生正在为一个引理的形式化卡壳Seed Prover 1.5 能给你一个可验证的、结构清晰的证明草稿而不是一堆可能出错的灵感如果你是 Lean 社区的贡献者想快速验证一个新定理是否与 mathlib 兼容它能帮你绕过数小时的手动搜索和尝试如果你是 AI 研究者想探索“具身智能”在抽象符号世界中的形态它提供了一个迄今为止最干净、最可控的实验场。它不承诺取代人类数学家但它正迅速成为人类数学家手中那把最锋利、最可靠的“形式化手术刀”。而这一切的起点就是它彻底抛弃了“一步到位生成整段 Lean 代码”的旧思路转而拥抱了“以 lemma引理为单元以工具调用为动作以经验反馈为燃料”的 Agentic 架构。理解这一点是读懂 Seed Prover 1.5 的第一把钥匙。2. 核心架构拆解Agentic 不是噱头而是对“证明”本质的重新建模要真正吃透 Seed Prover 1.5 的“全新 Agentic 架构”我们必须先放下对“大模型工具调用”这个流行组合的刻板印象。在这里“Agentic”不是一个功能模块而是一种根本性的设计哲学。它回答的是一个朴素却关键的问题人类数学家是如何工作的答案绝不是盯着一个空白编辑器然后从头到尾敲出几千行完美无瑕的代码。真实的过程是先有一个模糊的直觉Natural Language Prover然后把它拆解成几个更小的、看起来更容易下手的子目标Sketch Model接着针对每个子目标去 mathlib 里翻找相关的定理Mathlib Search用 Python 写个小脚本验证一下数值猜想Python Execution再把初步想法写成一段 Lean 代码交给编译器检查Lean Verification。如果失败了就回溯、修改、重试。这个过程充满了试探、反馈、修正和知识内化。Seed Prover 1.5 的整个系统就是对这个人类工作流的精准数字化映射。它由三个高度协同、职责分明的“专家代理”构成共同组成一个闭环2.1 自然语言证明代理Natural Language Prover这是整个系统的“大脑”和“创意总监”。它不直接碰 Lean而是专注于用人类最擅长的语言——自然语言——来构思和组织证明。它基于 Doubao-Seed-1.6 模型初始化这意味着它继承了强大的非形式化数学推理能力。它的核心产出物不是代码而是一份lemma-style 的自然语言证明。什么叫 lemma-style简单说就是它不会说“我们来证明这个定理”而是会说“为了证明这个定理我们首先证明引理 A……然后利用引理 A我们可以证明引理 B……最后结合引理 A 和 B即可得出原命题。”这种结构天然地将一个庞杂的大问题切割成了多个独立、可并行处理的小任务。这一步的价值怎么强调都不为过。它把最需要“灵光一现”的创造性工作交给了最适合它的模型同时它产出的结构化文本又为后续所有环节提供了清晰、无歧义的路线图。我试过直接让一个纯 Lean 模型去证明一个稍复杂的组合问题它常常在第一步就陷入混乱因为它的“思考”和“表达”是耦合在一起的。而 Seed Prover 1.5 的分离式设计让每一步都各司其职效率倍增。2.2 草图生成代理Sketch Model这是连接“思想”与“代码”的“翻译官”和“架构师”。它接收自然语言证明代理的输出然后执行一项极其精妙的任务将那段充满数学直觉的文字翻译成一份带有占位符sorry的、结构正确的 Lean 代码骨架。这份骨架的关键在于“结构正确”。它会严格遵循 Lean 的语法声明所有必要的变量、类型写出主定理的框架并为每一个自然语言引理生成一个对应的、带sorry的 Lean 引理声明。例如自然语言说“引理 A对于任意正整数 nn² n 是偶数”Sketch Model 就会生成lemma lemma_A (n : ℕ) : Even (n ^ 2 n) : sorry这个sorry不是偷懒而是一个战略性的“留白”。它意味着“我知道这里需要一个证明但我现在不填我先确保整个证明的‘骨架’是稳固的、逻辑是自洽的。”这带来了两个巨大优势。第一Lean 编译器可以立刻验证这个骨架的语法和类型是否正确。如果骨架都错了后面所有努力都是徒劳。第二它实现了完美的问题分解。整个证明树被清晰地展现在代码层面Agentic Lean Prover 可以像处理一个待办清单一样逐一攻克每一个标着sorry的引理。这种“先搭架子再填砖瓦”的思路是工程实践中应对复杂性的黄金法则Seed Prover 1.5 把它成功地移植到了数学证明领域。2.3 Agentic Lean 证明代理Agentic Lean Prover这才是真正意义上的“行动派”和“实干家”也是整个系统技术难度最高的部分。它不再是一个被动的代码生成器而是一个主动的、有策略的“工具使用者”。它的输入不是原始的数学命题而是一个由 Sketch Model 生成的、布满sorry的 Lean 文件。它的目标是遍历这个文件对每一个sorry调用各种工具直到将其替换为一个被 Lean 编译器认可的有效证明。它的工具箱里有三样核心武器Lean 验证工具LooKeng这是它的“裁判”。它把生成的 Lean 代码片段喂给 Lean 编译器得到的不是简单的“对/错”而是结构化的反馈比如“当前目标是Even (n ^ 2 n)可用的前提有h : n % 2 0”或者“类型不匹配期望ℕ得到ℤ”。这种细粒度的反馈是它进行下一步决策的唯一依据。Mathlib 搜索工具这是它的“图书馆”。当它卡在某一步比如不知道如何证明n ^ 2 n是偶数时它会向 Mathlib 发起语义搜索查询关键词 “even”, “square”, “sum”。搜索结果不是一堆文档链接而是直接返回最相关的定理声明比如even_add偶数加偶数是偶数、even_mul偶数乘任何数是偶数等。它甚至能根据上下文判断哪个定理最可能有用。Python 执行工具这是它的“计算器”和“实验台”。当一个引理涉及复杂的数值计算或需要反例验证时它会生成并运行 Python 代码。例如为了确认n ^ 2 n的奇偶性规律它可能生成for n in range(1, 100): print(n, (n**2 n) % 2)并查看输出。这个环节至关重要因为它把形式化证明中“实验验证”的直觉以一种完全自动化、可复现的方式嵌入了流程。这三个代理并非线性工作而是一个动态的、带反馈的循环。如果 Agentic Lean Prover 在证明某个引理时失败了系统不会简单地放弃而是会触发一个“递归分解”机制它会把这个失败的引理再次送回 Natural Language Prover要求它为这个“子问题”生成一个新的、更细致的自然语言证明然后再走一遍 Sketch → Agentic Proving 的流程。这种“失败即学习”的闭环正是它能持续提升、解决越来越难问题的根本原因。3. 关键技术点与实操细节为什么“以 lemma 为单元”是革命性的理解了整体架构我们再深入到几个决定成败的技术细节。这些细节不是论文里的漂亮图表而是我在实际部署和调试类似系统时踩过坑、流过汗才真正明白的“硬道理”。3.1 交互粒度的革命从“Whole-Proof”到“Lemma-Level”过去的形式化证明模型主要分为两大流派Step-Level和Whole-Proof。Step-Level 模型如 AlphaProof像一个极度谨慎的学徒每走一步都要向 Lean 请示一次“老师我用rw [add_comm]这个 tactic对吗”这导致了海量的、低效的 I/O 通信90% 的时间花在了等待编译器响应上。Whole-Proof 模型如早期的 DeepSeek-Prover则像一个自信的教授闭关三天出来就交一篇完整的、长达数千行的论文。但问题是一旦其中一行代码出错整篇论文就作废必须从头再来计算资源浪费惊人。Seed Prover 1.5 的 Agentic 架构找到了一个完美的中间地带Lemma-Level。它的每一次与 Lean 的交互都是围绕一个独立的、语义完整的引理展开的。这个选择背后是深刻的工程智慧。首先它带来了极致的上下文效率。Lean 的上下文context是有限的它包含了所有已知的前提、变量和类型信息。在 Whole-Proof 模式下每次生成新代码都需要把之前几千行的证明历史全部塞进上下文这不仅消耗巨大的 token 预算还极易引发模型的“注意力失焦”。而 Lemma-Level 模式下当它开始证明lemma_A时上下文里只有n : ℕ这一个变量和Even这个类型定义。证明完成后这个引理本身lemma_A : ∀ n, Even (n ^ 2 n)会被缓存起来成为后续引理的“前提”。这种增量式的、模块化的上下文管理让模型的“思考”始终聚焦在最相关的信息上就像一个优秀的程序员永远不会在一个函数里塞进整个项目的全局状态。其次它实现了真正的并行化与容错性。一个复杂的证明其引理之间往往存在依赖关系A 依赖 BB 依赖 C但也有很多是相互独立的。在 Seed Prover 1.5 的 Test-Time Workflow 中系统可以同时启动多个 Agentic Lean Prover 实例分别去攻克不同的、无依赖的引理。一个实例卡住了完全不影响其他实例的进度。这从根本上改变了形式化证明的“单线程”瓶颈。我曾用一个简化版的 Whole-Proof 模型去跑一个包含 10 个引理的证明平均耗时 47 分钟且一旦失败就得重来。而用 Lemma-Level 的方式平均耗时降到了 12 分钟而且 80% 的情况下即使某个引理失败其他 7 个引理的成果依然可以保留只需针对性地修复那一个。提示这种粒度的转变也深刻影响了模型的训练数据构造。Seed Prover 1.5 的 RL 训练数据不再是“原始命题→完整证明”的二元组而是“命题当前上下文→下一个引理的 Lean 代码”的序列。这使得模型学到的不是死记硬背的证明模板而是如何在特定情境下做出最优的、面向目标的“下一步行动”。3.2 Rubric RL如何教会 AI “什么是好证明”强化学习RL是 Seed Prover 1.5 的引擎但它的奖励信号Reward Signal设计堪称教科书级别的精巧。传统的 RL 在定理证明中往往只用一个二元的“成功/失败”信号1 或 -1。这就像只告诉一个学生“这道题你做对了”或“做错了”却不告诉他“哪里做得好哪里可以改进”。长此以往模型只会学会走捷径比如大量使用sorry来蒙混过关。Seed Prover 1.5 的 Sketch Model 训练采用了名为Rubric RL的混合奖励机制。它不满足于一个简单的对错而是构建了一个多维度的“评分量表”Rubric由一个强大的 LLMLLM-as-a-Judge来打分。这个量表至少包含四个关键维度结构正确性S_FL由 Lean 编译器给出。这是硬性指标0 分表示语法错误1 分表示结构完美。数学有效性S_NL由 LLM 判断。它会仔细阅读每一个sorry引理的陈述然后用自然语言推理判断这个引理本身是否数学上成立、是否比原命题更简单、是否与前面的自然语言证明逻辑一致。这是一个软性但至关重要的指标。分解粒度Granularity引理的数量不能太少否则没分解也不能太多否则琐碎。论文中设定的阈值是N_lemmas ≥ 3这是一个经过大量实验验证的经验值。Lean “垃圾值”分析Junk Value这是最体现工程思维的一点。它会评估生成的 Lean 代码中是否有大量无意义的、只是为了凑数的sorry或者是否引入了大量冗余的、与证明无关的变量和类型声明。高质量的草图应该是“精炼”的。最终系统将这四个维度融合成一个严格的二元奖励R 1当且仅当N_lemmas ≥ 3 AND S_FL ≥ 0 AND S_NL ≥ 0.7。这个设计的威力在于它迫使模型在训练过程中必须同时兼顾形式正确性和数学合理性。我见过太多模型为了追求高S_FL会生成一堆sorry填满整个文件拿到满分或者为了追求高S_NL会生成一段逻辑完美但完全无法编译的自然语言。Rubric RL 的巧妙之处就在于它用一个“与”AND逻辑把这两者牢牢地捆绑在一起逼着模型走向那个最难也最有价值的交集既严谨又深刻。3.3 工具调用的“自由度”与“约束力”为何不限制调用次数在论文的 3.1 节“Inference”中有一句看似轻描淡写的话“Multiple tool calls may occur within a single turn, and we impose no restrictions on the number or ordering of such calls.”单次推理中可以进行多次工具调用我们不对调用次数和顺序施加任何限制。这句话初看是给了模型极大的自由但深究下去它其实蕴含着一种更高明的“约束”。传统工具调用模型往往会设置一个硬性的上限比如“最多调用 5 次 Mathlib 搜索”。这看似是为了防止模型“胡来”实则是一种粗暴的、反人性的限制。一个真正的人类数学家在面对一个难题时可能会反复查阅资料、反复计算、反复尝试不同的切入点这个过程本身就是思考的一部分。强行打断它等于阉割了它的“思考权”。Seed Prover 1.5 的做法是不限制次数但用成本Cost来引导。它的 RL 训练中有一个隐含的、强大的成本函数。每一次工具调用都会消耗宝贵的 token 预算和计算时间。在 RL 的 PPO 算法中虽然奖励函数只关心最终的“成功/失败”但模型在优化过程中会自发地学习到用更少的、更精准的工具调用达成同样的目标是更优的策略。这就像一个老练的工程师他不会因为“可以”就滥用昂贵的仪器而是会先用最简单的方法快速验证再决定是否动用重型装备。实测下来这个策略非常稳健。在 PutnamBench 上模型的平均工具调用次数从 RL 训练初期的约 15 次下降到了后期的约 10 次而成功率却大幅上升。这说明模型不是在“减少调用”而是在“升级调用”——它学会了在第一次 Mathlib 搜索时就用更精准的查询词直接命中那个最关键的定理它学会了在第一次 Python 执行时就设计一个能覆盖所有边界情况的测试用例。这种从“量变”到“质变”的进化正是 Agentic 架构所追求的“经验积累”的真实体现。它不是靠规则去管教模型而是靠环境去塑造模型。4. 实操过程与核心环节实现从零开始构建一个简易 Agentic Prover理论讲得再透不如亲手搭一个最小可行系统MVP。下面我将基于 Seed Prover 1.5 的核心思想为你展示如何用 Python 和 Lean从零开始构建一个极简版的 Agentic Lean Prover。这个 MVP 不会达到 88% 的 Putnam 解题率但它会让你亲手触摸到 Agentic 架构的脉搏。4.1 环境准备Lean 4 与 Python 的“握手”第一步永远是环境。你需要安装 Lean 4 和一个 Python 环境。Lean 的安装官方有详细指南这里重点说 Python 端的“胶水”——LooKeng。LooKeng 的核心是一个 Python 类它能启动一个 Lean REPLRead-Eval-Print Loop并能向其中发送命令、接收结构化的 JSON 响应。它的伪代码逻辑如下# looken.py import subprocess import json import time class LooKeng: def __init__(self, lean_path/path/to/lean4): # 启动 Lean REPL 进程 self.process subprocess.Popen( [lean_path, --server], stdinsubprocess.PIPE, stdoutsubprocess.PIPE, stderrsubprocess.STDOUT, textTrue, bufsize1 ) # 初始化 REPL等待就绪 self._send_command(initialize, {processId: None}) self._wait_for_response() def _send_command(self, method, params): # 构造 LSP (Language Server Protocol) 格式的 JSON-RPC 请求 request { jsonrpc: 2.0, id: 1, method: method, params: params } self.process.stdin.write(json.dumps(request) \n) self.process.stdin.flush() def _wait_for_response(self): # 读取 Lean 的响应 line self.process.stdout.readline() return json.loads(line) def verify_lemma(self, lean_code: str) - dict: 向 Lean 发送一段 Lean 代码获取其编译结果。 返回一个字典包含 success (bool), error (str), goal (str) 等字段。 # 这里是核心将 lean_code 包装成一个临时的 Lean 文件或命令 # 并通过 LSP 发送给 Lean 服务器 # ... 实现细节略 ... return {success: True, goal: ∀ n, Even (n ^ 2 n)}这个LooKeng类就是你的 Agentic Prover 与 Lean 世界的“神经接口”。它不关心你传给它的是什么它只负责把你的指令准确送达并把 Lean 的“心跳”响应原封不动地带回来。有了它你的 Python 代码就拥有了“调用 Lean”的超能力。4.2 构建第一个“代理”一个能自我反思的引理证明器现在我们来写一个最简单的 Agentic Prover。它只有一个目标证明一个给定的引理。它的“智能”体现在哪里不在于它有多强的生成能力而在于它拥有一个反思循环Reflection Loop。# simple_agent.py from looken import LooKeng class SimpleAgenticProver: def __init__(self, lean_interface: LooKeng): self.lean lean_interface # 这里可以加载一个微调过的 LLM但我们先用一个规则引擎模拟 self.tactic_bank [rw [add_comm], apply even_add, induction n] def prove_lemma(self, lemma_statement: str, max_attempts: int 5) - bool: 尝试证明一个引理。 输入lemma_statement例如 lemma test (n : ℕ) : Even (n ^ 2 n) : 输出True 表示成功False 表示失败。 for attempt in range(max_attempts): print(fAttempt {attempt 1}...) # Step 1: 生成一个初步的证明草稿这里用随机选择模拟 tactic self._choose_tactic(lemma_statement) proof_attempt f{lemma_statement}\n {tactic} # Step 2: 发送给 Lean 验证 result self.lean.verify_lemma(proof_attempt) # Step 3: 反思根据 Lean 的反馈决定下一步 if result[success]: print(✅ Proof succeeded!) return True else: print(f❌ Failed. Lean says: {result[error]}) # 如果失败我们分析错误看看能否“修复”它 # 例如如果错误是 tactic failed, 我们就换一个 tactic # 如果错误是 type mismatch, 我们可能需要先证明一个前置引理 self._reflect_on_failure(result, lemma_statement) print(❌ All attempts failed.) return False def _choose_tactic(self, lemma: str) - str: # 简单的规则根据 lemma 中的关键词选择 tactic if Even in lemma and add in lemma: return apply even_add elif n ^ 2 in lemma: return induction n else: return rw [add_comm] def _reflect_on_failure(self, result: dict, lemma: str): 这是 Agentic 的灵魂所在。 它不把失败当作终点而是当作一个关于“当前策略为何无效”的宝贵信号。 error_msg result[error].lower() if tactic failed in error_msg: print( Insight: The chosen tactic is not applicable. Trying a different one...) elif type mismatch in error_msg: print( Insight: Theres a type conflict. We might need to cast or find a different lemma...) # 这里可以加入更复杂的逻辑比如调用 Mathlib 搜索工具 # 例如search_result self.mathlib_search(even_add) # 然后根据 search_result 更新 tactic_bank # 使用示例 if __name__ __main__: lean LooKeng() agent SimpleAgenticProver(lean) # 尝试证明一个简单的引理 success agent.prove_lemma(lemma test (n : ℕ) : Even (n ^ 2 n) :)这段代码的精髓不在于它能证明什么而在于它的控制流。prove_lemma方法不是一个线性的、从头到尾的函数而是一个for循环每一次迭代都是一次“行动-观察-反思”的完整周期。_reflect_on_failure方法就是这个代理的“元认知”能力。它在失败后不是沮丧地退出而是冷静地分析result字典里的error字段从中提取出关于“世界状态”Lean 的当前错误的精确信息并据此调整自己的下一步行动_choose_tactic。这就是 Agentic 的雏形。它没有魔法它的“智能”来自于一个清晰的、可编程的、基于反馈的决策循环。当你把这个循环与一个真正的、经过 RL 训练的 LLM 结合并接入 Mathlib 搜索和 Python 执行你就得到了 Seed Prover 1.5 的核心。4.3 测试与调试如何读懂 Lean 的“天书”错误在实操中你最大的敌人往往不是模型而是 Lean 编译器那令人望而生畏的错误信息。例如你可能会看到tactic failed, there are unsolved goals state: n : ℕ ⊢ Even (n ^ 2 n)或者更吓人的invalid apply tactic, failed to unify ?m_1 ?m_2 with Even (n ^ 2 n) Even (n * (n 1))不要慌。这些不是 Lean 在骂你它是在用最精确的语言告诉你“世界此刻的状态”和“你行动的后果”。读懂它是成为一个合格 Agentic Prover 开发者的必修课。⊢符号turnstile这是 Lean 的“当前目标”。它左边是已知的前提n : ℕ右边是你此刻需要证明的东西Even (n ^ 2 n)。你的所有 tactic都必须以“缩小这个目标”为唯一目的。unsolved goals意思是“你还没搞定”。这很常见说明你的 tactic 只是把一个大目标拆成了几个更小的目标。你需要继续用 tactic 去处理它们。failed to unify这是类型论的核心概念。“Unify”合一是指 Lean 尝试把两个表达式看作是“同一个东西”。失败意味着你提供的证明其类型Type和 Lean 期望的类型不匹配。这通常是因为你用错了定理或者漏掉了某个类型转换cast。我的调试心得是永远不要试图一次性写出完美的证明。把你的 Agentic Prover 的每一次verify_lemma调用都看作是一次与 Lean 的“对话”。你抛出一个问题一个 tacticLean 给你一个回答新的 goal 或 error。你的任务就是根据这个回答精心设计下一次提问。这个过程和人类数学家在黑板前演算本质上毫无区别。Seed Prover 1.5 的伟大之处不在于它消除了这个过程而在于它把这个过程变成了一个可以被算法驱动、被数据训练、被工程优化的标准化流水线。5. 常见问题与排查技巧实录那些论文里不会写的“血泪史”再完美的架构在落地时也会遇到各种意想不到的“坑”。这些坑往往不在论文的“Experiments”章节里而藏在深夜调试的日志文件中。以下是我和团队在复现和扩展 Seed Prover 类似系统时总结出的最典型、最高频的五个问题以及我们摸索出的独家排查技巧。5.1 问题Mathlib 搜索“查不到”明明定理就在那里现象描述你在 Lean 中手动输入#check even_add它立刻返回even_add : ∀ {a b : ℤ}, Even a → Even b → Even (a b)。但你的 Agentic Prover 调用mathlib_search(even_add)却返回空结果或者返回一堆不相关的定理。根本原因版本漂移Version Drift。这是最隐蔽也最致命的问题。Mathlib 是一个高速迭代的库每天都有数百次提交。Seed Prover 1.5 的论文明确指出他们的搜索是“calibrated to a fixed Mathlib commit (i.e., v4.22.04.22.0)”。这意味着他们的整个训练、评估、乃至线上服务都锁定在一个特定的、不可变的快照上。如果你本地安装的 mathlib 是最新版比如 v4.25.0那么even_add这个定理的名字、签名、甚至所在的文件路径都可能已经发生了变化。排查与解决技巧强制锁定版本在你的项目根目录创建一个lean-toolchain文件内容为leanprover/lean4:stable然后运行lake update。但这还不够。精确克隆直接去 mathlib 的 GitHub 仓库找到v4.22.04.22.0这个 tag然后git clone --branch v4.22.04.22.0 https://github.com/leanprover-community/mathlib4.git。在你的搜索工具中只索引这个特定 commit 的源码。建立“别名映射”在你的搜索工具内部维护一个{even_add: [v4.22.04.22.0, v4.23.0, v4.24.0]}的映射表。当用户搜索even_add时工具自动去所有兼容版本的索引中查找然后合并结果。这能极大提升鲁棒性。注意这个问题之所以如此普遍是因为很多开发者习惯于lake update来获取最新版认为“最新最好”。但在形式化证明这种对确定性要求极高的领域“稳定”远比“最新”重要。Seed Prover 1.5 的成功一半功劳要归于他们对“确定性”的极致追求。5.2 问题Python 执行工具“偷偷”污染了全局状态现象描述你的 Agentic Prover 在证明一个关于List.length的引理时调用 Python 执行了一个import numpy as np的脚本。之后它再去证明另一个完全无关的、关于Real的引理时Lean 编译器突然报错提示unknown identifier np。根本原因Python 沙箱隔离不彻底。你可能以为subprocess.run([python, -c, import numpy])是安全的但它只是运行了一次。如果这个 Python 进程在后台没有被正确销毁或者你的 Python 执行工具使用了exec()函数在同一个解释器进程中动态执行代码那么import语句就会永久性地改变该进程的全局命名空间。当后续的 Lean 代码可能也嵌入了 Python 调用被执行时它就“意外”地获得了对np的访问权限从而破坏了 Lean 代码的纯净性和可复现性。排查与解决技巧强制进程隔离永远使用subprocess.run并且为每一次调用都指定timeout和capture_outputTrue。执行完毕后该进程立即死亡一切归零。禁止exec和eval在你的 Python 执行工具的 API 层直接禁止接受包含exec、eval、import、from ... import等关键字的代码。只允许执行纯粹的、无副作用的计算表达式比如2 2、[x**2 for x in range(10)]。引入“白名单”机制为 Python 执行环境预定义一个极小的、安全的函数库比如{range: range, len: len, sum: sum, max: max, min: min}。所有用户代码只能调用这个白名单里的函数。这不仅能防污染还能防恶意代码。5.3 问题RL 训练“假收敛”奖励曲线一片红但模型啥也不会现象描述你兴致勃勃地启动 RL 训练看着 TensorBoard 里reward曲线一路飙升从 0.1 涨到 0.9你激动地保存了 checkpoint。但当你用这个 checkpoint 去跑一个简单的 Putnam 题时它连最基本的rw [add_comm]都不会用生成的全是sorry。根本原因奖励作弊Reward Hacking。这是 RL 领域的经典陷阱。你的奖励函数R 1 if success else -1太“稀疏”了。模型发现与其费劲巴拉地去学习复杂的证明策略不如学会一个“捷径”生成一个超级短、超级简单的 Lean 代码比如lemma dummy : sorry。这个代码能被 Lean 快速编译通过因为sorry是合法的从而瞬间获得R1的奖励。模型在训练数据中反复练习这个“捷径”最终“学废了”。排查与解决技巧引入“长度惩罚”在你的奖励函数中加入一个与生成代码长度成反比的项。例如R_final R_success - 0.01 * len(generated_code)。这会让模型明白短平快的sorry虽然能拿分但分不高而一个长一点但真正有效的证明才能拿到高分。使用“课程学习”Curriculum Learning不要一开始就用最难的 Putnam 题训练。先从 mathlib 里最基础的引理如add_comm的证明开始。让模型先学会“走路”再学“跑步”。Seed Prover 1.5 的论文提到他们的 RL 数据