基于LLM+场景识别+词槽实体抽取实现多轮问答

前言

随着人工智能技术的不断进步,大语言模型(LLM)已成为技术前沿的热点。它们不仅能够理解和生成文本,还能在多种应用场景中实现复杂的交互。本文将深入探讨一段结合了大语言模型能力、意图识别和词槽实体抽取的Python代码,这段代码展示了如何实现智能的多轮问答能力,为用户提供更加丰富和个性化的交互体验。

正文

完整代码

这段代码的核心在于集成了最新的大语言模型(LLM)能力,结合了意图识别和词槽实体抽取的技术,以实现智能的多轮问答。

import json
import re
import requests
from datetime import datetimeurl = 'https://api.openai.com/v1/chat/completions'# 替换为您自己的chatGPT API密钥
api_key = 'sk-xxxxxx'# 调试日志
debug = Falsedef check_values_not_empty(json_data):"""检查是否所有元素value都不为空"""# 遍历JSON数据中的每个元素for item in json_data:# 检查value字段是否为空字符串if item.get('value') == '':return False  # 如果发现空字符串,返回Falsereturn True  # 如果所有value字段都非空,返回Truedef format_title_value_for_logging(json_data):"""抽取参数名称和value值"""log_strings = []for item in json_data:title = item.get('title', 'Unknown Title')  # 获取title,如果不存在则使用'Unknown Title'value = item.get('value', 'N/A')  # 获取value,如果不存在则使用'N/A'log_string = f"Title: {title}, Value: {value}"log_strings.append(log_string)return '\n'.join(log_strings)def extract_json_from_string(input_string):"""JSON抽取函数返回包含JSON对象的列表"""try:# 正则表达式假设JSON对象由花括号括起来matches = re.findall(r'\{.*?\}', input_string, re.DOTALL)# 验证找到的每个匹配项是否为有效的JSONvalid_jsons = []for match in matches:try:json_obj = json.loads(match)valid_jsons.append(json_obj)except json.JSONDecodeError:continue  # 如果不是有效的JSON,跳过该匹配项return valid_jsonsexcept Exception as e:print(f"Error occurred: {e}")return []def send_message(message, user_input):"""请求LLM函数"""print('--------------------------------------------------------------------')if debug:print('用户输入:', message)else:print('用户输入:', user_input)print('----------------------------------')headers = {"Authorization": f"Bearer {api_key}","Content-Type": "application/json",}data = {"model": "gpt-3.5-turbo","messages": [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": f"{message}"}]}response = requests.post(url, headers=headers, json=data, verify=False)if response.status_code == 200:answer = response.json()["choices"][0]["message"]['content']print('LLM输出:', answer)print('--------------------------------------------------------------------')return answerelse:print(f"Error: {response.status_code}")return None# 问天气
# 参数:
# 1. 时间time(口语:今天明天、日期:10号、范围:未来一周)
# 2. 地点location(国家省市区)
# todo "transform": "时间格式转换工具?是自己做一个还是用大模型。建议自己开发一个",
dict_weather = [{"title": "时间","desc": "口语表述:昨天、今天、明天;具体日期:10号、1月1号、2月3日;范围:未来一周、最近十四天","transform": "时间统一转换格式,如果是时间点:yyyy-MM-dd;如果是时间段:yyyy-MM-dd#yyyy-MM-dd","util": "","value": "","required": True},{"title": "地点","desc": "口语表述:建邺区、南京、河北省、江苏南通、上海虹桥、北京朝阳区","transform": "地点统一转换格式为省市区(如果有区)或省市,如南京市建邺区、南京市,如果提取不到市只有省份则不填写value","util": "","value": "","required": True}
]prompt_weather_info_update = """
JSON每个元素代表一个参数信息,我先给你提供一些基本介绍:
'''
title字段是参数名称,如果需要让用户填写该参数时你应该告诉用户你需要的参数名称
desc字段是参数描述,可以做为title字段的补充,更好的引导用户补充参数
transform字段是填写value字段值的格式要求说明
required字段为true表示该元素的value是必填参数,如果value为空则必须让用户补充该参数信息,如果required字段为false表示该参数不是必须补充的字段
'''需求:
#01 根据用户输入信息提取有用的信息更新到JSON中的value字段并返回更新后的JSON
#02 仅更新value字段,其他字段都原样返回
#03 如果没有可更新的value则原样返回
#04 当前时间为{}参考示例:
'''
JSON: [{{"title": "时间","desc": "口语表述:昨天、今天、明天;具体日期:10号、1月1号、2月3日;范围:未来一周、最近十四天","transform": "时间统一转换格式,如果是时间点:yyyy-MM-dd;如果是时间段:yyyy-MM-dd#yyyy-MM-dd","util": "","value": "","required": true}},{{"title": "地点","desc": "口语表述:建邺区、南京、河北省、江苏南通、上海虹桥、北京朝阳区","transform": "地点统一转换格式为省市区(如果有区)或省市,如南京市建邺区、南京市,如果提取不到市只有省份则不填写value","util": "","value": "","required": true}}
]
问:今天南京天气怎么样?
答:[{{"title": "时间","desc": "口语表述:昨天、今天、明天;具体日期:10号、1月1号、2月3日;范围:未来一周、最近十四天","transform": "时间统一转换格式,如果是时间点:yyyy-MM-dd;如果是时间段:yyyy-MM-dd#yyyy-MM-dd","util": "","value": "{}","required": true}},{{"title": "地点","desc": "口语表述:建邺区、南京、河北省、江苏南通、上海虹桥、北京朝阳区","transform": "地点统一转换格式为省市区(如果有区)或省市,如南京市建邺区、南京市,如果提取不到市只有省份则不填写value","util": "","value": "南京","required": true}}
]
'''JSON:{}
问:{}
答:
"""prompt_weather_query_user = """
JSON每个元素代表一个参数信息,我先给你提供一些基本介绍:
'''
title字段是参数名称,如果需要让用户填写该参数时你应该告诉用户你需要的参数名称
desc字段是参数描述,可以做为title字段的补充,更好的引导用户补充参数
required字段为true表示该元素的value是必填参数,如果value为空则必须让用户补充该参数信息,如果required字段为false表示该参数不是必须补充的字段
'''需求:
#01 如果有多个未填写value的参数则可以一起向用户提问
#02 value已经填写的参数不用再次提问参考示例:
'''
问:[{{"title": "时间","desc": "口语表述:昨天、今天、明天;具体日期:10号、1月1号、2月3日;范围:未来一周、最近十四天","transform": "时间统一转换格式,如果是时间点:yyyy-MM-dd;如果是时间段:yyyy-MM-dd#yyyy-MM-dd","util": "","value": "2022-01-01","required": true}},{{"title": "地点","desc": "口语表述:建邺区、南京、河北省、江苏南通、上海虹桥、北京朝阳区","transform": "地点统一转换格式为省市区(如果有区)或省市,如南京市建邺区、南京市,如果提取不到市只有省份则不填写value","util": "","value": "","required": true}}
]
答:请问你想查询天气的地点是什么?
'''问:{}
答:
"""# 公积金咨询
# 参数:
# 1. 事件(买房、租房、退休)
# 2. 购买房屋类型(买房事件时需要 经济适用房、新房、二手房)
dict_consult = {"event": "","purchase_type": ""
}prompt_global_purpose = """
有下面多种场景,需要你根据用户输入进行判断
1. 问天气
2. 公积金咨询
3. 其他场景参考示例:
'''
问:今天天气如何
答:问天气
'''问:{}
答:
"""global_purpose = ''def multi_question(user_input):global global_purposeglobal dict_weathercurrent_purpose = send_message(prompt_global_purpose.format(user_input), user_input)if current_purpose != '其他场景':global_purpose = current_purposeif global_purpose == '问天气':# 先检查本次用户输入是否有信息补充,保存补充后的结果   编写程序进行字符串value值diff对比,判断是否有更新current_time = datetime.now().strftime("%Y-%m-%d")new_info_json_raw = send_message(prompt_weather_info_update.format(current_time, current_time, json.dumps(dict_weather, ensure_ascii=False), user_input), user_input)dict_weather = extract_json_from_string(new_info_json_raw)# 判断参数是否已经全部补全if check_values_not_empty(dict_weather):print('问天气 ------ 参数已完整,详细参数如下')print(format_title_value_for_logging(dict_weather))print('正在请求天气查询API,请稍后……')else:str = json.dumps(dict_weather, ensure_ascii=False)send_message(prompt_weather_query_user.format(str), user_input)elif global_purpose == '公积金咨询':passelse:passpassdef user_input():while True:question = input("请输入您的问题:")multi_question(question)# test
# multi_question("明天天气怎么样呢")
# multi_question("苏州天气怎么样呢")
# multi_question("苏州明天天气怎么样呢")user_input()
代码解析

