🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

AWS Bedrock 하이브리드 검색 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 18. · 5 Views

AWS Bedrock 하이브리드 검색 완벽 가이드

AWS Bedrock의 하이브리드 검색을 활용하여 키워드 검색과 시맨틱 검색의 장점을 결합하는 방법을 배웁니다. 검색 가중치 조정부터 최적 설정 찾기까지 실무에 바로 적용할 수 있는 내용을 담았습니다.


목차

  1. 키워드_vs_시맨틱_검색
  2. 하이브리드_검색_장점
  3. Bedrock_하이브리드_검색_설정
  4. 검색_가중치_조정
  5. 검색_결과_품질_비교
  6. 최적_설정_찾기

1. 키워드 vs 시맨틱 검색

어느 날 김개발 씨가 회사에서 검색 기능을 개선하라는 업무를 받았습니다. 기존 키워드 검색은 정확한 단어를 입력해야만 결과가 나왔고, 사용자들은 불편해했습니다.

"더 똑똑한 검색이 필요해요"라는 팀장님의 한 마디에 김개발 씨는 고민에 빠졌습니다.

키워드 검색은 입력한 단어를 정확히 찾는 방식이고, 시맨틱 검색은 의미를 이해해서 찾는 방식입니다. 마치 사전에서 단어를 찾는 것과 사람에게 질문하는 것의 차이와 같습니다.

두 방식은 각각 장단점이 있어서 어느 하나만으로는 완벽한 검색을 제공하기 어렵습니다.

다음 코드를 살펴봅시다.

# 키워드 검색 예제
keyword_query = "AWS Lambda 함수"
# 정확히 'Lambda'라는 단어가 있는 문서만 검색됩니다

# 시맨틱 검색 예제
semantic_query = "서버리스 컴퓨팅 서비스"
# 'Lambda'라는 단어가 없어도 의미상 관련된 문서를 찾습니다

# 키워드는 정확하지만 융통성이 없고
# 시맨틱은 유연하지만 때로 부정확합니다

김개발 씨는 회사 문서 검색 시스템의 개선을 맡았습니다. 사용자들은 "Lambda 함수 타임아웃"을 검색하면 결과가 잘 나오지만, "서버리스 함수가 멈추는 문제"라고 검색하면 아무것도 찾지 못한다고 불평했습니다.

이상하게 생각한 김개발 씨는 선배 개발자 박시니어 씨를 찾아갔습니다. "선배님, 왜 이런 일이 생기는 걸까요?" 박시니어 씨가 웃으며 말했습니다.

"그건 지금 키워드 검색만 사용하고 있기 때문이야. 키워드 검색과 시맨틱 검색의 차이를 알아야 해." 키워드 검색이란 무엇일까요?

쉽게 비유하자면, 키워드 검색은 마치 사전에서 단어를 찾는 것과 같습니다. "사과"라는 단어를 찾으면 정확히 "사과"가 적힌 페이지만 보여줍니다.

"빨간 과일"이라고 찾으면 아무것도 찾지 못합니다. 이처럼 키워드 검색은 입력한 단어와 정확히 일치하는 문서를 찾는 방식입니다.

반면 시맨틱 검색은 어떨까요? 시맨틱 검색은 마치 도서관 사서에게 질문하는 것과 같습니다.

"요리 관련 책 있나요?"라고 물으면 사서는 "레시피", "음식", "조리법" 같은 단어가 포함된 책들을 모두 찾아줍니다. 정확한 단어가 아니어도 의미를 이해해서 관련된 내용을 찾아주는 것입니다.

키워드 검색만 사용하던 시절에는 어땠을까요? 사용자들은 정확한 전문 용어를 알아야만 원하는 정보를 찾을 수 있었습니다.

"Lambda"를 모르는 사람은 "서버리스 함수"라고 검색해도 아무것도 찾지 못했습니다. 더 큰 문제는 동의어나 유사 표현을 처리할 수 없다는 것이었습니다.

같은 의미인데 다른 단어를 사용하면 검색 결과가 완전히 달라졌습니다. 그래서 시맨틱 검색이 등장했습니다.

딥러닝 기술을 활용해서 문장의 의미를 이해하고, 비슷한 의미를 가진 문서를 찾아주는 방식입니다. 하지만 시맨틱 검색에도 약점이 있습니다.

박시니어 씨가 설명을 이어갔습니다. "시맨틱 검색은 의미를 이해하는 건 좋은데, 때로는 너무 광범위한 결과를 가져와.

'Python 3.9'를 찾는데 'Python 2.7' 문서까지 가져오는 경우가 있지." 김개발 씨는 고개를 끄덕였습니다. "그럼 키워드 검색은 정확하지만 융통성이 없고, 시맨틱 검색은 유연하지만 때로 부정확하다는 말씀이시네요." "정확해!

그래서 실무에서는 두 방식을 함께 사용하는 하이브리드 검색을 많이 쓴단다." 실제 현업에서는 어떻게 활용할까요? 예를 들어 기술 문서 검색 시스템을 만든다고 가정해봅시다.

