springboot集成langchain4j实现票务助手实战

news2025/5/13 10:00:46

前言

看此篇的前置知识为langchain4j整合springboot,以及springboot集成langchain4j记忆对话。

Function-Calls介绍

  • langchain4j 中的 Function Calls(函数调用)是一种让大语言模型(LLM)与外部工具(如 API、代码执行器等)交互的机制。通过这种机制,LLM 可以根据上下文动态调用开发者预定义的函数,从而扩展其能力边界,解决纯文本生成无法处理的复杂任务(如数学计算、实时数据查询、业务逻辑处理等)。
  • 对于基础大模型来说,他只具备通用信息,他的参数都是拿公网进行训练,并且有一定的时间延迟,无法得知一些具体业务数据和实时数据,这些数据往往被各软件系统存储在自己数据库中:
  • 比如我现在开发一个智能票务助手我现在跟AI说需要退票,AI怎么做到呢?就需要让AI调用我们自己系统的退票业务方法,进行数据库操作。
  • 那这些都可以通过function-call进行完成,更多的用于实现类似智能客服场景,因为客服需要帮用户解决业务问题(就需要调用业务方法)。

Function-Calls流程

比如: 现在当用户问的是“kizzo页面访问量有多少”,大模型需要从程序内部获取
1.问大模型 “页面访问量有多少”
2.大模型在识别到你的问题是:“kizzo页面访问量有多少”
3.大模型提取“访问量”
4.调用 pageViewCount方法
5.通过返回的结果再结合上下文再次请求大模型
6.响应“Kizzo页面的访问量目前有1000次。”

用户 应用langchain4j 大模型 页面访问量有多少? 调用记忆接口,输入message"页面访问量有多少?" 提取关键字"访问量”并调用pageViewCount方法" 返回1000 组织语言,返回"Kizzo页面的访问量目前有1000次。" Kizzo页面的访问量目前有1000次。 用户 应用langchain4j 大模型

Function-Calls代码实现

  1. 加入回调
@Service
@Slf4j
public class ToolsService {
    @Tool("kizzo页面访问量有多少")
    public Integer pageViewCount(@P("访问量") String pv){
        //todo 此处可以查询数据库或rpc方法
        log.info("pv:{}", pv);
        // 结果
        return 1000;
    }
}

