langchain4j搭建失物招领系统(一)---初始化项目

一、项目初始化

首先,先搭建一个简单的springboot 项目,我们通过spring Initializr 初始化一个springboot 项目,jdk版本设置17,springboot 版本3.4.4,引入依赖如下:

xml 复制代码
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <scope>runtime</scope>
</dependency>
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <optional>true</optional>
</dependency>

定义一个AiController,

java 复制代码
@RestController
@RequestMapping("/ai")
public class AiController {

    @GetMapping("/chat")
    public String chat() {
        return "Hello World";
    }

}

启动,访问http://127.0.0.1:8080/ai/chat

页面输出:

项目初始化结束。

二、引入langchain4j依赖

因为使用的是阿里的百炼平台,这边直接引入百炼的依赖,其他大模型类似。

xml 复制代码
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
    <version>1.0.0-beta2</version>
</dependency>

三、langchain4j基本测试

1、文本输出

直接开始测试调用,选择deepseek-r1模型

java 复制代码
@Test
void test_deepseek_chat() {
    QwenChatModel chatModel = QwenChatModel.builder()
            .apiKey(System.getenv("ALI_AI_KEY"))
            .modelName("deepseek-r1")
            .build();

    System.out.println(chatModel.chat("你是谁?"));
}

返回

2、文本流式输出

java 复制代码
@Test
void test_deepseek_stream_chat() throws InterruptedException {
    QwenStreamingChatModel chatModel = QwenStreamingChatModel.builder()
            .apiKey(System.getenv("ALI_AI_KEY"))
            .modelName("deepseek-r1")
            .build();
    CountDownLatch countDownLatch = new CountDownLatch(1);
    chatModel.chat("你是谁?", new StreamingChatResponseHandler() {
        @Override
        public void onPartialResponse(String s) {
            System.out.println(s);
        }

        @Override
        public void onCompleteResponse(ChatResponse chatResponse) {
            System.out.println("完成。。。");
            countDownLatch.countDown();
        }

        @Override
        public void onError(Throwable throwable) {
            System.out.println("出错了。。。");
        }
    });
    countDownLatch.await();
}

返回

可以看到数据是流式输出的。

3、图片生成

使用万相大模型

java 复制代码
@Test
void test_image_generate(){
    WanxImageModel imageModel = WanxImageModel.builder()
            .apiKey(System.getenv("ALI_AI_KEY"))
            .modelName("wanx2.1-t2i-turbo")
            .build();
    Response<Image> generate = imageModel.generate("给我生成一张猫的图片");
    System.out.println(generate.content().url());
}

输出如下:

生成的图片

还不错。。。

4、图片理解

java 复制代码
@Test
void test_image_recognize(){
    QwenChatModel chatModel = QwenChatModel.builder()
            .apiKey(System.getenv("ALI_AI_KEY"))
            .modelName("qwen2.5-vl-32b-instruct")
            .build();
    UserMessage userMessage = UserMessage.from(
            TextContent.from("这个照片上面描述了什么?"),
            ImageContent.from("https://dashscope-result-wlcb-acdr-1.oss-cn-wulanchabu-acdr-1.aliyuncs.com/1d/76/20250325/b0fe3396/c09ada40-37f1-4748-9d32-82a373c79534151007983.png?Expires=1742978890&OSSAccessKeyId=LTAI5tKPD3TMqf2Lna1fASuh&Signature=gOV4MUh2glEKgk2PNXJZBOEENDI%3D")
    );
    ChatResponse chatResponse = chatModel.chat(userMessage);
    System.out.println(chatResponse.aiMessage().toString());
}

输出如下:

5、AI Services

langchain4j还有很多其他的组件,比如对话流记忆,RAG,function call(Tools)等等(这些我就不单独测试了),这些都能自由使用和组合,但在业务中使用,就会写很多类似的模板方法,langchain4j提供了更高层级的封装,就是AI Services。

需要先引入langchain4j的依赖

xml 复制代码
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-spring-boot-starter</artifactId>
    <version>${langchain4j.version}</version>
</dependency>

使用如下:

定义一个AI Services接口

java 复制代码
interface Assistant {

    String chat(String userMessage);

}

定义Tools

java 复制代码
static class Tools {

    @Tool("获取用户所在的班级")
    public String getUserClass(
            @P("用户姓名") String userName) {
        System.out.println("用户姓名是:"+userName);
        return "三班";
    }

}

组合AI Services

java 复制代码
@Test
void test_ai_service(){
    ChatLanguageModel model = QwenChatModel.builder()
            .apiKey(System.getenv("ALI_AI_KEY"))
            .modelName("qwen2.5-7b-instruct-1m")
            .build();
    Assistant assistant = AiServices.builder(Assistant.class)
            .chatLanguageModel(model)
            // 对话记忆
            .chatMemory(new MessageWindowChatMemory.Builder()
                    .id("test")
                    .maxMessages(10)
                    .chatMemoryStore(new InMemoryChatMemoryStore())
                    .build())
            // function call
            .tools(new Tools())
            .build();
    String message = assistant.chat("你好,我叫张三,今年20岁。");
    System.out.println(message);
    message = assistant.chat("我是谁,我是几班的?");
    System.out.println(message);
}