사용자가 "EC2 인스턴스 요금"을 검색하면 키워드 검색으로 정확히 "EC2", "인스턴스", "요금"이 포함된 문서를 찾습니다. 동시에 시맨틱 검색으로 "가상 서버 비용", "클라우드 가격" 같은 유사한 의미의 문서도 함께 찾아줍니다.

많은 기업에서 이런 패턴을 적극적으로 사용하고 있습니다. 아마존, 구글, 마이크로소프트 같은 빅테크 회사들은 이미 자사 제품의 검색 기능에 하이브리드 방식을 도입했습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 무조건 시맨틱 검색만 사용하려는 것입니다.

"더 똑똑하니까 시맨틱만 쓰면 되겠지"라고 생각하기 쉽지만, 정확한 전문 용어 검색에서는 오히려 키워드 검색이 더 좋은 결과를 냅니다. 따라서 두 방식의 균형을 맞추는 것이 중요합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, 그래서 하이브리드 검색이 필요하군요!" 키워드 검색과 시맨틱 검색의 차이를 제대로 이해하면 더 효과적인 검색 시스템을 설계할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 정확한 전문 용어 검색이 중요하면 키워드 검색 비중을 높이세요

  • 사용자 의도 파악이 중요하면 시맨틱 검색 비중을 높이세요
  • 실제 사용자 검색 패턴을 분석해서 적절한 비율을 찾아야 합니다

2. 하이브리드 검색 장점

김개발 씨는 키워드 검색과 시맨틱 검색의 차이를 이해했지만, 두 가지를 어떻게 합칠 수 있을지 막막했습니다. 박시니어 씨는 화이트보드에 그림을 그리며 설명하기 시작했습니다.

"하이브리드 검색은 두 마리 토끼를 다 잡는 방법이야."

하이브리드 검색은 키워드 검색과 시맨틱 검색을 동시에 실행하고 결과를 합치는 방식입니다. 마치 두 명의 전문가에게 동시에 질문하고 답변을 종합하는 것과 같습니다.

이렇게 하면 정확성과 유연성을 모두 얻을 수 있어서 검색 품질이 크게 향상됩니다.

다음 코드를 살펴봅시다.

from aws_bedrock import KnowledgeBase

# 하이브리드 검색 설정
kb = KnowledgeBase(kb_id="your-kb-id")

response = kb.retrieve(
    query="Lambda 함수 타임아웃 해결 방법",
    # 하이브리드 검색 활성화
    retrievalConfiguration={
        "vectorSearchConfiguration": {
            "overrideSearchType": "HYBRID"
        }
    }
)

# 키워드와 시맨틱 검색 결과가 모두 포함됩니다
for result in response['retrievalResults']:
    print(result['content']['text'])

박시니어 씨는 화이트보드에 벤 다이어그램을 그렸습니다. 왼쪽 원에는 "키워드 검색", 오른쪽 원에는 "시맨틱 검색", 그리고 두 원이 겹치는 부분에 "하이브리드"라고 적었습니다.

"자, 이걸 봐. 키워드 검색은 정확한 단어를 잘 찾고, 시맨틱 검색은 의미를 잘 이해하지.

하이브리드는 이 둘의 장점을 합친 거야." 김개발 씨가 물었습니다. "그럼 단순히 두 검색을 따로 하고 결과를 합치면 되는 건가요?" "좋은 질문이야!

단순히 합치는 게 아니라, 각 결과에 점수를 매기고 순위를 재조정하는 과정이 필요해." 하이브리드 검색의 작동 원리를 살펴봅시다. 쉽게 비유하자면, 하이브리드 검색은 마치 두 명의 심사위원이 채점하는 것과 같습니다.

첫 번째 심사위원(키워드 검색)은 정확한 단어 일치에 높은 점수를 주고, 두 번째 심사위원(시맨틱 검색)은 의미의 유사성에 높은 점수를 줍니다. 최종 점수는 두 심사위원의 점수를 합산해서 결정됩니다.

하이브리드 검색이 없던 시절에는 어땠을까요? 개발자들은 두 가지 선택지 중 하나를 골라야 했습니다.

키워드 검색을 선택하면 사용자가 정확한 용어를 모를 때 검색이 실패했습니다. 시맨틱 검색을 선택하면 너무 광범위한 결과가 나와서 원하는 정보를 찾기 어려웠습니다.

프로젝트마다 이 문제로 고민이 깊었습니다. 바로 이런 문제를 해결하기 위해 하이브리드 검색이 등장했습니다.

하이브리드 검색을 사용하면 최고의 정확도를 얻을 수 있습니다. 사용자가 "Lambda timeout"이라고 검색하면 키워드 검색으로 정확한 문서를 찾고, "서버리스 함수가 멈추는 문제"라고 검색하면 시맨틱 검색으로 관련 문서를 찾습니다.

또한 더 많은 관련 결과를 제공할 수 있습니다. 키워드 검색으로는 놓칠 수 있는 유용한 문서를 시맨틱 검색이 찾아내고, 시맨틱 검색이 가져온 부정확한 결과는 키워드 검색으로 필터링됩니다.

무엇보다 사용자 경험이 크게 개선된다는 큰 이점이 있습니다. 사용자는 어떤 방식으로 검색하든 원하는 정보를 찾을 수 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 KnowledgeBase 객체를 생성하는 부분을 보면 AWS Bedrock의 지식 베이스에 연결한다는 것을 알 수 있습니다.

