langchain4j搭建失物招领系统(五)---实现失物登记功能-大模型流式输出

今天来实现失物登记功能,整体实现类似于之前的丢失登记。

一、功能实现

1、失物数据定义

定义一个失物数据的数据库实体对象

java 复制代码
@EqualsAndHashCode(callSuper = true)
@Table(name = "lost_property")
@Entity
@Data
@Comment("失物表")
public class LostPropertyEntity extends BaseEntity {

    @Comment("捡到失物的用户姓名")
    private String username;

    @Comment("捡到失物的用户手机号")
    private String phone;

    @Comment("失物名称")
    private String lostName;

    @Comment("失物特征")
    private String lostType;

}

定义相应的查询工具类(用来更新操作)

java 复制代码
@Component
@Slf4j
public class LostPropertyTools {

    @Autowired
    private LostPropertyRepository lostPropertyRepository;

    @Tool("根据手机号查询物品登记信息")
    public List<LostPropertyEntity> queryLostPropertyByPhone(@P(value = "用户手机号") String phone) {
        log.info("根据手机号查询物品登记信息,手机号: {}", phone);
        return lostPropertyRepository.findAllByPhone(phone);
    }

}

2、大模型定义

定义一个流式功能的大模型,这次使用qwq-32b模型,支持function call,不过该模型只支持流式输出。

java 复制代码
@Configuration
public class ChatConfig {

    public static final String QAQ_CHAT_BEAN = "qwenQaQStreamingChatModel";

    @Bean(QAQ_CHAT_BEAN)
    public StreamingChatLanguageModel qwenStreamingChatModel() {
        return QwenStreamingChatModel.builder()
                .apiKey(System.getenv("ALI_AI_KEY"))
                .modelName("qwq-32b")
                .build();
    }


}

AI助手定义,使用Flux接受返回数据

java 复制代码
@AiService(wiringMode = AiServiceWiringMode.EXPLICIT, streamingChatModel = QAQ_CHAT_BEAN,
        tools = {"chatHistoryTools", "lostPropertyTools"})
public interface LostPropertyAssistant {

    /**
     * 登记失物信息
     */
    @SystemMessage(fromResource = "/message/system/registerLostProperty.txt")
    @UserMessage("当前sessionId:{{sessionId}};用户当前消息:{{message}}")
    Flux<String> registerLostProperty(@V("sessionId") String id, @V("message") String message);

}

3、提示词定义

整体类似于之前的丢失登记,增加了对于输出的描述(ps:这个提示词调试了好久。。。)

plain 复制代码
# 角色
你是一位专业且尽责的失物登记专员,始终秉持耐心、细致的态度,精准且全面地登记用户的失物信息,全力以赴保障失物能顺利归还失主。在与用户沟通时,使用礼貌、亲和的语言。

## 技能
### 技能 1: 登记失物信息
- 每次对话,需要调用读取用户历史对话内容工具获取用户对话历史。
- 如果用户已经输入了手机号,调用queryLostPropertyByPhone函数查询用户丢失物品的信息。若能查询到数据,可能有多条数据,将其与用户已输入的物品信息进行匹配(比较失物名称和失物特征是否是能匹配),最多返回一条已经匹配的数据,并填充id字段(返回记录id),并记录,判断用户意图是否为补充数据。若判断"是",询问用户是否要补充数据。若判断"否",则直接进入正常登记流程,无需向用户说明数据库查询情况。
- 当用户提供失物相关信息时,从中提取物品信息和相关特征,主动询问用户的姓名和手机号,并准确记录。同时,详细引导用户清晰描述失物的特征,包括颜色、材质、尺寸、特殊标识等关键细节。
- 将登记的姓名、手机号、失物名称(对物品的简单描述,如手机、钱包、狗等,不要包含特征)、失物特征(颜色、材质、尺寸、特殊标识等信息)进行系统整理并记录。
- 根据用户输入情况,准确判断是否完成登记,并标记"true"或"false"。若判断为"false",清晰告知用户还缺少哪些信息。
- 若用户表示没有更多信息或特征,也可以完成登记。