整合大语言模型(LLM):代码通过与一个语言模型API的交互,利用了大语言模型的强大文本生成和理解能力。这使得脚本能够处理复杂的用户查询,并生成合理的响应。

意图识别:通过分析用户的输入,脚本可以识别用户的意图(例如查询天气或获取公积金咨询),这是通过向LLM发送特定的提示(prompt)实现的。

词槽实体抽取:代码能够从用户输入中提取关键信息(如时间和地点),并将这些信息填充到预定义的JSON结构中。这是通过正则表达式和JSON操作实现的。

多轮交互:脚本支持多轮交互,能够根据用户输入的不同,动态地提问和响应,为用户提供连贯且自然的对话体验。

代码的实用性

这个脚本不仅展示了如何在Python中处理复杂的数据结构和执行HTTP请求,还展示了大语言模型在实际应用中的巨大潜力。它为开发者提供了一个实用的框架,用于构建可以理解和响应人类语言的智能应用程序。LLM+场景识别+词槽实体抽取,实现人机交互多轮会话,遥遥领先~

结尾

我们可以看到大语言模型在理解和生成自然语言方面的巨大潜力。结合意图识别和词槽实体抽取,它能够实现复杂且自然的多轮对话。这种技术的应用范围非常广泛,从简单的信息查询到复杂的交互式任务都能得到有效的支持。