이 부분이 핵심입니다. 다음으로 retrieve 메서드를 호출할 때 overrideSearchType을 "HYBRID"로 설정하는 부분에서 하이브리드 검색이 활성화됩니다.

마지막으로 검색 결과가 반환되면 두 가지 검색 방식의 결과가 이미 합쳐진 상태입니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 고객 지원 챗봇을 개발한다고 가정해봅시다. 고객이 "계정을 삭제하고 싶어요"라고 입력하면 하이브리드 검색으로 "계정 삭제" 관련 문서와 "회원 탈퇴", "서비스 해지" 같은 유사한 의미의 문서를 모두 찾아줍니다.

많은 기업의 고객 지원 시스템이 이런 방식을 채택하고 있습니다. AWS의 Bedrock 서비스를 사용하면 이런 하이브리드 검색을 간단한 설정만으로 구현할 수 있습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 하이브리드 검색을 활성화만 하고 가중치 조정을 하지 않는 것입니다.

기본 설정이 모든 경우에 최적인 것은 아닙니다. 자신의 데이터와 사용자 패턴에 맞게 가중치를 조정해야 최고의 결과를 얻을 수 있습니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 눈이 반짝였습니다.

"와, 이렇게 간단하게 두 가지를 합칠 수 있다니!" 하이브리드 검색을 제대로 이해하면 검색 품질을 획기적으로 향상시킬 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 하이브리드 검색은 대부분의 경우 단일 검색 방식보다 우수한 결과를 제공합니다

  • AWS Bedrock을 사용하면 복잡한 구현 없이 하이브리드 검색을 바로 사용할 수 있습니다
  • 검색 결과를 모니터링하면서 지속적으로 개선해야 합니다

3. Bedrock 하이브리드 검색 설정

김개발 씨는 드디어 직접 하이브리드 검색을 구현해보기로 했습니다. AWS 콘솔을 열고 Bedrock 서비스를 찾았지만, 어디서부터 시작해야 할지 막막했습니다.

"선배님, 실제로 어떻게 설정하나요?" 박시니어 씨가 자리로 와서 단계별로 알려주기 시작했습니다.

AWS Bedrock 하이브리드 검색 설정은 지식 베이스를 생성하고 검색 타입을 지정하는 과정입니다. 마치 레고 블록을 조립하듯이 단계별로 따라하면 됩니다.

OpenSearch Serverless를 백엔드로 사용하며, 벡터 임베딩과 키워드 인덱싱이 자동으로 처리됩니다.

다음 코드를 살펴봅시다.

import boto3
from botocore.config import Config

# Bedrock 클라이언트 생성
config = Config(region_name='us-east-1')
bedrock_agent = boto3.client('bedrock-agent-runtime', config=config)

# 하이브리드 검색 실행
response = bedrock_agent.retrieve(
    knowledgeBaseId='YOUR_KB_ID',
    retrievalQuery={
        'text': 'Lambda 함수 성능 최적화'
    },
    retrievalConfiguration={
        'vectorSearchConfiguration': {
            'overrideSearchType': 'HYBRID',  # SEMANTIC, HYBRID 중 선택
            'numberOfResults': 10
        }
    }
)

# 결과 확인
for item in response['retrievalResults']:
    print(f"Score: {item['score']}")
    print(f"Content: {item['content']['text'][:200]}")

김개발 씨는 박시니어 씨의 화면을 바라보며 메모를 시작했습니다. "첫 번째 단계는 뭐죠?" "먼저 AWS 콘솔에서 Bedrock 서비스로 들어가야 해.

그리고 Knowledge bases 메뉴를 찾아." 박시니어 씨가 화면을 공유하며 천천히 설명했습니다. "여기 보면 'Create knowledge base' 버튼이 있지?

이걸 클릭하면 설정 화면이 나와." 지식 베이스 생성 과정을 차근차근 살펴봅시다. 쉽게 비유하자면, 지식 베이스는 마치 도서관을 짓는 것과 같습니다.

먼저 건물을 세우고(지식 베이스 생성), 책장을 배치하고(데이터 소스 연결), 분류 체계를 만들어야(임베딩 모델 선택) 합니다. 이 모든 과정이 체계적으로 진행되어야 제대로 작동하는 검색 시스템이 완성됩니다.

지식 베이스를 만들 때 가장 중요한 선택은 데이터 소스입니다. "데이터는 어디에 저장되어 있니?" 박시니어 씨가 물었습니다.

"S3 버킷에 마크다운 파일로 저장되어 있어요." "좋아. 그럼 S3를 데이터 소스로 선택하면 돼.

Bedrock이 자동으로 파일을 읽어서 처리해줄 거야." AWS Bedrock은 S3, Confluence, Salesforce, SharePoint 같은 다양한 데이터 소스를 지원합니다. 파일 형식도 PDF, Word, Markdown, HTML 등 대부분의 텍스트 기반 포맷을 자동으로 인식합니다.

다음으로 중요한 것은 임베딩 모델 선택입니다. 박시니어 씨가 설명을 이어갔습니다.

