多智能体协作的数学建模竞赛全流程框架。输入题目,自动产出完整论文。
5 层架构 · 17 个专职 Agent · 辩论循环 · Agentic Tool Calling · Web 搜索 · Prompt 缓存优化 · 增量写盘容灾
题目文件 ──→ [L1: 问题分析] ──→ [L2: 数学建模] ──→ [L3: 代码实现] ──→ [L4: 论文写作] ──→ 完整论文
顺序流水线 辩论循环 Agentic 循环 Agentic 循环
(写→跑→修) (写→查→改)
(可选) [L5: 敏感性分析]
另有一种恢复模式:从一份已完成的 Layer 1 数据出发,只跑 L2→L3(L1 判需敏感性时再插 L5), 产出模型解释文档(面向团队的技术说明)而非竞赛论文:
已有 Layer1 数据 ──→ [L2: 数学建模] ──→ [L3: 代码实现] ──→ [模型解释文档]
辩论循环 Agentic 循环 (技术说明, 非论文)
│ (L1 判需敏感性时)
▼
[L5: 敏感性分析]
# 1. 安装
git clone https://github.com/J0Jng/MathModelingAgents.git
cd MathModelingAgents
pip install -e .
# 2. 配置
cp .env.example .env
# 编辑 .env,填入你的 API Key(至少配一个)
# 3. 运行
python main.py problem_2024a.md运行结束后,桌面上会出现一个文件夹,里面是完整的数学建模论文和所有中间结果。
python main.py 题目.md 交互模式下,配置组装后会先弹出两个模型选择菜单(菜单项严格来自 cli/model_catalog.py 的官方静态清单;清单中的逻辑别名如 glm-5.3、kimi-k2.7-code、minimax-m3 虽不在 /models 部署列表,chat 端点可直接使用):
Select Your [Quick-Thinking] LLM Engine (volcengine-plan): # 快速思考模型
Select Your [Deep-Thinking] LLM Engine (volcengine-plan): # 深度思考模型
选中的 quick/deep 模型作为最高优先级完全覆盖 provider 级角色硬编码(如 volcengine-plan 的 L3 coder / L4 writer),写回 config 后再启动建模流程。
| 环境变量 | 作用 |
|---|---|
MATHMODELING_QUICK_THINK_LLM |
快速思考模型的默认值(仅作默认模型,不关闭交互) |
MATHMODELING_DEEP_THINK_LLM |
深度思考模型的默认值(仅作默认模型,不关闭交互) |
MATHMODELING_SKIP_MODEL_PROMPT |
显式设为 1/true/yes/on 时跳过全部交互菜单(适合 CI / 脚本 / 无 TTY 环境) |
设置
MATHMODELING_SKIP_MODEL_PROMPT=1可完全跳过交互,直接使用默认模型。未显式设置该变量时,交互菜单照常弹出——即使你已在.env里用了QUICK/DEEP_THINK_LLM指定默认模型。provider 未知或交互异常时自动走默认模型,绝不阻塞。
框架分为 5 层,层与层之间只传递精华摘要而非原始输出。
Layer 1: 问题分析(4 Agent,顺序协作)
Decomposer → DataAnalyst → ConstraintAnalyst → ProblemManager
产出:理解题目边界、挖掘数据特征、明确约束假设
Layer 2: 数学建模(4 Agent,辩论循环)
ModelerA → ModelerB → ModelerC → ModelingManager ──→ 继续辩论 / 通过
产出:数学模型定义、公式推导、求解方案
Layer 3: 代码实现(3 Agent,Agentic Tool Calling)
SolverAgent(有工具,内部循环:写→跑→修→再跑)→ ImplManager → VizAgent
产出:可运行代码、results.json、论文级图表
Layer 4: 论文写作(2 Agent,Agentic Tool Calling)
PaperAgent(有工具,分节迭代:写→读数据核实→修改)→ PaperManager ──→ 修改 / 通过
产出:完整的中文学术论文(Markdown)
Layer 5: 敏感性分析(3 Agent,可选)
ParamPerturber → RobustnessAnalyst → SensitivityManager
产出:参数稳定性评估
模型解释层(explanation,1 Agent,恢复模式 --from-layer1 专用)
Explainer:面向团队的技术说明文档(建模思路/公式/求解/结果/敏感性结论)
产出:model_explanation.md(非竞赛论文格式)
Layer 3 的 CodingAgent 和 Layer 4 的 PaperAgent 不再是单次 LLM 调用,而是 有真实工具的自主循环 Agent:
┌─ SolverAgent(30 轮 max)─────────────┐
│ 工具: run_code / read_file / │
│ write_file / list_dir / │
│ web_search │
│ │
│ 写代码 → 执行 → 看报错 → 修复 │
│ → 再执行 → 结果正确 → 生成图表 │
│ → 自检 → SELF_CHECK_PASSED │
└────────────────────────────────────────┘
┌─ PaperAgent(30 轮 max)───────────────┐
│ 工具: read_file / list_dir / │
│ write_file(只读为主) │
│ │
│ 写 §1 → read_file 核实数据 → 改 │
│ → 写 §2 → read_file 核实公式 → 改 │
│ → ... → 全稿自审 → SELF_CHECK_PASSED │
└────────────────────────────────────────┘
Agent 接收 ──→ 静态 System Prompt ──→ LLM 调用 ──→ 输出写入 State
(可被 API 缓存) │ │
4 步降级链 逐 Agent 写盘
+ 3 次重试 (崩溃不丢已完成层)
主通道 (OpenCode Go) + 深度推理模型
──→ 失败 ──→ 备用通道 (DeepSeek 官方 API) + 同模型
──→ 失败 ──→ 主通道 + 快速模型
──→ 失败 ──→ 备用通道 + 快速模型
每步内部有 3 次指数退避重试(2s → 4s → 8s),覆盖 503、超时、限流等瞬态故障。
所有 Agent 的 System Prompt 均为纯静态字符串(无变量注入),确保 LLM API 的 prefix caching 可以命中。动态值(路径、轮次、重试次数等)全部移至 User Message。
每个 Agent 完成工作后立即将输出写入磁盘。即使后续层崩溃,已完成层的内容不会丢失。
崩溃后可用 --from-layer1 <dir> 从既有 Layer 1 输出的恢复模式继续。
沙盒执行环境自动检测中文字体(SimHei / Microsoft YaHei / STSong 等), 若系统无中文字体则输出警告。VizAgent 的 prompt 要求根据字体可用性 决定使用中文或英文标签,避免出现方块乱码。
Layer 1 的 Decomposer 自动进行多角度联网搜索(题目背景 + 建模方法),背景资料注入问题拆解与 Layer 2 建模上下文;
Layer 3 的 SolverAgent 可自主调用 web_search 查询数据字段含义、算法资料。Layer 4 的 PaperAgent 写参考文献前会用 check_url 验证每条 URL 的真实可达性,失效引用自动剔除。
- 后端:Tavily(免费 1000 次/月,推荐)或 ddgs(DuckDuckGo,免费无 key)
- 配置:
MATHMODELING_WEB_SEARCH_PROVIDER=auto|tavily|ddgs|off(默认auto:有 key 用 Tavily,否则 ddgs) - 容错:10 秒超时、异常吞噬、tavily 失败自动降级 ddgs;搜索失败静默跳过,不影响主流程
所有设置通过 .env 管理(API Key、模型名、超时、辩论轮数等),每个选项都有中文注释。
.env.example 可直接复制使用。
本项目设计时考虑了 AI 编码助手(如 Claude Code、GitHub Copilot、Cursor 等)的使用场景。 以下是指引 AI Agent 快速上手此项目的说明。
这是一个 LangGraph 多智能体数学建模框架。输入一道数学建模竞赛题目(Markdown 文件), 自动产出完整的解答论文(含代码、图表、分析)。
5 层流水线: L1 问题分析 → L2 数学建模(辩论) → L3 代码实现(Agentic) → L4 论文写作(Agentic) → L5 敏感性分析(可选)
- L1/L5:传统 LLM 节点链(System Prompt → 单次调用 → 输出)
- L2 建模师:Agentic 循环,绑定
model_search(模型知识库 RAG)+web_search+run_code工具辅助验证,以纯文本建模方案为一次发言的终止条件(连续 tool_calls 保底上限 10 轮) - L3 SolverAgent:有
run_code/read_file/write_file/list_dir/web_search工具的 Agentic 循环(写→跑→修,最多 30 轮),VizAgent 负责图表生成(最多 10 轮) - L4 PaperAgent:有
read_file/list_dir/write_file/check_url工具的 Agentic 循环(逐节写→核实→改,最多 30 轮) - 总 Agent 数:17(L1: 4, L2: 4, L3: 3, L4: 2, L5: 3, 模型解释: 1)
| 文件 | 作用 | 什么时候看 |
|---|---|---|
mathmodelingagents/graph/setup.py |
图拓扑定义(节点、边、路由) | 修改 Agent 编排流程 |
mathmodelingagents/graph/conditional_logic.py |
条件路由(辩论继续/结束、重试/通过、恢复模式路由) | 修改裁决逻辑 |
mathmodelingagents/graph/recovery.py |
Layer 1 状态恢复(--from-layer1) | 修改恢复模式 |
mathmodelingagents/agents/__init__.py |
Agent 工厂函数(含 Tool Calling 循环) | 修改 Agent 行为、添加工具 |
mathmodelingagents/agents/utils/prompt_templates.py |
全部 System Prompt(纯静态,可缓存) | 修改 Agent 指令 |
mathmodelingagents/tools/__init__.py |
沙盒执行 + LangChain Tool 封装 | 修改/添加工具 |
mathmodelingagents/tools/web_search.py |
Web 搜索(Tavily / ddgs) | 修改搜索后端 |
mathmodelingagents/llm_clients/__init__.py |
LLM 客户端 + 降级链 | 修改 API 调用逻辑 |
mathmodelingagents/default_config.py |
全局配置 + 模型路由 | 修改默认值、模型分配 |
.env.example |
环境变量说明 | 了解/修改用户配置项 |
main.py |
CLI 入口 | 了解启动流程 |
# 运行完整流程
python main.py problem_2024a.md
# 从已完成的 Layer 1 输出恢复,只跑 L2→L3(+L5),产出模型解释文档(调试/迭代推荐)
python main.py problem_2024a.md --from-layer1 <已有Layer1目录>
# 只用 DeepSeek 官方 API
python main.py problem_2024a.md --provider deepseek
# 用火山方舟 Agent Plan(订阅套餐,L3 coder→kimi-k2.7-code,L4 writer→minimax-m3)
python main.py problem_2024a.md --provider volcengine-plan
# 用火山方舟 Coding Plan(订阅套餐,qwen3.7-max 自动映射为 deepseek-v4-pro)
python main.py problem_2024a.md --provider volcengine
# 启用/控制敏感性分析(裸 -s = always 强制启用;auto 交给 Layer 1 决策;never 强制跳过)
python main.py problem_2024a.md -s
python main.py problem_2024a.md -s never- 找到
prompt_templates.py中对应的get_XXX_prompt()函数 - 所有 prompt 函数是无参数纯静态字符串(为了 API 缓存)。不要在 prompt 中注入变量,动态值通过
_build_context()在 user message 中提供 - 修改后用
--max-rounds 1 --provider deepseek小规模跑一轮冒烟验证(单元测试套件已移除,见下文「验证」)
prompt_templates.py:添加get_new_agent_prompt()函数_PROMPT_REGISTRY:注册新 promptagents/__init__.py:添加create_new_agent()工厂函数graph/setup.py:_create_agent_nodes创建节点、_add_layerN_nodes添加节点、_connect_layers连接边reporting.py:AGENT_DISPLAY添加显示名称default_config.py:如需要,在layer_model_overrides中配置模型
- 网络模块(socket, requests, urllib 等)被 import hook 阻断;
urllib.parse作为安全子模块精确豁免(纯解析无网络,matplotlib 字体配置内部依赖) - 子进程和线程(subprocess, threading)放行(matplotlib 内部需要)
- 每次 run_code 是独立进程,变量不跨调用保留。跨调用数据通过 write_file → read_file 传递
- 单次 run_code 硬上限 300s(
MAX_RUN_CODE_TIMEOUT),Agent 传入更大的 timeout 也会被钳制;复杂求解需拆分为多个小执行单元 - 中文字体:沙盒自动检测 SimHei/Microsoft YaHei,无字体时 Agent 应改用英文标签
单元测试套件(tests/)已于 2026-09 移除,当前验证方式:
# 小规模冒烟:一轮辩论完整流程(最快路径,需 API key)
python main.py problem_2024a.md --max-rounds 1 --provider deepseek
# 从已有 Layer 1 恢复,只跑后续层(调试某层推荐)
python main.py problem_2024a.md --from-layer1 <已有输出目录> --max-rounds 1
# RAG 检索冒烟(无需 API key)
.venv/Scripts/python.exe -c "from mathmodelingagents.knowledge import search_models; print(search_models('小样本 指数增长 预测', top_k=1)[0]['name'])"| 模型 | 适用角色 | 特点 |
|---|---|---|
deepseek-v4-pro |
Manager、建模师、SolverAgent | 深度推理,复杂逻辑,工具调用 |
deepseek-v4-flash |
数据分析、敏感性分析 | 快速响应,高性价比 |
qwen3.7-max |
PaperAgent 论文正文撰写(仅 opencode 通道) | 中文写作质量高 |
Provider 级角色覆盖(provider_layer_model_overrides),优先于全局分配:
| 角色 | 模型 | 说明 |
|---|---|---|
| L3 coder | kimi-k2.7-code |
火山主打编程模型 |
| L4 writer | minimax-m3 |
1M 上下文,长文写作 |
| 其余角色 | deepseek-v4-pro / deepseek-v4-flash |
沿用默认矩阵 |
Agent Plan 模型池(11 个):ark-code-latest、doubao-seed-2.1-turbo、doubao-seed-evolving、glm-5.3/latest、deepseek-v4-pro/flash、doubao-seed-2.0-lite/mini、minimax-m3、kimi-k2.7-code、kimi-k3。
- Base URL 为
https://ark.cn-beijing.volces.com/api/coding/v3(与 Agent Plan 的/api/plan/v3不同端点)。 - 火山两个套餐均不支持
qwen3.7-max,自动映射(Coding Plan →deepseek-v4-pro,Agent Plan →minimax-m3)。
glm-5.2·glm-5.1在 opencode 通道的长中文数学建模 prompt 下会返回空内容,已被排除。kimi-k2.7-code在 OpenCode Go 后端曾因长 prompt 返空被移除,且只接受temperature=1;本次在 volcengine-plan 通道重新启用为 L3 coder(火山原生端点行为不同),正式跑题前请先做小 prompt 实测输出质量(探针脚本scripts/probe_model_quality.py已随测试清理移除,可直接用任一题目 md +--max-rounds 1冒烟)。
Layer 2 辩论前会按题目特点从内置模型知识库(mathmodelingagents/knowledge/model_library.json,52 条)中检索候选模型池(Top-5),注入三位建模师第一轮作为参考起点(可超越池子);建模师还可用 model_search 工具按需补充检索(ADR-0003)。
Embedding 模型:BAAI/bge-small-zh-v1.5(512 维,fastembed 本地 ONNX 推理,不引入 torch)。
模型文件(约 91MB:model_optimized.onnx + tokenizer/config)是二进制,已在 .gitignore 中忽略、不随 git 提交;而预计算的向量库 knowledge/model_library_vectors.npz(52×512)随仓库提交。因此 clone 到新环境后需自行补下载模型:
第一步 · 判断是否需要下载
检查模型目录是否存在:
ls mathmodelingagents/knowledge/models/- 已有
models--Qdrant--bge-small-zh-v1.5/(含 snapshot)→ 已就绪,跳过下载,直接可用。 - 目录为空或不存在 → 执行下一步。
第二步 · 下载模型(国内网络实测:直连 HuggingFace 会 ConnectTimeout,不禁 xet 会 CAS 401,两个环境变量缺一不可)
export HF_ENDPOINT=https://hf-mirror.com
export HF_HUB_DISABLE_XET=1
.venv/Scripts/python.exe scripts/build_model_library.py --download-model第三步 · 验证下载成功
.venv/Scripts/python.exe -c "from mathmodelingagents.knowledge import search_models; print(search_models('小样本 指数增长 预测', top_k=1)[0]['name'])"首条应接近「灰色预测 GM(1,1)」,表示真实 embedding 检索已可用。
模型已下载后,search_models 走纯离线推理(local_files_only=True),运行期无需联网。
建库脚本:scripts/build_model_library.py 对 52 条模型条目(name + traits + usage)预计算向量并生成 knowledge/model_library_vectors.npz。向量库已随 git 提交,仅在更换 embedding 模型或改动 model_library.json 条目时才需重建:
.venv/Scripts/python.exe scripts/build_model_library.py # 模型已存在时,仅重建向量库一致性铁律:更换 embedding 模型后必须重跑建库脚本重建向量库,否则检索会因 names/维度不一致而退化为现场计算(模型也不可用时进一步 fail-open 为全量谱系注入)。
fail-open 行为:模型未下载 / 向量化失败 / 结构化提炼失败时,候选池自动降级为全量模型谱系注入,不阻塞主流程。
所有配置通过 .env 文件管理,完整列表见 .env.example。核心配置项:
| 变量 | 默认值 | 说明 |
|---|---|---|
MATHMODELING_LLM_PROVIDER |
opencode |
LLM 通道:opencode / deepseek / volcengine / volcengine-plan |
OPENCODE_GO_API_KEY |
(必填) | OpenCode Go API 密钥(主通道) |
DEEPSEEK_API_KEY |
(必填) | DeepSeek 官方 API 密钥(降级通道) |
VOLCENGINE_PLAN_API_KEY |
(选填) | 火山方舟 Agent Plan 专属密钥(订阅后从控制台换取) |
MATHMODELING_MAX_DEBATE_ROUNDS |
10 |
建模辩论最大轮数 |
MATHMODELING_MAX_IMPL_RETRIES |
3 |
代码实现最大重试次数 |
MATHMODELING_DEFAULT_MAX_TOKENS |
16384 |
单次 LLM 调用最大输出 |
MATHMODELING_SELECTED_LAYERS |
1,2,3,4 |
要执行的层(调试时可用 3,4 跳层) |
MATHMODELING_WEB_SEARCH_PROVIDER |
auto |
Web 搜索后端:auto/tavily/ddgs/off |
TAVILY_API_KEY |
(可选) | Tavily 搜索 key(不填则自动用 ddgs 免费后端) |
python main.py <题目文件> [选项]
参数:
problem_path 题目 Markdown 文件路径
选项:
--output, -o NAME 输出文件夹名(默认自动生成)
--sensitivity, -s [auto|always|never]
敏感性模式(默认 auto,由 Layer 1 分析题目后决策;
裸 -s 等价 always 强制启用,never 强制跳过)
--max-rounds, -r N 每层最大辩论轮次(默认 10)
--provider, -p 指定 LLM provider(opencode / deepseek / volcengine / volcengine-plan)
--from-layer1 DIR 从已完成的 Layer 1 输出目录恢复,只跑 L2→L3(+L5) 产出模型解释文档
示例:
python main.py problem_2024a.md
python main.py problem_2024a.md -s -o my_solution
python main.py problem_2024a.md -s never # 强制跳过敏感性分析
python main.py problem_2024a.md --from-layer1 results/problem_2024a # 恢复模式,产出模型解释文档MathModelingAgents/
├── main.py # 入口 + 代码验证
├── cli/
│ ├── model_catalog.py # 各 provider 官方静态模型清单(交互菜单数据源)
│ └── model_picker.py # 交互式 Quick/Deep 模型选择(questionary)
├── pyproject.toml
├── .env.example # 配置模板(复制为 .env)
├── .gitignore
│
└── mathmodelingagents/
├── default_config.py # 全局配置(所有值可通过 .env 覆盖)
│
├── agents/
│ ├── __init__.py # Agent 工厂函数(含 Tool Calling 循环)
│ └── utils/
│ ├── prompt_templates.py # 全部 System Prompt(静态,可缓存)
│ └── agent_states.py # AgentState 类型定义
│
├── knowledge/ # 模型知识库 RAG(Layer 2 候选模型池)
│ ├── model_library.json # 52 条数学模型条目
│ ├── model_library_vectors.npz# 预计算向量库(随 git 提交)
│ └── retrieval.py # 语义检索(bge-small-zh-v1.5, 本地 ONNX)
│
├── llm_clients/
│ └── __init__.py # LLM 客户端 + 统一降级链
│
├── tools/
│ ├── __init__.py # 沙盒代码执行 + LangChain Tool 封装
│ └── web_search.py # Web 搜索(Tavily / ddgs)+ check_url
│
├── graph/
│ ├── setup.py # LangGraph StateGraph 构建
│ ├── modeling_graph.py # 主入口类 MathModelingGraph
│ ├── conditional_logic.py # 辩论/重试/循环路由
│ ├── propagation.py # 初始状态 + 图执行参数
│ ├── checkpointer.py # 检查点(可选)
│ └── recovery.py # Layer 1 状态恢复(--from-layer1)
│
└── reporting.py # 增量写盘 + 最终报告汇总
- 编排引擎:LangGraph — 构建有状态的多 Agent 工作流图
- LLM 接口:
langchain-openai(ChatOpenAI) — 兼容 OpenAI API 协议 - Tool Calling:
langchain-core— AIMessage / ToolMessage 工具调用协议 - 模型:DeepSeek V4 Pro / Flash、Qwen3.7-Max、Kimi K2.7-Code、MiniMax M3(通过 OpenCode Go / 火山方舟 Agent & Coding Plan / DeepSeek 官方 API)
- 计算沙盒:
numpy·scipy·sympy·pandas·matplotlib·seaborn·scikit-learn·statsmodels - Web 搜索:Tavily(推荐) / ddgs(DuckDuckGo 免费后端)
MIT