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)
- 2026-05-130.2.141を公開
0.2系の最後のリリースです。
npm install @anthropic-ai/claude-agent-sdk@0.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
使用箇所を洗い出す
grep -rn "unstable_v2_\|SDKSession" src/のように、接頭辞と型名で検索します。0.3.142以降には存在しない識別子なので、ヒットした箇所はすべて移行対象です。 - 2
呼び出しを対応表どおりに置き換える
単発は
resultの判定、会話はpromptのジェネレータ、再開はoptions.resumeへ置き換えます。 - 3
セッションIDの保存先を決める
オブジェクトを持ち回る設計をやめ、IDの文字列だけを保存する設計に変えます。
- 4
終了処理を書き換える
await usingやsession.close()の代わりに、打ち切りたい箇所でq.close()を呼びます。V1の例はawait usingを使いません。 - 5
分岐の多い入力ジェネレータを動かして確かめる
V2のページが「一部の高度なストリーミング入力パターン」としか書いていないため、複雑な分岐を持つコードは移行後の動作を個別に確かめます。
セッションの実体はどこにあるか
V2
SDKSessionがセッションの実体で、sessionIdはその属性でした。会話を続けるには、このオブジェクトを手元に持ち続けます。
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で持つ設計への切り替えと、ジェネレータ内の分岐の動作確認に出ます。
関連する記事
Agent SDK をもっと見る →Claude Agent SDK入門 — Python / TypeScriptで最小エージェントを組む
Claude Agent SDKとMastraの違い — 完成したエージェントを借りるか、部品から組むか
Claude Agent SDKとLangGraphの違い — ループを任せるか、遷移を描くか
Claude Agent SDKの違いをOpenAI Agents SDKと比較 — 委譲・ツール・セッション
Claude Agent SDKがLinuxでmusl版バイナリを優先するバグの原因と対処
ClaudeCodeOptionsのcwdが反映されない理由と回避策 — Python Agent SDK