"임베딩 모델은 텍스트를 숫자 벡터로 변환해주는 역할을 해. Bedrock에서는 Amazon Titan Embeddings를 기본으로 제공하지." "다른 모델을 사용할 수도 있나요?" "물론이지.

Cohere Embed 같은 다른 모델도 선택할 수 있어. 하지만 처음에는 Titan으로 시작하는 게 좋아.

성능도 괜찮고 설정도 간단하거든." 벡터 데이터베이스는 OpenSearch Serverless가 자동으로 생성됩니다. 이 부분이 AWS Bedrock의 큰 장점입니다.

개발자가 직접 OpenSearch 클러스터를 구축하고 관리할 필요가 없습니다. Bedrock이 모든 인프라를 알아서 프로비저닝하고 스케일링합니다.

위의 코드를 단계별로 살펴보겠습니다. 먼저 boto3 라이브러리로 Bedrock 클라이언트를 생성하는 부분을 보면 리전을 지정한다는 것을 알 수 있습니다.

지식 베이스는 특정 리전에 생성되므로 같은 리전의 클라이언트를 사용해야 합니다. 다음으로 retrieve 메서드를 호출할 때 knowledgeBaseId를 필수로 지정해야 합니다.

이 ID는 콘솔에서 지식 베이스를 만들 때 자동으로 생성됩니다. 가장 중요한 부분은 overrideSearchType입니다.

이 파라미터에는 세 가지 값을 지정할 수 있습니다. "SEMANTIC"은 시맨틱 검색만 사용하고, "HYBRID"는 키워드와 시맨틱을 결합하며, 아무것도 지정하지 않으면 기본값인 시맨틱 검색이 실행됩니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 사내 기술 문서 검색 시스템을 구축한다고 가정해봅시다.

Confluence에 저장된 수천 개의 문서를 Bedrock 지식 베이스에 연결하고, 하이브리드 검색을 활성화하면 됩니다. 직원들은 자연어로 질문하면 관련 문서를 정확하게 찾을 수 있습니다.

많은 기업이 이런 방식으로 사내 지식 관리 시스템을 운영하고 있습니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 지식 베이스를 만들고 바로 검색을 시도하는 것입니다. 데이터 소스를 연결하고 나면 동기화(Sync) 과정이 필요합니다.

이 과정에서 모든 문서가 임베딩되고 인덱싱됩니다. 동기화가 완료되기 전에는 검색이 제대로 작동하지 않습니다.

또 다른 주의사항은 권한 설정입니다. Bedrock이 S3 버킷이나 다른 데이터 소스에 접근할 수 있도록 IAM 역할을 제대로 설정해야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 가이드를 따라 김개발 씨는 첫 번째 지식 베이스를 성공적으로 만들었습니다.

"오, 진짜 되네요!" AWS Bedrock의 하이브리드 검색 설정을 제대로 이해하면 복잡한 검색 시스템을 빠르게 구축할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 지식 베이스 생성 후 반드시 동기화(Sync)를 실행하고 완료될 때까지 기다리세요

  • 처음에는 작은 데이터셋으로 테스트하고 점진적으로 확장하는 것이 좋습니다
  • IAM 권한 설정을 꼼꼼히 확인해야 데이터 소스 연결이 제대로 작동합니다

4. 검색 가중치 조정

김개발 씨의 첫 하이브리드 검색 시스템이 가동되었습니다. 하지만 결과를 보니 뭔가 이상했습니다.

너무 광범위한 문서가 섞여서 나왔습니다. "선배님, 검색 결과가 좀 이상해요." 박시니어 씨가 화면을 보더니 고개를 끄덕였습니다.

"아, 가중치 조정이 필요하겠구나."

검색 가중치 조정은 키워드 검색과 시맨틱 검색의 비율을 조절하는 과정입니다. 마치 요리할 때 소금과 설탕의 비율을 맞추는 것과 같습니다.

가중치를 조정하면 검색 결과의 정확도와 다양성을 자신의 상황에 맞게 최적화할 수 있습니다.

다음 코드를 살펴봅시다.

import boto3

bedrock_agent = boto3.client('bedrock-agent-runtime', region_name='us-east-1')

# 키워드 검색 비중을 높인 하이브리드 검색
response = bedrock_agent.retrieve(
    knowledgeBaseId='YOUR_KB_ID',
    retrievalQuery={'text': 'Python 3.11 새로운 기능'},
    retrievalConfiguration={
        'vectorSearchConfiguration': {
            'overrideSearchType': 'HYBRID',
            # 가중치 설정: 0.0(순수 시맨틱) ~ 1.0(순수 키워드)
            'implicitFilterConfiguration': {
                'metadataAttributes': [
                    {
                        'key': 'hybrid_weight',
                        'value': 0.7  # 키워드 70%, 시맨틱 30%
                    }
                ]
            },
            'numberOfResults': 10
        }
    }
)

박시니어 씨가 의자를 당겨 앉으며 설명을 시작했습니다. "하이브리드 검색은 두 가지 검색 방식을 섞는 건데, 그 비율을 조정할 수 있어." "비율이요?

어떻게요?" "가중치라는 개념이 있어. 키워드 검색에 70%의 비중을 주고 시맨틱 검색에 30%의 비중을 준다던가, 또는 반대로 할 수도 있지." 가중치 조정의 개념을 이해해 봅시다.

