langchain4j [BUG] RedisEmbeddingStore从不同的索引返回嵌入向量

h5qlskok  于 2个月前  发布在  Redis
关注(0)|答案(2)|浏览(90)

描述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)

eimct9ow

eimct9ow1#

感谢您!请让我知道您是否完成了PR。@Rommek

ozxc1zmp

ozxc1zmp2#

你好,@Martin7-1,
我刚刚创建了一个PR - #1347,里面包含了修复。
我在描述旁边加了问号,表示我对某些点不是完全确定的(例如,我不得不使用API密钥跳过本地测试,我想知道我的更改是否符合向后兼容性的要求)。

相关问题