接入openai的问答系统

  1. 创建了新的 OpenAIClient 类来处理与OpenAI API的通信
  2. 添加了API密钥的安全存储和输入机制
  3. 实现了异步消息处理
  4. 添加了错误处理机制

要使用这个更新后的版本,你需要:

  1. 获取OpenAI API密钥(从 https://platform.openai.com/api-keys 获取)
  2. 首次运行程序时,会弹出对话框要求输入API密钥
  3. API密钥会被安全地保存在本地设置中

主要功能:

  • 支持实时对话
  • 异步处理API请求
  • 错误提示
  • 安全的API密钥存储
  • 支持清空对话历史

使用说明:

  1. 在输入框中输入你的问题
  2. 点击"发送"按钮或按回车键发送消息
  3. 等待AI响应
  4. 使用"清空对话"按钮可以开始新的对话

需要注意的是:

  1. 需要有有效的OpenAI API密钥
  2. 需要网络连接
  3. API调用可能会产生费用(取决于你的OpenAI账户设置)

首先,我们需要添加网络请求相关的功能,并创建一个专门处理OpenAI API调用的类。

  1. 首先创建一个新的头文件openai_client.h来处理OpenAI API调用:
#ifndef OPENAI_CLIENT_H
#define OPENAI_CLIENT_H
#include 
#include 
#include 
#include 
#include 
#include 

class OpenAIClient : public QObject
{
    Q_OBJECT

public:
    explicit OpenAIClient(QObject *parent = nullptr);
    void setApiKey(const QString &apiKey);
    void sendMessage(const QString &message);

signals:
    void responseReceived(const QString &response);
    void errorOccurred(const QString &error);

private:
    QNetworkAccessManager *networkManager;
    QString apiKey;
    QString apiEndpoint;
};

#endif // OPENAI_CLIENT_H

 

2  创建OpenAI客户端的实现文件openai_client.cpp:

#include "openai_client.h"
#include 
#include 
#include 
#include 

OpenAIClient::OpenAIClient(QObject *parent)
    : QObject(parent)
    , networkManager(new QNetworkAccessManager(this))
    , apiEndpoint("https://api.openai.com/v1/chat/completions")
{
}

void OpenAIClient::setApiKey(const QString &apiKey)
{
    this->apiKey = apiKey;
}

void OpenAIClient::sendMessage(const QString &message)
{
    if (apiKey.isEmpty()) {
        emit errorOccurred("API key not set");
        return;
    }

    QNetworkRequest request(apiEndpoint);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setRawHeader("Authorization", QString("Bearer %1").arg(apiKey).toUtf8());

    QJsonObject jsonObj;
    jsonObj["model"] = "gpt-3.5-turbo";

    QJsonArray messagesArray;
    QJsonObject systemMessage;
    systemMessage["role"] = "system";
    systemMessage["content"] = "你是一个友好的AI助手,会用简洁专业的语言回答问题。";
    messagesArray.append(systemMessage);

    QJsonObject userMessage;
    userMessage["role"] = "user";
    userMessage["content"] = message;
    messagesArray.append(userMessage);

    jsonObj["messages"] = messagesArray;
    jsonObj["temperature"] = 0.7;
    jsonObj["max_tokens"] = 1000;

    QJsonDocument doc(jsonObj);
    QByteArray data = doc.toJson();

    QNetworkReply *reply = networkManager->post(request, data);

    connect(reply, &QNetworkReply::finished, [=]() {
        if (reply->error() == QNetworkReply::NoError) {
            QJsonDocument responseDoc = QJsonDocument::fromJson(reply->readAll());
            QJsonObject responseObj = responseDoc.object();

            if (responseObj.contains("choices") && responseObj["choices"].isArray()) {
                QJsonArray choices = responseObj["choices"].toArray();
                if (!choices.isEmpty()) {
                    QJsonObject choice = choices[0].toObject();
                    if (choice.contains("message")) {
                        QJsonObject messageObj = choice["message"].toObject();
                        QString content = messageObj["content"].toString();
                        emit responseReceived(content);
                    }
                }
            }
        } else {
            emit errorOccurred(reply->errorString());
        }
        reply->deleteLater();
    });
}

 3、主窗口头文件mainwindow.h以包含OpenAI客户端:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "openai_client.h"
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void handleSendMessage();
    void handleClearChat();
    void handleAIResponse(const QString &response);
    void handleAIError(const QString &error);

private:
    void appendMessage(const QString &message, bool isUser);
    // QString getAIResponse(const QString &userInput);
    void setupOpenAI();

    QWidget *centralWidget;
    QVBoxLayout *mainLayout;
    QTextEdit *chatDisplay;
    QLineEdit *inputField;
    QPushButton *sendButton;
    QPushButton *clearButton;
    QScrollArea *scrollArea;
    OpenAIClient *openaiClient;
};