쉽게 비유하자면, 가중치 조정은 마치 음악 믹싱과 같습니다. 보컬과 악기의 볼륨을 각각 조절해서 최적의 사운드를 만드는 것처럼, 키워드 검색과 시맨틱 검색의 비중을 조절해서 최적의 검색 결과를 만듭니다.

어느 한쪽이 너무 크면 균형이 깨지고, 적절하게 섞으면 조화로운 결과가 나옵니다. 가중치를 조정하지 않으면 어떤 문제가 생길까요?

김개발 씨가 겪었던 문제가 바로 그것입니다. 기본 설정은 보통 50:50 비율인데, 이게 모든 상황에 맞는 것은 아닙니다.

예를 들어 정확한 버전 정보가 중요한 기술 문서 검색에서는 키워드 검색 비중이 높아야 합니다. "Python 3.11"을 찾는데 "Python 3.9" 문서까지 나오면 곤란하니까요.

반대로 사용자의 의도를 파악하는 것이 중요한 FAQ 검색에서는 시맨틱 검색 비중이 높아야 합니다. "비밀번호를 잊어버렸어요"와 "로그인이 안 돼요"는 다른 표현이지만 같은 해결책이 필요할 수 있습니다.

AWS Bedrock에서 가중치를 조정하는 방법을 알아봅시다. 안타깝게도 현재 Bedrock의 공개 API에서는 가중치를 직접 조정하는 파라미터가 명시적으로 제공되지 않습니다.

하지만 우회적인 방법이 있습니다. 첫 번째 방법은 메타데이터 필터링을 활용하는 것입니다.

특정 메타데이터 조건을 추가하면 간접적으로 키워드 검색의 비중을 높일 수 있습니다. 두 번째 방법은 numberOfResults를 조정하는 것입니다.

더 많은 결과를 가져온 다음 애플리케이션 레벨에서 재순위화하는 방식입니다. 위의 코드를 자세히 살펴보겠습니다.

코드에서 implicitFilterConfiguration 부분이 바로 간접적인 가중치 조정 방법입니다. 메타데이터 속성을 필터링 조건으로 추가하면 해당 조건을 만족하는 문서가 우선순위를 갖게 됩니다.

이것은 엄밀히 말하면 가중치 조정은 아니지만, 비슷한 효과를 낼 수 있습니다. 실전에서는 **재순위화(Re-ranking)**를 많이 사용합니다.

박시니어 씨가 추가 설명을 했습니다. "Bedrock에서 결과를 받은 다음에, 우리가 직접 점수를 재계산할 수도 있어.

예를 들어 정확한 키워드 매칭이 있으면 점수를 올려주고, 메타데이터 조건을 만족하면 또 올려주는 식으로." 실제 현업에서는 어떻게 활용할까요? 예를 들어 전자상거래 상품 검색을 만든다고 가정해봅시다.

사용자가 "나이키 에어맥스 270 검정"이라고 검색하면 정확한 모델명과 색상이 중요하므로 키워드 검색 비중을 높입니다. 반대로 "편한 러닝화"라고 검색하면 의미 파악이 중요하므로 시맨틱 검색 비중을 높입니다.

많은 전자상거래 플랫폼이 이런 방식으로 검색어의 특성을 분석해서 동적으로 가중치를 조정합니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 극단적인 가중치를 설정하는 것입니다. 키워드 100% 또는 시맨틱 100%로 설정하면 하이브리드 검색의 의미가 없어집니다.

대부분의 경우 30:70에서 70:30 사이가 적절합니다. 또 다른 실수는 모든 검색어에 같은 가중치를 적용하는 것입니다.

검색어의 특성에 따라 동적으로 조정하는 것이 더 좋은 결과를 냅니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 조언을 따라 김개발 씨는 검색어 길이와 특성을 분석해서 가중치를 동적으로 조정하는 로직을 추가했습니다. "이제 훨씬 나아졌어요!" 검색 가중치 조정을 제대로 이해하면 검색 품질을 한 단계 끌어올릴 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 검색어가 짧고 구체적이면 키워드 검색 비중을 높이세요

  • 검색어가 길고 추상적이면 시맨틱 검색 비중을 높이세요
  • A/B 테스트로 최적의 가중치를 찾는 것이 가장 확실합니다

5. 검색 결과 품질 비교

김개발 씨는 가중치를 여러 번 조정해보았지만, 어떤 설정이 가장 좋은지 확신이 서지 않았습니다. "선배님, 뭐가 더 나은지 어떻게 알 수 있죠?" 박시니어 씨는 웃으며 대답했습니다.

"그래서 측정이 중요하지. 객관적인 지표로 비교해야 해."

검색 결과 품질 비교는 서로 다른 검색 방식이나 설정의 성능을 객관적으로 측정하는 과정입니다. 마치 자동차의 연비를 측정하듯이 명확한 지표가 필요합니다.

Precision, Recall, MRR 같은 지표를 사용하면 어떤 설정이 더 우수한지 정량적으로 판단할 수 있습니다.

다음 코드를 살펴봅시다.

import boto3
from collections import defaultdict

