当前位置: 首页 > news >正文

【Java-LangChain:面向开发者的提示工程-8】聊天机器人

第八章 聊天机器人

使用一个大型语言模型的一个令人兴奋的事情是,我们可以用它来构建一个定制的聊天机器人 (Chatbot) ,只需要很少的工作量。在这一节中,我们将探索如何利用聊天的方式,与个性化(或专门针对特定任务或行为的)聊天机器人进行扩展对话。

像 ChatGPT 这样的聊天模型实际上是组装成以一系列消息作为输入,并返回一个模型生成的消息作为输出的。这种聊天格式原本的设计目标是简便多轮对话,但我们通过之前的学习可以知道,它对于不会涉及任何对话的单轮任务也同样有用。

环境配置

参考第二章的 环境配置小节内容即可。

身份与上下文构建

接下来,我们将定义两个辅助函数。
第一个方法已经陪伴了您一整个教程,即 getCompletion ,其适用于单轮对话。我们将 Prompt 放入某种类似用户消息的对话框中。
另一个称为 getCompletionFromMessage ,传入一个消息列表。这些消息可以来自大量不同的角色 (roles) ,我们会描述一下这些角色。

第一条消息中,我们以系统身份发送系统消息 (system message) ,它提供了一个总体的指示。系统消息则有助于设置助手的行为和角色,并作为对话的高级指示。你可以想象它在助手的耳边低语,引导它的回应,而用户不会注意到系统消息。因此,作为用户,如果你曾经使用过 ChatGPT,您可能从来不知道 ChatGPT 的系统消息是什么,这是有意为之的。系统消息的好处是为开发者提供了一种方法,在不让请求本身成为对话的一部分的情况下,引导助手并指导其回应。
在 ChatGPT 网页界面中,您的消息称为用户消息,而 ChatGPT 的消息称为助手消息。但在构建聊天机器人时,在发送了系统消息之后,您的角色可以仅作为用户 (user) ;也可以在用户和助手 (assistant) 之间交替,从而提供对话上下文。

现在让我们尝试在对话中使用这些消息。我们将使用上面的函数来获取从这些消息中得到的回答,同时,使用更高的温度 (temperature)(越高生成的越多样,更多内容见第七章)。
系统消息说,你是一个说话像莎士比亚的助手。这是我们向助手描述它应该如何表现的方式。然后,第一个用户消息是给我讲个笑话。接下来以助手身份给出回复是,为什么鸡会过马路? 最后发送用户消息是我不知道。

        List<ChatMessage> chatMessages = new ArrayList<>();ChatMessage  message = new ChatMessage();message.setRole("system");message.setContent("你是一个像莎士比亚一样说话的助手。");chatMessages.add(message);ChatMessage  message1 = new ChatMessage();message1.setRole("user");message1.setContent("给我讲个笑话");chatMessages.add(message1);ChatMessage  message2 = new ChatMessage();message2.setRole("assistant");message2.setContent("鸡为什么过马路");chatMessages.add(message2);ChatMessage  message3 = new ChatMessage();message3.setRole("user");message3.setContent("我不知道");chatMessages.add(message3);String result = this.getCompletionFromMessage(chatMessages, 1.5d);log.info("iterative1:\n{}", result);
因为它想躲过汤锅! 这个笑话有些“愚蠢”,与幽默玩了一个常见的危险情境,引起一些意外,以尽力让人们笑一笑。这种类型的笑话强调了荒诞和意想不到的情节。

让我们看另一个例子。助手的消息是你是一个友好的聊天机器人,第一个用户消息是嗨,我叫Isa。我们想要得到第一个用户消息。

        List<ChatMessage> chatMessages = new ArrayList<>();ChatMessage  message = new ChatMessage();message.setRole("system");message.setContent("你是个友好的聊天机器人。");chatMessages.add(message);ChatMessage  message1 = new ChatMessage();message1.setRole("user");message1.setContent("Hi, 我是Isa。");chatMessages.add(message1);String result = this.getCompletionFromMessage(chatMessages, 1.5d);log.info("iterative2:\n{}", result);
嗨Isa,很高兴认识你!有什么我可以帮助你的吗?

