Skip to main content

avada-eval

Safe, Decimal-exact expression evaluator for LLM tools, derived from simpleeval.

安全、可扩展、给大模型当计算工具用的表达式求值器。派生自 simpleeval(v1.0.8,commit 3b30888d0d5954df8a11b7e5ef26d17e19a96c29,MIT,© 2013-2026 Daniel Fairhead), 核心区别:用 decimal.Decimal 代替 float 做精确计算,并加固了资源耗尽(DoS)防护。

pip install avada-eval        # 或 uv add avada-eval

需要 Python ≥ 3.11;唯一运行时依赖 beartype(运行时类型检查,AVADA_BEARTYPE_ON=false 可关闭)。

快速示例

from avada_eval import simple_eval, SimpleEval  # 替换 `from simpleeval import ...`

simple_eval("0.1 + 0.2")  # Decimal('0.3')
simple_eval("1 / 3")  # Decimal('0.3333333333333333333333333333')
simple_eval("2 ** 100")  # 1267650600228229401496703205376(int 精确)
simple_eval("price * qty", names={"price": 19.99, "qty": 3})  # Decimal('59.97')

Decimal 语义(与 simpleeval 的差异)

项 simpleeval avada-eval
小数字面量 float 按源码原文构造的 Decimal(1.10 保留尾零)
整数字面量 int int(** // % 位运算与 Python 一致)
/ float Decimal(int/int 亦然)
负/小数指数 ** float Decimal;Decimal 路径只限制指数,结果超出 Emax → NumberTooHigh
Decimal 的 // % — 取整向下(与 int/float 一致,而非 decimal 模块的截断)
除零 ZeroDivisionError DivisionByZero(同时是 InvalidExpression 与 ZeroDivisionError)
外部 float 原样 float_policy="convert"(默认,Decimal(str(x)))或 "error"(FloatNotAllowed)
默认函数 rand randint int float str 另加 decimal round abs min max sum;float()/rand() 返回 Decimal;sum 同 min/max 也接受直接传数(sum(1, 2, 3))
函数参数错误 TypeError / ValueError InvalidArguments(个数/类型错)/ InvalidArgumentValue(值不可用),均为 InvalidExpression,且仍分别是 TypeError / ValueError;信息带表达式中的函数名与用法
精度/舍入 — context=decimal.Context(...),每次 eval 在 localcontext 中执行

默认 context:28 位有效数字、ROUND_HALF_EVEN、Emax/Emin = ±999999,InvalidOperation / DivisionByZero / Overflow 以异常抛出。设计决策见 ADR 0002。

LLM 工具用法(avada_eval.llm)

from avada_eval.llm import evaluate_for_llm, TOOL_DESCRIPTION

evaluate_for_llm("revenue * 12.5% + 1,000", {"revenue": 80000}).to_dict()
# {'ok': True, 'normalized': 'revenue * 0.125 + 1000', 'value': '11000.000', 'variables': {'revenue': '80000'}, ...}
  • evaluate_for_llm 从不因表达式错误而抛异常:语法错误、未知名字、除零、安全拒绝等都以 ok=False + error / error_type 返回,模型可据此重试;TOOL_DESCRIPTION 可直接作为工具描述。 函数参数写错(pct_change(1)、round("x"))返回 InvalidArguments 等;库内部的意外异常也不外抛,而是记日志(logger avada_eval.llm.tool)并返回 ok=False、error="internal error: <类型>: <消息>"。
  • sum / min / max / avg 可直接传数:sum(1, 2, 3)(该工具默认不支持列表字面量,列表只能经变量传入:sum(values))。
  • 财务函数:pct_change(new, old)、cagr(end, start, years)(均返回百分点)、ratio(a, b)、avg(...)。
  • 千分位:逗号两侧无空格且分组合法(首组 1-3 位、其后每组 3 位)才视为千分位;逗号后带空格永远是参数分隔符(max(1, 234))。
  • 百分号:紧贴数字、且其后是结尾/空白/非操作数() , * …)的 % 是百分号;10%3、10 % 3 仍是取模。

安全

安全模型继承 simpleeval 并只加强不削弱:禁止 _/func_ 前缀属性、format/format_map 等危险方法、DISALLOW_FUNCTIONS、模块访问(需显式 ModuleWrapper)、lambda / import / 赋值。

资源耗尽防护在分配或计算之前按估算值拦截(修复了 simpleeval 中 '%999999999d' % 1、f"{1:999999999}"、"a".center(999999999)、4000000 ** 4000000、 '%d' % 1e999999 等先分配/计算再检查的问题)。上限为 avada_eval.evaluator 的模块级常量,调用时读取:

常量 默认 作用
MAX_STRING_LENGTH 100000 构造出的字符串/序列长度(容器按嵌套元素总数计)
MAX_FORMAT_WIDTH 10000 格式化 width/precision 与 center/ljust/rjust/zfill/expandtabs 宽度
MAX_INT_BITS 15000 任何 int 的位数
MAX_POWER / MAX_SHIFT 4000000 / 10000 ** 底数与指数、移位量
MAX_POWER_BASE_DIGITS 1000 Decimal 小数次幂的底数位数
MAX_COMPREHENSION_LENGTH 10000 推导式迭代次数(EvalWithCompoundTypes)
import avada_eval.evaluator as evaluator

evaluator.MAX_FORMAT_WIDTH = 1000  # 与 simpleeval 一样,直接改模块属性

完整排查清单与拦不住的部分(表达式长度、推导式总内存、自定义 context 等)见 ADR 0003。 对不可信输入,仍建议限制表达式长度,并在带超时与内存上限的子进程中求值。

命令行

avada "0.1 + 0.2"
avada "round(x * 3, 1)" -v x=0.05 --rounding ROUND_HALF_UP
avada "a + 1,000" -v a=1.5 --json

开发

uv sync 后,make fmt 做格式化,./ci.sh(从仓库根运行)是唯一的零警告质量门: ruff format/check → mypy --strict → 结构检查 → 文档漂移 → pytest。

许可

MIT,见 LICENSE(保留 simpleeval 原版权声明)。

Metadata

Release files for avada-eval 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for avada-eval 0.1.1
File Size Uploaded
avada_eval-0.1.1.tar.gz 104.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for avada-eval 0.1.1
File Interpreter ABI Platform
avada_eval-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 140.0 kB

Release files / avada_eval-0.1.1.tar.gz

Download URL avada_eval-0.1.1.tar.gz
Size 104.4 kB
Tags Source
SHA-256 checksum
How to use checksums
871764cd80d2c82f087f7c7e4f28ab6975d764a96706e73158fd765e76f671ae
BLAKE2b-256 checksum
How to use checksums
6ac013406daf4886cc2fa10ec6e8e9a17d1ab98eb4de8bf51bfa5796bccc66c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.4

Release files / avada_eval-0.1.1-py3-none-any.whl

Download URL avada_eval-0.1.1-py3-none-any.whl
Size 35.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
108c8aee833d69efffadc2e576fe4dae443589eb6e431a30aaaf383ea0c0ac99
BLAKE2b-256 checksum
How to use checksums
f83102bdc7b2c1495c9ca214f80cbf7d297c9e0fcd265981ab43a101f54b48e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.4

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page