Lanchain4j的入门学习

手动创建AIservice类

arduino 复制代码
package com.ai.aiService;

public interface ConsultantService {
    public String chat(String message);//用于聊天的方法 使用aiservice的chat方法进行返回结果
}
less 复制代码
@Autowired
private ConsultantService consultantService;

@RequestMapping("/chat2")
public String chat2(@RequestParam("message") String message) {
    return consultantService.chat(message);
}//但是这个是通过手动的取创建aiservice
java 复制代码
//为aiService接口创建一个实现类,并将其注册为Spring Bean,以便在应用程序中使用
// 创建一个动态代理对象,代理对象实现了ConsultantService接口,
// 并将chatModel注入到代理对象中,以便在调用chat方法时能够使用chatModel进行聊天交互
@Autowired
private OpenAiChatModel model;
@Bean
public ConsultantService consultantService() {
    ConsultantService consultantService = AiServices.builder(ConsultantService.class)
    .chatModel(model)
    .build();
    return consultantService;
}//手动进行创建AIservice类

显示调用AiService类

typescript 复制代码
@AiService(
    wiringMode = AiServiceWiringMode.EXPLICIT,//手动装配
    chatModel = "openAiChatModel"//指定模型
)//使用AiService注解将ConsultantService2接口标记为一个AI服务,并指定其聊天模型为openAiChatModel
//自动的将chatmodel注入到ConsultantService2接口的实现类中,
// 以便在调用chat方法时能够使用chatModel进行聊天交互
public interface ConsultantService2 {
    public String chat(String message);
}
js 复制代码
less 复制代码
@Autowired
private ConsultantService consultantService2;

@RequestMapping("/chat3")//这个是aiService声明式使用
public String chat3(@RequestParam("message") String message) {
    return consultantService2.chat(message);
}

通过阻塞式调用等进行创建aiservice类

less 复制代码
package com.ai.aiService;

import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
import reactor.core.publisher.Flux;

@AiService(
    wiringMode = AiServiceWiringMode.EXPLICIT,
    chatModel = "openAiChatModel",
    streamingChatModel = "openAiStreamingChatModel",
    //    chatMemory = "chatMemory",//指定会话记忆对象  这个对象在bean配置类中进行创建并配置了会话记忆的相关参数
    chatMemoryProvider = "chatMemoryProvider",//指定会话记忆提供者  这个对象在bean配置类中进行创建并配置了会话记忆提供者的相关参数
    contentRetriever = "contentRetriever",//指定内容检索器  这个对象在bean配置类中进行创建并配置了内容检索器的相关参数
    tools = "reservationTool"//指定工具  这个对象在bean配置类中进行创建并配置了工具的相关参数
)//进行创建流式调用对象
public interface ConsultantService3 {
    //消息注解 设置聊天背景和角色
    //@SystemMessage("你是东哥的小助手,协助东哥解答问题,提供帮助。")//系统消息,设置聊天的背景和角色
    @SystemMessage(fromResource = "system.txt")//从资源文件中加载系统消息,设置聊天的背景和角色
    // @UserMessage("请你以东哥的小助手的身份,协助东哥解答问题,提供帮助。{{msg}}")
    //这两个注解区别是前者是系统消息,设置聊天的背景和角色,后者是用户消息,表示用户输入的消息内容,其中{{msg}}是一个占位符,用于在调用chat方法时动态传入用户输入的消息内容
    public Flux<String> chat(@MemoryId String memoryId, @UserMessage String message);
}
typescript 复制代码
@Repository
public class RedisChatMemoryStore implements ChatMemoryStore {
    //进行重写store接口中的方法,来实现对聊天记录的存储和管理
    //将其存放到redis中,来实现聊天记录的持久化和共享
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public List<ChatMessage> getMessages(Object memoryId) {

        //获取会话消息
        String json = stringRedisTemplate.opsForValue().get(memoryId);
        //把json数据转换成list
        List<ChatMessage> list = ChatMessageDeserializer.messagesFromJson(json);
        return list;
    }

    @Override
    public void updateMessages(Object memoryId, List<ChatMessage> list) {
        //更新会话消息

        //把list转换成json数据
        String json = ChatMessageSerializer.messagesToJson(list);
        //将json数据存储到redis中
        stringRedisTemplate.opsForValue().set(memoryId.toString(),json, Duration.ofDays(1));
    }

