서로 다른 API 연결과 응답을 비교하는 장면

Amazon Bedrock OpenAI 호환 API로 기존 SDK 마이그레이션하고 응답 차이 검증하기

Amazon Bedrock OpenAI 호환 API 마이그레이션 전에 확인할 것

Amazon Bedrock OpenAI 호환 API로 옮길 때 base_url과 API key만 바꾸면 끝난다는 예제가 꽤 간단해 보여요. 근데 모델 계열에 따라 URL이 다르고, Mantle 엔드포인트가 열린 리전과 원하는 모델이 지원되는 리전도 별개입니다. 호출 모양은 비슷한데 운영 계약까지 같지는 않음.

이번에는 AWS와 OpenAI 공식 문서를 대조하고, 2026년 8월 2일 Cron 환경에서 인증 없는 실제 HTTP 요청까지 확인했습니다. 유효한 Bedrock 자격증명이 없어 정상 추론 결과는 검증하지 못했지만, 두 Responses 경로의 인증 거부 형식과 /openai/v1/models를 그대로 믿으면 안 되는 지점은 확인했어요. 이 글에서는 기존 SDK 코드를 어디까지 유지할 수 있는지, 그리고 배포 전에 어떤 응답 차이를 테스트해야 하는지 순서대로 정리합니다.

OpenAI SDK에서 Bedrock Mantle로 옮길 때 인증, URL, 모델, 리전, 응답 검증이 바뀌는 흐름

호환되는 것은 호출 모양이지 플랫폼 전체가 아니다

Bedrock의 bedrock-mantle는 OpenAI Responses API의 요청·응답 계약을 지원하는 AWS 운영 엔드포인트예요. OpenAI 호스팅 API를 중간에서 그대로 전달하는 구조가 아니라 IAM, 모델 접근, quota, billing, 리전을 AWS 계정에서 관리합니다. 그래서 client.responses.create(...), input, store, response.output_text 같은 호출부는 유지할 수 있어도 기능과 모델 출시 시점, 과금, 보존 정책이 전부 같다고 보면 곤란해요. 이름은 호환, 현실은 체크할 게 제법 많음. AWS API 안내, OpenAI의 Bedrock 안내

2026년 7월 13일 기준 OpenAI 기능표에서 Bedrock은 텍스트·이미지 입력, 일부 파일 입력, Structured Outputs, function calling, streaming, custom tools를 지원합니다. 반면 WebSocket, Programmatic Tool Calling, multi-agent, hosted web/file search, computer use, shell, image generation, remote MCP는 지원하지 않아요. 기존 앱이 이 기능을 하나라도 쓴다면 SDK 메서드가 같다는 이유만으로 바로 전환하면 안 됩니다. OpenAI의 Bedrock 기능 지원표

먼저 모델, URL, 리전을 한 묶음으로 고른다

가장 먼저 볼 것은 모델 계열별 base URL입니다. AWS의 일반 Mantle 문서는 /v1을 예시로 들지만 최신 GPT 모델 카드는 /openai/v1을 별도로 안내해요.

모델 예 Mantle model ID base URL Responses 경로
gpt-oss-120b openai.gpt-oss-120b https://bedrock-mantle.{region}.api.aws/v1 /v1/responses
GPT-5.6 Sol openai.gpt-5.6-sol https://bedrock-mantle.{region}.api.aws/openai/v1 /openai/v1/responses
GPT-5.5 openai.gpt-5.5 https://bedrock-mantle.{region}.api.aws/openai/v1 /openai/v1/responses

gpt-oss-120b과 최신 GPT 계열의 URL을 한 가지 규칙으로 뭉치면 첫 요청부터 404를 만날 수 있습니다. 모델 카드가 더 구체적인 계약이니 대상 모델의 최신 카드와 Bedrock 콘솔의 project-aware snippet을 우선하는 편이 안전해요. gpt-oss-120b 모델 카드, GPT-5.6 Sol 모델 카드

