TokenEconomizer经验驱动的黑盒成本控制

架构与接口设计

微技能、工具剪枝与失败循环干预这三种核心机制,本身既不知道自己跑在哪个编码智能体上,也不知道评测框架或任务领域是什么。所有与智能体、宿主环境或领域相关的差异,全部收敛在纯标准库包 tokeneconomizer 的四个轻量接口中。

四个核心接口

tokeneconomizer 包不依赖任何第三方库。要接入一个新的智能体或一个新的任务领域,只需要实现下列四个边界之一,无需改动任何机制本身的代码:

  • 会话轨迹读取层(tokeneconomizer.trace):唯一负责读取已保存会话日志的模块(暴露 load_trajectory、call_cwds、tool_usage 与 parse_catalog),每种智能体的日志格式对应其中一个子模块。要支持一个新的编码智能体,只需在这里新增一个读取器,其余代码无需改动。
  • 统一账本与计价层(tokeneconomizer.ledger 与 tokeneconomizer.pricing):全项目对「成本」的唯一定义。各机制在此记录自己每次任务的额外开销(在插件中,一次会话算作一个任务);插件的会话账本与实验的汇总脚本都通过同一组模块读回数据,从而保证记录成本与报告成本绝不发生漂移。
  • 领域适配器(tokeneconomizer.domain.DomainAdapter):面向任务领域的接口,负责定义如何读取会话、工具剪枝应当保护或直接排除哪些工具、如何从轨迹中提取循环信号、传给可选裁判模型的任务文本,以及微技能的领域词表。插件使用的是 tokeneconomizer.plugin.adapter.LiveAdapter;论文基准测试的适配器(SWE-Bench、Web-Bench、CredData、ReposVul)则位于 experiments/te_bench/adapters/。
  • 阶段生命周期接口(tokeneconomizer.stage.Stage):每种机制向调用方暴露的统一四阶段钩子集合:before_task、build_tools、run_kwargs 与 after_task。

两条调用链路

共有两个调用方负责驱动上述 Stage,而核心机制模块绝不反向导入这两个调用方中的任何一个:

  • 日常插件运行时(tokeneconomizer.plugin):通过各智能体暴露的钩子(Pi 上为扩展事件),在开发者的日常会话中运行这些机制。每次会话结束时,在后台对完整会话日志运行 PrefixStage(微技能)与 ToolingStage(工具剪枝);而在会话进行中,每次工具调用都会实时驱动 loopguard.TurnGuard(循环守卫)。
  • 论文基准评估框架(experiments/te_bench):在基准任务流上顺序运行三大机制。Economizer 门面类将三个 Stage 围绕同一个领域适配器组装起来;te_bench.runner.AgentRunner 定义了任务执行容器(Docker、智能体 CLI、评分器)的抽象接口,论文实际使用的实现位于 experiments/te_harness。仅用于基准测试的控制器(如 SpiralStage、流式 NudgeGuard 以及 Codex 终止策略)也存放在该目录中。
架构边界由测试强制锁定。 tests/test_plugin_package.py 静态断言了两条铁律:三大核心机制模块绝不导入 tokeneconomizer.plugin,且 tokeneconomizer/ 下的任何代码绝不导入 experiments/。

六个生命周期钩子

在插件模式下,六个标准钩子把三大机制串联进智能体的日常会话。每一个钩子都遵循故障开放(fail-open)原则:任何异常都会退化为空输出(不对会话做任何改动),并将完整回溯写入 ~/.tokeneconomizer/errors.log。钩子进程仅使用 Python 标准库,且绝不阻塞等待任何模型调用。

钩子事件驱动的机制插件在该钩子中执行的动作
SessionStartmicroskills将当前仓库已确认的微技能(缓存渲染文本)作为 additionalContext 注入;在 Copilot 恢复会话时重放该会话最初启动时的同一份文本以保护缓存;用一行 systemMessage 播报新增事实、新排除的工具或等待确认的提议;顺带归档此前未收到结束钩子的静默会话。
UserPromptSubmitloopguard为循环守卫开启一个新的「提示轮次(prompt-turn)」,重置本轮计数器。
PostToolUseloopguard将该次工具调用折入当前轮次的守卫状态;若异步裁判已判定卡住,将重定向提示作为 additionalContext 附在工具结果后;若重定向后仍卡住,向用户发送一行如何停止的提示(Claude Code 上同时要求模型原样复述);绝不主动终止轮次。
PostToolUseFailureloopguard处理失败的工具调用(Claude Code 与 Copilot 仅在此事件上报失败调用),返回对应事件名的结构化响应并更新失败与空转计数。
Stoploopguard关闭当前提示轮次;若该轮「正常结束」(智能体自行停下,且最后一次编辑后没有失败的验证检查),将其工具调用长度汇入当前仓库的包络(envelope)样本。
SessionEndmicroskills, toolprune, ledger将会话路径交给后台脱离运行的 te fold 进程并立即返回,零阻塞结束会话。

