Langchain4j pgvector 实现为 EmbeddingStore?

问题描述 投票:0回答:1

我正在使用 Langchain4j 构建基于 RAG 的 AI 服务。我有一个微服务,它正在将我的文档(pdf、csv、words...)作为嵌入摄取并保存在我的 PostgreSQL 数据库(带有矢量扩展)中。

另一方面,我正在构建另一个微服务来保存人工智能对话逻辑。

为此,我正在创建下一个 bean

    @Bean
public EmbeddingStore<TextSegment> embeddingStore() {
    return new InMemoryEmbeddingStore<>();
}

    @Bean
public ContentRetriever contentRetriever() {
    return EmbeddingStoreContentRetriever.builder()
            .embeddingStore(embeddingStore())
            .embeddingModel(bedrockTitanEmbeddingModel())
            .maxResults(10) // on each interaction we will retrieve the 5 most relevant segments
            .minScore(0.2) // we want to retrieve segments very similar to the user query
            .build();
}
    @Bean
public RetrievalAugmentor retrievalAugmentor() {
    return DefaultRetrievalAugmentor.builder()
            .queryTransformer(queryTransformer())
            .contentRetriever(contentRetriever())
            .build();
}

    @Bean
public AiAgent aiAgent() {
    return AiServices.builder(ErekyAiAgent.class)
            .retrievalAugmentor(retrievalAugmentor())
            .chatLanguageModel(bedrockAnthropicChatModel())
            .contentRetriever(contentRetriever())
            .build();
}

ContentRetriever
要求我将embeddingStore作为强制参数。现在为了进行测试,我使用的是内存,但我看到 Langchain4j 有一个带有 pgvector 的实现。

在流程中我正在做的是:

  1. 根据用户提出的问题对我的 PostgreSQL 数据库进行查询
  2. 返回找到的文档文本列表
  3. 转换包含文档文本的字符串列表,我得到了
    List<TextSegment>
    列表,这是一种 langchain4j 库。
  4. 然后我需要再次将
    List<TextSegment>
    转换为嵌入,并将它们与
    List<TextSegment>
    一起添加,而不将它们嵌入到我正在使用的嵌入存储中。

逻辑是

List<String> documentTexts = getDocumentTextsFromUserQuestion(promptDto);
        List<TextSegment> textSegments = getTextSegments(documentTexts);
        embeddingStore.addAll(embedComponent.getEmbeddingsFromTextSegments(textSegments), textSegments);
        return new PromptDTO(aiAgent.answer(documentTexts, promptDto.getText()));

我发现由于某种原因,逻辑总是需要我将该数据添加到嵌入存储中,以便能够根据我的数据给出正确的答案。当我使用 Langchain4j 的 pgvector 实现并做了同样的事情时,我看到该实现正在我的数据库中创建一个表,其中包含我在插入这个新表之前已经保存的数据以给出答案。并且数据正在被复制,有没有一种方法可以让这项工作无需重复?

而且由于我已经将数据保存在数据库中,所以我不能直接用从用户问题+用户问题中找到的数据来调用AI?

我在Python中这样做,调用chain.run记录数据库中找到的数据,问题是用户问题,它有效,我不需要这个中间嵌入存储。

chain = load_qa_chain(llm, chain_type="stuff")
    # Call to the model
    # response = st.session_state.conversation({'question': user_question})
    response = chain.run(input_documents=document, question=user_question)
java spring artificial-intelligence pgvector langchain4j
1个回答
0
投票

不确定您是否已经修复了拦截器。我遇到了与 MongoDb 类似的问题,虽然它不是在使用嵌入式存储的 MongoDB 实现时在数据库中创建的新集合,但它恰好是 ObjectId 的另一个问题。我的项目正在进行中,直到我意识到我可以使用 langchain4j 来实现各种人工智能操作。因此,我已经对服务类中的 MongoDB 集合进行了各种查询和聚合,数据已存储为嵌入。我所做的就是重用这些查询并将它们存储在

InMemoryEmbeddingStore
中。我的查询已经从原始提示中收到了最相关的嵌入。或者,您可以将要嵌入的信息以纯文本形式存储在数据库中,并使用 langchain4j EmbeddingModel 将数据转换为嵌入,以推送到 InMemoryEmbeddingStore 中。这是我的解决方法的第一次迭代。

    // We will use initialize and use the ADA_002 to create embeddings on text field from database
    EmbeddingModel embeddingModel = new OpenAiEmbeddingModel.OpenAiEmbeddingModelBuilder()
            .modelName(OpenAiEmbeddingModelName.TEXT_EMBEDDING_ADA_002)
            .apiKey(youTubeRagChainProperties.getOpenaiKey())
            .maxRetries(2)
            .build();

    InMemoryEmbeddingStore<TextSegment> inMemoryEmbeddingStore = new InMemoryEmbeddingStore<>();

    // we can use query service to get most relevant search results
    List<QueryResults> querySearchResult = queryService.getDataFromVectorSearch(prompt);

    querySearchResult.forEach(result -> {
        TextSegment textSegment = TextSegment.from(result.getText());
        Embedding embedding = embeddingModel.embed(textSegment).content();
        inMemoryEmbeddingStore.add(embedding, textSegment);
    });

    // use embedding model and in memory store as retriever for optimal answer
    EmbeddingStoreContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
            .embeddingModel(embeddingModel)
            .embeddingStore(inMemoryEmbeddingStore)
            .build();

    String question = prompt;

    // given the prompt with the added context and user question, we can now build our model
    ChatLanguageModel chatLanguageModel = OpenAiChatModel.builder()
            .apiKey(openAiKey)
            .modelName(GPT_4o)
            .timeout(Duration.ofSeconds(60))
            .build();

    // using our AI system interface build the prompt
    Bot bot = AiServices.builder(Bot.class)
            .chatLanguageModel(chatLanguageModel)
            .contentRetriever(retriever)
            .build();

    return bot.chat(1, question);

langchain4j

InMemoryEmbeddingStore
的一个很棒的地方是您可以使用 ID 保存消息。 langchain4j 仍然经常更新一些内容,所以我相信您很快就能找到合适的解决方案。希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.