项目demo —— GPT 聊天机器人

  • 本文介绍我的开源项目 TelegramChatBot,这是一个基于 OpenAI GPT API 开发的 telegram 机器人,具有多模态交互能力,求 star!感谢大家!
  • 在 telegram @jokerController_bot 立即体验!
  • 欢迎对 GPT 应用开发或对 telegram 开发有兴趣的朋友和我交流

文章目录

  • 1. 项目简介
    • 1.1 特点
    • 1.2 状态机设计
    • 1.3 数据库设计
  • 2. 各功能最小用例
    • 2.1 文本生成
    • 2.2 图像生成
    • 2.3 语音输入 & 输出

1. 项目简介

1.1 特点

  • 一个由 OpenAI GPT API 驱动的 telegram 聊天机器人
  • 主打催眠玩法,通过在 system 参数中写入 “咒语” 来避免聊天时忘记催眠角色设置,支持咒语的增删查改。
  • 利用多种强大的 API,该机器人具有多模态交互能力,包括图像显示、语音输入输出等。使用API包括
    1. Text generation: gpt-3.5-turbo & gpt-4
    2. Image generation: stable-diffusion-xl-1024-v1-0
    3. Text-to-voice: tts-1
    4. Voice-to-text: whisper-1
  • 下图展示机器人的多模态交互能力,包括图像生成、语音输入输出以及催眠后生成风格化文本
    在这里插入图片描述

1.2 状态机设计

  • 机器人具有多种功能,但是 telegram bot 交互能力有限,难以像桌面软件或者 web 网页那样同时显示大量信息或布局多种功能的操作 UI。因此机器人底层设计为有限状态机以简化前端 UI,这样也更适合在移动端使用
    在这里插入图片描述

  • 下面给出机器人的操作菜单以及部分控制界面
    在这里插入图片描述

1.3 数据库设计

  • 需要存储的用户信息包括用户生成文本和语音的 OpenAI API key、用于生成图像的 Stability AI API key 以及用户编辑的咒语文本,使用 MySQL 数据库进行数据持久化,表设计如下
    CREATE TABLE IF NOT EXISTS user_info (
    	id INT NOT NULL AUTO_INCREMENT,
    	user_id VARCHAR(190) NOT NULL,
    	user_key VARCHAR(190) NOT NULL,
    	user_img_key VARCHAR(190) NOT NULL,
    	prompts TEXT,
    	PRIMARY KEY (id),
    	UNIQUE KEY (user_id)
    )
    
    其中 prompts 字段存储 json 格式的咒语文本

2. 各功能最小用例

  • 本节展示机器人使用的四个 API 的最简单调用方法,读者可以利用它们开发自己的 AI 应用

2.1 文本生成

  • 本项目使用 OpenAI GPT3.5 或 GPT4.0 模型生成文本,最小用例如下
    from openai import OpenAI
    client = OpenAI(api_key='XXX')	# 填入你的 api
    
    response = client.chat.completions.create(
      model="gpt-3.5-turbo",
      messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Who won the world series in 2020?"},
        {"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
        {"role": "user", "content": "Where was it played?"}
      ]
    )
    
    print(response.choices[0].message.content)
    
  • 注意几点
    1. 本项目使当前(2023.11.29)使用的包版本为 openai 1.3.1,文档参考这里
    2. messages 参数需要开发者自行维护,任何时刻,模型记忆仅涵盖在 message 信息内。可以通过 system 字段设置模型的行为,例如设定模型的个性或是提供其行为的具体说明等。本 bot 直接将用户咒语作为 system 参数,并且在组合 messages 的多轮对话时,总是在用户的最后一条回复后加上 “,扮演指定角色回答。” 的附加内容,以保证模型永远不会忘记角色设定
    3. 本 bot 调用以上方法时,还设置了 stream 参数要求模型进行流式传输器回复内容,这样就能通过多次编辑 bot 的回复消息内容实现流式显示,详见开源代码
    4. 如果对回答不满意,只要不将刚刚的回复内容组合进 messages 参数列表中,就可以要求模型进行重新回答,由于 GPT 模型是概率生成模型,每次重新回答都会有所不同
    5. GPT 模型有上下文长度限制,如果 messages 参数列表中内容太多超出限制就会报错,因此本 bot 提供了上下文长度设置功能来限制组合进 messages 列表的对话轮数
    6. 有时我们希望可以语言模型可以按照一定格式进行回复,比如我们希望模型在对话过程中自主识别出用户是否有生成图像的意图,如果有就按照用户当前回复来制图,这样就需要模型在每次回复时不仅回复自然语言回答,还要回复一个 “是否生成图像” 的 bool 变量,这时可以通过设置 response_format={ "type": "json_object" } 参数要求模型以 json 格式进行返回。本 bot 没有使用该功能,详见文档说明

