最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot集成LangChain來實現(xiàn)Rag應(yīng)用的問題小結(jié)

 更新時間:2024年09月26日 09:30:29   作者:HBLOGA  
檢索增強生成(RAG)是一種優(yōu)化大型語言模型(LLM)輸出的技術(shù),通過引用權(quán)威知識庫以增強模型的準確性和相關(guān)性,RAG允許LLM在不重新訓練的情況下訪問特定領(lǐng)域的知識,提高了其在各種應(yīng)用中的實用性和信任度,感興趣的朋友跟隨小編一起看看吧

1.什么是rag?

檢索增強生成(RAG)是指對大型語言模型輸出進行優(yōu)化,使其能夠在生成響應(yīng)之前引用訓練數(shù)據(jù)來源之外的權(quán)威知識庫。大型語言模型(LLM)用海量數(shù)據(jù)進行訓練,使用數(shù)十億個參數(shù)為回答問題、翻譯語言和完成句子等任務(wù)生成原始輸出。在 LLM 本就強大的功能基礎(chǔ)上,RAG 將其擴展為能訪問特定領(lǐng)域或組織的內(nèi)部知識庫,所有這些都無需重新訓練模型。這是一種經(jīng)濟高效地改進 LLM 輸出的方法,讓它在各種情境下都能保持相關(guān)性、準確性和實用性。

為什么檢索增強生成很重要?

LLM 是一項關(guān)鍵的人工智能(AI)技術(shù),為智能聊天機器人和其他自然語言處理(NLP)應(yīng)用程序提供支持。目標是通過交叉引用權(quán)威知識來源,創(chuàng)建能夠在各種環(huán)境中回答用戶問題的機器人。不幸的是,LLM 技術(shù)的本質(zhì)在 LLM 響應(yīng)中引入了不可預(yù)測性。此外,LLM 訓練數(shù)據(jù)是靜態(tài)的,并引入了其所掌握知識的截止日期。 LLM 面臨的已知挑戰(zhàn)包括:

  • 在沒有答案的情況下提供虛假信息。
  • 當用戶需要特定的當前響應(yīng)時,提供過時或通用的信息。
  • 從非權(quán)威來源創(chuàng)建響應(yīng)。
  • 由于術(shù)語混淆,不同的培訓來源使用相同的術(shù)語來談?wù)摬煌氖虑?,因此會產(chǎn)生不準確的響應(yīng)。

您可以將大型語言模型看作是一個過于熱情的新員工,他拒絕隨時了解時事,但總是會絕對自信地回答每一個問題。不幸的是,這種態(tài)度會對用戶的信任產(chǎn)生負面影響,這是您不希望聊天機器人效仿的! RAG 是解決其中一些挑戰(zhàn)的一種方法。它會重定向 LLM,從權(quán)威的、預(yù)先確定的知識來源中檢索相關(guān)信息。組織可以更好地控制生成的文本輸出,并且用戶可以深入了解 LLM 如何生成響應(yīng)。

檢索增強生成的工作原理是什么?

如果沒有 RAG,LLM 會接受用戶輸入,并根據(jù)它所接受訓練的信息或它已經(jīng)知道的信息創(chuàng)建響應(yīng)。RAG 引入了一個信息檢索組件,該組件利用用戶輸入首先從新數(shù)據(jù)源提取信息。用戶查詢和相關(guān)信息都提供給 LLM。LLM 使用新知識及其訓練數(shù)據(jù)來創(chuàng)建更好的響應(yīng)。以下各部分概述了該過程。

創(chuàng)建外部數(shù)據(jù)

LLM 原始訓練數(shù)據(jù)集之外的新數(shù)據(jù)稱為外部數(shù)據(jù)。它可以來自多個數(shù)據(jù)來源,例如 API、數(shù)據(jù)庫或文檔存儲庫。數(shù)據(jù)可能以各種格式存在,例如文件、數(shù)據(jù)庫記錄或長篇文本。另一種稱為嵌入語言模型的 AI 技術(shù)將數(shù)據(jù)轉(zhuǎn)換為數(shù)字表示形式并將其存儲在向量數(shù)據(jù)庫中。這個過程會創(chuàng)建一個生成式人工智能模型可以理解的知識庫。

檢索相關(guān)信息

下一步是執(zhí)行相關(guān)性搜索。用戶查詢將轉(zhuǎn)換為向量表示形式,并與向量數(shù)據(jù)庫匹配。例如,考慮一個可以回答組織的人力資源問題的智能聊天機器人。如果員工搜索:“我有多少年假?”,系統(tǒng)將檢索年假政策文件以及員工個人過去的休假記錄。這些特定文件將被退回,因為它們與員工輸入的內(nèi)容高度相關(guān)。相關(guān)性是使用數(shù)學向量計算和表示法計算和建立的。

