描述bug
在搜索过程中,RedisEmbeddingStore会在所有现有的Redis嵌入存储中找到嵌入,而不仅仅是当前的一个示例。
这个bug大约是在0.23.0版本时发现的,当时在RedisEmbeddingStoreIT中添加了一个待办事项注解:
// TODO fix: why redis returns embeddings from different indexes?
重现
使用相同的Redis示例创建至少两个Redis存储。
将嵌入添加到第一个存储后,在用第二个存储进行搜索时可以找到它们。
还可以运行以下测试(可以添加到RedisEmbeddingStoreIT):
@Test
void should_find_embedding_in_proper_store() {
final EmbeddingStore<TextSegment> firstStore = createStore("first-store");
final EmbeddingStore<TextSegment> secondStore = createStore("second-store");
Embedding embedding = embeddingModel().embed("hello").content();
String id = firstStore.add(embedding);
assertThat(id).isNotBlank();
List<EmbeddingMatch<TextSegment>> relevant = firstStore.findRelevant(embedding, 10);
assertThat(relevant).hasSize(1);
assertThat(secondStore.findRelevant(embedding, 10)).hasSize(0);
// new API
assertThat(firstStore.search(EmbeddingSearchRequest.builder()
.queryEmbedding(embedding)
.maxResults(10)
.build()).matches()).isEqualTo(relevant);
assertThat(secondStore.search(EmbeddingSearchRequest.builder()
.queryEmbedding(embedding)
.maxResults(10)
.build()).matches()).hasSize(0);
}
private EmbeddingStore<TextSegment> createStore(String name) {
return RedisEmbeddingStore.builder()
.host(redis.getHost())
.port(redis.getFirstMappedPort())
.indexName(name)
.dimension(384)
.metadataKeys(createMetadata().toMap().keySet())
.build();
}
当前的RedisEmbeddingStoreIT中的测试也可以用于重现,当删除以下行时:
try (JedisPooled jedis = new JedisPooled(redis.getHost(), redis.getFirstMappedPort())) {
jedis.flushDB(); // TODO fix: why redis returns embeddings from different indexes?
}
预期行为
RedisEmbeddingStore应该只返回来自当前存储的嵌入
请完成以下信息:
- LangChain4j版本:0.31.0
- 使用的LLM(s):llama3
- Java版本:openjdk 21.0.2 2024-01-16 LTS
- Spring Boot版本(如适用):3.2.5
附加上下文
问题是由于在Redis中存储的所有嵌入具有相同的键前缀(在RedisSchema中定义为"embedding:")而导致的。
由于langchain4j创建的所有Redis索引都在搜索相同的嵌入源。
(我正在处理PR)
2条答案
按热度按时间eimct9ow1#
感谢您!请让我知道您是否完成了PR。@Rommek
ozxc1zmp2#
你好,@Martin7-1,
我刚刚创建了一个PR - #1347,里面包含了修复。
我在描述旁边加了问号,表示我对某些点不是完全确定的(例如,我不得不使用API密钥跳过本地测试,我想知道我的更改是否符合向后兼容性的要求)。