Agent SDK のセッション:continue・resume・fork で会話を再開する

Claude Agent SDK エンジニアリング 7分で読めます

Claude Agent SDK のセッションは、エージェントが作業する間に積み上がる会話履歴です。SDK はこれを自動でディスクに書き出すので、あとから同じ文脈に戻って追加の質問をしたり、中断した作業を再開したり、別の方針を試したりできます。

この記事では、公式ドキュメント「Work with sessions」に沿って、continue・resume・fork の違いと使い分け、session_id の取り出し方、セッションファイルの保存場所、別のマシンで再開するときの考え方を整理します。対話型の Claude Code でのセッション操作は「Claude Code のセッション管理(再開・命名・分岐)」を参照してください。

セッションとは何か

セッションには、渡したプロンプト、エージェントが行ったすべてのツール呼び出し、ツールの結果、応答が含まれます。セッションに戻ると、エージェントは前回までの文脈(読んだファイル、行った分析、下した判断)をすべて持った状態で続きを始めます。

注意したいのは、セッションが保存するのは会話であってファイルシステムではない点です。エージェントが加えたファイル変更を記録して元に戻したい場合は、別の仕組みであるファイルチェックポイントを使います。

また、1回の query() の中では、エージェントは必要なだけターンを重ねます。権限の確認や AskUserQuestion もループの中で処理され、呼び出しは終わりません。セッション管理が必要になるのは、文脈を共有したい複数のプロンプトを送るときです。

用途別の選び方

公式は、作るアプリの形に応じて次のように使い分けるよう示しています。

作るもの使うもの
1回きりのタスク(追加の質問なし)何も要らない。query() 1回で済む
1つのプロセス内での複数ターンのチャットPython は ClaudeSDKClient、TypeScript は continue: true。ID の管理は不要
プロセスを再起動したあとに続きからPython は continue_conversation=True、TypeScript は continue: true。そのディレクトリの最新セッションを再開する
最新ではない特定の過去セッションに戻るセッション ID を控えて resume に渡す
元を残したまま別の方針を試すセッションを fork する
ディスクに何も残したくないステートレスな処理TypeScript は persistSession: false(メモリ上だけで動く)。Python は env オプションで環境変数 CLAUDE_CODE_SKIP_PROMPT_HISTORY を設定して記録の書き出しを抑える

3つのオプションの違いは次のとおりです。いずれも query() のオプション(Python の ClaudeAgentOptions、TypeScript の Options)に指定します。

自動でセッションを引き継ぐ

Python:ClaudeSDKClient

ClaudeSDKClient はセッション ID を内部で管理し、client.query() を呼ぶたびに同じセッションを続けます。応答は client.receive_response() で順に受け取ります。非同期コンテキストマネージャとして使えば接続の開始と終了も任せられます(手動なら connect() と disconnect())。

async with ClaudeSDKClient(options=options) as client:
    # 1回目:client がセッション ID を内部で控える
    await client.query("Analyze the auth module")
    async for message in client.receive_response():
        print_response(message)

    # 2回目:自動的に同じセッションの続きになる
    await client.query("Now refactor it to use JWT")
    async for message in client.receive_response():
        print_response(message)

同じクライアントを通しているので、2回目の問い合わせは resume も ID も使わずに1回目の分析を踏まえて動きます。

TypeScript:continue: true

TypeScript SDK には ClaudeSDKClient のようなセッションを保持するクライアントはありません。代わりに、2回目以降の query() に continue: true を付けると、SDK が現在のディレクトリで最新のセッションを探して再開します。

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

