在Java中集成LangChain使用大模型
LangChain是一個框架,旨在幫助開發(fā)人員使用語言模型構(gòu)建端到端的應(yīng)用程序。它提供了一套工具、組件和接口,可簡化創(chuàng)建由大型語言模型 (LLM) 和聊天模型提供支持的應(yīng)用程序的過程。LangChain 可以輕松管理與語言模型的交互,將多個組件鏈接在一起,并集成額外的資源,例如 API 和數(shù)據(jù)庫。
目前Quarkus提供了一些工具包用來集成langchain??梢约刹煌腖LM模型,openai或者huggingface上的模型,也能集成不同的向量數(shù)據(jù)庫,例如milvus,pinecone,redis,pgvector等。
這里以redis作為向量數(shù)據(jù)庫為例,參考下圖,一個完整的數(shù)據(jù)流程圖。

分步解析如下:
-
將準備好的數(shù)據(jù)通過LLM轉(zhuǎn)換成向量存入到向量數(shù)據(jù)庫。
-
用戶發(fā)送問題到應(yīng)用程序。
-
在redis中查詢相關(guān)聯(lián)的數(shù)據(jù)。
-
將相關(guān)聯(lián)的數(shù)據(jù)和用戶問題一起發(fā)送到LLM。
-
由LLM進行語義轉(zhuǎn)換返回到用戶。
接下來看如何在Java中實現(xiàn)對應(yīng)的步驟。
-
引入對應(yīng)的依賴包,不同的LLM引入不同的依賴,只能引入一個LLM模型,不同的向量數(shù)據(jù)庫選擇不同的依賴包,這里用redis為例。
<dependency><groupId>io.quarkiverse.langchain4j</groupId><artifactId>quarkus-langchain4j-openai</artifactId><version>0.6.2</version></dependency><dependency><groupId>io.quarkiverse.langchain4j</groupId><artifactId>quarkus-langchain4j-redis</artifactId><version>0.6.2</version></dependency><!--<dependency>--><!-- <groupId>io.quarkiverse.langchain4j</groupId>--><!-- <artifactId>quarkus-langchain4j-hugging-face</artifactId>--><!-- <version>0.6.2</version>--><!--</dependency>--> -
配置修改,Redis 向量數(shù)據(jù)庫需要使用redis stack的版本,這里是以dev模式啟動,會創(chuàng)建一個redis的docker container,實際中,你可以修改redis的配置,具體配置查看quarkus官網(wǎng)。使用你的openai的apikey或者huggingface的apikey替換相應(yīng)的配置,使用huggingface指定的模型URL可以是遠程的也可以是本地的。
quarkus.langchain4j.redis.dimension=1536quarkus.redis.devservices.image-name=redis/redis-stack:latestquarkus.langchain4j.openai.api-key=sk-***quarkus.langchain4j.openai.chat-model.temperature=0.5quarkus.langchain4j.openai.timeout=60squarkus.langchain4j.openai.base-url=https://proxy.openpi.com/v1/ -
導入數(shù)據(jù)到向量數(shù)據(jù)庫,這里需要指定Parser以及片區(qū)大小,這里會將resource/catalog下的準備好的文件轉(zhuǎn)換成向量存入到redis當中。
public void ingest(@Observes StartupEvent event) {System.out.printf("Ingesting documents...%n");List<Document> documents = FileSystemDocumentLoader.loadDocuments(new File("src/main/resources/catalog").toPath(),new TextDocumentParser());var ingestor = EmbeddingStoreIngestor.builder().embeddingStore(store).embeddingModel(embeddingModel).documentSplitter(recursive(500, 0)).build();ingestor.ingest(documents);System.out.printf("Ingested %d documents.%n", documents.size());} -
定義Retriever,跟Parser是成對出現(xiàn)。
public class RetrieverExample implements Retriever<TextSegment> {
private final EmbeddingStoreRetriever retriever;
RetrieverExample(RedisEmbeddingStore store, EmbeddingModel model) {retriever = EmbeddingStoreRetriever.from(store, model, 20);}
public List<TextSegment> findRelevant(String s) {return retriever.findRelevant(s);}} -
定義模型,這里指定retriever以及prompt。
public interface Bot {
你作為一個AI機器人回答關(guān)于財務(wù)相關(guān)的問題。
你的回答必須要有禮貌,用中文回答問題,并且確?;卮鸬膯栴}是跟財務(wù)相關(guān)的。
如果你不知道,回答你不知道這個問題的回答,請直接聯(lián)系客戶經(jīng)理。
用"我是您的智能客服,請問有什么可以幫助到您嗎"""")String chat( Object session, String question);}
-
處理用戶請求。只需要調(diào)用模型中定義的方法即可,這里以ws為例子。
public void onMessage(String message, Session session) {managedExecutor.execute(() -> {String response = bot.chat(session, message);try {session.getBasicRemote().sendText(response);} catch (IOException e) {throw new RuntimeException(e);}});
}
以上就完成了base on OpenAI的langchain的集成,最終演示效果如下。