ToolsService配置为了一个bean
@Tool 用于告诉AI什么对话调用这个方法
@P(“访问量")用于告诉AI,调用方法的时候需要提取对话中的什么信息,这里提取的是访问量

  1. 在AiConfig中的助手对象增加Function-Calls Tools
    @Bean
    public Assistant assistant(ChatLanguageModel chatLanguageModel, StreamingChatLanguageModel streamingChatLanguageModel, ToolsService toolsService){
        // 最多存储多少聊天记录
        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
        // 为Assistant动态代理对象chat ---> 对话内容存储ChatMemoryi ---> 聊天记录ChatMemory取出来 ---->放入到当前对话中
        Assistant assistant = AiServices.builder(Assistant.class)
                .tools(toolsService)
                .chatLanguageModel(chatLanguageModel)
                .streamingChatLanguageModel(streamingChatLanguageModel)
                .chatMemory(chatMemory)
                .build();
        return assistant;
    }

再次调用后结果如下:
在这里插入图片描述

预设角色(系统消息SystemMessage)

基础大模型是没有目的性的,你聊什么给什么,但是如果我们开发的事一个智能票务助手,我需要他以一个票务助手的角色跟我对话, 并且在我跟他说”退票”的时候, 让大模型一定要告诉我“车次”和“姓名"这样我才能去调用业务方法(假设有一个业务方法,需要根据车子和姓名才能查询具体车票),进行退票。
在langchain4j中实现也非常简单

  • @SystemMessage 系统消息,一般做一些预设角色的提示词,设置大模型的基本职责
  • 可以通过{{current date}} 传入参数,因为预设词中的文本可能需要实时变化
  • @V(“current date”),通过@V传入{{}中的参数
  • 一旦参数不止一个,就需要通过@UserMessage设置用户信息

代码实现:

  1. 在AiConfig中的助手对象重载一个stream流输出方法,用@SystemMessage预设提示词角色
        @SystemMessage("""
                您是“xx”航空公司的客户聊天支持代理。请以友好、乐于助人且愉快的方式来回复。
                您正在通过在线聊天系统与客户互动。
                在提供有关预订或取消预订的信息之前,您必须始终从用户处获取以下信息:预订号、客户姓名。
                请讲中文。
                今天的日期是 {{current_date}}.
                """)
        TokenStream stream(@UserMessage String message, @V("current_date") String currentDate);
  1. 在ToolsService中新增一个tool
    @Tool("退票")
    public String cancelBooking(@P("地区") String bookingNumber,@P("姓名") String name){
        //todo 业务方法,退票数据库操作
        log.info("bookingNumber:{},name:{}", bookingNumber,name);
        // 结果
        return "退票成功";
    }

  1. Controller中新增一个接口调用
    // 预设角色记忆流对话
    @RequestMapping(value = "/system_message_chat_stream",produces = "text/stream;charset=UTF8")
    public Flux<String> systemMessageStreamChat(@RequestParam(defaultValue="我是谁") String message) {
        TokenStream stream = assistant.stream(message, LocalDate.now().toString());
        return Flux.create(sink ->  {
            stream.onPartialResponse(s -> sink.next(s))
                    .onCompleteResponse(c -> sink.complete())
                    .onError(sink::error)
                    .start();
        });
    }

结果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2374567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Feed流推送之订阅推送

分类 feed流分为TimeLine和智能排序&#xff0c;前者不对内容进行过滤&#xff0c;一般根据发布的时间来进行排序&#xff0c;一般用于好友动态或者推送关注的人的消息&#xff0c;而后者一般有着复杂的算法&#xff0c;可以根据算法智能地向目标用户推送内容&#xff0c;例如…

wordpress自学笔记 第四节 商城菜单的添加和修改美化

wordpress自学笔记 摘自 超详细WordPress搭建独立站商城教程-第四节 商城菜单的添加和修改美化&#xff0c;2025 WordPress搭建独立站商城#WordPress建站教程https://www.bilibili.com/video/BV1UwwgeuEkK?spm_id_from333.788.videopod.sections&vd_sourcea0af3bbc6b6d…

GPU L2 Cache一致性协议对科学计算的影响研究

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生专属优惠。 一、GPU缓存层级革命&#xff1a;从Volta到Hopper的演进图谱 1.1 架构级缓存策略对比 ‌Vo…

【速写】KV-cache与解码的再探讨(以束搜索实现为例)

文章目录 1 Beam Search 解码算法实现2 实现带KV Cache的Beam Search解码3 关于在带kv-cache的情况下的use_cache参数 1 Beam Search 解码算法实现 下面是一个使用PyTorch实现的beam search解码算法&#xff1a; 几个小细节&#xff1a; 束搜索可以加入length_penalty&#…

(网络)应用层协议-HTTPS

1.HTTPS是什么&#xff1f; HTTPS是应用层的一种协议&#xff0c;是在HTTP的基础上进行了加密层的处理。 HTTP协议的内容都是按照文本的形式进行传输的&#xff0c;所以呢就很容易被别人知道传输的是什么。 我们在了解了TCP/IP之后是知道我们的数据在传输的过程中是通过路由器进…

vue3: pdf.js 3.4.120 using javascript

npm install pdfjs-dist3.4.120 项目结构&#xff1a; pdfjsViewer.vue <template><div><div v-if"loading" class"flex justify-center items-center py-8"><div class"animate-spin rounded-full h-12 w-12 border-b-2 borde…

想实现一个基于MCP的pptx生成系统架构图【初版实现】

技术栈:Python + MCP协议 + python-pptx + FastMCP 核心创新点:通过MCP协议实现PPTX元素的动态化生成与标准化模板管理 当前还是个半成品,后续持续更新。 主要先介绍一下思路。 一、MCP协议与系统设计原理 1.1 为什么选择MCP? 标准化工具调用:通过MCP将PPTX元素生成逻辑封…

PyTorch Lightning实战 - 训练 MNIST 数据集

MNIST with PyTorch Lightning 利用 PyTorch Lightning 训练 MNIST 数据。验证梯度范数、学习率、优化器对训练的影响。 pip show lightning Version: 2.5.1.post0Fast dev run DATASET_DIR"/repos/datasets" python mnist_pl.py --output_grad_norm --fast_dev_run…

力扣2094题解

记录&#xff1a; 2025.5.12 题目&#xff1a; 思路&#xff1a; 暴力遍历。 解题步骤&#xff1a; 1.统计数字出现次数&#xff1a;使用数组cnt来记录输入数组中每个数字的出现次数。 2.生成三位偶数&#xff1a;通过循环从100开始&#xff0c;每次递增2&#xff0c;生成…

DHCP自动分配IP

DHCP自动分配IP 练习1 路由器 Router>en Router#conf t Router(config)#ip dhcp pool ip10 //创建DHCP地址池 Router(dhcp-config)#network 192.168.20.0 255.255.255.0 // 配置网络地址和子网掩码 Router(dhcp-config)#default-router 192.168.20.254 //配置默认网关 Rou…

【CF】Day57——Codeforces Round 955 (Div. 2, with prizes from NEAR!) BCD

B. Collatz Conjecture 题目&#xff1a; 思路&#xff1a; 简单模拟 很简单的模拟&#xff0c;我们只需要快速的找到下一个离 x 最近的 y 的倍数即可&#xff08;要大于 x&#xff09; 这里我们可以这样写 add y - (x % y)&#xff0c;这样就知道如果 x 要变成 y 的倍数还要…

(done) 补充:xv6 的一个用户程序 init 是怎么启动的 ?它如何启动第一个 bash ?

先看 main.c 从函数名来看&#xff0c;比较相关的就 userinit() 和 scheduler() #include "types.h" #include "param.h" #include "memlayout.h" #include "riscv.h" #include "defs.h"volatile static int started 0;//…

超详细讲解C语言转义字符\a \b \r \t \? \n等等

转义字符 C语言有一组字符很特殊&#xff0c;叫做转义字符&#xff0c;顾名思义&#xff0c;改变原来的意思的字符。 1 \? ??)是一个三字母词&#xff0c;在以前的编译器它会被编译为] (??会被编译为[ 因此在以前输入(are you ok ??)就会被编译为are you ok ] 解决这个…

SpringBoot校园失物招领信息平台

SpringBoot校园失物招领信息平台 文章目录 SpringBoot校园失物招领信息平台1、技术栈2、项目说明2.1、登录注册2.2、管理员端截图2.3、用户端截图 3、核心代码实现3.1、前端首页3.2、前端招领广场3.3、后端业务处理 1、技术栈 本项目采用前后端分离的架构&#xff0c;前端和后…

rust 全栈应用框架dioxus server

接上一篇文章dioxus全栈应用框架的基本使用&#xff0c;支持web、desktop、mobile等平台。 可以先查看上一篇文章rust 全栈应用框架dioxus&#x1f448; 既然是全栈框架&#xff0c;那肯定是得有后端服务的&#xff0c;之前创建的服务没有包含后端服务包&#xff0c;我们修改…

西安交大多校联训NOIP1模拟赛题解

西安交大多校联训NOIP1模拟赛题解 T1 秘境形式化题意思路代码&#xff08;丑陋&#xff09; T2 礼物形式化题意思路代码&#xff08;实现&#xff09; T3 小盒子的数论形式化题意思路代码&#xff08;分讨&#xff09; T4 猫猫贴贴(CF997E)形式化题意思路代码&#xff08;深奥&…

数据结构(三)——栈和队列

一、栈和队列的定义和特点 栈&#xff1a;受约束的线性表&#xff0c;只允许栈顶元素入栈和出栈 对栈来说&#xff0c;表尾端称为栈顶&#xff0c;表头端称为栈底&#xff0c;不含元素的空表称为空栈 先进后出&#xff0c;后进先出 队列&#xff1a;受约束的线性表&#xff0…

若依定制pdf生成实战

一、介绍 使用 Java Apache POI 将文字渲染到 Word 模板是一种常见的文档自动化技术&#xff0c;广泛应用于批量生成或定制 Word 文档的场景。使用aspose可以将word转成pdf从而达到定制化pdf的目的。 参考文档&#xff1a;java实现Word转Pdf&#xff08;Windows、Linux通用&a…

c++STL-vector的模拟实现

cSTL-vector的模拟实现 vector的模拟实现基本信息构造函数析构函数返回容量&#xff08;capacity&#xff09;返回元素个数&#xff08;size&#xff09;扩容&#xff08;reserve和resize&#xff09;访问&#xff08;[]&#xff09;迭代器&#xff08;**iterator**&#xff09…

在 Elasticsearch 中连接两个索引

作者&#xff1a;来自 Elastic Kofi Bartlett 解释如何使用 terms query 和 enrich processor 来连接 Elasticsearch 中的两个索引。 更多有关连接两个索引的查询&#xff0c;请参阅文章 “Elastic&#xff1a;开发者上手指南” 中的 “丰富数据及 lookup” 章节。 Elasticsea…