Blog

Qdrant 벡터 DB를 이용해서 ChatGpt 사용 예제

2025-06-26

아래 예제에서는 Windows Server에 Qdrant 실행 파일(qdrant.exe)을 설치하고, C# 콘솔 애플리케이션에서 벡터 데이터를 삽입(upsert)한 뒤, 벡터 검색 결과를 ChatGPT API로 전달하여 답변을 얻는 전체 흐름을 설명합니다.


1. Qdrant 설치 및 실행

  1. 다운로드
    Qdrant GitHub 릴리즈 페이지에서 Windows용 qdrant.exe를 내려받습니다.

    ruby복사편집https://github.com/qdrant/qdrant/releases
    
  2. 실행
    다운로드한 qdrant.exe를 원하는 폴더(예: C:\qdrant)에 복사한 뒤, 관리자 권한으로 명령 프롬프트에서 다음을 실행합니다.

    bat복사편집cd C:\qdrant
    qdrant.exe serve --host 0.0.0.0 --port 6333
    
    • 기본적으로 메모리 모드로 실행되며, --storage-config 옵션을 주면 디스크에 영구 저장할 수 있습니다.


2. C#으로 벡터 데이터 삽입하기

아래 코드는

  1. OpenAI Embeddings API로 텍스트를 벡터로 변환

  2. Qdrant REST API에 컬렉션을 생성하고, 벡터 포인트를 upsert

하는 예제입니다.

csharp복사편집using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace QdrantDemo
{
    class Program
    {
        // TODO: 환경 변수나 설정 파일에서 읽어올 것
        const string OPENAI_API_KEY = "sk-…";
        const string QDRANT_URL     = "http://localhost:6333";
        const string COLLECTION_NAME= "my_collection";

        static async Task Main(string[] args)
        {
            using var http = new HttpClient();

            // 1. OpenAI Embeddings API 호출
            var text = "안녕하세요, Qdrant 벡터 DB 테스트 문장입니다.";
            var embedReq = new
            {
                model = "text-embedding-ada-002",
                input = text
            };
            http.DefaultRequestHeaders.Add("Authorization", $"Bearer {OPENAI_API_KEY}");
            var embedRes = await http.PostAsync(
                "https://api.openai.com/v1/embeddings",
                new StringContent(JsonSerializer.Serialize(embedReq), Encoding.UTF8, "application/json")
            );
            embedRes.EnsureSuccessStatusCode();
            using var embedJson = await JsonDocument.ParseAsync(await embedRes.Content.ReadAsStreamAsync());
            var vector = embedJson.RootElement
                                  .GetProperty("data")[0]
                                  .GetProperty("embedding")
                                  .EnumerateArray()
                                  .Select(v => v.GetDouble())
                                  .ToArray();

            // 2. Qdrant 컬렉션 생성 (한 번만 실행)
            var createColl = new
            {
                vectors = new { size = vector.Length, distance = "Cosine" }
            };
            var createRes = await http.PutAsync(
                $"{QDRANT_URL}/collections/{COLLECTION_NAME}",
                new StringContent(JsonSerializer.Serialize(createColl), Encoding.UTF8, "application/json")
            );
            createRes.EnsureSuccessStatusCode();

            // 3. 벡터 포인트 upsert
            var upsertPayload = new
            {
                points = new[]
                {
                    new {
                        id = 1,
                        vector = vector,
                        payload = new { text = text }
                    }
                }
            };
            var upsertRes = await http.PutAsync(
                $"{QDRANT_URL}/collections/{COLLECTION_NAME}/points",
                new StringContent(JsonSerializer.Serialize(upsertPayload), Encoding.UTF8, "application/json")
            );
            upsertRes.EnsureSuccessStatusCode();

            Console.WriteLine("벡터 데이터 삽입 완료!");
        }
    }
}

3. 벡터 검색 및 ChatGPT에 질의하기

다음 예제는

  1. 사용자의 질의를 Embedding으로 변환

  2. Qdrant에서 상위 3개 유사도 검색

  3. 검색된 텍스트를 ChatGPT에 컨텍스트로 전달하여 답변 받기

