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

[复制链接]
发表于 2025-9-23 02:18:46 | 显示全部楼层 |阅读模式
【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扩展:
  1. <dependency>
  2.     <groupId>dev.langchain4j</groupId>
  3.     <artifactId>langchain4j-open-ai</artifactId>
  4.     <version>1.0.0-beta3</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>dev.langchain4j</groupId>
  8.     <artifactId>langchain4j</artifactId>
  9.     <version>1.0.0-beta3</version>
  10. </dependency>
复制代码
1.2 申请密钥(零门槛!)



  • 正式情况:通过OpenAI平台获取API Key
  • 尝鲜体验:直接利用官方Demo Key(配额有限,仅支持gpt-4o-mini)
  1. // 配置类中直接使用demo密钥
  2. .baseUrl("http://langchain4j.dev/demo/openai/v1")
  3. .apiKey("demo")
复制代码


  • ⚠️如果你没有API密钥怎么办?
如果你没有本身的OpenAI API密钥,别担心。你可以暂时利用官方免费提供的演示密钥,用于演示目标。请注意,当利用演示密钥时,全部对OpenAI API的请求都需要通过官方的署理服务器,该代分析在将你的请求转发给OpenAI API之前注入真实的密钥。官方不会以任何方式收集或利用你的数据。演示密钥有配额限制,仅限于gpt-4o-mini模型,并且只应用于演示目标。
  1. OpenAiChatModel model = OpenAiChatModel.builder()
  2.     .baseUrl("http://langchain4j.dev/demo/openai/v1")
  3.     .apiKey("demo")
  4.     .modelName("gpt-4o-mini")
  5.     .build();
复制代码
1.3设置application.yml

  1. spring:
  2.   application:
  3.     name: AI
  4.   ai:
  5.     openai:
  6.       api-key: "demo"
  7.       base-url: "http://langchain4j.dev/demo/openai/v1"
复制代码

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

2.1 模型设置(智能引擎)

  1. @Configuration
  2. public class LangChain4jConfig {
  3.     @Bean
  4.     public ChatLanguageModel chatLanguageModel() {
  5.         return OpenAiChatModel.builder()
  6.                 .baseUrl("http://langchain4j.dev/demo/openai/v1")
  7.                 .apiKey("demo") // 替换为真实KEY时移除baseUrl
  8.                 .modelName("gpt-4o-mini") // 最新轻量级模型
  9.                 .build();
  10.     }
  11. }
复制代码
关键点分析


  • baseUrl仅在利用Demo Key时需要
  • modelName指定模型版本,保举性能优秀的gpt-4o-mini
2.2 谈天控制器(对话大脑)

  1. @RestController
  2. @RequestMapping("/ai")
  3. public class ChatController {
  4.     private final ChatLanguageModel model;
  5.     private final ChatMemory chatMemory; // 自动记忆上下文
  6.     @GetMapping(value = "/chat", produces = "text/plain;charset=utf-8")
  7.     public Mono<String> chat(@RequestParam String message) {
  8.         UserMessage userMsg = UserMessage.from("你叫小智,是一个人工智能\n" + message);
  9.         chatMemory.add(userMsg);
  10.         
  11.         AiMessage aiMsg = model.chat(chatMemory.messages()).aiMessage();
  12.         chatMemory.add(aiMsg);
  13.         
  14.         return Mono.just(aiMsg.text());
  15.     }
  16. }
