Pinecone 벡터 스토어
Pinecone 벡터 스토어 (Spring AI)
클라우드에서 관리되는 벡터 DB를 그대로 쓰고 싶다면 Pinecone이 편리한 선택이에요. 이 글은 Pinecone VectorStore를 설정해서 문서 임베딩을 저장하고 유사도 검색을 수행하는 과정을 안내해요.
Pinecone은 널리 쓰이는 클라우드 기반 벡터 데이터베이스로, 벡터를 효율적으로 저장하고 검색할 수 있게 해 줘요.
사전 준비 (Prerequisites)
- Pinecone 계정: 시작하기 전에 Pinecone 계정에 가입해요.
- Pinecone 프로젝트: 등록 후 API 키를 생성하고 인덱스를 만들어요. 설정에 필요한 정보예요.
- 문서 임베딩을 계산할
EmbeddingModel인스턴스. 필요한 경우PineconeVectorStore에 저장할 임베딩을 생성하는EmbeddingModel용 API 키를 준비해요.
PineconeVectorStore를 설정하려면 Pinecone 계정에서 다음 정보를 준비해요.
- Pinecone API Key
- Pinecone Index Name
- Pinecone Namespace
참고: 이 정보는 Pinecone UI 포털에서 확인할 수 있어요. 네임스페이스는 무료 Starter 플랜을 포함한 모든 현재 Pinecone 플랜에서 지원되며, 서버리스 인덱스당 최대 네임스페이스 수는 플랜에 따라 달라져요.
자동 설정 (Auto-configuration)
중요: Spring AI 자동 설정과 스타터 모듈의 아티팩트 이름에 큰 변화가 있었어요. 자세한 내용은 upgrade notes를 확인해 주세요.
Spring AI는 Pinecone 벡터 스토어용 Spring Boot 자동 설정을 제공해요. 활성화하려면 Maven pom.xml에 다음 의존성을 추가해요.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-pinecone</artifactId>
</dependency>
또는 Gradle build.gradle 파일에 이렇게 넣어요.
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-vector-store-pinecone'
}
참고: 스프링 AI BOM은 Dependency Management, Maven Central/Snapshot 저장소 추가는 Artifact Repositories 섹션을 참고해요.
또한 설정된 EmbeddingModel 빈이 필요해요. EmbeddingModel 섹션을 참고하면 되는데, 필요한 빈의 예시는 다음과 같아요.
@Bean
public EmbeddingModel embeddingModel() {
// Can be any other EmbeddingModel implementation.
return new OpenAiEmbeddingModel(OpenAiEmbeddingOptions.builder().apiKey(System.getenv("OPENAI_API_KEY")).build());
}
Pinecone에 연결하려면 인스턴스 접근 정보를 제공해야 해요. Spring Boot의 application.properties로 간단히 설정할 수 있어요.
spring.ai.vectorstore.pinecone.api-key=<your api key>
spring.ai.vectorstore.pinecone.index-name=<your index name>
# API key if needed, e.g. OpenAI
spring.ai.openai.api.key=<api-key>
벡터 스토어의 기본값과 설정 옵션은 아래 configuration parameters 목록을 참고해 주세요.
이제 애플리케이션에서 Pinecone Vector Store를 오토와이어해서 사용할 수 있어요.
@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
vectorStore.add(documents);
// Retrieve documents similar to a query
List<Document> results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());
설정 프로퍼티
Pinecone 벡터 스토어를 커스터마이즈할 수 있는 프로퍼티는 다음과 같아요.
| Property | Description | Default value |
|---|---|---|
spring.ai.vectorstore.pinecone.api-key |
Pinecone API Key | - |
spring.ai.vectorstore.pinecone.index-name |
Pinecone index name | - |
spring.ai.vectorstore.pinecone.namespace |
Pinecone namespace | - |
spring.ai.vectorstore.pinecone.content-field-name |
Pinecone metadata field name used to store the original text content. | document_content |
spring.ai.vectorstore.pinecone.distance-metadata-field-name |
Pinecone metadata field name used to store the computed distance. | distance |
spring.ai.vectorstore.pinecone.server-side-timeout |
20 sec. |
메타데이터 필터링 (Metadata filtering)
Pinecone 스토어에서도 일반적이고 이식 가능한 metadata filters를 활용할 수 있어요.
예를 들어 텍스트 표현 언어로 필터링할 수 있고,
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());
참고: 이 필터 표현식들은 동등한 Pinecone 필터로 변환돼요.
수동 설정 (Manual Configuration)
PineconeVectorStore를 수동으로 구성하고 싶다면 PineconeVectorStore#Builder를 사용하면 돼요.
프로젝트에 다음 의존성을 추가해요.
- OpenAI: 임베딩 계산에 필요해요.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
- Pinecone
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pinecone-store</artifactId>
</dependency>
참고: 스프링 AI BOM을 빌드 파일에 추가하는 방법은 Dependency Management 섹션을 참고해요.
샘플 코드
애플리케이션에서 Pinecone을 구성하는 방법은 다음과 같아요.
@Bean
public VectorStore pineconeVectorStore(EmbeddingModel embeddingModel) {
return PineconeVectorStore.builder(embeddingModel)
.apiKey(PINECONE_API_KEY)
.indexName(PINECONE_INDEX_NAME)
.namespace(PINECONE_NAMESPACE)
.contentFieldName(CUSTOM_CONTENT_FIELD_NAME) // optional field to store the original content. Defaults to `document_content`
.build();
}
메인 코드에서 문서를 몇 개 만들어요.
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")));
Pinecone에 문서를 추가해요.
vectorStore.add(documents);
그리고 마지막으로 쿼리와 유사한 문서를 검색해요.
List<Document> results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());
모든 게 잘 되면 "Spring AI rocks!!" 텍스트를 포함한 문서가 검색돼요.
네이티브 클라이언트 접근
Pinecone 벡터 스토어 구현은 getNativeClient() 메서드를 통해 내부의 네이티브 Pinecone 클라이언트(Pinecone)에 접근할 수 있게 해 줘요.
PineconeVectorStore vectorStore = context.getBean(PineconeVectorStore.class);
Optional<Pinecone> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
Pinecone client = nativeClient.get();
// Use the native client for Pinecone-specific operations
}
네이티브 클라이언트는 VectorStore 인터페이스로 노출되지 않는 Pinecone 고유 기능과 연산에 접근할 수 있게 해 줘요.