ターン途中の指示変更を使うと、ユーザーはレスポンスの完了を待たずに、要件の追加や方針の変更ができます。
ターン途中の指示変更は、Responses API への WebSocket 接続で
GPT-6 Astra(gpt-6-astra)を使用する場合に利用できます。
GPT-5.6 以前のモデルは指示変更に対応していません。
指示変更によって、アプリケーションに送信済みの出力が書き換えられたり、実行済みの操作が取り消されたり、開始済みのツールがキャンセルされたりすることはありません。
接続のセットアップと通信の基本的な動作については、WebSocket モードをご覧ください。正確なイベント定義については、Responses WebSocket イベントのリファレンスをご覧ください。
指示変更メッセージの送信
response.create でレスポンスを開始します。そのレスポンスの response.created イベントを受信したら、同じ接続で response.steer を送信します。このとき、previous_response_id にはそのレスポンスの ID を指定します。
{
"type": "response.steer",
"previous_response_id": "resp_1",
"input": "Keep the scope small enough for one developer to finish in two weeks."
}
このイベントで指定できるのは、type、previous_response_id、input のみです。input には、文字列、またはサポートされているコンテンツタイプのユーザーメッセージを含む空でない配列を設定します。
API は response.steer.accepted を送信し、入力がキューに入ったことを通知します。
{
"type": "response.steer.accepted",
"sequence_number": 4,
"steer": {
"id": "steer_0123456789abcdef0123456789abcdef",
"previous_response_id": "resp_1"
}
}
受け付けられたという通知は、入力がキューに入ったことを意味し、モデルがすでにその入力に基づいて動作したことを意味するわけではありません。アプリケーションからのツールの結果または承認が必要でない限り、API は追加指示を含む新しいレスポンスを自動的に作成します。
この継続レスポンスを自動作成する前に、サーバーは現在の出力項目と、すでに実行中のホスト型ツールの処理を完了させます。追加指示を含むレスポンスを受信するには、引き続きイベントを読み取ってください。response.create を再度送信しないでください。
指示変更によって元のレスポンスが中断されると、そのレスポンスは response.incomplete と incomplete_details.reason: "steered" で終了します。元のレスポンスが先に正常終了した場合は、完了ステータスが維持され、その後に指示変更を反映した継続レスポンスが生成されることもあります。
自動作成される継続レスポンスは、元のリクエストの設定を引き継ぎます。トークン数とツール呼び出し回数の制限は、レスポンスごとに個別に適用されます。
完全なサンプルの実行
.NET SDK では Responses WebSocket クライアントが提供されていないため、このサンプルの C# SDK 版は用意されていません。
import asyncio
from openai import AsyncOpenAI
async def main():
client = AsyncOpenAI()
initial_response_id = None
successor_response_id = None
async with client.responses.connect() as connection, asyncio.timeout(120):
await connection.response.create(
model="gpt-6-astra",
reasoning={"effort": "medium"},
input="Draft a project plan for building a task-tracking app.",
)
async for event in connection:
if event.type == "response.created":
if initial_response_id is None:
initial_response_id = event.response.id
# Simulate a user adding instructions while the response runs.
await connection.response.steer(
previous_response_id=initial_response_id,
input="Keep the scope small enough for one developer to finish in two weeks.",
)
else:
successor_response_id = event.response.id
elif event.type in {"response.steer.failed", "response.failed", "error"}:
raise RuntimeError(event.to_json())
elif event.type == "response.incomplete":
response = event.response
if (
response.id != initial_response_id
or response.incomplete_details is None
or response.incomplete_details.reason != "steered"
):
raise RuntimeError(event.to_json())
elif (
event.type == "response.completed"
and event.response.id == successor_response_id
):
print(event.response.output_text)
return
# Acceptance only queues the input. Keep reading past the first response.
raise RuntimeError("Connection closed before the steered response finished.")
asyncio.run(main())このサンプルでは、最初の response.created イベントの後に追加指示を送信します。実際のアプリケーションでは、ユーザーが追加指示を入力したときに送信してください。継続レスポンスの response.created イベントを受信した後は、新たな指示変更にその継続レスポンスの ID を使用します。
ツールの結果または承認の返送
レスポンスにクライアント側のツールの結果または承認が必要な場合、API は指示変更の入力をキューに保持します。同じ接続で、通常どおりツールまたは承認のフローを続けてください。
たとえば、元のレスポンスが get_project_status の呼び出しを出力して完了する場合があります。以下のペイロードには、関連するフィールドのみを示しています。
{
"type": "response.completed",
"response": {
"id": "resp_1",
"status": "completed",
"output": [
{
"type": "function_call",
"call_id": "call_project",
"name": "get_project_status",
"arguments": "{\"project\":\"task-tracker\"}"
}
]
}
}
元のレスポンスが完了すると、API は、受け付け済みの指示変更のうち、まだ入力を必要とするものについて response.steer.pending を送信します。その required_input フィールドには、追加指示を適用する前に API が必要とするツールの結果または承認が示されます。
{
"type": "response.steer.pending",
"sequence_number": 12,
"steer": {
"id": "steer_0123456789abcdef0123456789abcdef",
"previous_response_id": "resp_1"
},
"reason": "waiting_for_required_input",
"required_input": [
{
"type": "function_call_output",
"call_id": "call_project",
"name": "get_project_status"
}
]
}
同じ接続で response.create を使って必要な入力を返し、previous_response_id に resp_1 を設定します。受け付け済みの指示変更を繰り返し送信しないでください。明示的に送信した response.create では、そのリクエストで指定したツール、指示、その他の設定が使用されます。
この JSONC の例では、サーバーがキュー内の追加指示を挿入する位置をコメントで示しています。
{
"type": "response.create",
"model": "gpt-6-astra",
"previous_response_id": "resp_1",
"input": [
// The server implicitly prepends your accepted steer here:
// "Keep the scope small enough for one developer to finish in two weeks."
{
"type": "function_call_output",
"call_id": "call_project",
"output": "Design is complete. Development has not started.",
},
{
"role": "user",
"content": "Show me the updated plan before starting any work.",
},
],
}
ツールの結果を返す際に、response.steer.pending を待つ必要はありません。サーバーが対応する response.create をすでに受信している場合は、この通知を先に送信せずに処理を進められます。
失敗と接続切断への対処
response.steer.failed は、API が指示変更による入力の適用に失敗し、後から自動的に適用することもないことを意味します。このイベントは、元の input と previous_response_id を steer の下に含め、失敗の内容を説明する error オブジェクトとともに返します。
受け付け済みの送信内容は steer.id で追跡してください。後で失敗した場合も、同じ ID が使われます。
一般的なエラーコード:
invalid_input:サポートされているイベントフィールドとユーザーメッセージ入力のみを使用してください。steering_not_supported:モデル、リクエストパラメーター、またはその両方が指示変更に対応していない可能性があります。response_not_found:対象のレスポンスが、引き続き同じ WebSocket 接続で利用可能な状態である必要があります。too_many_pending_steers:保留中の指示変更の入力が多すぎます。必要なツールの結果や承認がある場合は、response.createを使って返してください。それ以外の場合は、継続レスポンスが自動作成されるのを待ってから追加の入力を送信してください。受け付け済みの指示変更を再送信しないでください。
キューに入った指示変更の入力は現在の接続上にのみ存在し、元のレスポンスとともには保存されません。送信した指示変更の入力を記録し、再送信する前にレスポンスのイベントや履歴と照合してください。保留中の指示変更が、接続切断後も保持されているとは限りません。WebSocket の復旧ガイダンスをご覧ください。