[Vector DB] Weaviate 기초 사용법

Weaviate의 사용법에 대해 작성해보겠습니다.

모든 데이터는 깃허브에 저장해 둘 예정입니다.
git clone https://github.com/joo9906/RAG 하시거나 직접 파일을 만들어보시면 될 것 같습니다.

 

현재 Weaviate는 25년 이후로 v3에서 v4로 넘어고, 공식문서를 통해 꽤나 친절하게 알려줍니다.

 

하지만 구글에 "Weaviate 사용법"을 검색하면 한글로 작성된 내용이 겉핥기 정도라 프로젝트 복기 겸 제가 작성했던 코드로 보다 쉽게 설명해보겠습니다. 공식 문서에서 제공하는 가이드를 실제 프로젝트에 적용하기에는 좀 애매한 부분이 있어, 제가 실제로 프로젝트에서 작성한 코드를 바탕으로 해보겠습니다.

 

저는 SSAFY에서 제공해 준 GMS의 OpenAI API를 활용하여 작성하였는데, 사용하고 계신 API Key가 있다면 그것만 바꿔주시고, 아니라면 직접 Weaviate API Key를 활용하셔야 합니다. 사용한 임베딩 모델은 GPT text-embedding-3-small 입니다.


개발 당시 복기

SSAFY에서 25년 10월~11월까지 최종 프로젝트인 HAND에서 감정분석 모델의 파인튜닝과 RAG를 활용한 MLOps를 담당하며 Weaviate를 처음으로 사용하게 되었습니다. 이전에는 전부 Chroma_db를 사용해서 RAG를 설계했어요.

무료+Docker를 통해 서버에 업로드가 가능하다는 점이 매력적이라 chroma DB와 Pinecone 대신 사용하기로 결정했습니다.

 

당시 GPT-5를 유료로 사용하고 있었는데 RAG를 설계하는 과정에서 Weaviate 코드 작성을 요청했고, gpt는 v3로 작성된 코드를 줘서 안그래도 시간이 부족한데 공식문서까지 뜯어보면서 수정을 한 기억이 있네요...

 

혹시 프로젝트와 세부 설정까지 끝난 코드가 궁금하시다면 아래의 HAND 깃허브를 방문하면 전부 확인하실 수 있습니다.

https://github.com/joo9906/HAND

 

GitHub - joo9906/HAND: 감정 완화 서비스의 AI 서버입니다.

감정 완화 서비스의 AI 서버입니다. Contribute to joo9906/HAND development by creating an account on GitHub.

github.com


사용방법

1. 초기 설정

Weaviate를 사용하기 위해서는 먼저 Docker Desktop을 설치해야 합니다.

컴퓨터에 맞는 버전을 설치 후 바로 활성화 해주세요.

https://docs.docker.com/desktop/setup/install/windows-install/

 

Windows

Get started with Docker for Windows. This guide covers system requirements, where to download, and instructions on how to install and update.

docs.docker.com

 

Weaviate 라이브러리를 설치해줍시다. 0.1.2 이후 버전이면 됩니다.

pip install pip install -U weaviate-client[agents]

 

로컬 기준으로 Weaviate에서 제공해주는 기본 docker-compose.yml 코드입니다.
docker-compose.yml 파일을 생성 후 아래의 코드를 붙여넣기 하시면 됩니다.

---
services:
  weaviate:
    command:
    - --host
    - 0.0.0.0
    - --port
    - '8080'
    - --scheme
    - http
    image: cr.weaviate.io/semitechnologies/weaviate:1.35.9
    ports:
    - 8080:8080
    - 50051:50051
    volumes:
    - weaviate_data:/var/lib/weaviate
    restart: on-failure:0
    environment:
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      CLUSTER_HOSTNAME: 'node1'
volumes:
  weaviate_data:

 

파일을 생성한 후 docker compose up -d를 터미널에 입력하고, 아래와 같은 내용이 뜨면 성공입니다.

