Jwrede/tokentoll

GitHub: Jwrede/tokentoll

一个通过静态分析 Python 代码中的 LLM API 调用来估算和对比成本变更的 CLI 工具与 GitHub Action,让代码审查阶段就能发现潜在的费用风险。

Stars: 1 | Forks: 0

# tokentoll [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/6558a4d5b0001539.svg)](https://github.com/Jwrede/tokentoll/actions/workflows/ci.yml) [![PyPI 版本](https://img.shields.io/pypi/v/tokentoll)](https://pypi.org/project/tokentoll/) [![GitHub Marketplace](https://img.shields.io/badge/marketplace-tokentoll-blue?logo=github)](https://github.com/marketplace/actions/tokentoll-llm-cost-diff) [![许可证:MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/) 一个 CLI 工具和 GitHub Action,用于静态分析你的代码中的 LLM API 调用, 估算其成本,并在你的终端或以 PR 评论的形式展示每次变更的成本影响。零运行时依赖。

tokentoll demo

## 问题背景 将模型从 `gpt-4o-mini` 单独替换为 `gpt-4o` 会导致成本增加 **15 倍**。 在热点路径中新增的一个 API 调用可能会给你的账单每月增加 **$10,000**。 这些变更通常隐藏在常规的代码审查中。 tokentoll 会找出你代码中的 LLM API 调用,估算其成本, 并在其进入生产环境之前向你展示每次变更的成本影响。 ## 快速开始 ``` pip install tokentoll # 扫描当前目录以查找 LLM API 调用及其成本 tokentoll scan . # 显示你上次 commit 的成本影响 tokentoll diff HEAD~1 # 比较两个分支 tokentoll diff main..feature-branch ``` ## GitHub Action ``` name: LLM Cost Diff on: pull_request: paths: - "**.py" permissions: pull-requests: write jobs: cost-diff: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: Jwrede/tokentoll@v0.6.1 ``` ## 检测范围 | SDK | 匹配模式 | 状态 | |-----|----------|--------| | OpenAI | `chat.completions.create`, `responses.create` | 已支持 | | Anthropic | `messages.create`, `messages.stream` | 已支持 | | Google GenAI | `models.generate_content` | 已支持 | | LiteLLM | `completion`, `acompletion` | 已支持 | | LangChain | `ChatOpenAI`, `ChatAnthropic`, `init_chat_model` | 已支持 | | Zhipu AI | `ZhipuAiClient`, `ZhipuAI` (GLM 模型) | 已支持 | | JS/TS SDKs | | 计划中 | ## 输出示例 ### `tokentoll scan` ``` LLM API Calls Detected ============================================================ File: src/agents/summarizer.py Line 42: openai client.chat.completions.create Model: gpt-4o | Max tokens: 4096 Est. cost/call: $0.03 | Monthly (1000 calls/month per call site): $26.50 Line 78: openai client.chat.completions.create Model: gpt-4o-mini | Max tokens: 1000 Est. cost/call: $0.000301 | Monthly (1000 calls/month per call site): $0.30 -- Total estimated monthly cost: $26.80 1000 calls/month per call site ``` ### `tokentoll diff` ``` LLM Cost Diff: main..feature-branch ============================================================ + ADDED src/agents/rewriter.py:35 openai | Model: gpt-4o Est. cost/call: $0.03 | Monthly: +$26.50 ~ MODIFIED src/agents/summarizer.py:42 openai | Model: gpt-4o -> gpt-4o-mini Est. cost/call: $0.03 -> $0.000301 | Monthly: -$26.20 -- Monthly cost impact: +$0.30 Added: 1 | Changed: 1 | Removed: 0 1000 calls/month per call site ``` ## 工作原理 ``` Source Code (.py files) | v +-------------+ +------------------+ | AST Scanner |---->| SDK Detectors | | (ast.parse) | | OpenAI, Anthropic| +-------------+ | Google, LiteLLM | | LangChain | +------------------+ | v +------------------+ | Pricing Engine | | 2200+ models | | Auto-cached | +------------------+ | +-----------+-----------+ | | v v +------------+ +-------------+ | Scan Report| | Diff Engine | | (costs) | | (old vs new) | +------------+ +-------------+ | | v v +------------+ +-------------+ | Table/JSON | | Table/JSON/ | | | | PR Comment | +------------+ +-------------+ ``` 1. 使用 `ast` 模块解析 Python 文件以查找 LLM API 调用 2. 多轮常量传播技术可解析以下来源的模型名称:变量、`os.getenv()` 回退值、类属性、构造函数参数、字典内容及 `**kwargs` 解包 3. 从本地缓存中查询定价(数据来源于 LiteLLM,涵盖 2200 多个模型) 4. 针对 diff 模式:比较两个 git 引用之间的调用并计算成本差值 5. 以表格、JSON 或 GitHub PR 评论的形式输出成本报告 ## CLI 参考 ``` tokentoll scan [PATH...] [--format table|json|markdown] [--calls-per-month N] [--config PATH] tokentoll diff [REF] [--base REF] [--head REF] [--format table|json|markdown|github-comment] [--config PATH] tokentoll update # Update bundled pricing data ``` ## 定价数据 定价数据已内置并支持离线使用。要更新至最新价格: ``` tokentoll update ``` 定价数据来源于 LiteLLM 的 `model_prices_and_context_window.json`, 涵盖了 OpenAI、Anthropic、Google、AWS Bedrock、Azure 等平台上的 300 多个模型。 ## 动态模型默认值 当 tokentoll 遇到无法解析其模型名称为变量的调用时, 它会应用合理的各 SDK 默认值,以便你仍然可以获得成本估算: | SDK | 默认模型 | |-----|---------------| | OpenAI | `gpt-4o` | | Anthropic | `claude-sonnet-4-20250514` | | Google GenAI | `gemini-2.0-flash` | | LiteLLM | `gpt-4o` | | LangChain | `gpt-4o` | | Zhipu AI | `zai/glm-4.6` | 这些默认值在扫描输出中显示为 `gpt-4o (default)`。你可以使用 `.tokentoll.yml` 配置文件(见下文),按项目或按路径覆盖它们。 ## 配置 在你的项目根目录中创建一个 `.tokentoll.yml` 来自定义行为。 tokentoll 会从扫描目录开始向上遍历,自动查找此文件。 ``` # 所有动态(未解析)调用的默认模型 default_model: gpt-4o # 各个 SDK 的默认值(覆盖上述内置默认值) default_models: openai: gpt-4o-mini anthropic: claude-haiku-3-20240307 # 每个调用位点每月的假定调用次数 calls_per_month: 5000 # 完全跳过对动态(未解析)模型的成本估算。当设为 true 时, # 模型名称无法静态解析的调用将被报告为无 # 成本,而不是按默认值计价。这对于倾向于 # 无估算而非猜测的项目很有用。 skip_dynamic_models: false # 基于路径的覆盖(最长前缀匹配) overrides: - path: tests/ calls_per_month: 100 - path: src/agents/ default_model: gpt-4o calls_per_month: 10000 - path: src/azure/ skip_dynamic_models: true ``` 动态模型默认值的解析顺序为:按 SDK 配置 (`default_models`) > 通用配置 (`default_model`) > 内置 SDK 默认值。 你还可以传递 `--config path/to/.tokentoll.yml` 来使用特定的配置文件。 ## Token 估算 默认情况下,tokentoll 使用“字符数/4”的启发式方法来估算 token 数量。 若要获得更准确的估算,请安装 [tiktoken](https://github.com/openai/tiktoken): ``` pip install tiktoken ``` 当 tiktoken 可用时,tokentoll 会为每个模型使用正确的分词器编码。 未知模型将回退到 `cl100k_base`。tiktoken 是延迟加载的,并且编码器会被缓存, 因此如果你不需要它,就不会有任何启动性能损耗。 ## 智能变量解析 真实的代码库很少将模型名称作为字符串字面量传递。tokentoll 的多轮常量传播引擎支持跟踪: ``` DEFAULT_MODEL = os.getenv("MODEL", "gpt-4o") class Config: model: str = DEFAULT_MODEL config = Config() kwargs = {"model": config.model, "max_tokens": 2000} client.chat.completions.create(**kwargs) # tokentoll 解析结果:model="gpt-4o", max_tokens=2000 ``` - 变量赋值 (`MODEL = "gpt-4o"`) - `os.getenv()` / `os.environ.get()` 回退值 - 函数默认参数 - 类属性默认值 - 构造函数参数传递 - 字典字面量和下标内容 - `**kwargs` 解包 ## 局限性 - 无法解析在运行时从外部配置文件或数据库加载的模型。这些调用将使用各 SDK 的默认值(可通过 `.tokentoll.yml` 配置)。 - 除非安装了 [tiktoken](https://github.com/openai/tiktoken),否则 token 估算使用“字符数/4”的启发式方法。 - 每月估算假设调用量是均匀分布的(可通过 `--calls-per-month` 或 `.tokentoll.yml` 进行配置)。 - 目前仅支持 Python(计划支持 JS/TS)。 ## 许可证 MIT
标签:API调用分析, DLL 劫持, FinOps, GitHub Action, LLM, Python, SaaS成本管理, Unmanaged PE, 代码审查, 大语言模型, 开源, 开源框架, 成本估算, 持续集成, 无后门, 模型切换检测, 费用监控, 逆向工具, 错误基检测, 静态代码分析