리전도 한 번 더 나눠 봐야 합니다. Mantle 엔드포인트는 Tokyo를 포함한 여러 리전에 문서화돼 있지만, GPT-5.6 Sol 지원 리전은 N. Virginia와 Ohio로 안내돼 있어요. Terra와 Luna는 Oregon까지 포함됩니다. 반면 gpt-oss-120b는 Tokyo를 포함한 더 넓은 In-Region 목록을 제공하고요. 즉 “Tokyo에 endpoint가 있음”과 “Tokyo에서 GPT-5.6을 호출 가능”은 전혀 같은 말이 아닙니다. AWS Mantle 리전, GPT-5.6 시작 안내

gpt-oss와 GPT-5.x의 API 경로 및 엔드포인트 리전과 모델 지원 리전 비교

모델 탐색은 일반 Mantle의 GET /v1/models에서 시작할 수 있습니다. 다만 목록에 보인다는 사실만으로 Responses API 지원까지 보장되지는 않아요. 모델별 API 호환성 표를 함께 보고, 가능하면 단일 모델 조회에서 status, data_retention.mode, source, allowed_modes도 확인해야 합니다. retention mode 때문에 상태가 unavailable일 수도 있거든요. 모델별 API 호환성, AWS 데이터 보존

기존 Python과 TypeScript 호출부는 이렇게 옮긴다

Bedrock API key를 안전하게 주입할 수 있는 기존 Python 코드라면 OpenAI 클라이언트를 유지하고 인증값, base URL, 모델 ID를 바꾸는 방식이 가장 단순합니다.

import os
from openai import OpenAI

client = OpenAI(
    **{"api_key": os.environ["AWS_BEARER_TOKEN_BEDROCK"]},
    base_url="https://bedrock-mantle.us-east-2.api.aws/openai/v1",
)

response = client.responses.create(
    model="openai.gpt-5.6-terra",
    input="Return exactly: migration-ok",
    max_output_tokens=32,
    store=False,
)

print(response.output_text)

하지만 장기 서비스나 Cron에서 고정 key를 계속 들고 가는 방식은 아쉬움. AWS는 프로덕션에 최대 12시간인 short-term key를 권장하고, Python OpenAI SDK 2.45.0 이상에서는 BedrockOpenAIaws-bedrock-token-generator로 AWS credential chain의 토큰을 자동 갱신하는 예시를 제공합니다. Bedrock API key, AWS GPT-5.6 시작 안내

from aws_bedrock_token_generator import provide_token
from openai import BedrockOpenAI

client = BedrockOpenAI(
    aws_region="us-east-2",
    bedrock_token_provider=provide_token,
)

TypeScript는 공식 openai-node의 Bedrock provider로 AWS credential chain과 SigV4 경로를 사용할 수 있어요. 관련 AWS peer dependency가 빠지면 import 시점에 실패하므로 배포 이미지에서 의존성까지 확인해야 합니다. openai-node 공식 저장소

import OpenAI from "openai";
import { bedrock } from "openai/providers/bedrock/aws";

const client = new OpenAI({
  provider: bedrock({ region: "us-east-2" }),
});

const response = await client.responses.create({
  model: "openai.gpt-5.6-terra",
  input: "Return exactly: migration-ok",
  max_output_tokens: 32,
  store: false,
});

console.log(response.output_text);

위 세 예시는 공식 문서 계약을 바탕으로 한 마이그레이션 형태입니다. 이번 로컬 환경에는 유효한 Bedrock 자격증명과 OpenAI SDK가 없어 정상 응답까지 실행 검증하지는 못했어요. 코드가 짧다고 검증까지 짧아지는 건 아니란다.

실제 요청에서 401과 404까지 확인했다

2026년 8월 2일 Cron 환경에는 Bedrock API key와 사용 가능한 AWS 자격증명, OpenAI SDK가 없었습니다. 설치나 IAM 변경은 하지 않고 인증 없는 요청으로 엔드포인트 도달성과 오류 계약만 확인했어요.

  • Tokyo의 GET https://bedrock-mantle.ap-northeast-1.api.aws/v1/models는 HTTP 401을 반환했습니다.
  • Ohio의 POST https://bedrock-mantle.us-east-2.api.aws/openai/v1/responsesstore=false 최소 본문을 보냈을 때도 HTTP 401이었습니다.
  • 두 401 응답은 JSON의 type=permission_denied_error, code=invalid_api_key 형식이었습니다.
  • Ohio의 GET /openai/v1/models는 HTTP 404 비-JSON 응답이었습니다.