curl http://localhost:8080/v1/meta을 입력하거나, http://localhost:8080/v1/meta 에 직접 들어가 보셔도 됩니다.


2. Weaviate 연결

이제 Docker에 띄우기 성공했다면, 연결도 해보겠습니다.
일단은 Weaviate 클라우드가 아닌 다른 임베딩 모델을 사용하는 코드로 작성하겠습니다.


HAND 프로젝트에서 AI 서버의 Vector DB 포트 번호는 8080, GRPC는 50051이었습니다.
혹시라도 서버가 있으시다면 본인에게 맞는 서버로 환경 변수를 수정해서 사용하시면 됩니다.

import os
from dotenv import load_dotenv
import weaviate

# Weaviate랑 연결 - 환경 변수 사용
WEAVIATE_HOST = os.getenv("WEAVIATE_HOST", "localhost")
WEAVIATE_HTTP_PORT = int(os.getenv("WEAVIATE_PORT", "8080"))
WEAVIATE_GRPC_PORT = int(os.getenv("WEAVIATE_GRPC_PORT", "50051"))

print(f"🔗 Weaviate 연결: {WEAVIATE_HOST}:{WEAVIATE_HTTP_PORT}")

client = weaviate.connect_to_custom(
    http_host=WEAVIATE_HOST,
    http_port=WEAVIATE_HTTP_PORT,
    grpc_host=WEAVIATE_HOST,
    grpc_port=WEAVIATE_GRPC_PORT,
    http_secure=False,
    grpc_secure=False,
    )

print(client.is_ready()) # True가 나오면 연결 성공입니다.

 

만약 Weaviate Cloud로 작업을 하게 되신다면 아래의 코드로 client를 교체하시면 됩니다.

with weaviate.connect_to_weaviate_cloud(
    cluster_url=weaviate_url,
    auth_credentials=weaviate_api_key,
) as client:

3. 컬렉션 생성

맨땅에 데이터를 넣을 순 없으니, 테이블(컬렉션)을 만들어 봅시다.


컬렉션을 만드는 함수는

client.collections.create(name='이름', description='설명', vector_config='임베딩 방법', properties=[컬럼]) 입니다.

import weaviate
import weaviate.classes.config as wvc

# Class 생성 및 필드 설정
existing = client.collections.list_all()

if "FirstCollection" not in existing:
    first_collection = client.collections.create(
        name="FirstCollection",
        description="처음으로 생성한 컬렉션",
        vector_config=wvc.Configure.Vectors.self_provided(), # 직접 임베딩 할거기 때문에 self_provided()를 사용합니다.
        properties=[
            wvc.Property(name="input", data_type=wvc.config.DataType.TEXT),
            wvc.Property(name="output", data_type=wvc.config.DataType.TEXT),
        ],
    )
    print("✅ FirstCollection 컬렉션 생성 완료")
else:
    print("✅ FirstCollection 이미 존재. 생성 생략.")

SQL식으로 말하자면 테이블이지만 Weaviate에서는 collection을 통해 데이터를 삽입 할 공간을 확보하는데, 설명이나 embedding 모델 등을 커스터마이징 할 수 있다는 점에서 큰 차이를 갖습니다.

 

컬럼은 properties로 생성하는데, 리스트 형식으로 되어있고 wvc.Property(name='컬럼명', data_type = wvc.DataType.자료형) 으로 넣어주시면 됩니다.
리스트 형식과 타입 힌트를 보며 파이썬 친화적인 Vector DB라고 느꼈습니다.

 

프로젝트 개발 당시 인프라를 담당하던 팀원이 할일이 너무 많아 Weaviate 쪽 코드는 공부를 하진 못해서 existing을 통해 컬렉션 유무를 파악하고 없으면 생성, 있으면 넘어가도록 했습니다. 이 예외처리가 없을 땐 서버를 내렸다 올리는 과정에서 한두번씩 터지는 경우가 있었는데 이후로는 괜찮아졌습니다.

 

