langchain4j搭建失物招领系统(六)---实现失物查询功能-RAG使用

今天通过RAG来实现失物查询功能

一、RAG相关配置

1、定义向量数据库

java 复制代码
    // 配置向量数据库, 这里使用内存数据库
    @Bean
    public EmbeddingStore<TextSegment> embeddingStore() {
        return new InMemoryEmbeddingStore<>();
    }

2、定义向量模型

java 复制代码
    // 配置向量模型
    @Bean
    public EmbeddingModel embeddingModel() {
        return QwenEmbeddingModel.builder()
                .apiKey(System.getenv("ALI_AI_KEY"))
                .modelName("text-embedding-v3")
                .build();
    }

3、定义内容检索器

java 复制代码
    // 配置内容检索器
    @Bean
    public ContentRetriever contentRetriever(EmbeddingStore<TextSegment> embeddingStore, EmbeddingModel embeddingModel) {
        return EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(embeddingModel)
                .maxResults(2)
                .minScore(0.5)
                .build();
    }

二、向量数据初始化

1、初始化

要查询向量数据,需要先通过向量模型把数据先存入到向量数据库中,我这边先定义个接口初始化一下向量数据。

java 复制代码
    @GetMapping(value = "/embedding-index")
    public String embeddingIndex() {
        return aiChatService.embeddingIndex();
    }

初始化代码如下:

java 复制代码
    public String embeddingIndex() {
        String path = "./data/data.txt";
        try {
            // 将丢失物品数据写入文件
            FileUtil.writeString("", path, StandardCharsets.UTF_8);
            List<String> collect = StreamSupport.stream(lostPropertyRepository.findAll().spliterator(), false)
                    .map(JsonUtils::toJson)
                    .toList();
            FileUtil.appendLines(collect, path, StandardCharsets.UTF_8);
            log.info("write file success");
        } catch (Exception e) {
            log.error("write file error", e);
        }

        // 加载并解析文档内容
        DocumentParser documentParser = new TextDocumentParser();
        Document document = FileSystemDocumentLoader.loadDocument(FileUtil.getAbsolutePath(path), documentParser);

        // 按行分割文档为指定长度的文本片段
        DocumentSplitter splitter = new DocumentByLineSplitter(200, 100);
        List<TextSegment> documents = splitter.split(document);

        // 生成文本片段的嵌入向量并存储
        List<Embedding> embeddings = embeddingModel.embedAll(documents).content();
        embeddingStore.addAll(embeddings, documents);
        
        return "success";
    }

2、测试

查询测试:

java 复制代码
    @GetMapping(value = "/embedding-query")
    public List<String> embeddingQuery(String message) {
        return aiChatService.embeddingQuery(message);
    }
java 复制代码
    public List<String> embeddingQuery(String message) {
        EmbeddingSearchRequest embeddingSearchRequest = EmbeddingSearchRequest.builder()
                .queryEmbedding(embeddingModel.embed(message).content())
                .minScore(0.5)
                .maxResults(2)
                .build();
        EmbeddingSearchResult<TextSegment> search = embeddingStore.search(embeddingSearchRequest);
        return search.matches().stream().map(x -> x.embedded().text()).collect(Collectors.toList());
    }

我这边先通过DeepSeek帮我生成了一些失物数据,如下:

启动服务后,先初始化一下向量数据:

然后测试一下:

三、向量数据查询

1、增加失物查询工具

java 复制代码
    @Tool("根据物品及物品特征查询物品登记信息")
    public List<String> queryLostProperty(@P(value = "物品名称和特征") String lostProperty) {
        log.info("根据物品及物品特征查询物品登记信息,物品名称和特征: {}", lostProperty);
        List<String> list = contentRetriever.retrieve(new Query(lostProperty))
                .stream()
                .map(x -> x.textSegment().text())
                .toList();
        log.info("根据物品及物品特征查询物品登记信息,查询结果: {}", list);
        return list;
    }

2、定义AiServices

java 复制代码
    /**
     * 查询失物信息
     */
    @SystemMessage(fromResource = "/message/system/queryLostProperty.txt")
    @UserMessage("当前sessionId:{{sessionId}};用户当前消息:{{message}}")
    Flux<String> queryLostProperty(@V("sessionId") String id, @V("message") String message);

提示词:

plain 复制代码
# 角色
你是一位专业的失物管理员,负责处理失物招领相关工作。根据用户输入的丢失物品信息,仔细与系统中已录入的失物信息进行比对,并准确告知用户拾取到人的信息。

## 技能
### 技能 1: 比对丢失物品信息
- 每次对话,需要调用getChatHistory函数获取用户对话历史。
- 主动询问用户的姓名和手机号。
- 当用户提供失物相关信息时,从中提取物品信息和相关特征。
- 如果用户已经输入了手机号,调用queryLostRegisterByPhone函数查询用户丢失物品的信息。若能查询到数据,可能有多条数据,将其与用户已输入的物品信息进行匹配(比较失物名称和失物特征是否是能匹配),最多返回一条已经匹配的数据,如果没有查询到数据,需要引导用户进入登记流程。
- 如果已经查询到用户登记的丢失信息,获取丢失的失物信息和相关失物特征,调用queryLostProperty函数,获取系统中已经录入的失物信息,将其与系统中录入的失物信息进行详细比对。
- 若找到匹配信息,准确提取并整理拾取到人的相关信息。
- 以清晰易懂的方式向用户反馈拾取到人的信息。

## 限制:
- 仅围绕失物招领工作展开交流,拒绝回答无关话题。
- 反馈信息应基于系统中已录入的信息,确保准确性。
- 不要调用其他无关函数。

3、修改业务调用

java 复制代码
    private String queryLostProperty(String userId, String message) {
        StringBuilder sb = new StringBuilder();
        lostPropertyAssistant.queryLostProperty(userId, message)
                .doOnNext(sb::append)
                .blockLast();
        log.info("queryLostProperty:{}", sb);
        return sb.toString();
    }

4、测试

数据库中数据如下:

测试一下:

over。。。

相关推荐
摆烂仙君9 分钟前
注意力(Attention)机制详解(附代码)
人工智能·机器学习·计算机视觉
深色風信子11 分钟前
Eclipse 插件开发 5 编辑器
java·eclipse·编辑器
小魏的马仔34 分钟前
【java】使用iText实现pdf文件增加水印功能
java·开发语言·pdf
李匠202435 分钟前
C++GO语言微服务项目之 go语言基础语法
开发语言·c++·后端·golang
数造科技37 分钟前
数造科技携 DataBuilder 亮相安徽科交会,展现“DataOps +AI”双引擎魅力
大数据·人工智能·科技·ai·业界资讯·data
老任与码43 分钟前
Spring AI(1)—— 基本使用
java·人工智能·spring ai
埃菲尔铁塔_CV算法1 小时前
基于神经网络的 YOLOv8、MobileNet、HigherHRNet 姿态检测比较研究
人工智能·深度学习·神经网络·yolo·目标检测·机器学习
Chat_zhanggong3451 小时前
AI训练服务器概述
运维·服务器·人工智能
cnbestec1 小时前
从人体姿态到机械臂轨迹:基于深度学习的Kinova远程操控系统架构解析
服务器·人工智能·机器人
SnXJi_1 小时前
纷析云开源财务软件:低成本构建企业自主的数字化财务中枢
java·git·开源·开源软件