---
title: はじめに
description: Runic は、エージェントがすでに解決済みの判断のための、セッション内キャッシュおよびトークン台帳です。
---
エージェントは、すでに決めたことを再び決めてしまいます。同じ PR が2回要約され、同じファイルが2回レビューされ、同じ変更履歴エントリが2回生成されます。そしてそのたびに、エージェントはすでに生成した回答を再生成するために全額を支払います。Runic は代わりにその回答を記憶します。

:::tip
**一度聞けば、一度だけ支払う。**
:::

## Runic とは

Runic は、MCP ツール呼び出しを含む、エージェントが行動するためにすでに使用しているあらゆるものの隣で、任意の確認として機能します。*「このまったく同じ判断を、以前にすでに解決したことがあるか？」*

- **キャッシュ**。エージェントがすでに行った判断の完全一致かつ正規化されたシグネチャ、つまり `{ intent, params }` をキーとします。生のタスクテキストや推論トレースをキーにすることはありません。
- **台帳**。消費したトークン数（エージェント報告）と再利用によって節約したトークン数を記録します。純粋な記録であり、強制はしません。
- **セッション単位のスコープ。** セッション間・エージェント間の共有は、セッション内での再利用に価値があることが証明された後の段階です。

## Runic が意図的に行わないこと

- **実行レイヤーではありません。** Runic が機能を呼び出したり、何かをデプロイしたり、コードを実行したりすることはありません。エージェントが、すでに行っている方法で自ら実行します。
- **権限管理やサンドボックス化のシステムではありません。** 何も実行されないなら、確認すべきこともありません。
- **セマンティックキャッシュではありません。** 一致判定は、そこに至る表現を曖昧に照合するのではなく、解決済みの判断に対して完全一致で行われます。これが近道ではなく制約である理由については、[スコープ](/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)
```

エージェント向けの契約は、この2つの関数だけです。このリポジトリ内のその他すべては、この2つの呼び出しを支えています。

<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
}
```

これを自分で再現する方法と、同じ仕組みが10,000件の判断でも成り立つことを示す合成スイープについては、[ベンチマーク](/benchmarks)を参照してください。

## パッケージ

| パッケージ | 機能 |
| --- | --- |
| [`@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) — 数分で Runic をエージェントに組み込む
- [仕組み](/how-it-works) — シグネチャアルゴリズムと、一致判定が完全一致である理由
- [スコープ](/scope) — 以前の実行レイヤー計画から何を削り、なぜそうしたのか

## コントリビューション

Runic はオープンソースであり、コントリビューションを歓迎しています。ガイドラインについては、リポジトリ内の `CONTRIBUTING.md` を参照してください。

## ライセンス

MIT