def evaluate_search_quality(kb_id, test_queries, search_type):
    """검색 품질 평가 함수"""
    bedrock = boto3.client('bedrock-agent-runtime', region_name='us-east-1')

    results = {
        'total_queries': len(test_queries),
        'avg_score': 0,
        'top_k_accuracy': 0
    }

    total_score = 0
    correct_in_top_k = 0

    for query, expected_doc_id in test_queries:
        response = bedrock.retrieve(
            knowledgeBaseId=kb_id,
            retrievalQuery={'text': query},
            retrievalConfiguration={
                'vectorSearchConfiguration': {
                    'overrideSearchType': search_type,  # SEMANTIC, HYBRID
                    'numberOfResults': 5
                }
            }
        )

        # 결과 분석
        for idx, result in enumerate(response['retrievalResults']):
            total_score += result['score']
            if result['metadata']['doc_id'] == expected_doc_id and idx < 5:
                correct_in_top_k += 1
                break

    results['avg_score'] = total_score / len(test_queries)
    results['top_k_accuracy'] = correct_in_top_k / len(test_queries)

    return results

# 시맨틱 vs 하이브리드 비교
semantic_results = evaluate_search_quality(kb_id, test_queries, 'SEMANTIC')
hybrid_results = evaluate_search_quality(kb_id, test_queries, 'HYBRID')

print(f"Semantic - Accuracy: {semantic_results['top_k_accuracy']:.2%}")
print(f"Hybrid - Accuracy: {hybrid_results['top_k_accuracy']:.2%}")

박시니어 씨가 새로운 노트북 페이지를 펼쳤습니다. "검색 품질을 측정하는 데는 여러 가지 지표가 있어.

가장 기본적인 것부터 알아보자." 김개발 씨는 펜을 들고 메모할 준비를 했습니다. 검색 품질 지표의 세계로 들어가 봅시다.

쉽게 비유하자면, 검색 품질 측정은 마치 학생의 성적을 평가하는 것과 같습니다. 시험 점수(Precision), 출석률(Recall), 등수(Ranking) 같은 다양한 기준으로 종합적으로 판단해야 합니다.

어느 하나만 좋아서는 안 되고, 전체적인 균형이 중요합니다. 가장 먼저 알아야 할 지표는 **Precision(정밀도)**입니다.

"Precision은 검색 결과 중에서 실제로 관련 있는 문서의 비율이야." 박시니어 씨가 설명했습니다. "예를 들어 10개 결과를 보여줬는데 그중 7개가 관련 있으면 Precision은 70%야." "아, 그럼 높을수록 좋은 거네요?" "맞아.

하지만 Precision만 높다고 좋은 건 아니야." 다음은 **Recall(재현율)**입니다. "Recall은 실제 관련 문서 중에서 몇 개를 찾아냈는지의 비율이야.

관련 문서가 총 20개인데 10개만 찾았으면 Recall은 50%지." 김개발 씨가 고개를 갸우뚱했습니다. "Precision이 높으면 Recall도 높지 않나요?" "좋은 질문이야!

사실 이 둘은 트레이드오프 관계야. Precision을 높이려고 엄격하게 필터링하면 Recall이 낮아지고, Recall을 높이려고 많이 가져오면 Precision이 낮아지지." 세 번째 중요한 지표는 **MRR(Mean Reciprocal Rank)**입니다.

"MRR은 첫 번째 관련 문서가 몇 번째 순위에 나타나는지를 측정해. 첫 번째에 나오면 1점, 두 번째면 0.5점, 세 번째면 0.33점 이런 식이야." "왜 그게 중요한가요?" "사용자는 보통 검색 결과의 상위 몇 개만 보거든.

첫 페이지에 원하는 답이 없으면 검색을 다시 하거나 포기해버려." 실제 측정 방법을 알아봅시다. 위의 코드를 보면 evaluate_search_quality 함수가 핵심입니다.

이 함수는 테스트 쿼리 세트를 받아서 각 쿼리에 대한 검색 결과를 평가합니다. 먼저 테스트 쿼리를 준비해야 합니다.

각 쿼리에는 정답 문서 ID가 함께 있어야 합니다. 이것을 Ground Truth라고 부릅니다.

예를 들어 "Lambda 타임아웃 해결"이라는 쿼리의 정답은 "doc_123" 같은 식입니다. 다음으로 각 쿼리를 실행하고 결과를 분석합니다.

정답 문서가 상위 K개 안에 있는지 확인하는 것을 Top-K Accuracy라고 합니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 고객 지원 챗봇의 검색 품질을 개선한다고 가정해봅시다. 먼저 실제 고객 질문 100개를 샘플로 뽑고, 각 질문에 대한 정답 문서를 지정합니다.

그 다음 시맨틱 검색, 하이브리드 검색(가중치 0.3), 하이브리드 검색(가중치 0.7)을 각각 테스트합니다. 결과를 비교하면 이런 식으로 나올 수 있습니다.

시맨틱 검색: Precision 0.65, Recall 0.82, MRR 0.71 하이브리드(0.3): Precision 0.72, Recall 0.79, MRR 0.78 하이브리드(0.7): Precision 0.78, Recall 0.73, MRR 0.82 이 결과를 보면 하이브리드(0.7) 설정이 Precision과 MRR이 가장 높다는 것을 알 수 있습니다. 고객 지원에서는 정확한 답변이 중요하므로 이 설정을 선택하는 것이 좋습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 테스트 데이터가 너무 적다는 것입니다.

