[C++] 281 FLTK : ChatGPTアプリの製作 その10 AIリネーム機能 文字列削除関数

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

AIリネーム機能を改良しました。半角スペースやカギ括弧を削除するための関数を作成しました。この関数は今後も重宝しそうです。

こういった気の利いた関数をChatGPTに書かせようとすると高確率でデタラメを提示してくるので、最初から自分で書く方が速かったりします。完成目前の仕上げはしっかりやってくれることもあります。

ここまで機能を揃えるともうChatGPT Plusを解約しても問題ないでしょう。来週は月更新せずに済みそうです。

void deleteString(string& str, const char* del) {
    size_t size = strlen(del);
    size_t pos = 0;
    while ((pos = str.find(del, pos)) != string::npos) {
        // cout << "pos: " << pos << endl;
        str.erase(pos, size);
    }
}

void renameCB(Fl_Widget*, void*){
    input -> value("これまでの質問回答の内容から15文字程度で日本語タイトルを考えて下さい。英単語が混ざってもかまいません。");
    sendBtn->do_callback();
    
    Fl_Text_Buffer* buffer = output->buffer();
    title = buffer->text();

    cout << "title加工前: " << title << endl;
    
    // 半角スペースと「」を削除
    deleteString(title, " ");
    deleteString(title, "「");
    deleteString(title, "」");

    cout << "title加工後: " << title << endl;

    vector<string> tokens;
    string delimiter = ".";
    size_t pos = 0;
    string token;
    string jsonFileStr = string(jsonFile);
    while ((pos = jsonFileStr.find(delimiter)) != string::npos) {
        token = jsonFileStr.substr(0, pos);
        tokens.push_back(token);
        jsonFileStr.erase(0, pos + delimiter.length());
    }
    tokens.push_back(jsonFile);

    string jsonFileNew = tokens[0] + "_" + title + ".json";

    cout << "jsonFileNew: " << jsonFileNew << endl;

    int result = std::rename(jsonFile.c_str(), jsonFileNew.c_str());
    if (result == 0) {
        std::printf("File renamed successfully.\n");
    } else {
        std::printf("Error renaming file.\n");
    }

    Fl_Text_Buffer* bufferNotice = new Fl_Text_Buffer();
    string notice = "JSONファイルをリネームしました。\n" + jsonFileNew;
    bufferNotice -> text(notice.c_str());
    noticeDisplay -> buffer(bufferNotice);
}

[C++] 280 FLTK : ChatGPTアプリの製作 その9 AIリネーム機能実装

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

せっかくAIを使っているのですから、作成しているJSONファイルの命名を手伝わせています。

指定の文字数は守らない、カギ括弧を付けるなと指示しても付けてくる、など全然ルールを守りませんが最低限のことはやってくれます。

カギ括弧はこちらで削除したいものの、良い方法が分からず模索中です。

