
1. 개요
Amazon Bedrock을 활용하여 AI 모델을 호출하는 API를 구축하고, 이를 API Gateway를 통해 외부에서 접근할 수 있도록 구성하는 과정을 소개합니다. 이번 포스팅에서는 Visual Studio Code를 활용하여 API 요청을 보내고, 응답을 확인하는 과정까지 다룹니다
2. Amazon Bedrock 소개
Amazon Bedrock은 OpenAI의 GPT, Anthropic의 Claude, Stability AI의 Stable Diffusion 등 다양한 AI 모델을 제공하여 텍스트 생성, 이미지 생성, 번역, 요약 등의 작업을 쉽게 수행할 수 있도록 합니다.
2.1 주요 기능
- 다양한 AI 모델 제공 (Anthropic Claude, Stability AI, Amazon Titan 등)
- 서버리스 환경에서 AI 서비스 실행 가능
- API 기반으로 쉽게 통합 가능
- 보안 및 개인정보 보호 지원
3. Bedrock Summary API Architecture

3.1 실습 전 아키텍처 개요 설명
이 아키텍처는 Amazon Bedrock을 활용하여 긴 텍스트를 요약하는 API를 구축하는 방법을 보여줍니다. 사용자는 API Gateway를 통해 텍스트를 입력하면, AWS Lambda가 이를 받아 Amazon Bedrock의 모델을 호출하여 요약된 결과를 반환하는 구조입니다.
3.1.1 사용자 입력
- 사용자는 긴 텍스트를 API에 POST 요청으로 보냅니다.
3.1.2 Amazon API Gateway
- API Gateway는 사용자 요청을 AWS Lambda로 전달하는 역할을 합니다.
- API Gateway는 인증, 로깅, 트래픽 관리 등의 기능도 수행할 수 있습니다.
3.1.3 AWS Lambda
- Lambda 함수는 API Gateway에서 받은 텍스트를 Amazon Bedrock으로 전달합니다.
- Bedrock에서 반환된 요약된 텍스트를 다시 API Gateway로 전달합니다.
3.1.4 Amazon Bedrock
- Amazon Bedrock은 텍스트 요약을 수행하는 AI 모델을 제공하는 AWS 서비스입니다.
- Lambda 함수는 Amazon Bedrock의 Text-to-Text 모델을 호출하여 긴 텍스트를 요약합니다.
3.1.5 IAM Role
- Amazon Bedrock과 AWS Lambda 간의 원활한 통신을 위해 IAM Role이 필요합니다.
- Lambda 함수가 Bedrock을 호출할 수 있도록 적절한 권한을 부여합니다.
3.1.6 응답 반환
- Lambda 함수는 Bedrock에서 생성한 요약된 텍스트를 API Gateway를 통해 사용자에게 반환합니다.
Hands-on
아래 Python 코드는 Amazon Bedrock의 Claude 3.5 Sonnet 모델을 이용해 긴 텍스트를 요약하는 Lambda 함수를 정의하고, 실제로 테스트하는 스크립트를 포함하고 있습니다.
# summary.py 파일
import boto3
import json
AWS_REGION_BEDROCK = "ap-northeast-2"
client = boto3.client(service_name="bedrock-runtime", region_name=AWS_REGION_BEDROCK)
def lambda_handler(event, context):
try:
# Request Body Parsing
body = json.loads(event.get("body", "{}")) # body가 None일 경우 대비
text = body.get("text", "")
# Query String Parsing (None 방지)
query_params = event.get("queryStringParameters") or {} # None 방지
points = query_params.get("points", "3") # 기본값 "3"
if not text:
return {
"statusCode": 400,
"body": json.dumps({"error": "Text is required!"})
}
# Claude API 요청 생성
claude_request = get_claude_request(text, points)
response = client.invoke_model(
modelId="anthropic.claude-3-5-sonnet-20240620-v1:0",
accept="application/json",
contentType="application/json",
body=json.dumps(claude_request)
)
response_body = json.loads(response["body"].read())
# API 응답 처리 수정
if isinstance(response_body, dict) and "content" in response_body:
content = response_body["content"]
if isinstance(content, list) and len(content) > 0:
summary_text = content[0].get("text", "No summary generated")
else:
summary_text = "No valid summary generated"
else:
summary_text = "Invalid API response"
return {
"statusCode": 200,
"body": json.dumps({"summary": summary_text})
}
except Exception as e:
return {
"statusCode": 500,
"body": json.dumps({"error": str(e)})
}
def get_claude_request(text: str, points: str):
prompt = f"""Text: {text} \n
From the text above, summarize the story in {points} points.\n
"""
return {
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1000,
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": prompt}
]
}
]
}
# 로컬 실행용 테스트
if __name__ == "__main__":
test_event = {
"body": json.dumps({"text": "This is a sample text that needs to be summarized."}),
"queryStringParameters": {"points": "3"}
}
response = lambda_handler(test_event, None)
print(response)
# Summary.test.py 파일
import json
from summary import handler
event = {
"body": json.dumps(
{
"text": """
Vincent was a jazzman, a saxophonist with a smooth, soulful sound that could melt the coldest of hearts. He had been playing the clubs and
bars of the city for years, honing his craft and building a reputation as one of the best musicians in town.
Mia was an actress, a rising star with a talent for drama and a fierce determination to succeed. She had been working non-stop for the past few years, taking on any role she could get, no matter how small, in order to make a name for herself in the competitive world of Hollywood.
One night, Vincent and Mia crossed paths at a jazz club in the city. Vincent was playing a set with his band, and Mia was in the audience,
sipping on a martini and enjoying the music. As soon as their eyes met, Vincent knew he was in trouble. Mia was the most beautiful woman he had ever seen, with piercing green eyes and long, curly hair that cascaded down her back like a golden waterfall.
Despite the fact that Mia was a celebrity and Vincent was just a struggling musician, they quickly hit it off. They talked for hours after
the show, exchanging stories and laughter, and before long, they were inseparable.
As the weeks went by, Vincent and Mia found themselves spending more and more time together. They would go on long walks through the city,
holding hands and talking about their dreams and aspirations. They would sit in Vincent's small apartment, listening to jazz records and drinking coffee until the early hours of the morning.
Despite their differences - Vincent was a struggling artist, while Mia was a successful celebrity - they found a deep connection in their shared passion for their craft. They inspired each other to work harder and push themselves to be the best they could be.
As the months passed, Vincent and Mia's relationship grew stronger. They began to talk about their future together, about the possibility of starting a family and building a life filled with love, laughter, and music.
But as their love for each other grew, so did the challenges they faced. Mia's career was taking off, and she found herself constantly on the road, filming in different locations and attending red carpet events.
"""
}
),
"queryStringParameters": {
"points": "3"
}
}
response = handler(event, {})
print(response)

