How to properly create "messages" in JSON for OpenAI API in QT
-
wrote on 20 Apr 2024, 19:44 last edited by
The "messages" in OpenAI Chat completion requires it to have a format (order does not matter) as such { "messages" : [{"role": "user", "content": "Hello"}], "model" : "gpt-3.5-turbo" }
My challenge is how to properly create them using QJsonObject, QJsonArray in QT. The "brute force" by forcing putting QString with an escape "" in front of appropriate " works but it is ugly and hard to extend (after all the text part of Chat is dynamic).
Here is the code snippet. Test1 fails and Test2 (Brute force succeeds). In between the 2 tests, I have tried numerous QJSonObject, QJsonArrays combinations but to no avail. There has to be an elegant solution to this. Appreciate for your help.
void MainWindow::test6()
{
QString str1 = "[{"role": "user", "content": "Hello"}]";/* * First Test */ QJsonObject obj; obj["model"] = "gpt-3.5-turbo"; obj["messages"] = str1; QJsonDocument doc(obj); QByteArray postData; postData = doc.toJson(); qDebug().noquote() << postData; /* * Result is wrong - has escape \" instead of " * inside : { "messages": "[{\"role\": \"user\", \"content\": \"Hello\"}]", "model": "gpt-3.5-turbo" } */ /* * Test2 */ QString str2 = "{ \"messages\" : [{\"role\": \"user\", \"content\": \"Hello\"}], \"model\" : \"gpt-3.5-turbo\"}"; postData = str2.toUtf8(); qDebug().noquote() << postData; /* * Result is correct { "messages" : [{"role": "user", "content": "Hello"}], "model" : "gpt-3.5-turbo"} */
}
By the way, I do know about qDebug().noquote() but this is not about display. This is about how to put into QByteArray a string which does not contain escape . Only without that when set via QNetWorkAccessManager post will work with OpenAI API
Thanks
-
The "messages" in OpenAI Chat completion requires it to have a format (order does not matter) as such { "messages" : [{"role": "user", "content": "Hello"}], "model" : "gpt-3.5-turbo" }
My challenge is how to properly create them using QJsonObject, QJsonArray in QT. The "brute force" by forcing putting QString with an escape "" in front of appropriate " works but it is ugly and hard to extend (after all the text part of Chat is dynamic).
Here is the code snippet. Test1 fails and Test2 (Brute force succeeds). In between the 2 tests, I have tried numerous QJSonObject, QJsonArrays combinations but to no avail. There has to be an elegant solution to this. Appreciate for your help.
void MainWindow::test6()
{
QString str1 = "[{"role": "user", "content": "Hello"}]";/* * First Test */ QJsonObject obj; obj["model"] = "gpt-3.5-turbo"; obj["messages"] = str1; QJsonDocument doc(obj); QByteArray postData; postData = doc.toJson(); qDebug().noquote() << postData; /* * Result is wrong - has escape \" instead of " * inside : { "messages": "[{\"role\": \"user\", \"content\": \"Hello\"}]", "model": "gpt-3.5-turbo" } */ /* * Test2 */ QString str2 = "{ \"messages\" : [{\"role\": \"user\", \"content\": \"Hello\"}], \"model\" : \"gpt-3.5-turbo\"}"; postData = str2.toUtf8(); qDebug().noquote() << postData; /* * Result is correct { "messages" : [{"role": "user", "content": "Hello"}], "model" : "gpt-3.5-turbo"} */
}
By the way, I do know about qDebug().noquote() but this is not about display. This is about how to put into QByteArray a string which does not contain escape . Only without that when set via QNetWorkAccessManager post will work with OpenAI API
Thanks
wrote on 20 Apr 2024, 19:57 last edited by mpergand@Sean-Yiu
Try raw strings:
https://en.cppreference.com/w/cpp/language/string_literalAnyway if you do:
QByteArray bytes=str2.toLatin1():
there is no escape \n in the array, because there are just needed for the conversion to C string. -
The "messages" in OpenAI Chat completion requires it to have a format (order does not matter) as such { "messages" : [{"role": "user", "content": "Hello"}], "model" : "gpt-3.5-turbo" }
My challenge is how to properly create them using QJsonObject, QJsonArray in QT. The "brute force" by forcing putting QString with an escape "" in front of appropriate " works but it is ugly and hard to extend (after all the text part of Chat is dynamic).
Here is the code snippet. Test1 fails and Test2 (Brute force succeeds). In between the 2 tests, I have tried numerous QJSonObject, QJsonArrays combinations but to no avail. There has to be an elegant solution to this. Appreciate for your help.
void MainWindow::test6()
{
QString str1 = "[{"role": "user", "content": "Hello"}]";/* * First Test */ QJsonObject obj; obj["model"] = "gpt-3.5-turbo"; obj["messages"] = str1; QJsonDocument doc(obj); QByteArray postData; postData = doc.toJson(); qDebug().noquote() << postData; /* * Result is wrong - has escape \" instead of " * inside : { "messages": "[{\"role\": \"user\", \"content\": \"Hello\"}]", "model": "gpt-3.5-turbo" } */ /* * Test2 */ QString str2 = "{ \"messages\" : [{\"role\": \"user\", \"content\": \"Hello\"}], \"model\" : \"gpt-3.5-turbo\"}"; postData = str2.toUtf8(); qDebug().noquote() << postData; /* * Result is correct { "messages" : [{"role": "user", "content": "Hello"}], "model" : "gpt-3.5-turbo"} */
}
By the way, I do know about qDebug().noquote() but this is not about display. This is about how to put into QByteArray a string which does not contain escape . Only without that when set via QNetWorkAccessManager post will work with OpenAI API
Thanks
wrote on 20 Apr 2024, 20:05 last edited by JonB@Sean-Yiu said in How to properly create "messages" in JSON for OpenAI API in QT:
QString str1 = "[{"role": "user", "content": "Hello"}]" obj["messages"] = str1;
I don't understand why you are treating this as a string. Looking at your
{ "messages" : [{"role": "user", "content": "Hello"}], "model" : "gpt-3.5-turbo" }
It (the value of
messages
) is a JSON array with a single JSON object element. Build your JSON structure correctly (as per whatever the API expects/specifies) and it will come out right for serializing. -
The "messages" in OpenAI Chat completion requires it to have a format (order does not matter) as such { "messages" : [{"role": "user", "content": "Hello"}], "model" : "gpt-3.5-turbo" }
My challenge is how to properly create them using QJsonObject, QJsonArray in QT. The "brute force" by forcing putting QString with an escape "" in front of appropriate " works but it is ugly and hard to extend (after all the text part of Chat is dynamic).
Here is the code snippet. Test1 fails and Test2 (Brute force succeeds). In between the 2 tests, I have tried numerous QJSonObject, QJsonArrays combinations but to no avail. There has to be an elegant solution to this. Appreciate for your help.
void MainWindow::test6()
{
QString str1 = "[{"role": "user", "content": "Hello"}]";/* * First Test */ QJsonObject obj; obj["model"] = "gpt-3.5-turbo"; obj["messages"] = str1; QJsonDocument doc(obj); QByteArray postData; postData = doc.toJson(); qDebug().noquote() << postData; /* * Result is wrong - has escape \" instead of " * inside : { "messages": "[{\"role\": \"user\", \"content\": \"Hello\"}]", "model": "gpt-3.5-turbo" } */ /* * Test2 */ QString str2 = "{ \"messages\" : [{\"role\": \"user\", \"content\": \"Hello\"}], \"model\" : \"gpt-3.5-turbo\"}"; postData = str2.toUtf8(); qDebug().noquote() << postData; /* * Result is correct { "messages" : [{"role": "user", "content": "Hello"}], "model" : "gpt-3.5-turbo"} */
}
By the way, I do know about qDebug().noquote() but this is not about display. This is about how to put into QByteArray a string which does not contain escape . Only without that when set via QNetWorkAccessManager post will work with OpenAI API
Thanks
wrote on 21 Apr 2024, 02:25 last edited by ChrisW67Further to @JonB's comment:
QJsonObject message; message.insert("role", QJsonValue("user")); message.insert("content", QJsonValue("Hello")); QJsonArray messages = QJsonArray(); messages.append(message); QJsonObject mainObj; mainObj.insert("messages", messages); mainObj.insert("model", QJsonValue("gpt-3.5-turbo")); QJsonDocument doc(mainObj); qDebug().noquote() << doc.toJson(QJsonDocument::Compact); // Output {"messages":[{"content":"Hello","role":"user"}],"model":"gpt-3.5-turbo"} ```
-
@Sean-Yiu said in How to properly create "messages" in JSON for OpenAI API in QT:
QString str1 = "[{"role": "user", "content": "Hello"}]" obj["messages"] = str1;
I don't understand why you are treating this as a string. Looking at your
{ "messages" : [{"role": "user", "content": "Hello"}], "model" : "gpt-3.5-turbo" }
It (the value of
messages
) is a JSON array with a single JSON object element. Build your JSON structure correctly (as per whatever the API expects/specifies) and it will come out right for serializing.wrote on 22 Apr 2024, 05:53 last edited by/* * Test3 */ QJsonArray array; QString str3 = "\"role\": \"user\""; QString str4 = "\"content\": \"Hello\""; array = { str3, str4 }; qDebug().noquote() << "str3= " << str3; qDebug().noquote() << "str4= " << str4; QJsonObject obj_new; obj_new["model"] = "gpt-3.5-turbo"; obj_new["messages"] = array; postData = doc.toJson(); qDebug().noquote() << "PostData= " << postData; } Result:
str3= "role": "user" << no problem
str4= "content": "Hello" << no problemPostData= {
"messages": "[{"role": "user", "content": "Hello"}]"
^ ^ ^ ^ ^ ^ << problem
"model": "gpt-3.5-turbo"
}I think what's going is somehow when doc.toJson() interprets a " as " and actually adds the escape in there. Looks like a bug in QT ?
-
/* * Test3 */ QJsonArray array; QString str3 = "\"role\": \"user\""; QString str4 = "\"content\": \"Hello\""; array = { str3, str4 }; qDebug().noquote() << "str3= " << str3; qDebug().noquote() << "str4= " << str4; QJsonObject obj_new; obj_new["model"] = "gpt-3.5-turbo"; obj_new["messages"] = array; postData = doc.toJson(); qDebug().noquote() << "PostData= " << postData; } Result:
str3= "role": "user" << no problem
str4= "content": "Hello" << no problemPostData= {
"messages": "[{"role": "user", "content": "Hello"}]"
^ ^ ^ ^ ^ ^ << problem
"model": "gpt-3.5-turbo"
}I think what's going is somehow when doc.toJson() interprets a " as " and actually adds the escape in there. Looks like a bug in QT ?
@Sean-Yiu said in How to properly create "messages" in JSON for OpenAI API in QT:
. Looks like a bug in QT ?
No. You add two strings to an array so Qt is doing the correct thing here. If you want to add a jsonvalue then add a QJsonValue and not strings.
-
@Sean-Yiu
Try raw strings:
https://en.cppreference.com/w/cpp/language/string_literalAnyway if you do:
QByteArray bytes=str2.toLatin1():
there is no escape \n in the array, because there are just needed for the conversion to C string. -
@mpergand
Dont think that's the problem. Please look at my Test3 example I just entered. it shows the doc.toJson adds an escape | in there@Sean-Yiu said in How to properly create "messages" in JSON for OpenAI API in QT:
t shows the doc.toJson adds an escape | in there
Which is correct as the you add strings containing " so they must be escaped.
-
/* * Test3 */ QJsonArray array; QString str3 = "\"role\": \"user\""; QString str4 = "\"content\": \"Hello\""; array = { str3, str4 }; qDebug().noquote() << "str3= " << str3; qDebug().noquote() << "str4= " << str4; QJsonObject obj_new; obj_new["model"] = "gpt-3.5-turbo"; obj_new["messages"] = array; postData = doc.toJson(); qDebug().noquote() << "PostData= " << postData; } Result:
str3= "role": "user" << no problem
str4= "content": "Hello" << no problemPostData= {
"messages": "[{"role": "user", "content": "Hello"}]"
^ ^ ^ ^ ^ ^ << problem
"model": "gpt-3.5-turbo"
}I think what's going is somehow when doc.toJson() interprets a " as " and actually adds the escape in there. Looks like a bug in QT ?
wrote on 22 Apr 2024, 07:15 last edited by@Sean-Yiu said in How to properly create "messages" in JSON for OpenAI API in QT:
QJsonArray array; QString str3 = "\"role\": \"user\""; QString str4 = "\"content\": \"Hello\""; array = { str3, str4 };
I really don't know what you are doing here. Again, what are you doing creating any string like
"\"role\": \"user\""
? In the original you have:[{"role": "user", "content": "Hello"}]
That is an array containing a single JSON object, which has two string keys, each of which has a string value. You already have such a construct,
"model" : "gpt-3.5-turbo"
, these must all be handled properly and the same way.Seems to me @ChrisW67 already wrote the correct code for this for you, so why did you deviate from that anyway?
-
@Sean-Yiu said in How to properly create "messages" in JSON for OpenAI API in QT:
. Looks like a bug in QT ?
No. You add two strings to an array so Qt is doing the correct thing here. If you want to add a jsonvalue then add a QJsonValue and not strings.
wrote on 22 Apr 2024, 07:40 last edited by@Christian-Ehrlicher
/*
* Test3
*/
QJsonArray array;
QString str3 = ""role": "user"";
QString str4 = ""content": "Hello"";
array = { QJsonValue(str3), QJsonValue(str4) };//qDebug().noquote() << "str3= " << str3; //qDebug().noquote() << "str4= " << str4; QJsonObject obj_new; obj_new["model"] = "gpt-3.5-turbo"; obj_new["messages"] = array; postData = doc.toJson(); qDebug().noquote() << "PostData= " << postData;
Same problem. in Debug mode, I look inside array and the contents are correct. But side postData, they are not.
-
@Christian-Ehrlicher
/*
* Test3
*/
QJsonArray array;
QString str3 = ""role": "user"";
QString str4 = ""content": "Hello"";
array = { QJsonValue(str3), QJsonValue(str4) };//qDebug().noquote() << "str3= " << str3; //qDebug().noquote() << "str4= " << str4; QJsonObject obj_new; obj_new["model"] = "gpt-3.5-turbo"; obj_new["messages"] = array; postData = doc.toJson(); qDebug().noquote() << "PostData= " << postData;
Same problem. in Debug mode, I look inside array and the contents are correct. But side postData, they are not.
@Sean-Yiu said in How to properly create "messages" in JSON for OpenAI API in QT:
""role": "user"";
This is a a plain string. You have to convert it to a correct JSON key value pair (aka object).
This was told you from three different persons but you ignore it. Do you want help? Then don't ignore what we are telling you. -
@Christian-Ehrlicher
/*
* Test3
*/
QJsonArray array;
QString str3 = ""role": "user"";
QString str4 = ""content": "Hello"";
array = { QJsonValue(str3), QJsonValue(str4) };//qDebug().noquote() << "str3= " << str3; //qDebug().noquote() << "str4= " << str4; QJsonObject obj_new; obj_new["model"] = "gpt-3.5-turbo"; obj_new["messages"] = array; postData = doc.toJson(); qDebug().noquote() << "PostData= " << postData;
Same problem. in Debug mode, I look inside array and the contents are correct. But side postData, they are not.
wrote on 22 Apr 2024, 08:22 last edited by JonB@Sean-Yiu
As @Christian-Ehrlicher has said, and as we keep telling you. What about my:Seems to me @ChrisW67 already wrote the correct code for this for you, so why did you deviate from that anyway?
?
QJsonObject message; message.insert("role", QJsonValue("user")); message.insert("content", QJsonValue("Hello"));
So long as you have any string(s) like
QString str3 = ""role": "user""; QString str4 = ""content": "Hello"";
(with/without any embedded quotes/backslashes) you will not get anywhere.
BTW, when the JSON you want has any unquoted/not inside a literal string:
[
--- you want aQJsonArray
.{
--- you want aQJsonObject
, that will have any number of key-value pairs for each"key" : "string-value"
inside it.
JSON is really very simple.
-
@Christian-Ehrlicher
/*
* Test3
*/
QJsonArray array;
QString str3 = ""role": "user"";
QString str4 = ""content": "Hello"";
array = { QJsonValue(str3), QJsonValue(str4) };//qDebug().noquote() << "str3= " << str3; //qDebug().noquote() << "str4= " << str4; QJsonObject obj_new; obj_new["model"] = "gpt-3.5-turbo"; obj_new["messages"] = array; postData = doc.toJson(); qDebug().noquote() << "PostData= " << postData;
Same problem. in Debug mode, I look inside array and the contents are correct. But side postData, they are not.
wrote on 22 Apr 2024, 08:31 last edited by ChrisW67@Sean-Yiu There is no problem in Qt. Others have explained and I have already shown you how to construct your data structure using the Qt JSON classes.
The part of the data structure that you are so twisted around trying to create is a QJsonArray of message QJsonObjects. Each message object has keys
role
andcontent
with values "user" and "Hello" respectively.{ "messages" : [ <<<< this bit here { "role": "user", "content": "Hello" } ], "model" : "gpt-3.5-turbo" }
What your code does:
QJsonArray array; QString str3 = R"("role": "user")"; QString str4 = R"("content": "Hello")"; array = { str3, str4 }; qDebug().noquote() << "str3= " << str3; qDebug().noquote() << "str4= " << str4; qDebug().noquote() << array; // Ouptut is str3= "role": "user" str4= "content": "Hello" QJsonArray(["\"role\": \"user\"","\"content\": \"Hello\""])
You can see that the input strings are what you asked for. You can also see that the result is a QJsonArray of two strings:
[ "\"role\": \"user\"", <<<< str3 one single string "\"content\": \"Hello\"" <<<< str4another single string ]
As your strings have embedded double quotes that need to be escaped in JSON output.
-
wrote on 1 Jun 2024, 06:08 last edited by
Thanks. I understand better now.