让我们再试一个例子。系统消息是,你是一个友好的聊天机器人,第一个用户消息是,是的,你能提醒我我的名字是什么吗?

        List<ChatMessage> chatMessages = new ArrayList<>();ChatMessage  message = new ChatMessage();message.setRole("system");message.setContent("你是个友好的聊天机器人。");chatMessages.add(message);ChatMessage  message1 = new ChatMessage();message1.setRole("user");message1.setContent("好,你能提醒我,我的名字是什么吗?");chatMessages.add(message1);String result = this.getCompletionFromMessage(chatMessages, 1.5d);log.info("iterative3:\n{}", result);
当然可以!请告诉我你的名字,我将会一直记得。

如上所见,模型实际上并不知道我的名字。

因此,每次与语言模型的交互都互相独立,这意味着我们必须提供所有相关的消息,以便模型在当前对话中进行引用。如果想让模型引用或 “记住” 对话的早期部分,则必须在模型的输入中提供早期的交流。我们将其称为上下文 (context) 。尝试以下示例。

        List<ChatMessage> chatMessages = new ArrayList<>();ChatMessage  message = new ChatMessage();message.setRole("system");message.setContent("你是个友好的聊天机器人。");chatMessages.add(message);ChatMessage  message1 = new ChatMessage();message1.setRole("user");message1.setContent("Hi, 我是Isa");chatMessages.add(message1);ChatMessage  message2 = new ChatMessage();message2.setRole("assistant");message2.setContent("Hi Isa! 很高兴认识你。今天有什么可以帮到你的吗?");chatMessages.add(message2);ChatMessage  message3 = new ChatMessage();message3.setRole("user");message3.setContent("是的,你可以提醒我, 我的名字是什么?");chatMessages.add(message3);String result = this.getCompletionFromMessage(chatMessages, 1.5d);log.info("iterative4:\n{}", result);
当然,Isa,你的名字是Isa。请问有什么具体的提醒需要我帮助你吗?

现在我们已经给模型提供了上下文,也就是之前的对话中提到的我的名字,然后我们会问同样的问题,也就是我的名字是什么。因为模型有了需要的全部上下文,所以它能够做出回应,就像我们在输入的消息列表中看到的一样。

订餐机器人

现在,我们构建一个 “订餐机器人”,我们需要它自动收集用户信息,接受比萨饼店的订单。

下面这个函数将收集我们的用户消息,以便我们可以避免像刚才一样手动输入。这个函数将从我们下面构建的用户界面中收集 Prompt ,然后将其附加到一个名为上下文( context )的列表中,并在每次调用模型时使用该上下文。
模型的响应也会添加到上下文中,所以用户消息和模型消息都被添加到上下文中,上下文逐渐变长。这样,模型就有了需要的信息来确定下一步要做什么。

现在,我们将设置并运行这个 UI 来显示订单机器人。初始的上下文包含了包含菜单的系统消息,在每次调用时都会使用。此后随着对话进行,上下文也会不断增长。

Java快速转换到大模型开发:
配套课程的所有代码已经发布在:https://github.com/Starcloud-Cloud/java-langchain
课程合作请留言

相关文章:

【Java-LangChain:面向开发者的提示工程-8】聊天机器人

第八章 聊天机器人 使用一个大型语言模型的一个令人兴奋的事情是&#xff0c;我们可以用它来构建一个定制的聊天机器人 (Chatbot) &#xff0c;只需要很少的工作量。在这一节中&#xff0c;我们将探索如何利用聊天的方式&#xff0c;与个性化&#xff08;或专门针对特定任务或…...

利用t.ppft.interval分别计算T分布置信区间[实例]

scipy.stats.t.interval用于计算t分布的置信区间&#xff0c;即给定置信水平时&#xff0c;计算对应的置信区间的下限和上限。 scipy.stats.t.ppf用于计算t分布的百分位点&#xff0c;即给定百分位数&#xff08;概率&#xff09;时&#xff0c;该函数返回给定百分位数对应的t…...

软件工程第三周

可行性研究 续 表达工作量的方式 LOC估算&#xff1a;Line of Code 估算公式S(Sopt4SmSpess)/6 FP&#xff1a;功能点 1. LOC (Line of Code) 估算 定义&#xff1a;LOC是指一个软件项目中的代码行数。 2. FP (Function Points) 估算 定义&#xff1a;FP是基于软件的功能性和…...

