---
title: 简介
description: Runic 是一个跨会话缓存和令牌账本，用于记录代理已经解决过的决策。
---
代理会重新决定它们已经决定过的事情。同一个 PR 被总结两次，同一个文件被审查两次，同一条变更日志条目被生成两次——而且每一次，代理都要付出完整成本来重新生成它已经产出的答案。Runic 会记住这个答案。

:::tip
**只问一次。只付一次。**
:::

## Runic 是什么

Runic 位于代理已经用于执行操作的任何机制旁边——包括 MCP 工具调用——作为一项可选检查：*"我以前是否已经解决过这个完全相同的决策？"*

- **一个缓存**，以代理已经做出的决策的精确匹配、规范化签名为键——`{ intent, params }`，绝不使用原始任务文本，也绝不使用推理轨迹。
- **一个账本**，记录已花费的令牌（由代理报告）与复用时节省的令牌。纯粹的记账，不进行强制执行。
- **按会话划分范围。** 跨会话/跨代理共享是后续阶段，前提是先证明单会话复用确实重要。

## Runic 有意不是什么

- **不是执行层。** Runic 从不调用任何能力、部署任何内容或运行代码——代理会自行完成这些操作，并沿用它现有的方式。
- **不是权限或沙箱系统。** 如果没有任何内容执行，就没有需要检查的东西。
- **不是语义缓存。** 匹配针对已解决的决策进行精确匹配，而不是对导致该决策的措辞进行模糊匹配。请参阅 [Scope](/scope)，了解为什么这是约束而非捷径。

## 安装

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

## 循环流程

```txt
agent resolves a task into a structured decision
        │
        ▼
askRunic({ intent, params })
        │
        ├─ hit  → return cached artifact, log tokens saved
        └─ miss → agent generates its own way (as it does today)
                        │
                        ▼
                storeResult({ intent, params }, artifact, tokensSpent)
```

两个函数构成了面向代理的全部契约。此仓库中的其他所有内容都为这两个调用提供支持。

<CodeGroup>

```ts Without Runic
// Every call regenerates the answer, even for a decision you've
// already resolved once today.
async function summarizePr(repo: string, pr: number) {
  const result = await callYourLLM(promptFor(repo, pr));
  return result; // paid full price, every single time
}
```

```ts With Runic
import { askRunic, storeResult } from "@runic-labs/sdk";

async function summarizePr(repo: string, pr: number) {
  const decision = { intent: "summarize_pr", params: { repo, pr } };

  const cached = await askRunic(decision);
  if (cached) return cached.artifact; // no LLM call, no tokens spent

  const result = await callYourLLM(promptFor(repo, pr));
  await storeResult(decision, result, result.tokensUsed);
  return result;
}
```

</CodeGroup>

## 真实数据，而非估算

Runic 从不自行衡量令牌成本——代理会使用其自身提供商实际返回的数据进行报告。一次针对 OpenRouter 的真实运行中，共解决了 48 个决策，其中只有 8 个实际是唯一的：

```json
{
  "decisions": 48,
  "uniqueDecisions": 8,
  "apiCalls": 8,
  "cacheHits": 40,
  "tokensSpent": 2582,
  "tokensSaved": 12910,
  "tokensWithoutRunic": 15492,
  "savingsPercent": 83
}
```

请参阅 [Benchmarks](/benchmarks)，了解如何自行复现这一结果，以及展示相同机制在 10,000 个决策时依然成立的合成测试。

## 软件包

| 软件包 | 功能 |
| --- | --- |
| [`@runic-labs/sdk`](/sdk) | `askRunic` / `storeResult` — 面向代理的全部契约 |
| [`@runic-labs/cache`](/cache) | 签名 → 工件存储（内存中 + 文件支持） |
| [`@runic-labs/ledger`](/ledger) | 已花费与已节省的核算 |
| [`@runic-labs/cli`](/cli) | `runic cache status`, `runic ledger status` |

## 后续步骤

- [Quickstart](/quickstart) — 在几分钟内将 Runic 接入你的代理
- [How it works](/how-it-works) — 签名算法，以及为什么匹配是精确的
- [Scope](/scope) — 早期执行层计划中被删减的内容，以及原因

## 贡献

Runic 是开源项目，欢迎贡献。请参阅仓库中的 `CONTRIBUTING.md` 以了解指南。

## 许可证

MIT
