
안녕하세요! 오늘은 AWS Amazon Bedrock의 Knowledge Base와 RAG(Retrieval-Augmented Generation) 기술을 활용해서 코드 스타일 검사와 보안 취약점 탐지를 자동화하는 시스템을 구축해보겠습니다. GitHub PR 자동 리뷰 Agent의 핵심 기능을 직접 만들어보는 실습입니다.
전체 아키텍처를 간단히 설명하면 이렇습니다. S3에 PEP8 스타일 가이드와 OWASP 보안 문서를 저장해두고, Bedrock Knowledge Base가 이 문서들을 벡터로 인덱싱합니다. 코드를 검사할 때 RetrieveAndGenerate API가 관련 문서를 검색해서 Claude에게 컨텍스트로 제공하고, Claude가 그 기준에 맞춰 코드를 리뷰하는 구조입니다.

Bedrock Knowledge Base는 RAG 파이프라인 전체를 완전 관리형으로 제공하는 AWS 서비스입니다. 데이터 수집, 청킹, 임베딩 변환, 벡터 저장, 검색, 응답 생성까지의 과정을 직접 구현할 필요 없이 데이터 소스 연결만으로 구성할 수 있습니다.
주요 기능
- 관련 정보 검색: 데이터 소스에서 사용자 질문과 관련된 정보를 찾아 반환
- 정확한 응답 생성: 검색된 정보를 바탕으로 관련성 높은 답변 생성
- 프롬프트 보강: 검색된 정보를 프롬프트에 자동으로 추가
- 출처 인용 포함: 응답에 원본 소스 참조를 포함해 할루시네이션 최소화
- 이미지 검색: 문서 내 이미지도 쿼리 결과로 추출 가능
동작 방식
- 데이터 위치를 지정 (S3 등)
- 임베딩 모델 선택
- Bedrock이 데이터를 벡터 임베딩으로 변환하여 벡터 저장소에 저장
- 이후 쿼리가 들어오면 벡터 검색으로 관련 정보를 찾아 LLM에 전달
Bedrock Agents와의 연동
Knowledge Base는 Bedrock Agents에 연결할 수 있어, 에이전트가 사용자 입력에 따라 관련 정보를 자동으로 식별하고 검색하도록 만들 수 있습니다.
RAG (Retrieval Augmented Generation)
- RAG는 LLM이 응답을 생성할 때, 외부 데이터 소스에서 관련 정보를 검색해 컨텍스트로 함께 제공하는 아키텍처 패턴입니다.
- LLM은 학습 시점의 데이터만 알고 있기 때문에, 학습 이후에 생성된 정보나 학습 데이터에 포함되지 않은 도메인 특화 정보(사내 문서, 제품 DB 등)는 답변할 수 없습니다. RAG는 이 한계를 모델 재학습 없이 해결합니다.
동작 순서
1. 사용자 질문을 벡터로 변환
2. 벡터 DB에서 유사도가 높은 문서 청크를 검색
3. 검색된 문서를 원래 질문과 함께 LLM에 전달
4. LLM이 제공된 컨텍스트를 바탕으로 응답 생성
파인튜닝과의 차이점은, 파인튜닝은 모델 가중치 자체를 변경하는 반면 RAG는 모델을 그대로 두고 추론 시점에 외부 지식을 주입한다는 점입니다. 데이터가 자주 변경되거나 출처 추적이 필요한 경우 RAG가 더 적합합니다.
1단계. IAM 유저 생성 및 액세스 키 발급
먼저 AWS 콘솔에서 Bedrock과 S3에 접근할 수 있는 IAM 유저를 만들어야 합니다.
AWS 콘솔에 루트 계정으로 로그인한 후, 검색창에 IAM을 입력해서 이동합니다. 왼쪽 사이드바에서 사용자를 클릭하고 사용자 생성 버튼을 누릅니다.