// 2回目:continue: true で直前のセッションを再開する
for await (const message of query({
  prompt: "Now refactor it to use JWT",
  options: {
    continue: true,
    allowedTools: ["Read", "Edit", "Write", "Glob", "Grep"]
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}

なお、createSession() と send / stream を使う実験的な V2 セッション API は、TypeScript Agent SDK 0.3.142 で削除されています。現在は query() とこの記事のオプションを使います。

session_id を控えて resume する

セッション ID を取り出す

resume と fork にはセッション ID が必要です。ID は結果メッセージ(Python の ResultMessage、TypeScript の SDKResultMessage)の session_id にあり、成功でもエラーでも必ず入っています。TypeScript では最初の init の SystemMessage にも直接のフィールドとして入り、Python では SystemMessage.data の中にあります。

let sessionId: string | undefined;

try {
  for await (const message of query({
    prompt: "Analyze the auth module and suggest improvements",
    options: { allowedTools: ["Read", "Glob", "Grep"] }
  })) {
    if (message.type === "result") {
      sessionId = message.session_id;
      if (message.subtype === "success") console.log(message.result);
    }
  }
} catch (error) {
  // 1回きりの query() はエラー結果を返したあとに例外を投げる
  console.error(`Session ended with an error: ${error}`);
}

1回きりの query() はエラー結果を出したあとに例外を投げるため、公式の例は try で囲んでいます。エラー結果なら ID はループの中で取れていますが、接続やプロセスの失敗では結果メッセージ自体が来ないので ID は空のままです。

ID を指定して再開する

控えた ID を resume に渡すと、そのセッションの続きから動きます(Python は ClaudeAgentOptions(resume=session_id, ...))。

for await (const message of query({
  prompt: "Now implement the refactoring you suggested",
  options: {
    resume: sessionId,
    allowedTools: ["Read", "Edit", "Write", "Glob", "Grep"]
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}

公式が挙げる再開の場面は次の3つです。

セッションファイルの保存場所

セッションは ~/.claude/projects/<encoded-cwd>/*.jsonl に保存されます。環境変数 CLAUDE_CONFIG_DIR を設定している場合は $CLAUDE_CONFIG_DIR/projects/ の下です。<encoded-cwd> は作業ディレクトリの絶対パスの英数字以外をすべて - に置き換えたもので、/Users/me/proj なら -Users-me-proj になります(変換後が200文字を超える場合は切り詰めてハッシュが付きます)。

再開はどの作業ディレクトリからでもでき、Claude Code は現在のプロジェクトのディレクトリ以外も探して ID を見つけます。ただしセッションファイルが同じマシンにあることが条件です。v2.1.223 より前は現在のプロジェクトと git worktree の範囲しか探さず、古い CLI を同梱した SDK では今もその挙動です。

fork で別の方向を試す

fork は、元の履歴をコピーした新しいセッションを作り、そこから分岐させます。fork 側には新しいセッション ID が付き、元のセッションの ID と履歴は変わりません。結果として、別々に再開できる2つのセッションが手に入ります。指定は resume と組み合わせて、TypeScript は forkSession: true、Python は fork_session=True です。

// JWT で進めていたセッションから分岐して OAuth2 の案を出させる
let forkedId: string | undefined;

for await (const message of query({
  prompt: "Instead of JWT, outline how OAuth2 would work for the auth module",
  options: {
    resume: sessionId,
    forkSession: true,
    maxTurns: 5
  }
})) {
  if (message.type === "system" && message.subtype === "init") {
    forkedId = message.session_id; // 元の sessionId とは別の ID
  }
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}

// 元のセッションはそのまま。resume すれば JWT の流れを続けられる
for await (const message of query({
  prompt: "Continue with the JWT approach",
  options: { resume: sessionId }
})) { /* ... */ }

forkedId が元の ID と異なり、元のセッションを再開すると JWT の流れがそのまま続くことで、fork が元の履歴を変えていないことを確かめられます。

fork が分岐させるのも会話履歴だけです。fork した側のエージェントがファイルを編集すれば、その変更は実際にディスクに書かれ、同じディレクトリで動く他のセッションからも見えます。ファイル変更も分岐・巻き戻ししたい場合はファイルチェックポイントを併用します。

別ホストでの再開とセッション一覧

セッションファイルは作成したマシンのローカルにあります。CI のワーカーや使い捨てのコンテナ、サーバーレス環境など別のホストで再開したい場合、公式は次の3つの方法を示しています。

方法内容
セッションストアを渡すsessionStore / session_store アダプターを指定し、記録を自前のバックエンドへ複製する。検索キーは作業ディレクトリから作られるので、元の実行と同じ cwd で再開する
セッションファイルを移す最初の実行の ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl を保存し、新しいホストの ~/.claude/projects/ 配下に置いてから resume を呼ぶ
再開に頼らない分析結果・判断・差分など必要なものをアプリの状態として保存し、新しいセッションのプロンプトに渡す。記録ファイルを持ち回るより堅牢なことが多い

ディスク上のセッションを扱う関数も両 SDK にあります。

用途TypeScriptPython
セッションの一覧listSessions()list_sessions()
メッセージの読み出しgetSessionMessages()get_session_messages()
1件の情報取得getSessionInfo()get_session_info()
名前の変更renameSession()rename_session()
タグ付けtagSession()tag_session()

TypeScript の listSessions() は dir・limit・includeWorktrees を受け取り、sessionId・summary・lastModified などを持つ一覧を返します。dir を省略すると全プロジェクトが対象です。これらを使えば、独自のセッション選択画面や古いセッションの整理、記録の閲覧ツールを作れます。

TypeScript の Options には、ほかに特定のメッセージ UUID の時点から再開する resumeSessionAt や、自動生成の代わりに任意の UUID をセッション ID に使う sessionId もあります。

本ページは Work with sessions の内容に基づく非公式の日本語解説で、オプション名と関数名は Agent SDK reference - TypeScript と照合しています(確認日 2026-10-15)。オプション名・フィールド名は公式表記のまま記載しています。最新の仕様は公式ドキュメントを確認してください。