动态链接那些事

1、为什么要动态链接 1.1 空间浪费 对于静态链接来说&#xff0c;在程序运行之前&#xff0c;会将程序所需的所有模块编译、链接成一个可执行文件。这种情况下&#xff0c;如果 Program1 和 Program2 都需要用到 Lib.o 模块&#xff0c;那么&#xff0c;内存中和磁盘中实际上就…...

力扣:118. 杨辉三角(Python3)

题目&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官…...

QGIS文章二——DEM高程裁剪和3D地形图

经常看到别人基于高程文件制作出精美的3D地图&#xff0c;笔者按照互联网几种制作方式进行尝试后&#xff0c;写的DEM高程裁剪和3D地形图教程&#xff0c;或许其中有一些错误的&#xff0c;也请指出。 本文基于海南省的shp文件和海南省DEM高程文件&#xff0c;制作海口地区的3D…...

【kubernetes】kubernetes中的StatefulSet使用

TOC 1 为什么需要StatefulSet 常规的应用通常使用Deployment&#xff0c;如果需要在所有机器上部署则使用DaemonSet&#xff0c;但是有这样一类应用&#xff0c;它们在运行时需要存储一些数据&#xff0c;并且当Pod在其它节点上重建时也希望这些数据能够在重建后的Pod上获取&…...

创建文件夹

/storage/emulated/0/代码文件/ 没有就创建 文件名命名方法&#xff1a;编号. 库 时间戳 使用Python的os模块来检查目录是否存在&#xff0c;并在不存在时创建它。下面是一个示例代码&#xff0c;演示了如何检查指定路径下的目录是否存在&#xff0c;若不存在则创建&#xf…...

点击router-link时候会发生什么?

当你点击链接或按钮时&#xff0c;将会导航到 User 组件&#xff0c;就会显示相应的用户 ID。 这里说一下执行流程&#xff0c;当点击一个 router-link 时&#xff0c;Vue Router会执行以下流程&#xff1a; 1&#xff09;点击事件触发: 当你点击 router-link 组件时&#xf…...

【Spring】@Bean方法中存在继承如何分析

文章目录 1. 提问&#xff1a;如果让您分析Spring MVC的原理&#xff0c;您如何开始分析呢2. 如何破局3. 资料参考 本文主要介绍&#xff1a;如何分析 Bean方法存在继承 或 Bean方法中存在调用子类方法。 1. 提问&#xff1a;如果让您分析Spring MVC的原理&#xff0c;您如何…...

【Vim 插件管理器】Vim-plug和Vim-vbundle的区别

- vundle是一款老款的插件管理工具 - vim-plug相对较新&#xff0c;特点是支持异步加载&#xff0c;相比vundle而言 Vim-plug 是一个自由、开源、速度非常快的、极简的 vim 插件管理器。它可以并行地安装或更新插件。你还可以回滚更新。它创建浅层克隆shallow clone最小化磁盘…...

电子计算机核心发展(继电器-真空管-晶体管)

目录 继电器 最大的机电计算机之一——哈弗Mark1号&#xff0c;IBM1944年 背景 组成 性能 核心——继电器 简介 缺点 速度 齿轮磨损 Bug的由来 真空管诞生 组成 控制开关电流 继电器对比 磨损 速度 缺点 影响 代表 第一个可编程计算机 第一个真正通用&am…...

SDI-12协议与STM32 进行uart通信

场景是用stm32与一款温湿度传感器通信&#xff0c;不过是基于SDI-12协议&#xff0c;SDI-12时序和UART类似&#xff0c;故采用UART传输&#xff0c;原理图如下 其中DIR_OUT_SDI是一个IO引脚&#xff0c;控制UART_TX_SDI是否使能&#xff0c;U10是三态门IC&#xff0c;即拉低DIR…...

JS中的强制类型转换

JavaScript 中有多种强制类型转换的方式&#xff0c;可以将一个数据类型转换为另一种数据类型。这可以通过一些内置函数或操作符来实现。 显式类型转换&#xff08;强制类型转换&#xff09;&#xff1a; 显式类型转换是通过特定的函数或操作符来明确指定要进行的类型转换。以下…...