사용자 이름은 bedrocktry 처럼 알아보기 쉽게 설정합니다. AWS Management Console 액세스는 이번 실습에서는 체크하지 않아도 됩니다. 프로그래밍 방식 액세스만 사용할 것이기 때문입니다.
권한 설정 단계에서 직접 정책 연결을 선택하고 아래 두 가지 정책을 추가합니다.
- AmazonBedrockFullAccess
- AmazonS3FullAccess

실제 운영 환경이라면 최소 권한 원칙에 따라 더 세밀하게 설정해야 하지만, 실습 목적이므로 위 두 정책으로 진행합니다.
사용자 생성이 완료되면 해당 유저를 클릭하고 보안 자격 증명 탭으로 이동합니다. 액세스 키 만들기를 클릭하고, 사용 사례는 로컬 코드로 선택합니다. 생성된 액세스 키 ID와 시크릿 액세스 키를 반드시 안전한 곳에 저장해두세요. 시크릿 키는 이 화면을 벗어나면 다시 확인할 수 없습니다.
발급받은 키는 로컬 환경에서 아래와 같이 설정합니다.


발급받은 키는 실습 환경에서 아래와 같이 설정합니다.


2단계. Amazon Bedrock에서 Claude Sonnet 4.6 모델 연동
AWS 콘솔에서 Amazon Bedrock으로 이동합니다. 리전이 아시아 태평양(서울), ap-northeast-2로 설정되어 있는지 꼭 확인하세요.

왼쪽 메뉴에서 Model Catalog를 클릭합니다. 검색창에 Claude를 입력하면 Anthropic의 모델 목록이 나타납니다. Claude Sonnet 4.6을 찾아서 액세스 요청을 클릭합니다.


3단계. S3 버킷 생성 및 가이드 문서 업로드
Knowledge Base가 참고할 문서들을 S3에 저장할 버킷을 만들겠습니다
# AWS CLI로 생성 (또는 콘솔에서)
!aws s3 mb s3://kb-docs-bucket-2026 --region ap-northeast-2
# 폴더 구조 생성
!aws s3api put-object --bucket kb-docs-bucket-2026 --key style-guides/
!aws s3api put-object --bucket kb-docs-bucket-2026 --key security/
!aws s3api put-object --bucket kb-docs-bucket-2026 --key frameworks/
colab 에서 아래의 코드를 이용해서 S3 버킷을 생성합니다.

