개인 웹사이트용 $0 RAG 챗봇: Qdrant vs Upstash Vector
요약
개인 웹사이트를 위한 $0 RAG 챗봇 구축 방법을 비교 분석했습니다. Qdrant Cloud와 Upstash Vector 두 가지 무료 벡터 데이터베이스를 사용하여, 운영 비용 없이도 질문에 답변하고 출처까지 제공하는 챗봇을 구현할 수 있습니다. 두 서비스 모두 성능 면에서는 큰 차이가 없었으나, 클러스터 관리 및 비용 청구 방식에서 차이점을 보였습니다.
핵심 포인트
- Qdrant와 Upstash를 이용해 개인 웹사이트용 RAG 챗봇을 $0으로 구축 가능합니다.
- 두 데이터베이스 모두 검색 품질이나 속도 면에서는 큰 성능 차이를 보이지 않았습니다.
- Qdrant는 유휴 클러스터를 삭제하는 반면, Upstash는 항상 활성화되어 비용이 청구됩니다.
- 개인 프로젝트 규모에서는 어떤 벡터 DB를 사용해도 충분한 성능을 제공합니다.
만약 개인 웹사이트에 챗봇을 만들고 싶다고 가정해 봅시다. 이 챗봇은 방문자의 질문에 사용자의 페이지에서 답변하고, 각 답변 뒤의 페이지 링크도 제공해야 합니다. 일반적으로 이용 가능한 옵션들은 모두 매달 비용이 발생합니다.
- 호스팅된 챗봇 빌더. 설정하기는 빠르지만, 작은 무료 플랜을 넘어서면 월별 요금을 지불해야 하며, 무료 플랜은 보통 메시지 수에 제한이 있거나 제공업체의 브랜딩을 표시합니다.
- 직접 호스팅. 벡터 데이터베이스와 API를 위한 서버, 그리고 모델(해당 서버에서 실행하거나 유료 API를 통해)이 필요합니다. 작은 서버조차도 매달 청구서가 발생하며, 자체적으로 기능을 갖춘 모델을 운영하는 것은 작은 서버보다 훨씬 많은 비용이 듭니다.
하루에 방문자가 몇 명에 불과한 개인 웹사이트의 경우, 어느 쪽도 합리적이지 않습니다. 그래서 저는 운영 비용이 전혀 들지 않는 설정을 찾아보았고, 두 가지를 발견했습니다. 둘 다 전적으로 무료 티어에서 실행되며 신용카드 등록이 필요하지 않으며, 단 하나의 부분에서 차이가 납니다: 벡터 데이터베이스인 Qdrant Cloud 또는 Upstash Vector입니다.
저는 이 두 가지 버전을 모두 만들었습니다. 그 외에는 동일하며, 이 게시물에서는 각 설정이 $0으로 무엇을 제공하는지 다루고, 이후 두 데이터베이스를 직접 비교합니다. 둘 다 라이브 상태입니다: Qdrant 버전과 그 Upstash 쌍둥이. 사례 연구에서는 디자인을 다루며, 다음 주에는 직접 구축하는 방법에 대한 단계별 가이드인 파트 2가 올라올 예정입니다.