void renameCB(Fl_Widget*, void*){
    input -> value("これまでの質問回答の内容から15文字程度で日本語タイトルを考えて下さい。英単語が混ざってもかまいません。");
    sendBtn->do_callback();

    
    Fl_Text_Buffer* buffer = output->buffer();
    title = buffer->text();

    cout << "title加工前: " << title << endl;
    // 先頭の半角スペースを削除する
    title.erase(title.begin(), std::find_if(title.begin(), title.end(), [](char c) {
        return !std::isspace(c);
    }));

    if (title.length() > 0) {
        char c = title[0];
        if ((c >= 0x21 && c <= 0x2F) || (c >= 0x3A && c <= 0x40) || (c >= 0x5B && c <= 0x60) || (c >= 0x7B && c <= 0x7E)|| c == static_cast<char>(0x300C) || c == static_cast<char>(0x300D)) {
            // 先頭の文字が記号である場合
            title.erase(title.begin(), title.begin() + 3);
        }
    }

   if (title.length() > 0) {
        char c = title.back();
        if ((c >= 0x21 && c <= 0x2F) || (c >= 0x3A && c <= 0x40) || (c >= 0x5B && c <= 0x60) || (c >= 0x7B && c <= 0x7E) || c == static_cast<char>(0x300C) || c == static_cast<char>(0x300D)) {
            // 末尾の文字が記号である場合(カギ括弧を含む)
            title.erase(title.end() - 3, title.end());
        }
    }

    cout << "title加工後: " << title << endl;

    vector<string> tokens;
    string delimiter = ".";
    size_t pos = 0;
    string token;
    string jsonFileStr = string(jsonFile);
    while ((pos = jsonFileStr.find(delimiter)) != string::npos) {
        token = jsonFileStr.substr(0, pos);
        tokens.push_back(token);
        jsonFileStr.erase(0, pos + delimiter.length());
    }
    tokens.push_back(jsonFile);

    string jsonFileNew = tokens[0] + "_" + title + ".json";

    cout << "jsonFileNew: " << jsonFileNew << endl;

    int result = std::rename(jsonFile.c_str(), jsonFileNew.c_str());
    if (result == 0) {
        std::printf("File renamed successfully.\n");
    } else {
        std::printf("Error renaming file.\n");
    }

    Fl_Text_Buffer* bufferNotice = new Fl_Text_Buffer();
    string notice = "JSONファイルをリネームしました。\n" + jsonFileNew;
    bufferNotice -> text(notice.c_str());
    noticeDisplay -> buffer(bufferNotice);
}

[C++] 279 FLTK : ChatGPTアプリの製作 その8 コードをFl_Text_Displayに表示・改良

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

ChatGPTから得られた回答を一旦JSONに格納してから取り出すという手順が間違いの元でした。

回答の生データをそのままFl_Text_Displayに表示してから、JSONに格納するようにしました。

これで可読性が大幅に改善しました。

ただJSONに収まった時点でprintf(“%s\n”,str)のようなコード中の改行文字とエスケープシーケンスとしてリテラル化した改行文字が混在してしまうので完全な復元ができない、という問題を抱えたままです。

自分で簡単なパーサー(解析器)を作るしかないのかもしれません。

vector<string> getCode(string str){
    vector<string> codes;
    size_t start_pos = str.find("```");
    while (start_pos != string::npos) {
        size_t end_pos = str.find("```", start_pos + 1);
        if (end_pos != string::npos) {
            code = str.substr(start_pos + 3, end_pos - start_pos - 3);

            size_t start_pos2 = code.find("#");
            code.erase(0, start_pos2);
            codes.push_back(code);
            cout << "getCode内code:\n" << code << endl;

            str.erase(start_pos, end_pos - start_pos + 3);
            cout << "getCode内str:\n" << str << endl;
        }
        start_pos = str.find("```");
    }

    return codes;
}

[C++] 278 FLTK : ChatGPTアプリの製作 その7 コードをFl_Text_Displayに表示

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

これはかなり手こずりました。ChatGPTからは有益なヒントを得られず、自力解決でした。かなり泥臭い手法です。

ChatGPTから受け取った回答をJSON解析するため、改行文字やダブルクォートをリテラルにしているので、これらを元に戻しました。printf(\”%s\n\”, content_cstr);のような置き換える必要のないところまで改行になってしまいますが、これ位はしかたないです。

