python实战(五)——构建自己的大模型助手

一、任务目标

        本文将利用大语言模型强大的对话能力,搭建一个PC端问答助手。具体来说,我们将使用API来调用我们想要的大模型,并结合Prompt让大模型根据任务类型生成对应的输出。为了更方便地调用大模型助手,我们将结合python第三方库中的语音识别库进行开发,实现调用麦克风语音输入和音箱语音响应的人机交互。

二、简易版问答助手

        得益于目前高度集成的工具库,我们只需要少量的代码便可以实现语音的交互以及大模型的调用,这里直接给出代码:

import pyttsx3
import openai
import random
import speech_recognition as sr# 使用默认麦克风
recognizer = sr.Recognizer()
microphone = sr.Microphone()
# 初始化tts引擎
engine = pyttsx3.init()
# 设置发音人的语音
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[0].id)
# 设置发音人的语速
engine.setProperty('rate', 200)# api
openai.api_key = "your api key"
openai.api_base = "your api base"# 持续识别语音,直到用户输入退出指令
while True:with microphone as source:print("请开始说话...")audio = recognizer.listen(source)try:# 将音频转换为文字print('语音识别中...')text = recognizer.recognize_google(audio, language='zh-CN')print(f"你说了:{text}")# 要转换的文本# 这里使用一个简单的触发词if '嘿小娜' == text:responses = ['您好,有什么可以帮您的吗?', '在呢!有什么吩咐?', '需要我做些什么?']response = random.choice(responses)# 将文本转换为语音engine.say(response)# 播放声音engine.runAndWait()# 理解用户输入意图elif '嘿小娜' in text and '再见' not in text:chat_completion = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=[{"role": "system","content": "你是一个私人的电脑语音助手,名字叫小娜,你将以尊敬的语气回答你主人提出的问题。请注意,输入给你的文本是麦克风语音转化成的汉语文本,没有标点符号,你需要根据语境进行标点符号位置的判断从而理解语义,并回答相应的问题。需要注意的是,你回答的文字应当在50个汉字以内。"},{"role": "user", "content": text}])response = chat_completion.choices[0].message.content# 将文本转换为语音engine.say(response)# 播放声音engine.runAndWait()if '嘿小娜' in text and '再见' in text:engine.say('下次见!')# 播放声音engine.runAndWait()breakexcept sr.UnknownValueError:print("未识别出触发词")except sr.RequestError as e:print(f"识别服务出错; {e}")

        这里主要有以下几个需要注意的地方:

  • 语音识别模块使用了比较基础的python库,识别并转文字之后的文本不包含标点符号,因此需要在prompt中特别说明,当然这也是一个明显可以优化的地方(换个更强大的语音识别库)。
  • 同样,语音响应模块也较为简单,助手发出的声音较为正式(播音腔),发音也算流畅,但与真人对话场景还是存在比较大的差异,这里可以使用诸如chattts之类的强大的文本转语音库,实现极其逼真的语音响应(例如输入一段真人语音,chattts可以学习这个人的声纹信息,从而发出几乎一模一样的声音,着实令人震惊!)。
  • 大模型输出模块并没有采用流式输出,实际上,流式输出可以让语音响应更加及时,不需要等大语言模型把回复完全生成了之后再进行朗读(当然,不选择流式输出的另一个考量就是流式输出较难对大模型输出的文本进行后处理)。

三、结合电脑交互的个人助手

        这里还是以上面的代码为基础,我们给问答助手加入一些控制浏览器的能力,同时通过prompt让大模型生成我们期望的输出格式,便于后续调用对应的控制能力

1、prompt输出优化

        下面的代码主体结构和前述内容一致,但为了更充分的利用大模型的理解能力和交互能力,我们通过修改prompt让大模型输出半格式化的响应,进而对半格式化的响应进行解析,并调用对应交互功能。