WebSocket实战之四WSS配置

一、前言 上一篇文章WebSocket实战之三遇上PAC &#xff0c;碰到的问题只能上安全的WebSocket&#xff08;WSS&#xff09;才能解决&#xff0c;配置证书还是挺麻烦的&#xff0c;主要是每年都需要重新更新证书&#xff0c;我配置过的证书最长有效期也只有两年&#xff0c;搞不…...

veImageX 演进之路:Web 图片加载提速50%

背景说明 火山引擎veImageX演进之路主要介绍了veImageX在字节内部从2012年随着字节成长过程中逐步演进的过程&#xff0c;演进中包括V1、V2、V3版本并最终面向行业输出&#xff1b;整个演进过程中包括服务端、客户端、网络库、业务场景与优化等多个角度介绍在图像处理压缩、省成…...

WebSocket实战之五JSR356

一、前言 前几篇WebSocket例子服务端我是用NodeJS实现,这一篇我们用Java来搭建一个WebSocket服务端&#xff0c;从2011年WebSocket协议RFC6455发布后&#xff0c;大多数浏览器都实现了WebSocket协议客户端的API,而对于服务端Java也定义了一个规范JSR356,即Java API for WebSoc…...

flask-sqlalchemy结合Blueprint遇到循环引入问题的解决方案

想要用flask_sqlalchemy结合Blueprint分模块写一下SQL的增删改查接口&#xff0c;结果发现有循环引入问题。 一开始&#xff0c;我在app.py中使用db SQLAlchemy(app)创建数据库对象&#xff1b;并且使用app.register_blueprint(db_bp, url_prefix/db)注册蓝图。 这使得我的依…...

05_对象性能模式

对象性能模式 面向对象很好地解决了“抽象”的问题,但是必不可免地要付出定的代价。对于通常情况来讲&#xff0c;面向对象的成本大都可以忽略计。但是某些情况&#xff0c;面向对象所带来的成本必须谨慎处理。 典型模型&#xff1a; SingletonFlyweight Singleton 单件模式…...

快速选择排序

"你经过我每个灿烂时刻&#xff0c;我才真正学会如你般自由" 前些天有些无聊&#xff0c;想试试自己写的快排能否过leetcode上的排序算法题。结果是&#xff0c;不用截图可想而知&#xff0c;肯定是没过的&#xff0c;否则也不会有这篇文章的产出。 这份快排算法代码…...

国庆中秋特辑(六)大学生常见30道宝藏编程面试题

以下是 30 道大学生 Java 面试常见编程面试题和答案&#xff0c;包含完整代码&#xff1a; 什么是 Java 中的 main 方法&#xff1f; 答&#xff1a;main 方法是 Java 程序的入口点。它是一个特殊的方法&#xff0c;不需要被声明。当 Java 运行时系统执行一个 Java 程序时&…...

Centos7 安装mysql 8.0.34

Centos7 安装mysql 8.0.34 准备工作 centos7 服务器 xshell 安装教程 安装并配置 在安装MySQL之前&#xff0c;我们应该确保系统已经更新到最新的软件包和安全补丁。打开终端&#xff0c;输入以下命令来更新系统 yum update为了方便安装MySQL&#xff0c;我们需要下载并…...

如何在 Google Earth 中创建轨迹、路线并制作动画

如何创建航迹 https://kurviger.de/en Google 地球飞行教程(天桥动画) 选择合适的点 &#xff08;可调整视图快照&#xff09;点击录制&#xff0c;依次点击图标即可...

蓝桥杯每日一题2023.9.30

蓝桥杯大赛历届真题 - C&C 大学 B 组 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 对于此题&#xff0c;首先想到了dfs进行一一找寻&#xff0c;注意每次不要将重复的算进去&#xff0c;故我们每次循环可以记录一个开始的位置&#xff0c;下一次到这个位置时&#xff0c;…...

springboot和vue:十、vue2和vue3的差异+组件间的传值

