2024년 10월 2일 AWS에서 Bedrock을 Seoul 리전에도 출시하였습니다.

이번 글에서는 Bedrock에서도 RAG의 기능을 보다 편리하게 사용할 수 있는 "Knowledge Bases(지식기반)" 서비스에 대해서 알아보고 Private하게 구성하는 방법에 대해서 설명합니다.
RAG?
RAG(Retrieval-Augmented Generation)는 대규모 언어 모델(LLM)의 응답을 향상시키기 위해, 모델이 원래 학습된 데이터 외부의 신뢰할 수 있는 지식 베이스를 참조하도록 하는 방식입니다. LLM은 방대한 양의 데이터와 수십억 개의 매개 변수를 활용해 질문에 대한 답변, 번역, 문장 완성 등 다양한 작업을 수행합니다. RAG를 사용하면 LLM의 성능을 특정 도메인 또는 조직의 내부 지식 기반으로 확장할 수 있어, 모델을 재학습하지 않고도 맞춤형 응답을 제공할 수 있습니다. 이 접근법은 비용 효율적이면서도 응답의 관련성, 정확성, 유용성을 크게 높여줍니다.
RAG가 없는 경우
LLM은 사용자 입력을 받아 학습된 정보만을 기반으로 응답을 생성합니다. 반면, RAG를 사용하면 사용자의 입력을 활용해 추가적인 외부 데이터 소스에서 필요한 정보를 검색하는 단계를 추가합니다. 사용자 쿼리와 검색된 관련 정보가 함께 LLM에 전달되므로, 기존 학습 데이터에 새로운 정보를 더하여 더욱 정확한 응답을 생성할 수 있습니다.
외부 데이터 활용
RAG에서 사용하는 외부 데이터는 LLM이 원래 학습한 데이터 세트 밖에 있는 정보입니다. 이러한 데이터는 API, 데이터베이스, 문서 리포지토리 등 다양한 소스에서 가져올 수 있으며, 파일, 데이터베이스 레코드, 긴 형식의 텍스트 등 여러 형식으로 존재합니다. 이를 효율적으로 활용하기 위해 임베딩 언어 모델을 사용하여 데이터를 벡터 형식으로 변환하고, 벡터 데이터베이스에 저장합니다. 이 과정을 통해 생성형 AI 모델이 이해할 수 있는 지식 라이브러리가 형성됩니다.
관련 정보 검색 단계
- 사용자 쿼리 벡터화: 사용자 입력을 벡터 표현으로 변환합니다.
- 벡터 매칭: 변환된 벡터를 벡터 데이터베이스와 비교하여 유사한 문서 또는 데이터를 검색합니다.
- 예를 들어, 회사의 스마트 챗봇이 "연차휴가는 얼마나 남았나요?"라는 질문에 대해 직원의 과거 휴가 기록과 회사 휴가 정책 문서를 검색해 가장 관련성 높은 정보를 제공합니다.
- 관련성은 수학적 벡터 계산을 통해 결정됩니다.
외부 데이터가 최신이 아닐 경우, 검색된 정보가 정확하지 않을 수 있습니다. 이를 방지하기 위해, 외부 데이터 소스는 주기적으로 업데이트하고, 임베딩 벡터도 최신 상태로 갱신합니다. 이 작업은 자동화된 실시간 프로세스 또는 주기적인 배치 처리를 통해 이루어질 수 있으며, 데이터의 최신성을 유지하는 것이 중요합니다.
RAG는 기존 LLM의 강력한 기능을 확장하여, 특정 도메인에 최적화된 응답을 제공함으로써 비즈니스 요구 사항을 충족시키는 강력한 도구입니다. 이를 통해 모델 재학습 없이도 효율적이고 비용 절감된 방식으로 고품질의 응답을 생성할 수 있습니다.
다음 다이어그램은 RAG와 LLM의 통합 과정을 시각적으로 설명합니다.
(그림 출처 : https://aws.amazon.com/ko/what-is/retrieval-augmented-generation/)
이러한 일련의 과정을 거쳐서 RAG가 적용된 Bedrock을 사용할 수 있게 되는데, 그만큼 관리/설정을 해야하는 항목이 많아집니다.
그렇기에 AWS에서는 Bedrock에서 완전관리형 RAG인 Knowledge Bases(지식기반) 서비스를 제공합니다.
Bedrock Knowledge Bases(지식기반)
AWS Bedrock Knowledge Bases는 AWS에서 제공하는 완전 관리형 기능으로, 대규모 언어 모델(LLM)과 외부 데이터 소스를 결합하여 더 정교한 응답을 생성할 수 있도록 지원합니다. Bedrock Knowledge Bases를 사용하면 별도의 복잡한 인프라 구축 없이도 특정 도메인에 최적화된 RAG(Retrieval-Augmented Generation) 기능을 손쉽게 구현할 수 있습니다.
이 기능은 사용자가 자신만의 문서, 데이터베이스, FAQ, 정책 문서 등의 다양한 정보 소스를 업로드하여 LLM이 이를 참조할 수 있도록 합니다. 이를 통해, LLM이 기존 학습 데이터에만 의존하지 않고도 조직의 내부 정보와 외부 데이터까지 활용하여 더 정확하고 맞춤형 응답을 제공할 수 있습니다.
AWS Bedrock Knowledge Bases의 주요 기능 및 장점
-
손쉬운 데이터 통합
- JSON, CSV, PDF 등 다양한 형식의 데이터를 Knowledge Bases에 업로드할 수 있습니다.
- 사전 학습된 LLM에 데이터를 추가로 학습시키지 않고도, 업로드된 문서를 즉시 활용할 수 있어 빠른 적용이 가능합니다.
-
자동 벡터 인덱싱 및 검색 최적화
- 업로드된 문서들은 자동으로 임베딩되어 벡터 형식으로 저장됩니다.
- LLM은 사용자의 쿼리를 벡터화한 후, Knowledge Bases의 벡터 데이터와 비교하여 가장 관련성 높은 정보를 신속하게 검색합니다.
- 이 과정을 통해, LLM이 단순한 질문에 대해 더 정확하고 컨텍스트가 풍부한 답변을 생성합니다.
-
확장 가능한 RAG 아키텍처
- Bedrock Knowledge Bases는 기존 RAG 아키텍처의 복잡성을 대폭 줄여줍니다. 별도의 벡터 데이터베이스나 검색 엔진 설정 없이도, AWS에서 제공하는 관리형 환경 내에서 RAG 기능을 활용할 수 있습니다.
- 조직의 내부 정보와 외부 데이터가 LLM 응답에 포함되므로, 특정 도메인 지식에 최적화된 맞춤형 답변이 가능합니다.
-
보안 및 프라이버시 강화
- AWS의 보안 기능을 활용하여 Knowledge Bases에 저장된 데이터에 대한 암호화와 액세스 제어를 설정할 수 있습니다.
- 기업 내부의 민감한 데이터도 안전하게 관리할 수 있어, 데이터 유출 위험을 최소화합니다.
-
빠른 시간 내에 높은 정확도의 응답 생성
- LLM 프롬프트를 Knowledge Bases에서 검색한 관련 정보로 보강하여, 사용자의 질문에 대한 응답을 최적화합니다.
- 이를 통해, 고객 지원, 내부 직원 질의 응답, 기술 문서 참조 등의 다양한 비즈니스 시나리오에서 정확도 높은 답변을 빠르게 생성할 수 있습니다.
-
비용 효율성
- Knowledge Bases 기능을 활용하면 별도의 외부 솔루션 없이도 자체 데이터와 LLM을 결합한 RAG 아키텍처를 구현할 수 있어 비용을 절감할 수 있습니다.
- 모델 재훈련이 필요 없기 때문에 추가적인 컴퓨팅 리소스를 절약할 수 있습니다.
Bedrock, RAG에 대한 간단하게 알아보았으며, 아래에서 부터는 Bedrock의 Knowledge Bases를 구현해보고, Private은 어떻게 추가적으로 구현을 하는지 알아보도록 하겠습니다.
Bedrock Knowledge Bases 구현하기
시나리오는 2개로 진행하도록 하겠습니다.
시나리오1 : Lambda를 통해 Bedrock Knowledge Bases(지식기반)을 호출하여 RAG가 정상 동작하는지 확인
시나리오2 : 시나리오1에 Private한 구성으로 정상 동작하는지 확인
시나리오1

아키텍처는 위와 같습니다.
Private에 대한 접근 제한을 하지 않은 상태로 Knowledge Bases의 기능을 확인할 수 있도록 아래와 같이 구성해보도록 하겠습니다.
1. S3 생성
Bedrock Knowledge Bases를 사용하기 위한 데이터 소스로 S3를 구성하도록 하겠습니다.- Bedrock의 리전과 동일한 위치의 S3만 연결이 가능합니다.
- 서울 리전 기준으로 S3를 제외한 아래 항목들은 Preview로만 제공됩니다.
- 웹 크롤러, Conluence, Salesforce, Sharepoint


2. Bedrock 호출을 위한 Lambda 생성
Lambda에서 Bedrock 호출시 사용할 언어가 Python이므로 런타임도 동일하게 설정하여 구성합니다.

Lambda 설정에서 변경해야될 사항은 아래와 같습니다.
- 기본적으로 실행의 제한시간이 3초로 되어있고, Bedrock을 호출해서 응답을 얻기에는 평균적으로 부족한 시간입니다.(Sonnet 3.5 기준)
- 아래와 같이 3->15초로 변경합니다.

Lambda에 사용된 코드 및 변경해야될 부분은 아래와 같습니다.
- knowledgeBaseId는 추후 생성하는 Bedrock Knowledge Bases의 ID로 변경해야 합니다.
- modelArn은 Genearte에 사용되는 모델로 필요하다면 변경하여 사용할 수 있습니다.(지원되는 모델중에서만 가능합니다.)
import boto3
import json
def lambda_handler(event, context):
client = boto3.client('bedrock-agent-runtime', region_name='ap-northeast-2')
input_data = {
'input': {
'text': event['query']
},
'retrieveAndGenerateConfiguration': {
'knowledgeBaseConfiguration': {
'knowledgeBaseId': '변경필요',
'modelArn': 'arn:aws:bedrock:ap-northeast-2::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0'
},
'type': 'KNOWLEDGE_BASE'
}
}
print(input_data)
response = client.retrieve_and_generate(**input_data)
return response
또한 Lambda의 권한의 설정을 해야합니다.
- AWSLambdaVPCAccessExecutionRole : 시나리오 2에서 VPC에 통합하기 위한 권한
- AmazonBedrockFullAccess : Bedrock 호출을 위한 권한

3. Bedrock 생성
현재 서울 리전에서는 아래와 같은 모델만 사용 가능하며 엑세스를 활성화 하도록 합니다.

아래와 같이 생성을 진행합니다.
위에서 언급한것 처럼 데이터 소스는 현재 정식으로 지원하는것은 S3만 있으며, 그외 나머지는 Preview입니다.


데이터 소스는 S3이므로 RAG로써 사용할 S3를 선택하고 그외의 설정은 기본으로 진행합니다.
임베딩 모델 / 벡터 데이터베이스 선택에서는 현재 서울 리전 기준으로는 임베딩 모델은 Amazon의 Titan만 지원합니다.
벡터 데이터베이스는 빠른 저장소 생성시에는 기본적으로 OpenSearch Serveless로 선택 및 생성됩니다.


다른 것을 사용하고자 하면 아래의 선택지가 있으며, 사전에 생성을 해두어야 연결을 할 수 있습니다.

아래와 같이 생성이 완료되면 지식 기반ID를 확인 할 수 있으며, 해당 ID는 Lambda의 코드에 업데이트 합니다.
또한, RAG로 기능을 확인하기 위한 데이터를 S3에 넣어두었다면, 데이터 소스의 "동기화"를 클릭합니다.

4. 기능 확인하기
인천메트로서비스 임직원 행동강령이라는 데이터를 기준으로 기능을 확인해보겠습니다.

- 일반 Bedrock의 Claude 3.5 Sonnet을 이용해 질문했을때는 아래와 같습니다.

- Bedorck의 Knowledge Bases에서 동일한 모델(Claude 3.5 Sonnet)을 이용해 질문했을때는 아래와 같습니다.

- 동일한 질문을 하더라도 Bedrock의 Knowledge Bases는 현재 연결된 내 데이터에서 답변을 합니다.
- 또한, 해당 데이터가 어디서 온것인지에 대해 문서 및 청크를 제공합니다.
- Lambda에서는 아래와 같이 테스트 할 수 있습니다.

- 당연히 Bedrock Console에서 보이는것과 동일하게 Response를 확인 할 수 있습니다.

여기까지는 이 모든 자원들이 Public하게 서로 호출/연결되며 사용되는 것으로 실제기업에서는 사용하지 못할 가능성이 높습니다.
RAG를 사용하고자 하는 기업은 통상적으로 내부 데이터를 활용하기 떄문에 Public하게 누구나 접근할 수 있는 환경을 원하지 않기 떄문입니다.
아래 시나리오2는 위 구성에서 Private하게 구성하는 것을 알아보도록 하겠습니다.
시나리오2
시나리오2의 아키텍처는 아래와 같습니다.- Lambda는 VPC에 통합
- OpenSearch Serverless의 엑세스 유형을 Private으로 변경
- Bedrock은 Enpoint를 통해 호출되도록 설정
- S3는 Public Access의 접근을 제한(시나리오1에서 이미 설정 완료)

Private한 환경으로 구성하기 위해서는 아래 순서로 진행합니다.
1. VPC/ Subnet / SG 생성
VPC만 생성하면되며, 이름, IP는 임의로 지정합니다.

Endpoint를 사용하기 위해서는 아래와 같은 추가 설정이 필요합니다.

"DNS 호스트 이름 활성화" 를 활성화 하고 저장합니다.

해당 기능을 활성화하지 않고 Endpoint를 생성할 경우 아래와 같은 에러메시지를 확인할 수 있습니다.

사용할 Subnet은 아래와 같이 생성하며, 가용영역을 지정합니다.

Security Group은 인바운드에 대해서 443을 0.0.0.0/0으로 오픈하여 생성합니다.
Bedrock에 대한 호출은 HTTPS로 통신하기 때문에 443입니다.

2. Endpoint 생성
Bedrock Endpoint 생성시에는 총 4가지가 보여지며 각각 Action이 다르기 때문에 아래 내용 / 링크를 참고하면 됩니다.
bedrock
– 모델을 관리, 훈련 및 배포하기 위한 제어 평면 API를 포함합니다.bedrock-runtime
– Amazon Bedrock에 호스팅된 모델에 대한 추론 요청을 만드는 데이터 플레인 API를 포함합니다.bedrock-agent
– 에이전트, 지식 기반, 프롬프트 관리 및 프롬프트 흐름을 만들고 관리하기 위한 제어 평면 API를 포함합니다.bedrock-agent-runtime
– 에이전트 및 흐름을 호출하고 지식 기반을 쿼리하기 위한 데이터 플레인 API를 포함합니다.
이번 시나리오에서는 Knowledge Bases만 사용하므로 "agent-runtime"만 생성합니다.

생성해둔 VPC, Subnet, SG를 각각 지정하여 생성합니다.

3. OpenSearch Serverless 설정
Bedrock Knowledge Bases를 생성할때 기본적으로 선택된 OpenSearch Serverless가 생성된 곳에 가면, 네트워크 정책이 있습니다.
이 기능의 설정을 수정하여 Pubilc -> Private로 엑세스 유형을 변경할 수 있습니다.

엑세스 유형 -> Private에서 "AWS service Private access"를 선택하고, 서비스 유형을 아래와 같이 입력합니다.

4. Lambda VPC 연결
아래와 같이 Lambda를 기존에 만들어준 VPC, Subnet, SG를 선택하여 연결합니다.

5. Private 정상 동작 확인
- Lambda에서 테스트를 수행하면 기존과 동일하게 정상적인 동작을 하는 것을 확인 할 수 있습니다.

- Private 통신을 임의로 방해하도록 SG에 Port를 HTTPS(443) -> HTTP(80)으로 변경하면 아래와 같이 Lambda에서 Timeout이 발생하는 것을 확인 할 수 있습니다.


결론
- AWS Bedrock이 서울리전을 지원하게 되어 리전간 자원을 구성할 필요가 없어졌습니다.
- AWS Bedrock의 Knowledge Bases는 RAG를 보다 편리하게 구성하도록 제공되는 기능입니다.
- 다만, 현재 Embedding, Generate 하기 위한 제공되는 Model은 제한적입니다.
- 완벽한 Private구성이라고 할수는 없다고 생각합니다.
- Bedrock에서 S3를 Endpoint를 통해서 접근하는 것은 아닙니다.
- 전문가(AWS) 답변을 통해서 해당 구간은 AWS 내부(백본) 통신임을 확인하였습니다.