import pyttsx3
import openai
import speech_recognition as sr
# 导入自建模块
from automation.open_chrome import open_website
from automation.web_address import web_dic
from automation.open_search import open_search# 使用默认麦克风
recognizer = sr.Recognizer()
microphone = sr.Microphone()
# 初始化tts引擎
engine = pyttsx3.init()
# 设置发音人的语音
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[0].id)
engine.setProperty('rate', 200)
openai.api_key = "Your api key"
openai.api_base = "Your api base"while True:with microphone as source:print("请开始说话...")audio = recognizer.listen(source)try:# 将音频转换为文字print('语音识别中...')text = recognizer.recognize_google(audio, language='zh-CN')print(f"你说了:{text}")if '小娜' not in text:continue# 要转换的文本prompt = (f"你是一个强大的私人电脑管家,名字叫小娜。你可以使用谷歌浏览器打开用户指定的网站(B站、百度、谷歌中的其中一个),也可以使用谷歌浏览器搜索用户指定的内容。"f"用户给你的指令将以三个井号符合进行分隔,你需要根据用户的需求返回对应的回答格式。如果用户需要你打开指定的网站,你需要返回‘打开网站|网站名称’的答复格式;"f"如果用户需要你帮助他搜索指定内容,你需要返回‘搜索|待搜索内容’的答复格式;如果用户输入的指令既不是打开指定网站也不是搜索指定内容,则你需要以尊敬的态度回复用户的对话,"f"返回答复的格式为‘问答|你的回复’,需要注意的是,你回复的文字应当在50个汉字以内。以下是用户的指令:###{text}###,请务必返回指定格式的答复。"f"另外,如果用户与你说再见,则你只需要需要返回‘退出程序|你的告别语’即可。")chat_completion = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=[{"role": "system", "content": prompt}])response = chat_completion.choices[0].message.contentprint(response)response = response.strip('(')response = response.strip(')')response = response.strip('(')response = response.strip(')')response = response.strip("'")print(response)order_type, answer = response.split('|')[0], response.split('|')[1]if '问答' in order_type:# 将文本转换为语音engine.say(answer)# 播放声音engine.runAndWait()elif '打开网站' in order_type:if answer not in web_dic:answer = '谷歌'address = web_dic[answer]open_website(address)elif '搜索' in order_type:browser = 'https://www.google.com'open_search(browser, answer)elif '退出程序' in order_type:# 将文本转换为语音engine.say(answer)# 播放声音engine.runAndWait()breakexcept sr.UnknownValueError:print("未识别出触发词")except sr.RequestError as e:print(f"识别服务出错; {e}")

        上述代码中的prompt为:

        f"你是一个强大的私人电脑管家,名字叫小娜。你可以使用谷歌浏览器打开用户指定的网站(B站、百度、谷歌中的其中一个),也可以使用谷歌浏览器搜索用户指定的内容。"
        f"用户给你的指令将以三个井号符合进行分隔,你需要根据用户的需求返回对应的回答格式。如果用户需要你打开指定的网站,你需要返回‘打开网站|网站名称’的答复格式;"
        f"如果用户需要你帮助他搜索指定内容,你需要返回‘搜索|待搜索内容’的答复格式;如果用户输入的指令既不是打开指定网站也不是搜索指定内容,则你需要以尊敬的态度回复用户的对话,"
        f"返回答复的格式为‘问答|你的回复’,需要注意的是,你回复的文字应当在50个汉字以内。以下是用户的指令:###{text}###,请务必返回指定格式的答复。"
        f"另外,如果用户与你说再见,则你只需要需要返回‘退出程序|你的告别语’即可。"

        这里面,我们指定了四种响应类型——打开网站、搜索、常规问答以及退出程序。我们通过.split()方法即可对模型的响应进行分隔,如果是“打开网站”或者“搜索”则调用open_website或者open_search功能,而对于“退出程序”或者“常规问答”则无需任何操作,直接输出大模型的回答。此外,对于“打开网站”和“搜索”,我们让大模型总结和推断需要打开哪个网站,或者需要搜索什么问题,open_website和open_search直接输入大模型的响应结果。

2、控制浏览器

        这里我们实现了简单的控制代码,读者可自行优化。

(1)打开网站(automation/open_chrome.py)

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Optionsdef open_website(website_address):# 配置ChromeDriver的路径chrome_driver_path = ChromeDriverManager().install()# 创建Chrome选项对象chrome_options = Options()chrome_options.add_experimental_option("detach", True)# 创建Chrome浏览器的实例driver = webdriver.Chrome(service=Service(chrome_driver_path), options=chrome_options)# 将浏览器窗口最大化driver.maximize_window()# 打开指定的网站driver.get(website_address)