이 사이트에 대한 질문에 답변하고 그 출처를 보여주는 Qdrant 버전.
간단한 답변
$0으로 사이트에 RAG 챗봇을 운영할 수 있으며, 두 데이터베이스 모두 작동합니다. 이 정도 규모에서는 데이터베이스가 검색 품질이나 속도에 아무런 변화를 주지 않았습니다. 두 서비스 모두 모든 검색 모드에서 38개 테스트 질문에 대해 소수점 셋째 자리까지 동일한 점수를 기록했습니다. 하이브리드 검색은 API 서버에서 13~15ms가 걸렸고, 데이터베이스 자체는 그중 약 1밀리초를 사용했습니다.
달라진 부분은 로컬 개발 환경, 조정할 수 있는 정도, 그리고 무료 티어 규칙이었습니다. Qdrant는 유휴 상태인 무료 클러스터를 삭제합니다. Upstash는 절대로 잠들지 않지만, 작성하는 모든 벡터에 대해 비용을 청구합니다. 프로젝트가 어떤 규칙을 감당할 수 있는지에 따라 하나를 선택하세요.
$0 스택 (The $0 stack)
모든 구성 요소는 무료 티어이거나 오픈 모델입니다:
| 구성 요소 | 사용한 것 | 비용 |
|---|---|---|
| 콘텐츠 | 사이트 자체 페이지를 llms-full.txt 파일 하나로 처리 | 없음: 사이트에서 생성함 |
| ... | ||
| How it fits together: 매일 밤, 사이트의 콘텐츠는 제목별로 구획(passage)으로 분할되며 (제 사이트의 경우 76개), 각 구획은 두 번 임베딩되어 데이터베이스에 저장됩니다. 방문자가 질문을 하면, 그 질문도 같은 방식으로 임베딩되고 하이브리드 검색이 의미 기반으로 상위 20개 구획과 키워드 기반으로 상위 20개를 가져와 Reciprocal Rank Fusion (RRF)으로 결합하여 상위 5개를 만듭니다. 이후 Groq가 이를 인용하며 짧은 답변을 작성합니다. 하나의 스크립트 태그로 사이트에 채팅 버튼이 추가됩니다. |
$0으로 얻는 것과 그렇지 않은 것
- 하루 약 150개의 답변, 분당 약 5개. Groq의 무료 티어는 계정당 일일 200,000 토큰과 분당 8,000 토큰을 허용하며, 하나의 답변은 약 1,000~1,600 토큰을 사용합니다. 이는 다섯 개의 구절(passages), 질문, 그리고 답변에 필요한 양입니다. 개인 사이트 운영에는 충분한 용량입니다. 할당량이 소진되면 채팅창에 오류 대신 대체 링크("Book a call" 등)가 표시됩니다.
- 조용한 시간 이후의 느린 첫 답변. 함수가 유휴 상태였다가 호출될 경우, Vercel이 부팅하고 모델을 로드하는 과정 때문에 첫 답변을 시작하는 데 4~5초가 걸립니다. 따뜻하게 유지된(Warm) 답변은 파키스탄에 있는 제 노트북 기준으로 약 1.3초 만에 시작되는데, 이 시간의 대부분은 미국까지 갔다가 돌아오는 이동 시간에 해당합니다.
- 간단한 점검 사항. Qdrant의 무료 클러스터는 매주 생존 신호(sign of life)가 필요하며, Upstash는 쓰기 작업량(writes)을 측정합니다. 자세한 내용은 아래에서 다룹니다.
- 개인 용도로만 사용 가능. Vercel의 Hobby 플랜은 비상업적 프로젝트를 위한 것이므로, 상업적인 사이트를 운영하려면 유료 플랜이나 다른 호스팅 환경이 필요합니다.
공정한 비교를 위해
이것이 $0으로 얻을 수 있는 것입니다. 이 게시물의 나머지 부분은 비교 내용입니다. 어떤 데이터베이스가 구절(passages)을 저장해야 할까요?
두 레포지토리는 서로 복사본입니다. 파서(parser), 청커(chunker), 임베딩 코드, 프롬프트, API, 채팅창 및 테스트 코드는 바이트 단위로 동일합니다. 오직 하나의 파일만 다릅니다: 데이터베이스와 통신하는 약 70줄의 store.py 파일뿐입니다.
나머지 모든 것은 동등하게 유지되었습니다:
- 동일한 76개의 구절, 동일한 ID 및 동일한 벡터
- 동일한 융합 방식(fusion): RRF (Reciprocal Rank Fusion)를 사용하며 k = 60, 각 측에서 20개의 후보군을 가져와 상위 5개를 유지함
- 동일한 동점 처리 기준(tie-break) (이유는 아래에 더 자세히 설명)
- 두 데이터베이스 모두 AWS us-east-1에 위치하며, 워싱턴 D.C.의 Vercel 함수 옆에 배치됨
검색 품질을 측정하기 위해 이 사이트에 대한 38개의 질문을 작성했으며, 각 질문은 해당 답변 페이지들을 나열합니다. 그중 26개는 제가 페이지를 알고 있는 상태에서 직접 작성했고, 나머지 12개는 방문자가 물어볼 법한 방식으로 의역(paraphrased)했습니다("우리가 비용을 지불하는 소프트웨어의 소유자는 누가 될까요?"). 각 질문은 네 가지 점수를 받습니다:
- hit@1: 가장 적절한 페이지가 첫 번째로 순위가 매겨짐.
- hit@3: 상위 3개 안에 있음.
- hit@5: 답변 모델이 읽는 다섯 개의 패시지 중 하나임.
- MRR (mean reciprocal rank): 첫 번째 자리에 1점, 두 번째에 ½점, 세 번째에 ⅓점을 부여하고 평균을 냄. 1.0이면 완벽함.
한눈에 보기
| Qdrant Cloud | Upstash Vector | |
|---|---|---|
| 검색 품질 (hit@1 / hit@3 / MRR) | 0.84 / 0.97 / 0.900 | 0.84 / 0.97 / 0.900 |
| ... | ||
| 여기에 각 행을 자세히 설명합니다. |
1. 검색 품질: 동일함
| 검색 모드 | Qdrant | Upstash |
|---|---|---|
| 하이브리드, RRF (챗봇의 선택) | 0.84 / 0.97 / 1.00 / 0.900 | 0.84 / 0.97 / 1.00 / 0.900 |
| ... | ||
| 38개 질문에 대한 hit@1 / hit@3 / hit@5 / MRR. |
이것은 우연이 아닙니다. 몇천 개의 벡터를 사용하여 두 데이터베이스 모두 질문을 모든 벡터와 비교합니다: 정확 검색(exact search)입니다. 데이터베이스가 실제로 차이를 보이는 근사 인덱스(approximate indexes), 예를 들어 HNSW는 더 큰 크기에서만 시작됩니다. Qdrant는 심지어 세그먼트가 10 MB의 벡터를 보유할 때까지 HNSW 인덱스를 구축하지 않는데, 이는 384 차원에서 약 6,500개의 패시지에 해당합니다. 제 사이트의 벡터는 117 KB에 달했습니다. 스트레스 테스트로 색인화한 Upstash 자체 문서의 경우 5,061개 패시지와 7.8 MB가 되어 여전히 기준치 이하입니다.
동일한 벡터, 정확 검색, 그리고 동일한 융합 공식은 동일한 결과를 가져옵니다. 저는 별도의 밀집(dense) 목록과 키워드 목록에서 Upstash의 RRF를 재계산하여 그 융합 점수를 확인했습니다: 이는 1 / (60 + rank)이며, 순위는 0부터 계산되어 소수점 아홉째 자리까지 일치합니다. 이것이 바로 Qdrant가 k = 60일 때 수행하는 방식과 정확히 같습니다.
따라서 검색 품질은 데이터베이스가 아니라 파이프라인에서 나온 것입니다. 차이를 만든 것은 무엇이었을까요:
- 하이브리드 검색(Hybrid search). 키워드만으로는 해당 페이지의 단어를 재사용하는 질문에서는 좋은 성능을 보였으나, 의역된 표현(paraphrases)이 사용되는 경우에는 성능이 급격히 떨어졌습니다 (hit@1이 0.92에서 0.50으로 하락). 의미(Meaning)만 사용하는 방식은 결코 최선의 방법이 아니었습니다. RRF만이 모든 38개 질문에 대해 올바른 페이지를 상위 5개 안에 포함시키는 유일한 방식이었습니다.
- DBSF 대비 RRF. 두 데이터베이스가 제공하는 또 다른 융합(fusion) 방식인 DBSF는 제가 진행한 처음 26개 질문에서 더 나은 성능을 보였지만 (hit@1 기준 0.96 대 0.88), 그 우위는 키워드 친화적인 문구에서 비롯되었습니다. 의역된 질문에서는 RRF가 더 좋았습니다 (0.75 대 0.67). DBSF는 검색 중 더 자신감(confident)을 보이는 쪽을 따르는데, 방문자의 단어가 페이지의 내용과 다를 경우 키워드 검색은 확신에 차게 잘못됩니다: 어떤 기사가 작성되었는지에 대한 질문이 DBSF의 상위 5개 목록에서 완전히 제외되는 사례가 있었습니다.
- 깔끔한 소스 파일. 사이트 내용을 직접 크롤링하여 읽는
llms-full.txt파일을 사용하는 것보다 hit@1 성능이 두 데이터베이스 모두에서 0.84에서 0.66으로 하락했습니다. 페이지 추출기가 카드 그리드에서 도구 이름들을 누락시키고 FAQ 내용을 소개(About) 페이지에 혼합하는 문제가 있었습니다.
2. 속도: 가장 작은 부분은 데이터베이스입니다
API는 워싱턴 D.C.의 Vercel에서 실행되며, 두 데이터베이스는 바로 옆 AWS us-east-1에서 운영됩니다. 다음 시간 측정치는 함수 자체 로그를 기반으로 합니다:
| Vercel 내부 | Qdrant | Upstash |
|---|---|---|
| 하이브리드 검색, 워밍업(중앙값) | ~15 ms (최대 17) | 13 ms (최대 21) |
| ... | ||
| Inside either database, a search takes about a millisecond. The rest is the HTTPS round trip and 10 to 20 passages of text coming back as JSON. |
방문자가 느끼는 경험은 다르므로, 저는 파키스탄에 있는 제 노트북으로도 측정했습니다:
| 파키스탄에서 미국까지 | Qdrant | Upstash |
|---|---|---|
| 검색만 (중앙값 / p95) | 781 / 894 ms | 783 / 889 ms |
| ... | ||
| A search from Pakistan takes about 780 ms on both, and it's nearly all network: an empty request's round trip alone was 371 ms. In an answer, the time goes to the network and to Groq, whose speed varied from call to call: the first words left the server anywhere from 0.45 to 2.4 seconds after the request arrived. |