返回如下:

基本测试使用就这些,后面就直接配合springboot 使用。

四、springboot中使用

定义一个配置类,配置对话流历史的存储方式

java 复制代码
@Configuration
public class AssistantConfig {

    @Bean
    public ChatMemoryProvider chatMemoryProvider(ChatMemoryStore chatMemoryStore){
        return id -> new MessageWindowChatMemory.Builder()
                .id(id)
                .chatMemoryStore(chatMemoryStore)
                .maxMessages(10)
                .build();
    }

    @Bean
    public ChatMemoryStore chatMemoryStore(){
        return new InMemoryChatMemoryStore();
    }

}

定义Tools,使用@Component依赖注入到spring容器中

java 复制代码
@Component
public class TestTools {

    @Tool("获取用户所在的班级")
    public String getUserClass(
            @P("用户姓名") String userName) {
        System.out.println("用户姓名是:"+userName);
        return "三班";
    }

    @Tool("获取今天的天气")
    public String getWeather(
            @P("地址") String address) {
        System.out.println("当前地址是:"+address);
        return "天气晴朗!";
    }

}

定义ai services,配置相应的使用参数

java 复制代码
@AiService(wiringMode = AiServiceWiringMode.EXPLICIT, chatModel = "qwenChatModel",
        streamingChatModel = "qwenStreamingChatModel", chatMemoryProvider = "chatMemoryProvider",
        tools = "testTools")
public interface AiAssistant {

    String chat(@MemoryId String id, @UserMessage String message);

    Flux<String> chatStream(@MemoryId String id, @UserMessage String message);

}

配置属性中配置qwen的配置

properties 复制代码
langchain4j.community.dashscope.chat-model.api-key=${ALI_AI_KEY}
langchain4j.community.dashscope.chat-model.model-name=qwen2.5-7b-instruct-1m
langchain4j.community.dashscope.streaming-chat-model.api-key=${ALI_AI_KEY}
langchain4j.community.dashscope.streaming-chat-model.model-name=qwen2.5-7b-instruct-1m

Flux输出还需要引入langchain4j依赖

xml 复制代码
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-reactor</artifactId>
    <version>${langchain4j.version}</version>
</dependency>

定义web接口

java 复制代码
@RestController
@RequestMapping("/ai")
@RequiredArgsConstructor
public class AiController {

    private final AiAssistant aiAssistant;

    @GetMapping("/chat")
    public String chat(@RequestParam(value = "message", defaultValue = "Hello") String message,
                       @RequestParam(value = "userId", defaultValue = "111") String userId) {
        return aiAssistant.chat(userId,message);
    }

    @GetMapping(value = "/chat-stream",produces = MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
    public Flux<String> chatStream(@RequestParam(value = "message", defaultValue = "Hello") String message,
                             @RequestParam(value = "userId", defaultValue = "111") String userId) {
        return aiAssistant.chatStream(userId,message);
    }

}

页面上直接调用

历史对话&tools使用

换另一个用户,发现对话流式是新的

流式输出

over。。。

相关推荐
wand codemonkey12 分钟前
SpringbootWeb【入门】+MySQL【安装】+【DataDrip安装 】+【连接MySQL】
java·mysql·mybatis
测试员周周6 小时前
【Appium 系列】第16节-WebView-H5上下文切换 — 混合应用的自动化难点
运维·开发语言·人工智能·功能测试·appium·自动化·测试用例
K姐研究社8 小时前
怎么用AI制作电商口播视频,开拍APP一键生成
人工智能·音视频
LaughingZhu8 小时前
Product Hunt 每日热榜 | 2026-05-21
前端·人工智能·经验分享·chatgpt·html
Mahir088 小时前
Spring 循环依赖深度解密:从问题本质到三级缓存源码级解析
java·后端·spring·缓存·面试·循环依赖·三级缓存
传说故事8 小时前
【论文阅读】MotuBrain: An Advanced World Action Model for Robot Control
论文阅读·人工智能·具身智能·wam
北京耐用通信9 小时前
全域适配工业场景耐达讯自动化Modbus TCP 转 PROFIBUS 网关轻松实现以太网与现场总线互通
网络·人工智能·网络协议·自动化·信息与通信
火山引擎开发者社区9 小时前
TRAE × 火山引擎 Supabase:为你的 AI 应用装上“数据引擎”
人工智能
RyFit9 小时前
SpringAI 常见问题及解决方案大全
java·ai
小a彤9 小时前
GE 在 CANN 五层架构中的位置
人工智能·深度学习·transformer