插件运行时的三处针对性增强

后台归档进程 te fold 与轮次守卫 TurnGuard 复用了论文实验中的同一套核心类(PrefixStage、ToolingStage、SpiralState.update、assess_abort 等),所有默认阈值均未重新调参,但针对真实交互式场景做了三项关键适配:

  1. 识别经由 Shell 命令完成的源码编辑:除了专用的 Edit 工具外,守卫还会统计通过 sed -i、perl -pi、重定向或 tee 写入源文件、内联 Python 脚本写回文件、patch / git apply,以及 Codex 的 apply_patch <<'PATCH' 所做的修改。若不计入这些操作,全程通过 Bash 改代码的智能体会被误认为「从未编辑过文件」。
  2. 确保重定向永远先于「仍然卡住」提示触发:基准测试中的任务流很长,学习到的包络(envelope)很大,因此硬兜底线(默认 2.5 倍包络)总在卡死规则底线(默认 20 次调用)之后才触发。而在交互式仓库中,平时的一轮往往很短,学习到的包络较小,2.5 倍包络可能落在 20 次调用以内。为此,插件强制保证:只要本轮还有未使用的重定向配额,第一次触发卡死判定时必定先发送重定向,唯有重定向之后的第二个卡死片段才会向用户发出停止提示。
  3. 裁判与重定向生成脱离钩子异步执行:卡死裁判与重定向文本生成运行在独立的后台进程 te judge 中,而非阻塞在钩子内部。当前 PostToolUse 仅负责启动后台任务并立即返回;待后续工具调用触发 PostToolUse 时,再拾取已生成的裁决与重定向文本并注入上下文。

与论文实验设置的差异

自主连续运行的基准测试与人类开发者的日常交互会话在工作方式上存在本质差异。下表总结了插件相比论文实验设置所做的八项调整及其设计原因:

维度论文实验(Experiments)日常插件(Plugin)为什么这样设计
工作单元单个基准测试任务(task)微技能与工具剪枝按「会话(session)」;循环守卫按「提示轮次(prompt-turn)」交互式开发里用户天然把工作拆成短轮次;若把整场长会话当成一条轨迹,仅因长度就会误判为卡住。
学习信号官方评分器的 resolved 结果包络从「正常结束(ended green)」的轮次学习:智能体自行停止,且最后一次编辑后无失败检查真实日常仓库没有基准评分器;微技能与证据剪枝本就不依赖评分器。
事实注入通道任务提示词(prompt)前缀SessionStart 的 additionalContext(Pi 为系统提示词固定段落)实测验证可直达各智能体模型,且不污染用户自己输入的提示词。
工具移除方式启动参数 --disallowed-tools 或启动时注入 Codex 配置写入仓库本地设置文件(.claude/settings.local.json、.codex/config.toml、.github/copilot/settings.local.json),并在仓库空闲满 60 分钟后落盘,从下一次会话生效插件不负责启动智能体;等待空闲是为了防止用户 resume 热会话时因工具列表变化而丢失整个对话历史的提示缓存。
剪枝候选范围构造上无用的工具(提问、计划模式、子智能体、联网)加证据剪枝仅凭未使用证据(10 次提示横跨 2 个会话,或 5 个会话);向用户提问、计划模式、子智能体与联网工具受到保护永不剪除真实会话中开发者需要提问、规划与查网页。
卡死裁决者有裁判的实验组由轨迹裁判决定;无裁判组由严格规则直接触发守卫开启时始终先经裁判模型(在满 min_turns 且出现重复失败或密集报错时后台唤醒),唯有远超包络 2.5 倍且严格空转的兜底线(backstop)可免裁判触发纯规则会误伤已经找到根因、正在逐步修复的长轮次;交互式轮次常超出小包络,因此仅超包络不会唤醒裁判。
重定向与终止杀死智能体进程,用续写提示词重启;仍卡住则直接终止任务在工具结果后附加轮中重定向提示;仍卡住时仅输出一行停止方式提示,绝不终止轮次并非所有智能体钩子都能中断轮次(Codex 与 Copilot 忽略 continue: false),且交互场景下应由开发者决定去留。
微技能读取范围按基准定制的领域词表(Python/git 或 Node/web),提示词以测试命令为核心通用跨语言摘要:同时识别各生态解释器、构建与检查命令(make、tsc、cargo check 等)、编辑文件与归一化报错行真实仓库可能使用任意语言或多语言混编。

关于各智能体钩子行为的实测细节与缓存保护验证,请继续阅读下一节 插件验证与状态隐私;原始英文设计文档见仓库中的 docs/ARCHITECTURE.md 与 docs/PLUGIN.md。

本站为 TokenEconomizer 论文与仓库的中文导览 · Apache-2.0加州大学伯克利分校 · 微软研究院