(2)搜索(automation/open_search.py)

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import timedef open_search(browser, query):# 配置ChromeDriver的路径chrome_driver_path = ChromeDriverManager().install()# 创建Chrome选项对象chrome_options = Options()chrome_options.add_experimental_option("detach", True)# 创建Chrome浏览器的实例driver = webdriver.Chrome(service=Service(chrome_driver_path), options=chrome_options)# 将浏览器窗口最大化driver.maximize_window()# 打开指定的网站driver.get(browser)# 等待页面加载time.sleep(2)# 找到搜索框元素search_box = driver.find_element(By.NAME, "q")# 在搜索框中输入搜索内容search_box.send_keys(query)# 模拟按下回车键进行搜索search_box.send_keys(Keys.RETURN)# 等待搜索结果加载time.sleep(2)

(3)网站地址(automation/web_address.py)

web_dic = {'B站':'https://www.bilibili.com/','百度':'https://www.baidu.com','谷歌':'https://www.google.com','微博':'https://www.weibo.com','github':'https://github.com/'
}

四、总结

        本文实现了PC端智能问答助手的构建,基于大模型的交互能力和一些简单的控制代码,即可打造出一个专属于你自己的电脑AI管家!

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

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

相关文章

FPGA技术优势

在当今数字化时代,现场可编程门阵列(FPGA)因其高灵活性和强大的处理能力而广泛应用于各种行业。FPGA允许用户在单个芯片上实现大量数字逻辑,以相对较高的速度并且无需依赖传统顺序程序。这种独特的能力使得FPGA能够在许多复杂应用中脱颖而出。 FPGA的基本特性 FPGA是一种…

Android OpenGL ES详解——裁剪Scissor

目录 一、概念 二、如何使用 1、开启裁剪测试 2、关闭裁剪测试 3、指定裁剪窗口(位置和大小) 4、裁剪应用举例 三、窗口、视⼝和裁剪区域三者区别 四、源码下载 一、概念 定义1: 裁剪是OpenGL中提⾼渲染的⼀种方式,只刷新…

江协科技STM32学习- P22 实验-ADC单通道/ADC多通道

🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝​…

PostgreSQL和MySQL在MVCC

PostgreSQL和MySQL在MVCC(多版本并发控制)机制上的不同主要体现在以下几个方面: MVCC实现方式 : PostgreSQL将数据记录的多个版本保存在数据库中,当这些版本不再需要时,垃圾收集器会回收这些记录。MySQL/…

【数据结构】树-二叉树-堆(下)

🍃 如果觉得本系列文章内容还不错,欢迎订阅🚩 🎊个人主页:小编的个人主页 🎀 🎉欢迎大家点赞👍收藏⭐文章 ✌️ 🤞 🤟 🤘 🤙 👈 &…

D365 FO开发参考

FO数据库表参考 InventTable in Main - Common Data Model - Common Data Model | Microsoft Learn FO编程Query参考 Query.addDataSource Method | Microsoft Learn FO核心Enums查询 BatchStatus Enum (Microsoft.Dynamics.Ax.Xpp) | Microsoft Learn FO Function 开发参…

前端笔面试查漏补缺

面试笔试的知识总结&#xff0c;查漏补缺 一、CSS样式隔离 CSS样式隔离用于确保组件或元素的样式不会与其他组件或元素的样式发生冲突。 1.scoped css -- <style scoped> 构建工具&#xff08;vue-loader&#xff09;会在编译阶段对css特殊处理&#xff0c;给当前组…

-XSS-

链接 https://github.com/do0dl3/xss-labs 搭建过程非常容易的 搭建好之后&#xff0c;就可以点击图片开始闯关了 第一关--JS弹窗函数alert() 显示payload的长度是4 level1.php?nametest level1.php?nametest1 发现只要改变name的值就显示什么在页面上 没有什么过滤的 …

【数据结构与算法】《Java 算法宝典:探秘从排序到回溯的奇妙世界》