2.2 图像生成

  • 本项目使用 stability.ai 的 stable-diffusion-xl-1024-v1-0 模型生成图像,最小用例如下

    import os
    import io
    import warnings
    from PIL import Image
    from stability_sdk import client
    import stability_sdk.interfaces.gooseai.generation.generation_pb2 as generation
    
    # Our Host URL should not be prepended with "https" nor should it have a trailing slash.
    os.environ['STABILITY_HOST'] = 'grpc.stability.ai:443'
    
    # Sign up for an account at the following link to get an API Key.
    # https://platform.stability.ai/
    
    # Click on the following link once you have created an account to be taken to your API Key.
    # https://platform.stability.ai/account/keys
    
    # Paste your API Key below.
    
    # Set up our connection to the API.
    stability_api = client.StabilityInference(
        key='XXX', # 填入你的 api
        verbose=True, # Print debug messages.
        engine="stable-diffusion-xl-1024-v1-0", # Set the engine to use for generation.
        # Check out the following link for a list of available engines: https://platform.stability.ai/docs/features/api-parameters#engine
    )
    
    # Set up our initial generation parameters.
    answers = stability_api.generate(
        prompt="expansive landscape rolling greens with gargantuan yggdrasil, intricate world-spanning roots towering under a blue alien sky, masterful, ghibli",
        seed=4253978046, # If a seed is provided, the resulting generated image will be deterministic.
                         # What this means is that as long as all generation parameters remain the same, you can always recall the same image simply by generating it again.
                         # Note: This isn't quite the case for Clip Guided generations, which we'll tackle in a future example notebook.
        steps=50, # Amount of inference steps performed on image generation. Defaults to 30. 
        cfg_scale=8.0, # Influences how strongly your generation is guided to match your prompt.
                       # Setting this value higher increases the strength in which it tries to match your prompt.
                       # Defaults to 7.0 if not specified.
        width=1024, # Generation width, defaults to 512 if not included.
        height=1024, # Generation height, defaults to 512 if not included.
        samples=1, # Number of images to generate, defaults to 1 if not included.
        sampler=generation.SAMPLER_K_DPMPP_2M # Choose which sampler we want to denoise our generation with.
                                                     # Defaults to k_dpmpp_2m if not specified. Clip Guidance only supports ancestral samplers.
                                                     # (Available Samplers: ddim, plms, k_euler, k_euler_ancestral, k_heun, k_dpm_2, k_dpm_2_ancestral, k_dpmpp_2s_ancestral, k_lms, k_dpmpp_2m, k_dpmpp_sde)
    )
    
    # Set up our warning to print to the console if the adult content classifier is tripped.
    # If adult content classifier is not tripped, save generated images.
    for resp in answers:
        for artifact in resp.artifacts:
            if artifact.finish_reason == generation.FILTER:
                warnings.warn(
                    "Your request activated the API's safety filters and could not be processed."
                    "Please modify the prompt and try again.")
            if artifact.type == generation.ARTIFACT_IMAGE:
                img = Image.open(io.BytesIO(artifact.binary))
                img.save(str(artifact.seed)+ ".png") # Save our generated images with their seed number as the filename.
    
  • 注意几点

    1. 本项目当前(2023.11.29)使用的包版本为 stability-sdk 0.4.0,文档参考这里
    2. 这个模型是一个 text-to-image 的模型,生成图像质量会显著受到 prompt 质量影响,因此不适合直接用自然语言作为 prompt 来生成图像。本 bot 利用 GPT 模型的 in-context learning 能力,先把自然语言翻译成较高质量的 image prompt,再调用该模型生成图像,这一步输入给 GPT 模型的 prompt 如下
      IMGPROMPT = "A prompt example for 一个童话般的宁静小镇,鸟瞰视角,动漫风格 is “a painting of a fairy tale town, serene landscape, a bird's eye view, anime style, Highly detailed, Vivid Colors.” "
      IMGPROMPT += "Another prompt example for 双马尾动漫少女,蓝黑色头发,颜色鲜艳 is “a painting of 1girl, blue | black hair, low twintails, anime style, with bright colors, Highly detailed.” "
      IMGPROMPT += "Another prompt example for 拟人化的兔子肖像,油画,史诗电影风格 is “a oil portrait of the bunny, Octane rendering, anthropomorphic creature, reddit moderator, epic, cinematic, elegant, highly detailed, featured on artstation.” "
      IMGPROMPT += "Another prompt example for 黄昏下,大雨中,两个持刀的海盗在海盗船上决斗 is “Two knife-wielding pirates dueling on a pirate ship, dusk, heavy rain, unreal engine, 8k, high-definition, by Alphonse Mucha and Wayne Barlowe.” "
      IMGPROMPT += "Now write a prompts for "
      
      当然,bot 也提供了直接使用用户输入内容作为 prompt 生成图像的命令,熟悉 AI 图像生成方法的用户可以直接提供高质量的 image prompt 序列