데이터베이스의 공유 시간은 어느 쪽이든 약 1ms입니다. 나머지는 거리 문제입니다.
콜드 스타트(Cold starts) 비용은 둘 다 약 3~4초가 소요됩니다. 저는 각 서비스별로 샘플을 하나씩 테스트했기 때문에, 0.6초의 차이는 노이즈일 수 있습니다. Qdrant 환경에서 추적해 보니, 코드가 실행되기까지 약 3.3초가 경과하는데, 이는 Vercel이 대형 함수를 부팅하고 Python이 라이브러리를 가져오는 시간입니다. 해결책은 데이터베이스 속도를 높이는 것이 아니라 번들(bundle) 크기를 줄이는 것입니다.
샘플 자체가 작기 때문에 (각 환경당 6~8개의 채팅 및 50개의 상태 검사), 이를 순위 매기는 기준이 아닌 규모의 차이로 간주해야 합니다. 솔직한 요약은 동률입니다.
3. 설정 및 로컬 개발
Qdrant는 노트북에서 실행됩니다. docker compose up -d 하나만으로 클라우드와 동일한 버전을 얻을 수 있습니다 (둘 다 1.19.2로 고정). 또한, 저장된 모든 패시지(passage)를 탐색할 수 있는 대시보드가 제공됩니다. 실험은 빨랐습니다. 로컬에서 검색하는 데 약 4ms가 걸렸고, 컬렉션 설정 변경은 요청 한 번으로 제자리에서 이루어졌으며, 할당량에 아무런 영향도 주지 않았습니다. 클라우드로 전환하는 것은 클러스터 URL과 키라는 두 가지 설정만 필요했고 코드 수정은 전혀 없었습니다. 평가 점수(eval) 역시 정확히 동일했습니다.
클라우드 설정은 약 5분이 걸렸습니다: 로그인, 간단한 프로필 양식 작성, 무료 클러스터 생성, 키 생성. 카드 정보는 필요하지 않았습니다.
Upstash는 로컬 버전이 없습니다. 설정은 콘솔의 양식 하나로 끝납니다: 이름, 리전(region), 유형(하이브리드/Hybrid), 그리고 덴스 벡터(dense vector)의 크기 및 메트릭(384, 코사인). 4~5분이면 충분하며, 카드 정보도 필요 없고 설치하거나 계속 실행할 것도 없습니다. 하지만 개발 중 모든 검색은 클라우드로 왕복하는 과정입니다 (파키스탄에서 약 700ms 소요), 그리고 재인덱싱(re-index) 할 때마다 일일 할당량을 사용합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기