
TiDB Cloud와 Groq를 사용하여 성장하는 지식 RAG 채팅을 작게 테스트하기
요약
TiDB Cloud와 Groq를 활용하여 비용 효율적인 지식 기반 RAG 채팅 시스템을 구축하는 방법을 소개합니다. 데이터 축적에 따라 검색 대상이 성장할 수 있는 구조를 설계하여 PoC 단계의 비용 부담을 최소화하는 데 중점을 둡니다.
핵심 포인트
- TiDB Cloud의 무료 티어를 활용한 저비용 RAG PoC 구축
- SQL, 벡터, 하이브리드 검색을 동일한 기반에서 테스트 가능
- 데이터 등록 및 업데이트를 통한 RAG 검색 대상의 지속적 확장
- Groq, OpenAI 등 요구사항에 따른 LLM 교체 용이성
서론
업무용 「지식에 답변해 주는 채팅」을 제안하려고 하면, 가장 먼저 고민되는 것이 비용이었습니다.
대형 클라우드의 매니지드 검색 서비스나 AI 검색 계열의 구성은 강력하지만, 제안 단계의 작은 PoC(Proof of Concept)에서도 견적 비용이 무거워지기 쉽습니다. 실제 문의가 많다면 설명하기 쉽겠지만, 「지식을 보유하고 있을 뿐」인 기간에도 고정비가 발생하는 구성이라면 초기 제안으로서 통과시키기 어려운 상황이 있었습니다.
한편, JSON을 수동으로 만들어 정적으로 검색하는 것에는 한계가 있습니다. 특히 매일 지견이 축적되는 타입의 업무에서는 주 1회, 월 1회의 수동 업데이트가 운영의 병목(Bottleneck)이 됩니다.
제가 원했던 것은 다음과 같은 메커니즘입니다.
- 처음에는 작게 시작할 수 있다
- 관리 화면에서 지식을 등록·업데이트할 수 있다
- 등록된 지식이 DB에 축적되어, RAG의 검색 대상으로 성장한다
- SQL 검색, 벡터 검색 (Vector Search), 하이브리드 검색을 동일한 기반에서 테스트할 수 있다
- 답변 생성 LLM은 요구 사항에 따라 Groq / OpenAI 등으로 교체할 수 있다
그래서 이번에는 TiDB Cloud와 Groq를 사용하여, 기존 웹사이트의 FAQ 채팅을 RAG화하는 실험을 진행했습니다.
TiDB Cloud Starter는 1 인스턴스당 월 5GiB의 row storage, 5GiB의 columnar storage, 50 million Request Units (RUs)의 무료 혜택이 있으며, 조직 전체로는 최대 5 인스턴스분인 25GiB + 250M RUs까지 무료 혜택이 있다고 안내되어 있습니다 (2026-06-20 기준).
여기서 말하는 RUs는 단순한 「읽기 횟수」가 아니라, 쿼리나 트랜잭션에서 소비되는 리소스량을 나타내는 단위입니다. 따라서 무료 혜택 범위 내에서 어디까지 사용할 수 있는지는 데이터 양뿐만 아니라 검색 방식이나 쿼리를 던지는 방식에도 좌우됩니다.
또한, TiDB는 SQL뿐만 아니라 Vector Search/RAG 용도로도 전면에 내세우고 있기 때문에, 작게 시작하는 지식 기반으로서 궁합이 좋아 보였습니다.
이 기사의 주제는 「Groq로 실서비스까지 전부 가능한가」가 아닙니다. 답변 생성 LLM은 Groq든 OpenAI든 Azure OpenAI든, 요구 사항에 따라 교체할 수 있는 부분입니다.
오히려 중요한 것은 지식을 TiDB에 둠으로써, 향후 관리 화면이나 사용자 게시 플로우를 통해 데이터를 등록하고, RAG의 검색 대상을 운영 흐름 속에서 키워나갈 수 있는가 하는 점입니다.
참고:
- https://www.pingcap.com/tidb-cloud-starter-pricing-details/
- https://www.pingcap.com/pricing/
- https://docs.pingcap.com/tidbcloud/select-cluster-tier/
- https://docs.pingcap.com/ai/vector-search-overview/
- https://console.groq.com/docs/rate-limits
만든 것
가상의 서비스 사이트 「NEURAMNESIA」의 FAQ/예약/안전성/매각 페이지 등을 지식화하여, 채팅으로 질문할 수 있는 검증 페이지를 만들었습니다.
이번에는 관리 화면 자체까지는 만들지 않았지만, 최종적으로는 「운영자나 사용자가 지식을 등록한다 → TiDB에 축적된다 → 채팅의 답변 범위가 성장한다」라는 구성을 상정하고 있습니다.
실제로 동작하는 데모는 이쪽입니다.
데모 화면에서는 검색 방식을 전환하면서 답변 본문, 참조 소스, 검색 로그, LLM 생성 상태를 확인할 수 있습니다.

