注意
此仓库是 StanfordBDHG 对 MacPaw OpenAI 项目的一个分支,增加了对以下内容的支持:
此仓库包含 Swift 社区维护的对 OpenAI 公共 API 的实现。
OpenAI 是一家于 2015 年在加利福尼亚州旧金山成立的非营利人工智能研究组织。它的创建目的是以造福全人类和促进社会进步的方式推进数字智能。该组织努力开发能够自主思考、行动和快速适应的人工智能 (AI) 程序和系统。 OpenAI 的使命是确保安全和负责任地使用人工智能来实现公民利益、经济增长和其他公共利益;这包括对通用人工智能安全、自然语言处理、应用强化学习方法、机器视觉算法等重要课题的前沿研究。
OpenAI API 几乎可以应用于任何涉及理解或生成自然语言或代码的任务。我们提供了一系列具有不同功率级别的模型,适用于不同的任务,以及微调您自己的自定义模型的能力。这些模型可用于从内容生成到语义搜索和分类的所有内容。
OpenAI 可通过 Swift Package Manager 获得。 Swift Package Manager 是一种用于自动分发 Swift 代码的工具,并已集成到 swift 编译器中。设置好 Swift 包后,将 OpenAI 作为依赖项添加到 Package.swift 的 dependencies 值中即可。
dependencies: [
.package(url: "https://github.com/MacPaw/OpenAI.git", branch: "main")
]
要初始化 API 实例,您需要从您的 Open AI 组织获取 API 令牌。
请记住,您的 API 密钥是秘密! 不要与他人分享或在任何客户端代码(浏览器、应用程序)中暴露它。生产请求必须通过您自己的后端服务器进行路由,您的 API 密钥可以安全地从环境变量或密钥管理服务中加载。
获得令牌后,您可以初始化 OpenAI
类,它是 API 的入口点。
⚠️ OpenAI 强烈建议客户端应用程序的开发人员通过单独的后端服务代理请求,以确保 API 密钥的安全。 API 密钥可以访问和操纵客户计费、使用情况和组织数据,因此暴露它们存在重大风险。
let openAI = OpenAI(apiToken: "YOUR_TOKEN_HERE")
可以选择使用令牌、组织标识符和 timeoutInterval 初始化 OpenAI
。
let configuration = OpenAI.Configuration(token: "YOUR_TOKEN_HERE", organizationIdentifier: "YOUR_ORGANIZATION_ID_HERE", timeoutInterval: 60.0)
let openAI = OpenAI(configuration: configuration)
拥有令牌并且实例初始化后,您就可以发出请求了。
给定提示,模型将返回一个或多个预测的补全,并且还可以返回每个位置的替代令牌的概率。
请求
struct CompletionsQuery: Codable {
/// ID of the model to use.
public let model: Model
/// The prompt(s) to generate completions for, encoded as a string, array of strings, array of tokens, or array of token arrays.
public let prompt: String
/// What sampling temperature to use. Higher values means the model will take more risks. Try 0.9 for more creative applications, and 0 (argmax sampling) for ones with a well-defined answer.
public let temperature: Double?
/// The maximum number of tokens to generate in the completion.
public let maxTokens: Int?
/// An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.
public let topP: Double?
/// Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim.
public let frequencyPenalty: Double?
/// Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics.
public let presencePenalty: Double?
/// Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence.
public let stop: [String]?
/// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse.
public let user: String?
}
响应
struct CompletionsResult: Codable, Equatable {
public struct Choice: Codable, Equatable {
public let text: String
public let index: Int
}
public let id: String
public let object: String
public let created: TimeInterval
public let model: Model
public let choices: [Choice]
public let usage: Usage
}
示例
let query = CompletionsQuery(model: .textDavinci_003, prompt: "What is 42?", temperature: 0, maxTokens: 100, topP: 1, frequencyPenalty: 0, presencePenalty: 0, stop: ["\\n"])
openAI.completions(query: query) { result in
//Handle result here
}
//or
let result = try await openAI.completions(query: query)
(lldb) po result
▿ CompletionsResult
- id : "cmpl-6P9be2p2fQlwB7zTOl0NxCOetGmX3"
- object : "text_completion"
- created : 1671453146.0
- model : OpenAI.Model.textDavinci_003
▿ choices : 1 element
▿ 0 : Choice
- text : "\n\n42 is the answer to the ultimate question of life, the universe, and everything, according to the book The Hitchhiker\'s Guide to the Galaxy."
- index : 0
可以通过使用 completionsStream
函数进行补全流式传输。 令牌将逐个发送。
闭包
openAI.completionsStream(query: query) { partialResult in
switch partialResult {
case .success(let result):
print(result.choices)
case .failure(let error):
//Handle chunk error here
}
} completion: { error in
//Handle streaming error here
}
Combine
openAI
.completionsStream(query: query)
.sink { completion in
//Handle completion result here
} receiveValue: { result in
//Handle chunk here
}.store(in: &cancellables)
结构化并发
for try await result in openAI.completionsStream(query: query) {
//Handle result here
}
有关更多信息,请查看 补全文档。
使用 OpenAI Chat API,您可以构建自己的应用程序,使用 gpt-3.5-turbo
来执行以下操作:
请求
struct ChatQuery: Codable {
/// ID of the model to use. Currently, only gpt-3.5-turbo and gpt-3.5-turbo-0301 are supported.
public let model: Model
/// The messages to generate chat completions for
public let messages: [Chat]
/// A list of functions the model may generate JSON inputs for.
public let functions: [ChatFunctionDeclaration]?
/// What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and We generally recommend altering this or top_p but not both.
public let temperature: Double?
/// An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.
public let topP: Double?
/// How many chat completion choices to generate for each input message.
public let n: Int?
/// Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence.
public let stop: [String]?
/// The maximum number of tokens to generate in the completion.
public let maxTokens: Int?
/// Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics.
public let presencePenalty: Double?
/// Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim.
public let frequencyPenalty: Double?
///Modify the likelihood of specified tokens appearing in the completion.
public let logitBias: [String:Int]?
/// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse.
public let user: String?
}
响应
struct ChatResult: Codable, Equatable {
public struct Choice: Codable, Equatable {
public let index: Int
public let message: Chat
public let finishReason: String
}
public struct Usage: Codable, Equatable {
public let promptTokens: Int
public let completionTokens: Int
public let totalTokens: Int
}
public let id: String
public let object: String
public let created: TimeInterval
public let model: Model
public let choices: [Choice]
public let usage: Usage
}
示例
let query = ChatQuery(model: .gpt3_5Turbo, messages: [.init(role: .user, content: "who are you")])
let result = try await openAI.chats(query: query)
(lldb) po result
▿ ChatResult
- id : "chatcmpl-6pwjgxGV2iPP4QGdyOLXnTY0LE3F8"
- object : "chat.completion"
- created : 1677838528.0
- model : "gpt-3.5-turbo-0301"
▿ choices : 1 element
▿ 0 : Choice
- index : 0
▿ message : Chat
- role : "assistant"
- content : "\n\nI\'m an AI language model developed by OpenAI, created to provide assistance and support for various tasks such as answering questions, generating text, and providing recommendations. Nice to meet you!"
- finish_reason : "stop"
▿ usage : Usage
- prompt_tokens : 10
- completion_tokens : 39
- total_tokens : 49
可以通过使用 chatStream
函数进行聊天流式传输。 令牌将逐个发送。
闭包
openAI.chatsStream(query: query) { partialResult in
switch partialResult {
case .success(let result):
print(result.choices)
case .failure(let error):
//Handle chunk error here
}
} completion: { error in
//Handle streaming error here
}
Combine
openAI
.chatsStream(query: query)
.sink { completion in
//Handle completion result here
} receiveValue: { result in
//Handle chunk here
}.store(in: &cancellables)
结构化并发
for try await result in openAI.chatsStream(query: query) {
//Handle result here
}
函数调用
let openAI = OpenAI(apiToken: "...")
// Declare functions which GPT-3 might decide to call.
let functions = [
ChatFunctionDeclaration(
name: "get_current_weather",
description: "Get the current weather in a given location",
parameters:
JSONSchema(
type: .object,
properties: [
"location": .init(type: .string, description: "The city and state, e.g. San Francisco, CA"),
"unit": .init(type: .string, enumValues: ["celsius", "fahrenheit"])
],
required: ["location"]
)
)
]
let query = ChatQuery(
model: "gpt-3.5-turbo-0613", // 0613 is the earliest version with function calls support.
messages: [
Chat(role: .user, content: "What's the weather like in Boston?")
],
functions: functions
)
let result = try await openAI.chats(query: query)
结果将是(此处为了便于阅读而序列化为 JSON)
{
"id": "chatcmpl-1234",
"object": "chat.completion",
"created": 1686000000,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"function_call": {
"name": "get_current_weather",
"arguments": "{\n \"location\": \"Boston, MA\"\n}"
}
},
"finish_reason": "function_call"
}
],
"usage": { "total_tokens": 100, "completion_tokens": 18, "prompt_tokens": 82 }
}
有关更多信息,请查看 聊天文档。
给定提示和/或输入图像,模型将生成新图像。
随着人工智能的不断发展,Dall-E 的有趣概念也在不断发展。 Dall-E 由人工智能研究实验室 OpenAI 开发,已被归类为一种人工智能系统,可以根据人类提供的描述生成图像。凭借其从动画和插图到设计和工程的潜在应用 - 更不用说两者之间无限的可能性 - 很容易理解为什么人们对这项新技术如此兴奋。
请求
struct ImagesQuery: Codable {
/// A text description of the desired image(s). The maximum length is 1000 characters.
public let prompt: String
/// The number of images to generate. Must be between 1 and 10.
public let n: Int?
/// The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024.
public let size: String?
}
响应
struct ImagesResult: Codable, Equatable {
public struct URLResult: Codable, Equatable {
public let url: String
}
public let created: TimeInterval
public let data: [URLResult]
}
示例
let query = ImagesQuery(prompt: "White cat with heterochromia sitting on the kitchen table", n: 1, size: "1024x1024")
openAI.images(query: query) { result in
//Handle result here
}
//or
let result = try await openAI.images(query: query)
(lldb) po result
▿ ImagesResult
- created : 1671453505.0
▿ data : 1 element
▿ 0 : URLResult
- url : "https://oaidalleapiprodscus.blob.core.windows.net/private/org-CWjU5cDIzgCcVjq10pp5yX5Q/user-GoBXgChvLBqLHdBiMJBUbPqF/img-WZVUK2dOD4HKbKwW1NeMJHBd.png?st=2022-12-19T11%3A38%3A25Z&se=2022-12-19T13%3A38%3A25Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-12-19T09%3A35%3A16Z&ske=2022-12-20T09%3A35%3A16Z&sks=b&skv=2021-08-06&sig=mh52rmtbQ8CXArv5bMaU6lhgZHFBZz/ePr4y%2BJwLKOc%3D"
生成的图像
给定原始图像和提示,创建编辑或扩展的图像。
请求
public struct ImageEditsQuery: Codable {
/// The image to edit. Must be a valid PNG file, less than 4MB, and square. If mask is not provided, image must have transparency, which will be used as the mask.
public let image: Data
public let fileName: String
/// An additional image whose fully transparent areas (e.g. where alpha is zero) indicate where image should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions as image.
public let mask: Data?
public let maskFileName: String?
/// A text description of the desired image(s). The maximum length is 1000 characters.
public let prompt: String
/// The number of images to generate. Must be between 1 and 10.
public let n: Int?
/// The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024.
public let size: String?
}
响应
以与 ImagesQuery 类似的方式使用 ImagesResult 响应。
示例
let data = image.pngData()
let query = ImageEditQuery(image: data, fileName: "whitecat.png", prompt: "White cat with heterochromia sitting on the kitchen table with a bowl of food", n: 1, size: "1024x1024")
openAI.imageEdits(query: query) { result in
//Handle result here
}
//or
let result = try await openAI.imageEdits(query: query)
创建给定图像的变体。
请求
public struct ImageVariationsQuery: Codable {
/// The image to edit. Must be a valid PNG file, less than 4MB, and square. If mask is not provided, image must have transparency, which will be used as the mask.
public let image: Data
public let fileName: String
/// The number of images to generate. Must be between 1 and 10.
public let n: Int?
/// The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024.
public let size: String?
}
响应
以与 ImagesQuery 类似的方式使用 ImagesResult 响应。
示例
let data = image.pngData()
let query = ImageVariationQuery(image: data, fileName: "whitecat.png", n: 1, size: "1024x1024")
openAI.imageVariations(query: query) { result in
//Handle result here
}
//or
let result = try await openAI.imageVariations(query: query)
有关更多信息,请查看 图像文档。
语音到文本 API 提供了两个端点,转录和翻译,基于我们最先进的开源 large-v2 Whisper 模型。 它们可用于
将音频转录为音频所使用的任何语言。 将音频翻译并转录为英语。 文件上传目前限制为 25 MB,并支持以下输入文件类型:mp3、mp4、mpeg、mpga、m4a、wav 和 webm。
此函数将 AudioSpeechQuery
发送到 OpenAI API,以使用特定的声音和格式从文本创建音频语音。
请求
public struct AudioSpeechQuery: Codable, Equatable {
//...
public let model: Model // tts-1 or tts-1-hd
public let input: String
public let voice: AudioSpeechVoice
public let responseFormat: AudioSpeechResponseFormat
public let speed: String? // Initializes with Double?
//...
}
响应
/// Audio data for one of the following formats :`mp3`, `opus`, `aac`, `flac`
public let audioData: Data?
示例
let query = AudioSpeechQuery(model: .tts_1, input: "Hello, world!", voice: .alloy, responseFormat: .mp3, speed: 1.0)
openAI.audioCreateSpeech(query: query) { result in
// Handle response here
}
//or
let result = try await openAI.audioCreateSpeech(query: query)
将音频转录为输入语言。
请求
public struct AudioTranscriptionQuery: Codable, Equatable {
public let file: Data
public let fileName: String
public let model: Model
public let prompt: String?
public let temperature: Double?
public let language: String?
}
响应
public struct AudioTranscriptionResult: Codable, Equatable {
public let text: String
}
示例
let data = Data(contentsOfURL:...)
let query = AudioTranscriptionQuery(file: data, fileName: "audio.m4a", model: .whisper_1)
openAI.audioTranscriptions(query: query) { result in
//Handle result here
}
//or
let result = try await openAI.audioTranscriptions(query: query)
将音频翻译成英语。
请求
public struct AudioTranslationQuery: Codable, Equatable {
public let file: Data
public let fileName: String
public let model: Model
public let prompt: String?
public let temperature: Double?
}
响应
public struct AudioTranslationResult: Codable, Equatable {
public let text: String
}
示例
let data = Data(contentsOfURL:...)
let query = AudioTranslationQuery(file: data, fileName: "audio.m4a", model: .whisper_1)
openAI.audioTranslations(query: query) { result in
//Handle result here
}
//or
let result = try await openAI.audioTranslations(query: query)
有关更多信息,请查看 音频文档。
为提供的输入、指令和参数创建新的编辑。
请求
struct EditsQuery: Codable {
/// ID of the model to use.
public let model: Model
/// Input text to get embeddings for.
public let input: String?
/// The instruction that tells the model how to edit the prompt.
public let instruction: String
/// The number of images to generate. Must be between 1 and 10.
public let n: Int?
/// What sampling temperature to use. Higher values means the model will take more risks. Try 0.9 for more creative applications, and 0 (argmax sampling) for ones with a well-defined answer.
public let temperature: Double?
/// An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.
public let topP: Double?
}
响应
struct EditsResult: Codable, Equatable {
public struct Choice: Codable, Equatable {
public let text: String
public let index: Int
}
public struct Usage: Codable, Equatable {
public let promptTokens: Int
public let completionTokens: Int
public let totalTokens: Int
enum CodingKeys: String, CodingKey {
case promptTokens = "prompt_tokens"
case completionTokens = "completion_tokens"
case totalTokens = "total_tokens"
}
}
public let object: String
public let created: TimeInterval
public let choices: [Choice]
public let usage: Usage
}
示例
let query = EditsQuery(model: .gpt4, input: "What day of the wek is it?", instruction: "Fix the spelling mistakes")
openAI.edits(query: query) { result in
//Handle response here
}
//or
let result = try await openAI.edits(query: query)
有关更多信息,请查看 编辑文档。
获取给定输入的向量表示,该向量可以很容易地被机器学习模型和算法使用。
请求
struct EmbeddingsQuery: Codable {
/// ID of the model to use.
public let model: Model
/// Input text to get embeddings for
public let input: String
}
响应
struct EmbeddingsResult: Codable, Equatable {
public struct Embedding: Codable, Equatable {
public let object: String
public let embedding: [Double]
public let index: Int
}
public let data: [Embedding]
public let usage: Usage
}
示例
let query = EmbeddingsQuery(model: .textSearchBabbageDoc, input: "The food was delicious and the waiter...")
openAI.embeddings(query: query) { result in
//Handle response here
}
//or
let result = try await openAI.embeddings(query: query)
(lldb) po result
▿ EmbeddingsResult
▿ data : 1 element
▿ 0 : Embedding
- object : "embedding"
▿ embedding : 2048 elements
- 0 : 0.0010535449
- 1 : 0.024234328
- 2 : -0.0084999
- 3 : 0.008647452
.......
- 2044 : 0.017536353
- 2045 : -0.005897616
- 2046 : -0.026559394
- 2047 : -0.016633155
- index : 0
(lldb)
有关更多信息,请查看 嵌入文档。
模型表示为 typealias typealias Model = String
。
public extension Model {
static let gpt4_turbo_preview = "gpt-4-turbo-preview"
static let gpt4_vision_preview = "gpt-4-vision-preview"
static let gpt4_0125_preview = "gpt-4-0125-preview"
static let gpt4_1106_preview = "gpt-4-1106-preview"
static let gpt4 = "gpt-4"
static let gpt4_0613 = "gpt-4-0613"
static let gpt4_0314 = "gpt-4-0314"
static let gpt4_32k = "gpt-4-32k"
static let gpt4_32k_0613 = "gpt-4-32k-0613"
static let gpt4_32k_0314 = "gpt-4-32k-0314"
static let gpt3_5Turbo = "gpt-3.5-turbo"
static let gpt3_5Turbo_0125 = "gpt-3.5-turbo-0125"
static let gpt3_5Turbo_1106 = "gpt-3.5-turbo-1106"
static let gpt3_5Turbo_0613 = "gpt-3.5-turbo-0613"
static let gpt3_5Turbo_0301 = "gpt-3.5-turbo-0301"
static let gpt3_5Turbo_16k = "gpt-3.5-turbo-16k"
static let gpt3_5Turbo_16k_0613 = "gpt-3.5-turbo-16k-0613"
static let textDavinci_003 = "text-davinci-003"
static let textDavinci_002 = "text-davinci-002"
static let textCurie = "text-curie-001"
static let textBabbage = "text-babbage-001"
static let textAda = "text-ada-001"
static let textDavinci_001 = "text-davinci-001"
static let codeDavinciEdit_001 = "code-davinci-edit-001"
static let tts_1 = "tts-1"
static let tts_1_hd = "tts-1-hd"
static let whisper_1 = "whisper-1"
static let dall_e_2 = "dall-e-2"
static let dall_e_3 = "dall-e-3"
static let davinci = "davinci"
static let curie = "curie"
static let babbage = "babbage"
static let ada = "ada"
static let textEmbeddingAda = "text-embedding-ada-002"
static let textSearchAda = "text-search-ada-doc-001"
static let textSearchBabbageDoc = "text-search-babbage-doc-001"
static let textSearchBabbageQuery001 = "text-search-babbage-query-001"
static let textEmbedding3 = "text-embedding-3-small"
static let textEmbedding3Large = "text-embedding-3-large"
static let textModerationStable = "text-moderation-stable"
static let textModerationLatest = "text-moderation-latest"
static let moderation = "text-moderation-007"
}
支持 GPT-4 模型。
例如:要使用 gpt-4-turbo-preview
模型,请将 .gpt4_turbo_preview
作为参数传递给 ChatQuery
init。
let query = ChatQuery(model: .gpt4_turbo_preview, messages: [
.init(role: .system, content: "You are Librarian-GPT. You know everything about the books."),
.init(role: .user, content: "Who wrote Harry Potter?")
])
let result = try await openAI.chats(query: query)
XCTAssertFalse(result.choices.isEmpty)
如果您需要使用上面未表示的某些模型,您也可以传递自定义字符串。
列出当前可用的模型。
响应
public struct ModelsResult: Codable, Equatable {
public let data: [ModelResult]
public let object: String
}
示例
openAI.models() { result in
//Handle result here
}
//or
let result = try await openAI.models()
检索模型实例,提供所有权信息。
请求
public struct ModelQuery: Codable, Equatable {
public let model: Model
}
响应
public struct ModelResult: Codable, Equatable {
public let id: Model
public let object: String
public let ownedBy: String
}
示例
let query = ModelQuery(model: .gpt4)
openAI.model(query: query) { result in
//Handle result here
}
//or
let result = try await openAI.model(query: query)
有关更多信息,请查看 模型文档。
给定一个输入文本,如果模型将其分类为违反 OpenAI 的内容政策,则输出结果。
请求
public struct ModerationsQuery: Codable {
public let input: String
public let model: Model?
}
响应
public struct ModerationsResult: Codable, Equatable {
public let id: String
public let model: Model
public let results: [CategoryResult]
}
示例
let query = ModerationsQuery(input: "I want to kill them.")
openAI.moderations(query: query) { result in
//Handle result here
}
//or
let result = try await openAI.moderations(query: query)
有关更多信息,请查看 审核文档。
该组件附带几个方便的实用函数来处理向量。
public struct Vector {
/// Returns the similarity between two vectors
///
/// - Parameters:
/// - a: The first vector
/// - b: The second vector
public static func cosineSimilarity(a: [Double], b: [Double]) -> Double {
return dot(a, b) / (mag(a) * mag(b))
}
/// Returns the difference between two vectors. Cosine distance is defined as `1 - cosineSimilarity(a, b)`
///
/// - Parameters:
/// - a: The first vector
/// - b: The second vector
public func cosineDifference(a: [Double], b: [Double]) -> Double {
return 1 - Self.cosineSimilarity(a: a, b: b)
}
}
示例
let vector1 = [0.213123, 0.3214124, 0.421412, 0.3214521251, 0.412412, 0.3214124, 0.1414124, 0.3214521251, 0.213123, 0.3214124, 0.1414124, 0.4214214, 0.213123, 0.3214124, 0.1414124, 0.3214521251, 0.213123, 0.3214124, 0.1414124, 0.3214521251]
let vector2 = [0.213123, 0.3214124, 0.1414124, 0.3214521251, 0.213123, 0.3214124, 0.1414124, 0.3214521251, 0.213123, 0.511515, 0.1414124, 0.3214521251, 0.213123, 0.3214124, 0.1414124, 0.3214521251, 0.213123, 0.3214124, 0.1414124, 0.3213213]
let similarity = Vector.cosineSimilarity(a: vector1, b: vector2)
print(similarity) //0.9510201910206734
在数据分析中,余弦相似度是两个数字序列之间相似性的度量。
在此处阅读有关余弦相似性的更多信息:here.
该库包含内置的 Combine 扩展。
func completions(query: CompletionsQuery) -> AnyPublisher<CompletionsResult, Error>
func images(query: ImagesQuery) -> AnyPublisher<ImagesResult, Error>
func embeddings(query: EmbeddingsQuery) -> AnyPublisher<EmbeddingsResult, Error>
func chats(query: ChatQuery) -> AnyPublisher<ChatResult, Error>
func edits(query: EditsQuery) -> AnyPublisher<EditsResult, Error>
func model(query: ModelQuery) -> AnyPublisher<ModelResult, Error>
func models() -> AnyPublisher<ModelsResult, Error>
func moderations(query: ModerationsQuery) -> AnyPublisher<ModerationsResult, Error>
func audioTranscriptions(query: AudioTranscriptionQuery) -> AnyPublisher<AudioTranscriptionResult, Error>
func audioTranslations(query: AudioTranslationQuery) -> AnyPublisher<AudioTranslationResult, Error>
您可以在 Demo 文件夹中找到示例 iOS 应用程序。
使您的 Pull Requests 对任何查看它们的人来说都是清晰和明显的。
将 main
设置为您的目标分支。
Feat: ...
用于新特性和新功能实现。Bug: ...
用于错误修复。Fix: ...
用于修复小问题,例如代码中的拼写错误或不准确之处。Chore: ...
用于无聊的事情,例如代码润色、重构、修复弃用等。PR 命名示例:Feat: Add Threads API handling
或 Bug: Fix message result duplication
分支命名示例:feat/add-threads-API-handling
或 bug/fix-message-result-duplication
什么
...
为什么
...
受影响的区域
...
更多信息
...
如果需要和可能,我们将感谢您在代码中包含测试。❤️
MIT License
Copyright (c) 2023 MacPaw Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.