【LangChain4j快速入门】5分钟用Java接入AI大模型,Spring Boot整合实战!| 附源码

【LangChain4j快速入门】5分钟用Java接入AI大模型,Spring Boot整合实战!

前言:当Java遇上大模型

在AI浪潮席卷全球的今天,Java开发者如何快速拥抱大语言模型?LangChain4j作为专为Java打造的AI开发框架,以极简的API设计和强大的扩展能力,让集成ChatGPT、GPT-4o-mini等模型变得异常轻松!本文将带你通过实战代码+图文详解,5分钟完成Spring Boot与GPT-4o-mini的对接,开启你的AI应用开发之旅!


一、环境准备:闪电战配置

1.1 添加关键依赖

在Spring Boot项目的pom.xml中加入LangChain4j核心库与OpenAI扩展:

<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId><version>1.0.0-beta3</version>
</dependency>
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j</artifactId><version>1.0.0-beta3</version>
</dependency>

1.2 申请密钥(零门槛!)

  • 正式环境:通过OpenAI平台获取API Key
  • 尝鲜体验:直接使用官方Demo Key(配额有限,仅支持gpt-4o-mini)
// 配置类中直接使用demo密钥
.baseUrl("http://langchain4j.dev/demo/openai/v1")
.apiKey("demo")
  • ⚠️如果你没有API密钥怎么办?

如果你没有自己的OpenAI API密钥,别担心。你可以临时使用官方免费提供的演示密钥,用于演示目的。请注意,当使用演示密钥时,所有对OpenAI API的请求都需要通过官方的代理服务器,该代理会在将你的请求转发给OpenAI API之前注入真实的密钥。官方不会以任何方式收集或使用你的数据。演示密钥有配额限制,仅限于gpt-4o-mini模型,并且只应用于演示目的。

OpenAiChatModel model = OpenAiChatModel.builder().baseUrl("http://langchain4j.dev/demo/openai/v1").apiKey("demo").modelName("gpt-4o-mini").build();

1.3配置application.yml

spring:application:name: AIai:openai:api-key: "demo"base-url: "http://langchain4j.dev/demo/openai/v1"

二、核心实现:3步构建AI聊天接口

2.1 模型配置(智能引擎)

@Configuration
public class LangChain4jConfig {@Beanpublic ChatLanguageModel chatLanguageModel() {return OpenAiChatModel.builder().baseUrl("http://langchain4j.dev/demo/openai/v1").apiKey("demo") // 替换为真实KEY时移除baseUrl.modelName("gpt-4o-mini") // 最新轻量级模型.build();}
}

关键点说明