增強 LLM 提示

接下來,RAG 模型通過在上下文中添加檢索到的相關(guān)數(shù)據(jù)來增強用戶輸入(或提示)。此步驟使用提示工程技術(shù)與 LLM 進行有效溝通。增強提示允許大型語言模型為用戶查詢生成準確的答案。

更新外部數(shù)據(jù)

下一個問題可能是——如果外部數(shù)據(jù)過時了怎么辦? 要維護當前信息以供檢索,請異步更新文檔并更新文檔的嵌入表示形式。您可以通過自動化實時流程或定期批處理來執(zhí)行此操作。這是數(shù)據(jù)分析中常見的挑戰(zhàn)——可以使用不同的數(shù)據(jù)科學方法進行變更管理。 下圖顯示了將 RAG 與 LLM 配合使用的概念流程。

2.什么是LangChain?

LangChain 是一個用于開發(fā)由語言模型驅(qū)動的應(yīng)用程序的框架。他主要擁有 2 個能力:

  • 可以將 LLM 模型與外部數(shù)據(jù)源進行連接
  • 允許與 LLM 模型進行交互

LLM 模型:Large Language Model,大型語言模型

3.代碼工程

實驗?zāi)康?/h3>
利用LangChain實現(xiàn)rag應(yīng)用

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>rag</artifactId>
    <properties>
        <java.version>17</java.version>
        <langchain4j.version>0.23.0</langchain4j.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-embeddings</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-embeddings-all-minilm-l6-v2</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

controller

package com.et.rag.controller;
import com.et.rag.service.SBotService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@Controller
@RequiredArgsConstructor
public class SBotController {
    private final SBotService sBotService;
    @GetMapping
    public String home() {
        return "index";
    }
    @PostMapping("/ask")
    public ResponseEntity<String> ask(@RequestBody String question) {
        try {
            return ResponseEntity.ok(sBotService.askQuestion(question));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body("Sorry, I can't process your question right now.");
        }
    }
}

service

package com.et.rag.service;
import dev.langchain4j.chain.ConversationalRetrievalChain;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
@Slf4j
public class SBotService {
    private final ConversationalRetrievalChain chain;
    public String askQuestion(String question) {
        log.debug("======================================================");
        log.debug("Question: " + question);
        String answer = chain.execute(question);
        log.debug("Answer: " + answer);
        log.debug("======================================================");
        return answer;
    }
}

EmbeddingStoreLoggingRetriever

package com.et.rag.retriever;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.retriever.EmbeddingStoreRetriever;
import dev.langchain4j.retriever.Retriever;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
 * EmbeddingStoreLoggingRetriever is a logging-enhanced for an EmbeddingStoreRetriever.
 * <p>
 * This class logs the relevant TextSegments discovered by the supplied
 * EmbeddingStoreRetriever for improved transparency and debugging.
 * <p>
 * Logging happens at INFO level, printing each relevant TextSegment found
 * for a given input text once the findRelevant method is called.
 */
@RequiredArgsConstructor
@Slf4j
public class EmbeddingStoreLoggingRetriever implements Retriever<TextSegment> {
    private final EmbeddingStoreRetriever retriever;
    @Override
    public List<TextSegment> findRelevant(String text) {
        List<TextSegment> relevant = retriever.findRelevant(text);
        relevant.forEach(segment -> {
            log.debug("=======================================================");
            log.debug("Found relevant text segment: {}", segment);
        });
        return relevant;
    }
}

components

初始化documents

package com.et.rag.configuration;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.UrlDocumentLoader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import static com.et.rag.constant.Constants.SPRING_BOOT_RESOURCES_LIST;
@Configuration
public class DocumentConfiguration {
    @Bean
    public List<Document> documents() {
        return SPRING_BOOT_RESOURCES_LIST.stream()
                .map(url -> {
                    try {
                        return UrlDocumentLoader.load(url);
                    } catch (Exception e) {
                        throw new RuntimeException("Failed to load document from " + url, e);
                    }
                })
                .toList();
    }
}

初始化langchain