10개 쿼리로 테스트해서 나온 결과는 신뢰하기 어렵습니다. 최소 50개, 가능하면 100개 이상의 다양한 쿼리로 테스트해야 합니다.

또 다른 실수는 개발자의 주관이 개입되는 것입니다. Ground Truth를 지정할 때 한 사람의 판단만으로 하면 편향이 생길 수 있습니다.

가능하면 여러 사람이 검토하거나, 실제 사용자 행동 데이터를 활용하는 것이 좋습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨와 함께 체계적인 평가를 진행한 김개발 씨는 드디어 최적의 설정을 찾았습니다. "데이터로 증명하니까 확신이 생기네요!" 검색 결과 품질 비교를 제대로 이해하면 주관적 판단이 아닌 객관적 데이터로 의사결정을 할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 최소 50-100개의 테스트 쿼리로 평가해야 신뢰할 수 있는 결과가 나옵니다

  • Precision, Recall, MRR을 종합적으로 봐야 하며, 어느 하나만 높다고 좋은 것은 아닙니다
  • 정기적으로 재평가하면서 검색 품질을 지속적으로 모니터링해야 합니다

6. 최적 설정 찾기

김개발 씨는 이제 품질 측정 방법을 알게 되었지만, 여전히 막막했습니다. "선배님, 설정 조합이 너무 많은데 어떻게 최적값을 찾죠?" 박시니어 씨는 빙그레 웃으며 대답했습니다.

"그래서 체계적인 접근이 필요해. 무작정 바꿔보는 게 아니라 전략이 있어야 하지."

최적 설정 찾기는 체계적인 실험과 분석을 통해 가장 좋은 성능을 내는 파라미터 조합을 발견하는 과정입니다. 마치 과학자가 실험을 설계하듯이 변수를 하나씩 바꿔가며 테스트해야 합니다.

그리드 서치, A/B 테스트, 점진적 개선 같은 방법론을 활용하면 효율적으로 최적값을 찾을 수 있습니다.

다음 코드를 살펴봅시다.

import boto3
import itertools
from typing import List, Tuple

def grid_search_optimization(
    kb_id: str,
    test_queries: List[Tuple[str, str]],
    search_types: List[str],
    num_results_range: List[int]
):
    """그리드 서치로 최적 설정 찾기"""

    bedrock = boto3.client('bedrock-agent-runtime', region_name='us-east-1')
    best_config = None
    best_score = 0

    # 모든 조합 테스트
    for search_type, num_results in itertools.product(search_types, num_results_range):
        print(f"Testing: {search_type}, top-{num_results}")

        correct = 0
        total_score = 0

        for query, expected_doc in test_queries:
            response = bedrock.retrieve(
                knowledgeBaseId=kb_id,
                retrievalQuery={'text': query},
                retrievalConfiguration={
                    'vectorSearchConfiguration': {
                        'overrideSearchType': search_type,
                        'numberOfResults': num_results
                    }
                }
            )

            # 정답이 상위 결과에 있는지 확인
            for idx, result in enumerate(response['retrievalResults']):
                total_score += result['score']
                if result['metadata'].get('doc_id') == expected_doc and idx < 3:
                    correct += 1
                    break

        accuracy = correct / len(test_queries)
        avg_score = total_score / len(test_queries)
        combined_score = accuracy * 0.7 + (avg_score / 10) * 0.3

        print(f"  Accuracy: {accuracy:.2%}, Combined: {combined_score:.3f}")

        # 최적 설정 업데이트
        if combined_score > best_score:
            best_score = combined_score
            best_config = {
                'search_type': search_type,
                'num_results': num_results,
                'accuracy': accuracy,
                'score': combined_score
            }

    return best_config

# 실행
result = grid_search_optimization(
    kb_id='YOUR_KB_ID',
    test_queries=test_data,
    search_types=['SEMANTIC', 'HYBRID'],
    num_results_range=[5, 10, 20]
)

print(f"\nBest Configuration:")
print(f"  Search Type: {result['search_type']}")
print(f"  Top-K: {result['num_results']}")
print(f"  Accuracy: {result['accuracy']:.2%}")

박시니어 씨가 화이트보드에 표를 그리기 시작했습니다. 가로축에는 검색 타입, 세로축에는 결과 개수를 적었습니다.

"이렇게 체계적으로 접근해야 해." 김개발 씨는 표를 바라보며 물었습니다. "모든 조합을 다 테스트하는 건가요?" "그게 가장 확실한 방법이지.

이걸 그리드 서치라고 불러." **그리드 서치(Grid Search)**의 개념을 이해해 봅시다. 쉽게 비유하자면, 그리드 서치는 마치 보물찾기를 할 때 지도를 격자로 나누고 한 칸씩 탐색하는 것과 같습니다.

모든 가능성을 빠짐없이 확인하므로 최적값을 놓칠 가능성이 없습니다. 시간이 좀 걸리더라도 확실한 방법입니다.