// code取り出し&表示
    vector<string> codes;
    size_t start_pos = content2.find("```");
    while (start_pos != string::npos) {
        size_t end_pos = content2.find("```", start_pos + 1);
        if (end_pos != string::npos) {
            code = content2.substr(start_pos + 3, end_pos - start_pos - 3);

            size_t start_pos2 = code.find("#");
            code.erase(0, start_pos2);
            codes.push_back(code);
            cout << "code: " << code << endl;

            content2.erase(start_pos, end_pos - start_pos + 3);
            cout << "content2: " << content2 << endl;
        }
        start_pos = content2.find("```");
    }

    Fl_Text_Buffer* bufferCode = new Fl_Text_Buffer();
    string codeStr = codes[0];

    pos = 0;
    while ((pos = codeStr.find("\\n", pos)) != string::npos) {
        codeStr.replace(pos, 2, "\n");
        pos += 2;
    }
    pos = 0;
    while ((pos = codeStr.find("\\n", pos)) != string::npos) {
        codeStr.replace(pos, 2, "\n");
        pos += 2;
    }
    pos = 0;
    while ((pos = codeStr.find('\\', pos)) != string::npos) {
        codeStr.erase(pos, 1);
        pos += 2;
    }

    bufferCode -> text(codeStr.c_str());
    codeDisplay -> buffer(bufferCode);
    codeDisplay -> wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 5);

[C++] 277 FLTK : ChatGPTアプリの製作 その6 JSONをドラッグ&ドロップ

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

JSONファイルをGUIにドラッグ&ドロップできるようにしました。

ChatGPTの回答文からコードを取り出すことはできましたが、改行やインデント整形ができません(GUIの左下)。Fl_Text_Displayは文字列リテラルであればコードをきれいに並べて表示できます。文字列変数の場合はどうすればよいのか調査中です。

#pragma once
#include <FLstd.h>
#include "cppstd.h"

class Box : public Fl_Box {
    Fl_Input* input;

    public:
        Box(int, int, int, int, Fl_Input*);
    private:
        int handle(int);
};
#include "Box.h"

Box::Box(int x, int y, int width_input, int height_input, Fl_Input* input) : Fl_Box(FL_NO_BOX, x, y, width_input, height_input, "") 
{
    this->input = input;
}

int Box::handle(int event){
    switch (event) {
        case FL_DND_DRAG:
        case FL_DND_ENTER:
        case FL_DND_RELEASE:
            return 1;
        case FL_PASTE:
            input -> value(Fl::event_text()); 
            input -> textsize(12);

            return 1;
        default:
            return Fl_Box::handle(event);
    }
}

[C++] 276 FLTK : ChatGPTアプリの製作 その5 JSONを読み込む

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

過去の質問回答が入っているJSONファイルを読み込み、追加の質問が出来るようにしました。

今のところJSONファイルのパスを直接入力する仕様ですが、ドラッグ&ドロップやFileChooserにも対応する予定です。

あとは回答からソースコード部分を取り出して、見やすくすることぐらいでしょうか。

void loadCB(Fl_Widget*, void*){
    load = true;
    sendNum = 0;
    input -> value("");
    sysInput -> value("");

    Fl_Text_Buffer* bufferDelete = new Fl_Text_Buffer();
    bufferDelete -> text("");
    output->buffer(bufferDelete);

    const char* jsonLoadFile = jsonInput -> value();
    // JSONファイルの内容をjsonに変換
    std::ifstream ifs(jsonLoadFile);
    json jsonLoadData = json::parse(ifs);
    jsonData = jsonLoadData;

    // jsonをstringに変換
    string jsonLoadString = jsonLoadData.dump(2);

    Fl_Text_Buffer*bufferLoad = new Fl_Text_Buffer();
    bufferLoad -> text(jsonLoadString.c_str());
    jsonDisplay -> buffer(bufferLoad);
    jsonDisplay -> wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 5);

    // 現在の行数を取得
    int lineCount2 = jsonDisplay->buffer()->count_lines(0, jsonDisplay->buffer()->length());

    // 最終行が見えるようにスクロールを設定
    jsonDisplay->scroll(lineCount2, 0);

}

[C++] 275 FLTK : ChatGPTアプリの製作 その4 JSONを見やすくする

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

GUI右側のFl_Browserは右端の折り返しが出来ないのでFl_Text_Displayに変更しました。

動作は遅くなってしまいましたが、断然見やすくなりました。

