---
title: '@runic-labs/ledger'
description: 追加式记录已花费的令牌与通过复用节省的令牌。
sidebar:
  order: 5
---
`@runic-labs/ledger` 纯粹用于记账——它绝不强制执行预算，绝不拒绝调用，也绝不估算你未报告的成本。它回答一个问题：*处理这些决策实际上花费了多少，以及其中有多少通过复用得以避免？*

```package-install
npm i @runic-labs/ledger
```

## `createLedger(store?)`

```ts
import { createLedger, FileLedgerStore, defaultLedgerFilePath } from "@runic-labs/ledger";

const ledger = createLedger(new FileLedgerStore({ filePath: defaultLedgerFilePath() }));
```

如果未传入 store，默认使用 `.runic/ledger.json`（或 `$RUNIC_HOME/ledger.json`）下的 `FileLedgerStore`。

| Prop | Type | Default | Description |
| - | - | - | - |
| `recordMiss(signature, tokensSpent)?` | `void` | - | Logs a cache miss — the agent generated its own way and spent tokensSpent. |
| `recordHit(signature)?` | `void` | - | Logs a cache hit, recording the same tokensSpent as the original miss for this signature. |
| `summary()?` | `LedgerSummary` | - | Aggregated totals — see below. |
| `all()?` | `LedgerEvent[]` | - | The full raw event log. |
| `clear()?` | `void` | - | Removes all events. |

## `LedgerSummary`

```ts
interface LedgerSummary {
  totalSpent: number;
  totalSaved: number;
  hitsBySignature: Record<string, number>;
}
```

```ts
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` 用来输出最终数字的计算方式——参见 [基准测试](/benchmarks)。

## 为什么 `recordHit` 不接受 `tokensSpent` 参数

一次命中的价值被定义为*该签名的原始未命中所花费的成本*——账本会自行查找，而不是相信调用方能在每次命中时都正确重复该值。如果某个签名以某种方式被命中却不存在先前的未命中记录（正常使用中不应发生，但账本不会假设它不可能发生），它会记录 `0`，而不是猜测。

## 存储后端

与 `@runic-labs/cache` 使用相同的模式：`MemoryLedgerStore` 用于测试和临时运行，`FileLedgerStore` 用于跨独立进程调用的持久化。对于其他后端，请自行实现 `LedgerStore` 接口：

```ts
interface LedgerStore {
  append(event: LedgerEvent): void;
  all(): LedgerEvent[];
  clear(): void;
}
```

## 下一步

- [缓存](/cache) — 相匹配的、以签名为键的存储
- [CLI](/cli) — `runic ledger status` 从命令行读取此摘要