summary.py
에서 handler
함수를 불러와 실행한 후, 긴 텍스트를 전달하여 요약을 요청합니다. 이때 "points": "3"
을 설정하면 Claude 모델이 3가지 요약 포인트를 생성하도록 요청하게 됩니다.
코드 실행 흐름은 다음과 같습니다. 먼저, 사용자가 event
객체에 긴 텍스트를 입력하면 handler()
함수가 호출되어 해당 텍스트가 Claude 모델로 전달됩니다. 이후, Claude 모델이 입력된 텍스트를 분석하여 요약을 생성하고, 결과를 JSON 형태로 반환하게 됩니다.
이제 AWS Lambda와 API Gateway에 배포하여 Serverless Summary API 로 활용 해보겠습니다.
4. AWS Lambda 배포 (Hands-on)






InvokeModel
) 허용 특정 모델이 아닌 모든 모델을 호출할 수 있는 정책을 허용해줍니다.{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:ap-northeast-2:[Account Number]:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-2:[Account Number]:log-group:/aws/lambda/py-text-funtuin:*"
]
},
{
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": "*"
}
]
}



{
"body": "{\"text\":\"Vincent was a jazzman, a saxophonist with a smooth, soulful sound that could melt the coldest of hearts. He had been playing the clubs and bars of the city for years, honing his craft and building a reputation as one of the best musicians in town. Mia was an actress, a rising star with a talent for drama and a fierce determination to succeed. She had been working non-stop for the past few years, taking on any role she could get, no matter how small, in order to make a name for herself in the competitive world of Hollywood. One night, Vincent and Mia crossed paths at a jazz club in the city. Vincent was playing a set with his band, and Mia was in the audience, sipping on a martini and enjoying the music. As soon as their eyes met, Vincent knew he was in trouble. Mia was the most beautiful woman he had ever seen, with piercing green eyes and long, curly hair that cascaded down her back like a golden waterfall. Despite the fact that Mia was a celebrity and Vincent was just a struggling musician, they quickly hit it off. They talked for hours after the show, exchanging stories and laughter, and before long, they were inseparable. As the weeks went by, Vincent and Mia found themselves spending more and more time together. They would go on long walks through the city, holding hands and talking about their dreams and aspirations. They would sit in Vincent's small apartment, listening to jazz records and drinking coffee until the early hours of the morning. Despite their differences - Vincent was a struggling artist, while Mia was a successful celebrity - they found a deep connection in their shared passion for their craft. They inspired each other to work harder and push themselves to be the best they could be. As the months passed, Vincent and Mia's relationship grew stronger. They began to talk about their future together, about the possibility of starting a family and building a life filled with love, laughter, and music. But as their love for each other grew, so did the challenges they faced. Mia's career was taking off, and she found herself constantly on the road, filming in different locations and attending red carpet events.\"}",
"queryStringParameters": {
"points": "3"
}
}
body
: 요약할 원본 텍스트를 포함합니다.
JSON 형식이지만 문자열("body": "{\"text\":\"...\"}"
)로 인코딩되어 있어, Lambda 내부에서 json.loads(event["body"])
를 통해 디코딩해야 합니다.queryStringParameters
points :
값으로 요약의 주요 포인트 개수를 지정합니다. 현재 "points": "3"
으로 설정되어 있어, 요약 시 3가지 핵심 내용을 추출하도록 요청됩니다. 이렇게 작성하고 TEST 버튼을 실행해보겠습니다.