2.3 语音输入 & 输出

  • 本项目使用 OpenAI tts-1 模型实现文字转语音,使用 whisper-1 模型实现语音转文字,最小用例如下
    from pathlib import Path
    from openai import OpenAI
    client = OpenAI(api_key='XXX')	# 填入你的 api
    
    # text2voice
    speech_file_path = Path(__file__).parent / "speech.ogg"
    response = client.audio.speech.create(
      model="tts-1",
      voice="alloy",
      input="Hello, World! 你好世界!",
      response_format='opus'
    )
    response.stream_to_file(speech_file_path)
    
    # voice2text
    file_path = Path(__file__).parent / "speech.ogg"
    audio_file = open(file_path, "rb")
    transcript = client.audio.transcriptions.create(
      model="whisper-1", 
      file=audio_file, 
      response_format="text"
    )
    print(transcript)
    
  • 本项目使当前(2023.11.29)使用的包版本为 openai 1.3.1,文档参考
    • Text-to-voice: tts-1
    • Voice-to-text: whisper-1

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQL server-excel数据追加到表

参考文章:SQL server 2019 从Excel导入数据_mssql2019 导入excel数据-CSDN博客 将excel数据导入到SQL server数据库的详细过程 注意:第一行数据默认为数据库表中的字段,所以这个必须要有,否则无法映射导入 问题1:ADD…

如何使用阿里云虚拟主机和域名设置网站?

本文档将向您展示如何使用阿里云虚拟主机来设置一个新网站,并完成一个域名。如果您按照此处的步骤操作,您将启动并运行一个新网站,可以使用您选择的名称在全球范围内访问,并托管在阿里云平台上。 本文档假设您已经拥有有效的阿里…

Python爬虫遇到重定向URL问题时如何解决?

什么是重定向 重定向是指当用户请求一个URL时,服务器返回一个中断请求的URL的响应。这种情况通常发生在网站对URL进行了修改或者重定向到其他页面的情况下。其中,如果处理不当开发,可能会导致爬虫无法获取所需的数据,从而影响爬虫…

基于SSM的仓库管理系统的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

CentOS7安装RabbitMQ

服务器系统版本:CentOS7 安装RabbitMq版本:3.7.18 将此安装包目录下的两个文件上传到服务/usr/local/rabbitmq中备用。 安装Erlang依赖包 rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm安装RabbitMQ安装包(需要联网) yum install -y rabbitmq-server-3.7.1…

Message全局提示(antd-design组件库)简单用法

1.Message全局提示 全局展示操作反馈信息。 2.何时使用 可提供成功、警告和错误等反馈信息。 顶部居中显示并自动消失,是一种不打断用户操作的轻量级提示方式。 组件代码来自: 全局提示 Message - Ant Design 3.本地验证前的准备 参考文章【react项目ant…

【LeetCode】101. 对称二叉树