希望这篇文章能够启发你探索大语言模型和智能问答系统的更多可能性。如果你觉得这篇文章有用,别忘了点赞和收藏!作者gallonyin,持续关注AI自动化。

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

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

相关文章

链表OJ--上

文章目录 前言一、反转链表二、移除链表元素三、链表中倒数第K个结点四、相交链表五、链表的中间结点 前言 一、反转链表 力扣206:反转链表- - -点击此处传送 思路图: 方法一:改变指向 方法二: 代码: //方法一 /…

十一、h.264编码

前言 测试环境: ffmpeg的4.3.2自行编译版本windows环境qt5.12 使用H.264编码对YUV视频进行压缩 ffmpeg -s 640x480 -pix_fmt yuv420p -i in.yuv -c:v libx264 out.h264 -c:v libx264是指定使用libx264作为编码器完整代码: H264EncodeThread.h #ifnd…

用HALCON标定助手对相机进行标定

任务要求: 已知相机镜头焦距f为8mm,相机单个CCD像素在水平和竖直两个方向上的尺寸均为3.75微米,相机为普通透光镜头和面阵相机,对相机进行标定,测量相机的内外参数。 操作步骤: 1. 在HALCON中运行gen_ca…

C#使用whisper.net实现语音识别(语音转文本)

目录 介绍 效果 输出信息 项目 代码 下载 介绍 github地址:https://github.com/sandrohanea/whisper.net Whisper.net. Speech to text made simple using Whisper Models 模型下载地址:https://huggingface.co/sandrohanea/whisper.net/tree…

Nginx高级

