Kdrant: Qdrant를 위한 관용적이고 코루틴 우선적인 Kotlin 클라이언트
요약
Kdrant는 Qdrant 벡터 데이터베이스를 위한 Kotlin 전용 클라이언트 라이브러리입니다. 코루틴 우선 설계와 타입 안전한 DSL을 제공하며, gRPC 대신 Ktor 기반의 가벼운 REST 엔진을 사용하여 Kotlin 환경에 최적화되어 있습니다.
핵심 포인트
- 코루틴(suspend 함수)을 지원하여 비동기 프로그래밍에 최적화
- 타입 안전한 DSL을 통해 컬렉션 및 필터링을 선언적으로 작성 가능
- gRPC/Netty 없이 Ktor와 kotlinx-serialization 기반의 가벼운 구조
- 검색 결과를 사용자 정의 데이터 클래스로 즉시 디코딩 지원
JVM 기반으로 개발하면서 Qdrant를 사용하고 싶다면, 공식 클라이언트는 io.qdrant:client이며 이는 Java용으로 빌드되었습니다. 모든 호출은 ListenableFuture를 반환하고, 요청은 protobuf 빌더로 조립되며, 여러분의 클래스패스(classpath)에 gRPC/Netty 스택을 끌어들입니다. Kotlin에서 이는 언어와 싸워야 함을 의미합니다:
// Kotlin에서 사용하는 공식 Java 클라이언트
val future: ListenableFuture<UpdateResult> = client.upsertAsync("articles", points)
val result = future.get() // 블로킹(block)하거나, 직접 future→coroutine 브릿지를 붙여야 함
코루틴(coroutines)을 사용하려 하면 퓨처(futures)를 마주하게 됩니다. DSL을 원하면 protobuf 빌더를 마주하게 됩니다.
Kdrant 소개
Kdrant는 여러분이 실제로 Kotlin으로 작성하고 싶어 할 클라이언트입니다:
- 코루틴 우선 (Coroutine-first) — 모든 작업은 협력적 취소(cooperative cancellation)와 타임아웃을 지원하는
suspend함수입니다. - 타입 안전 DSL (Type-safe DSLs) — 컬렉션(collections), 포인트(points), 페이로드(payloads), 필터(filters)를 위한 DSL을 제공합니다.
- 작은 점유율 (Small footprint) — Ktor +
kotlinx-serialization기반의 순수 Kotlin REST 엔진입니다. gRPC, Netty 또는 protobuf를 사용하지 않습니다. - 타입화된 에러 (Typed errors) — 철저하게 처리(handle exhaustively)할 수 있는 sealed
KdrantException을 제공합니다.
이 라이브러리는 안정적이며(1.1.0, SemVer), Maven Central의 io.github.nacode-studios 아래에 게시되어 있습니다.
빠른 시작
JDK 17 이상이 필요합니다. 의존성(dependency)은 하나입니다:
dependencies {
implementation("io.github.nacode-studios:kdrant-transport-rest:1.1.0")
}
로컬에서 Qdrant를 실행합니다:
docker run -p 6333:6333 qdrant/qdrant
연결하고, 컬렉션을 생성하고, upsert하고, 검색합니다:
val qdrant = Kdrant(host = "localhost", port = 6333) {
apiKey = System.getenv("QDRANT_API_KEY") // 인증이 필요 없는 로컬 노드의 경우 생략
requestTimeout = 5.seconds
...
Kdrant는 이미 가지고 있는 벡터를 저장하고 검색합니다. 임베딩(embeddings)을 생성하지는 않습니다.
Kotlin처럼 읽히는 필터 DSL
Qdrant의 전체 필터링 모델을 선언적으로 표현합니다:
val query = filter {
must {
"lang" eq "en"
...
결과를 여러분의 타입으로 즉시 디코딩하세요
@Serializable data class Article(val title: String, val lang: String)
val articles: List<Hit<Article>> = qdrant.searchAs<Article>("articles") {
...
Hybrid search (dense + sparse) (하이브리드 검색 (밀집 + 희소))
최신 /points/query 엔진이 완벽하게 지원됩니다. Reciprocal Rank Fusion (RRF)을 사용하여 여러 프리페치 (prefetch) 소스를 결합함으로써 진정한 밀집 (dense) + 키워드 (keyword) 하이브리드 검색을 수행할 수 있습니다:
val hits = qdrant.search("articles") {
prefetch { query(denseVector); using = "text"; limit = 50 }
prefetch { querySparse(indices, values); using = "keywords"; limit = 50 }
...
recommend / discover / context, 그룹화 및 배치 검색 (batch search), 멀티 벡터 (multi-vectors), 그리고 Flow 기반의 scroll 기능도 모두 갖추고 있습니다.
RAG를 구축하시나요? 바로 연결됩니다.
Kdrant는 직접 코드를 작성할 필요가 없도록 일급 시민 (first-class) 통합 기능을 제공합니다:
- Spring Boot 스타터 — 자동 설정된
QdrantClient빈 (bean) - Spring AI —
VectorStore구현 - LangChain4j —
EmbeddingStore구현
Qdrant를 위한 docker-compose가 포함된 실행 가능한 example-rag 서비스 (ingest → embed → store → retrieve)가 있어, 전체 과정을 엔드 투 엔드 (end to end)로 확인할 수 있습니다.
솔직한 트레이드오프 (tradeoff)
순수 처리량 (throughput)과 스트리밍 (streaming) 측면에서는 여전히 gRPC/HTTP2가 우세합니다. 만약 해당 부분이 병목 지점(bottleneck)이라면 공식 클라이언트를 사용하세요. Kdrant는 이를 관용적인 (idiomatic) Kotlin과 훨씬 작은 풋프린트 (footprint)와 맞바꿉니다:
| Kdrant | Official io.qdrant:client | |
|---|---|---|
| Wire protocol | Ktor CIO 기반 REST | gRPC (HTTP/2) |
| ... |
일반적인 RAG 및 임베딩 검색 (embedding-search) 워크로드의 경우, 저는 기꺼이 이 트레이드오프를 선택하겠습니다.
사용해 보기
- ⭐ Repo: https://github.com/NaCode-Studios/Kdrant
- 📦 Maven Central:
io.github.nacode-studios:kdrant-transport-rest:1.1.0 - 📖 API docs: https://nacode-studios.github.io/Kdrant/
- 🪪 Apache-2.0
피드백은 언제나 환영합니다 — 특히 API 사용성 (API ergonomics)에 대한 의견을 부탁드립니다. Kotlin 네이티브 Qdrant 클라이언트에서 필요로 하는 기능이 있다면, 이슈 (issue)를 생성하여 함께 논의해 봅시다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기