  • baseUrl仅在使用Demo Key时需要
  • modelName指定模型版本,推荐性能优异的gpt-4o-mini

2.2 聊天控制器(对话大脑)

@RestController
@RequestMapping("/ai")
public class ChatController {private final ChatLanguageModel model;private final ChatMemory chatMemory; // 自动记忆上下文@GetMapping(value = "/chat", produces = "text/plain;charset=utf-8")public Mono<String> chat(@RequestParam String message) {UserMessage userMsg = UserMessage.from("你叫小智,是一个人工智能\n" + message);chatMemory.add(userMsg);AiMessage aiMsg = model.chat(chatMemory.messages()).aiMessage();chatMemory.add(aiMsg);return Mono.just(aiMsg.text());}
}
package org.example.ai.config;import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class CommonConfiguration {/*** 定义一个基于消息数量限制的 ChatMemory Bean*/@Beanpublic ChatMemory messageWindowChatMemory(ChatMemoryStore chatMemoryStore) {return MessageWindowChatMemory.builder().id("session-1") // 会话 ID.maxMessages(10) // 最大消息数量.chatMemoryStore(chatMemoryStore) // 持久化存储.build();}/*** 定义一个简单的内存存储实现*/@Beanpublic ChatMemoryStore inMemoryChatMemoryStore() {return new InMemoryChatMemoryStore();}
}

亮点功能

  • ChatMemory自动维护对话上下文
  • 强制UTF-8编码解决中文乱码
  • 响应式编程支持(Mono)

在这里插入图片描述
在这里插入图片描述

三、效果验证:你的第一个AI接口

启动应用后访问:

http://localhost:8080/ai/chat?message=讲个程序员笑话

预期响应

好的,主人!为什么程序员总把万圣节和圣诞节搞混?
因为 Oct 31 == Dec 25!(Octal 31 = Decimal 25)

在这里插入图片描述
加入前端代码

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>小智AI助手</title><script src="https://unpkg.com/vue@3/dist/vue.global.js"></script><style>/* 现代聊天界面样式 */:root {--primary: #4CAF50;--bg: #f5f5f5;--user-bg: #e3f2fd;--ai-bg: #ffffff;}body {margin: 0;font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;background: var(--bg);}.chat-container {max-width: 800px;margin: 20px auto;border-radius: 12px;box-shadow: 0 2px 15px rgba(0,0,0,0.1);background: white;height: 90vh;display: flex;flex-direction: column;}.messages {flex: 1;overflow-y: auto;padding: 20px;display: flex;flex-direction: column;gap: 15px;}.message {max-width: 70%;padding: 12px 16px;border-radius: 18px;animation: fadeIn 0.3s ease;}.user-message {background: var(--user-bg);align-self: flex-end;border-bottom-right-radius: 4px;}.ai-message {background: var(--ai-bg);align-self: flex-start;border-bottom-left-radius: 4px;box-shadow: 0 2px 4px rgba(0,0,0,0.05);}.loading-dots {display: inline-block;font-size: 24px;}.loading-dots::after {content: '...';animation: dots 1.5s infinite;}.input-area {padding: 20px;border-top: 1px solid #eee;display: flex;gap: 10px;}input {flex: 1;padding: 12px;border: 1px solid #ddd;border-radius: 25px;font-size: 16px;outline: none;transition: 0.3s;}input:focus {border-color: var(--primary);box-shadow: 0 0 0 3px rgba(76,175,80,0.1);}button {padding: 12px 24px;background: var(--primary);border: none;border-radius: 25px;color: white;cursor: pointer;transition: 0.3s;}button:disabled {opacity: 0.7;cursor: not-allowed;}@keyframes dots {0%, 20% { content: '.'; }40% { content: '..'; }60%, 100% { content: '...'; }}@keyframes fadeIn {from { opacity: 0; transform: translateY(10px); }to { opacity: 1; transform: translateY(0); }}</style>
</head>
<body>
<div id="app"><div class="chat-container"><div class="messages"><div v-for="(msg, index) in messages":key="index":class="['message', msg.role === 'user' ? 'user-message' : 'ai-message']">{{ msg.content }}</div><div v-if="loading" class="message ai-message"><span class="loading-dots"></span></div></div><div class="input-area"><inputv-model="inputMessage"@keyup.enter="sendMessage"placeholder="和小智聊天吧~":disabled="loading"><button @click="sendMessage" :disabled="!inputMessage || loading">{{ loading ? '思考中' : '发送' }}</button></div></div>
</div><script>const { createApp } = Vue;createApp({data() {return {messages: [],inputMessage: '',loading: false}},methods: {async sendMessage() {if (!this.inputMessage.trim() || this.loading) return;const userMessage = this.inputMessage;this.messages.push({ role: 'user', content: userMessage });this.inputMessage = '';this.loading = true;try {const response = await fetch(`/ai/chat?message=${encodeURIComponent(userMessage)}`);const text = await response.text();this.messages.push({ role: 'assistant', content: text });} catch (error) {this.messages.push({role: 'assistant',content: '哎呀,小智暂时无法连接,请稍后再试~'});} finally {this.loading = false;this.scrollToBottom();}},scrollToBottom() {this.$nextTick(() => {const container = document.querySelector('.messages');container.scrollTop = container.scrollHeight;});}},mounted() {// 初始欢迎语this.messages.push({role: 'assistant',content: '你好!我是小智,有什么可以帮您的?'});}}).mount('#app');
</script>
</body>
</html>

完整代码

package org.example.ai.config;import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class LangChain4jConfig {@Beanpublic ChatLanguageModel chatLanguageModel() {return OpenAiChatModel.builder().baseUrl("http://langchain4j.dev/demo/openai/v1").apiKey("demo").modelName("gpt-4o-mini").build();}
}
package org.example.ai.config;import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class CommonConfiguration {/*** 定义一个基于消息数量限制的 ChatMemory Bean*/@Beanpublic ChatMemory messageWindowChatMemory(ChatMemoryStore chatMemoryStore) {return MessageWindowChatMemory.builder().id("session-1") // 会话 ID.maxMessages(10) // 最大消息数量.chatMemoryStore(chatMemoryStore) // 持久化存储.build();}/*** 定义一个简单的内存存储实现*/@Beanpublic ChatMemoryStore inMemoryChatMemoryStore() {return new InMemoryChatMemoryStore();}
}
package org.example.ai.controller;import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;@RestController
@RequestMapping("/ai")
@RequiredArgsConstructor
public class ChatController {private final ChatLanguageModel chatLanguageModel;private final ChatMemory chatMemory;@RequestMapping (value = "/chat", produces = "text/plain;charset=utf-8")public Mono<String> chat(@RequestParam(required = false, defaultValue = "") String message) {UserMessage userMessage = UserMessage.from("你叫小智,是一个人工智能\n" + message);chatMemory.add(userMessage);AiMessage aiMessage = chatLanguageModel.chat(chatMemory.messages()).aiMessage();chatMemory.add(aiMessage);return Mono.just(aiMessage.text());}
}

在这里插入图片描述

四、生产级优化建议

  1. 密钥安全:通过application.yml配置,避免硬编码
    langchain4j:openai:api-key: ${OPENAI_API_KEY}
    
  2. 限流降级:集成Resilience4j实现请求限流
  3. 性能监控:通过Micrometer对接Prometheus
  4. 上下文管理:使用PersistentChatMemory实现对话持久化

总结:为什么选择LangChain4j?

通过本文实战,我们体验到了:
极简集成:5行代码对接GPT-4o-mini
开箱即用:自动记忆管理、流式响应支持
生态丰富:支持20+模型厂商,轻松切换
Spring Boot友好:自动配置+依赖注入

下一步探索

  • 尝试AI服务(Assistant API)实现复杂逻辑
  • 结合Embedding实现RAG知识库
  • 使用Tools API让模型调用外部服务

立即访问LangChain4j官网开启你的AI应用开发之旅!如果你在实践过程中遇到任何问题,欢迎在评论区留言交流~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/79828.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025第十七届“华中杯”大学生数学建模挑战赛题目B 题 校园共享单车的调度与维护问题完整成品正文33页(不含附录)文章思路 模型 代码 结果分享

校园共享单车运营优化与调度模型研究 摘 要 本研究聚焦校园共享单车点位布局、供需平衡、运营效率及故障车辆回收四大核心问题&#xff0c;通过构建一系列数学模型&#xff0c;系统分析与优化共享单车的运维体系。 针对问题一&#xff0c;我们建立了基于多时段观测的库存估算…

Unity游戏多语言工具包

由于一开始的代码没有考虑多语言场景&#xff0c;导致代码中提示框和UI显示直接用了中文&#xff0c;最近开始提取代码的中文&#xff0c;提取起来太麻烦&#xff0c;所以拓展了之前的多语言包&#xff0c;降低了操作复杂度。最后把工具代码提取出来到单独项目里面&#xff0c;…

.NET MCP 文档

MCP 概述 MCP&#xff08;Model Context Protocol&#xff09;是由 Anthropic 推出的一种开放协议&#xff0c;类似 AI 的 USB-C 扩展坞&#xff0c;用于在大模型和数据源之间建立安全的通信&#xff08;授权&#xff09;&#xff0c;让 AI 应用能够安全地访问和操作本地或远程…

【Linux】vim配置----超详细

目录 一、插件管理器准备 二、目录准备 三、安装插件 一、插件管理器准备 Vim-plug 是一个Vim插件管理器&#xff0c;利用异步并行可以快速地安装、更新和卸载插件。它的安装和配置都非常简单&#xff0c;而且在操作过程中会给出很多易读的反馈信息&#xff0c;是一个自由、…

PHP实现图片自动添加水印效果

<?php // 设置原始图片路径和水印图片路径 $original_image original.jpg; $watermark_image watermark.png;// 创建图片资源 $original imagecreatefromjpeg($original_image); $watermark imagecreatefrompng($watermark_image);// 获取图片尺寸 $original_width im…

检查新接手LINUX服务器应用的部署情况和正在运行的服务

当接手一台新的 Linux 服务器时&#xff0c;第一要务就是摸清系统上已经安装部署了哪些应用和服务。 本文将以 CentOS7为例&#xff0c;详细介绍如何系统地排查已安装的应用和服务&#xff0c;包括它们的安装方式和安装位置。 1.查看系统基本信息 首先获取系统整体信息&…

使用注解方式整合ssm时,启动tomcat扫描不到resource下面的xxxmapper.xml问题,解决方法

解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.xxx.mapper.方法 在Spring与Mybatis整合时&#xff0c;可能会遇到这样的报错 原因&#xff1a; 其原因为mapper路径的映射错误&#xff0c;表示在尝试执行某个 Mapper 接口的方法时…

C++11特性补充

目录 lambda表达式 定义 捕捉的方式 可变模板参数 递归函数方式展开参数包 数组展开参数包 移动构造和移动赋值 包装器 绑定bind 智能指针 RAII auto_ptr unique_ptr shared_ptr 循环引用 weak_ptr 补充 总结 特殊类的设计 不能被拷贝的类 只能在堆上创建…

My SQL 索引

核心目标&#xff1a; 理解 mysql 索引的工作原理、类型、优缺点&#xff0c;并掌握创建、管理和优化索引的方法&#xff0c;以显著提升数据库查询性能。 什么是索引&#xff1f; 索引是一种特殊的数据库结构&#xff0c;它包含表中一列或多列的值以及指向这些值所在物理行的指…

极狐GitLab 注册限制如何设置?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 注册限制 (BASIC SELF) 您可以对注册实施以下限制&#xff1a; 禁用新注册。新注册需要管理员批准。需要用户电子邮件确认。…

10.(vue3.x+vite)div实现tooltip功能(css实现)

1:效果截图 2:代码实现 <template><div><div class="tooltip" style="margin-top: 20%; margin-left: 20%; background-color: blueviolet; color: white;

Linux下 文件的查找、复制、移动和解压缩

1、在/var/log目录下创建一个hehe.log的文件&#xff0c;其文件内容是&#xff1a; myhostname ghl mydomain localdomain relayhost [smtp.qq.com]:587 smtp_use_tls yes smtp_sasl_auth_enable yes smtp_sasl_security_options noanonymous smtp_sasl_tls_security_opt…

Ubuntu 安装 Docker 教程(官方推荐方式)

✅ 步骤 1&#xff1a;卸载旧版本&#xff08;如果有&#xff09; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done---### ✅ 步骤 2&#xff1a;更新 APT 索引并安装依赖项bash sudo a…

计算机视觉与深度学习 | Transformer原理,公式,代码,应用

Transformer 详解 Transformer 是 Google 在 2017 年提出的基于自注意力机制的深度学习模型,彻底改变了序列建模的范式,解决了 RNN 和 LSTM 在长距离依赖和并行计算上的局限性。以下是其原理、公式、代码和应用的详细解析。 一、原理 核心架构 Transformer 由 编码器(Encod…

计算机基础 | 常见进制与单位简介 / 表示 / 描述

注&#xff1a;本文为 “进制与常见单位应用” 相关文章合辑。 原文为繁体&#xff0c;注意术语描述差异。 略作重排。 进制简介&#xff08;二进制、八进制、十进制、十六进制&#xff09; 发表于 2017-01-20 郑中胜 数字系统&#xff08;Numeral system&#xff09;&#…

门面模式与适配器模式

一、门面模式 门面模式&#xff1a;提供统一接口访问子系统接口 1、包含角色 外观系统对外的统一接口子系统类的集合&#xff1b;并不知道外观角色的存在&#xff0c;需要为了配合外观角色而做特殊处理或修改 2、举例 原本开关灯要分别操作各个房间的灯&#xff0c;现在设置总…

SpringBoot Actuator指标收集:Micrometer与Prometheus集成

文章目录 引言一、Spring Boot Actuator基础二、Micrometer简介与集成三、基本指标收集与配置四、自定义业务指标实现五、与Prometheus集成六、实战案例&#xff1a;API性能监控总结 引言 在现代微服务架构中&#xff0c;监控应用程序的健康状况和性能指标变得至关重要。Sprin…

【Android面试八股文】Android应用进程的启动流程【二】

应用进程 1.1 Android系统进程的启动过程&#xff1a; 1、init进程fork出Zygote进程后&#xff0c;Zygote进程会创建一个服务端socket&#xff0c;等待AMS发起socket请求。 同时&#xff0c;由Zygote进程fork出的SystemServer进程会启动各项系统服务&#xff0c;其中就包含了A…

基于Django的AI客服租车分析系统

基于Django的AI客服租车分析系统 【包含内容】 【一】项目提供完整源代码及详细注释 【二】系统设计思路与实现说明 【三】AI智能客服与用户交互指导手册 【技术栈】 ①&#xff1a;系统环境&#xff1a;Python 3.8&#xff0c;Django 4.2框架 ②&#xff1a;开发环境&a…

全同态加密医疗数据分析集python实现

目录 摘要一、前言二、全同态加密与医疗数据分析概述2.1 全同态加密(FHE)简介2.2 医疗数据分析需求三、数据生成与预处理四、系统架构与流程4.1 系统架构图五、核心数学公式六、异步任务调度与(可选)GPU 加速七、PyQt6 GUI 设计八、完整代码实现九、自查测试与总结十、展望…