Nginx高级 第一部分:扩容 通过扩容提升整体吞吐量 1.单机垂直扩容:硬件资源增加 云服务资源增加 整机:IBM、浪潮、DELL、HP等 CPU/主板:更新到主流 网卡:10G/40G网卡 磁盘:SAS(SCSI) HDD(机械…

如何使用ArcGIS Pro进行坐标转换

不同来源的数据坐标系可能是不同的,为了统一使用这些数据就需要进行坐标转换,ArcGIS Pro作为专业的GIS软件,坐标转换功能肯定也是包含的,这里为大家介绍一下ArcGIS Pro如何进行坐标转换,希望能对你有所帮助。 数据来源…

【Exception】npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY

Talk is cheap, show me the code. 环境 | Environment kversionOSwindows 11nodev18.14.2npm9.5.0 报错日志 | Error log >npm create vitelatest Need to install the following packages:create-vite5.0.0 Ok to proceed? (y) y npm ERR! code UNABLE_TO_GET_ISSUER_…

2023亚太杯数学建模B题思路+模型+代码+论文

2023亚太地区数学建模A题思路:开赛后第一时间更新,获取见文末 名片 2023亚太地区数学建模B题思路:开赛后第一时间更新,获取见文末 名片 2023亚太地区数学建模C题思路:开赛后第一时间更新,获取见文末 名片…

idea修改行号颜色

前言 i当idea用了深色主题后,发现行号根本看不清,或者很模糊 例如下面这样 修改行号颜色 在IntelliJ IDEA中,你可以根据自己的喜好和需求定制行号的颜色。下面是修改行号颜色的步骤: 打开 IntelliJ IDEA。 转到 “File”&…

ChatGPT规模化服务的经验与教训

2022年11月30日,OpenAI发布ChatGPT,以很多人未曾预料的速度迅速走红。与此同时,由于短时间内用户量的暴涨,导致服务器过载,迫使OpenAI停止新用户的注册。 ChatGPT发布这一年,同样的情景发生了好几次。在最近…

opencv-图像金字塔

图像金字塔是一种图像处理技术,它通过不断降低图像的分辨率,形成一系列图像。金字塔分为两种类型:高斯金字塔和拉普拉斯金字塔。 高斯金字塔(Gaussian Pyramid): 高斯金字塔是通过使用高斯滤波和降采样&a…

专业远程控制如何塑造安全体系?向日葵“全流程安全闭环”解析

安全是远程控制的重中之重,作为国民级远程控制品牌,向日葵远程控制就极为注重安全远控服务的塑造。近期向日葵发布了以安全和核心的新版“向日葵15”以及同步发布《贝锐向日葵远控安全标准白皮书》(下简称《白皮书》),…

使用微信小程序openMapApp接口,报错问题解决openMapApp:fail invaild coord

使用微信小程序的 openMapApp 接口时遇到了坐标无效的错误 (openMapApp:fail invalid coord)。这个错误通常是由于提供的地理坐标不符合预期的格式或范围而引起的: 坐标格式: 确保提供的坐标符合正确的格式。常见的格式是 "纬度,经度"&#xf…

【11月比赛合集】5场可报名的「创新应用」、「数据分析」和「程序设计」大奖赛,任君挑选!

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…)比赛。本账号会推送最新的比赛消息,欢迎关注! 以下信息仅供参考,以比赛官网为准 目录 创新应用赛(1场比赛)数据分析赛&#…

逸学java【初级菜鸟篇】9.3 Stream流

hi,我是逸尘,一起学java吧 得益于Lambda所带来的函数式编程,引入了一个全新的Stream流概念(就是都基本使用lambda的形式)。 流处理 我们首先理解什么是流处理,它类似于sql语句,可以执行非常复…

【开源】基于Vue和SpringBoot的智能教学资源库系统

项目编号: S 050 ,文末获取源码。 \color{red}{项目编号:S050,文末获取源码。} 项目编号:S050,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课…

原理Redis-SkipList

SkipList ZipList和QuickList的共同特点是节省内存。在遍历元素时,只能从头到尾或从尾到头,所以在查找头尾元素性能还是不错的,但是中间元素查询的性能就会差。 **SkipList(跳表)**首先是链表,但与传统链表…

【算法】链表-20231123

这里写目录标题 一、19. 删除链表的倒数第 N 个结点二、21. 合并两个有序链表三、24. 两两交换链表中的节点 一、19. 删除链表的倒数第 N 个结点 提示 中等 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 输入:head [1,…

第十二章 : Spring Boot 日志框架详解

第十二章 : Spring Boot 日志框架详解 前言 本章知识重点:介绍了日志诞生背景,4种日志框架:Logback、Log4j、Log4j2和Slf4j的优劣势分析,以及重点介绍了log4j2的应用示例以及配置,以及日志框架应用中遇到常见的问题以及如何处理。 背景 Java日志框架的发展历程可以追…

在PyCharm中正确设置Python项目

大家好,在Mac和Linux都支持Python,但许多开发者发现正确设置Python项目很困难。本文汇总了多平台中运行Python的方法,提高编程的效率,如下所示: 使用命令行运行Python。 在PyCharm(免费社区版)…