驚いたことにChatGPTはマイナーなライブラリであるFLTKの機能にかなり精通しています。

void sendCB(Fl_Widget*, void*) {
    // 開始時間取得
    if (sendNum == 0){
        auto now = std::chrono::system_clock::now();
        auto time_t = std::chrono::system_clock::to_time_t(now);
        std::tm tm = *std::localtime(&time_t);

        // 日時を指定されたフォーマットで文字列に変換する
        std::stringstream ss;
        ss << std::put_time(&tm, "%y%m%d_%H%M%S");
        startTime = ss.str();

        sendNum++;
    }

    const char* system = sysInput -> value();
    systemStr = string(system);

    const char* question0 = nullptr;
    question0 = input -> value();
	string question(question0);
	json response = chatWithOpenAI(question);
	string resDump = response.dump();
	cout << resDump << endl;

    string content = response["choices"][0]["message"]["content"].get<string>();
    cout << content << endl;

    while (!content.empty() && content.front() == '\n') {
        content.erase(0, 1);
    }

    size_t pos = 0;
    while ((pos = content.find('"', pos)) != string::npos) {
        content.replace(pos, 1, "\\\"");
        pos += 2;
    }

    pos = 0;
    while ((pos = content.find('\n', pos)) != string::npos) {
        content.replace(pos, 1, "\\n");
        pos += 2;
    }

    string res = R"({"role":"assistant","content":")" + content + R"("})";
    json resJson = json::parse(res);

    jsonData = json::parse(requestData);
    jsonData["messages"].push_back(resJson);

    cout << "回答追加後jsonData: " << jsonData.dump() << endl;

    // jsonファイル化
    jsonFileName = "/Users/[ユーザID]/ChatGPT/" + startTime + "_ChatGPT.json";
    std::ofstream ofs(jsonFileName, std::ios::out | std::ios::trunc);
    ofs << std::setw(2) << jsonData << std::endl;
    ofs.close();

	Fl_Text_Buffer*buffer = new Fl_Text_Buffer();
	buffer -> text(content.c_str());
	output -> buffer(buffer);
	output -> wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 5);

    // JSON表示
    std::ifstream ifs(jsonFileName);
    json jsonData = json::parse(ifs);

    // Convert json to string with pretty-print
    string jsonString = jsonData.dump(2);

    Fl_Text_Buffer*buffer2 = new Fl_Text_Buffer();
	buffer2 -> text(jsonString.c_str());
	jsonDisplay -> buffer(buffer2);
	jsonDisplay -> wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 5);

    // 現在の行数を取得
    int lineCount = jsonDisplay->buffer()->count_lines(0, jsonDisplay->buffer()->length());

    // 最終行が見えるようにスクロールを設定
    jsonDisplay->scroll(lineCount, 0);
}

[C++] 274 FLTK : ChatGPTアプリの製作 その3 質問回答履歴表示 JSON

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

ChatGPTアプリGUIの右側に質問回答履歴のJSONファイルを表示しました。

次は過去のJSONファイルを読み込んで質問を再開できるようにします。

#include <FLstd.h>
#include <cppstd.h>
#include <ChatGPT.h>

using json = nlohmann::json;
extern string requestData;
json jsonData;
Fl_Multiline_Input* input;
Fl_Text_Display* output;
Fl_Input* sysInput;
Fl_Input* jsonInput;
Fl_Browser* browser;
int sendNum;
string startTime;
string jsonFileName;
string systemStr;