首先用vue-cli创建一个vue2的项目。 vue2和vue3的差异 main.js的语法有所差别。 vue2是 import Vue from vue import App from ./App.vuenew Vue({render: h > h(App), }).$mount(#app)vue3是 import { createApp } from vue import App from ./App.vuecreateApp(App).…...

SQL:增、删、改、查 基本语句 Navicat建库(用法 + 例子)

文章目录 新建数据库新建表 增、删、改、查select 查找insert 添加delete 删除update 修改where 扩展 < > < > ! <> 比较运算符and or 逻辑运算符between...and... 介于..和..之间in 包含like 模糊查询is null 为空的 查询扩展order by 排序limit start coun…...

vue-cli搭建过程(HBuilder X搭建)

vue.js:前端主流框架&#xff08;对某一方面技术完整的封装&#xff0c;是一套完善的解决方案&#xff09; vue-cli搭建项目&#xff08;官方提供脚手架&#xff09; vue脚手架&#xff1a;是一套项目搭建的快捷方式&#xff0c;可以将项目中的依赖集成进来&#xff0c;生成统…...

MySQL索引:结构、语法、分类和优化

MySQL索引是数据库中非常关键的性能优化手段。它们提供了快速访问数据的方法&#xff0c;同时也可以极大地提高查询效率。本文将深入介绍MySQL索引的结构、语法、分类&#xff0c;以及如何使用Profile和EXPLAIN来优化查询性能&#xff0c;带有详细的实例演示。 索引结构 MySQ…...

Vue中添加旋转动画

// transform: scale(1.2) rotate(-180deg); 放大 旋转 // transform: rotate(-180deg); 旋转 <i class"el-icon-close"></i>i {font-size: 20px;line-height: 24px;transition: transform 0.2s linear;}i:hover {color: red;transform-origin: cen…...

基于SSM农产品商城系统

基于SSM农产品商城系统的设计与实现&#xff0c;前后端分离&#xff0c;文档 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 农产品列表 产品详情 个人中心 登陆界面 管…...

眼科医院网站设计怎么做/天津优化网络公司的建议

首先我们打开一个测试用的文档。 然后&#xff0c;如果我们需要隐藏某一列&#xff0c;则选中这一列。 在【开始】选项卡的“单元格”组中单击【格式】按钮 在打开的下拉菜单中选择【隐藏和取消隐藏】&#xff0c;根据下级菜单中的相关命令来进行行列的隐藏操作。 选择【隐藏行…...

重庆网站建设营销/站长统计app最新版本2023

本文要谈的IM通信协议指的是应用层通信“语言”&#xff0c;并非指传输层协议&#xff08;如TCP、UDP&#xff09;。IM通信协议的制定是IM开发中起点&#xff0c;也是贯穿设计、开发、运维始终的核心所在&#xff0c;通信协议设计的好坏&#xff0c;直接影响后绪环节的用户体验…...

做电影网站投资多少/鸿科经纬教网店运营推广

element-ui的菜单样式重构&#xff0c;需要了解结构&#xff0c;再做定制。 ul.myMenuName .el-menuli.el-submenudiv.el-submenu__title //-----------------1 级菜单ul.el-menu .el-menu--inlineli.el-submenudiv.el-submenu__titile //------------1-1级菜单ul.el-menu .el…...

政府网站官网/seo整站优化一年价格多少

实现的框图如下所示&#xff1a;考虑对32位数据处理核心器件就是一个乘法器。a是输入的32位数据&#xff0c;num是移位的5位数据b是乘法器的64位输出下面是实现各种移位的算法&#xff1a;1、逻辑左移&#xff1a;结果取D2、逻辑右移&#xff1a;num取反加1&#xff0c;结果取C…...

做cosplay网站教程/郑州网站seo外包

? “Python猫” &#xff0c;一个值得加星标的公众号剧照 | 《犬夜叉》“ 如果你的Linux服务器突然负载暴增&#xff0c;告警短信快发爆你的手机&#xff0c;如何在最短时间内找出Linux性能问题所在&#xff1f;来看Netflix性能工程团队的这篇博文&#xff0c;看它们通过十条命…...

广州网站建设高端/手机百度下载免费

2019独角兽企业重金招聘Python工程师标准>>> 1、问题 通过一个死循环将读取键盘对应的设备文件将触发键盘事件在屏幕上打印出来&#xff0c;按esc退出程序 代码是在unbuntu10.04编译执行通过的 2、input_event描述 在Linux内核中&#xff0c;input设备用input_dev结…...