让 LLM 帮你写一个排程算法、装箱方案或者路径规划的代码——听起来是个很自然的使用场景。但一篇来自宾夕法尼亚大学(Dan Roth 团队)的新论文告诉你:别急着让它优化,你可能反而把事情搞砸了。
三种写法,哪个最好?
论文构建了一个叫 CP-SynC-XL 的基准测试,包含 100 个组合优化问题、4,577 个实例,然后让 LLM 用三种不同的范式来生成求解器:
- 纯 Python 算法搜索:LLM 直接写搜索算法的 Python 代码
- Python + OR-Tools 约束建模:LLM 用 OR-Tools 的 Python API 建模,调用求解器
- MiniZinc + OR-Tools 声明式建模:LLM 用 MiniZinc 声明式语言建模,再由 OR-Tools 求解
结果很有意思。
Python + OR-Tools 胜率最高——在多个 LLM 上都取得了最高的正确率。MiniZinc + OR-Tools 虽然用了相同的 OR-Tools 后端,但覆盖率更低——声明式语言的抽象反而让 LLM 更容易出错。纯 Python 则最容易产出"能通过 schema 验证但在实际测试中失败"的解。
这个发现直接推翻了一个直觉:更高级的抽象(MiniZinc)= 更好的结果。实际上,LLM 对 API 级别的约束建模(Python + OR-Tools)反而最靠谱。
启发式陷阱:优化欲害了模型
接下来是论文最核心的发现。
研究者让 LLM 在生成求解器时尝试加入搜索优化(比如剪枝策略、启发式函数、bound 设定)。结果呢?
- 中位加速比只有 1.03-1.12x——几乎没效果
- 呈现强烈的双峰分布——很多实例反而变慢了
- 在长尾问题上正确率急剧下降
为什么会这样?研究者做了代码级的审查,发现了一个反复出现的模式——他们称之为启发式陷阱(heuristic trap):
- 在纯 Python 路径下,LLM 可能用局部近似替代完整的搜索
- 在 Python + OR-Tools 路径下,LLM 可能注入未经验证的 bound 约束
- 在 MiniZinc + OR-Tools 路径下,LLM 可能添加冗余的声明式结构,反而让求解器过载
换句话说,LLM 对"优化"的理解经常是错误的。它以为自己在加速,实际上是在引入 bug 或者改变问题语义。
"形式化,别优化"
基于这些发现,论文提出了一个保守但实用的设计原则:
让 LLM 主要负责形式化——定义变量、约束和目标函数,交给经过验证的求解器去求解。LLM 写的任何搜索优化,使用前都必须单独审查。
这是一个"退一步"的策略。它承认 LLM 在建模方面有用(定义"是什么"),但在算法优化方面不可靠(决定"怎么找")。把这两件事拆开,让 LLM 做自己擅长的事,把优化交给成熟的求解引擎。
对 AI Agent 开发的启示
这个发现对做 AI coding agent 的人有直接的价值。
很多 Agent 工具(Cursor、Claude Code、Copilot)都会让 LLM 生成并修改代码。如果 LLM 正在写的是一个涉及搜索/优化的算法,Agent 应该知道:不要轻易接受 LLM 的"优化建议",除非有独立的验证机制。
论文也暗示了一个更广泛的 pattern:LLM 在"描述问题结构"方面比在"设计求解策略"方面更可靠。这个区分在更多领域可能都成立——比如数据库查询优化、编译器优化、甚至网络路由策略。
论文地址:arXiv:2605.12421