Persist Sessions ไปยัง External Storage
Mirror session transcripts ไปยัง S3, Redis หรือ backend ของคุณเองเพื่อให้ host ใดก็ตามสามารถ resume ได้
โดยค่าเริ่มต้น SDK จะเขียน session transcripts เป็นไฟล์ JSONL ภายใต้ ~/.claude/projects/ บน local filesystem adapter SessionStore ช่วยให้คุณ mirror transcripts เหล่านั้นไปยัง backend ของคุณเอง เช่น S3, Redis หรือ database เพื่อให้ session ที่สร้างบน host หนึ่งสามารถ resume บน host อื่นได้
เหตุผลทั่วไปในการใช้ session store:
- Multi-host deployments. Serverless functions, autoscaled workers และ CI runners ไม่แชร์ filesystem shared store ช่วยให้ replica ใดก็ตามสามารถ resume session ใดก็ตามได้
- Durability. Local containers เป็น ephemeral store ที่ backed ด้วย S3 หรือ database รอดจากการ restart และ redeploy
- Compliance และ audit. เก็บ transcripts ใน storage ที่คุณ govern อยู่แล้ว พร้อม retention rules, encryption และ access controls ของคุณเอง
Interface SessionStore
SessionStore คือ object ที่มีสองวิธีที่จำเป็น append และ load และสามวิธีที่เป็น optional SDK จะเรียก append เพื่อเขียน transcript entries ระหว่าง query และ load เพื่ออ่านกลับมาสำหรับ resume
// Export จาก @anthropic-ai/claude-agent-sdk เป็น
// 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[]>;
};
# Export จาก claude_agent_sdk เป็น
# SessionStore, SessionKey, SessionStoreEntry.
class SessionKey(TypedDict):
project_key: str
session_id: str
subpath: NotRequired[str]
class SessionStore(Protocol):
# Required
async def append(
self, key: SessionKey, entries: list[SessionStoreEntry]
) -> None: ...
async def load(self, key: SessionKey) -> list[SessionStoreEntry] | None: ...
# Optional — omit หรือ raise NotImplementedError
async def list_sessions(
self, project_key: str
) -> list[SessionStoreListEntry]: ...
async def delete(self, key: SessionKey) -> None: ...
async def list_subkeys(self, key: SessionListSubkeysKey) -> list[str]: ...
SessionKey ระบุ transcript หนึ่งอัน projectKey เป็น stable, filesystem-safe encoding ของ working directory, sessionId เป็น session UUID และ subpath จะถูกตั้งเมื่อ entry เป็นของ subagent transcript หรือ sidecar file แทน main conversation
| Method | Required | เรียกเมื่อ |
|---|---|---|
append | Yes | หลังจากแต่ละ batch ของ transcript entries ถูกเขียน locally |
load | Yes | ครั้งเดียวก่อน subprocess spawn เมื่อตั้ง resume |
listSessions | No | โดย listSessions({ sessionStore }) และโดย query()/startup() พร้อม continue: true |
delete | No | โดย deleteSession({ sessionStore }) |
listSubkeys | No | ระหว่าง resume เพื่อค้นพบ subagent transcripts |
Quick Start
SDK มาพร้อม InMemorySessionStore สำหรับการพัฒนาและทดสอบ ตัวอย่างด้านล่างรัน query พร้อม store ที่แนบ, capture session ID จาก result message จากนั้น resume จาก store ใน query() call ที่สอง:
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 จาก store agent มี context เต็มจาก 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);
}
}
import asyncio
from claude_agent_sdk import (
ClaudeAgentOptions,
InMemorySessionStore,
ResultMessage,
query,
)
store = InMemorySessionStore()
async def main():
session_id = None
async for message in query(
prompt="List the Python files under src/",
options=ClaudeAgentOptions(session_store=store),
):
if isinstance(message, ResultMessage):
session_id = message.session_id
# Resume จาก store agent มี context เต็มจาก call แรก
async for message in query(
prompt="Summarize what those files do",
options=ClaudeAgentOptions(session_store=store, resume=session_id),
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())
เขียน Adapter ของคุณเอง
Implement append และ load กับ backend ของคุณ เพิ่ม listSessions, delete และ listSubkeys หากต้องการให้ listSessions(), deleteSession() และ subagent resume ทำงานกับ store
Entries ที่ส่งไปยัง append มี type เป็น SessionStoreEntry (object { type: string; ... }) ให้ treat เป็น opaque JSON-safe values: persist ตามลำดับและส่งคืนจาก load ในลำดับเดิม
Reference Implementations
TypeScript SDK repository มี reference adapters ที่รันได้สำหรับ S3, Redis และ Postgres ภายใต้ examples/session-stores/
| Adapter | Backend client | Storage model |
|---|---|---|
S3SessionStore | @aws-sdk/client-s3 | ไฟล์ JSONL part หนึ่งต่อ append(); load() list, sort และ concatenate |
RedisSessionStore | ioredis | RPUSH/LRANGE list ต่อ transcript บวก sorted-set session index |
PostgresSessionStore | pg | แถวต่อ entry ใน jsonb table เรียงตาม BIGSERIAL |
Adapter แต่ละตัวรับ pre-configured client instance ดังนั้นคุณควบคุม credentials, TLS, region และ pooling ตัวอย่างกับ 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);
}
}
// ภายหลัง อาจบน host อื่น:
for await (const message of query({
prompt: "Continue where we left off",
options: { sessionStore: store, resume: "previous-session-id" },
})) {
// ...
}
Validate Adapter ของคุณ
ทั้งสอง SDKs มาพร้อม conformance suite ที่ assert contract พฤติกรรมที่ append, load และ optional methods ต้องปฏิบัติตาม
ใน TypeScript ให้ copy shared/conformance.ts จาก example directory เข้า test suite ของคุณ ใน Python, suite มาพร้อมใน package:
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)
หมายเหตุพฤติกรรม
Dual-write Architecture
Store เป็น mirror ไม่ใช่ตัวแทน Claude Code subprocess เขียนไปยัง local disk ก่อนเสมอ SDK จะ forward แต่ละ batch ไปยัง append() หากต้องการให้ local copy เป็น ephemeral ให้ชี้ CLAUDE_CONFIG_DIR ไปยัง temp directory ใน options.env
Mirror Writes เป็น Best-effort
หาก append() ปฏิเสธหรือหมดเวลา error จะถูก log, message { type: "system", subtype: "mirror_error" } จะถูก emit เข้า iterator และ query จะดำเนินต่อ local transcript ยังคง durable บน disk ดังนั้น store outage จะไม่ขัดแย้ง agent หรือสูญเสียข้อมูล locally
getSessionMessages ส่งคืน Post-compaction Chain
getSessionMessages({ sessionStore }) ส่งคืน linked message chain ที่ agent จะเห็นเมื่อ resume หลังจาก auto-compaction turns ก่อนหน้าจะถูกแทนที่ด้วย summary ดังนั้น session ที่ store เก็บ 503 raw entries อาจส่งคืน 18 messages จาก getSessionMessages
forkSession ไม่ใช่ Byte Copy
forkSession({ sessionStore }) อ่าน source entries, เขียนทับทุก field sessionId และ remap message UUIDs จากนั้น append transformed entries ภายใต้ key ใหม่
Subagent Transcripts
Subagent transcripts ถูก mirror ภายใต้ subpath: "subagents/agent-<id>" listSubagents({ sessionStore }) ต้องการ adapter เพื่อ implement listSubkeys
Retention
SDK ไม่ลบจาก store ของคุณเอง Retention เป็นความรับผิดชอบของ adapter: implement TTLs, S3 lifecycle policies หรือ scheduled cleanup ตามความต้องการ compliance ของคุณ
รองรับโดย
SDK functions ต่อไปนี้รับ option sessionStore และทำงานกับ store แทน local filesystem เมื่อ provide:
query()startup()listSessions()getSessionInfo()getSessionMessages()renameSession()tagSession()deleteSession()forkSession()listSubagents()getSubagentMessages()
Resources ที่เกี่ยวข้อง
- Work with sessions: Continue, resume และ fork โดยไม่ต้องมี custom store
- Host the SDK: Deployment patterns สำหรับสภาพแวดล้อม multi-host
- TypeScript
Options: Full option reference examples/session-stores/: Runnable S3, Redis และ Postgres reference adapters