구성은 다음과 같습니다.
Chat Lab에서는 다음과 같이 검색 방식을 전환할 수 있습니다.
Current JSONL
: 기존의 로컬 JSONL 검색
TiDB Keyword
: TiDB 상의 LIKE 기반 검색
TiDB Vector Local
: TiDB의 VECTOR 열을 사용한 벡터 검색 (Vector Search)
TiDB Hybrid Local
: TiDB Vector + TiDB Keyword의 rank fusion
TiDB Fulltext
:MATCH ... AGAINST를 시도하고, 미지원 시 Keyword로 폴백 (Fallback)
일반적인 서비스 화면이라면 검색 방식은 Hybrid 등으로 고정하는 것을 상정하지만, 이번에는 기술 검증용 데모이므로 일부러 검색 모드를 화면상에서 전환할 수 있도록 했습니다. 같은 질문을 던졌을 때 참조 소스나 검색 로그가 어떻게 변하는지 볼 수 있도록 하기 위해서입니다.
답변 생성은 Groq에 요청하고 있습니다. 즉, 검색은 TiDB/JSONL 측, 답변 생성은 Groq 측으로 역할을 분담했습니다.
다만, 여기서 Groq는 "이번에 사용한 생성 LLM"을 의미합니다. 주인공은 지식(Knowledge)을 TiDB에 모아서 등록, 업데이트, 검색하기 쉬운 형태로 만드는 것입니다. LLM API는 실제 서비스의 요구사항에 따라 교체할 수 있도록 검색 부분과는 분리하여 다루고 있습니다.
지식의 저장소
TiDB에는 knowledge_chunks라는 테이블을 하나 만들었습니다.
CREATE TABLE IF NOT EXISTS knowledge_chunks (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
record_id VARCHAR(191) NOT NULL,
...
처음에는 기존 React 데이터로부터 docs/rag/knowledge.jsonl을 생성하고, 이를 TiDB로 upsert했습니다.
npm run rag
npm run rag:tidb:import
이번에는 외부 Embedding API 키 없이도 벡터 검색 (Vector Search)을 테스트할 수 있도록, 검증용인 local-hash-ngram-v1이라는 로컬 임베딩 (local embedding)도 준비했습니다.
npm run rag:tidb:import-local-vector
여기서 말하는 Local은 TiDB 측이 로컬이라는 의미가 아니라, 임베딩 (embedding) 생성을 외부 API가 아닌 로컬의 간이 로직으로 수행한다는 의미입니다.
이 로컬 임베딩은 실제 서비스의 의미 검색 (Semantic Search)용이 아닙니다. 어디까지나 TiDB의 VECTOR 열과 벡터 검색 경로를 검증하기 위한 간이 임베딩입니다. 실제 서비스에서는 OpenAI Embeddings 등 용도에 맞는 임베딩 프로바이더 (embedding provider)로 교체하는 것을 상정하고 있습니다.
Groq로 답변 생성하기
API에서는 먼저 검색 모드에 따라 RAG 컨텍스트를 가져온 뒤, 그 결과를 Groq에 전달합니다.
Groq를 사용한 이유는 이번 검증에서 빠르고 쉽게 테스트할 수 있었기 때문입니다. 상용 사이트에서 사용할 경우에는 Groq / OpenAI / Azure OpenAI 등의 후보군에 대해 이용 약관, 속도 제한 (Rate Limit), 지원, 데이터 취급, 비용 상한 등을 확인한 후 선택해야 합니다.
이 구현에서는 LLM 선정을 지식 기반으로부터 분리하여 나중에 교체할 수 있도록 했습니다.
제안 단계에서 고려한다면 다음과 같이 나누는 것이 현실적이라고 생각합니다.
| 단계 | LLM에 대한 관점 |
|---|---|
| 기술 검증·데모 | Groq로 빠르게 테스트 |
| ... |
즉, 이 글에서 고정하고자 하는 것은 LLM 프로바이더 (LLM provider)가 아니라, 지식을 TiDB에 모아서 키워나갈 수 있는 구성입니다. LLM은 고객 요구사항이나 운영 조건에 맞춰 다시 선택할 수 있는 부품으로 취급합니다.
요청 예시:
{
"message": "예약 흐름을 짧게 알려주세요",
"provider": "groq",
...
응답에는 답변뿐만 아니라 검색 모드, 참조 소스, 간단한 처리 로그도 반환하도록 했습니다.
{
"retrievalMode": "tidb-hybrid",
"provider": "groq",
...
이렇게 구성해 두면 Chat Lab 상에서 "어떤 검색 방식이 작동하고 있는지", "Groq 생성이 성공했는지", "어떤 소스가 사용되었는지"를 확인할 수 있습니다.
이번에 중점을 둔 것은 검색과 생성을 분리하여 관측할 수 있다는 점입니다.
RAG 채팅에서는 제대로 답변하지 못했을 때, 다음 중 어디에서 실패했는지를 구분해서 볼 수 있어야 합니다.
- 검색 대상 지식이 부족했는가
- 검색 방식이 맞지 않았는가
- 참조 소스는 맞았지만, LLM 생성에 실패했는가
- 속도 제한 등으로 LLM API를 호출할 수 없었는가
검색 성공과 생성 성공을 분리해 두면 장애 발생 시나 품질 개선 시 원인 파악(Troubleshooting)이 쉬워집니다.
Groq 측은 Chat Completions 호환 API로 취급하여, 모델이나 temperature 등은 앱 측 설정에서 교체할 수 있도록 했습니다. 이번에는 모델 비교가 아니라, RAG 구성으로서 "검색 결과를 가져와서 그것을 LLM에 전달하여 답변하는" 경로의 검증을 주된 목적으로 하고 있습니다.
검색 방식
1. Current JSONL
원래의 간이 구현입니다. 로컬 JSONL을 읽어 제목이나 본문에 대해 가벼운 스코어링 (scoring)을 수행합니다.
소규모라면 이 방식도 작동하지만, 지식(knowledge)이 늘어나거나 사용자가 등록한 데이터를 축적하는 용도로는 적합하지 않습니다.
2. TiDB Keyword
TiDB에 저장한 title/content/kind에 대해, LIKE 기반으로 스코어링 (scoring)을 수행합니다.
일본어 질문에 대해 완전한 자연어 검색은 아니지만, 사이트 내 FAQ나 페이지 단위의 지식(knowledge)에서는 상당히 실용적이었습니다.
3. TiDB Vector Local
embedding VECTOR(1536)에 넣은 벡터를 사용하여, VEC_COSINE_DISTANCE로 가까운 청크(chunk)를 가져옵니다.
다만 이번에는 검증용 로컬 hash embedding을 사용했으므로, 의미 검색 (semantic search)의 정밀도는 높지 않습니다. 실제로 후술할 간이 비교에서는 벡터 (Vector) 단독의 정밀도가 다소 낮았습니다.
4. TiDB Hybrid Local
벡터 (Vector) 검색과 키워드 (Keyword) 검색을 모두 실행하고, 순위를 융합합니다.
이번 실험에서는 벡터 (Vector) 단독으로 흐트러진 결과를 키워드 (Keyword)가 보정하여, 실용적인 측면에서 상당히 안정적이었습니다.
5. TiDB Fulltext
TiDB Cloud의 FULLTEXT 검색을 테스트하기 위해, 다음과 같은 인덱스 (index)도 준비했습니다.
CREATE FULLTEXT INDEX IF NOT EXISTS idx_knowledge_chunks_fulltext
ON knowledge_chunks (title, content);
하지만 이번에 사용한 TiDB 환경에서는 MATCH ... AGAINST가 UnknownType: *ast.MatchAgainst가 되었습니다. 따라서 구현 시에는 FULLTEXT가 실패할 경우 키워드 (Keyword) 검색으로 폴백 (fallback)하도록 처리했습니다.
TiDB Cloud의 FULLTEXT 지원 여부는 플랜, 리전, 환경에 따라 차이가 있습니다. 공식 문서에서도 TiDB Cloud Starter / Essential의 일부 AWS 리전에서는 FULLTEXT 구문과 인덱스 (index)를 지원하는 반면, TiDB Self-Managed나 TiDB Cloud Dedicated에서는 FULLTEXT 인덱스 이용에 제한이 있다고 설명되어 있습니다.
따라서 RAG 기반으로 사용할 경우에는 "FULLTEXT를 사용할 수 있다는 전제"로 구축하기보다, 이용 가능 여부를 확인한 뒤 사용할 수 없을 경우를 대비한 대안을 마련해 두는 것이 안전합니다.
이는 기사를 작성하는 데 있어 오히려 좋은 인사이트였습니다. RAG 기반에서는 "사용 가능한 검색 방식을 테스트하는 것"뿐만 아니라, "환경 차이나 미지원 기능에 어떻게 대응(fallback)할 것인가"도 설계에 포함해야 합니다.
작은 질문 세트로 검색 방식 비교하기
5개의 질문을 5개의 검색 모드로 각각 1회씩 실행했습니다. 답변 생성은 Groq를 사용했습니다.
샘플 수가 적기 때문에 여기서의 수치는 엄격한 벤치마크 (benchmark)가 아니라, 검색 방식별 경향을 파악하기 위한 간이 비교입니다.
질문 세트:
- 예약 흐름을 짧게 알려주세요
- 체험 후 부작용이나 안전성에 대해 알려주세요
- 초보자에게 추천하는 체험 메뉴가 있나요
- 기억을 매각할 경우의 흐름과 감정에 대해 알려주세요
- 주차장과 취소 수수료에 대해 알려주세요
실행 명령어:
npm run rag:benchmark -- --rounds=1 --delay-ms=3000
결과:
| Mode | Actual search | Runs | Avg ms | P50 ms | Source hit | Top source hit | LLM generated | Fallbacks |
|---|---|---|---|---|---|---|---|---|
| Current JSONL | JSONL | 5 | 534 | 659 | 100% | 60% | 60% | 0 |
| ... |
이번 지표의 대략적인 의미는 다음과 같습니다.
Source hit
: 기대한 소스, 또는 범위를 벗어난 질문에 대해 "데이터 없음"이라고 판단할 수 있었는가 -
Top source hit
: 최상단 소스가 기대한 대로였는가 -
LLM generated
: Groq로 답변을 생성할 수 있었는가 -
Fallbacks
: FULLTEXT 실패 시 등에 다른 검색으로 전환된 횟수
TiDB Fulltext의 Source hit / Top source hit
는 FULLTEXT 자체의 검색 결과가 아닙니다. 이번 환경에서는 FULLTEXT가 전체 실패하여, Keyword 검색으로 폴백(Fallback)한 후의 결과입니다.
또한, LLM generated가 100%가 되지 않는 모드가 있는데, 이는 검색 실패뿐만 아니라 Groq 측의 레이트 리밋(Rate Limit) 등으로 인해 생성을 스킵한 케이스도 포함됩니다.
이번 평가는 질문마다 "이 페이지나 데이터가 반환되면 타당하다"라고 생각되는 기대 소스를 수동으로 정하고, 그 소스가 검색 결과에 포함되는지 확인하는 간이 평가입니다. 답변 본문의 정확성을 엄밀하게 채점한 것이 아니라, 검색 방식별 경향을 보기 위한 것입니다.
세부적인 판정 방법이나, 이 평가를 통해 알 수 있는 점과 알 수 없는 점은 기사 말미의 보충 설명에 정리해 두었습니다.
결과에서 알 수 있었던 것
TiDB Keyword는 상당히 견고하다
TiDB Keyword는 Top source hit가 100%였습니다.
이번과 같은 FAQ/페이지 본문 기반의 지식(Knowledge)에서는, 처음부터 고도의 Vector 검색을 도입하지 않더라도 토큰 설계와 스코어링(Scoring)을 제대로 한다면 충분히 경쟁력이 있다는 인상을 받았습니다.
특히 FAQ나 서비스 설명 페이지처럼, 제목이나 본문에 문의어가 어느 정도 그대로 등장하는 데이터에서는 Keyword 검색이 상당히 강력합니다.
Vector 단독은 임베딩(Embedding) 품질에 크게 의존한다
TiDB Vector Local은 빠른 반면, Top source hit는 0%였습니다.
이는 TiDB의 Vector Search가 나쁘다기보다, 이번에 사용한 local-hash-ngram-v1이 의미 검색용 임베딩(Embedding)이 아니기 때문입니다.
오히려 이 점이 기사로서 중요한 포인트입니다.
Vector Search를 사용한다고 해서 자동으로 똑똑해지는 것이 아니라, 임베딩(Embedding) 설계가 검색 품질을 크게 좌우합니다.
실제 서비스(Production)에서 사용한다면, OpenAI Embeddings와 같은 의미 벡터를 사용하여 재검증하고 싶은 부분입니다.
Hybrid는 실용적이었다
TiDB Hybrid Local은 Source hit 100%, Top source hit 80%, LLM generated 100%였습니다.
Vector 단독으로는 결과가 거칠었지만, Keyword와 조합함으로써 상당히 안정되었습니다.
이번처럼 "제목이나 본문에 명확한 단어가 있는 지식"의 경우, Keyword를 축으로 삼으면서 Vector로 보조하는 형태가 현실적이라고 느꼈습니다.
FULLTEXT는 환경 차이를 고려해야 한다
FULLTEXT를 구현은 했지만, 이번 TiDB 환경에서는 MATCH ... AGAINST를 사용할 수 없어 전건(All) Keyword로 폴백(Fallback)되었습니다.
리포트에는 다음과 같이 남아 있습니다.
TiDB 검색은 tidb-fulltext-error: UnknownType: *ast.MatchAgainst. tidb-keyword로 폴백했습니다.
여기서 중요한 것은 "FULLTEXT를 사용할 수 없어서 실패했다"가 아니라, 검색 방식별로 대체할 수 있는 경로(Fallback)를 마련해 두는 것입니다.
RAG 기반으로 구축할 때는 이러한 "사용할 수 있으면 사용하고, 불가능하면 폴백한다"는 설계를 해두는 것이 안심할 수 있습니다.
Groq의 레이트 리밋(Rate Limit)도 관측되었다
간이 비교 중, Groq의 TPM 레이트 리밋(Rate Limit)에 걸린 케이스가 있었습니다.
Groq의 레이트 리밋(Rate Limit)은 RPM, RPD, TPM, TPD 등 여러 단위로 관리되며 조직 단위로 적용됩니다. 따라서 짧은 시간 내에 연속 실행하는 검증에서는 모델이나 토큰 양에 따라 생성에 실패할 수 있습니다.
이번 구현에서는 그럴 경우 LLM 답변 생성을 스킵하고, 검색 결과 기반의 폴백(Fallback) 답변을 반환하도록 했습니다.
이 또한 실운영에서는 중요합니다.
RAG 채팅은 "검색"과 "생성"을 나누어 보아야 하며, LLM 측의 일시적인 실패가 있더라도 검색 결과나 참조 소스는 반환할 수 있는 설계로 만들어 두어야 시스템이 견고해집니다.
비용 측면에서 느낀 점
이번에 가장 시험해보고 싶었던 것은 기술적인 측면만이 아닙니다.
"문의가 왔을 때만 LLM을 호출하고, 지식 자체는 DB에 축적하며, 관리 화면에서 업데이트할 수 있다"라는 구성이 제안 관점에서 현실적인지를 보고 싶었습니다.
이 점에서 TiDB Cloud Starter는 궁합이 상당히 좋아 보였습니다.
- SQL로 일반적인 처리가 가능함
- JSON 메타데이터도 가질 수 있음
- Vector 열(Column)도 가질 수 있음
- 처음에는 무료 티어(Free Tier)로 테스트 가능함
- 지식을 DB로 모을 수 있어, 향후 관리 화면이나 등록 동선을 만들기 쉬움
이번에는 정적 JSONL로부터 투입했지만, 정말로 하고 싶은 것은 "사용자나 운영자가 관리 화면에서 등록하면 지식이 성장하는" 형태입니다.
그 경우에도 기반이 TiDB라면, 처음에는 1개의 테이블로 시작해서 나중에 승인 플로우(Approval Flow), 카테고리, 공개/비공개, 감사 로그(Audit Log) 등을 추가해 나갈 수 있을 것 같습니다.
프로덕션화한다면 추가하고 싶은 것
이번 구현은 어디까지나 작은 PoC(Proof of Concept)입니다.
프로덕션화한다면 검색 정밀도나 화면뿐만 아니라, 지식을 안전하게 성장시키기 위한 메커니즘이 필요합니다.
예를 들어, 다음과 같은 것들입니다.
- 관리 화면을 통한 지식 등록
- 등록 내용의 승인 플로우 (Approval Flow)
- 공개/비공개 플래그
- 카테고리나 태그를 통한 필터링
- 업데이트 이력 및 감사 로그 (Audit Log)
- 임베딩 (Embedding) 재생성 작업
- 오래된 청크 (Chunk)의 무효화
- 권한별 검색
- LLM 실패 시의 폴백 (Fallback)
- 비용 상한 및 속도 제한 (Rate Limit) 대책
특히 "성장하는 지식 베이스 (Knowledge Base)"로 만들려면, 단순히 DB에 데이터를 저장하는 것만으로는 부족합니다.
누가 등록했는지, 누가 승인했는지, 언제부터 유효한지, 오래된 정보를 어떻게 무효화할 것인지. 이러한 운영 정보까지 포함하여 설계해 두어야 합니다.
다만, 처음부터 전부 만들 필요는 없습니다.
우선 1개의 테이블과 간단한 검색부터 시작해서, 필요해지면 승인 플로우나 감사 로그를 추가한다. 그러한 단계적인 방식의 구축이 가능하다는 점이 DB에 지식을 모으는 구성의 장점이라고 생각했습니다.
요약
이번에 TiDB Cloud와 Groq로 작은 RAG 채팅을 만들고, TiDB를 "성장하는 지식 기반"으로 사용할 수 있는지 테스트했습니다.
알게 된 점은 다음과 같습니다.
- TiDB에 지식을 모으면 관리 화면이나 등록 동선을 통해 "성장하는 지식 베이스"로 만들기 쉽다
- FAQ/페이지 본문 기반의 지식에서는 TiDB Keyword가 상당히 견고하다
- 벡터 검색 (Vector Search)은 작동했지만, 정밀도는 임베딩 (Embedding) 품질에 크게 의존한다
- 하이브리드 (Hybrid) 검색은 Keyword의 견고함과 Vector의 확장성을 양립하기 쉽다
- FULLTEXT는 환경 차이를 고려하여 폴백 (Fallback) 설계를 하는 것이 좋다
- Groq 생성은 빠르지만, LLM 부분은 요구 사항에 따라 교체하는 것을 전제로 하는 것이 좋다
거대한 매니지드 검색 기반을 갑자기 구축하기 전에, TiDB Cloud Starter를 지식의 저장소로서 작게 검증하는 것은 상당히 현실적이라고 느꼈습니다.
이번과 같은 구성이라면, 처음에는 JSONL로 시작해서 다음으로 TiDB로 옮기고, 마지막으로 관리 화면이나 자동 등록 플로우를 추가하는 단계적인 제안이 쉬울 것 같습니다. 답변 생성 LLM은 Groq로 검증했지만, 이 부분은 프로덕션 요구 사항에 따라 교체할 수 있는 부분입니다.
"지식을 보유하고 있는 것만으로 무거운 고정비가 발생하는" 구성을 피하면서, 사용자와 운영자의 등록을 통해 지식이 성장하고, 필요할 때 SQL, Vector, Hybrid 검색으로 확장할 수 있다. 그 점이 이 구성의 가장 큰 매력이었습니다.
보충: 평가 방법에 대하여
이번 검색 비교는 엄격한 벤치마크라기보다, RAG 채팅의 검색 방식별 경향을 보기 위한 간이 평가입니다.
사용자나 운영자가 관리 화면에서 지식을 등록할 수 있게 되면, DB에는 지식이 축적되어 갑니다. 그 상태에서 "축적된 지식을 채팅 답변에 사용할 때, 어떤 검색 방식이 다루기 쉬울까"를 보기 위해 질문 세트와 기대 소스 (Expected Source)를 수동으로 준비했습니다.
기대 소스를 정하는 방법
"기대하는 소스"는 질문마다 수동으로 정의한 페이지 이름, 데이터 이름, URL 파편입니다.
예를 들어, "예약 흐름을 짧게 알려주세요"라는 질문에서는 BookingPage, bookingSteps, /booking 중 어느 하나라도 sources에 포함되면 기대 소스에 부합한다고 판단했습니다.
{
id: "booking-flow",
text: "예약 흐름을 짧게 알려주세요",
...
}
API 응답에는 검색으로 찾아낸 소스가 배열로 반환됩니다.
{
"sources": [
"BookingPage (https://novamnesis-laboratories.vercel.app/booking)",
...
]
}
이 경우, BookingPage가 포함되어 있으므로 Source hit은 성공입니다. 또한 첫 번째 항목이 BookingPage이므로 Top source hit도 성공입니다.
반면, 만약 sources가 다음 순서였다면, Source hit은 성공이지만 Top source hit은 실패로 처리합니다.
{
"sources": [
"FaqPage (https://novamnesis-laboratories.vercel.app/faq)",
...
즉, Source hit은 "후보 중에 정답일 것 같은 정보가 포함되었는가", Top source hit은 "가장 먼저 사용될 가능성이 높은 후보가 기대대로였는가"를 확인하기 위한 간이 지표입니다.
이 평가를 통해 알 수 있는 것과 알 수 없는 것
이번 결과로부터 알 수 있는 것과 알 수 없는 것을 나누면 다음과 같습니다.
- 알 수 있는 것: 소규모의 정적 지식(Static Knowledge)이라면 JSONL로도 충분히 작동한다.
- 알 수 있는 것: 이번 질문 세트에서는 TiDB Keyword의 첫 번째 후보가 안정적이었다.
- 알 수 있는 것: TiDB를 사용하면 관리 화면을 통해 지식을 확장해 나가는 구성으로 발전시키기 쉽다.
- 알 수 없는 것: TiDB를 사용한다고 해서 항상 JSONL보다 검색 정밀도가 높아지는 것은 아니다.
- 알 수 없는 것: 벡터 검색 (Vector Search)을 도입한다고 해서 자동으로 정밀도가 올라가는 것은 아니다.
또한, 이 평가는 답변 본문의 정확성을 직접 채점하는 것이 아닙니다. 어디까지나 "검색을 통해 기대하는 소스(Source)를 찾아냈는가"를 확인하기 위한 간이 평가입니다. 의미상으로는 올바른 다른 페이지를 찾아냈더라도, 직접 정의한 기대 소스에 포함되지 않는다면 hit으로 처리되지 않을 가능성이 있습니다.
따라서 이 글의 결론은 "검색 정밀도만으로 TiDB가 압도적으로 승리했다"는 것이 아닙니다.
작게 시작하는 것이 목적이라면 JSONL로도 충분합니다. 다만, 사용자나 운영자가 지식을 등록하고 채팅의 답변 범위를 지속적으로 키워나간다면, 빠른 단계에서 DB로 전환하는 것이 추후 확장성 측면에서 유리합니다. 이번 실험은 그 DB로서 TiDB를 사용하였고, 검색 방식별 동작을 확인했다는 위치에 있습니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기