package com.et.rag.configuration;
import com.et.rag.retriever.EmbeddingStoreLoggingRetriever;
import dev.langchain4j.chain.ConversationalRetrievalChain;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.AllMiniLmL6V2EmbeddingModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.retriever.EmbeddingStoreRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.List;
import static com.et.rag.constant.Constants.PROMPT_TEMPLATE_2;
@Configuration
@RequiredArgsConstructor
@Slf4j
public class LangChainConfiguration {
    @Value("${langchain.api.key}")
    private String apiKey;
    @Value("${langchain.timeout}")
    private Long timeout;
    private final List<Document> documents;
    @Bean
    public ConversationalRetrievalChain chain() {
        EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel();
        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                .documentSplitter(DocumentSplitters.recursive(500, 0))
                .embeddingModel(embeddingModel)
                .embeddingStore(embeddingStore)
                .build();
        log.info("Ingesting Spring Boot Resources ...");
        ingestor.ingest(documents);
        log.info("Ingested {} documents", documents.size());
        EmbeddingStoreRetriever retriever = EmbeddingStoreRetriever.from(embeddingStore, embeddingModel);
        EmbeddingStoreLoggingRetriever loggingRetriever = new EmbeddingStoreLoggingRetriever(retriever);
        /*MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
                .maxMessages(10)
                .build();*/
        log.info("Building ConversationalRetrievalChain ...");
        ConversationalRetrievalChain chain = ConversationalRetrievalChain.builder()
                .chatLanguageModel(OpenAiChatModel.builder()
                        .apiKey(apiKey)
                        .timeout(Duration.ofSeconds(timeout))
                        .build()
                )
                .promptTemplate(PromptTemplate.from(PROMPT_TEMPLATE_2))
                //.chatMemory(chatMemory)
                .retriever(loggingRetriever)
                .build();
        log.info("Spring Boot knowledge base is ready!");
        return chain;
    }
}

application.yaml

langchain:
  api:
    # "demo" is a free API key for testing purposes only. Please replace it with your own API key.
    key: demo
    # key: OPEN_API_KEY
  # API call to complete before it is timed out.
  timeout: 30

index.html

<!DOCTYPE html>
<html lang="en"
      xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Spring Boot Doc Bot</title>
    <link  rel="external nofollow"  rel="stylesheet">
    <link rel="stylesheet"  rel="external nofollow" >
</head>
<body>
<nav class="bg-dark text-white py-3">
    <div class="text-center d-flex justify-content-center align-items-center">
        <img src="/logo.png" alt="Logo" style="width:60px; margin-right: 10px;">
        <h2 style="margin: 0;">Welcome to Spring Boot Documentation Bot</h2>
    </div>
</nav>
<div class="container mt-5">
    <div class="row">
        <div class="col-md-8 offset-2">
            <h3 class="text-center mb-3">Ask your Spring related queries here!</h3>
            <form>
                <div class="mb-3">
                    <label for="questionInput" class="form-label">Question</label>
                    <input type="text" class="form-control" id="questionInput" name="question" placeholder="Enter your question" required>
                </div>
                <div class="mb-3 text-center">
                    <button id="submitBtn" type="button" class="btn btn-primary">Ask!</button>
                    <button id="clearBtn" type="button" class="btn btn-secondary">Clear</button>
                </div>
            </form>
        </div>
    </div>
    <div class="row my-5">
        <div class="col-md-8 offset-md-2">
            <label for="answerBox" class="form-label"><h5>Answer</h5></label>
            <div class="position-relative my-3">
                <textarea class="form-control" rows="10" id="answerBox" disabled></textarea>
                <a href="#" rel="external nofollow"  class="position-absolute top-0 end-0 m-2" id="copyBtn">
                    <i class="far fa-copy"></i>
                </a>
            </div>
        </div>
    </div>
</div>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
    $(document).ready(function () {
        $("#submitBtn").click(function () {
            let questionValue = $("#questionInput").val();
            if (!questionValue) {
                alert('Please enter your question');
                return;
            }
            $("#answerBox").val('Please wait... fetching answer...');
            $.ajax({
                type: "POST",
                url: "/ask",
                data: JSON.stringify({ question: $("#questionInput").val() }),
                //contentType: "application/json; charset=utf-8",
                dataType: "text",
                success: function (data) {
                    //console.log(typeof data);
                    //console.log(data);
                    $("#answerBox").val(data);
                },
                error: function (errMsg) {
                    alert(errMsg);
                }
            });
        });
        $("#clearBtn").click(function () {
            $("#questionInput").val('');
            $("#answerBox").val('');
        });
        document.getElementById("copyBtn").addEventListener("click", function() {
            var copyText = document.getElementById("answerBox");
            copyText.select();
            copyText.setSelectionRange(0, 99999);
            document.execCommand("copy");
            alert("Copied: " + copyText.value);
        });
    });
</script>
</body>
</html>

只是一些關(guān)鍵代碼,所有代碼請參見下面代碼倉庫

代碼倉庫

GitHub - Harries/springboot-demo: a simple springboot demo with some components for example: redis,solr,rockmq and so on.(dag)

4.測試

