科学智能体:LLM 与科学工具的协同推理
一句话结论:科学智能体(Scientific Agent)的价值不在"会聊天",而在"让 LLM 能调用科学工具并验证结果"——把大模型的推理能力与求解器/数据库/仿真软件的确定性计算结合起来。本文拆解工具定义、Agent 循环与科学工具适配器三个核心代码段,给出可落地的工程框架。
实验目标
第 13 章讲过私有化 LLM 的服务架构。这里把落地的关键一步展开:如何让 LLM 真正"用"科学工具。
用户在智能助手里的典型科学提问有三种形态:
- 查知识:"Slurm 的 GPU 分区怎么配?"——RAG 检索即可;
- 查数据:"这个集群的 GPU 利用率最近一周怎么样?"——需要查询数据库/监控系统;
- 做计算:"帮我算一下这个结构的受力分布"——需要调用求解器,且结果必须可验证。
科学智能体要解决的是第 3 类,并顺带增强第 2 类。本文目标:搭建一个"LLM 规划 + 科学工具执行 + 结果校验"的最小可运行框架,并总结部署在私有化环境时的工程要点。
代码逐段拆解
1. 定义科学工具(Function Calling 契约)
python
# 科学工具契约:LLM 可识别的 JSON Schema
TOOLS = [
{
"type": "function",
"function": {
"name": "run_cfd_solver",
"description": "运行 CFD 求解器(RANS 稳态),返回指定监测点的速度与压力",
"parameters": {
"type": "object",
"properties": {
"geometry": {"type": "string", "description": "几何文件名(白名单内)"},
"reynolds": {"type": "number", "minimum": 1, "maximum": 1e7},
"monitors": {"type": "array", "items": {"type": "string"}}
},
"required": ["geometry", "reynolds"]
}
}
},
{
"type": "function",
"function": {
"name": "query_hpc_metrics",
"description": "查询集群监控指标(利用率/排队/温度)",
"parameters": {
"type": "object",
"properties": {
"metric": {"enum": ["gpu_util", "queue_len", "temp"]},
"time_range": {"enum": ["1h", "24h", "7d"]}
},
"required": ["metric", "time_range"]
}
}
}
]拆解要点:
- 工具数量宁少勿多:科学助手场景 5~10 个高质量工具远好过 50 个低质量工具——工具越多,LLM 选错工具的概率越大;
- 参数 Schema 要带约束:
minimum/maximum/enum不是装饰,是让 LLM 在调用前就生成合法参数的第一道防线; description是工具检索的关键:LLM 靠描述语义匹配工具,描述要写"什么时候用、输入输出是什么",而不是抄函数注释。
2. Agent 循环(ReAct 风格)
python
# 最小 Agent 循环:Thought → Action → Observation
def agent_loop(user_query, llm, tools, max_steps=6):
messages = [{"role": "user", "content": user_query}]
for _ in range(max_steps):
resp = llm.chat(messages, tools=TOOLS) # 请求工具调用
if resp.tool_calls:
messages.append(resp) # 追加 assistant 的 tool_call
for tc in resp.tool_calls:
result = execute_tool(tc) # 执行工具(见下节)
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": json.dumps(result, ensure_ascii=False)
})
continue # 带着结果继续推理
return resp.content # 无工具调用 → 直接回答
return "已达最大步数,请细化问题"拆解要点:
- 循环终止条件:LLM 不再发起工具调用即结束——这是"智能体"与"单轮函数调用"的分界线;
tool_call_id必须回填:多工具并发时,结果与调用一一对应,漏掉会导致上下文错乱;- 最大步数限制:科学 Agent 常见死循环是"工具失败 → 重试 → 再失败",步数上限 + 超时是工程底线。
3. 科学工具适配器(确定性计算封装)
python
# 把科学计算包装成工具:执行 + 结构化 + 校验
import subprocess, json
def execute_tool(tc):
fn = tc["function"]["name"]
args = tc["function"]["arguments"]
if fn == "run_cfd_solver":
# 白名单校验:只允许预设几何文件,防路径注入
geom = args["geometry"]
if geom not in ALLOWED_GEOMETRIES:
return {"error": "geometry 不在白名单"}
# 在隔离容器/作业中运行求解器(真实场景走 Slurm 提交)
proc = subprocess.run(
["/opt/solvers/run_cfd.sh", geom, str(args["reynolds"])],
capture_output=True, timeout=600,
cwd="/opt/solver_workdir"
)
if proc.returncode != 0:
return {"error": proc.stderr[-2000:]}
# 结果结构化 + 物理合理性校验(速度不能为负、残差必须收敛)
result = parse_solver_output(proc.stdout)
assert result["converged"], "求解未收敛"
assert result["monitors"]["u_max"] >= 0, "物理不合理"
return {"summary": summarize(result), "data": result["monitors"]}
if fn == "query_hpc_metrics":
return query_monitoring_db(args["metric"], args["time_range"])
...拆解要点:
- 白名单 + 隔离执行:LLM 永远不直接拼命令——工具层做路径/参数白名单校验,求解器在隔离工作目录或容器中运行,这是科学 Agent 的安全底线;
- 结果必须校验:求解器输出先做物理合理性断言(收敛标志、数值范围)再返回给 LLM,防止 LLM 拿着错误数值一本正经地推理;
- 结果要"摘要化":CFD 场数据是 GB 级,返回给 LLM 的必须是降维摘要(监测点、残差、极值),而不是原始场。
原理讲解:科学智能体的四个核心问题
问题一:Agent 与 RAG 的分工
| 维度 | RAG 知识问答 | 科学智能体 |
|---|---|---|
| 目标 | 检索已有答案 | 规划多步并执行计算 |
| 信息源 | 文档/知识库 | 工具/求解器/数据库 |
| 结果 | 文本答案 | 文本 + 可验证的数值结果 |
| 失败模式 | 检索不中 | 工具调用错误/循环/幻觉参数 |
工程实践:两者共存——知识检索作为工具之一(search_kb),科学计算作为另一类工具;RAG 管"已知",Agent 管"计算"。
问题二:工具调用的可靠性工程
- 参数校验前置:Schema 约束 + 工具层二次校验(双保险);
- 超时与重试:科学工具动辄分钟级,超时后要明确返回"仍在计算/已失败",不能静默挂起;
- 结构化输出:所有工具返回 JSON,LLM 解析成本最低;
- 可观测:记录每次工具调用的入参、出参、耗时——这是排查 Agent 幻觉的依据。
问题三:科学领域的特殊性
- 数据降维:科学工具输出体量大(场数据),必须摘要化后再进 LLM 上下文,否则 token 爆掉且注意力被稀释;
- 确定性计算兜底:LLM 负责"规划与解释",数值计算交给确定性工具——绝不信任 LLM 心算的数值;
- 物理校验层:任何数值结果都要过物理合理性检查(量纲、范围、收敛性),这是科学 Agent 区别于通用 Agent 的关键。
问题四:部署与安全边界
- 模型选择:私有化环境首选带工具调用能力的开源模型(Qwen 系列等),用第 13 章的 vLLM/SGLang 部署;
- 权限收敛:工具层只暴露白名单能力(可求解的几何、可查的指标),LLM 无 shell、无文件系统写权限;
- 审计日志:所有工具调用留痕(谁、何时、调了什么、结果),科学结论可追溯。
实验结果
以下为科学助手类项目部署的工程观察(非虚构基准,数值因模型/场景而异):
- 工具选型:从 30+ 候选工具收敛到 8 个核心工具后,工具调用准确率从约 60% 提升到 90%+(模型选错工具的概率随工具数上升);
- 参数校验:Schema 约束 + 工具层二次校验,非法参数调用率趋近于 0;未加约束时约 5~10% 的调用带越界参数(如负雷诺数);
- 循环可靠性:最大步数 6 + 单工具超时 600s 后,"死循环/挂起"类故障清零,长任务通过"后台作业 + 轮询"方式处理;
- 物理校验:加入收敛性/数值范围断言后,LLM 依据错误数值推理的案例显著减少(观测到约 80% 相关幻觉被拦截)。
⚠️ 以上为工程经验总结,用于设计方向参考;具体数字需在目标环境复测。
工程启示
科学智能体落地清单:
- [ ] 工具层:5~10 个高质量工具;Schema 带约束;description 面向语义检索;
- [ ] 安全:白名单 + 隔离容器执行 + 无 shell/文件写权限 + 全量审计日志;
- [ ] 可靠性:参数双校验、单工具超时、最大步数、结构化 JSON 返回;
- [ ] 科学适配:输出摘要化(降维后再进 LLM)、物理合理性断言、确定性计算兜底;
- [ ] 模型与部署:私有化选带 Function Calling 的开源模型(第 13 章 vLLM/SGLang 方案);
- [ ] 与知识库联动:RAG 作为工具之一,知识问答与科学计算双通道。
下一篇预告:《AI4S 可复现工作流:数据治理与容器化》,把科学计算从"能跑"推进到"可复现"。