Chroma 벡터 스토어
Chroma 벡터 스토어 (Spring AI)
임베딩 데이터베이스로 검색까지 함께 해결하고 싶다면 Chroma가 가볍고 좋은 선택이에요. 이 글은 Chroma VectorStore를 설정해서 문서 임베딩을 저장하고 유사도 검색을 수행하는 과정을 안내해요.
Chroma는 오픈소스 임베딩 데이터베이스예요. 문서 임베딩, 콘텐츠, 메타데이터를 저장하고, 메타데이터 필터링을 포함한 임베딩 검색을 할 수 있는 도구를 제공해요.
사전 준비 (Prerequisites)
- ChromaDB에 접근 가능해야 해요. Chroma Cloud와 호환되며, 부록의 로컬 ChromaDB 설정에서 Docker 컨테이너로 로컬 DB를 구성하는 방법을 보여 줘요.
- Chroma Cloud: 대시보드에서 API 키, tenant 이름, database 이름을 준비해요.
- 로컬 ChromaDB: 컨테이너를 시작하는 것 외에 추가 설정이 필요 없어요.
- 문서 임베딩을 계산할
EmbeddingModel인스턴스가 필요해요. 필요한 경우ChromaVectorStore에 저장할 임베딩을 생성하는EmbeddingModel용 API 키를 준비해요.
시작 시 ChromaVectorStore는 컬렉션이 없으면 필요한 컬렉션을 생성해요.
자동 설정 (Auto-configuration)
중요: Spring AI 자동 설정과 스타터 모듈의 아티팩트 이름에 큰 변화가 있었어요. 자세한 내용은 upgrade notes를 확인해 주세요.
Spring AI는 Chroma 벡터 스토어용 Spring Boot 자동 설정을 제공해요. 활성화하려면 프로젝트의 Maven pom.xml에 다음 의존성을 추가해요.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-chroma</artifactId>
</dependency>
또는 Gradle build.gradle 파일에 이렇게 넣어요.
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-vector-store-chroma'
}
참고: 스프링 AI BOM은 Dependency Management, Maven Central/Snapshot 저장소 추가는 Artifact Repositories 섹션을 참고해요.
벡터 스토어 구현이 필요한 스키마를 직접 초기화해 줄 수 있지만, 반드시 옵트인해야 해요. 적절한 생성자에서 initializeSchema 불리언을 지정하거나 application.properties 파일에 ...initialize-schema=true를 설정하면 돼요.
중요: 이것은 breaking change예요! 이전 버전의 Spring AI에서는 이 스키마 초기화가 기본으로 동작했어요.
또한 설정된 EmbeddingModel 빈이 필요해요. EmbeddingModel 섹션을 참고하면 되는데, 필요한 빈의 예시는 다음과 같아요.
@Bean
public EmbeddingModel embeddingModel() {
// Can be any other EmbeddingModel implementation.
return new OpenAiEmbeddingModel(OpenAiEmbeddingOptions.builder().apiKey(System.getenv("OPENAI_API_KEY")).build());
}
Chroma에 연결하려면 인스턴스 접근 정보를 제공해야 해요. Spring Boot의 application.properties로 간단히 설정할 수 있어요.
# Chroma Vector Store connection properties
spring.ai.vectorstore.chroma.client.host=<your Chroma instance host> // for Chroma Cloud: api.trychroma.com
spring.ai.vectorstore.chroma.client.port=<your Chroma instance port> // for Chroma Cloud: 443
spring.ai.vectorstore.chroma.client.key-token=<your access token (if configure)> // for Chroma Cloud: use the API key
spring.ai.vectorstore.chroma.client.username=<your username (if configure)>
spring.ai.vectorstore.chroma.client.password=<your password (if configure)>
# Chroma Vector Store tenant and database properties (required for Chroma Cloud)
spring.ai.vectorstore.chroma.tenant-name=<your tenant name> // default: SpringAiTenant
spring.ai.vectorstore.chroma.database-name=<your database name> // default: SpringAiDatabase
# Chroma Vector Store collection properties
spring.ai.vectorstore.chroma.initialize-schema=<true or false>
spring.ai.vectorstore.chroma.collection-name=<your collection name>
# Chroma Vector Store configuration properties
# OpenAI API key if the OpenAI auto-configuration is used.
spring.ai.openai.api.key=<OpenAI Api-key>
벡터 스토어의 기본값과 설정 옵션은 아래 configuration parameters 목록을 참고해 주세요.
이제 애플리케이션에서 Chroma 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());
설정 프로퍼티
벡터 스토어를 커스터마이즈할 수 있는 프로퍼티는 다음과 같아요.
| Property | Description | Default value |
|---|---|---|
spring.ai.vectorstore.chroma.client.host |
Server connection host | http://localhost |
spring.ai.vectorstore.chroma.client.port |
Server connection port | 8000 |
spring.ai.vectorstore.chroma.client.key-token |
Access token (if configured) | - |
spring.ai.vectorstore.chroma.client.username |
Access username (if configured) | - |
spring.ai.vectorstore.chroma.client.password |
Access password (if configured) | - |
spring.ai.vectorstore.chroma.tenant-name |
Tenant (required for Chroma Cloud) | SpringAiTenant |
spring.ai.vectorstore.chroma.database-name |
Database name (required for Chroma Cloud) | SpringAiDatabase |
spring.ai.vectorstore.chroma.collection-name |
Collection name | SpringAiCollection |
spring.ai.vectorstore.chroma.initialize-schema |
Whether to initialize the required schema (creates tenant/database/collection if they don't exist) | false |
참고: Static API Token Authentication으로 보호된 ChromaDB는
ChromaApi#withKeyToken(<Your Token Credentials>)메서드로 자격 증명을 설정해요. 기본 인증(Basic Authentication)으로 보호된 ChromaDB는ChromaApi#withBasicAuth(<your user>, <your password>)메서드를 사용해요.
Chroma Cloud 설정
Chroma Cloud에서는 Chroma Cloud 인스턴스의 tenant와 database 이름을 제공해야 해요. 설정 예시는 다음과 같아요.
# Chroma Cloud connection
spring.ai.vectorstore.chroma.client.host=api.trychroma.com
spring.ai.vectorstore.chroma.client.port=443
spring.ai.vectorstore.chroma.client.key-token=<your-chroma-cloud-api-key>
# Chroma Cloud tenant and database (required)
spring.ai.vectorstore.chroma.tenant-name=<your-tenant-id>
spring.ai.vectorstore.chroma.database-name=<your-database-name>
# Collection configuration
spring.ai.vectorstore.chroma.collection-name=my-collection
spring.ai.vectorstore.chroma.initialize-schema=true
참고: Chroma Cloud의 경우
- host는
api.trychroma.com이어야 해요.- port는
443(HTTPS)이어야 해요.key-token으로 API 키를 반드시 제공해야 해요.- tenant와 database 이름은 Chroma Cloud 설정과 일치해야 해요.
initialize-schema=true로 설정하면 컬렉션이 없을 때 자동 생성해요(기존 tenant/database는 다시 만들지 않아요).
메타데이터 필터링 (Metadata filtering)
ChromaVector 스토어에서도 일반적이고 이식 가능한 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("john", "jill"),
b.eq("article_type", "blog")).build()).build());
참고: 이 (이식 가능한) 필터 표현식들은 Chroma 고유의
where필터 표현식으로 자동 변환돼요.
예를 들어 이 이식 가능한 필터 표현식:
author in ['john', 'jill'] && article_type == 'blog'
은 Chroma 고유 형식으로 이렇게 변환돼요.
{"$and":[
{"author": {"$in": ["john", "jill"]}},
{"article_type":{"$eq":"blog"}}]
}
수동 설정 (Manual Configuration)
Chroma Vector Store를 수동으로 구성하고 싶다면 Spring Boot 애플리케이션에서 ChromaVectorStore 빈을 만들어 주면 돼요.
프로젝트에 다음 의존성을 추가해요.
- Chroma VectorStore.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-chroma-store</artifactId>
</dependency>
- OpenAI: 임베딩 계산에 필요해요. 다른 임베딩 모델 구현을 사용해도 돼요.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
참고: 스프링 AI BOM을 빌드 파일에 추가하는 방법은 Dependency Management 섹션을 참고해요.
샘플 코드
적절한 ChromaDB 인증 설정으로 RestClient.Builder 인스턴스를 만들고, 그것으로 ChromaApi 인스턴스를 생성해요.
@Bean
public RestClient.Builder builder() {
return RestClient.builder().requestFactory(new SimpleClientHttpRequestFactory());
}
@Bean
public ChromaApi chromaApi(RestClient.Builder restClientBuilder) {
String chromaUrl = "http://localhost:8000";
ChromaApi chromaApi = new ChromaApi(chromaUrl, restClientBuilder);
return chromaApi;
}
Spring Boot OpenAI 스타터를 프로젝트에 추가해서 OpenAI의 임베딩과 통합해요. 이렇게 하면 Embeddings 클라이언트 구현이 제공돼요.
@Bean
public VectorStore chromaVectorStore(EmbeddingModel embeddingModel, ChromaApi chromaApi) {
return ChromaVectorStore.builder(chromaApi, embeddingModel)
.tenantName("your-tenant-name") // default: SpringAiTenant
.databaseName("your-database-name") // default: SpringAiDatabase
.collectionName("TestCollection")
.initializeSchema(true)
.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")));
벡터 스토어에 문서를 추가해요.
vectorStore.add(documents);
그리고 마지막으로 쿼리와 유사한 문서를 검색해요.
List<Document> results = vectorStore.similaritySearch("Spring");
모든 게 잘 되면 "Spring AI rocks!!" 텍스트를 포함한 문서가 검색돼요.
Chroma 로컬 실행
docker run -it --rm --name chroma -p 8000:8000 ghcr.io/chroma-core/chroma:1.0.0
http://localhost:8000/api/v1에 chroma 스토어가 시작돼요.