Bug description
When using VectorStoreChatMemoryAdvisor
to implement chat memory with Redis vector store, if spring.ai.vectorstore.redis.initialize-schema
is set to true
, the program will automatically create a Redis search schema, which causes RedisVectorStore
to be unable to retrieve related records.
The reason is that VectorStoreChatMemoryAdvisor
writes "conversationId"
as metadata into the document and uses conversationId
as the query condition. However, RedisVectorStoreProperties
does not support setting metadataFields
when automatically configuring RedisVectorStore
, leading to retrieval failure.
It is necessary to manually configure RedisVectorStore
to retrieve records correctly, like this (see code below), which is not elegant because it defeats the purpose of auto-configuration.
@Bean
public RedisVectorStore vectorStore(EmbeddingModel embeddingModel, RedisVectorStoreProperties properties,
JedisConnectionFactory jedisConnectionFactory, ObjectProvider<ObservationRegistry> observationRegistry,
ObjectProvider<VectorStoreObservationConvention> customObservationConvention,
BatchingStrategy batchingStrategy) {
JedisPooled jedisPooled = this.jedisPooled(jedisConnectionFactory);
return RedisVectorStore.builder(jedisPooled, embeddingModel)
.initializeSchema(properties.isInitializeSchema())
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
.customObservationConvention(customObservationConvention.getIfAvailable(() -> null))
.batchingStrategy(batchingStrategy)
.indexName(properties.getIndexName())
.prefix(properties.getPrefix())
// Set metadata fields to include conversationId for retrieval
.metadataFields(RedisVectorStore.MetadataField.tag("conversationId"))
.build();
}
Environment - Spring Boot: 3.4.6 - Spring AI: 1.0.0 - Java: 21 - Vector store: redis-stack v7.2.0
Steps to reproduce
1. Use VectorStoreChatMemoryAdvisor
with Redis vector store.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-advisors-vector-store</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-redis</artifactId>
<version>1.0.0</version>
</dependency>
// configuration
@Bean
public ChatClient chatClient(ChatClient.Builder clientBuilder, VectorStore vectorStore) {
return clientBuilder
.defaultSystem("You are a helpful assistant.")
.defaultAdvisors(VectorStoreChatMemoryAdvisor.builder(vectorStore).build())
.build();
}
- Set
spring.ai.vectorstore.redis.initialize-schema=true
.
spring:
data:
redis:
client-type: jedis
ai:
ollama:
chat:
options:
model: deepseek-r1
embedding:
options:
model: bge-m3
vectorstore:
redis:
initialize-schema: true
- Attempt to retrieve chat memory by
conversationId
in a conversation.
// controller
@GetMapping(value = "/stream/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestParam @NotBlank String prompt, @RequestParam @NotBlank String conversationId) {
return chatClient
.prompt(Prompt.builder().content(prompt).build())
.advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, conversationId))
.stream().content();
}
Expected behavior
Chat memory relevant to the current conversationId
should be retrievable automatically without manual configuration of RedisVectorStore
.
Possible solutions
1. Set spring.ai.vectorstore.redis.initialize-schema=false
and manually create the schema in Redis.
2. Add a List<MetadataField> metadataFields
property to RedisVectorStoreProperties
.
3. Use RedisVectorStore.Builder
as a dependency to build RedisVectorStore
, where RedisVectorStore.Builder
depends on RedisVectorStoreProperties
and provides a RedisVectorStoreBuilderCustomizer
for builder enhancement, like this:
// VectorStoreBuilderCustomizer.java
public interface VectorStoreBuilderCustomizer<T extends VectorStore.Builder<T>> {
void customize(T builder);
}
// RedisVectorStoreBuilderCustomizer.java
public interface RedisVectorStoreBuilderCustomizer extends VectorStoreBuilderCustomizer<RedisVectorStore.Builder> {
}
// RedisVectorStoreAutoConfiguration.java
@Bean
@ConditionalOnMissingBean
public RedisVectorStore.Builder vectorStoreBuilder(EmbeddingModel embeddingModel, RedisVectorStoreProperties properties,
JedisConnectionFactory jedisConnectionFactory, ObjectProvider<ObservationRegistry> observationRegistry,
ObjectProvider<VectorStoreObservationConvention> customObservationConvention,
BatchingStrategy batchingStrategy, ObjectProvider<RedisVectorStoreBuilderCustomizer> vectorStoreBuilderCustomizers) {
JedisPooled jedisPooled = this.jedisPooled(jedisConnectionFactory);
RedisVectorStore.Builder builder = RedisVectorStore.builder(jedisPooled, embeddingModel)
.initializeSchema(properties.isInitializeSchema())
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
.customObservationConvention(customObservationConvention.getIfAvailable(() -> null))
.batchingStrategy(batchingStrategy)
.indexName(properties.getIndexName())
.prefix(properties.getPrefix());
vectorStoreBuilderCustomizers.orderedStream().forEach(customizer -> customizer.customize(builder));
return builder;
}
@Bean
@ConditionalOnMissingBean
public RedisVectorStore vectorStore(RedisVectorStore.Builder vectorStoreBuilder) {
return vectorStoreBuilder.build();
}
I am not sure why RedisVectorStoreProperties
does not directly provide a metadataFields
property. If there is a reason, please consider solution 3. In fact, solution 3 does not explicitly depend on RedisVectorStoreProperties
, but instead uses RedisVectorStore.Builder
to determine how to build the RedisVectorStore
.
If you are open to my suggestion, I can propose a PR.
Comment From: byquan2004
I have similar problem,when I use the filterExpression method in redisVectorStore for similarity retrieval!
The above picture shows the problem I encountered. If I remove the filterExpression and use similarity search, there will be no problem of not being able to search.
I want to know whether the knowledgeId I added is considered metadata and whether it supports search. These problems also occurred when I used 1.0.0-m7.
My project environment redis-stack-server -- latest jdk -- 17 springai -- 1.0.0
Comment From: lanpf
@byquan2004 This is because RedisVectorStoreProperties does not support any metadataFields settings (as mentioned in the issue). You can manually configure RedisVectorStore, set your metadataFields to solve the problem. I am waiting for feedback from the community, and I think they should have seen this issue by now.