Typesense 벡터 스토어

Typesense 벡터 스토어 (Typesense)

이 섹션에서는 TypesenseVectorStore를 설정해서 문서 임베딩을 저장하고 유사도 검색을 수행하는 방법을 안내해요. Typesense는 50ms 미만의 즉각적인 검색에 최적화된 오픈소스 오타 허용 검색 엔진으로, 직관적인 개발자 경험을 제공해요. 일반 검색 데이터와 함께 고차원 벡터를 저장·질의할 수 있는 벡터 검색 기능을 제공해요.

출처: 문서

본문

Typesense

이 섹션은 TypesenseVectorStore를 설정해 문서 임베딩을 저장하고 유사도 검색을 수행하는 방법을 안내해요.

Typesense는 즉각적인 50ms 미만 검색에 최적화되고 직관적인 개발자 경험을 제공하는 오픈소스 오타 허용 검색 엔진이에요. 일반 검색 데이터와 함께 고차원 벡터를 저장·질의할 수 있는 벡터 검색 기능을 제공해요.

사전 준비 (Prerequisites)

  • 실행 중인 Typesense 인스턴스. 다음 옵션이 가능해요:

  • 필요하다면, TypesenseVectorStore가 저장하는 임베딩을 생성하기 위한 EmbeddingModel용 API 키.

자동 설정 (Auto-configuration)

참고: Spring AI auto-configuration과 starter 모듈의 아티팩트 이름에 큰 변화가 있었어요. 자세한 내용은 upgrade notes를 참고해 주세요.

Spring AI는 Typesense Vector Store에 대한 Spring Boot 자동 설정을 제공해요. 활성화하려면 프로젝트의 Maven pom.xml 파일에 다음 의존성을 추가하세요:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-vector-store-typesense</artifactId>
</dependency>

또는 Gradle build.gradle 빌드 파일에:

dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-vector-store-typesense'
}

참고: 빌드 파일에 Spring AI BOM을 추가하려면 Dependency Management 섹션을 참고해 주세요.

기본값과 구성 옵션을 알려면 벡터 스토어의 구성 파라미터 목록을 살펴보세요.

참고: 빌드 파일에 Maven Central 및/또는 Snapshot 저장소를 추가하려면 Artifact Repositories 섹션을 참고해 주세요.

벡터 스토어 구현은 필요한 스키마를 초기화할 수 있지만 application.properties 파일에서 …initialize-schema=true를 설정해 선택해야 해요. 추가로 구성된 EmbeddingModel 빈이 필요해요. 자세한 내용은 EmbeddingModel 섹션을 참고하세요.

이제 애플리케이션에서 TypesenseVectorStore를 벡터 스토어로 오토와이어할 수 있어요:

@Autowired VectorStore vectorStore;

// ...

List<Document> documents = List.of(
    new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")),
    new Document("The World is Big and Salvation Lurks Around the Corner"),
    new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")));

// Add the documents to Typesense
vectorStore.add(documents);

// Retrieve documents similar to a query
List<Document> results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());

구성 프로퍼티 (Configuration Properties)

Typesense에 연결하고 TypesenseVectorStore를 사용하려면 인스턴스의 접근 세부 정보를 제공해야 해요. 간단한 구성은 Spring Boot의 application.yml로 제공할 수 있어요:

spring:
  ai:
    vectorstore:
      typesense:
        initialize-schema: true
        collection-name: vector_store
        embedding-dimension: 1536
        client:
          protocol: http
          host: localhost
          port: 8108
          api-key: ***

spring.ai.vectorstore.typesense.*로 시작하는 프로퍼티는 TypesenseVectorStore를 구성하는 데 사용돼요:

Property Description Default Value
spring.ai.vectorstore.typesense.initialize-schema 필요한 스키마를 초기화할지 여부 false
spring.ai.vectorstore.typesense.collection-name 벡터를 저장할 collection의 이름 vector_store
spring.ai.vectorstore.typesense.embedding-dimension 벡터의 차원 수 1536
spring.ai.vectorstore.typesense.client.protocol HTTP 프로토콜 http
spring.ai.vectorstore.typesense.client.host 호스트 이름 localhost
spring.ai.vectorstore.typesense.client.port 포트 8108
spring.ai.vectorstore.typesense.client.api-key API 키 xyz