复制代码
  1. package org.example.ai.config;
  2. import dev.langchain4j.memory.ChatMemory;
  3. import dev.langchain4j.memory.chat.MessageWindowChatMemory;
  4. import dev.langchain4j.store.memory.chat.ChatMemoryStore;
  5. import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. @Configuration
  9. public class CommonConfiguration {
  10.     /**
  11.      * 定义一个基于消息数量限制的 ChatMemory Bean
  12.      */
  13.     @Bean
  14.     public ChatMemory messageWindowChatMemory(ChatMemoryStore chatMemoryStore) {
  15.         return MessageWindowChatMemory.builder()
  16.                 .id("session-1") // 会话 ID
  17.                 .maxMessages(10) // 最大消息数量
  18.                 .chatMemoryStore(chatMemoryStore) // 持久化存储
  19.                 .build();
  20.     }
  21.     /**
  22.      * 定义一个简单的内存存储实现
  23.      */
  24.     @Bean
  25.     public ChatMemoryStore inMemoryChatMemoryStore() {
  26.         return new InMemoryChatMemoryStore();
  27.     }
  28. }
复制代码
亮点功能


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



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

启动应用后访问:
  1. http://localhost:8080/ai/chat?message=讲个程序员笑话
复制代码
预期相应
  1. 好的,主人!为什么程序员总把万圣节和圣诞节搞混?
  2. 因为 Oct 31 == Dec 25!(Octal 31 = Decimal 25)
复制代码

