View a markdown version of this page

AgentCore ゲートウェイでサンプリングを使用する - Amazon Bedrock AgentCore

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

AgentCore ゲートウェイでサンプリングを使用する

サンプリングは、 MCP サーバーがツール呼び出し中にクライアントから LLM の完了をリクエストできるようにする MCP 機能です。これにより、サーバーは言語モデルに直接アクセスすることなく AI 機能を活用できます。クライアントはモデルの呼び出しを処理し、結果を返します。AgentCore Gateway は、MCP サーバーターゲットからのサンプリングリクエストをクライアントに転送し、リクエストをidゲートウェイ生成識別子に置き換えます。

前提条件

ゲートウェイでサンプリングを使用するには:

  • 有効なセッション (バージョン 2025-11-25 以前) — サンプリングにはセッションサポートが必要です。「ゲートウェイで MCP セッションを使用する」を参照してください。バージョン 2026-07-28以降では、これらのバージョンはステートレスであるため、 sessionConfiguration をゲートウェイに追加する必要はありません。

  • レスポンスストリーミングが有効 (バージョン 2025-11-25 以前) — サンプリングリクエストは、オープン接続中に SSE チャンクとして送信されます。ゲートウェイの trueで streamingConfiguration.enableResponseStreamingを に設定しますprotocolConfiguration.mcp。バージョン 2026-07-28以降では、レスポンスストリーミングを有効にする必要はありません。これらのバージョンは、レスポンスストリームでサーバーが開始したリクエストではなく、マルチラウンドトリップリクエスト (MRTR) パターンを通じてサンプリングを提供します。詳細については、Model Context Protocol ドキュメントの「マルチラウンドトリップリクエスト」を参照してください。

  • MCP サーバーターゲットタイプ — サンプリングリクエストは MCP サーバーターゲットから送信されます。

  • クライアントがサンプリング機能を宣言する — クライアントは、ゲートウェイがサンプリングリクエストを転送するためのサンプリングのサポートを宣言する必要があります。バージョン 2025-11-25以前では、クライアントはこのサポートをinitializeリクエストで宣言します。バージョン 2026-07-28以降では、クライアントは _metaフィールド () のリクエストごとに宣言しますio.modelcontextprotocol/clientCapabilities。

サンプリングの仕組み

ツールの実行中に MCP サーバーターゲットが LLM を完了する必要がある場合は、 sampling/createMessage リクエストを送信します。ゲートウェイはこのリクエストを SSE イベントとしてクライアントに転送し、リクエスト を置き換えますid。クライアントは言語モデルを呼び出し、結果をゲートウェイに送り返し、その結果をターゲットに転送します。

注記

ここで説明するフローは、サーバーがオープン SSE ストリームでサーバー開始リクエストsampling/createMessageとして送信するバージョン 2025-11-25以前に適用されます。バージョン 2026-07-28以降では、サンプリングは代わりにマルチラウンドトリップリクエスト (MRTR) パターンを使用します。サーバーは、 を resultTypeに設定して中間結果を返しますinput_required。次に、クライアントは元のリクエストの再試行の完了を提供します。詳細については、Model Context Protocol ドキュメントの「マルチラウンドトリップリクエスト」を参照してください。

サンプリングリクエストには以下が含まれます。

  • messages — モデルに送信する会話メッセージ。

  • modelPreferences — 必要なモデル機能 (インテリジェンス、速度、コスト) に関するオプションのヒント。

  • systemPrompt — モデルのオプションのシステムプロンプト。

  • maxTokens — 生成するトークンの最大数。

クライアントは次のように応答します。

  • model — 使用されたモデル。

  • role — 常に assistant。

  • content — 生成されたコンテンツ (テキストまたはイメージ)。

注記

クライアントは、使用するモデルとリクエストの処理方法を完全に制御できます。サーバーの modelPreferencesは、要件ではなくヒントです。クライアントは、独自のポリシーに基づいてリクエストを変更または拒否することもできます。

サンプリングフロー

  1. クライアントは Mcp-Session-Idヘッダーを使用してtools/callリクエストを送信します。

  2. Gateway は、ツール呼び出しを MCP サーバーターゲットに転送します。

  3. ターゲットは SSE ストリームを開き、sampling/createMessageリクエストを送信します。

  4. Gateway はサンプリングリクエストを SSE イベントとしてクライアントに転送し、リクエスト を置き換えますid。

  5. クライアントは、提供されたメッセージを使用して言語モデルを呼び出します。

  6. クライアントは、ゲートウェイのリクエストidと同じ Mcp-Session-Idと を使用して、サンプリング結果を含む新しいリクエストを送信します。

  7. Gateway は、結果を MCP サーバーターゲットに転送します。

  8. ターゲットは処理を続行し、最終的なツール結果を返します。

  9. Gateway は最終結果をクライアントに転送し、ストリームを閉じます。