void sendCB(Fl_Widget*, void*) {
    // 開始時間取得
    if (sendNum == 0){
        auto now = std::chrono::system_clock::now();
        auto time_t = std::chrono::system_clock::to_time_t(now);
        std::tm tm = *std::localtime(&time_t);

        // 日時を指定されたフォーマットで文字列に変換する
        std::stringstream ss;
        ss << std::put_time(&tm, "%y%m%d_%H%M%S");
        startTime = ss.str();

        sendNum++;
    }

    const char* system = sysInput -> value();
    systemStr = string(system);

    const char* question0 = nullptr;
    question0 = input -> value();
    string question(question0);
    json response = chatWithOpenAI(question);
    string resDump = response.dump();
    cout << resDump << endl;

    string content = response["choices"][0]["message"]["content"].get<string>();
    cout << content << endl;

    while (!content.empty() && content.front() == '\n') {
        content.erase(0, 1);
    }

    size_t pos = 0;
    while ((pos = content.find('"', pos)) != string::npos) {
        content.replace(pos, 1, "\\\"");
        pos += 2;
    }

    pos = 0;
    while ((pos = content.find('\n', pos)) != string::npos) {
        content.replace(pos, 1, "\\n");
        pos += 2;
    }

    string res = R"({"role":"assistant","content":")" + content + R"("})";
    json resJson = json::parse(res);

    jsonData = json::parse(requestData);
    jsonData["messages"].push_back(resJson);

    cout << "回答追加後jsonData: " << jsonData.dump() << endl;

    // jsonファイル化
    jsonFileName = "/Users/[ユーザID]/ChatGPT/" + startTime + "_ChatGPT.json";
    std::ofstream ofs(jsonFileName, std::ios::out | std::ios::trunc);
    ofs << std::setw(2) << jsonData << std::endl;
    ofs.close();

    Fl_Text_Buffer*buffer = new Fl_Text_Buffer();
    buffer -> text(content.c_str());
    output -> buffer(buffer);
    output -> wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 5);

    browser -> load(jsonFileName.c_str());
    int line_num = browser->size();
    browser -> bottomline(line_num);
    browser -> has_scrollbar(Fl_Browser_::BOTH);
}

int main(int argc, char **argv) {
    Fl_Window* window = new Fl_Window (100, 100, 960, 640, "ChatGPT");
    window->color(fl_rgb_color(208,207,207));
	 
    // Question inputLabel
    Fl_Box* inputLabel = new Fl_Box(14,22,26,23,"Q");
    inputLabel->labelsize(18);
    inputLabel->labelcolor(fl_rgb_color(62,66,60));
    inputLabel->align(Fl_Align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT));

    // Question input
    input = new Fl_Multiline_Input(47, 15, 360, 105);
    input->textsize(12);
    // input->wrap_mode(Fl_Multiline_Input::WRAP_AT_BOUNDS, 0); // 折り返し設定

    Fl_Scroll *scroll = new Fl_Scroll(47, 15, 360, 105);
    scroll->end();
    scroll->type(Fl_Scroll::VERTICAL_ALWAYS);
    scroll->scrollbar_size(20);
    scroll->add(input);
    	
    // sendBtn
    Fl_Button* sendBtn = new Fl_Button(420,15,60,40,"送信");
    sendBtn->color(fl_rgb_color(112,128,144));
    sendBtn->labelcolor(fl_rgb_color(208,207,207));
    sendBtn->labelsize(16);
    sendBtn->callback(sendCB);

    // Response
    output = new Fl_Text_Display(19,130,450,500,"Response");
    output->labelcolor(fl_rgb_color(62,66,60));
    output->textsize(12);
    output->align(Fl_Align(FL_ALIGN_TOP_RIGHT));
    output->labelsize(10);

    // Sys設定 sysLabel
    Fl_Box* sysLabel = new Fl_Box(499,22,60,17,"Sys設定");
    sysLabel->labelsize(16);
    sysLabel->labelcolor(fl_rgb_color(62,66,60));
    sysLabel->align(Fl_Align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT));

    // Sys設定 sysInput
    sysInput = new Fl_Input(573, 15, 370, 30);
    sysInput->textsize(12);

    // JSON jsonLabel
    Fl_Box* jsonLabel = new Fl_Box(507,62,44,16,"JSON");
    jsonLabel->labelsize(16);
    jsonLabel->labelcolor(fl_rgb_color(62,66,60));
    jsonLabel->align(Fl_Align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT));

    // JSON jsonInput
    jsonInput = new Fl_Input(573, 55, 335, 30);
    jsonInput->textsize(12);

    // jsonBtn
    Fl_Button* jsonBtn = new Fl_Button(913,60,30,20,"...");
    jsonBtn->color(fl_rgb_color(112,128,144));
    jsonBtn->labelcolor(fl_rgb_color(208,207,207));
    jsonBtn->labelsize(16);
    // jsonBtn->callback(sendCB);

    // Browser
    browser = new Fl_Browser(493, 100, 450, 532);
    browser->textsize(12);
    browser->type(FL_HOLD_BROWSER);

    window->end();  
   	window->show(argc, argv);

   	return Fl::run();
}

