用 Qwen3 Agent 30 行代码搞定数学猜想验证——OpenAI 刚用 AI 推翻了几何学定论
用 Qwen3 Agent 30 行代码搞定数学猜想验证——OpenAI 刚用 AI 推翻了几何学定论
上周 Hacker News 炸了一条新闻:OpenAI 的模型推翻了离散几何领域一个存在多年的核心猜想。不是辅助人类,是模型自主找到了反例。
很多人的第一反应是"这不可能"——数学猜想验证不是写代码,是需要严格逻辑推理的。但这件事恰好说明了一个趋势:Agent + 工具调用的组合,正在让 LLM 从"聊天机器人"变成真正能干活的研究助手。
今天我们不讲玄学,直接动手:用 Qwen3 的 Agent 能力,搭一个能自主调用 Python 解释器、验证数学命题的 mini 研究 Agent。全程不到 50 行代码,跑完你会对"Agent Frontier"这个词有具体感受。
先搞清楚:Agent 和普通调用有什么区别
普通调用:你问 → 模型答 → 结束。
Agent 调用:你给目标 → 模型自己决定调用哪些工具 → 看结果 → 再决定下一步 → 直到完成目标。
Qwen3 系列(包括最新的 Qwen3.7-Max)原生支持 Function Calling,配合 tool_choice 参数可以让模型在多轮中自主规划。我们要做的就是给它一把"计算器"——一个能执行 Python 代码的工具。
环境准备
pip install openai
就这一个依赖。我们用 OpenAI SDK,因为 Qwen3 完全兼容 OpenAI 格式,只需要换 base_url。
完整代码
import json
import subprocess
import sys
from openai import OpenAI
# 用无量Api,国内直连,不需要梯子
client = OpenAI(
api_key="你的API Key",
base_url="https://api2everything.xyz/v1"
)
# ── 工具定义 ──────────────────────────────────────────────
def execute_python(code: str) -> str:
"""在沙箱里跑 Python,返回 stdout 或报错信息"""
try:
result = subprocess.run(
[sys.executable, "-c", code],
capture_output=True, text=True, timeout=10
)
return result.stdout or result.stderr or "(no output)"
except subprocess.TimeoutExpired:
return "Timeout: 代码执行超过 10 秒"
TOOLS = [
{
"type": "function",
"function": {
"name": "execute_python",
"description": "执行 Python 代码并返回结果,用于数值计算、验证数学命题、枚举反例等",
"parameters": {
"type": "object",
"properties": {
"code": {"type": "string", "description": "要执行的 Python 代码"}
},
"required": ["code"]
}
}
}
]
# ── Agent 主循环 ──────────────────────────────────────────
def run_agent(task: str, model: str = "qwen3-235b-a22b"):
messages = [
{
"role": "system",
"content": (
"你是一个数学研究助手。遇到需要验证的命题,"
"优先调用 execute_python 工具写代码验证,不要凭直觉猜测。"
"给出结论时说明验证过程。"
)
},
{"role": "user", "content": task}
]
print(f"\n🎯 任务:{task}\n{'─'*50}")
for step in range(6): # 最多 6 轮工具调用
response = client.chat.completions.create(
model=model,
messages=messages,
tools=TOOLS,
tool_choice="auto"
)
msg = response.choices[0].message
# 没有工具调用 → 模型给出最终答案
if not msg.tool_calls:
print(f"\n✅ 结论:\n{msg.content}")
return msg.content
# 处理工具调用
messages.append(msg)
for tc in msg.tool_calls:
args = json.loads(tc.function.arguments)
print(f"\n🔧 Step {step+1} - 调用工具:{tc.function.name}")
print(f" 代码:\n{args['code']}")
result = execute_python(args["code"])
print(f" 结果:{result}")
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": result
})
return "达到最大步数限制"
# ── 跑起来 ────────────────────────────────────────────────
if __name__ == "__main__":
# 任务1:验证一个经典数论命题
run_agent("验证:对所有 n < 1000,n² + n + 41 是否都是质数?如果不是,找出第一个反例。")
# 任务2:离散几何小实验(致敬 OpenAI 那篇论文)
run_agent(
"在二维平面上随机生成 20 个整数坐标点(坐标范围 0-10),"
"找出其中共线点最多的一组直线,输出这条线上的所有点。"
)
跑一下看看
任务 1 的输出大概是这样:
🎯 任务:验证:对所有 n < 1000,n² + n + 41 是否都是质数...
─────────────────────────────────────────────────────
🔧 Step 1 - 调用工具:execute_python
代码:
from sympy import isprime
for n in range(1000):
val = n*n + n + 41
if not isprime(val):
print(f"反例:n={n}, n²+n+41={val}")
break
else:
print("n < 1000 范围内全是质数")
结果:反例:n=40, n²+n+41=1681
✅ 结论:
n=40 时,40²+40+41 = 1681 = 41²,不是质数。
这个公式在 n=0 到 39 范围内确实全部产生质数,
但 n=40 时恰好等于 41 的平方,猜想不成立。
模型没有直接回答,而是自己写代码、跑代码、看结果、再给结论。这就是 Agent 和普通问答的本质区别。
几个值得注意的细节
工具描述要写清楚。description 字段直接影响模型决策——写"执行代码"和写"用于数值计算、验证数学命题、枚举反例",模型的调用时机会有明显差异。
消息历史要完整传回。每次工具调用后,必须把 tool 角色的结果追加进 messages,否则模型下一轮看不到执行结果,会陷入循环。
超时保护不能省。让模型自主写代码就意味着可能写出死循环,timeout=10 是基本防护。
模型选择:Qwen3.7-Max 推理能力强但贵,日常验证用 qwen3-30b-a3b(MoE 小模型)速度更快,成本低一个数量级。
关于成本
这套 Agent 每次完整跑下来大概消耗 2000-5000 tokens(含工具调用上下文)。
如果直接调官方 API,加上网络问题和汇率,成本会高不少。我最近在用无量Api(api2everything.xyz),同样的 Qwen3、Claude、GPT-4o,价格比官方便宜约 65%,国内直连不需要代理,OpenAI 格式兼容,上面代码里的 base_url 换一行就能跑。注册还送 ¥1 余额,余额永久不过期,拿来跑这种实验挺合适。
延伸方向
这个框架稍微改改就能做:
- 给它加
search_web工具 → 自主查资料的研究助手 - 换成文件读写工具 → 自动分析 CSV 数据集
- 接入数据库查询 → 自然语言转 SQL 并验证结果
Agent 的核心不复杂:工具 + 循环 + 消息历史。复杂的是怎么让模型在正确的时机调用正确的工具——这靠的是 system prompt 和工具描述的质量。
代码跑起来有问题,或者想聊 Agent 架构设计,评论区见。觉得有用的话点个赞,后续还会写 multi-agent 协作的实战。