를 보여줍니다.

csharp복사편집using System;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace QdrantChatGPT
{
    class Program
    {
        const string OPENAI_API_KEY = "sk-…";
        const string QDRANT_URL     = "http://localhost:6333";
        const string COLLECTION_NAME= "my_collection";

        static async Task Main(string[] args)
        {
            Console.Write("질문을 입력하세요: ");
            var userQuestion = Console.ReadLine();

            using var http = new HttpClient();
            http.DefaultRequestHeaders.Add("Authorization", $"Bearer {OPENAI_API_KEY}");

            // 1. 질문을 벡터로 변환
            var embedReq = new { model = "text-embedding-ada-002", input = userQuestion };
            var embedRes = await http.PostAsync(
                "https://api.openai.com/v1/embeddings",
                new StringContent(JsonSerializer.Serialize(embedReq), Encoding.UTF8, "application/json")
            );
            embedRes.EnsureSuccessStatusCode();
            using var embedJson = await JsonDocument.ParseAsync(await embedRes.Content.ReadAsStreamAsync());
            var queryVector = embedJson.RootElement
                                       .GetProperty("data")[0]
                                       .GetProperty("embedding")
                                       .EnumerateArray()
                                       .Select(v => v.GetDouble())
                                       .ToArray();

            // 2. Qdrant에서 유사도 검색
            var searchPayload = new
            {
                vector = queryVector,
                top = 3
            };
            var searchRes = await http.PostAsync(
                $"{QDRANT_URL}/collections/{COLLECTION_NAME}/points/search",
                new StringContent(JsonSerializer.Serialize(searchPayload), Encoding.UTF8, "application/json")
            );
            searchRes.EnsureSuccessStatusCode();
            using var searchJson = await JsonDocument.ParseAsync(await searchRes.Content.ReadAsStreamAsync());
            var hits = searchJson.RootElement.GetProperty("result")
                              .EnumerateArray()
                              .Select(e => e.GetProperty("payload").GetProperty("text").GetString())
                              .ToList();

            // 3. ChatGPT에 컨텍스트와 함께 질문
            var systemMsg = "다음 컨텍스트를 참고하여 사용자의 질문에 답변해주세요.";
            var userMsg   = $"컨텍스트:\n- {string.Join("\n- ", hits)}\n\n질문: {userQuestion}";

            var chatReq = new
            {
                model = "gpt-3.5-turbo",
                messages = new[]
                {
                    new { role = "system", content = systemMsg },
                    new { role = "user", content = userMsg }
                }
            };
            var chatRes = await http.PostAsync(
                "https://api.openai.com/v1/chat/completions",
                new StringContent(JsonSerializer.Serialize(chatReq), Encoding.UTF8, "application/json")
            );
            chatRes.EnsureSuccessStatusCode();
            using var chatJson = await JsonDocument.ParseAsync(await chatRes.Content.ReadAsStreamAsync());
            var answer = chatJson.RootElement
                                 .GetProperty("choices")[0]
                                 .GetProperty("message")
                                 .GetProperty("content")
                                 .GetString();

            Console.WriteLine("\n===== ChatGPT 응답 =====");
            Console.WriteLine(answer);
        }
    }
}

요약

  1. Qdrant 실행: qdrant.exe serve로 로컬에서 HTTP API(포트 6333) 제공

  2. 데이터 삽입: OpenAI Embeddings → Qdrant 컬렉션 생성 → points upsert

  3. 검색 & 질의: 질문 Embedding → Qdrant 검색(top-k) → ChatGPT에 컨텍스트 포함해 질문

이 구조를 통해 사용자의 질의에 대해 벡터 DB에서 관련 문서를 찾아, 보다 정교한 답변을 ChatGPT로부터 받아올 수 있습니다.

인클루드웹 솔루션이 궁금하신가요?

건설관리, 프로젝트관리, 영업관리 솔루션 도입을 무료로 상담해 드립니다.