버킷 생성 후 폴더 구조를 만듭니다. 폴더 만들기 버튼으로 style-guides와 security 폴더를 생성합니다.
%%bash
cat << EOF > pep8.txt
PEP 8 - Python Code Style Guide
## Naming Conventions
- 변수명: snake_case 사용 (예: user_name, total_count)
- 함수명: snake_case 사용 (예: calculate_total, get_user_data)
- 클래스명: PascalCase 사용 (예: UserProfile, DataProcessor)
- 상수명: UPPER_SNAKE_CASE 사용 (예: MAX_RETRIES, DEFAULT_TIMEOUT)
## Indentation
- 4 spaces per indentation level (tab 사용 금지)
## Line Length
- 최대 79 characters
- 주석/문서열은 72 characters
EOF
%%bash
cat << EOF > owasp-top10.txt
OWASP Top 10 - Web Application Security Risks
## A01:2021 - Broken Access Control
- 사용자의 권한이 적절하게 관리되지 않아 비인가된 접근이 허용되는 문제.
## A02:2021 - Cryptographic Failures
- 민감한 데이터의 암호화가 부적절하거나 누락되어 데이터 유출로 이어지는 문제.
## A03:2021 - Injection
- SQL, NoSQL, OS 명령어 등 신뢰할 수 없는 데이터가 쿼리나 명령의 일부로 해석되어 실행되는 문제.
## A04:2021 - Insecure Design
- 보안 통제를 적절하게 구현하지 못하여 설계 단계에서부터 보안 취약점이 발생하는 문제.
## A05:2021 - Security Misconfiguration
- 보안 설정이 미흡하거나 기본 설정이 그대로 사용되어 취약점이 노출되는 문제.
## A06:2021 - Vulnerable and Outdated Components
- 알려진 취약점을 가진 오래된 라이브러리나 컴포넌트를 사용하여 발생하는 문제.
## A07:2021 - Identification and Authentication Failures
- 사용자 인증 또는 세션 관리 기능이 제대로 구현되지 않아 계정 탈취가 가능한 문제.
## A08:2021 - Software and Data Integrity Failures
- 소프트웨어 업데이트, 중요한 데이터, CI/CD 파이프라인 등의 무결성 검증이 부족하여 발생하는 문제.
## A09:2021 - Security Logging and Monitoring Failures
- 보안 이벤트 로깅 및 모니터링이 부적절하여 침해 사고 발생 시 탐지 및 대응이 어려운 문제.
## A10:2021 - Server-Side Request Forgery (SSRF)
- 공격자가 서버 측에서 임의의 URL로 요청을 보내 내부 시스템에 접근하거나 정보를 탈취하는 문제.
EOF
# 문서 업로드
!aws s3 cp pep8.txt s3://kb-docs-bucket-2026/style-guides/
!aws s3 cp owasp-top10.txt s3://kb-docs-bucket-2026/security/
샘플 문서를 작성한 후에 생성해둔 폴더에 맞게 업로드합니다.
4단계. Bedrock Knowledge Base 생성
Bedrock Knowledge Base는 RAG 파이프라인 전체를 완전 관리형으로 제공하는 AWS 서비스입니다. 데이터 수집, 청킹, 임베딩 변환, 벡터 저장, 검색, 응답 생성까지의 과정을 직접 구현할 필요 없이 데이터 소스 연결만으로 구성할 수 있습니다.
- 지원하는 데이터 소스로는 Amazon S3, Confluence, Salesforce, SharePoint, OneDrive, Web Crawler 등이 있습니다.
- 지원하는 벡터 DB로는 Amazon OpenSearch Serverless, Aurora, Neptune Analytics, MongoDB, Pinecone, Redis Enterprise Cloud, 그리고 2025년 말에 추가된 Amazon S3 Vectors가 있습니다. S3 Vectors는 기존 벡터 DB 대비 최대 90% 비용 절감이 가능한 옵션입니다.
- 제공하는 주요 API는 두 가지입니다.
- RetrieveAndGenerate: 검색과 응답 생성을 한 번에 처리
- Retrieve: 관련 문서 검색만 수행, 응답 생성은 별도로 처
Amazon Bedrock 콘솔로 돌아와서 왼쪽 메뉴의 지식 기반(Knowledge Bases)을 클릭하고 지식 기반 생성을 선택합니다.
지식 기반 이름은 자동으로 생성한 이름으로 하고, IAM 권한은 새 서비스 역할 생성으로 두면 Bedrock이 필요한 권한을 자동으로 설정해줍니다.



데이터 소스 설정에서는 Amazon S3를 선택하고, 'S3 찾아보기'에서 아까 만든 버킷을 선택합니다.
- S3 URI: s3://kb-docs-bucket-2026

