在Java中集成LangChain使用大模型
LangChain是一个框架,旨在帮助开发人员使用语言模型构建端到端的应用程序。它提供了一套工具、组件和接口,可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互,将多个组件链接在一起,并集成额外的资源,例如 API 和数据库。
目前Quarkus提供了一些工具包用来集成langchain。可以集成不同的LLM模型,openai或者huggingface上的模型,也能集成不同的向量数据库,例如milvus,pinecone,redis,pgvector等。
这里以redis作为向量数据库为例,参考下图,一个完整的数据流程图。

分步解析如下:
-
将准备好的数据通过LLM转换成向量存入到向量数据库。
-
用户发送问题到应用程序。
-
在redis中查询相关联的数据。
-
将相关联的数据和用户问题一起发送到LLM。
-
由LLM进行语义转换返回到用户。
接下来看如何在Java中实现对应的步骤。
-
引入对应的依赖包,不同的LLM引入不同的依赖,只能引入一个LLM模型,不同的向量数据库选择不同的依赖包,这里用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 向量数据库需要使用redis stack的版本,这里是以dev模式启动,会创建一个redis的docker container,实际中,你可以修改redis的配置,具体配置查看quarkus官网。使用你的openai的apikey或者huggingface的apikey替换相应的配置,使用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/ -
导入数据到向量数据库,这里需要指定Parser以及片区大小,这里会将resource/catalog下的准备好的文件转换成向量存入到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是成对出现。
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机器人回答关于财务相关的问题。
你的回答必须要有礼貌,用中文回答问题,并且确保回答的问题是跟财务相关的。
如果你不知道,回答你不知道这个问题的回答,请直接联系客户经理。
用"我是您的智能客服,请问有什么可以帮助到您吗"""")String chat( Object session, String question);}
-
处理用户请求。只需要调用模型中定义的方法即可,这里以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的集成,最终演示效果如下。

