Oracle Database 23ai - AI Vector Search

Oracle Database 23ai (23.4+)의 AI Vector Search 기능은 Spring AI VectorStore로 사용할 수 있어서 문서 임베딩을 저장하고 유사도 검색을 수행하는 데 도움을 줘요. 물론 다른 모든 기능도 사용할 수 있어요.

출처: 문서

본문

Oracle Database 23ai (23.4+)의 AI Vector Search 기능은 Spring AI VectorStore로 사용할 수 있어서 문서 임베딩을 저장하고 유사도 검색을 수행하는 데 도움을 줘요. 물론 다른 모든 기능도 사용할 수 있어요.

참고: Run Oracle Database 23ai locally 부록은 가벼운 Docker 컨테이너로 데이터베이스를 시작하는 방법을 보여 줘요.

자동 구성 (Auto-Configuration)

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

프로젝트에 Oracle Vector Store boot starter 의존성을 추가하는 것으로 시작하세요:

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

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

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

이 벡터 스토어가 스키마를 초기화하도록 하려면 적절한 생성자에서 initializeSchema boolean 파라미터에 true를 전달하거나 application.properties 파일에서 …initialize-schema=true를 설정해야 해요.

참고: 이것은 호환성을 깨는 변경이에요! 이전 버전의 Spring AI에서는 이 스키마 초기화가 기본으로 일어났어요.

Vector Store는 문서의 임베딩을 계산하기 위한 EmbeddingModel 인스턴스도 요구해요. 사용 가능한 EmbeddingModel 구현 중 하나를 선택할 수 있어요. 예를 들어 OpenAI EmbeddingModel을 사용하려면 프로젝트에 다음 의존성을 추가하세요:

<dependency>
	<groupId>org.springframework.ai</groupId>
	<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

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

dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-model-openai'
}

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

OracleVectorStore를 연결하고 구성하려면 데이터베이스의 접근 세부 정보를 제공해야 해요. 간단한 구성은 Spring Boot의 application.yml로 제공할 수 있어요.

spring:
  datasource:
    url: jdbc:oracle:thin:@//localhost:1521/freepdb1
    username: mlops
    password: mlops
  ai:
	vectorstore:
	  oracle:
		index-type: IVF
		distance-type: COSINE
		dimensions: 1536

참고: 기본값과 구성 옵션을 알려면 구성 파라미터 목록을 확인하세요.

이제 애플리케이션에서 OracleVectorStore를 오토와이어해서 사용할 수 있어요:

@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 Oracle Vector Store
vectorStore.add(documents);

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

구성 프로퍼티 (Configuration properties)

Spring Boot 구성에서 다음 프로퍼티를 사용해 OracleVectorStore를 커스터마이즈할 수 있어요.

Property Description Default value
spring.ai.vectorstore.oracle.index-type 최근접 이웃 검색 인덱스 타입. 옵션은 NONE - 정확한 최근접 이웃 검색, IVF - Inverted Flat File 인덱스. 빌드 시간이 더 빠르고 HNSW보다 메모리를 덜 쓰지만 쿼리 성능은 더 낮아요(속도-재현율 트레이드오프 기준). HNSW - 다층 그래프를 생성. 빌드 시간이 더 느리고 IVF보다 메모리를 더 쓰지만 쿼리 성능이 더 좋아요(속도-재현율 트레이드오프 기준). NONE
spring.ai.vectorstore.oracle.distance-type COSINE(기본값), DOT, EUCLIDEAN, EUCLIDEAN_SQUARED, MANHATTAN 중 검색 거리 타입. 참고: 벡터가 정규화되어 있으면 최고 성능을 위해 DOT이나 COSINE을 사용할 수 있어요. COSINE
spring.ai.vectorstore.oracle.forced-normalization 삽입 전과 유사도 검색에 벡터 정규화를 활성화할지 여부(true면). 주의: 검색 요청 유사도 임계값을 허용하려면 true로 설정해야 해요. 참고: 벡터가 정규화되어 있으면 최고 성능을 위해 DOT이나 COSINE을 사용할 수 있어요. false
spring.ai.vectorstore.oracle.dimensions 임베딩 차원. 명시적으로 지정하지 않으면 OracleVectorStore가 최대 65535를 허용해요. 차원은 테이블 생성 시 임베딩 컬럼에 설정돼요. 차원을 바꾸면 테이블도 다시 만들어야 해요. 65535
spring.ai.vectorstore.oracle.remove-existing-vector-store-table 시작 시 기존 테이블을 삭제. false
spring.ai.vectorstore.oracle.initialize-schema 필요한 스키마를 초기화할지 여부. false
spring.ai.vectorstore.oracle.search-accuracy 인덱스 존재 시 요청된 정확도 목표를 나타냄. 기본적으로 비활성화. 기본 인덱스 정확도(95)를 재정의하려면 [1,100] 범위의 정수를 제공해야 해요. 낮은 정확도를 사용하면 속도-정확도를 맞바꾸는 근사 유사도 검색을 제공해요. -1 (DEFAULT_SEARCH_ACCURACY)

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

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

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

vectorStore.similaritySearch(
    SearchRequest.builder()
    .query("The World")
    .topK(TOP_K)
    .similarityThreshold(SIMILARITY_THRESHOLD)
    .filterExpression("author in ['john', 'jill'] && article_type == 'blog'").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("author","john", "jill"),
        b.eq("article_type", "blog")).build()).build());

참고: 이 필터 표현식은 동일한 OracleVectorStore 필터로 변환돼요.

수동 구성 (Manual Configuration)

Spring Boot 자동 설정 대신 OracleVectorStore를 수동 구성할 수 있어요. 이를 위해 프로젝트에 Oracle JDBC 드라이버와 JdbcTemplate 자동 설정 의존성을 추가해야 해요:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
	<groupId>com.oracle.database.jdbc</groupId>
	<artifactId>ojdbc11</artifactId>
	<scope>runtime</scope>
</dependency>

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

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

애플리케이션에서 OracleVectorStore를 구성하려면 다음 설정을 사용할 수 있어요:

@Bean
public VectorStore vectorStore(JdbcTemplate jdbcTemplate, EmbeddingModel embeddingModel) {
    return OracleVectorStore.builder(jdbcTemplate, embeddingModel)
        .tableName("my_vectors")
        .indexType(OracleVectorStoreIndexType.IVF)
        .distanceType(OracleVectorStoreDistanceType.COSINE)
        .dimensions(1536)
        .searchAccuracy(95)
        .initializeSchema(true)
        .build();
}

Oracle Database 23ai 로컬 실행 (Run Oracle Database 23ai locally)

docker run --rm --name oracle23ai -p 1521:1521 -e APP_USER=mlops -e APP_USER_PASSWORD=mlops -e ORACLE_PASSWORD=mlops gvenzl/oracle-free:23-slim

그런 다음 다음을 사용해 데이터베이스에 연결할 수 있어요:

sql mlops/mlops@localhost/freepdb1

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

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

OracleVectorStore vectorStore = context.getBean(OracleVectorStore.class);
Optional<OracleConnection> nativeClient = vectorStore.getNativeClient();

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

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

더 알아보기 (Learn more)