AI를 활용해서 코드를 만들어 달라고 하면 마지막에 꼭 client.close() 코드를 붙여주는데, 해당 코드를 지우지 않으면 연결을 종료해버리므로 데이터의 삽입이나 추가 작업이 불가능하니 없애주세요. 터미널에 경고가 떠도 별로 의미있는 내용은 아니므로 모든 작업을 끝내고 코드 마지막에 추가해주시면 됩니다.


4. 데이터 삽입

OpenAI API 기준으로 embedding 까지 적용하며 들어가보겠습니다.

제 데이터는 json으로 작성되었으므로 json을 읽는 함수도 포함시켜 놨습니다.

# jsonl 파일 가공을 위한 함수
def load_jsonl(path):
    with open(path, "r", encoding="utf-8") as f:
        return [json.loads(line) for line in f if line.strip()]

class Embedding():
    def __init__(self):
        self.api_key = API_KEY
        self.emb_model = EMB_MODEL
        self.emb_url = EMB_URL
    # 임베딩
    def embed(self, text: str) -> list:
        headers = {
            "Content-type": "application/json",
            "Authorization": f"Bearer {self.api_key}",
        }
        payload = {"model": self.emb_model, "input": text}

        res = requests.post(self.emb_url, headers=headers, json=payload)
        res.raise_for_status()

        result = res.json()["data"][0]["embedding"]

        return [float(v) for v in result]
        
emb = Embedding()

위의 embed 함수를 사용하면 앞으로 text를 vector로 변환하여 줍니다. 

 

이후 삽입할 컬렉션을 선택하고, 임베딩하여 넣어주면 되는데 컬렉션은 딕셔너리 형식으로 작성되어 있기에 get 함수를 사용하면 컬렉션의 이름으로 찾아올 수 있습니다.
enumerate 함수는 인덱스와 값을 매칭해주는 것으로 ['a', 'b', 'c']가 있을 때 (1, a) (2, b) (3, c) 로 매칭해줍니다.
인덱스를 활용해야 할 때 필수입니다.

 

그리고 임베딩을 API 호출로 활용하다 보니 여러 이슈로 뻑나는 경우가 있어 벡터 검증을 하는 코드를 넣어 두었습니다.

first_data = load_jsonl("first_data.jsonl")
first_collection = client.collections.get("FirstCollection")

for idx, d in enumerate(single_data):
    try:
        # 1. 임베딩 생성 (에러 처리 포함)
        vector_embedding = emb.embed(d["input"])

        # 2. 벡터 검증
        if not vector_embedding or len(vector_embedding) == 0:
            print(f"❌ Row {idx}: 벡터가 비어있습니다")
            continue

        # 3. 데이터 객체 생성
        data_object = {
            "input": d["input"].strip(),
            "output": d["output"].strip()
        }

        # 4. Insert 및 반환값 확인
        uuid = single_collection.data.insert(
            properties=data_object,
            vector=vector_embedding
        )
        print(f"✅ Single {idx}: 저장 완료 (UUID: {uuid})")

    except Exception as e:
        print(f"❌ Row {idx} 에러: {str(e)}")
        continue

 


마무리하며

이렇게 4단계를 거치면 json 형식의 데이터셋을 임베딩까지 완료해서 Weaviate에 저장하는 코드가 완성되었습니다.

 

Weaviate Cloud를 사용하면 코드가 조금씩 달라지지만, 사실 Weaviate를 활용하는 이유가 커스터마이징이 가능하다는 점이 크다고 생각하여 다른 임베딩 모델을 사용하는 것으로 작성하였습니다.

 

다음 게시글에는 저장된 데이터를 가져와서 RAG에 붙여보도록 하겠습니다.

'AI 관련 지식 > VDB' 카테고리의 다른 글

[Vector DB] Weaviate 고도화  (0) 2026.06.09