我正在从客户端接收代表 ChatGPT API 请求中的函数的数据,可在此处查看:https://platform.openai.com/docs/api-reference/chat/create。
我希望接收到的 JSON 由 Newtonsoft.Json 进行解析,然后在 JSON 解析期间进行 JSchema 解析,但似乎 JSchema 解析可能发生在正常的 JSON 解析之前,并且我的
[JsonIgnore]
具有讽刺意味的是,属性被 JSchema 解析忽略。
这是我的主要问题:
json1
会导致错误?ParametersJson
的类型是字符串时,为什么 JSchema 解析器需要一个对象或布尔值?json1
中那样对 JSON 进行编码,并按照我期望的方式将其全部反序列化,而不会出现错误?我想在客户端将 JSON 模式保留为字符串。这是错误:
未处理的异常。 Newtonsoft.Json.Schema.JSchemaReaderException:读取架构时遇到意外标记。预期 StartObject,布尔值,得到字符串。路径“参数”,第 7 行,位置 9。 在 Newtonsoft.Json.Schema.Infrastruct.JSchemaReader.EnsureToken(JsonReader reader,字符串名称,List`1 tokenTypes,字符串 errorMessage)
这是 .NET Fiddle:https://dotnetfiddle.net/GE8OMP
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Schema;
public class Program
{
public static void Main()
{
string json0 = @"
{
'Name': 'TestFunction',
'Description': 'This is a test function.',
'parameters':
{
'type': 'object',
'properties':
{
'prop1':
{
'type': 'string'
}
}
}
}".Replace("'", "\"");
string json1 = @"
{
'Name': 'TestFunction',
'Description': 'This is a test function.',
'parameters':
'{
'type': 'object',
'properties':
{
'prop1':
{
'type': 'string'
}
}
}'
}".Replace("'", "\"");
var arr = new[]{json0, json1};
foreach (var json in arr)
{
Function deserializedFunction = JsonConvert.DeserializeObject<Function>(json);
Console.WriteLine($"Name: {deserializedFunction.Name}");
Console.WriteLine($"Description: {deserializedFunction.Description}");
Console.WriteLine($"Parameters: {deserializedFunction.Parameters}");
Console.WriteLine("-------------");
}
}
}
#nullable enable
public class Function
{
/// <summary>
/// The name of the function to be called. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.
/// </summary>
public string Name { get; set; }
/// <summary>
/// A description of what the function does, used by the model to choose when and how to call the function.
/// </summary>
public string? Description { get; set; }
/// <summary>
/// The parameters the functions accepts, described as a JSON Schema object.
/// <br></br>
/// <br></br>
/// To describe a function that accepts no parameters, provide the value {"type": "object", "properties": { } }.
/// </summary>
// Need to convert from string coming from client to the JSchema object.
[JsonIgnore]
public JSchema Parameters { get; set; }
[JsonProperty("parameters")]
public string ParametersJson { get => Parameters.ToString(); set => Parameters = JSchema.Parse(value); }
public Function(string name, string? description, JSchema parameters)
{
Name = name;
Description = description;
Parameters = parameters;
}
}
第一件事是你的第二个 JSON 无效:
parameters
值中的引号需要转义(\"
)。
JSON 中字符串值不能有多行。
正确的 JSON 应该是:
{
"Name": "TestFunction",
"Description": "This is a test function.",
"parameters": "{\"type\": \"object\", \"properties\": {\"prop1\": {\"type\": \"string\"}}}"
}
假设您已经修复了 JSON 问题,对于构造函数,您应该处理具有多种类型的
parameters
:
在构造函数中将
parameters
类型更改为JToken
,以允许值有多种类型。
处理不同
parameters.Type
的JTokenType
(String
,Object
)。
public Function(string name, string? description, JToken parameters)
{
Name = name;
Description = description;
if (parameters.Type == JTokenType.String)
{
Parameters = JSchema.Parse(parameters.ToString());
}
else if (parameters.Type == JTokenType.Object)
{
Parameters = parameters.ToObject<JSchema>();
}
}
注意处理不同
if-else
的JTokenType
语句也可以简化为:
Parameters = JSchema.Parse(parameters.ToString());
恕我直言,你需要修复 json1
string json1 = @"
{
'Name': 'TestFunction',
'Description': 'This is a test function.',
'parameters':
'{
'type': 'object',
'properties':
{
'prop1':
{
'type': 'string'
}
}
}'
}".Replace("'{", "{").Replace("}'", "}").Replace("'", "\"");