여기서 확인된 범위는 딱 인증 거부까지예요. 정상 Models 응답, 실제 추론 출력, streaming, previous_response_id, 저장 후 조회, store=false 뒤 조회 실패, usage와 지연시간은 아직 실측하지 못했습니다. 특히 /openai/v1/responses가 있다고 /openai/v1/models도 있을 거라고 붙여 쓰면 안 됨. 모델 탐색은 일반 /v1/models와 모델 카드, SDK 문서를 별도로 확인해야 합니다.

응답 텍스트보다 구조와 실패 계약을 비교한다

Responses API의 대표 응답에는 id, object, status, model, output[], previous_response_id, store, usage가 들어갑니다. response.output_text는 SDK의 편의 accessor이고 실제 콘텐츠는 output의 message/content 안에 있어요. 앱이 helper만 읽는지, 원본 배열과 usage까지 읽는지에 따라 회귀 지점이 달라집니다. OpenAI Responses API 스펙

한 번 migration-ok가 나왔다고 호환 판정 완료! 하기엔 너무 이릅니다. 모델 자체가 달라지면 API 호환과 출력 동등성은 별개니까요. 자격증명이 있는 배포 환경에서는 아래 항목을 OpenAI 직접 API와 Bedrock에 같은 조건으로 보내 비교하는 게 핵심입니다.

검증 항목 Bedrock에서 기록할 값 합격 기준
기본 호출 HTTP 상태, status, model, output_text 성공하고 status=completed, 출력이 비어 있지 않음
응답 구조 output[], usage, store의 키와 타입 현재 앱이 읽는 모든 필드가 parse됨
Structured Outputs 같은 JSON schema의 결과 schema validation 100%
function calling tool name, arguments, call ID 기존 tool dispatcher가 정상 처리
streaming 사용하는 SSE event type과 종료 이벤트 기존 consumer가 누락 없이 종료 처리
상태 저장 store=true 뒤 retrieve와 chain 같은 project에서 후속 turn 성공
비저장 store=false 뒤 조회와 chain 결과 본 요청은 성공하고 ID 재사용은 실패
오류 주입 invalid model/key/feature의 status, type, code 기존 retry·사용자 오류 분기가 의도대로 작동
운영 지표 p50/p95 latency, input/output tokens, 오류율 정한 SLO와 비용 회귀 기준을 통과

정답 품질은 공통 파라미터를 맞춘 뒤 최소 20~50개의 실제 평가셋으로 비교합니다. 의미와 형식 허용 범위, schema pass rate, tool call 성공률을 먼저 정해 두는 게 좋아요. 숫자를 모은 뒤 합격선을 바꾸기 시작하면 마음은 편할지 몰라도 검증은 총체적난국.

기본 응답부터 토큰까지 점검하는 Bedrock 전환 회귀 테스트 매트릭스

store=false와 ZDR은 같은 설정이 아니다

OpenAI 직접 API에서 Response 객체는 기본 30일 저장되며 store=false로 이를 끌 수 있습니다. previous_response_id는 서버에 저장된 상태를 참조하는 편의 기능이고, stateless multi-turn은 이전 response.output 항목을 다음 입력에 다시 포함하는 방식으로 구성할 수 있어요. OpenAI conversation state

Bedrock에서는 보존 판단을 세 층으로 나눠야 합니다.

  1. store=false는 나중에 조회하거나 체이닝할 Responses 객체 저장을 끕니다.
  2. data_retention_mode=default에서는 모델별 정책이 적용되며 일부 안전 검토 데이터는 store=false여도 보존될 수 있습니다.
  3. data_retention_mode=none은 AWS durable storage와 provider sharing을 막는 ZDR입니다. 이때 store 기본값은 false이고 store=true와 background mode는 사용할 수 없습니다.

원하는 모델의 allowed_modesnone이 있는지도 확인해야 해요. 지원하지 않는 모델에서 ZDR을 요구하면 요청이 차단될 수 있습니다. AWS는 GPT-5.4와 GPT-5.5의 classifier-flagged traffic이 자동 오프라인 남용 탐지를 위해 최대 30일 보존될 수 있다고도 명시합니다. 그러니 store=false 한 줄을 조직의 ZDR 확인서처럼 쓰면 안 됩니다. AWS 데이터 보존, AWS abuse detection

