데이터 모델 정의하기

데이터 모델 정의하기 (Preview)

Semantic Kernel 벡터 스토어 커넥터는 모델 우선(model first) 접근 방식을 써요. 레코드를 upsert하거나 조회하는 모든 메서드에 강타입(strongly typed) 모델 클래스를 쓰고, 그 속성들에 각 속성의 역할을 나타내는 어트리뷰트/어노테이션을 붙이는 방식이죠.

어트리뷰트를 쓰는 대안으로 레코드 정의로 스키마를 정의하는 방법이나, 직접 데이터 모델을 정의하지 않고 쓰는 방법도 있어요. 하지만 이 페이지에선 가장 기본적인 "어트리뷰트로 모델 정의하기"를 다룹니다.

모델 예시

C#에서는 VectorStoreKey, VectorStoreData, VectorStoreVector 어트리뷰트로 각 속성의 역할을 표시해요. 아래는 호텔(Hotel) 모델 예시입니다.

using Microsoft.Extensions.VectorData;

public class Hotel
{
    [VectorStoreKey]
    public ulong HotelId { get; set; }

    [VectorStoreData(IsIndexed = true)]
    public string HotelName { get; set; }

    [VectorStoreData(IsFullTextIndexed = true)]
    public string Description { get; set; }

    [VectorStoreVector(Dimensions: 4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)]
    public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }

    [VectorStoreData(IsIndexed = true)]
    public string[] Tags { get; set; }
}

Python에서는 vectorstoremodel 데코레이터와 VectorStoreRecordKeyField, VectorStoreRecordDataField, VectorStoreRecordVectorField 어노테이션을 써요. 어노테이션은 dataclasses 모듈로 정의한 클래스에 붙이는데, Pydantic BaseModel이나 순수 파이썬 클래스로도 할 수 있어요.

from dataclasses import dataclass, field
from typing import Annotated
from semantic_kernel.data import (
    DistanceFunction,
    IndexKind,
    VectorStoreRecordDataField,
    VectorStoreRecordDefinition,
    VectorStoreRecordKeyField,
    VectorStoreRecordVectorField,
    vectorstoremodel,
)

@vectorstoremodel
@dataclass
class Hotel:
    hotel_id: Annotated[str, VectorStoreRecordKeyField()] = field(default_factory=lambda: str(uuid4()))
    hotel_name: Annotated[str, VectorStoreRecordDataField(is_filterable=True)]
    description: Annotated[str, VectorStoreRecordDataField(is_full_text_searchable=True)]
    description_embedding: Annotated[list[float], VectorStoreRecordVectorField(dimensions=4, distance_function=DistanceFunction.COSINE, index_kind=IndexKind.HNSW)]
    tags: Annotated[list[str], VectorStoreRecordDataField(is_filterable=True)]

어트리뷰트/어노테이션 살펴보기

각각 어떤 의미인지 하나씩 볼게요.

키 어트리뷰트 — VectorStoreKey / VectorStoreRecordKeyField

이 속성이 레코드의 키임을 나타낼 때 써요.

[VectorStoreKey]
public ulong HotelId { get; set; }

주요 파라미터:

  • StorageName (선택) — 속성의 DB 내 대체 이름을 지정할 수 있어요. 모든 커넥터가 지원하진 않고, JsonPropertyNameAttribute 같은 대안이 있는 경우도 있어요.

Python의 VectorStoreRecordKeyField는 기반 클래스 외에 별도 추가 파라미터가 없어요.

데이터 어트리뷰트 — VectorStoreData / VectorStoreRecordDataField

키나 벡터가 아닌 일반 데이터 속성임을 나타내요.

[VectorStoreData(IsIndexed = true)]
public string HotelName { get; set; }

주요 파라미터:

  • IsIndexed / is_filterable (선택) — DB가 속성별 인덱스 옵트인을 요구하는 경우 필터링용으로 인덱싱할지 여부. 기본값은 false.
  • IsFullTextIndexed / is_full_text_searchable (선택) — 전체 텍스트 검색을 지원하는 DB에서 전체 텍스트 검색용으로 인덱싱할지 여부. 기본값은 false.
  • StorageName (선택) — DB 내 대체 이름. 지원 여부는 커넥터별로 달라요.

Python의 VectorStoreRecordDataField에는 여기에 더해 has_embedding, embedding_property_name 같은 임베딩 연관 파라미터도 있어요.

벡터 어트리뷰트 — VectorStoreVector / VectorStoreRecordVectorField

이 속성이 벡터임을 나타내요.

[VectorStoreVector(Dimensions: 4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)]
public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }

주요 파라미터:

  • Dimensions / dimensions (컬렉션 생성 시 필수) — 벡터의 차원 수. 컬렉션의 벡터 인덱스를 만들 때 필요해요.
  • IndexKind / index_kind (선택) — 벡터를 인덱싱할 인덱스 종류. 기본값은 벡터 스토어 타입마다 달라요.
  • DistanceFunction / distance_function (선택) — 벡터 검색 시 벡터 비교에 쓰는 함수 종류. 기본값은 벡터 스토어 타입마다 달라요.
  • StorageName (선택) — DB 내 대체 이름. 지원 여부는 커넥터별로 달라요.

흥미로운 점은 VectorStoreVector 어트리뷰트를 벡터 타입이 아닌 속성(예: string)에도 쓸 수 있다는 거예요. 이렇게 하면 벡터 스토어에 Microsoft.Extensions.AI.IEmbeddingGenerator 인스턴스를 제공해야 해요. 그럼 upsert 시 string 속성의 텍스트가 자동으로 벡터로 변환되어 DB에 벡터로 저장돼요. 단, 이 방식으로는 벡터를 다시 조회할 수 없어요.

[VectorStoreVector(Dimensions: 4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)]
public string DescriptionEmbedding { get; set; }

일반적인 인덱스 종류와 거리 함수 타입은 Microsoft.SemanticKernel.Data.IndexKindMicrosoft.SemanticKernel.Data.DistanceFunction 클래스, Python에선 semantic_kernel.data.IndexKind·DistanceFunction에 정적 값으로 제공돼요. 개별 벡터 스토어 구현이 특이한 타입의 인덱스·거리 함수를 지원할 땐 자체 값을 쓸 수도 있어요.

출처: https://learn.microsoft.com/en-us/semantic-kernel/concepts/vector-store-connectors/defining-your-data-model