Cursor Python SDK
cursor-sdkパッケージを使用すると、自分のPythonコードからCursorのエージェントを呼び出せます。Cursor IDE、CLI、Webアプリで動作するものと同じエージェントを、同期・非同期クライアント、型付きdataclass、ストリームやページを通常のイテレーションで扱う機能を通じて、Pythonからスクリプトで利用できます。はじめるには、Cursor内で/sdkスキルを実行します。
REST APIについては、Cloud Agents APIを参照してください。その他の言語については、SDK Bridgeを参照してください。
概要
SDK は、ローカルとクラウドの実行時を単一のインターフェースで扱えます。エージェントの実行場所にかかわらず、同じコードを記述できます。
| 実行時 | 概要 | 使用場面 |
|---|---|---|
| ローカル | ディスク上のローカルファイルに対してエージェントを実行します。 | ワーキングツリーに対する開発スクリプトや CI チェック。 |
| クラウド (Cursor ホスト) | リポジトリをクローンした隔離された VM 上で実行します。VM は Cursor が管理します。 | 呼び出し元にリポジトリがない場合、多数のエージェントを並行して実行したい場合、または呼び出し元が切断されても実行を継続する必要がある場合。 |
Agent.create() に local または cloud を渡して実行時を設定します。
認証
エージェントを作成する前に、CURSOR_API_KEY を設定するか、api_key を渡します。
SDK は、ローカル実行とクラウド実行の両方で、ユーザー API キーとサービスアカウント API キーを使用できます。Team Admin API キーはまだサポートされていません。
- Cursor Dashboard -> API Keys から取得するユーザー API キー
- Team settings から取得するサービスアカウント API キー。サービスアカウントを参照してください
export CURSOR_API_KEY="your-key"利用状況と請求
SDK の実行には、IDE や Cloud Agents での実行と同じ料金体系、リクエストプール、プライバシーモードのルールが適用されます。利用料金は、チームの利用ダッシュボードの SDK タグに表示されます。
コード内で実行ごとのトークン数を確認するには、トークン利用を参照してください。エージェントの実行に対する請求対象の利用量とドル建てコストを取得するには、agent.get_usage()を参照してください。
コアコンセプト
| コンセプト | 説明 |
|---|---|
| エージェント | 会話の状態、ワークスペース設定、モデル選択、各種設定を保持する永続的なハンドル。複数のプロンプトにまたがって存続します。 |
| Run | 1 回のプロンプト送信。独自のストリーム、ステータス、結果、会話、キャンセルを持ちます。 |
| SDKMessage | Run 中に生成される型付きストリームメッセージ。ローカルとクラウドの実行時で同じ形式です。 |
| CursorClient | ライフサイクルの制御、カスタム HTTP オプションの指定、または 1 つのプロセス内で複数のワークスペースを使用するための明示的なクライアント。Client はそのエイリアスです。 |
| AsyncClient | 非同期用の対応クライアント。すべての非同期操作に必要です。 |
インストール
pip install cursor-sdkPython 3.10 以降が必要です。
クイックスタート
import osfrom cursor_sdk import Agent, LocalAgentOptionswith Agent.create( model="composer-2.5", api_key="crsr_key", local=LocalAgentOptions(cwd=os.getcwd()),) as agent: print(agent.send("Summarize what this repository does").text())ストリームイベントでは、アシスタントのテキストを抽出し、ツール呼び出しを処理して、実行状態を確認する方法を説明します。ワンショットプロンプト (作成、実行、完了) については、Agent.prompt()を参照してください。
Cloud クイックスタート
Python SDK は、Cursor の Cloud Agent を標準でサポートしています。接続されているリポジトリを一覧表示し、そのいずれかでエージェントを起動して、実行の完了を待ち、最終結果を確認できます。
from cursor_sdk import Agent, CloudAgentOptions, CloudRepositorywith Agent.create( model="composer-2.5", api_key="crsr_key", cloud=CloudAgentOptions( repos=[CloudRepository(url="https://github.com/your-org/your-repo", starting_ref="main")], auto_create_pr=True, ),) as agent: print(agent.send("Add structured logging to the auth middleware").text())SDK で開始した Cloud Agent は、デフォルトのエージェントリストには表示されません。Cursor Web または Cursor エージェントウィンドウで表示するには、フィルター > ソース > SDK をクリックします。
非同期での利用
非同期クライアントは同期版と同等の機能を備えており、サーバー、ボット、エージェントの並行オーケストレーションでの利用を推奨します。AsyncAgent、AsyncClient、AsyncRun、AsyncCursor は、cursor_sdk と cursor_sdk.asyncio の両方からエクスポートされます。
import asyncioimport osfrom cursor_sdk import AsyncClient, LocalAgentOptionsasync def main(): async with await AsyncClient.launch_bridge(workspace=os.getcwd()) as client: async with await client.agents.create( model="composer-2.5", api_key="crsr_key", local=LocalAgentOptions(cwd=os.getcwd()), ) as agent: run = await agent.send("Summarize what this repository does") print(await run.text())asyncio.run(main())グローバルな非同期デフォルトクライアントはありません。AsyncClient を明示的にインスタンス化するか、AsyncClient.launch_bridge(...) を非同期コンテキストマネージャとして使用し、各イベントループがそれぞれ独自のクライアントを持つようにしてください。同じコードパス内で同期クライアントと非同期クライアントを混在させないでください。
直接呼び出す AsyncAgent クラスメソッドでは、client= が必要です。await client.agents.create(...) または
await AsyncAgent.create(..., client=client) を使用してください。
| 同期 | 非同期 |
|---|---|
CursorClient / Client | AsyncClient / AsyncCursorClient |
Agent | AsyncAgent |
Run | AsyncRun |
Cursor | AsyncCursor |
ListResult | AsyncListResult |
DefaultHttpxClient | DefaultAsyncHttpxClient |
エージェントの作成
Agent.create() はオプションを検証し、すぐにハンドルを返します。実行時を選択するには、local または cloud を指定します。
from cursor_sdk import Agent, CloudAgentOptions, CloudRepository, LocalAgentOptionsagent = Agent.create( model="composer-2.5", local=LocalAgentOptions(cwd="."),)cloud_agent = Agent.create( model="composer-2.5", cloud=CloudAgentOptions( repos=[CloudRepository(url="https://github.com/your-org/your-repo", starting_ref="main")], auto_create_pr=True, ),)agent.agent_id は即座に設定されます。ローカルエージェントには agent-<uuid> ID、Cloud Agent には bc-<uuid> ID が割り当てられます。agent.model は型付きの ModelSelection であるため、agent.model.id と agent.model.params をそのまま使用できます。
SDK で開始された Cloud Agent は、デフォルトのエージェントリストには表示されません。 Cursor Web または Cursor エージェントウィンドウで表示するには、Filter > Source > SDK をクリックします。
リポジトリなしのCloud Agent
Cloud Agent は、リポジトリがない空の VM で実行できます。空の repos リストを指定して cloud を渡すか、repos を省略します。cloud を省略すると、ローカル実行時が選択されます。
from cursor_sdk import Agent, CloudAgentOptionswith Agent.create(cloud=CloudAgentOptions(repos=[])) as agent: run = agent.send("Research the top 3 Python testing frameworks and summarize.") print(run.wait().result)リポジトリなしエージェントを作成するには、アカウントまたはチームで有効にする必要があります。リポジトリスコープの API キーでは作成できないため、代わりに制限なしのサービスアカウントキーまたはユーザー API キーを使用してください。
セッション環境変数
Cloud Agent で短期間のみ有効な認証情報や、そのエージェント内でのみ使用する値が必要な場合は、実行時に env_vars を渡します。
import osagent = Agent.create( model="composer-2.5", cloud=CloudAgentOptions( repos=[CloudRepository(url="https://github.com/your-org/your-repo")], env_vars={ "STAGING_API_TOKEN": os.environ["STAGING_API_TOKEN"], }, ),)これらの値は保存時に暗号化され、Cloud Agent のシェルに注入され、エージェントの削除時に削除されます。env_vars は、呼び出し元が指定した agent_id とは併用できません。agent_id は省略し、サーバーが発行した ID を agent.agent_id から取得してください。変数名を CURSOR_ で始めることはできません。
1 回の実行中にのみ存在させる値は、代わりに agent.send() に渡してください。実行ごとの環境変数を参照してください。
エージェント メタデータ
Cloud Agent の作成時に、独自の識別子を付与できます。メタデータを使用すると、エージェントをシステム内のユーザー、テナント、ワークフロー、またはチケットに関連付けられます。メタデータは client.agents.get() および client.agents.list() で取得した SDKAgentInfo.metadata から読み取れます。これらのタグは、VM 内から現在の実行の ID、所有者、ターン、ワークスペースを公開する、VM 内のエージェント メタデータ API とは異なります。
from cursor_sdk import Agent, CloudAgentOptions, CloudRepositorywith Agent.create( model="composer-2.5", cloud=CloudAgentOptions( repos=[CloudRepository(url="https://github.com/your-org/your-repo")], metadata={ "end_user_id": "user-123", "ticket_id": "ENG-456", }, ),) as agent: print(agent.agent_id)Cloud Agent では、作成時にメタデータを指定できます。最大 50 個のキーと値のペアを追加できます。キーは空にできず、255 文字以下である必要があります。値は 4096 バイト以下の文字列である必要があります。空文字列の値も使用でき、空のマッピングはメタデータなしとして扱われます。
API キーに紐づくアカウントでメタデータが有効になっていない場合、空でないマップを指定してエージェントを作成すると
403 feature_unavailable が返されます。
モデルパラメータ
ModelSelection.params を使用して、推論の深さや Cursor Router の optimize_for など、モデル固有のオプションを指定します。パラメータ ID と値はモデルによって異なります。Cursor.models.list() を使用して、アカウントで利用可能なパラメータとプリセットバリアントを確認してください。
from cursor_sdk import Agent, LocalAgentOptions, ModelParameterValue, ModelSelectionagent = Agent.create( model=ModelSelection( id="composer-2.5", params=[ModelParameterValue(id="fast", value="true")], ), local=LocalAgentOptions(cwd="."),)特定のモデルのパラメータ ID とプリセットバリアントを確認するには、Cursor.models.list() を使用します。auto-smart の選択コントラクトについては、Cursor Router を参照してください。
Cursor Router
Cursor Router は、Auto リクエストごとにモデルを選択します。SDK では、Router は optimize_for パラメータを持つ auto-smart モデルです。Teams とエンタープライズで利用できます。auto-smart をカタログに表示するには、エンタープライズ管理者が事前にチームで Router を有効にする必要があります。
Cursor SDK はエージェント SDK であり、スタンドアロンのモデル推論 API やチャット補完 API ではありません。Router は、ワークスペースを理解し、ツールを呼び出し、コマンドを実行し、ファイルを編集できる Cursor エージェント実行用のモデルを選択します。Cursor は現在、任意のモデル呼び出しに使用できる生の Router エンドポイントを公開していません。
Cost、Balance、またはIntelligenceを選択
auto-smartを渡し、optimize_forを明示的に指定します。
| プロダクトラベル | SDK値 |
|---|---|
| Cost | cost |
| Balance | balanced |
| Intelligence | intelligence |
プロダクト内の文言ではBalanceを使用します。balancedはSDKのワイヤー値としてのみ使用します。
import osfrom cursor_sdk import Agent, LocalAgentOptions, ModelParameterValue, ModelSelectionwith Agent.create( model=ModelSelection( id="auto-smart", params=[ModelParameterValue(id="optimize_for", value="balanced")], ), local=LocalAgentOptions(cwd=os.getcwd()),) as agent: run = agent.send("Find and fix the failing authentication test") result = run.wait() print(result.status)必ず optimize_for を指定してください。省略したり、レガシーな default 値を送信したりしないでください。カタログ経由の検出がサポートされているコントラクトです。
モデルカタログでRouterを確認する
Cursor.models.list() は、API keyの現在のaccountとチームで利用可能なモデル、パラメータ定義、preset variantsを返します。Routerが利用可能な場合、Cursor Routerは auto-smart として表示されます。チーム管理者はRouterを無効にしたり、メンバーが選択できるoptimization modesを制限したりできます。
選択をハードコーディングする前に、カタログを信頼できる唯一の情報源として扱ってください。
from cursor_sdk import Cursor, ModelParameterValue, ModelSelectionmodels = Cursor.models.list()router = next((model for model in models if model.id == "auto-smart"), None)optimize_for = next( ( parameter for parameter in (router.parameters if router else []) if parameter.id == "optimize_for" ), None,)if router is None or optimize_for is None: raise RuntimeError( "Cursor Router is not available for this API key. " "Verify that Router is enabled for the key's team." )requested_mode = "balanced"allowed_values = {entry.value for entry in optimize_for.values}if requested_mode not in allowed_values: raise RuntimeError( f'Router mode "{requested_mode}" is not enabled for this team.' )model = ModelSelection( id=router.id, params=[ModelParameterValue(id=optimize_for.id, value=requested_mode)],)実行ごとにモードを切り替える
agent.send() でモデルを指定して、実行ごとのルーターモードを変更できます。
from cursor_sdk import ModelParameterValue, ModelSelection, SendOptionsrun = agent.send( "Handle this complex migration", SendOptions( model=ModelSelection( id="auto-smart", params=[ModelParameterValue(id="optimize_for", value="intelligence")], ), ),)実行ごとのモデル上書きは、その後も維持されます。以降の送信で上書きを指定しない場合も、新しく選択したモデルが引き続き使用されます。実行ごとのモデル上書きを参照してください。
モデル ID: auto-smart、auto、default
| 選択 | 意味 |
|---|---|
optimize_for を指定した auto-smart | Cursor Router。Cost、Balance、またはIntelligenceを使用する場合に選択します。 |
ModelSelection(id="auto") | 特定のモデルがカタログにない場合、サーバーが選択するAutoフォールバックです。明示的にルーターモードを指定する必要がある場合は、auto-smart を使用してください。 |
optimize_for の省略、または default の送信 | サポートされているルーターコントラクトではありません。許可されている値を必ず検出し、cost、balanced、または intelligence を渡してください。 |
請求とルーティングプール
- すべての Auto モードでは、各リクエストのルーティング先モデルの定価で請求されます。
- 基盤モデルはリクエストごとに変わる場合があります。再現性のある比較が必要な場合は、固定のモデル ID を使用してください。
- エンタープライズのモデル許可リストによってルーティングプールが決まります。必須モデルをブロックすると、Router が無効になる場合があります。
現在の料金とルーティングプールについては、Cursor Router と Auto モード を参照してください。
Router が表示されない場合のトラブルシューティング
auto-smart が表示されない、または最適化モードが拒否される場合:
Cursor.models.list()を呼び出します。- 結果に
auto-smartが含まれていることを確認します。 optimize_forに目的の値 (cost、balanced、またはintelligence) が含まれていることを確認します。- API キーに紐づくチームで Router が有効になっていることを確認します。
- 複数のチームに所属している場合は、キーが意図したチームコンテキストで使用されていることを確認します。
- Router を利用できない、または有効な基盤モデルを選択できない場合は、チームのモデルアクセス ポリシーを確認します。
生の辞書
IDE の自動補完や型チェックがより適切に機能するため、アプリケーションコードでは型付きデータクラスの使用を推奨します。SDK では、短いスクリプトや外部から提供される JSON に対して、通常の辞書も使用できます。スネークケースのキーは正規化されます。
from cursor_sdk import Agentwith Agent.create( { "api_key": "crsr_key", "model": {"id": "composer-2.5"}, "local": {"cwd": "."}, }) as agent: ...エージェント
Agent.create()、Agent.resume()、client.agents.create()、client.agents.resume() が返すハンドル。
class Agent: agent_id: str model: ModelSelection | None client: CursorClient def send( self, message: str | Mapping[str, Any] | UserMessage, options: SendOptions | Mapping[str, Any] | None = None, *, idempotency_key: str | None = None, ) -> Run: ... def reload(self) -> None: ... def close(self) -> None: ... def list_messages( self, options: Mapping[str, Any] | None = None ) -> list[AgentMessage]: ... def list_artifacts(self) -> list[SDKArtifact]: ... def download_artifact(self, path: str) -> bytes: ... def get_usage(self, *, run_id: str | None = None) -> AgentUsage: ... def archive(self, options: Mapping[str, Any] | None = None) -> None: ... def unarchive(self, options: Mapping[str, Any] | None = None) -> None: ... def delete(self, options: Mapping[str, Any] | None = None) -> None: ...| メンバー | 説明 |
|---|---|
agent_id | 安定したエージェント識別子。ローカルでは agent-<uuid>、クラウドでは bc-<uuid>。 |
model | 現在の型付きモデル選択。モデルの上書きを指定した送信が成功すると更新されます。 |
send | 指定したプロンプトで新しい実行を開始します。Run ハンドルを返します。 |
reload | 破棄せずにファイルシステム設定 (フック、プロジェクト MCP、サブエージェント) を再読み込みします。 |
close | エージェントを閉じ、リソースを解放します。 |
list_messages | エージェントのメッセージ履歴を一覧表示します。 |
list_artifacts | エージェントが生成したファイルを一覧表示します (クラウドのみ。ローカルでは空のリストを返します) 。 |
download_artifact | パスでファイルをダウンロードします (クラウドのみ。ローカルでは例外が発生します) 。 |
get_usage | エージェントの課金対象トークン利用量と米ドル費用を取得します。 |
archive / unarchive / delete | Cloud Agent のライフサイクルを管理します。 |
コンテキストマネージャーを使用すると、自動的にクリーンアップされます。
with Agent.create(model="composer-2.5", local=LocalAgentOptions(cwd=".")) as agent: print(agent.send("Explain this repository").text())client= を指定せずに同期 Agent.* または Cursor.* ヘルパーを使用すると、SDK はモジュールレベルのデフォルトクライアントを起動または再利用します。このクライアントはプロセス終了時に自動的に閉じられますが、明示的に閉じることもできます。
from cursor_sdk import close_default_clientclose_default_client()Agent.prompt()
Agent.prompt( message: str | Mapping[str, Any] | UserMessage, options: AgentOptions | Mapping[str, Any] | None = None, *, client: CursorClient | None = None,) -> RunResultワンショットの便利なメソッド: エージェントを作成し、1つのプロンプトを送信して、実行が完了するのを待ち、破棄します。
from cursor_sdk import Agent, AgentOptions, LocalAgentOptionsresult = Agent.prompt( "What does the auth middleware do?", AgentOptions(model="composer-2.5", local=LocalAgentOptions(cwd=".")),)print(result.result)非同期版 (AsyncClient がすでに開いていることを前提としています) :
from cursor_sdk import AgentOptions, AsyncAgent, LocalAgentOptionsresult = await AsyncAgent.prompt( "What does the auth middleware do?", AgentOptions(model="composer-2.5", local=LocalAgentOptions(cwd=".")), client=client,)CursorClient
ライフサイクルを明示的に制御する場合、カスタムのブリッジのエンドポイントや HTTP オプションを使用する場合、または 1 つのプロセスで複数のワークスペースを扱う場合は、CursorClient を使用します。Client も引き続きエイリアスとして利用できます。
from cursor_sdk import CursorClient, LocalAgentOptionswith CursorClient.launch_bridge(workspace=".") as client: with client.agents.create( model="composer-2.5", api_key="crsr_key", local=LocalAgentOptions(cwd="."), ) as agent: print(agent.send("Summarize what this repository does").text())プラットフォーム上ですでに cursor-sdk-bridge が動作している場合は、別のインスタンスを起動せずに CursorClient.connect(base_url, auth_token) でアタッチしてください。client.ping() と client.get_version() はブリッジの稼働状況とバージョンを返します。AsyncClient.connect(...) は sync 版と同じ形式です。
from cursor_sdk import CursorClientwith CursorClient.connect("http://127.0.0.1:43210", auth_token=bridge_token) as client: print(client.ping(), client.get_version()["bridgeVersion"])リソース
明示的なクライアントでは、リソース名前空間が公開されています。
| リソース | 同期メソッドの例 | 非同期メソッドの例 |
|---|---|---|
agents | client.agents.create(...), client.agents.list(...), client.agents.get(...) | await client.agents.create(...), await client.agents.list(...) |
models | client.models.list() | await client.models.list() |
repositories | client.repositories.list() | await client.repositories.list() |
client.create_agent(...) や client.list_agents(...) などのトップレベルメソッドも引き続き利用できますが、アプリケーションコードではリソース名前空間を使用することを推奨します。
カスタム HTTP クライアント
sync クライアントと async クライアントの両方で、プロキシ、トランスポート、その他の高度な HTTP 設定に対応するため、カスタム httpx クライアントを指定できます。
from cursor_sdk import CursorClient, DefaultHttpxClientwith CursorClient.launch_bridge( workspace=".", http_client=DefaultHttpxClient(proxy="http://proxy.example.com"),) as client: ...from cursor_sdk import AsyncClient, DefaultAsyncHttpxClientasync with await AsyncClient.launch_bridge( workspace=".", http_client=DefaultAsyncHttpxClient(proxy="http://proxy.example.com"),) as client: ...DefaultHttpxClient と DefaultAsyncHttpxClient は、SDK のデフォルトのタイムアウト設定とリダイレクト動作を維持します。通常の httpx.Client と httpx.AsyncClient は、代わりに httpx のデフォルト設定を使用します。
タイムアウトとリトライの設定
どちらのクライアントも with_options(...) を提供しており、接続設定を共有し、デフォルトを上書きするシャローコピーを返します。すべてのリクエストには timeout を使用するか、unary_timeout と stream_timeout を個別に設定します。max_retries はクライアントのリトライを制御します:
short = client.with_options(timeout=5.0, max_retries=2)agent = short.agents.create(model="composer-2.5", local=LocalAgentOptions(cwd="."))非同期版:
short_async = async_client.with_options(timeout=5.0, max_retries=2)agent = await short_async.agents.create(model="composer-2.5", local=LocalAgentOptions(cwd="."))メッセージを送信する
agent.send() は呼び出すたびに Run を返します。await async_agent.send() は呼び出すたびに AsyncRun を返します。エージェントは実行をまたいで会話コンテキストを保持します。実行は、1 回のプロンプトに対する作業単位です。
print(agent.send("Find the bug in src/auth.py").text())# 同じエージェントなので、会話のコンテキストはすべて保持されるprint(agent.send("Fix it and add a regression test").text())非同期版:
run = await agent.send("Find the bug in src/auth.py")print(await run.text())run = await agent.send("Fix it and add a regression test")print(await run.text())テキストと一緒に画像を送信するには:
run = agent.send( { "text": "What's in this screenshot?", "images": [{"data": base64_png, "mime_type": "image/png"}], })ヘルパーのデータクラスも使用できます。SDKImage.from_file(path) はディスクから読み込み、base64 エンコードも自動で処理します。
from cursor_sdk import SDKImage, UserMessagerun = agent.send( UserMessage( text="What's in this screenshot?", images=[SDKImage.from_file("screenshot.png")], ))エンコード済みのバイト列やリモート URL をすでにお持ちの場合は、SDKImage.data_image(base64_data, mime_type) と SDKImage.url_image(url) も利用できます。
実行
class Run: id: str agent_id: str status: str # "running" | "finished" | "error" | "cancelled" | "expired" result: str model: ModelSelection | None duration_ms: int git: RunGitInfo | None created_at: str | None usage: TokenUsage | None # 累積値。ライブハンドルのプロパティ def stream(self) -> Iterator[SDKMessage]: ... def messages(self) -> Iterator[SDKMessage]: ... def events(self) -> Iterator[RunStreamEvent]: ... def iter_text(self) -> Iterator[str]: ... def text(self) -> str: ... def wait(self) -> RunResult: ... def cancel(self) -> None: ... def conversation(self) -> list[ConversationTurn]: ... def conversation_json(self) -> str: ... def observe(self, *, after_offset: str | None = None) -> Iterator[RunStreamEvent]: ... def supports(self, operation: str) -> bool: ... def unsupported_reason(self, operation: str) -> str | None: ... def on_did_change_status( self, listener: Callable[[str], None] ) -> Callable[[], None]: ...run.stream() は run.messages() の別名です。run を直接反復処理すると、run.events() と同様に RunStreamEvent エンベロープが返されます。
AsyncRun には、usage を含む同じ状態フィールドがあります。I/O を行うメソッドは非同期です:async for message in run.stream()、async for message in run.messages()、async for event in run.events()、async for text in run.iter_text()、await run.text()、await run.wait()、await run.cancel()、await run.conversation()、await run.conversation_json()、および async for event in run.observe()。
ストリーミング
run = agent.send("Find the bug in src/auth.py")for message in run.messages(): if message.type == "assistant": for block in message.message.content: if block.type == "text": print(block.text, end="") elif message.type == "thinking": print(message.text, end="") elif message.type == "tool_call": print(f"[tool] {message.name}: {message.status}") elif message.type == "status": print(f"[status] {message.status}") elif message.type == "usage": print(f"[usage] turn total={message.usage.total_tokens}")実行ストリームは一度しか消費できません。run.messages()、run.events()、run.iter_text() はいずれも同じ基盤ストリームを読み取り、その位置を進めます。ストリームが完了すると、実行には最終結果 (run.result、run.status、run.usage、run.git、...) が格納されます。run.wait() を呼び出すと、残りのイベントをすべて処理し、型付きの RunResult を返します。
ストリーミングなしで待機する
result = run.wait()print(result.status) # "finished" | "error" | "cancelled" | "expired"print(result.result) # 最終的な assistant text(ある場合)print(result.model) # この実行で使用された解決済みの ModelSelectionprint(result.duration_ms)print(result.usage) # 累積の TokenUsage。取得できない場合は Noneprint(result.git) # Cloud 上での RunGitInfo非同期版:
result = await run.wait()トークン使用量
実行時が提供する場合、実行はトークン利用を報告します。累積合計は、ライブハンドルの run.usage (ストリーミング中または wait() 後) か、run.wait() が返す RunResult の result.usage から取得できます。どちらにも、利用を報告したすべてのターンの合計を表す TokenUsage が格納されます。いずれのターンも利用を報告しなかった場合は、どちらも None になります。たとえば、ターンを完了せずにキャンセルされた実行、利用を公開しない実行時、または利用がまだ同期されていないデタッチされた Cloud スナップショットなどが該当します。
@dataclass(frozen=True)class TokenUsage: input_tokens: int output_tokens: int cache_read_tokens: int cache_write_tokens: int total_tokens: int reasoning_tokens: int | None = None| フィールド | 説明 |
|---|---|
input_tokens | モデルに送信されたプロンプトのトークン数。 |
output_tokens | モデルが生成したトークン数。 |
cache_read_tokens | プロンプトキャッシュから取得したトークン数。 |
cache_write_tokens | プロンプトキャッシュに書き込んだトークン数。 |
total_tokens | input_tokens + output_tokens + cache_read_tokens + cache_write_tokens。reasoning_tokensは含まれません。 |
reasoning_tokens | output_tokensの一部である推論トークン。モデルまたは実行時から報告されなかった場合はNoneです。 |
result = run.wait()if result.usage is not None: print(f"total: {result.usage.total_tokens}") print(f"in: {result.usage.input_tokens}, out: {result.usage.output_tokens}") print( f"cache read/write: {result.usage.cache_read_tokens}/{result.usage.cache_write_tokens}" )else: print("no usage reported for this run")reasoning_tokens はすでに output_tokens に含まれているため、二重計上を避けるために total_tokens には含まれません。
ストリーミング中にターンごとの数値を取得するには、usage ストリームイベント (SDKUsageMessage) を処理します。このイベントは、利用が報告された各ターンの終了時に1回発生し、そのターンの TokenUsage を保持します。run.usage と result.usage は、実行全体を通じて累積されます。ストリームのターン終了後、ハンドルはこれらの合計値を優先します。それ以外の場合は、ブリッジから提供された wait() の利用、または get_run / list_runs のスナップショットの利用を使用します。
for message in run.messages(): if message.type == "usage": print(f"turn used {message.usage.total_tokens} tokens")# または、メッセージを自分で消費せずに wait() の後で:result = run.wait()print(run.usage, result.usage)非同期版: async for message in run.messages() と await run.wait()。run.usage は引き続き AsyncRun の同期プロパティです。
TokenUsage は cursor_sdk からエクスポートされます (高度な用途向けに to_token_usage / sum_token_usage も提供) 。ワイヤー形式の JSON はキャメルケース (