SpyBara
Go Premium

agent-sdk/session-storage.md 2026-06-16 21:57 UTC to 2026-06-17 17:02 UTC

2 added, 0 removed.

2026
Fri 26 07:02 Thu 25 23:58 Wed 24 22:02 Tue 23 22:00 Mon 22 23:59 Fri 19 22:58 Thu 18 22:00 Wed 17 17:02 Tue 16 21:57 Mon 15 23:02 Sat 13 21:59 Fri 12 22:00 Thu 11 23:01 Wed 10 23:57 Tue 9 06:34 Mon 8 06:52 Sat 6 06:24 Fri 5 06:45 Thu 4 06:52 Wed 3 06:53 Tue 2 06:51

Simpan sesi ke penyimpanan eksternal

Cerminkan transkrip sesi ke S3, Redis, atau backend Anda sendiri sehingga host apa pun dapat melanjutkannya.

Secara default, SDK menulis transkrip sesi ke file JSONL di bawah ~/.claude/projects/ pada sistem file lokal. Adaptor SessionStore memungkinkan Anda mencerminkan transkrip tersebut ke backend Anda sendiri, seperti S3, Redis, atau database, sehingga sesi yang dibuat di satu host dapat dilanjutkan di host lain.

Alasan umum untuk menggunakan session store:

  • Penerapan multi-host. Fungsi serverless, pekerja yang diskalakan otomatis, dan runner CI tidak berbagi sistem file. Penyimpanan bersama memungkinkan replika apa pun melanjutkan sesi apa pun.
  • Daya tahan. Kontainer lokal bersifat sementara. Penyimpanan yang didukung oleh S3 atau database bertahan melalui restart dan redeploy.
  • Kepatuhan dan audit. Simpan transkrip dalam penyimpanan yang sudah Anda kelola, dengan aturan retensi, enkripsi, dan kontrol akses Anda sendiri.

Antarmuka `SessionStore`

SessionStore adalah objek dengan dua metode yang diperlukan, append dan load, serta tiga metode opsional. SDK memanggil append untuk menulis entri transkrip selama kueri dan load untuk membacanya kembali untuk resume.

// Exported from @anthropic-ai/claude-agent-sdk as
// SessionStore, SessionKey, SessionStoreEntry.

type SessionKey = {
projectKey: string;
sessionId: string;
subpath?: string;
};

type SessionStore = {
// Required
append(key: SessionKey, entries: SessionStoreEntry[]): Promise<void>;
load(key: SessionKey): Promise<SessionStoreEntry[] | null>;

// Optional
listSessions?(
projectKey: string,
): Promise<Array<{ sessionId: string; mtime: number }>>;
delete?(key: SessionKey): Promise<void>;
listSubkeys?(key: {
projectKey: string;
sessionId: string;
}): Promise<string[]>;
};

SessionKey mengatasi satu transkrip. projectKey adalah pengkodean stabil dan aman sistem file dari direktori kerja, sessionId adalah UUID sesi, dan subpath diatur ketika entri milik transkrip subagent atau file sidecar daripada percakapan utama. Perlakukan subpath sebagai sufiks kunci yang tidak transparan; ini mengikuti tata letak on-disk, misalnya subagents/agent-<id>. Ketika subpath tidak ditentukan, kunci merujuk ke transkrip utama.

Metode Diperlukan Dipanggil ketika
append Ya Setelah setiap batch entri transkrip ditulis secara lokal. Entri adalah objek yang aman JSON, satu per baris dalam JSONL lokal.
load Ya Sekali sebelum subprocess spawn, ketika resume diatur. Kembalikan null jika sesi tidak dikenal.
listSessions Tidak Oleh listSessions({ sessionStore }) dan oleh query()/startup() dengan continue: true. Jika tidak ditentukan, panggilan tersebut melempar.
delete Tidak Oleh deleteSession({ sessionStore }). Menghapus kunci utama (tanpa subpath) harus cascade ke semua subkey untuk sesi itu. Jika tidak ditentukan, penghapusan adalah no-op, yang cocok untuk backend append-only.
listSubkeys Tidak Selama resume, untuk menemukan transkrip subagent. Jika tidak ditentukan, hanya transkrip utama yang dipulihkan.