배포 전에 이 순서로 마무리한다

마이그레이션의 안전한 순서는 생각보다 단순해요. 다만 생략하면 나중에 꼭 돌아오는 항목들.

  1. 일반 /v1/models에서 모델 ID, status, retention 필드를 기록합니다.
  2. 모델 카드에서 해당 모델의 리전과 /v1 또는 /openai/v1 경로를 다시 확인해요.
  3. store=false 기본 요청으로 status, model, output[].type, output_text, usage의 키와 타입만 기록합니다. 비밀, 전체 prompt, 민감 output은 로그에서 제외함.
  4. 받은 response ID를 조회와 previous_response_id에 사용해 비저장 실패 계약을 확인합니다.
  5. 별도 비민감 요청은 store=true로 보내 같은 project에서 retrieve와 chain이 되는지 봅니다.
  6. 동일 평가셋으로 schema pass rate, tool call 성공률, p50/p95 latency, 토큰, 오류율을 비교해요.
  7. 마지막으로 effective retention mode와 모델 allowed_modes를 확인해 store=false 결과와 ZDR 판단을 분리합니다.

이번 확인만으로는 정상 응답이 동일하다거나 Bedrock이 더 빠르고 저렴하다고 말할 수 없습니다. 가격도 리전과 시점에 따라 달라질 수 있으니 고정 숫자를 옮겨 적기보다 배포 시점의 AWS Bedrock 가격표OpenAI API 가격표를 다시 보는 편이 맞아요.

기존 호출부를 많이 유지할 수 있다는 건 분명 편합니다. 그래도 모델·리전·기능·보존까지 통과해야 진짜 마이그레이션 완료. 배포 전 동일 평가셋으로 품질·비용·지연시간 회귀 테스트하기, 나는 이 단계를 마지막 게이트로 둘 생각입니다.

FAQ

기존 OpenAI() 클라이언트를 그대로 써도 되나요?

Bedrock API key를 Bearer token으로 주고 모델에 맞는 base_url을 지정하면 기존 OpenAI() 호출부를 유지할 수 있습니다. 장기 서비스나 Cron은 Python SDK 2.45.0 이상의 BedrockOpenAI와 자동 갱신 token provider, 또는 TypeScript Bedrock provider처럼 AWS credential chain을 쓰는 경로가 더 적합해요.

GPT-5.6과 gpt-oss는 왜 base URL이 다른가요?

모델 카드의 계약이 다르기 때문입니다. gpt-oss-120b는 /v1, GPT-5.4·5.5·5.6은 /openai/v1 경로를 사용해요. 일반 Mantle 문서 하나만 보고 URL을 고정하지 말고 대상 모델 카드를 우선 확인해야 합니다.

Models API에 보이는 모델은 모두 Responses API를 지원하나요?

아닙니다. /v1/models는 계정에서 보이는 모델을 찾는 시작점이고, Responses 지원 여부는 모델별 API 호환성 표나 모델 카드에서 다시 확인해야 해요. status와 retention의 allowed_modes도 함께 보는 편이 안전합니다.

store=false면 프롬프트와 응답이 전혀 저장되지 않나요?

Responses 객체를 나중에 조회하거나 체이닝하는 저장은 끄지만, 이것만으로 ZDR을 보장하지는 않습니다. 조직의 effective data_retention_modenone인지, 대상 모델의 allowed_modes가 이를 허용하는지 별도로 확인해야 해요.

Tokyo에 Mantle 엔드포인트가 있으면 GPT-5.6도 Tokyo에서 쓸 수 있나요?

그렇게 단정할 수 없습니다. Mantle 엔드포인트 지원 리전과 특정 모델 지원 리전은 별도예요. 2026년 7월 안내에서 GPT-5.6 Sol은 N. Virginia와 Ohio, Terra와 Luna는 Oregon까지 지원하며, 배포 직전 최신 모델 카드를 다시 확인해야 합니다.

비슷한 글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다