101. 对称二叉树 难度:简单 题目 给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输入:root [1,2,2,3,4,4,3] 输出:true示例 2: 输入:root [1,2,2,null,3,null,3] 输出&#…

Java高级技术(注解)

一,注解 二,案例 三,注解原理 四,元注解 五,案例 六,解析注解 七,案例

本地部署GPT的实战方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

C++面向对象复习笔记暨备忘录

C指针 指针作为形参 交换两个实际参数的值 #include <iostream> #include<cassert> using namespace std;int swap(int *x, int* y) {int a;a *x;*x *y;*y a;return 0; } int main() {int a 1;int b 2;swap(&a, &b);cout << a << &quo…

多模块项目打包部署

目录结构 这些模块间相互依赖&#xff0c;打包的时候打父模块&#xff0c;就是带root的这个 先clean&#xff0c;再package&#xff0c;就跟一般的项目一样了。 有可能遇到报错Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test&#xff…

springboot基础配置及maven运行

目录 1、spring快速开始&#xff1a; 2、通过idea工具打开导入包 3、maven打包 1、springboot快速开始&#xff1a; 环境依赖&#xff1a;jdk17 Spring | Quickstart spring初始化包下载&#xff1a; 点击generate&#xff0c;下载包 2、通过idea工具打开导入包 我之前写了…

【云备份】热点管理模块

文章目录 整体思路概括热点管理实现构造函数Hotjudge ——热点判断RunModule ——运行模块 代码实现hot.hpp 整体思路概括 整体概括&#xff1a; 对服务器上备份的文件进行检测&#xff0c;那些文件长时间没有被访问&#xff0c;则认为是非热点文件 进行压缩存储&#xff0c;节…

华清远见嵌入式学习——C++——作业2

作业要求&#xff1a; 代码&#xff1a; #include <iostream>using namespace std;class Rect { private:int width;int height;public:void init(int w,int h);void set_w(int w);void set_h(int h);void show(); };void Rect::init(int w,int h) {width w;height h;…

BUUCTF sqltest 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 网站遭受到攻击了&#xff0c;还好我们获取到了全部网络流量。 链接: https://pan.baidu.com/s/1AdQXVGKb6rkzqMLkSnGGBQ 提取码: 34uu 注意&#xff1a;得到的 flag 请包上 flag{} 提交 密文&#xff1a; 下载附件…

GDPU 数据结构 天码行空12

文章目录 数据结构实验十二 图的遍历及应用一、【实验目的】二、【实验内容】三、实验源代码&#x1f37b; CPP&#x1f37b; C 数据结构实验十二 图的遍历及应用 一、【实验目的】 1、 理解图的存储结构与基本操作&#xff1b; 2、熟悉图的深度度优先遍历和广度优先遍历算法…

RabbitMQ的Web管理页面

访问页面 http://IP:15672/账号密码默认都是&#xff1a;guest 主页概览 Overview 显示当前RabbitMQ Broker的运行信息、连接信息、集群信息以及配置信息等。 连接 Connections 无论生产者还是消费者&#xff0c;都需要与RabbitMQ建立连接后才可以完成消息的生产和消费&#…

PHP:js中怎么使用PHP变量,php变量为数组时的处理

方法一&#xff1a;使用内嵌 PHP 脚本标记 1、简单的拼接 使用内嵌的 PHP 脚本标记 <?php ?> 将 PHP 变量 $phpVariable 的值嵌入到 JavaScript 代码中。 <?php $phpVariable "Hello, World!"; ?><script> // 将 PHP 变量的值传递给 JavaS…

mac安装homebrew/brew遇到443

文章目录 问题描述解决方法方法一方法二 参考文献 问题描述 brew 全称Homebrew 是Mac OSX上的软件包管理工具 想在mac终端安装&#xff0c;运行网上提供的指令 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)&quo…

【Springboot系列】SpringBoot整合Jpa

文章目录 前言&#xff1a;什么是JPA&#xff1f;JPA优缺点优点1.简化开发&#xff1a;2.高度抽象&#xff1a;3.跨数据库支持&#xff1a;4.自动化的事务管理&#xff1a; 缺点1.学习成本较高&#xff1a;2.性能问题&#xff1a;3.灵活性受限&#xff1a; 示例版本依赖代码Use…