그리드 서치 없이 무작정 시도하면 어떤 문제가 생길까요? "이 설정 좋은 것 같은데?"라는 주관적 느낌으로 선택하면 실제로는 더 좋은 설정을 놓칠 수 있습니다.

또한 왜 이 설정이 좋은지 설명하기 어렵습니다. 팀원들에게 "그냥 제 느낌에는..."이라고 말할 수는 없으니까요.

체계적인 최적화 전략을 세워봅시다. 첫 번째 단계는 테스트할 변수 정의입니다.

AWS Bedrock 하이브리드 검색에서 조정할 수 있는 주요 변수는 다음과 같습니다. 검색 타입: SEMANTIC vs HYBRID 결과 개수: 5, 10, 20, 50 메타데이터 필터: 사용 여부 재순위화: 적용 여부 박시니어 씨가 설명을 이어갔습니다.

"처음부터 모든 변수를 다 바꾸면 너무 복잡해져. 먼저 중요한 변수 2-3개만 선택해서 시작하는 게 좋아." 두 번째 단계는 평가 지표 설정입니다.

"어떤 지표를 최적화할 것인지 명확히 해야 해." 박시니어 씨가 강조했습니다. "정확도가 중요한지, 속도가 중요한지, 아니면 사용자 만족도가 중요한지에 따라 최적 설정이 달라지거든." 김개발 씨는 고개를 끄덕이며 메모했습니다.

"우리는 고객 지원이니까 정확도가 가장 중요하겠네요." 세 번째 단계는 실험 실행과 기록입니다. 위의 코드를 자세히 살펴봅시다.

grid_search_optimization 함수는 모든 파라미터 조합을 체계적으로 테스트합니다. itertools.product를 사용하면 모든 조합을 쉽게 생성할 수 있습니다.

각 조합에 대해 테스트 쿼리를 실행하고 결과를 기록합니다. 중요한 것은 단일 지표로 통합하는 것입니다.

코드에서는 정확도 70%, 평균 점수 30%의 가중치를 준 combined_score를 사용했습니다. 네 번째 단계는 결과 분석과 검증입니다.

"최적 설정을 찾았다고 끝이 아니야." 박시니어 씨가 말했습니다. "새로운 테스트 데이터로 검증해봐야 해.

이걸 교차 검증이라고 하지." 김개발 씨가 물었습니다. "왜 또 검증이 필요한가요?" "과적합(Overfitting) 때문이야.

테스트 데이터에만 최적화되고 실제 데이터에서는 성능이 떨어질 수 있거든." 실제 현업에서는 어떻게 활용할까요? 예를 들어 이커머스 상품 검색 최적화 프로젝트를 진행한다고 가정해봅시다.

먼저 지난달 실제 사용자 검색어 1000개를 샘플로 추출합니다. 각 검색어에 대해 사용자가 실제로 클릭한 상품을 정답으로 설정합니다.

그 다음 그리드 서치로 최적 설정을 찾고, 이번 달 새로운 검색 데이터로 검증합니다. 성능이 유지되면 배포하고, 그렇지 않으면 다시 조정합니다.

많은 성공적인 검색 시스템이 이런 지속적 개선 사이클을 운영합니다. A/B 테스트도 중요한 방법입니다.

"실험실에서 좋았던 설정이 실제 사용자에게도 좋을까?" 박시니어 씨가 질문을 던졌습니다. "그건...

모르죠." "맞아. 그래서 실제 환경에서 A/B 테스트를 해봐야 해.

사용자의 50%에게는 기존 설정을, 나머지 50%에게는 새로운 설정을 적용하고 클릭률, 구매 전환율 같은 실제 비즈니스 지표를 비교하는 거야." 하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 **지역 최적값(Local Optimum)**에 갇히는 것입니다.

처음 찾은 좋은 설정에 만족하고 더 이상 탐색하지 않으면, 더 좋은 전역 최적값을 놓칠 수 있습니다. 또 다른 실수는 과도한 최적화입니다.

0.01% 차이를 위해 며칠을 소비하는 것은 비효율적입니다. 충분히 좋은 설정을 찾았으면 실제 사용자에게 배포하고 피드백을 받는 것이 더 가치 있습니다.

자동화도 고려해야 합니다. 박시니어 씨가 마지막 조언을 했습니다.

"이런 최적화 과정을 정기적으로 반복해야 해. 데이터가 바뀌면 최적 설정도 바뀌니까.

가능하면 자동화해서 매주 또는 매월 재평가하도록 만들면 좋아." 다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 가이드를 따라 김개발 씨는 체계적인 최적화 프로세스를 구축했습니다.

그리고 2주 후, 검색 만족도가 20% 향상되었다는 보고를 받았습니다. "선배님, 성공했어요!" 최적 설정 찾기를 제대로 이해하면 과학적이고 체계적인 접근으로 검색 시스템을 개선할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 처음에는 중요한 변수 2-3개만 선택해서 그리드 서치를 시작하세요

  • 실험 결과를 꼼꼼히 기록하고 시각화하면 패턴을 발견하기 쉽습니다
  • 오프라인 평가와 온라인 A/B 테스트를 모두 활용해야 실제 효과를 검증할 수 있습니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#AWS#Bedrock#HybridSearch#SemanticSearch#RAG

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.