임베딩 모델은 Titan Embeddings V2를 선택합니다.
Titan Embedding
Amazon Titan Embedding은 AWS에서 제공하는 텍스트 임베딩 모델입니다. 텍스트를 고차원 벡터 공간의 숫자 배열로 변환하며, 의미적으로 유사한 텍스트는 벡터 공간에서 가까운 위치에 매핑됩니다.
임베딩 모델의 역할은 두 가지입니다.
- 인덱싱 시점: 문서를 청크 단위로 나눠 각 청크를 벡터로 변환 후 벡터 DB에 저장
- 검색 시점: 사용자 질문을 벡터로 변환 후, 저장된 벡터들과 코사인 유사도 등으로 비교
Titan Embedding은 다국어를 지원하며, Bedrock Knowledge Base와 네이티브로 통합되어 별도 설정 없이 사용할 수 있습니다. 현재 amazon.titan-embed-text-v2 버전은 최대 8,192 토큰 입력을 지원하고, 256 / 512 / 1,024 차원의 벡터를 출력할 수 있습니다.
벡터 스토어는 S3 vector bucket을 선택합니다. Knowledge Base 생성 시 벡터 스토어로 S3 vector bucket을 선택하면 두 가지 방식 중 하나를 고를 수 있습니다. Quick create a new vector store를 선택하면 Amazon Bedrock이 S3 vector bucket과 vector index를 자동으로 생성하고 필요한 설정을 구성해줍니다. 실습에서는 Quick create a new vector store로 진행하면 가장 간편합니다
Amazon S3 Vectors는 비용 효율적인 벡터 스토리지를 제공하며, 대규모 벡터 데이터셋을 내구성 있고 탄력적으로 저장하면서 서브세컨드 쿼리 성능을 지원합니다. OpenSearch Serverless 대비 스토리지 비용을 크게 줄일 수 있어 실습이나 소규모 프로젝트에 적합한 선택입니다.
생성 완료 후 Knowledge Base ID를 꼭 복사해두세요. 10자리 영숫자 조합(예: ABC123DEFG)으로 생성되며, 이후 코드에서 반드시 필요합니다.
생성이 완료되면 데이터 소스 동기화를 해줘야 합니다. Knowledge Base 상세 페이지에서 데이터 소스를 선택하고 동기화 버튼을 클릭합니다. Amazon Bedrock이 S3 데이터 소스에서 데이터를 자동으로 가져오고, 콘텐츠를 텍스트 블록으로 변환한 뒤 임베딩을 생성해 S3 vector index에 저장합니다. 완료까지 1~2분 정도 소요됩니다.
4단계. AWS 지식 기반(Knowledge Base) 연동 스타일 및 보안 검사 코드 작성
코드 스타일 검사 (PEP8 가이드라인 기반)
import boto3
def style_check(code, kb_id):
"""코드 스타일 검사 후 위반 사항 리스트 반환"""
# Ensure bedrock-agent-runtime client is used
bedrock_agent_client_for_rag = boto3.client('bedrock-agent-runtime', region_name='ap-northeast-2')
prompt = f"""
당신은 코드 스타일 검사기입니다. 다음 코드에서 PEP8 또는 일반적인 스타일 규칙을 위반한 부분을 찾아주세요.
형식:
- [라인번호] 위반 유형: 설명
코드:
{code}
"""
response = bedrock_agent_client_for_rag.retrieve_and_generate(
input={'text': prompt},
retrieveAndGenerateConfiguration={
'type': 'KNOWLEDGE_BASE',
'knowledgeBaseConfiguration': {
'knowledgeBaseId': kb_id,
'modelArn': 'global.anthropic.claude-sonnet-4-6'
}
}
)
# 1. 여기서 return을 하면서 함수가 깔끔하게 끝납니다.
return response['output']['text']
# ========================================================
# 2. 실행 테스트 영역 (들여쓰기를 모두 맨 앞으로 당겼습니다!)
# ========================================================
# 단일 코드 테스트
bad_code = """
def Sum(a,b):
return a+b
"""
print("=== 단일 bad_code 테스트 결과 ===")
print(style_check(bad_code, kb_id))
print("-" * 40)
# 샘플 리스트 다중 테스트 수행
samples = [
"""def add(a,b): return a+b""", # 한 줄에 여러 구문
"""def GetUserData(): pass""", # 함수명 대문자 시작
"""import os,sys""", # 여러 import 한 줄에
"""x = 1\ny = 2\nz=x+y""", # 공백 부족
"""def long_function_name_very_long_parameter_list(param1, param2, param3, param4, param5): pass"""
]
print("=== 여러 샘플 코드 순회 검사 시작 ===")
for i, sample_code in enumerate(samples, 1):
print(f"\n[샘플 {i}] 검사할 코드: {sample_code}")
try:
result = style_check(sample_code, kb_id)
print(f"결과:\n{result}")
except Exception as e:
print(f"❌ 샘플 {i} 검사 중 에러 발생: {e}")
print("=" * 30)
보안 취약점 검사 코드 (OWASP Top 10 기반)
import boto3
def check_security(code, kb_id):
"""보안 취약점 검사"""
# Explicitly create a bedrock-agent-runtime client for retrieve_and_generate
bedrock_agent_client = boto3.client('bedrock-agent-runtime', region_name='ap-northeast-2')
response = bedrock_agent_client.retrieve_and_generate(
input={'text': f"""
다음 코드에서 보안 취약점을 찾아주세요. 특히 SQL Injection, XSS, 하드코딩된 비밀번호를 중점적으로 검사해주세요.
코드:
{code}
취약점이 있으면 위치, 유형, 심각도, 수정 제안을 포함해 주세요.
"""},
retrieveAndGenerateConfiguration={
'type': 'KNOWLEDGE_BASE',
'knowledgeBaseConfiguration': {
'knowledgeBaseId': kb_id,
'modelArn': 'global.anthropic.claude-sonnet-4-6'
}
}
)
return response['output']['text']
# ========================================================
# 수정 구간: 들여쓰기를 맨 앞으로 맞추고 끊긴 문자열을 닫아줬습니다.
# ========================================================
# 취약한 코드 테스트
vulnerable_code = """
def get_user_by_name(username):
query = "SELECT * FROM users WHERE name = '" + username + "'"
""" # 👈 닫는 따옴표 추가
# 결과 출력 추가
print(check_security(vulnerable_code, kb_id))
import boto3
def generate_security_report(code, kb_id):
"""보안 취약점 리포트 (JSON 형식) 생성"""
# Explicitly create a bedrock-agent-runtime client for retrieve_and_generate
bedrock_agent_client = boto3.client('bedrock-agent-runtime', region_name='ap-northeast-2')
response = bedrock_agent_client.retrieve_and_generate(
input={'text': f"""
다음 코드의 보안 취약점을 분석하고 JSON 형식으로 보고서를 작성해주세요.
형식:
{{
"vulnerabilities": [
{{
"line": 라인번호,
"type": "취약점 유형",
"severity": "CRITICAL/HIGH/MEDIUM/LOW",
"description": "설명",
"suggestion": "수정 제안"
}}
],
"summary": "전체 평가"
}}
코드:
{code}
"""},
retrieveAndGenerateConfiguration={
'type': 'KNOWLEDGE_BASE',
'knowledgeBaseConfiguration': {
'knowledgeBaseId': kb_id,
'modelArn': 'global.anthropic.claude-sonnet-4-6'
}
}
)
return response['output']['text']
# ========================================================
# 수정 및 추가 구간: 들여쓰기를 맞추고, vulnerable_code를 정의했습니다.
# ========================================================
# 테스트용 취약한 샘플 코드 정의 (앞 단계에서 썼던 코드 활용)
vulnerable_code = """
def get_user_by_name(username):
query = "SELECT * FROM users WHERE name = '" + username + "'"
return query
"""
# 결과를 파일로 저장
report = generate_security_report(vulnerable_code, kb_id)
with open('security_report.json', 'w', encoding='utf-8') as f:
f.write(report)
print("✅ 리포트 저장 완료: security_report.json")
'Concepts > Cloud Infra' 카테고리의 다른 글
| Amazon Bedrock Agent를 활용한 AI 에이전트 구축 (0) | 2026.05.25 |
|---|---|
| Amazon Bedrock으로 AI 코드 리뷰어 만들기: LLM 호출부터 RAG까지 완전 정복 (0) | 2026.05.24 |
| AWS 기초개념 : 가상화&EC2 (0) | 2026.05.19 |
| AWS 구성 및 IAM (0) | 2026.05.18 |
| 클라우드 컴퓨팅 (0) | 2026.05.13 |