手把手教你做一个属于自己的GPT

目录

一、项目展示:

二、项目介绍:

三、项目实现:

        第一步:申领api

        第二步:安装配置库

         第三步:编写代码


一、项目展示:

二、项目介绍:

        本项目采用pyqt来构建界面,调用了讯飞星火平台的api,来完成gpt智能问答系统,并且支持prompt提示优化,具有历史记录功能,还可以打包成成.exe文件供朋友使用。

三、项目实现:

        第一步:申领api

注册完账号,进入主页,点击服务管理

点击创建新应用

        给应用起名字

创建完成后,点击创建好的应用

点击立即购买

选择创建好的应用,选择第一个,点击购买,完成实名认证

实名认证完后会送200w tokens,完全够用了,接下来记住这些信息

        第二步:安装配置库

        pip install pyqt5

        pip install urllib

        pip install websocket

        pip install configparser

缺啥补啥就对了,另外如果后续想自己设计页面,需要看看博客教程配置一下qtDesigner

         第三步:编写代码

        1.创建名为wsPram.py的文件,将如下代码cv进去,代码的功能就是生成api链接的

from datetime import datetime
from time import mktime
from urllib.parse import urlencode
from wsgiref.handlers import format_date_time
from urllib.parse import urlparse
import base64
import hashlib
import hmac
class Ws_Param(object):
    # 初始化
    def __init__(self, APPID, APIKey, APISecret, gpt_url):
        self.APPID = APPID
        self.APIKey = APIKey
        self.APISecret = APISecret
        self.host = urlparse(gpt_url).netloc
        self.path = urlparse(gpt_url).path
        self.gpt_url = gpt_url

    # 生成url
    def create_url(self):
        # 生成RFC1123格式的时间戳
        now = datetime.now()
        date = format_date_time(mktime(now.timetuple()))

        # 拼接字符串
        signature_origin = "host: " + self.host + "\n"
        signature_origin += "date: " + date + "\n"
        signature_origin += "GET " + self.path + " HTTP/1.1"

        # 进行hmac-sha256进行加密
        signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
                                 digestmod=hashlib.sha256).digest()

        signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')

        authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'
        authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
        v = {
            "authorization": authorization,
            "date": date,
            "host": self.host
        }
        # 拼接鉴权参数,生成url
        url = self.gpt_url + '?' + urlencode(v)
        # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致
        return url

2. 调用接口,实现与gpt互动交流

也可以根据官方教程下载代码,自己改进

因为gpt不能一下子生成全部回复,生成的回复是一段一段的,于是采用webscoket来接收相应回复,实现实时回复效果。这里我使用列表,将每次回复都添加进列表里,回复完成后输出列表,就是一整段话了。

import _thread as thread
import json
import ssl
import websocket
import configparser
from wsPram import Ws_Param
class GptMsg():
    def __init__(self):
        self.config = configparser.ConfigParser()
        self.config.read('cfig/config.ini', encoding='utf-8')
        self.APPID = self.config['DEFAULT']['APPID']
        self.APISecret =self. config['DEFAULT']['APISecret']
        self.APIKey = self.config['DEFAULT']['APIKey']

        self.gpt_url = 'wss://spark-api.xf-yun.com/v3.5/chat'
        self.domain='generalv3.5'
        self.msg = []

        self.txt = self.config['DEFAULT']['TXT']
        self.name = self.config['DEFAULT']['NAME']
        self.history_text = [{"role":"system","content": self.txt}]
        print('gpt初始化成功')
    def send_msg(self, question):
        # 获取url
        wsParam = Ws_Param(self.APPID, self.APIKey, self.APISecret, self.gpt_url)
        websocket.enableTrace(False)
        wsUrl = wsParam.create_url()
        # 消息加入
        ques_json = {"role": "user", "content": question}
        self.history_text.append(ques_json)
        # 发送消息
        ws = websocket.WebSocketApp(wsUrl, on_message=self.on_message, on_error=self.on_error, on_close=self.on_close, on_open=self.on_open)
        ws.appid = self.APPID
        ws.domain = self.domain
        ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})

    # 收到websocket错误的处理
    def on_error(self, ws, error):
        print("### error:", error)

    # 收到websocket关闭的处理
    def on_close(self, ws, *args):
        print("### closed ###")

    # 收到websocket连接建立的处理
    def on_open(self, ws):
        thread.start_new_thread(self.run, (ws,))

    def run(self, ws, *args):
        data = json.dumps(self.gen_params(appid=ws.appid, domain=ws.domain))
        ws.send(data)

    def gen_params(self, appid, domain):
        # print(window.history_text)
        if len(self.history_text) >= 60:
            self.history_text.pop(1)
            self.history_text.pop(2)
        data = {
            "header": {
                "app_id": appid,
                "uid": "1234",
            },
            "parameter": {
                "chat": {
                    "domain": domain,
                    "temperature": 0.5,
                    "max_tokens": 4096,
                    "auditing": "default",
                }
            },
            "payload": {
                "message": {
                    "text": self.history_text
                }
            }
        }
        return data

    # 收到websocket消息的处理
    def on_message(self, ws, message):
        data = json.loads(message)
        code = data['header']['code']
        if code != 0:
            print(f'请求错误: {code}, {data}')
            ws.close()
        else:
            choices = data["payload"]["choices"]
            status = choices["status"]
            content = choices["text"][0]["content"]
            self.msg.append(content)
            print(content)
            if status == 2:
                self.msg.append('`')
                ws.close()

