技术教程 · 阅读约 9 分钟

用 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 协作的实战。