Claude Media
TypeScript Agent SDK V2廃止の理由と移行先

TypeScript Agent SDK V2廃止の理由と移行先

TypeScript Agent SDK 0.3.142でV2セッションAPIが廃止されました。何ができなくなったのか、query()への書き換え方を実装コードで示します。

V2を使うコードは0.3.142以降でどうなるか

TypeScript Agent SDK 0.3.142は、unstable_v2_createSession・unstable_v2_resumeSession・unstable_v2_promptの3関数と、SDKSession・SDKSessionOptionsの2つの型を削除しました。V2のimportが残ったまま0.3.142以降へ上げると、importが解決できなくなります。

あゆみ

V2が消えた境目(npmレジストリの公開日、UTC)

  1. 2026-05-130.2.141を公開

    0.2系の最後のリリースです。npm install @anthropic-ai/claude-agent-sdk@0.2はこの版に解決されます。

  2. 2026-05-140.3.142を公開

    V2のAPIと型が消えた最初のリリースです。0.3.0〜0.3.141は存在せず、0.2.141から直接0.3.142へ進みました。

0.2.xは118回のリリースを重ねた系列で、V2のインターフェースを含む最後のバージョンです。V2を使い続けるには、この系列へ固定します。

番号が飛んだ理由は、SDKのバージョンが同梱するClaude Codeに揃えてあるためと考えられます。TypeScript SDKリファレンスでは、SDK v0.3.191はClaude Code v2.1.191を同梱し、パッチ番号が対応します。

npmの範囲指定にも注意が要ります。0.x系のキャレット指定は左端の非ゼロ桁を固定するため、^0.2.141は0.3.xを含みません。0.2系を範囲指定していたプロジェクトは、手で書き換えるまで0.3.142に上がらず、V2も残ります。

V2が解こうとしていた問題

V2は、非同期ジェネレータとyieldの手動調整を不要にする実験的なセッションAPIでした。Agent SDK入門で扱うV1のquery()は、1本の非同期ジェネレータで入出力の両方を担います。V2はsession.send()で送り、session.stream()で受け取る、ターンごとのサイクルに分けました。

V1でマルチターンを組むには、会話全体を1つのジェネレータ関数として先に書き、その中で何度もyieldします。次のメッセージが外部の入力や前の応答に左右されるなら、ジェネレータの中でawaitしながらyieldの間合いを自分で測らなければなりません。V2はこの調整を2つの独立した呼び出しに分け、好きなタイミングで送れるようにしていました。

V2の概念役割V1での対応
unstable_v2_createSession()役割セッションを開始V1での対応query()(初回呼び出し)
unstable_v2_resumeSession(id, opts)役割保存済みセッションを継続V1での対応query({ options: { resume: id } })
unstable_v2_prompt(text, opts)役割単発プロンプトの簡易実行V1での対応query()とresultサブタイプの判定
session.send(msg)役割メッセージを送信V1での対応入力ジェネレータのyield
session.stream()役割応答を受信V1での対応query()のfor awaitループ
session.close() / await using役割セッションを終了V1での対応query()が返すオブジェクトのclose()
forkSessionオプション役割元のセッションを分岐V1での対応V1のみ

なぜV2は廃止されたのか

V2ページの冒頭警告は、削除したバージョンと移行先を示すだけで、理由には触れていません。理由を読み取れる材料は、V2自身の記述に残っています。

第一に、関数名が最後までunstable_接頭辞のままでした。安定版に昇格しないまま削除されたことになります。

第二に、V2のページは「Feature availability」の節で、V1にあってV2にない機能を自ら挙げています。セッションフォーク(forkSessionオプション)と、一部の高度なストリーミング入力パターンです。フォークは、元のセッションを壊さず別の方針を試すための機能で、SDK overviewのSessions行にも「resume or fork」と書かれています。この主要機能を欠いたままでは、安定版へ進める段階になかったと考えられます。

移行先として示されたのはV1のquery()です。AsyncIterable<SDKUserMessage>を渡せば複数ターンを組め、options.resumeで保存済みセッションへ戻れます。V2ページ自体も、冒頭の警告は「0.2.x以前のコードを保守する人向けに残している」と書き添えています。

V1のquery()への書き直し

V2の使い方は、単発・単一セッション・マルチターン・再開の4つで、どれもV1のquery()に対応します。

単発プロンプト

V2のunstable_v2_prompt()は、V1ではquery()を呼び、resultサブタイプのメッセージだけを拾う形になります。