MCP サーバーターゲット開発者向けガイダンス

重要

サンプリングリクエストを送信する MCP サーバーターゲットは、サンプリング呼び出しを try-catch ブロックにラップし、クライアントがサンプリングをサポートしていない場合を処理する必要があります。ゲートウェイのクライアントがサンプリング機能を宣言しなかった場合、ゲートウェイはそれをターゲットに宣言しません。ターゲットがサンプリングリクエストを送信すると、ゲートウェイはターゲットに -32601 (メソッドが見つかりません) エラーを返します。

サンプリングが利用できない場合、サーバーはフォールバックパスを実装する必要があります (組み込みモデルの使用や AI アシストステップのスキップなど)。

リクエスト状態の保護 (バージョン 2026-07-28 以降)

バージョン 2026-07-28以降では、サンプリングはマルチラウンドトリップリクエスト (MRTR) パターンを使用します。このパターンは、クライアントと MCP サーバーターゲットrequestStateの間で不透明になります。この値を保護することは共有責任です。ゲートウェイはそれを保存せずに承認して転送しますが、MCP サーバーターゲットはそれを検証し、あるユーザーが別のユーザーのリクエスト状態を再生できないようにする必要があります。MCP サーバーが従う必要がある完全な責任共有モデルと保護ガイダンスについては、「MCP サーバーターゲットの考慮事項」の「誘発とサンプリングのリクエスト状態を保護する」を参照してください。

エラー処理

シナリオ エラー 説明

保留中のサンプリングリクエストがない場合にクライアントがサンプリングレスポンスを送信する

JSON-RPC -32600 (無効なリクエスト)

このセッションに一致するサンプリングリクエストが見つかりませんでした。

クライアントidが保留中のリクエストと一致しない でサンプリングレスポンスを送信する

JSON-RPC -32600 (無効なリクエスト)

は、sampling/createMessageリクエストでゲートウェイによって送信されたものと一致するid必要があります。

MCP サーバーがサンプリングリクエストを送信したが、ゲートウェイがサポートを宣言しなかった

JSON-RPC -32601 (メソッドが見つかりません)

MCP サーバーターゲットに戻ります。トラブルシューティングを参照してください。

トラブルシューティング

エラー: "Error calling tool 'sample_tool': Method not found: sampling/createMessage"

このエラーは、MCP サーバーターゲットがサンプリングリクエストを送信しても、ゲートウェイのクライアントがサンプリング機能を宣言しなかった場合に発生します。バージョン 2025-11-25以前では、クライアントは 中にこの機能を宣言しますinitialize。バージョン 2026-07-28以降では、クライアントは _metaフィールドの各リクエストに対して宣言します。ゲートウェイは -32601 (メソッドが見つからない) エラーをターゲットに返します。ターゲットは、これをツール実行エラーとしてクライアントに返す場合があります。

解決するには:

  • MCP サーバー開発者の場合: サンプリング呼び出しに関するエラー処理を追加します。サンプリングがサポートされていない場合は、フォールバックパスを実装します。

    重要

    create_message 通話related_request_id=ctx.request_context.request_idには を含める必要があります。これは、ゲートウェイがサンプリングリクエストを元のツール呼び出しに正しく関連付けるために必要です。これがないと、サンプリングは機能しません。

    try: result = await ctx.session.create_message( messages=[{"role": "user", "content": {"type": "text", "text": "Summarize this document"}}], max_tokens=500, related_request_id=ctx.request_context.request_id, ) except Exception as e: # Fallback when client doesn't support sampling logger.warning(f"Sampling not supported: {e}") result = fallback_summarization(document)
  • ゲートウェイクライアント開発者の場合: バージョン 2025-11-25以前では、クライアントが 中にサンプリング機能を宣言していることを確認しますinitialize。バージョン 2026-07-28以降では、 _metaフィールド () の各リクエストに対して宣言しますio.modelcontextprotocol/clientCapabilities。次の例は、 initialize宣言を示しています。

    { "capabilities": { "sampling": {} } }

コードサンプル

注記

LangGraph MCP クライアント (langchain-mcp-adapters) と Strands MCP クライアントは現在サンプリングをサポートしていません。ゲートウェイからのサンプリングリクエストを処理するには、以下に示す MCP クライアントアプローチを使用します。

例
Python requests package (2025-11-25 and earlier)

これらのバージョンでは、クライアントは 中にサンプリング機能を宣言しinitialize、サンプリングリクエストはオープン SSE ストリームのsampling/createMessageリクエストとして到着します。MCP-Protocol-Version ヘッダーをゲートウェイがサポートするバージョンに設定します。