    @Override
    public void deleteMessages(Object memoryId) {
        stringRedisTemplate.delete(memoryId.toString());
    }
}
typescript 复制代码
//构建chatMemoryProvider对象
@Bean
public ChatMemoryProvider chatMemoryProvider() {
    ChatMemoryProvider chatMemoryProvider = new ChatMemoryProvider() {
        //chatMemoryProvider接口是一个提供会话记忆对象的接口,定义了一个get方法,用于根据传入的参数获取对应的ChatMemory对象
        @Override
        public ChatMemory get(Object memoryId) {
            //根据传入的参数o来获取对应的ChatMemory对象
            //可以根据o的类型或者值来决定返回哪个ChatMemory对象
            //例如,如果o是一个用户ID,可以根据用户ID来获取对应的ChatMemory对象
            //如果o是一个会话ID,可以根据会话ID来获取对应的ChatMemory对象
            //这里可以根据实际需求进行实现,返回一个ChatMemory对象
            MessageWindowChatMemory build = MessageWindowChatMemory.builder()
            .id(memoryId)
            .maxMessages(20)
            .chatMemoryStore(chatMemoryStore)
            .build();

            return build;
        }
    };

    return chatMemoryProvider;
}
scss 复制代码
//构建向量数据库操作对象
@Bean
public EmbeddingStore store() {
    //加载文档进内存
    // List<Document> content = ClassPathDocumentLoader.loadDocuments("content");
    List<Document> content = ClassPathDocumentLoader.loadDocuments("content", new ApachePdfBoxDocumentParser());//加载pdf文档
    //List<Document> content = FileSystemDocumentLoader.loadDocuments("D:\ideaproject\java-ai\src\main\resources\content");
    //构建向量数据库操作对象 操作的是内存版本的向量数据库
    //InMemoryEmbeddingStore Store = new InMemoryEmbeddingStore();
    //构建文档分割器对象
    DocumentSplitter recursive = DocumentSplitters.recursive(500, 100);
    //构建embeddingStoreIngestor对象 完成数据切割向量化,存储到向量数据库中
    EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
    //.embeddingStore(Store)
    .embeddingStore(RedisEmbeddingStore)//使用redis作为向量数据库
    .documentSplitter(recursive)
    .embeddingModel(embeddingModel)
    .build();
    //将文档转换成向量并存储到向量数据库中
    ingestor.ingest(content);
    return RedisEmbeddingStore;
}


//构建向量数据库检索对象
@Bean
public ContentRetriever contentRetriever(/*EmbeddingStore store*/) {//构建向量数据库检索对象 注意名字是store 不是默认的embeddingStore
    return EmbeddingStoreContentRetriever.builder()
    .embeddingStore(RedisEmbeddingStore)
    .minScore(0.5)
    .maxResults(3)
    .embeddingModel(embeddingModel)
    .build();
}
less 复制代码
@Component
public class ReservationTool {
    @Autowired
    private reservationService reservationService;

    //工具方法 添加预约信息
    @Tool("预约志愿填报服务")//使用Tool注解将addReservation方法标记为一个工具方法,并指定其名称为"预约志愿填报服务"
    public void addReservation(@P("考生姓名") String name,
                               @P("考生性别") String gender,
                               @P("考生手机号") String phone,
                               @P("预约沟通时间 格式 yyyy-MM-dd'T'HH:mm") String communicationTime,
                               @P("考生所在省份") String province,
                               @P("考生预估分数") Integer estimatedScore
                              ) {//创建预约对象
        Reservation reservation = new Reservation(null,name,gender,phone,java.time.LocalDateTime.parse(communicationTime),province,estimatedScore);
        //调用service方法添加预约信息
        reservationService.addReservation(reservation);
    }
    //查询预约信息
    @Tool("根据考生手机号查询预约单")
    public Reservation getReservationByPhone(@P("考生手机号") String phone) {
        //调用service方法查询预约信息
        return reservationService.getReservationByPhone(phone);
    }
}
相关推荐
devlei5 小时前
从源码泄露看AI Agent未来:深度对比Claude Code原生实现与OpenClaw开源方案
android·前端·后端
努力的小郑6 小时前
Canal 不难,难的是用好:从接入到治理
后端·mysql·性能优化
Victor3567 小时前
MongoDB(87)如何使用GridFS?
后端
Victor3567 小时前
MongoDB(88)如何进行数据迁移?
后端
小红的布丁7 小时前
单线程 Redis 的高性能之道
redis·后端
GetcharZp7 小时前
Go 语言只能写后端?这款 2D 游戏引擎刷新你的认知!
后端
宁瑶琴9 小时前
COBOL语言的云计算
开发语言·后端·golang
普通网友9 小时前
阿里云国际版服务器,真的是学生党的性价比之选吗?
后端·python·阿里云·flask·云计算
IT_陈寒10 小时前
Vue的这个响应式问题,坑了我整整两小时
前端·人工智能·后端
Soofjan11 小时前
Go 内存回收-GC 源码1-触发与阶段
后端