@runic-labs/ledger
追加式记录已花费的令牌与通过复用节省的令牌。
@runic-labs/ledger 纯粹用于记账——它绝不强制执行预算,绝不拒绝调用,也绝不估算你未报告的成本。它回答一个问题:处理这些决策实际上花费了多少,以及其中有多少通过复用得以避免?
npm install @runic-labs/ledgerpnpm add @runic-labs/ledgeryarn add @runic-labs/ledgerbun add @runic-labs/ledgercreateLedger(store?)
import { createLedger, FileLedgerStore, defaultLedgerFilePath } from "@runic-labs/ledger";
const ledger = createLedger(new FileLedgerStore({ filePath: defaultLedgerFilePath() }));
如果未传入 store,默认使用 .runic/ledger.json(或 $RUNIC_HOME/ledger.json)下的 FileLedgerStore。
recordMiss(signature, tokensSpent)?void
Logs a cache miss — the agent generated its own way and spent tokensSpent.
voidrecordHit(signature)?void
Logs a cache hit, recording the same tokensSpent as the original miss for this signature.
voidsummary()?LedgerSummary
Aggregated totals — see below.
LedgerSummaryall()?LedgerEvent[]
The full raw event log.
LedgerEvent[]clear()?void
Removes all events.
voidLedgerSummary
interface LedgerSummary {
totalSpent: number;
totalSaved: number;
hitsBySignature: Record<string, number>;
}
const summary = ledger.summary();
const totalHits = Object.values(summary.hitsBySignature).reduce((a, b) => a + b, 0);
const tokensWithoutRunic = summary.totalSpent + summary.totalSaved;
const savingsPercent = Math.round((summary.totalSaved / tokensWithoutRunic) * 100);
这正是 benchmarks/openrouter-savings 和 benchmarks/reuse-sweep 用来输出最终数字的计算方式——参见 基准测试。
为什么 recordHit 不接受 tokensSpent 参数
一次命中的价值被定义为该签名的原始未命中所花费的成本——账本会自行查找,而不是相信调用方能在每次命中时都正确重复该值。如果某个签名以某种方式被命中却不存在先前的未命中记录(正常使用中不应发生,但账本不会假设它不可能发生),它会记录 0,而不是猜测。
存储后端
与 @runic-labs/cache 使用相同的模式:MemoryLedgerStore 用于测试和临时运行,FileLedgerStore 用于跨独立进程调用的持久化。对于其他后端,请自行实现 LedgerStore 接口:
interface LedgerStore {
append(event: LedgerEvent): void;
all(): LedgerEvent[];
clear(): void;
}