import requests import json import sseclient gateway_url = "https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp" headers = { "Content-Type": "application/json", "Accept": "text/event-stream", "Authorization": "Bearer YOUR_ACCESS_TOKEN" } # Step 1: Initialize with sampling capability init_response = requests.post(gateway_url, headers=headers, json={ "jsonrpc": "2.0", "id": "init-request", "method": "initialize", "params": { "protocolVersion": "2025-06-18", "capabilities": {"sampling": {}}, "clientInfo": {"name": "my-agent", "version": "1.0.0"} } }) session_id = init_response.headers["Mcp-Session-Id"] headers["Mcp-Session-Id"] = session_id headers["MCP-Protocol-Version"] = "2025-06-18" # Step 2: Call tool (streaming response) response = requests.post(gateway_url, headers=headers, json={ "jsonrpc": "2.0", "id": "tool-call-1", "method": "tools/call", "params": { "name": "summarizeDocument", "arguments": {"documentId": "doc-789"} } }, stream=True) # Step 3: Process SSE events client = sseclient.SSEClient(response) for event in client.events(): data = json.loads(event.data) if data.get("method") == "sampling/createMessage": sampling_id = data["id"] print(f"Sampling request: {data['params']['messages']}") # Step 4: Invoke your LLM and send result llm_result = invoke_your_model(data["params"]) # Your LLM invocation requests.post(gateway_url, headers=headers, json={ "jsonrpc": "2.0", "id": sampling_id, "result": { "model": "claude-sonnet-4-20250514", "role": "assistant", "content": {"type": "text", "text": llm_result} } }) elif "result" in data: print(f"Tool result: {data['result']}") break
Python requests package (2026-07-28)

バージョン では2026-07-28、サンプリングは SSE ストリームでサーバー開始リクエストの代わりにマルチラウンドトリップリクエストパターンを使用します。クライアントは、各リクエスト_metaで のサンプリング機能を宣言します。ツールを完了する必要がある場合、レスポンスは のsampling/createMessageリクエストinputRequestsと不透明な を含むinput_required結果ですrequestState。クライアントはモデルを呼び出し、新しい id、、inputResponsesおよび変更されていない を使用して元のリクエストを再試行しますrequestState。セッションとinitializeハンドシェイクは使用されません。ゲートウェイの には が含まれているsupportedVersions必要があります2026-07-28。

import requests gateway_url = "https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp" META = { "io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/clientInfo": {"name": "my-agent", "version": "1.0.0"}, "io.modelcontextprotocol/clientCapabilities": {"sampling": {}} } headers = { "Content-Type": "application/json", "Accept": "application/json, text/event-stream", "Authorization": "Bearer YOUR_ACCESS_TOKEN", "MCP-Protocol-Version": "2026-07-28", "Mcp-Method": "tools/call", "Mcp-Name": "summarizeDocument" } arguments = {"documentId": "doc-789"} # Step 1: Call the tool, declaring the sampling capability in _meta response = requests.post(gateway_url, headers=headers, json={ "jsonrpc": "2.0", "id": "tool-call-1", "method": "tools/call", "params": {"name": "summarizeDocument", "arguments": arguments, "_meta": META} }).json() result = response["result"] if result.get("resultType") == "input_required": # Step 2: Fulfill each sampling request by invoking your model input_responses = {} for key, input_request in result.get("inputRequests", {}).items(): params = input_request["params"] print(f"Sampling request: {params['messages']}") llm_result = invoke_your_model(params) # Your LLM invocation input_responses[key] = { "model": "claude-sonnet-4-20250514", "role": "assistant", "content": {"type": "text", "text": llm_result} } # Step 3: Retry the tool call with a new id, the input responses, # and the requestState echoed back unmodified retry_params = {"name": "summarizeDocument", "arguments": arguments, "_meta": META, "inputResponses": input_responses} if "requestState" in result: retry_params["requestState"] = result["requestState"] response = requests.post(gateway_url, headers=headers, json={ "jsonrpc": "2.0", "id": "tool-call-2", "method": "tools/call", "params": retry_params }).json() result = response["result"] print(f"Tool result: {result}")
MCP Client
from mcp import ClientSession from mcp.client.streamable_http import streamablehttp_client import asyncio async def sampling_handler(request): """Handle sampling requests from the server by invoking an LLM.""" messages = request.params.messages llm_response = await invoke_your_model(messages, max_tokens=request.params.maxTokens) return { "model": "claude-sonnet-4-20250514", "role": "assistant", "content": {"type": "text", "text": llm_response} } async def use_sampling(url, token): headers = {"Authorization": f"Bearer {token}"} async with streamablehttp_client(url=url, headers=headers) as ( read_stream, write_stream, _ ): async with ClientSession( read_stream, write_stream, sampling_handler=sampling_handler ) as session: await session.initialize() result = await session.call_tool( name="summarizeDocument", arguments={"documentId": "doc-789"} ) print(f"Tool result: {result}") return result asyncio.run(use_sampling( url="https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp", token="YOUR_ACCESS_TOKEN" ))