使用Spring Boot和LangChain构建Java中的AI ChatGPT仿制教程

学习使用 Java 中的 Spring Boot、LangChain 和 Hilla 构建 ChatGPT 克隆。涵盖同步聊天完成和高级流完成。

许多用于 AI 应用程序开发的库主要是用Python或 JavaScript 编写的。好消息是其中一些库也具有 Java API。在本教程中,我将向您展示如何使用Spring Boot、 LangChain 和Hilla构建 ChatGPT 克隆。

本教程将涵盖简单的同步聊天完成和更高级的流式完成,以获得更好的用户体验。

大神完成得开源源代码

您可以在我的GitHub 存储库中找到该示例的源代码。

https://github.com/marcushellberg/spring-boot-react-langchain-chatgpt

要求

  • Java 17+

  • Node 18+

  • Hilla(https://hilla.dev/)

  • LangChain4j(https://github.com/langchain4j/langchain4j)

  • OPENAI_API_KEY环境变量中的 OpenAI API 密钥

创建Spring Boot和React项目,添加LangChain

首先,使用 Hilla CLI 创建一个新的 Hilla 项目。这将创建一个带有React前端的 Spring Boot 项目。

npx @hilla/cli init ai-assistant

在 IDE 中打开生成的项目。然后,将LangChain4j依赖项添加到文件中pom.xml

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j</artifactId>
    <version>0.22.0</version> <!-- TODO: use latest version -->
</dependency>

使用 LangChain 使用内存完成简单的 OpenAI 聊天

我们将通过简单的同步聊天完成来开始探索 LangChain4j。在本例中,我们希望调用 OpenAI 聊天完成 API 并获得单个响应。我们还希望跟踪聊天历史记录中最多 1,000 个标记。

com.example.application.service包中,创建一个ChatService.java包含以下内容的类:

@BrowserCallable
@AnonymousAllowed
public class ChatService {

    @Value("${openai.api.key}")
    private String OPENAI_API_KEY;

    private Assistant assistant;

    interface Assistant {
        String chat(String message);
    }

    @PostConstruct
    public void init() {
        var memory = TokenWindowChatMemory.withMaxTokens(1000, new OpenAiTokenizer("gpt-3.5-turbo"));
        assistant = AiServices.builder(Assistant.class)
                .chatLanguageModel(OpenAiChatModel.withApiKey(OPENAI_API_KEY))
                .chatMemory(memory)
                .build();
    }

    public String chat(String message) {
        return assistant.chat(message);
    }
}
  • @BrowserCallable使该类可供前端使用。

  • @AnonymousAllowed允许匿名用户调用这些方法。

  • @Value从环境变量注入 OpenAI API 密钥OPENAI_API_KEY

  • Assistant是我们用来调用聊天 API 的接口。

  • init()使用 1,000 个令牌内存和模型初始化助手gpt-3.5-turbo

  • chat()是我们将从前端调用的方法。

Application.java通过在 IDE 中运行或使用默认Maven目标来启动应用程序:

MVN

这将为前端生成TypeScript 类型和服务方法。

接下来,App.tsxfrontend文件夹中打开并使用以下内容更新它:

export default function App() {
    const [messages, setMessages] = useState<MessageListItem[]>([]);

    async function sendMessage(message: string) {
    setMessages((messages) => [
        ...messages,
        {
        text: message,
        userName: "You",
        },
    ]);

    const response = await ChatService.chat(message);
    setMessages((messages) => [
        ...messages,
        {
        text: response,
        userName: "Assistant",
        },
    ]);
    }

    return (
    <div className="p-m flex flex-col h-full box-border">
        <MessageList items={messages} className="flex-grow" />
        <MessageInput onSubmit={(e) => sendMessage(e.detail.value)} />
    </div>
    );
}


文章来源地址https://www.toymoban.com/diary/java/380.html

  • 我们使用Hilla UI 组件库中的MessageList和组件MessageInput

  • sendMessage()将消息添加到消息列表中,并调用类chat()上的方法ChatService。收到响应后,会将其添加到消息列表中。

您现在拥有一个正在运行的聊天应用程序,该应用程序使用 OpenAI 聊天 API 并跟踪聊天历史记录。它对于短消息非常有效,但对于长答案来说速度很慢。为了改善用户体验,我们可以使用流式完成来代替,在收到响应时显示响应。

显示用户和AI机器人之间两条消息的聊天界面

使用 LangChain 使用内存流式传输 OpenAI 聊天完成情况

让我们更新该类ChatService以使用流式完成:

@BrowserCallable
@AnonymousAllowed
public class ChatService {

    @Value("${openai.api.key}")
    private String OPENAI_API_KEY;
    private Assistant assistant;

    interface Assistant {
        TokenStream chat(String message);
    }

    @PostConstruct
    public void init() {
        var memory = TokenWindowChatMemory.withMaxTokens(1000, new OpenAiTokenizer("gpt-3.5-turbo"));

        assistant = AiServices.builder(Assistant.class)
                .streamingChatLanguageModel(OpenAiStreamingChatModel.withApiKey(OPENAI_API_KEY))
                .chatMemory(memory)
                .build();
    }

    public Flux<String> chatStream(String message) {
        Sinks.Many<String> sink = Sinks.many().unicast().onBackpressureBuffer();

        assistant.chat(message)
                .onNext(sink::tryEmitNext)
                .onComplete(sink::tryEmitComplete)
                .onError(sink::tryEmitError)
                .start();

        return sink.asFlux();
    }
}

代码与以前基本相同,但有一些重要的区别:

  • Assistant现在返回 a TokenStream而不是 a String

  • init()使用streamingChatLanguageModel()而不是  chatLanguageModel().

  • chatStream()返回 一个 Flux<String>而不是 一个 String

更新App.tsx以下内容:

export default function App() {
    const [messages, setMessages] = useState<MessageListItem[]>([]);

    function addMessage(message: MessageListItem) {
    setMessages((messages) => [...messages, message]);
    }

    function appendToLastMessage(chunk: string) {
    setMessages((messages) => {
        const lastMessage = messages[messages.length - 1];
        lastMessage.text += chunk;
        return [...messages.slice(0, -1), lastMessage];
    });
    }

    async function sendMessage(message: string) {
    addMessage({
        text: message,
        userName: "You",
    });

    let first = true;
    ChatService.chatStream(message).onNext((chunk) => {
        if (first && chunk) {
        addMessage({
            text: chunk,
            userName: "Assistant",
        });
        first = false;
        } else {
        appendToLastMessage(chunk);
        }
    });
    }

    return (
    <div className="p-m flex flex-col h-full box-border">
        <MessageList items={messages} className="flex-grow" />
        <MessageInput onSubmit={(e) => sendMessage(e.detail.value)} />
    </div>
    );
}

模板与以前相同,但我们处理响应的方式不同。我们不再等待收到响应,而是开始监听响应块。当收到第一个块时,我们将其添加为新消息。当收到后续块时,我们将它们附加到最后一条消息中。

重新运行应用程序,您应该看到响应按收到时的样子显示。

结论

正如您所看到的,LangChain 可以轻松地在 Java 和 Spring Boot 中构建由 LLM 驱动的 AI 应用程序。

完成基本设置后,您可以按照本文前面链接的 LangChain4j GitHub 页面上的示例,通过链接操作、添加外部工具等来扩展功能。在Hilla 文档中了解有关 Hilla 的更多信息。

Hilla 文档:https://hilla.dev/docs/react


到此这篇关于使用Spring Boot和LangChain构建Java中的AI ChatGPT仿制教程的文章就介绍到这了,更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

原文地址:https://www.toymoban.com/diary/java/380.html

如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用
上一篇 2023年10月11日 15:48
下一篇 2023年10月12日 10:19

相关文章

  • OpenAi最简洁的Java流式返回接入方式,没有第三方依赖,只需要使用Spring Boot即可!轻松构建你的带有聊天记忆、画图功能的chatgpt!

    OpenAi最简洁的Java流式返回接入方式,没有第三方依赖,只需要使用Spring Boot即可!轻松构建你的带有聊天记忆、画图功能的chatgpt! GitHub - NiuXiangQian/chatgpt-stream: OpenAi最简洁的Java流式返回接入方式,没有第三方依赖,只需要使用Spring Boot即可!轻松构建你的带有聊天记忆、画图

    2024年02月12日
    浏览(55)
  • 【ChatGPT】在20分钟内使用 LangChain + Ray构建自托管问答服务

    This is part 3 of a blog series. In this blog, we’ll show you how to build an LLM question and answering service. In future parts, we will optimize the code and measure performance: cost, latency and throughput. 这是博客系列的第 3 部分。在本博客中,我们将向您展示如何构建LLM问答服务。在以后的部分中,我们将优化代码

    2024年02月03日
    浏览(54)
  • 【ChatGPT】使用 LangChain 和 Ray 实现 100 行代码构建 LLM 开源搜索引擎【1】

    目录 Introduction Building the index 构建索引 Accelerating indexing using Ray 使用 Ray 加速索引编制 Serving

    2024年02月08日
    浏览(45)
  • Spring boot +React集成ChatGPT 智能AI

    2024年02月12日
    浏览(44)
  • Spring Boot:轻松构建Java应用程序

    Spring Boot 是一个用于简化Spring应用程序开发的框架。通过自动配置和提供各种生产级功能,Spring Boot帮助开发者更快速、更简单地构建基于Spring的应用程序。在这篇博客中,我们将探讨Spring Boot的特点以及如何开始使用它。 Spring Boot 的主要优势在于它简化了Spring应用程序的开

    2024年02月01日
    浏览(43)
  • 入门Spring Boot:快速构建Java应用的利器

    Spring Boot是由Pivotal团队开发的开源框架,它基于Spring框架,旨在简化Java应用程序的开发过程。它提供了一种约定大于配置的方式,通过自动配置和起步依赖(Starter Dependencies)来消除繁琐的配置,从而使开发者能够更快地构建独立、可执行的、生产级的Spring应用。 与传统的

    2024年02月07日
    浏览(46)
  • 精通Spring Boot单元测试:构建健壮的Java应用

    在当今软件开发领域,单元测试已经成为确保应用质量和可维护性的关键步骤。特别是在Java生态系统中,Spring Boot框架作为一种广泛应用的解决方案,其对于单元测试的支持更是让开发者受益匪浅。本博客的目标是为开发者提供一份清晰易懂的指南,帮助他们利用Spring Boot框

    2024年03月15日
    浏览(60)
  • Spring Boot的魔法:构建高效Java应用的秘诀

    🎉欢迎来到架构设计专栏~Spring Boot的魔法:构建高效Java应用的秘诀 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:架构设计 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有限,

    2024年02月08日
    浏览(49)
  • 用通俗易懂的方式讲解:使用 MongoDB 和 Langchain 构建生成型AI聊天机器人

    想象一下:你收到了你梦寐以求的礼物:一台非凡的时光机,可以将你带到任何地方、任何时候。 你只有10分钟让它运行,否则它将消失。你拥有一份2000页的PDF,详细介绍了关于这台时光机的一切:它的历史、创造者、构造细节、操作指南、过去的用户,甚至还有一种回到过

    2024年01月23日
    浏览(46)
  • 使用 Spring Boot 构建微服务

    Spring Boot 为所有这些阶段提供开箱即用的支持,并提供插件和模块形式的专用组件。  打包 - 它提供自己的 Maven 支持,将代码和所有依赖项打包为 Uber jar,包括容器本身。为此,您需要添加以下构建插件和一个简单的重新打包目标,该目标重新打包在正常 Maven 打包阶段构建

    2024年02月06日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包