啟動Spring Boot應(yīng)用,訪問http://127.0.0.1:8080/

5.引用

GitHub - miliariadnane/spring-boot-doc-rag-bot: This repository contains a documentation bot powered by an LLM using @langchain4j to swiftly find answers to your Spring Boot questions. It provides easy browsing of Spring documentation and leverages the RAG technique to retrieve relevant details on demand.

什么是 RAG?— 檢索增強生成 AI 詳解 — AWS

GitHub - liaokongVFX/LangChain-Chinese-Getting-Started-Guide: LangChain 的中文入門教程

Spring Boot集成LangChain來實現(xiàn)Rag應(yīng)用 | Harries Blog™

到此這篇關(guān)于Spring Boot集成LangChain來實現(xiàn)Rag應(yīng)用的文章就介紹到這了,更多相關(guān)Spring Boot集成LangChain Rag應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入探究Java中的HashMap為什么會產(chǎn)生死循環(huán)

    深入探究Java中的HashMap為什么會產(chǎn)生死循環(huán)

    HashMap?死循環(huán)發(fā)生在?JDK?1.8?之前的版本中,這篇文章主要來和大家深入探究一下為什么Java中HashMap會產(chǎn)生死循環(huán),感興趣的小伙伴可以了解一下
    2023-05-05
  • Java隨機數(shù)算法原理與實現(xiàn)方法實例詳解

    Java隨機數(shù)算法原理與實現(xiàn)方法實例詳解

    這篇文章主要介紹了Java隨機數(shù)算法原理與實現(xiàn)方法,簡單分析了隨機數(shù)算法的原理并結(jié)合具體實例形式給出了java編程計算隨機數(shù)的具體操作技巧,需要的朋友可以參考下
    2017-09-09
  • spring boot實現(xiàn)在request里解密參數(shù)返回

    spring boot實現(xiàn)在request里解密參數(shù)返回

    這篇文章主要介紹了Spring Boot實現(xiàn)在request里解密參數(shù)返回操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 關(guān)于LocalDateTime最常用方法和時間轉(zhuǎn)換方式

    關(guān)于LocalDateTime最常用方法和時間轉(zhuǎn)換方式

    Java8版本引入了LocalDateTime和LocalDate類,極大地方便了日期和時間的處理,本文主要介紹了字符串與LocalDateTime的互轉(zhuǎn),Long型時間戳與UTC時間字符串的轉(zhuǎn)換,獲取今天、某天的起止時間,自定義時間的設(shè)置,以及LocalDateTime與Date的相互轉(zhuǎn)換等常用方法
    2024-11-11
  • java操作excel表格詳解

    java操作excel表格詳解

    在日常工作中,對Excel工作表格的操作處理可是多的數(shù)不清楚,下面是java語言對其的操作,有需要的小伙伴可以參考下
    2021-10-10
  • idea熱部署插件jrebel正式版及破解版安裝詳細圖文教程

    idea熱部署插件jrebel正式版及破解版安裝詳細圖文教程

    這篇文章主要介紹了idea熱部署插件jrebel正式版及破解版安裝詳細教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • 如何基于Jenkins構(gòu)建Jmeter項目

    如何基于Jenkins構(gòu)建Jmeter項目

    這篇文章主要介紹了如何基于Jenkins構(gòu)建Jmeter項目,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Java基礎(chǔ)之代理原理與用法詳解

    Java基礎(chǔ)之代理原理與用法詳解

    這篇文章主要介紹了Java基礎(chǔ)之代理原理與用法,結(jié)合實例形式詳細分析了java代理的概念、原理、用法及相關(guān)操作注意事項,需要的朋友可以參考下
    2020-02-02
  • Java中的SuppressWarnings注解使用

    Java中的SuppressWarnings注解使用

    這篇文章主要介紹了Java中的SuppressWarnings注解使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Java基礎(chǔ)知識之StringWriter流的使用

    Java基礎(chǔ)知識之StringWriter流的使用

    這篇文章主要介紹了Java基礎(chǔ)知識之StringWriter流的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評論

右玉县| 观塘区| 宜黄县| 正安县| 沙田区| 桦川县| 赤水市| 九龙城区| 多伦县| 麻栗坡县| 页游| 鱼台县| 康保县| 涿鹿县| 扬州市| 大冶市| 商水县| 城口县| 怀集县| 宝鸡市| 改则县| 盐源县| 蓬安县| 陆丰市| 新安县| 卢氏县| 南昌市| 扎兰屯市| 宜兴市| 康保县| 宿迁市| 自治县| 宜昌市| 黑水县| 利津县| 达拉特旗| 新兴县| 曲阳县| 团风县| 黄石市| 威海市|