5. API Gateway and Lambda Funtion 통합 (Hands-on)

5.1 API Gateway와 Lambda의 연결 흐름
AWS Lambda를 API Gateway와 통합하면 REST API 또는 HTTP API를 생성하여 클라이언트(웹, 모바일 앱 등)가 Lambda 함수를 호출할 수 있도록 합니다. 이 구조는 Serverless Architecture 에서 매우 유용하며, API를 통해 Lambda 함수를 쉽게 호출하고 응답을 받을 수 있습니다.
- 사용자 요청
클라이언트(브라우저, 앱, Postman 등)가 API Gateway의 엔드포인트로 HTTP 요청을 보냄 (POST /summary).
- API Gateway가 요청을 Lambda로 전달
API Gateway는 요청을 Lambda로 포워딩하고, 이벤트(JSON)를 Lambda에 전달.
- Lambda가 요청을 처리
Lambda 함수가 요청을 받아 Amazon Bedrock을 호출하고, 텍스트 요약을 생성.
결과(JSON)를 API Gateway로 반환.
- API Gateway가 클라이언트에 응답 반환
Lambda의 응답을 받아 HTTP Response(200 OK, JSON 데이터 포함)로 Client에 반환.
5.2 API Gateway 생성





1. Method Type 선택
-> POST Method → 클라이언트가 데이터를 전달할 때 사용됨.
2. Integration Type 선택 (Lambda Function)
-> Lambda Function을 선택하면 API Gateway가 요청을 AWS Lambda로 전달하여 실행.
-> Lambda 함수는 Serverless 방식으로 요청을 처리하고 응답을 반환.
3. Lambda Proxy Integration 활성화
-> Lambda Proxy Integration을 사용하면, API Gateway가 요청을 구조화된 이벤트(JSON 형식)로 Lambda에 전달.
-> 이점: API Gateway가 요청 본문(Body), HTTP 헤더, 경로 변수, 쿼리 매개변수 등을 Lambda에 그대로 전달. Lambda가 API Gateway에서 오는 원본 요청을 직접 처리 가능하고 응답도 API Gateway를 거치지 않고 Lambda에서 직접 HTTP 응답(JSON)을 구성.
4. Lambda Function 연결
-> 위에서 생성한 Lambda 함수 (py-text-funtuin) 선택됨. API Gateway가 Lambda를 호출할 수 있도록 권한(IAM Role) 자동 부여.
5. Integration Timeout 설정
-> 기본값 29,000ms (29초) → 요청이 너무 오래 걸리면 API Gateway에서 자동으로 중단.
위와 같이 선택하고 API Gateway를 생성합니다.




request.http
파일을 생성하여 API를 호출하는 예제입니다.POST https://0f75fti1oe.execute-api.ap-northeast-2.amazonaws.com/prod/text
Content-Type: application/json
{
"text": "Vincent was a jazzman, a saxophonist with a smooth, soulful sound that could melt the coldest of hearts..."
}

필드 | 설명 |
HTTP/1.1 200 OK | 요청이 정상적으로 처리되었음을 의미 |
summary | 요청한 텍스트의 요약 결과 |
x-amz-apigw-id | API Gateway가 요청을 추적하는 고유 ID |
X-Amzn-Trace-Id | AWS X-Ray에서 트레이싱을 위한 ID |
x-amzn-RequestId | Amazon API Gateway에서 할당한 요청 ID |
6. 결론
이 포스팅에서는 Lambda + API Gateway를 활용하여 Amazon Bedrock과 통신하는 API를 호출하는 과정을 살펴보았습니다.
Visual Studio Code에서 request.http
파일을 사용하여 쉽게 API 요청을 보낼 수 있으며, 응답을 통해 AI 모델이 생성한 요약 결과를 확인할 수 있었습니다.