if __name__ == '__main__':
    gpt = GptMsg()
    while True:
        question = input('请输入问题:')
        gpt.send_msg(question)
        print('完整回答:', gpt.msg)

效果如图所示:

3.编写界面

界面使用的是pyqt,使用qrdesigner设计的界面

import sys
from threading import Thread

from PySide2.QtCore import QObject, QFile, Signal, QTimer
from PySide2.QtGui import QImage, QPixmap, QIcon
from PySide2.QtWidgets import *
from PySide2.QtUiTools import QUiLoader
from PySide2 import QtCore


from GPT.gptMsg import GptMsg


class GptWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        qfile = QFile("ui/gpt.ui")
        qfile.open(QFile.ReadOnly)
        qfile.close()
        self.ui = QUiLoader().load(qfile)
        self.gpt = GptMsg()
        self.ai_answer_list = []
        self.initStyle()
        self.initBtn()
        self.timer()


    def initStyle(self):
        self.ui.setStyleSheet('font-size:16px; font-weight: bold; background-color: rgb(248,252,255);')
        self.ui.textBrowser.setStyleSheet('background-color: rgb(202,232,234);')
        self.ui.lineEdit.setStyleSheet('height:30px;background-color: rgb(233,247,249);')
        self.ui.pushButton.setStyleSheet('background-color: rgb(61,192,246);')
        self.ui.pushButton_2.setStyleSheet('background-color: rgb(82,222,148);')

    def initBtn(self):
        self.ui.pushButton_2.clicked.connect(self.send)
        self.ui.lineEdit.returnPressed.connect(self.send)
        self.ui.pushButton.clicked.connect(self.clear)

    def send(self):
        question = self.ui.lineEdit.text()
        self.ui.lineEdit.setText('')
        self.gpt.msg.append('您的输入:' + question)
        self.gpt.msg.append('`')
        self.gpt.msg.append(f'{self.gpt.name}回复:')
        Thread(target=self.send_msg, args=(question,)).start()

    def send_msg(self, question):
        self.gpt.send_msg(question)


    def clear(self):
        self.ui.textBrowser.setPlainText('')
        self.gpt.history_text = [{"role":"system","content": self.gpt.txt}]


    def timer(self):
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.show_msg)
        self.timer.start(30)  # 定时器开始计时30ms

    def show_msg(self):
        if len(self.gpt.msg) != 0:
            text = self.gpt.msg[0]
            self.gpt.msg.pop(0)
            if text != '`':
                self.ui.textBrowser.insertPlainText(text)
                self.ai_answer_list.append(text)
            if text == '`':
                self.ui.textBrowser.append('')
                self.ui.textBrowser.append('')
                ai_answer = "".join(self.ai_answer_list)
                self.ai_answer_list = []
                if f'{self.gpt.name}回复:' in ai_answer:
                    ai_answer = ai_answer.split(':')[1]
                    ai_dict = {"role": "assistant", "content": ai_answer}
                    self.gpt.history_text.append(ai_dict)
if __name__ == '__main__':
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon('cfig/logo.png'))
    window = GptWindow()
    window.ui.show()
    sys.exit(app.exec_())

config.ini配置文件 

上面三条换成申领api的信息

txt就是prompt语句,你可以让机器人成为任何你指定的人

NAME就是机器人的名字

[DEFAULT]
APPID = 你的id
APISecret = 你的APISecret 
APIKey = 你的key
TXT = 你是一个乐于助人的机器人
NAME = AI

运行结果

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值