#endif // MAINWINDOW_H

4、主窗口实现文件mainwindow.cpp以使用OpenAI客户端:

#include "mainwindow.h"
#include 
#include 
#include 
#include 
#include 
#include
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    // 创建中心部件
    centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);

    // 创建主布局
    mainLayout = new QVBoxLayout(centralWidget);

    // 创建聊天显示区域
    chatDisplay = new QTextEdit(this);
    chatDisplay->setReadOnly(true);
    chatDisplay->setStyleSheet("QTextEdit { background-color: #f5f5f5; }");
    mainLayout->addWidget(chatDisplay);

    // 创建输入区域
    QHBoxLayout *inputLayout = new QHBoxLayout();

    inputField = new QLineEdit(this);
    inputField->setPlaceholderText("输入你的问题...");
    inputLayout->addWidget(inputField);

    sendButton = new QPushButton("发送", this);
    inputLayout->addWidget(sendButton);

    clearButton = new QPushButton("清空对话", this);
    inputLayout->addWidget(clearButton);

    mainLayout->addLayout(inputLayout);

    // 连接信号和槽
    connect(sendButton, &QPushButton::clicked, this, &MainWindow::handleSendMessage);
    connect(clearButton, &QPushButton::clicked, this, &MainWindow::handleClearChat);
    connect(inputField, &QLineEdit::returnPressed, this, &MainWindow::handleSendMessage);

    // 设置窗口标题和大小
    setWindowTitle("AI 问答系统");
    resize(600, 400);
    //初始化open AI客户端
    setupOpenAI();

    // 添加欢迎消息
    appendMessage("你好!我是AI助手,有什么我可以帮你的吗?", false);
}

MainWindow::~MainWindow()
{
    delete openaiClient;
}
void MainWindow::setupOpenAI(){

    openaiClient=new OpenAIClient(this);
    //从设置中读取API密钥
    QSettings settings("your company","AIChat");
    QString apiKey=settings.value("apiKey").toString();
    if(apiKey.isEmpty()){
        bool ok;
        apiKey=QInputDialog::getText(this,"openAI api 密钥","请输入你的openai密钥:", QLineEdit::Password,"",&ok);
        if(ok && !apiKey.isEmpty()){

            settings.setValue("apiKey",apiKey);
        }
    }
    openaiClient->setApiKey(apiKey);
    //连接信号
    connect(openaiClient,&OpenAIClient::responseReceived,this,&MainWindow::handleAIResponse);
    connect(openaiClient,&OpenAIClient::errorOccurred,this,&MainWindow::handleAIError);
}
void MainWindow::handleSendMessage()
{
    QString userInput = inputField->text().trimmed();
    if (userInput.isEmpty()) {
        return;
    }

    // 显示用户消息
    appendMessage(userInput, true);
    inputField->clear();

    // 获取并显示AI响应
    // QString aiResponse = getAIResponse(userInput);
    // appendMessage(aiResponse, false);
    openaiClient->sendMessage(userInput);
}

void MainWindow::handleClearChat()
{
    chatDisplay->clear();
    appendMessage("你好!我是AI助手,有什么我可以帮你的吗?", false);
}
void MainWindow::handleAIResponse(const QString &response){

    appendMessage(response,false);
}
void MainWindow::handleAIError(const QString &error)
{

    QMessageBox::warning(this,"错误","AI响应出错:"+ error);
}
void MainWindow::appendMessage(const QString &message, bool isUser)
{
    QString timestamp = QDateTime::currentDateTime().toString("hh:mm:ss");
    QString formattedMessage = QString("[%1] %2: %3\n")
                                   .arg(timestamp)
                                   .arg(isUser ? "你" : "AI")
                                   .arg(message);

    chatDisplay->append(formattedMessage);

    // 滚动到底部
    QScrollBar *scrollbar = chatDisplay->verticalScrollBar();
    scrollbar->setValue(scrollbar->maximum());
}

6、源文件QtDemo.pro

QT       += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp \
    openai_client.cpp

HEADERS += \
    mainwindow.h \
    openai_client.h

TRANSLATIONS += \
    QtDemo_zh_CN.ts
CONFIG += lrelease
CONFIG += embed_translations

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALL_ROOT *=0

7运行之后弹出填写API密钥,输入密钥后,对话窗口就会弹出,进行AI对话了

你可能感兴趣的:(Qt软件开发,自然语言处理,qt,自然语言处理)