// V2(廃止)
import { unstable_v2_prompt } from "@anthropic-ai/claude-agent-sdk";
 
const result = await unstable_v2_prompt("What is 2 + 2?", {
  model: "claude-opus-4-7"
});
if (result.subtype === "success") {
  console.log(result.result);
}
// V1(移行先)
import { query } from "@anthropic-ai/claude-agent-sdk";
 
const q = query({
  prompt: "What is 2 + 2?",
  options: { model: "claude-opus-4-7" }
});
 
for await (const msg of q) {
  if (msg.type === "result" && msg.subtype === "success") {
    console.log(msg.result);
  }
}

単一セッションでの応答受信

V2のcreateSession()とsend()・stream()は、V1ではquery()に文字列を渡す1本のループになります。

// V1
import { query } from "@anthropic-ai/claude-agent-sdk";
 
const q = query({
  prompt: "Hello!",
  options: { model: "claude-opus-4-7" }
});
 
for await (const msg of q) {
  if (msg.type === "assistant") {
    const text = msg.message.content
      .filter((block) => block.type === "text")
      .map((block) => block.text)
      .join("");
    console.log(text);
  }
}

マルチターンの会話

V2はsession.send()を呼ぶたびに新しいターンを送れました。V1では入力そのものを非同期イテラブルにしてpromptへ渡します。

import { query } from "@anthropic-ai/claude-agent-sdk";
 
async function* createInputStream() {
  yield {
    type: "user",
    session_id: "",
    message: { role: "user", content: [{ type: "text", text: "What is 5 + 3?" }] },
    parent_tool_use_id: null
  };
  yield {
    type: "user",
    session_id: "",
    message: { role: "user", content: [{ type: "text", text: "Multiply by 2" }] },
    parent_tool_use_id: null
  };
}
 
const q = query({
  prompt: createInputStream(),
  options: { model: "claude-opus-4-7" }
});
 
for await (const msg of q) {
  if (msg.type === "assistant") {
    const text = msg.message.content
      .filter((block) => block.type === "text")
      .map((block) => block.text)
      .join("");
    console.log(text);
  }
}

セッションの再開

V2のresumeSession(sessionId, options)は、V1ではquery()のoptions.resumeにセッションIDを渡す形です。

// V1
const resumedQuery = query({
  prompt: "What number did I ask you to remember?",
  options: {
    model: "claude-opus-4-7",
    resume: sessionId
  }
});
 
for await (const msg of resumedQuery) {
  if (msg.type === "assistant") {
    const text = msg.message.content
      .filter((block) => block.type === "text")
      .map((block) => block.text)
      .join("");
    console.log(text);
  }
}

セッションが1つだけの用途なら、IDを持ち回らない手もあります。continue: trueを渡すと、そのディレクトリで直近のセッションを引き継ぎます。IDを保存して選ぶresume、元を残して分岐するforkSessionとの使い分けは、Agent SDKのセッション管理にまとめています。

