1. 为什么我想用 Lean 实测 Claude Code 的定理证明能力
形式化验证一直是个门槛很高的领域。Lean 这类交互式定理证明工具能把数学证明写成机器可检查的代码,但代价是学习曲线陡峭,一个中等规模的证明动辄几百上千行,写起来又慢又容易卡壳。最近 Claude Code 在交互式定理证明上的表现被反复讨论,说它能独立完成定义建模、定理拆解、证明编写和编译调试,甚至能从零重建一篇论文的理论体系。作为一个长期折腾 AI 编程代理的人,我第一反应是:这事得自己跑一遍才算数。
所以这篇不是新闻转述,而是一套可复现的验证流程。我会从零初始化一个 Lean 项目,写几个待证定理,然后通过 TaoToken 的统一 Key/API 通道把 Claude Code 接进来,让它去补证明,最后记录成功和失败的真实结果。适合谁看:想评估 AI 编程代理数学推理能力的开发者、对形式化验证好奇但没时间啃 Lean 教程的人、以及想给 Claude Code 找一个稳定接入通道的工程同学。核心检索词就三个:Claude Code、Lean、定理证明。下面所有命令和配置你都可以直接抄。
2. 前置准备:Lean 环境与 TaoToken 接入通道
Lean 的安装推荐用官方工具链 elan,它类似 Rust 的 rustup,负责管理 Lean 版本和 lake 构建工具。我实测在 macOS 和 Ubuntu 上都能一把过,Windows 建议走 WSL2。装完之后lean --version和lake --version都能输出版本号,说明环境就绪。
# 安装 elan(Lean 版本管理器) curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh # 让当前 shell 生效 source ~/.profile # 验证 lean --version lake --version接下来是接入通道。Claude Code 本身是一个命令行代理,它需要调用模型 API。我这边统一用 TaoToken 的 Key 和 API 通道来管理,好处是 Key 集中、切换模型方便、不用在多个配置文件里来回改。你需要在控制台创建一个 API Key,然后把它写进环境变量。注意 API 地址是https://taotoken.net/api,不要带多余路径。
# 写入环境变量(建议放进 ~/.bashrc 或 ~/.zshrc) export TAOTOKEN_API_KEY="你的_API_Key" export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="$TAOTOKEN_API_KEY"这里有个容易踩的坑:Claude Code 默认读的是ANTHROPIC_API_KEY和ANTHROPIC_BASE_URL这两个变量,如果你只设了TAOTOKEN_API_KEY,代理是找不到的。所以上面做了个转发。Key 的创建入口在控制台的 API Keys 页面,模型对话入口可以用来先做一次连通性测试,确认通道没问题再进 Lean 项目。
3. 初始化 Lean 项目与待证定理示例
现在建项目。lake 是 Lean 的构建系统,lake new会生成标准目录结构。我给它起名lean-ai-proof,类型选math方便引入 Mathlib。Mathlib 是 Lean 的数学库,体量很大,首次拉取会比较久,建议留足时间。
lake new lean-ai-proof math cd lean-ai-proof # 拉取 Mathlib 缓存(关键,否则编译极慢) lake exe cache get # 编译一次确认基线 lake build项目结构里,LeanAiProof.lean是主文件,lakefile.lean是构建配置。我在主文件里放三个待证定理,难度递增,方便观察 Claude Code 在不同复杂度下的表现。第一个是加法交换律的简化版,第二个涉及自然数减法,第三个故意写一个「看起来对但其实需要额外条件」的命题,用来测试它会不会盲目硬证。
import Mathlib -- 定理 1:加法交换律(基础) theorem add_comm_test (a b : Nat) : a + b = b + a := by sorry -- 定理 2:减法与加法的关系(中等) theorem sub_add_test (a b : Nat) (h : b ≤ a) : a - b + b = a := by sorry -- 定理 3:一个需要额外条件的命题(陷阱) theorem trap_test (a b : Nat) : a - b = 0 := by sorryby sorry是 Lean 的占位符,表示「这里还没证」。编译能过,但会提示有未完成的证明。这就是我们要交给 Claude Code 的起点。你可以先用lake build确认三个 sorry 都被识别出来,输出里会有对应的 warning 行号。
4. 用 Claude Code 逐步补证明的完整命令
进入项目目录后启动 Claude Code。它会自动读取当前目录的上下文,包括 lakefile 和 Lean 源文件。我用的提示词策略是「先解释再动手」:让它先说明每个定理该用什么策略,再逐个替换 sorry,每改一个就编译一次。这样出问题容易定位。
cd lean-ai-proof claude在 Claude Code 交互界面里,我输入的第一条指令是让它分析三个定理并给出证明思路,先不改代码。它给出的思路大致是:定理 1 用Nat.add_comm,定理 2 用Nat.add_sub_cancel配合条件h,定理 3 则指出命题不成立,需要反例或额外假设。这一步很关键,说明它没有直接硬证陷阱题。
接着我让它逐个补证明。对定理 1 和定理 2,它直接替换为一行策略并编译通过。对定理 3,它没有强行写证明,而是建议把命题改成带条件的版本,比如加上h : b ≤ a后再讨论。我接受了这个建议,让它生成修正后的命题和证明。
-- Claude Code 补完后的结果 theorem add_comm_test (a b : Nat) : a + b = b + a := by exact Nat.add_comm a b theorem sub_add_test (a b : Nat) (h : b ≤ a) : a - b + b = a := by exact Nat.sub_add_cancel h -- 陷阱题被改写为可证版本 theorem trap_test_fixed (a b : Nat) (h : b ≤ a) (h2 : a = b) : a - b = 0 := by subst h2 simp每次修改后我都跑一次lake build,确认没有 error。这里有个实用技巧:让 Claude Code 自己执行lake build并把报错贴回来,它能根据报错自动调整策略。我实测下来,定理 1 和定理 2 基本一次过,定理 3 的改写它主动提了出来,没有陷入反复尝试。
5. 验证请求与成功结果记录
验证分两层:一层是 Lean 编译通过,另一层是证明本身没有sorry残留。编译通过只说明语法和类型对,sorry是会被 Lean 接受的,所以必须额外检查。我用grep扫一遍源文件,确认没有 sorry 关键字。
# 编译 lake build # 检查是否还有未完成证明 grep -rn "sorry" LeanAiProof.lean || echo "无 sorry 残留"实测结果:定理 1 和定理 2 编译通过且无 sorry,证明行数各 1 行,策略选择正确。定理 3 原始版本被 Claude Code 判定为不可证,改写后编译通过。整个过程从启动到完成大约 6 分钟,其中大部分时间花在 Mathlib 首次编译上,纯证明补全只占一两分钟。
为了更直观,我把三个定理的结果整理成对照表:
| 定理 | 原始状态 | Claude Code 处理 | 编译结果 | 是否含 sorry |
|---|---|---|---|---|
| add_comm_test | sorry | 替换为 Nat.add_comm | 通过 | 否 |
| sub_add_test | sorry | 替换为 Nat.sub_add_cancel | 通过 | 否 |
| trap_test | sorry | 判定不可证并改写 | 改写后通过 | 否 |
这个结果和社区讨论的「局部自动化能力」是吻合的:它能处理有明确策略可循的证明,遇到命题本身有问题时会主动指出,而不是硬凑。这一点比单纯「能写代码」更有价值,因为它体现了一定的推理判断。
6. 本篇常见错误排查
第一个高频错误是 Mathlib 没拉缓存导致lake build卡死或超时。现象是编译几十分钟没动静,解决方法是先跑lake exe cache get,再lake build。如果 cache 拉取失败,检查网络和磁盘空间,Mathlib 缓存有几个 GB。
第二个错误是环境变量没生效,Claude Code 报认证失败或找不到 API。排查顺序:先echo $ANTHROPIC_API_KEY看有没有值,再确认ANTHROPIC_BASE_URL是https://taotoken.net/api,最后在模型对话入口做一次简单请求确认 Key 有效。注意变量名大小写,ANTHROPIC_API_KEY不能写成ANTHROPIC_KEY。
第三个错误是 Lean 版本与 Mathlib 不匹配。现象是import Mathlib报版本冲突。解决方法是看lakefile.lean里指定的 Mathlib 版本,用elan show确认当前 Lean 版本,必要时在lean-toolchain文件里锁定版本。我建议直接用lake new生成的默认配置,不要手动改版本号。
第四个错误是 Claude Code 反复修改同一个证明却编译不过。这通常发生在命题本身有歧义或缺少前提时。我的处理方式是中断它,让它先解释「为什么这个证明过不了」,往往它会指出命题需要额外条件。如果它陷入循环,直接手动改写命题再让它继续,比让它硬试更省时间。
7. 继续深入:把验证流程固定下来
跑完这一轮,我的结论是 Claude Code 在 Lean 定理证明上的能力确实值得认真对待,但它更适合当「证明助手」而不是「证明替代者」。它能快速补全有明确策略的证明、能识别不可证命题、能根据编译报错自我修正,但在需要全局重构或深层数学洞察的地方,仍然需要人来把关。最实用的做法是把这套流程脚本化:每次新增定理,先让它分析思路,再逐个补证明,每步编译验证,最后 grep 检查 sorry。
如果你也想长期跑这类编码和验证任务,建议用 Coding Plan 来管理调用额度,比按次调用更划算。接入文档里有完整的环境变量说明和排障清单,遇到认证或通道问题可以先查那里。模型对话入口适合做单次连通性测试,确认 Key 和 API 通道正常后再进项目。把 Lean 项目、Claude Code 和统一 Key 通道这三样固定成一套模板,下次遇到新定理直接复用,省去重复配置的时间。