## 限制:
- 仅处理与失物登记紧密相关的内容,拒绝回答无关话题。
- 所输出的内容需严格按照要求的格式进行组织,精准记录关键信息,禁止输出其他非json格式以外的内容,不要使用markdown语言输出。
- 对于用户反馈的信息,要确保准确记录和及时处理,不得遗漏重要信息。
- 要充分结合用户的历史对话记录,自然地承上启下,与用户进行协商,禁止机械重复话术,禁止重复或者相似的回复。
- 如果判断完成登记,必须要准确告诉用户已经完成登记。

## 输出格式
需要识别下面的JSON Schema,返回相应的json内容,输出JSON Schema 描述如下:
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "LostPropertyOutput",
  "type": "object",
  "properties": {
    "output": {
      "type": "string",
      "description": "大模型对用户的输出"
    },
    "username": {
      "type": "string",
      "description": "用户姓名"
    },
    "phone": {
      "type": "string",
      "description": "用户手机号"
    },
    "lostName": {
      "type": "string",
      "description": "失物名称"
    },
    "lostType": {
      "type": "string",
      "description": "失物特征"
    },
    "completed": {
      "type": "boolean",
      "description": "是否完成登记"
    },
    "id": {
      "type": "number",
      "description": "数据库记录id"
    }
  },
  "required": ["output", "completed"]
}

4、业务流程修改

增加一个registerLostProperty方法,实现如下:

java 复制代码
    private String registerLostProperty(String userId, String message) {
        StringBuilder sb = new StringBuilder();
        lostPropertyAssistant.registerLostProperty(userId, message)
                .doOnNext(sb::append)
                .blockLast();
        log.info("registerLostProperty sb:{}", sb);
        LostPropertyOutput lostPropertyOutput = JsonUtils.fromJson(sb.toString(), LostPropertyOutput.class);
        if (lostPropertyOutput.getCompleted()) {
            LostPropertyEntity lostPropertyEntity = new LostPropertyEntity();
            BeanUtils.copyProperties(lostPropertyOutput, lostPropertyEntity);
            lostPropertyRepository.save(lostPropertyEntity);
        }
        return lostPropertyOutput.getOutput();
    }

修改switch语句:

二、功能测试

1、失物登记测试

访问http://127.0.0.1:8080/

数据库内容如下:

2、数据修改测试

重新设置一个新的用户id

数据库内容如下:

功能完成。。。。

整体看来,感觉流式输出更适合查询相关的流程。

相关推荐
feng9952043 分钟前
技术伦理双轨认证如何重构AI工程师能力评估体系——基于AAIA框架的技术解析与行业实证研究
人工智能·aaif·aaia·iaaai
2301_776681651 小时前
【用「概率思维」重新理解生活】
开发语言·人工智能·自然语言处理
蜡笔小新..1 小时前
从零开始:用PyTorch构建CIFAR-10图像分类模型达到接近1的准确率
人工智能·pytorch·机器学习·分类·cifar-10
富唯智能2 小时前
转运机器人可以绕障吗?
人工智能·智能机器人·转运机器人
熊大如如2 小时前
Java 反射
java·开发语言
猿来入此小猿2 小时前
基于SSM实现的健身房系统功能实现十六
java·毕业设计·ssm·毕业源码·免费学习·猿来入此·健身平台
视觉语言导航2 小时前
湖南大学3D场景问答最新综述!3D-SQA:3D场景问答助力具身智能场景理解
人工智能·深度学习·具身智能
AidLux2 小时前
端侧智能重构智能监控新路径 | 2025 高通边缘智能创新应用大赛第三场公开课来袭!
大数据·人工智能
引量AI2 小时前
TikTok矩阵运营干货:从0到1打造爆款矩阵
人工智能·矩阵·自动化·tiktok矩阵·海外社媒
goTsHgo3 小时前
Spring Boot 自动装配原理详解
java·spring boot