加入前端代码
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>小智AI助手</title>
  7.     <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  8.     <style>
  9.         /* 现代聊天界面样式 */
  10.         :root {
  11.             --primary: #4CAF50;
  12.             --bg: #f5f5f5;
  13.             --user-bg: #e3f2fd;
  14.             --ai-bg: #ffffff;
  15.         }
  16.         body {
  17.             margin: 0;
  18.             font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  19.             background: var(--bg);
  20.         }
  21.         .chat-container {
  22.             max-width: 800px;
  23.             margin: 20px auto;
  24.             border-radius: 12px;
  25.             box-shadow: 0 2px 15px rgba(0,0,0,0.1);
  26.             background: white;
  27.             height: 90vh;
  28.             display: flex;
  29.             flex-direction: column;
  30.         }
  31.         .messages {
  32.             flex: 1;
  33.             overflow-y: auto;
  34.             padding: 20px;
  35.             display: flex;
  36.             flex-direction: column;
  37.             gap: 15px;
  38.         }
  39.         .message {
  40.             max-width: 70%;
  41.             padding: 12px 16px;
  42.             border-radius: 18px;
  43.             animation: fadeIn 0.3s ease;
  44.         }
  45.         .user-message {
  46.             background: var(--user-bg);
  47.             align-self: flex-end;
  48.             border-bottom-right-radius: 4px;
  49.         }
  50.         .ai-message {
  51.             background: var(--ai-bg);
  52.             align-self: flex-start;
  53.             border-bottom-left-radius: 4px;
  54.             box-shadow: 0 2px 4px rgba(0,0,0,0.05);
  55.         }
  56.         .loading-dots {
  57.             display: inline-block;
  58.             font-size: 24px;
  59.         }
  60.         .loading-dots::after {
  61.             content: '...';
  62.             animation: dots 1.5s infinite;
  63.         }
  64.         .input-area {
  65.             padding: 20px;
  66.             border-top: 1px solid #eee;
  67.             display: flex;
  68.             gap: 10px;
  69.         }
  70.         input {
  71.             flex: 1;
  72.             padding: 12px;
  73.             border: 1px solid #ddd;
  74.             border-radius: 25px;
  75.             font-size: 16px;
  76.             outline: none;
  77.             transition: 0.3s;
  78.         }
  79.         input:focus {
  80.             border-color: var(--primary);
  81.             box-shadow: 0 0 0 3px rgba(76,175,80,0.1);
  82.         }
  83.         button {
  84.             padding: 12px 24px;
  85.             background: var(--primary);
  86.             border: none;
  87.             border-radius: 25px;
  88.             color: white;
  89.             cursor: pointer;
  90.             transition: 0.3s;
  91.         }
  92.         button:disabled {
  93.             opacity: 0.7;
  94.             cursor: not-allowed;
  95.         }
  96.         @keyframes dots {
  97.             0%, 20% { content: '.'; }
  98.             40% { content: '..'; }
  99.             60%, 100% { content: '...'; }
  100.         }
  101.         @keyframes fadeIn {
  102.             from { opacity: 0; transform: translateY(10px); }
  103.             to { opacity: 1; transform: translateY(0); }
  104.         }
  105.     </style>
  106. </head>
  107. <body>
  108. <div id="app">
  109.     <div class="chat-container">
  110.         <div class="messages">
  111.             <div v-for="(msg, index) in messages"
  112.                  :key="index"
  113.                  :class="['message', msg.role === 'user' ? 'user-message' : 'ai-message']">
  114.                 {{ msg.content }}
  115.             </div>
  116.             <div v-if="loading" class="message ai-message">
  117.                 <span class="loading-dots"></span>
  118.             </div>
  119.         </div>
  120.         <div class="input-area">
  121.             <input
  122.                     v-model="inputMessage"
  123.                     @keyup.enter="sendMessage"
  124.                     placeholder="和小智聊天吧~"
  125.                     :disabled="loading"
  126.             >
  127.             <button @click="sendMessage" :disabled="!inputMessage || loading">
  128.                 {{ loading ? '思考中' : '发送' }}
  129.             </button>
  130.         </div>
  131.     </div>
  132. </div>
  133. <script>
  134.     const { createApp } = Vue;
  135.     createApp({
  136.         data() {
  137.             return {
  138.                 messages: [],
  139.                 inputMessage: '',
  140.                 loading: false
  141.             }
  142.         },
  143.         methods: {
  144.             async sendMessage() {
  145.                 if (!this.inputMessage.trim() || this.loading) return;
  146.                 const userMessage = this.inputMessage;
  147.                 this.messages.push({ role: 'user', content: userMessage });
  148.                 this.inputMessage = '';
  149.                 this.loading = true;
  150.                 try {
  151.                     const response = await fetch(`/ai/chat?message=${encodeURIComponent(userMessage)}`);
  152.                     const text = await response.text();
  153.                     this.messages.push({ role: 'assistant', content: text });
  154.                 } catch (error) {
  155.                     this.messages.push({
  156.                         role: 'assistant',
  157.                         content: '哎呀,小智暂时无法连接,请稍后再试~'
  158.                     });
  159.                 } finally {
  160.                     this.loading = false;
  161.                     this.scrollToBottom();
  162.                 }
  163.             },
  164.             scrollToBottom() {
  165.                 this.$nextTick(() => {
  166.                     const container = document.querySelector('.messages');
  167.                     container.scrollTop = container.scrollHeight;
  168.                 });
  169.             }
  170.         },
  171.         mounted() {
  172.             // 初始欢迎语
  173.             this.messages.push({
  174.                 role: 'assistant',
  175.                 content: '你好!我是小智,有什么可以帮您的?'
  176.             });
  177.         }
  178.     }).mount('#app');
  179. </script>
  180. </body>
  181. </html>
复制代码

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

四、生产级优化发起


  • 密钥安全:通过application.yml设置,制止硬编码
    1. langchain4j:
    2.   openai:
    3.     api-key: ${OPENAI_API_KEY}
    复制代码
  • 限流降级:集成Resilience4j实现请求限流
  • 性能监控监控:通过Micrometer对接Prometheus
  • 上下文管理:利用PersistentChatMemory实现对话长期化

总结:为什么选择LangChain4j?

通过本文实战,我们体验到了:
极简集成:5行代码对接GPT-4o-mini
开箱即用:自动影象管理、流式相应支持
生态丰富:支持20+模型厂商,轻松切换
Spring Boot友爱:自动设置+依靠注入
下一步探索


  • 实验AI服务(Assistant API)实现复杂逻辑
  • 结合Embedding实现RAG知识库
  • 利用Tools API让模型调用外部服务
立刻访问LangChain4j官网开启你的AI应用开辟之旅!如果你在实践过程中碰到任何题目,欢迎在品评区留言交换~

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表