[C++] 273 FLTK : ChatGPTアプリの製作 その2 質問を積み上げていく

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

ChatGPT APIでは質問と回答をJSON形式データに追加していき、stringとして送信します。ソースコードなどを送受信しても問題がないよう質問と回答内のダブルクォートや改行文字をエスケープするようにしています。

roleをsystemにして”あなたは熟練のプログラマです”などとキャラ付けも可能です。

色々とややこしすぎて疲れました。ここまで出来たら後はのんびり進めていきます。

#include <ChatGPT.h>

using json = nlohmann::json;

extern json jsonData;

int count;
string requestData;

// Utility function to write response data to a string
size_t writeCallback(char* buf, size_t size, size_t nmemb, void* up) {
    // Append the response data to the string
    ((string*)up)->append((char*)buf, size * nmemb);
    return size * nmemb;
}

// json chatWithOpenAI(const string& question) {
json chatWithOpenAI(string question) {
    
    // Set up the request parameters
    string url = "https://api.openai.com/v1/chat/completions";

    const char* apiKey;
    apiKey = getenv("CHATGPT_API_KEY");

    if (apiKey == NULL) {
        // appファイルは環境変数を取得できない
        apiKey = "APIキー";
    }

    cout << "apiKey: " << apiKey << endl;
    string authHeader = "Authorization: Bearer " + string(apiKey);
    curl_slist* headers = {};
    headers = curl_slist_append(headers, authHeader.c_str());
    headers = curl_slist_append(headers, "Content-Type: application/json");

    size_t pos = 0;
    while ((pos = question.find('"', pos)) != string::npos) {
        question.replace(pos, 1, "\\\"");
        pos += 2;
    }

    pos = 0;
    while ((pos = question.find('\n', pos)) != string::npos) {
        question.replace(pos, 1, "\\n");
        pos += 2;
    }

    if (count == 0){
        requestData = R"({"model":"gpt-3.5-turbo", "messages":[{"role":"user","content":")" + question + R"("}], "temperature":0.0})";
        cout << "requestData: " << requestData << endl;
        count++;
    } else {
        question = R"({"role":"user","content":")" + question + R"("})";
        json questionJson = json::parse(question);
        jsonData["messages"].push_back(questionJson);
        requestData = jsonData.dump();
        cout << "2回目以降質問追加 jsonData: " << requestData << endl;
    }
    
    string responseData = "";


    // Set up a curl session
    CURL* curl = curl_easy_init();
    if (curl) {
        // Set the request options
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestData.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);

        // Send the request
        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << endl;
        }

        // Clean up
        curl_easy_cleanup(curl);

    } else {
        cerr << "curl_easy_init() failed" << endl;
    }

    // Parse the response data and extract the chat response
    json responseJson = json::parse(responseData);

    return responseJson;
}
回答追加後jsonData: {"messages":[
{"content":"ChatGPTとは","role":"user"},
{"content":"ChatGPTは、人工知能による自然言語処理技術を用いたチャットボットです。
ユーザーがChatGPTに質問や会話をすると、ChatGPTは自然な言葉で返答を行います。
ChatGPTは、様々なトピックに関する知識を持っており、ユーザーが何を求めているかを理解し、
適切な回答を提供することができます。ChatGPTは、オンラインカウンセリングやカスタマーサポート、
教育などの分野で活用されています。","role":"assistant"},
{"content":"どのように模倣するのですか","role":"user"},
{"content":"ChatGPTは、自然言語処理技術を用いて、人間が話す言葉を理解し、
それに適切な返答を生成することができます。ChatGPTは、大量のテキストデータを学習し、
その中からパターンを抽出して、自然な言葉での返答を生成することができます。
ChatGPTは、深層学習アルゴリズムを使用して、自己学習を行い、より正確な返答を生成するように改善されます。
ChatGPTは、人間の言語を模倣するために、自然言語処理技術と機械学習技術を組み合わせて使用しています。","role":"assistant"},
{"content":"どのようなプログラムですか","role":"user"},
{"content":"ChatGPTは、自然言語処理技術を用いたチャットボットのプログラムです。
ChatGPTは、Pythonプログラミング言語を使用して開発されており、深層学習ライブラリであるPyTorchを
使用しています。
ChatGPTは、大量のテキストデータを学習するために、トランスフォーマーと呼ばれる
ニューラルネットワークモデルを使用しています。ChatGPTは、オープンソースであり、
誰でも自由に使用することができます。
ChatGPTは、自然言語処理技術を用いたチャットボットのプログラムとして、オンラインカウンセリングや
カスタマーサポート、教育などの分野で活用されています。","role":"assistant"}],
"model":"gpt-3.5-turbo","temperature":0.0}

[C++] 272 FLTK : ChatGPTアプリの製作 その1 ChatGPT API

[M1 Mac, Monterey 12.6.3, clang 13.0.0, FLTK 1.3.8, ChatGPT Plus, NO IDE]

FLTKでChatGPTアプリを製作します。あくまで私個人用です。

とりあえずたたき台を作成しました。返信されたJSONをそのまま表示しています。

#include <FLstd.h>
#include <cppstd.h>
#include <ChatGPT.h>

Fl_Input* input;
Fl_Text_Display* output;

void sendCB(Fl_Widget*, void*) {
	const char* question0 = input->value();
	string question = string(question0);
	json response = chatWithOpenAI(question);
	string resDump = response.dump();
	cout << resDump << endl;

	Fl_Text_Buffer *buffer = new Fl_Text_Buffer();
	buffer -> text(resDump.c_str());

	output -> buffer(buffer);
	output -> wrap_mode(Fl_Text_Display::WRAP_AT_BOUNDS, 5);
}

int main(int argc, char **argv) {
	Fl_Window* window = new Fl_Window (100, 100, 960, 640, "ChatGPT");
	window->color(fl_rgb_color(208,207,207));
	 
	// Question label
	Fl_Box* inputLabel = new Fl_Box(14,22,26,23,"Q");
	inputLabel->labelsize(18);
	inputLabel->labelcolor(fl_rgb_color(62,66,60));
	inputLabel->align(Fl_Align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT));

	// Question input
	input = new Fl_Input(47,18,360,30,"");
	input->textsize(12);
    	
	// sendBtn
	Fl_Button* sendBtn = new Fl_Button(420,13,60,40,"送信");
	sendBtn->color(fl_rgb_color(112,128,144));
	sendBtn->labelcolor(fl_rgb_color(208,207,207));
	sendBtn->labelsize(16);
	sendBtn->callback(sendCB);

	// Response
	output = new Fl_Text_Display(30,70,448,552,"Response");
	output->labelcolor(fl_rgb_color(62,66,60));
	output->textsize(12);
	output->align(Fl_Align(FL_ALIGN_TOP_RIGHT));
	output->labelsize(10);

	window->end();  
	window->show(argc, argv);

	return Fl::run();
}