リコールキャッシング

繰り返しのリコールは、10分の1の価格で。

リクエストごとにオプトインすると、WOSは検索結果をクエリテキストに紐づけてキャッシュします。ルールはLLMのプロンプトキャッシングと同じプレフィックス方式です。キャッシュが有効な間、繰り返しや続きのクエリは前回の結果を再利用し、キャッシュされた部分は通常のトークン単価の10%で課金されます。

Tablet・Scroll限定。 キャッシングは現在および将来のすべてのTablet・Scrollモデルで動作します。Bookはサポートしていません。Bookは記憶の上で推論し、呼び出しの間に学習するため、同じ質問でも答えが正当に変わることがあり、キャッシュされた結果は設計上誤った答えになります。Bookにcache_controlを送ると、明確に403を返します。

1つの会話、3つのターン

エージェントが記憶と会話し続けるとき、実際に起きることです。毎ターン、それまでの会話をクエリとして送り、cache_controlをオンにします。

writeターン1 - 「アリス: 去年の春リスボンに引っ越したの。」

クエリ全体が検索されキャッシュされます: 入力は2倍 (TTL 5分)。

extendターン2 - 同じテキスト + 「ボブ: そっちの天気はどう?」

ボブの文だけが索引付けされ検索されます。前の部分は0.1倍、新しい文は2倍。キャッシュはその文で終わるようになります。

hitターン3 - まったく同じクエリをもう一度 (リトライ、リフレッシュ)

エンジン呼び出しは一切ありません。すべて0.1倍: 90%割引です。

料金

操作トークン課金意味
キャッシュ書き込み - TTL 5分最初のリクエストです。結果は5分間保持され、読み取るたびに有効期間が延長されます。
キャッシュ書き込み - TTL 1時間最初のリクエストで、1時間保持されます。
キャッシュ読み取り - ヒットまたはプレフィックスヒット0.1×書き込み後のすべてのリクエスト: キャッシュされた部分は通常のトークン単価の10分の1になります。

どれだけ節約できるか

具体例: エージェントが3,000トークンの会話をクエリとして送り、5分以内に10回繰り返すか続けるとします。キャッシュなしでは定価で30,000入力トークン。5分キャッシュなら最初の書き込み6,000(2倍) + 9回のキャッシュ読み取り約2,700 = 課金トークン8,700で、71%の節約です。会話が長くなるほど節約は大きくなります。

プレフィックスのルール

マッチングはクエリの先頭部分で行われます。先頭がそのままで、末尾に新しいテキストが追加されただけなら、キャッシュ部分を再利用し、新しい部分だけを検索します。キャッシュされたテキストの終わりより前で何かが変わると、何も再利用できません。

prefix match
cached    [ A B C D E F G ]

○   [ A B C D E F G ] E
✗   [ B C D E F G ] E

ヒット - 先頭は変わらず、Eだけが新しい部分です
ミス - 先頭が変わったため、クエリ全体を再検索して再キャッシュします

覚えておくべき3つのルール

  • 延長すると新しい末尾まで再キャッシュされます。 [A B C D E F G] + E の後、キャッシュはEで終わります。末尾は書き込み料金で一度だけ課金され、次のターンはAからEまで全体をプレフィックスとして再びマッチできます。
  • 1リクエストにつき連続したプレフィックスは1つです。 1つのクエリを2つのキャッシュ断片に分割することはできず、マッチするのは先頭部分だけです。
  • 書き込みは即座に無効化します。 store、store-turn、bulk-store、forget、supersede、ストア削除が起きると、そのストアのキャッシュは破棄されます。キャッシュされた回答が古い記憶を返すことはありません。

有効にする方法

hits = mem.search(
    "...the conversation so far...", user_id="alice",
    cache_control={"ttl": "5m"},   # or "1h"
)
const hits = await mem.search(
  "...the conversation so far...", "alice", 10,
  { cache_control: { ttl: "5m" } },   // or "1h"
);
let hits = mem.search_with(
    "...the conversation so far...", "alice", 10,
    serde_json::json!({"cache_control": {"ttl": "5m"}}),   // or "1h"
).await?;
curl -X POST https://api.wontopos.com/api/v1/memory/search \
  -H "X-API-Key: $WOS_API_KEY" -H "Content-Type: application/json" \
  -d '{"user_id":"alice",
       "query":"...the conversation so far...",
       "cache_control":{"ttl":"5m"}}'   # or "1h"
レスポンス - cacheオブジェクトが何が起きたかを報告します
{ "memories": [ ... ],
  "cache": { "status": "hit",              // "write" | "hit" | "extend"
             "ttl": "5m",
             "cache_read_input_tokens": 412,
             "cache_creation_input_tokens": 0 } }

この機能に SDK は必須ではありません。キャッシングは 1 回の HTTP 呼び出しに付くフィールド 1 つなので、どのプログラミング言語からでも動作します。curl タブが万能のレシピで、Python・TypeScript・Rust の SDK は同じ呼び出しを包んだ便利ツールにすぎません。

キャッシングはワークスペース内でストアごと、モデルごとに分離されており、デフォルトはオフです。cache_controlを送らなければ、リクエストは何も変わりません。