共计 5157 个字符,预计需要花费 13 分钟才能阅读完成。
学习使用 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:
dev.langchain4j
langchain4j
0.22.0
使用 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.tsx在 frontend 文 件夹中打开并使用以下内容更新它:
export default function App() {const [messages, setMessages] = useState([]);
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 (
sendMessage(e.detail.value)} />
);
}
文章来源地址 https://www.toymoban.com/diary/java/380.html
-
我们使用 Hilla UI 组件库中的 MessageList 和组件MessageInput
-
sendMessage()将消息添加到消息列表中,并调用类 chat() 上的方法ChatService。收到响应后,会将其添加到消息列表中。
您现在拥有一个正在运行的聊天应用程序,该应用程序使用 OpenAI 聊天 API 并跟踪聊天历史记录。它对于短消息非常有效,但对于长答案来说速度很慢。为了改善用户体验,我们可以使用流式完成来代替,在收到响应时显示响应。
使用 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 chatStream(String message) {Sinks.Many 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。
更新 App.tsx 以下内容:
export default function App() {const [messages, setMessages] = useState([]);
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 (
sendMessage(e.detail.value)} />
);
}
模板与以前相同,但我们处理响应的方式不同。我们不再等待收到响应,而是开始监听响应块。当收到第一个块时,我们将其添加为新消息。当收到后续块时,我们将它们附加到最后一条消息中。
重新运行应用程序,您应该看到响应按收到时的样子显示。
结论
正如您所看到的,LangChain 可以轻松地在 Java 和 Spring Boot 中构建由 LLM 驱动的 AI 应用程序。
完成基本设置后,您可以按照本文前面链接的 LangChain4j GitHub 页面上的示例,通过链接操作、添加外部工具等来扩展功能。在 Hilla 文档中了解有关 Hilla 的更多信息。
Hilla 文档:https://hilla.dev/docs/react文章来源:https://www.toymoban.com/diary/java/380.html
到此这篇关于使用 Spring Boot 和 LangChain 构建 Java 中的 AI ChatGPT 仿制教程的文章就介绍到这了, 更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持 TOY 模板网!
原文地址:https://www.toymoban.com/diary/java/380.html
如若转载,请注明出处:如若内容造成侵权 / 违法违规 / 事实不符,请联系站长进行投诉反馈,一经查实,立即删除!