Mulai cepat

SDK mengirimkan InMemorySessionStore untuk pengembangan dan pengujian. Contoh di bawah menjalankan kueri dengan penyimpanan yang terpasang, menangkap ID sesi dari pesan hasil, kemudian melanjutkan dari penyimpanan dalam panggilan query() kedua. Panggilan kedua melewatkan instance penyimpanan yang sama ditambah resume, sehingga SDK memuat transkrip dari penyimpanan daripada sistem file lokal:

import { query, InMemorySessionStore } from "@anthropic-ai/claude-agent-sdk";

const store = new InMemorySessionStore();

let sessionId: string | undefined;
for await (const message of query({
prompt: "List the TypeScript files under src/",
options: { sessionStore: store },
})) {
if (message.type === "result") {
sessionId = message.session_id;
}
}

// Resume from the store. The agent has full context from the first call.
for await (const message of query({
prompt: "Summarize what those files do",
options: { sessionStore: store, resume: sessionId },
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}

Kueri kedua mencetak ringkasan file dari kueri pertama, yang menunjukkan bahwa agen melanjutkan dengan konteks penuh dari penyimpanan.

Tulis adaptor Anda sendiri

Implementasikan append dan load terhadap backend Anda. Tambahkan listSessions, delete, dan listSubkeys jika Anda ingin listSessions(), deleteSession(), dan subagent resume bekerja terhadap penyimpanan.

Entri yang dilewatkan ke append diketik sebagai SessionStoreEntry (objek { type: string; ... }). Perlakukan mereka sebagai nilai yang aman JSON yang tidak transparan: simpan dalam urutan dan kembalikan dari load dalam urutan yang sama. load harus mengembalikan entri yang deep-equal dengan apa yang ditambahkan; serialisasi byte-equal tidak diperlukan, jadi backend seperti Postgres jsonb yang mengurutkan ulang kunci objek tidak masalah.

Implementasi referensi

Repositori TypeScript SDK mencakup adaptor referensi yang dapat dijalankan untuk S3, Redis, dan Postgres di bawah examples/session-stores/. Mereka tidak dipublikasikan ke npm; salin file src/ yang Anda butuhkan ke proyek Anda dan instal klien backend yang sesuai.

Adaptor Klien backend Model penyimpanan
S3SessionStore @aws-sdk/client-s3 Satu file bagian JSONL per append(); load() mencantumkan, mengurutkan, dan menggabungkan.
RedisSessionStore ioredis RPUSH/LRANGE list per transkrip, ditambah indeks sorted-set sesi.
PostgresSessionStore pg Satu baris per entri dalam tabel jsonb, diurutkan oleh BIGSERIAL.

Setiap adaptor mengambil instance klien yang telah dikonfigurasi sebelumnya, sehingga Anda mengontrol kredensial, TLS, region, dan pooling. Misalnya, dengan S3:

import { query } from "@anthropic-ai/claude-agent-sdk";
import { S3Client } from "@aws-sdk/client-s3";
import { S3SessionStore } from "./S3SessionStore"; // copied from examples/session-stores/s3

const store = new S3SessionStore({
  bucket: "my-claude-sessions",
  prefix: "transcripts",
  client: new S3Client({ region: "us-east-1" }),
});

for await (const message of query({
  prompt: "Hello!",
  options: { sessionStore: store },
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}

// Later, possibly on a different host:
for await (const message of query({
  prompt: "Continue where we left off",
  options: { sessionStore: store, resume: "previous-session-id" },
})) {
  // ...
}

Validasi adaptor Anda

Kedua SDK mengirimkan suite conformance yang menegaskan kontrak perilaku append, load, dan metode opsional harus memuaskan. Tes untuk metode opsional melewati secara otomatis ketika metode tersebut tidak diimplementasikan.

Di TypeScript, salin shared/conformance.ts dari direktori contoh ke dalam suite pengujian Anda. Di Python, suite dikirimkan dalam paket:

import pytest
from claude_agent_sdk.testing import run_session_store_conformance


@pytest.mark.asyncio
async def test_my_store_conformance():
    await run_session_store_conformance(MyRedisStore)

Catatan perilaku

Arsitektur dual-write

Penyimpanan adalah cerminan, bukan pengganti. Subprocess Claude Code selalu menulis ke disk lokal terlebih dahulu; SDK kemudian meneruskan setiap batch ke append(). Jika Anda ingin salinan lokal bersifat sementara, arahkan CLAUDE_CONFIG_DIR ke direktori temp di options.env. Karena cerminan bergantung pada penulisan lokal, sessionStore tidak dapat digabungkan dengan persistSession: false; SDK melempar jika Anda menetapkan keduanya. Ini juga melempar jika digabungkan dengan enableFileCheckpointing, karena blob cadangan riwayat file ditulis langsung ke disk lokal dan tidak dicerminkan ke penyimpanan.

Penulisan cerminan adalah best-effort

Jika append() menolak atau timeout, kesalahan dicatat, pesan { type: "system", subtype: "mirror_error" } dipancarkan ke iterator, dan kueri berlanjut. Transkrip lokal sudah tahan lama di disk, jadi pemadaman penyimpanan tidak mengganggu agen atau kehilangan data secara lokal. Batch yang gagal tidak dicoba ulang, jadi pantau mirror_error jika Anda perlu mendeteksi kehilangan data penyimpanan.

`getSessionMessages` mengembalikan rantai post-compaction

getSessionMessages({ sessionStore }) mengembalikan rantai pesan tertaut yang akan dilihat agen pada resume. Setelah auto-compaction, giliran sebelumnya diganti dengan ringkasan, jadi sesi yang penyimpanannya menyimpan 503 entri mentah dapat mengembalikan 18 pesan dari getSessionMessages. Untuk riwayat mentah lengkap, termasuk giliran pre-compaction dan entri metadata, panggil store.load(key) secara langsung.

`forkSession` bukan salinan byte

forkSession({ sessionStore }) membaca entri sumber, menulis ulang setiap bidang sessionId dan memetakan ulang UUID pesan, kemudian menambahkan entri yang ditransformasi di bawah kunci baru. Salinan tingkat adaptor atau shortcut CopyObject akan menghasilkan transkrip yang masih mereferensikan ID sesi lama, jadi SDK tidak menggunakannya.

Transkrip subagent

Transkrip subagent dicerminkan di bawah subpath: "subagents/agent-<id>". listSubagents({ sessionStore }) memerlukan adaptor untuk mengimplementasikan listSubkeys; getSubagentMessages({ sessionStore }) menggunakannya ketika tersedia tetapi kembali ke subpath langsung ketika tidak ditentukan. Resume juga memanggil listSubkeys untuk memulihkan file subagent; tanpanya, hanya transkrip utama yang dimaterialisasi.

Retensi

SDK tidak pernah menghapus dari penyimpanan Anda sendiri. Retensi adalah tanggung jawab adaptor: implementasikan TTL, kebijakan lifecycle S3, atau pembersihan terjadwal sesuai dengan persyaratan kepatuhan Anda. Transkrip lokal di bawah CLAUDE_CONFIG_DIR disapu secara independen oleh pengaturan cleanupPeriodDays.

Didukung pada

Fungsi SDK berikut menerima opsi sessionStore dan beroperasi terhadap penyimpanan daripada sistem file lokal ketika disediakan: