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) 패턴을 통해 샘플링을 제공합니다. 자세한 내용은 모델 컨텍스트 프로토콜 설명서의 다중 왕복 요청을 참조하세요.

  • 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. 그런 다음 클라이언트는 원래 요청의 재시도 시 완료를 제공합니다. 자세한 내용은 모델 컨텍스트 프로토콜 설명서의 다중 왕복 요청을 참조하세요.

샘플링 요청에는 다음이 포함됩니다.

  • 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 이상에서 샘플링은 클라이언트와 MCP 서버 대상 requestState 간에 불투명한 다중 왕복 요청(MRTR) 패턴을 사용합니다. 이 값을 보호하는 것은 공동 책임입니다. 게이트웨이는 값을 저장하지 않고 권한을 부여하고 전달하는 반면, MCP 서버 대상은 값을 검증하고 한 사용자가 다른 사용자의 요청 상태를 재생하지 못하도록 해야 합니다. MCP 서버가 따라야 하는 전체 공동 책임 모델 및 보호 지침은 MCP 서버 대상 고려 사항의 유도 및 샘플링을 위한 요청 상태 보호를 참조하세요.

오류 처리

시나리오 오류 설명

보류 중인 샘플링 요청이 없을 때 클라이언트가 샘플링 응답을 보냅니다.

JSON-RPC-32600(잘못된 요청)

이 세션에 대해 일치하는 샘플링 요청을 찾을 수 없습니다.

클라이언트는 보류 중인 요청과 일치하지 id 않는를 사용하여 샘플링 응답을 보냅니다.

JSON-RPC-32600(잘못된 요청)

는 sampling/createMessage 요청에서 게이트웨이가 보낸 것과 일치해야 id 합니다.

MCP 서버가 샘플링 요청을 보내지만 게이트웨이가 지원을 선언하지 않음

JSON-RPC-32601(메서드를 찾을 수 없음)

MCP 서버 대상으로 반환됩니다. 문제 해결을 참조하세요.

문제 해결

오류: "오류 호출 도구 'sample_tool': 메서드를 찾을 수 없음: 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" ))