目录 标题&#xff1a;《Java 算法宝典&#xff1a;探秘从排序到回溯的奇妙世界》一、排序算法1、冒泡排序2、选择排序3、插入排序4、快速排序5、归并排序 二、查找算法1、线性查找2、二分查找 三、递归算法四、动态规划五、图算法1. 深度优先搜索&#xff08;DFS&#xff09;2…

sqlserver、达梦、mysql的差异

差异项sqlserver达梦mysql单行注释---- 1、-- &#xff0c;--后面带个空格 2、# 包裹对象名称&#xff0c;如表、表字段等 [tableName] "tableName"tableName表字段自增IDENTITY(1, 1)IDENTITY(1, 1)AUTO_INCREMENT二进制数据类型IMAGEIMAGE、BLOBBLOB 存储一个汉字需…

transformControls THREE.Object3D.add: object not an instance of THREE.Object3D.

把scene.add(transformControls);改为scene.add(transformControls.getHelper());

python删除文件夹下面的所有文件示例

要删除指定路径下的文件夹和文件&#xff0c;可以使用 Python 的 shutil 模块。这将允许你递归地删除文件夹及其内容。以下是一个示例&#xff1a; import shutil from pathlib import Path# 指定要删除的目录路径 directory Path(path/to/your/directory)# 检查目录是否存在…

计算机视觉专栏(1)【LeNet】论文详解

Lenet 系列 论文精讲部分0.摘要1.引言2.CNN3.结果分析4.总结 论文精讲部分 本专栏旨在深入解析计算机视觉模型的论文及其发展背景&#xff0c;并通过代码部分的实际实验来加深理解。读者可以根据自己的需要参考其中的内容。其主体为原文&#xff0c;笔者理解内容会采用引用格式…

[ 问题解决篇 ] 解决windows虚拟机安装vmtools报错-winserver2012安装vmtools及安装KB2919355补丁 (附离线工具)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Window on ARM解锁所有的TTS语音包供python调用

Window on ARM解锁所有的TTS语音包供python调用 可用的语音包查看查看TTS可用的语音包解锁语音包设置升级系统打开注册表导出注册表修改注册表导入新的注册表可用的语音包查看 微软的Windows 10操作系统为设备上安装的每种语言提供了一套语音。但只有部分已安装的语音能在整个…

EPLAN创建宏并自定义部件库详细案例操作(三)

#通过导入EDZ格式部件库的样式,模仿制作一个自定义的部件库# 续 EPLAN创建宏并自定义部件库详细案例操作(二) 需要部件库文件(EDZ)格式,可以在此下载: https://download.csdn.net/download/weixin_44166380/89935582 五、创建部件库 本章节的部分操作忽略,具体可参见…

掌握 CTE 技巧,实现连续日期和月份的 SQL 报表统计

在 SQL 查询中&#xff0c;报表统计往往涉及到特定时间段内的数据汇总&#xff0c;如每日、每月的销售数据等。然而&#xff0c;面对缺少数据的日期或月份&#xff0c;传统 SQL 查询可能会直接跳过这些日期&#xff0c;使得输出的报表在视觉上并不连续。本文将展示如何利用 CTE…

APScheduler:强大的Python定时任务调度器

安装 使用pip安装APScheduler&#xff1a; pip install apscheduler基本概念 APScheduler有四种组件&#xff1a; Triggers&#xff1a;包含调度逻辑&#xff0c;每个作业有其专属触发器&#xff0c;决定下次运行时间。触发器无状态&#xff0c;仅依据初始配置工作。Job St…

电子电气架构 --- 车载芯片现状

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所有人的看法和评价都是暂时的&#xff0c;只有自己的经历是伴随一生的&#xff0c;几乎所有的担忧和畏惧…

我docker拉取mysql镜像时用的是latest,我该怎么看我的镜像版本是多少?可以通过一下三种方法查看

我docker拉取mysql镜像时用的是latest&#xff0c;我该怎么看我的镜像版本是多少&#xff1f; 方法一&#xff1a;查看 Docker 镜像标签 你可以查看 Docker 镜像的标签信息&#xff0c;了解当前使用的 MySQL 镜像版本。 具体步骤如下&#xff1a; 1. 列出本地 Docker 镜像&am…