我需要使用OpenAI API,并且在格式化请求时遇到了困难。我首先参考了OpenAI API playground中列出的curl代码,并且在我的终端中运行成功。该请求如下所示:
curl https://api.openai.com/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ "model": "gpt-4o", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Write a haiku about weightlifting" } ] } ], "temperature": 1, "max_tokens": 2048, "top_p": 1, "frequency_penalty": 0, "presence_penalty": 0, "response_format": { "type": "text" }}'
然后,我开始将该请求从curl转换为Swift。我参考了一些YouTube教程,以下是我目前的代码。
let openAiUrl = URL(string: "https://api.openai.com/v1/chat/completions")!var request = URLRequest(url: openAiUrl)request.setValue("application/json", forHTTPHeaderField: "Content-Type")request.addValue("Bearer \(openAiApiKey)", forHTTPHeaderField: "Authorization")request.httpMethod = "POST"let httpBody: [String: Any] = [ "messages" : [ { "role": "user", //Error: consecutive statements on a line must be separated by ';' "content": "Write a haiku about weightlifting" } ], "model": "gpt-4o", "max_tokens" : 100, "temperature": String(temperature), "frequency_penalty": 0, "presence_penalty": 0, "response_format": { //Error: consecutive statements on a line must be separated by ';' "type": "text" }]
我在使用大括号的两行代码上收到了“Consecutive statements on a line must be separated by ‘;‘”的错误提示。
我需要做些什么来格式化API请求?温度变量是一个当前设置为1.0的Double类型。
回答:
尝试使用JSONEncoder
来编码json参数,如下所示:
let body = """{ "messages" : [ { "role": "user", "content": "Write a haiku about weightlifting" } ], "model": "gpt-4o", "max_tokens" : 100, "temperature": 1.0, "frequency_penalty": 0, "presence_penalty": 0, "response_format": { "type": "text" }}""" do { request.httpBody = try JSONEncoder().encode(body) let (responseData, response) = try await URLSession.shared.data(for: request) print("-----> \n \(String(data: responseData, encoding: .utf8) as AnyObject) \n") } catch { print("---> error: \(error)") }
EDIT-1
这是我使用SwiftUI的测试代码。由于我没有密钥,无法完全测试这段代码,但它可以编译并提供一些关于响应的信息。
import SwiftUIstruct ContentView: View { let openAiApiKey = "for testing" var body: some View { Text("testing") .task { await doPost() } } func doPost() async { let openAiUrl = URL(string: "https://api.openai.com/v1/chat/completions")! var request = URLRequest(url: openAiUrl) request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue("Bearer \(openAiApiKey)", forHTTPHeaderField: "Authorization") request.httpMethod = "POST" let body = """{"messages": [{"role": "user","content": "Write a haiku about weightlifting"}],"model": "gpt-4o","max_tokens" : 100,"temperature": 1.0,"frequency_penalty": 0,"presence_penalty": 0,"response_format": { "type": "text"}}""" do { request.httpBody = try JSONEncoder().encode(body) let (responseData, response) = try await URLSession.shared.data(for: request) print("-----> responseData \n \(String(data: responseData, encoding: .utf8) as AnyObject) \n") } catch { print(error) } }}
EDIT-2
另一个替代方案,
struct ContentView: View { let openAiApiKey = "for testing" var body: some View { Text("testing") .task { let url = URL(string: "https://api.openai.com/v1/chat/completions")! var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue("Bearer \(openAiApiKey)", forHTTPHeaderField: "Authorization") let requestBody: [String: Any] = [ "model": "gpt-4o", "messages": [ [ "role": "user", "content": [ [ "type": "text", "text": "Write a haiku about weightlifting" ] ] ] ], "temperature": 1, "max_tokens": 2048, "top_p": 1, "frequency_penalty": 0, "presence_penalty": 0, "response_format": [ "type": "text" ] ] do { request.httpBody = try JSONSerialization.data(withJSONObject: requestBody) let (responseData, response) = try await URLSession.shared.data(for: request) print("-----> responseData \n \(String(data: responseData, encoding: .utf8) as AnyObject) \n") } catch { print(error) } } }}