セッションの中身はディスク上のファイルです。Claude Codeは~/.claude/projects/<作業ディレクトリ名>/*.jsonlに保存し、CLAUDE_CONFIG_DIRを設定していればその下のprojects/を使います。resumeは別の作業ディレクトリからでも効きますが、ファイルが今のマシンに存在することが条件です。マシンをまたぐ場合は、SessionStoreアダプターで共有ストレージへ写します。

ターンの間に処理を挟みたいとき

V2の売りは、send()とstream()の間に自由にロジックを置けることでした。V1で同じことをするには、ジェネレータの中で外部からの入力を待たせます。

import { query, type SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
 
const inbox: string[] = [];
let wake: (() => void) | undefined;
 
export function push(text: string) {
  inbox.push(text);
  wake?.();
}
 
async function* turns(): AsyncGenerator<SDKUserMessage> {
  while (true) {
    while (inbox.length === 0) {
      await new Promise<void>((resolve) => (wake = resolve));
    }
    yield {
      type: "user",
      message: { role: "user", content: inbox.shift()! },
      parent_tool_use_id: null
    };
  }
}
 
const q = query({ prompt: turns(), options: { model: "claude-opus-4-7" } });
// 応答は for await (const msg of q) で読み、終えるときは q.close() を呼ぶ

push()を呼んだ分だけ新しいターンが送られます。q.close()は問い合わせを閉じ、下のプロセスも終了させます。

文字列のpromptでは使えない操作がある点にも注意が要ります。interrupt()、setModel()、setPermissionMode()、applyFlagSettings()は、リファレンスで「streaming input modeでのみ利用可能」とされています。V2のSDKSessionが持つのはsessionId・send()・stream()・close()だけで、interrupt()やsetModel()はありません。割り込みやモデル切り替えが必要なコードは、V1では上のようにAsyncIterableを渡す形にします。

SDKUserMessageにはpriority("now"・"next"・"later")というフィールドもあります。実行中のターンに送ったメッセージをいつ読ませるかの指定で、nowは割り込み、laterはターン終了後、next(既定)は実行中のツールが終わった時点です。

移行の順序と、状態の持ち方の違い

手順

V2からV1へ移す順序

  1. 1

    使用箇所を洗い出す

    grep -rn "unstable_v2_\|SDKSession" src/のように、接頭辞と型名で検索します。0.3.142以降には存在しない識別子なので、ヒットした箇所はすべて移行対象です。

  2. 2

    呼び出しを対応表どおりに置き換える

    単発はresultの判定、会話はpromptのジェネレータ、再開はoptions.resumeへ置き換えます。

  3. 3

    セッションIDの保存先を決める

    オブジェクトを持ち回る設計をやめ、IDの文字列だけを保存する設計に変えます。

  4. 4

    終了処理を書き換える

    await usingやsession.close()の代わりに、打ち切りたい箇所でq.close()を呼びます。V1の例はawait usingを使いません。

  5. 5

    分岐の多い入力ジェネレータを動かして確かめる

    V2のページが「一部の高度なストリーミング入力パターン」としか書いていないため、複雑な分岐を持つコードは移行後の動作を個別に確かめます。

くらべる

セッションの実体はどこにあるか

オブジェクト

V2

SDKSessionがセッションの実体で、sessionIdはその属性でした。会話を続けるには、このオブジェクトを手元に持ち続けます。

ID文字列

V1

クライアント側にセッションを表すオブジェクトはありません。IDは各メッセージのsession_idに入っており、結果メッセージには必ず含まれます。次のquery()のoptions.resumeへ渡すだけで会話が続きます。

ID文字列だけで引き継げるため、リクエストごとにプロセスが替わるWebアプリでも、同じマシンの上なら扱えます。TypeScriptではIDがinitのSystemMessageにも直接入っているので、最初のターンの途中で読み出して保存できます。

V2の3関数は、optionsにmodel以外の追加オプションも受け付けるとされていましたが、型の詳細は公開されていませんでした。V1のquery()はOptions型ですべてのオプションが定義されています。V2で暗黙に渡していた設定は、Optionsの型で名前を引き直します。

0.2.x系に留まる場合の制約

SDKは同梱するClaude Codeと版が連動するので、0.2.141より後に増えたオプションや機能は、0.2系では使えません。リファレンスに載っている例を挙げます。

機能必要な版
updateSettings()(設定ファイルへ永続化)必要な版SDK 0.3.257以降
permissionPromptsオプション必要な版Claude Code v2.1.259以降
verbatimPromptsオプション必要な版SDK 0.3.280以降、Claude Code v2.1.248以降

セッションの再開にも差が出ます。v2.1.223より前のClaude Codeは、IDの探索を現在のプロジェクトディレクトリとそのgit worktreeに限っていました。古いCLIを同梱するSDKは今もこの挙動です。

セッションAPIだけを理由に固定する前に、こうした機能が必要になっていないか見直します。0.2.x系のコードを保守する間は、V2が最後まで公開していたSDKSessionの定義が参照になります。

interface SDKSession {
  readonly sessionId: string;
  send(message: string | SDKUserMessage): Promise<void>;
  stream(): AsyncGenerator<SDKMessage, void>;
  close(): void;
}

よくある質問

Python版のAgent SDKにも同じ廃止の影響があるか

V2のページが扱うのはTypeScript Agent SDKのAPIです。Pythonでは、ClaudeSDKClientが同一クライアントの呼び出し間で会話を自動的に引き継ぎます。query()で続ける場合はcontinue_conversationかresumeを指定します。Python側のコードは今回の削除で書き換える必要がありません。

まとめ

V2はunstable_接頭辞のまま、フォークを欠いた状態で削除されました。0.3.142以降はquery()とAsyncIterable<SDKUserMessage>・options.resumeへ移すか、0.2系に固定するかの二択で、固定する場合は新しい機能を受け取れなくなります。移行の手間はコードの置き換えより、セッションをIDで持つ設計への切り替えと、ジェネレータ内の分岐の動作確認に出ます。

この記事を共有:XはてブLinkedIn