LangGraph 工具 calculator_tool 计算器工具完整逐行详解
·
calculator_tool 计算器工具完整逐行详解
整体作用
这是一个 LangChain 标准结构化工具(Structured Tool),专门给大模型调用,用来安全计算数学表达式。 通过严格限制 eval 执行权限,杜绝代码注入风险,只允许基础四则运算与简单数值函数。
1. 装饰器 @tool
python
运行
@tool
def calculator_tool(expression: str) -> str:
- 来源:
from langchain.tools import tool - 功能:自动把普通 Python 函数转换成 LLM 可识别工具
- 自动读取函数文档字符串(docstring)生成工具描述
- 自动解析参数类型
expression: str生成 JSON Schema - LLM 在需要计算时,会自动生成 tool_call 调用这个函数
- 约束:大模型会严格按照
expression传一段纯数学表达式,如"35 * (10 - 2)"
2. 文档字符串 docstring
python
运行
"""
Evaluates basic mathematical expressions.
Args:
expression: A mathematical expression like "25 + 17" or "100 / 4"
Returns:
The calculated result as a string
"""
这段内容会完整传给 LLM,让模型明白:
- 工具用途:计算数学式子
- 需要传入什么格式参数
- 返回什么类型结果
3. 函数入参与返回值标注
expression: str:必须传入字符串格式数学表达式,不能直接传数字-> str:计算完成后统一转为字符串返回,方便大模型拼接回答
4. try-except 异常捕获块
python
运行
try:
# 计算逻辑
except Exception as e:
return f"Error calculating: {str(e)}"
捕获所有计算异常,常见报错场景:
- 语法错误:
"5 ++ 3"、"(10+2"括号不匹配 - 除零错误:
"10 / 0" - 包含未授权函数 / 变量 不会直接抛出程序崩溃,而是返回可读错误文本给 LLM,模型可以修正表达式重新计算。
5. 安全白名单 allowed_names
python
运行
allowed_names = {
'abs': abs, 'round': round, 'min': min, 'max': max,
'sum': sum, 'len': len, 'int': int, 'float': float
}
eval 默认能执行任意 Python 代码,极度危险,这里手动只放行安全数值函数:
- abs:绝对值
- round:四舍五入
- min/max:取最小最大值
- sum:求和
- int/float:类型转换 不在这个字典里的函数(如
open、__import__、os、exec)一律无法调用。
6. 核心安全执行语句 eval
python
运行
result = eval(expression, {"__builtins__": {}}, allowed_names)
eval(待执行字符串, 全局作用域, 局部作用域) 三层安全隔离:
-
第二个参数
{"__builtins__": {}}清空 Python 所有默认内置函数,彻底屏蔽系统操作、文件读写、导入模块等高危能力。 没有这一行,攻击者写__import__("os").system("rm -rf /")会直接破坏服务器。 -
第三个参数
allowed_names局部作用域仅提供我们手动允许的数学工具,表达式里只能使用字典里定义的函数。
示例对比
允许:
python
运行
eval("abs(-10)", {}, allowed_names) # 返回 10
eval("round(3.1415, 2)", {}, allowed_names) # 返回3.14
eval("20 * 5 - 8 / 2", {}, allowed_names)
禁止(直接报错):
python
运行
eval("open('secret.txt')", {}, allowed_names)
eval("__import__('os')", {}, allowed_names)
7. 结果处理
python
运行
return str(result)
计算结果可能是 int /float,统一转字符串输出,LLM 更容易解析、拼接进回答。
完整运行测试示例
python
运行
from langchain.tools import tool
@tool
def calculator_tool(expression: str) -> str:
"""
Evaluates basic mathematical expressions.
Args:
expression: A mathematical expression like "25 + 17" or "100 / 4"
Returns:
The calculated result as a string
"""
try:
# For safety, only allow basic math operations
allowed_names = {
'abs': abs, 'round': round, 'min': min, 'max': max,
'sum': sum, 'len': len, 'int': int, 'float': float
}
# Evaluate the expression safely
result = eval(expression, {"__builtins__": {}}, allowed_names)
return str(result)
except Exception as e:
return f"Error calculating: {str(e)}"
# 测试正常计算
print(calculator_tool.run("100 / (5 + 15)")) # 5.0
print(calculator_tool.run("abs(-99)")) # 99
# 测试错误表达式
print(calculator_tool.run("10 / 0"))
# Error calculating: division by zero
现有工具优缺点
优点
eval双层隔离,极大降低代码注入风险,可在线上环境安全使用- 自带异常兜底,不会中断 Agent 流程
- LangChain 标准工具,可直接
llm.bind_tools()给大模型调用 - 支持括号、四则运算、基础数值函数
局限
- 不支持幂运算
**、开方、三角函数(可手动补充进 allowed_names) - 不支持中文数字、中文运算符,只能接收英文符号表达式
- 仅拦截函数调用,无法屏蔽复杂无限循环表达式(极少场景风险)
len被放进白名单,表达式中写len([1,2,3])会生效,不需要可以删除
更多推荐



所有评论(0)