수동 구성 (Manual Configuration)

Spring Boot 자동 설정 대신 Typesense 벡터 스토어를 수동 구성할 수 있어요. 이를 위해 프로젝트에 spring-ai-typesense-store를 추가해야 해요:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-typesense-store</artifactId>
</dependency>

또는 Gradle build.gradle 빌드 파일에:

dependencies {
    implementation 'org.springframework.ai:spring-ai-typesense-store'
}

참고: 빌드 파일에 Spring AI BOM을 추가하려면 Dependency Management 섹션을 참고해 주세요.

Typesense Client 빈을 만드세요:

@Bean
public Client typesenseClient() {
    List<Node> nodes = new ArrayList<>();
    nodes.add(new Node("http", "localhost", "8108"));
    Configuration configuration = new Configuration(nodes, Duration.ofSeconds(5), "xyz");
    return new Client(configuration);
}

그런 다음 빌더 패턴으로 TypesenseVectorStore 빈을 만드세요:

@Bean
public VectorStore vectorStore(Client client, EmbeddingModel embeddingModel) {
    return TypesenseVectorStore.builder(client, embeddingModel)
        .collectionName("custom_vectors")     // Optional: defaults to "vector_store"
        .embeddingDimension(1536)            // Optional: defaults to 1536
        .initializeSchema(true)              // Optional: defaults to false
        .batchingStrategy(new TokenCountBatchingStrategy()) // Optional: defaults to TokenCountBatchingStrategy
        .build();
}

// This can be any EmbeddingModel implementation
@Bean
public EmbeddingModel embeddingModel() {
    return new OpenAiEmbeddingModel(OpenAiEmbeddingOptions.builder().apiKey(System.getenv("OPENAI_API_KEY")).build());
}

메타데이터 필터링 (Metadata Filtering)

Typesense 스토어에서도 일반적이고 휴대 가능한 메타데이터 필터를 활용할 수 있어요.

예를 들어 텍스트 표현 언어를 사용할 수 있어요:

vectorStore.similaritySearch(
    SearchRequest.builder()
        .query("The World")
        .topK(TOP_K)
        .similarityThreshold(SIMILARITY_THRESHOLD)
        .filterExpression("country in ['UK', 'NL'] && year >= 2020").build());

또는 Filter.Expression DSL로 프로그래밍 방식으로:

FilterExpressionBuilder b = new FilterExpressionBuilder();

vectorStore.similaritySearch(SearchRequest.builder()
    .query("The World")
    .topK(TOP_K)
    .similarityThreshold(SIMILARITY_THRESHOLD)
    .filterExpression(b.and(
        b.in("country", "UK", "NL"),
        b.gte("year", 2020)).build()).build());

참고: 이 (휴대 가능한) 필터 표현식은 자동으로 Typesense 검색 필터로 변환돼요.

예를 들어 이 휴대 가능한 필터 표현식:

country in ['UK', 'NL'] && year >= 2020

은 고유한 Typesense 필터 형식으로 변환돼요:

country: ['UK', 'NL'] && year: >=2020

참고: 문서가 예상 순서대로 검색되지 않거나 검색 결과가 예상과 다르면 사용 중인 임베딩 모델을 확인해 보세요.

임베딩 모델은 검색 결과에 상당한 영향을 줄 수 있어요 (즉, 데이터가 스페인어라면 스페인어 또는 다국어 임베딩 모델을 사용하는지 확인하세요).

네이티브 클라이언트 접근 (Accessing the Native Client)

Typesense Vector Store 구현은 getNativeClient() 메서드를 통해 내부 네이티브 Typesense 클라이언트(Client)에 접근을 제공해요:

TypesenseVectorStore vectorStore = context.getBean(TypesenseVectorStore.class);
Optional<Client> nativeClient = vectorStore.getNativeClient();

if (nativeClient.isPresent()) {
    Client client = nativeClient.get();
    // Use the native client for Typesense-specific operations
}

네이티브 클라이언트는 VectorStore 인터페이스로는 노출되지 않는 Typesense 특화 기능과 작업에 접근할 수 있게 해 줘요.

더 알아보기 (Learn more)