Gunakan API Openai dengan Ruby! ? ❤️
Streaming teks dengan GPT-4O, menyalin dan menerjemahkan audio dengan bisikan, atau membuat gambar dengan dall · e ...
Pekerjakan saya untuk membangun rel rel+ai Anda | Rails ai | ? Ruby AI Builders Discord | ? X | ? Permata Antropik | ? Permata Midjourney
Tambahkan baris ini ke gemfile aplikasi Anda:
gem "ruby-openai"
Dan kemudian mengeksekusi:
$ bundle install
Atau instal dengan:
$ gem install ruby-openai
dan membutuhkan dengan:
require "openai"
Untuk tes cepat Anda dapat meneruskan token Anda langsung ke klien baru:
client = OpenAI :: Client . new (
access_token : "access_token_goes_here" ,
log_errors : true # Highly recommended in development, so you can see what errors OpenAI is returning. Not recommended in production because it could leak private data to your logs.
)
Untuk pengaturan yang lebih kuat, Anda dapat mengonfigurasi permata dengan kunci API Anda, misalnya dalam file inisialisasi openai.rb
. Never Hardcode Secrets ke CodeBase Anda - alih -alih menggunakan sesuatu seperti dotenv untuk meneruskan kunci dengan aman ke lingkungan Anda.
OpenAI . configure do | config |
config . access_token = ENV . fetch ( "OPENAI_ACCESS_TOKEN" )
config . organization_id = ENV . fetch ( "OPENAI_ORGANIZATION_ID" ) # Optional
config . log_errors = true # Highly recommended in development, so you can see what errors OpenAI is returning. Not recommended in production because it could leak private data to your logs.
end
Maka Anda dapat membuat klien seperti ini:
client = OpenAI :: Client . new
Anda masih dapat mengganti default konfigurasi saat membuat klien baru; Opsi apa pun yang tidak termasuk akan kembali ke set konfigurasi global apa pun dengan OpenAi.configure. misalnya dalam contoh ini organisasi_id, request_timeout, dll. Akan mundur ke set mana pun secara global menggunakan openai.configure, dengan hanya akses_token yang ditimpa:
client = OpenAI :: Client . new ( access_token : "access_token_goes_here" )
request_timeout
saat menginisialisasi klien. client = OpenAI :: Client . new (
access_token : "access_token_goes_here" ,
uri_base : "https://oai.hconeai.com/" ,
request_timeout : 240 ,
extra_headers : {
"X-Proxy-TTL" => "43200" , # For https://github.com/6/openai-caching-proxy-worker#specifying-a-cache-ttl
"X-Proxy-Refresh" : "true" , # For https://github.com/6/openai-caching-proxy-worker#refreshing-the-cache
"Helicone-Auth" : "Bearer HELICONE_API_KEY" , # For https://docs.helicone.ai/getting-started/integration-method/openai-proxy
"helicone-stream-force-format" => "true" , # Use this with Helicone otherwise streaming drops chunks # https://github.com/alexrudall/ruby-openai/issues/251
}
)
atau saat mengkonfigurasi permata:
OpenAI . configure do | config |
config . access_token = ENV . fetch ( "OPENAI_ACCESS_TOKEN" )
config . log_errors = true # Optional
config . organization_id = ENV . fetch ( "OPENAI_ORGANIZATION_ID" ) # Optional
config . uri_base = "https://oai.hconeai.com/" # Optional
config . request_timeout = 240 # Optional
config . extra_headers = {
"X-Proxy-TTL" => "43200" , # For https://github.com/6/openai-caching-proxy-worker#specifying-a-cache-ttl
"X-Proxy-Refresh" : "true" , # For https://github.com/6/openai-caching-proxy-worker#refreshing-the-cache
"Helicone-Auth" : "Bearer HELICONE_API_KEY" # For https://docs.helicone.ai/getting-started/integration-method/openai-proxy
} # Optional
end
Anda dapat secara dinamis meneruskan header per objek klien, yang akan digabungkan dengan header apa pun yang diatur secara global dengan openai.configure:
client = OpenAI :: Client . new ( access_token : "access_token_goes_here" )
client . add_headers ( "X-Proxy-TTL" => "43200" )
Secara default, ruby-openai
tidak mencatat Faraday::Error
yang ditemui saat menjalankan permintaan jaringan untuk menghindari data bocor (misalnya 400 -an, 500 -an, kesalahan SSL dan banyak lagi - lihat di sini untuk daftar lengkap subkelas Faraday::Error
dan dan banyak apa yang bisa menyebabkan mereka).
Jika Anda ingin mengaktifkan fungsi ini, Anda dapat mengatur log_errors
ke true
saat mengkonfigurasi klien:
client = OpenAI :: Client . new ( log_errors : true )
Anda dapat meneruskan middleware Faraday ke klien di blok, misalnya. Untuk mengaktifkan logging verbose dengan ruby's logger:
client = OpenAI :: Client . new do | f |
f . response :logger , Logger . new ( $stdout ) , bodies : true
end
Untuk menggunakan AZURE OpenAI Service API, Anda dapat mengonfigurasi permata seperti ini:
OpenAI . configure do | config |
config . access_token = ENV . fetch ( "AZURE_OPENAI_API_KEY" )
config . uri_base = ENV . fetch ( "AZURE_OPENAI_URI" )
config . api_type = :azure
config . api_version = "2023-03-15-preview"
end
dimana AZURE_OPENAI_URI
adalah misalnya https://custom-domain.openai.azure.com/openai/deployments/gpt-35-turbo
Ollama memungkinkan Anda untuk menjalankan LLMS open-source, seperti Llama 3, secara lokal. Ini menawarkan kompatibilitas obrolan dengan API Openai.
Anda dapat mengunduh ollama di sini. Di macOS Anda dapat menginstal dan menjalankan ollama seperti ini:
brew install ollama
ollama serve
ollama pull llama3:latest # In new terminal tab.
Buat klien menggunakan server ollama Anda dan model yang ditarik, dan streaming percakapan secara gratis:
client = OpenAI :: Client . new (
uri_base : "http://localhost:11434"
)
client . chat (
parameters : {
model : "llama3" , # Required.
messages : [ { role : "user" , content : "Hello!" } ] , # Required.
temperature : 0.7 ,
stream : proc do | chunk , _bytesize |
print chunk . dig ( "choices" , 0 , "delta" , "content" )
end
}
)
# => Hi! It's nice to meet you. Is there something I can help you with, or would you like to chat?
Obrolan API GROQ secara luas kompatibel dengan API Openai, dengan beberapa perbedaan kecil. Dapatkan token akses dari sini, lalu:
client = OpenAI :: Client . new (
access_token : "groq_access_token_goes_here" ,
uri_base : "https://api.groq.com/openai"
)
client . chat (
parameters : {
model : "llama3-8b-8192" , # Required.
messages : [ { role : "user" , content : "Hello!" } ] , # Required.
temperature : 0.7 ,
stream : proc do | chunk , _bytesize |
print chunk . dig ( "choices" , 0 , "delta" , "content" )
end
}
)
Openai parse meminta teks ke token, yang merupakan kata atau bagian dari kata -kata. (Token ini tidak terkait dengan API ACCess_Token Anda.) Menghitung token dapat membantu Anda memperkirakan biaya Anda. Ini juga dapat membantu Anda memastikan ukuran teks cepat Anda berada dalam batas-batas maks dari jendela konteks model Anda, dan memilih parameter penyelesaian max_tokens
yang sesuai sehingga respons Anda juga cocok.
Untuk memperkirakan penghitungan token dari teks Anda:
OpenAI . rough_token_count ( "Your text" )
Jika Anda membutuhkan hitungan yang lebih akurat, coba Tiktoken_Ruby.
Ada berbagai model yang dapat digunakan untuk menghasilkan teks. Untuk daftar lengkap dan untuk mengambil informasi tentang satu model:
client . models . list
client . models . retrieve ( id : "gpt-4o" )
GPT adalah model yang dapat digunakan untuk menghasilkan teks dengan gaya percakapan. Anda dapat menggunakannya untuk menghasilkan respons terhadap urutan pesan:
response = client . chat (
parameters : {
model : "gpt-4o" , # Required.
messages : [ { role : "user" , content : "Hello!" } ] , # Required.
temperature : 0.7 ,
}
)
puts response . dig ( "choices" , 0 , "message" , "content" )
# => "Hello! How may I assist you today?"
Panduan cepat untuk streaming obrolan dengan Rails 7 dan Hotwire
Anda dapat melakukan streaming dari API secara realtime, yang bisa jauh lebih cepat dan digunakan untuk menciptakan pengalaman pengguna yang lebih menarik. Lewati proc (atau objek apa pun dengan metode #call
) ke parameter stream
untuk menerima aliran potongan penyelesaian saat dihasilkan. Setiap kali satu atau lebih potongan diterima, proc akan dipanggil sekali dengan setiap potongan, diuraikan sebagai hash. Jika Openai mengembalikan kesalahan, ruby-openai
akan menimbulkan kesalahan Faraday.
client . chat (
parameters : {
model : "gpt-4o" , # Required.
messages : [ { role : "user" , content : "Describe a character called Anna!" } ] , # Required.
temperature : 0.7 ,
stream : proc do | chunk , _bytesize |
print chunk . dig ( "choices" , 0 , "delta" , "content" )
end
}
)
# => "Anna is a young woman in her mid-twenties, with wavy chestnut hair that falls to her shoulders..."
Catatan: Untuk mendapatkan informasi penggunaan, Anda dapat memberikan parameter stream_options
dan OpenAI akan memberikan potongan akhir dengan penggunaannya. Inilah contohnya:
stream_proc = proc { | chunk , _bytesize | puts "--------------" ; puts chunk . inspect ; }
client . chat (
parameters : {
model : "gpt-4o" ,
stream : stream_proc ,
stream_options : { include_usage : true } ,
messages : [ { role : "user" , content : "Hello!" } ] ,
}
)
# => --------------
# => {"id"=>"chatcmpl-7bbq05PiZqlHxjV1j7OHnKKDURKaf", "object"=>"chat.completion.chunk", "created"=>1718750612, "model"=>"gpt-4o-2024-05-13", "system_fingerprint"=>"fp_9cb5d38cf7", "choices"=>[{"index"=>0, "delta"=>{"role"=>"assistant", "content"=>""}, "logprobs"=>nil, "finish_reason"=>nil}], "usage"=>nil}
# => --------------
# => {"id"=>"chatcmpl-7bbq05PiZqlHxjV1j7OHnKKDURKaf", "object"=>"chat.completion.chunk", "created"=>1718750612, "model"=>"gpt-4o-2024-05-13", "system_fingerprint"=>"fp_9cb5d38cf7", "choices"=>[{"index"=>0, "delta"=>{"content"=>"Hello"}, "logprobs"=>nil, "finish_reason"=>nil}], "usage"=>nil}
# => --------------
# => ... more content chunks
# => --------------
# => {"id"=>"chatcmpl-7bbq05PiZqlHxjV1j7OHnKKDURKaf", "object"=>"chat.completion.chunk", "created"=>1718750612, "model"=>"gpt-4o-2024-05-13", "system_fingerprint"=>"fp_9cb5d38cf7", "choices"=>[{"index"=>0, "delta"=>{}, "logprobs"=>nil, "finish_reason"=>"stop"}], "usage"=>nil}
# => --------------
# => {"id"=>"chatcmpl-7bbq05PiZqlHxjV1j7OHnKKDURKaf", "object"=>"chat.completion.chunk", "created"=>1718750612, "model"=>"gpt-4o-2024-05-13", "system_fingerprint"=>"fp_9cb5d38cf7", "choices"=>[], "usage"=>{"prompt_tokens"=>9, "completion_tokens"=>9, "total_tokens"=>18}}
Anda dapat menggunakan model visi GPT-4 untuk menghasilkan deskripsi gambar:
messages = [
{ "type" : "text" , "text" : "What’s in this image?" } ,
{ "type" : "image_url" ,
"image_url" : {
"url" : "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg" ,
} ,
}
]
response = client . chat (
parameters : {
model : "gpt-4-vision-preview" , # Required.
messages : [ { role : "user" , content : messages } ] , # Required.
}
)
puts response . dig ( "choices" , 0 , "message" , "content" )
# => "The image depicts a serene natural landscape featuring a long wooden boardwalk extending straight ahead"
Anda dapat mengatur respons_format untuk meminta tanggapan di JSON:
response = client . chat (
parameters : {
model : "gpt-4o" ,
response_format : { type : "json_object" } ,
messages : [ { role : "user" , content : "Hello! Give me some JSON please." } ] ,
temperature : 0.7 ,
} )
puts response . dig ( "choices" , 0 , "message" , "content" )
# =>
# {
# "name": "John",
# "age": 30,
# "city": "New York",
# "hobbies": ["reading", "traveling", "hiking"],
# "isStudent": false
# }
Anda dapat mengalirkannya juga!
response = client . chat (
parameters : {
model : "gpt-4o" ,
messages : [ { role : "user" , content : "Can I have some JSON please?" } ] ,
response_format : { type : "json_object" } ,
stream : proc do | chunk , _bytesize |
print chunk . dig ( "choices" , 0 , "delta" , "content" )
end
}
)
# =>
# {
# "message": "Sure, please let me know what specific JSON data you are looking for.",
# "JSON_data": {
# "example_1": {
# "key_1": "value_1",
# "key_2": "value_2",
# "key_3": "value_3"
# },
# "example_2": {
# "key_4": "value_4",
# "key_5": "value_5",
# "key_6": "value_6"
# }
# }
# }
Anda dapat menggambarkan dan meneruskan fungsi dan model akan secara cerdas memilih untuk mengeluarkan objek JSON yang berisi argumen untuk memanggil mereka - mis., Untuk menggunakan metode Anda get_current_weather
untuk mendapatkan cuaca di lokasi tertentu. Perhatikan bahwa Tool_Choice adalah opsional, tetapi jika Anda mengecualikannya, model akan memilih apakah akan menggunakan fungsi atau tidak (lihat di sini).
def get_current_weather ( location : , unit : "fahrenheit" )
# Here you could use a weather api to fetch the weather.
"The weather in #{ location } is nice ? #{ unit } "
end
messages = [
{
"role" : "user" ,
"content" : "What is the weather like in San Francisco?" ,
} ,
]
response =
client . chat (
parameters : {
model : "gpt-4o" ,
messages : messages , # Defined above because we'll use it again
tools : [
{
type : "function" ,
function : {
name : "get_current_weather" ,
description : "Get the current weather in a given location" ,
parameters : { # Format: https://json-schema.org/understanding-json-schema
type : :object ,
properties : {
location : {
type : :string ,
description : "The city and state, e.g. San Francisco, CA" ,
} ,
unit : {
type : "string" ,
enum : %w[ celsius fahrenheit ] ,
} ,
} ,
required : [ "location" ] ,
} ,
} ,
}
] ,
# Optional, defaults to "auto"
# Can also put "none" or specific functions, see docs
tool_choice : "required"
} ,
)
message = response . dig ( "choices" , 0 , "message" )
if message [ "role" ] == "assistant" && message [ "tool_calls" ]
message [ "tool_calls" ] . each do | tool_call |
tool_call_id = tool_call . dig ( "id" )
function_name = tool_call . dig ( "function" , "name" )
function_args = JSON . parse (
tool_call . dig ( "function" , "arguments" ) ,
{ symbolize_names : true } ,
)
function_response =
case function_name
when "get_current_weather"
get_current_weather ( ** function_args ) # => "The weather is nice ?"
else
# decide how to handle
end
# For a subsequent message with the role "tool", OpenAI requires the preceding message to have a tool_calls argument.
messages << message
messages << {
tool_call_id : tool_call_id ,
role : "tool" ,
name : function_name ,
content : function_response
} # Extend the conversation with the results of the functions
end
second_response = client . chat (
parameters : {
model : "gpt-4o" ,
messages : messages
}
)
puts second_response . dig ( "choices" , 0 , "message" , "content" )
# At this point, the model has decided to call functions, you've called the functions
# and provided the response back, and the model has considered this and responded.
end
# => "It looks like the weather is nice and sunny in San Francisco! If you're planning to go out, it should be a pleasant day."
Tekan Openai API untuk penyelesaian menggunakan model GPT-3 lainnya:
response = client . completions (
parameters : {
model : "gpt-4o" ,
prompt : "Once upon a time" ,
max_tokens : 5
}
)
puts response [ "choices" ] . map { | c | c [ "text" ] }
# => [", there lived a great"]
Anda dapat menggunakan titik akhir embeddings untuk mendapatkan vektor angka yang mewakili input. Anda kemudian dapat membandingkan vektor -vektor ini dengan input yang berbeda untuk secara efisien memeriksa seberapa mirip inputnya.
response = client . embeddings (
parameters : {
model : "text-embedding-ada-002" ,
input : "The food was delicious and the waiter..."
}
)
puts response . dig ( "data" , 0 , "embedding" )
# => Vector representation of your embedding
Titik akhir batch memungkinkan Anda untuk membuat dan mengelola batch besar permintaan API untuk berjalan secara tidak sinkron. Saat ini, titik akhir yang didukung untuk batch adalah /v1/chat/completions
(API Penyelesaian Obrolan) dan /v1/embeddings
(Embeddings API).
Untuk menggunakan titik akhir batch, Anda harus terlebih dahulu mengunggah file JSONL yang berisi permintaan batch menggunakan titik akhir file. File harus diunggah dengan tujuan yang diatur ke batch
. Setiap baris dalam file JSONL mewakili satu permintaan dan harus memiliki format berikut:
{
"custom_id" : " request-1 " ,
"method" : " POST " ,
"url" : " /v1/chat/completions " ,
"body" : {
"model" : " gpt-4o " ,
"messages" : [
{ "role" : " system " , "content" : " You are a helpful assistant. " },
{ "role" : " user " , "content" : " What is 2+2? " }
]
}
}
Setelah mengunggah file JSONL, Anda dapat membuat batch baru dengan menyediakan ID file, titik akhir, dan jendela penyelesaian:
response = client . batches . create (
parameters : {
input_file_id : "file-abc123" ,
endpoint : "/v1/chat/completions" ,
completion_window : "24h"
}
)
batch_id = response [ "id" ]
Anda dapat mengambil informasi tentang batch tertentu menggunakan ID -nya:
batch = client . batches . retrieve ( id : batch_id )
Untuk membatalkan batch yang sedang berlangsung:
client . batches . cancel ( id : batch_id )
Anda juga dapat mendaftar semua batch:
client . batches . list
Setelah batch ["foved_at"] ada, Anda dapat mengambil file output atau kesalahan:
batch = client . batches . retrieve ( id : batch_id )
output_file_id = batch [ "output_file_id" ]
output_response = client . files . content ( id : output_file_id )
error_file_id = batch [ "error_file_id" ]
error_response = client . files . content ( id : error_file_id )
File -file ini berada dalam format JSONL, dengan setiap baris mewakili output atau kesalahan untuk satu permintaan. Garis -garisnya bisa dalam urutan apa pun:
{
"id" : " response-1 " ,
"custom_id" : " request-1 " ,
"response" : {
"id" : " chatcmpl-abc123 " ,
"object" : " chat.completion " ,
"created" : 1677858242 ,
"model" : " gpt-4o " ,
"choices" : [
{
"index" : 0 ,
"message" : {
"role" : " assistant " ,
"content" : " 2+2 equals 4. "
}
}
]
}
}
Jika suatu permintaan gagal dengan kesalahan non-HTTP, objek kesalahan akan berisi lebih banyak informasi tentang penyebab kegagalan.
Masukkan data Anda di file .jsonl
seperti ini:
{ "prompt" : " Overjoyed with my new phone! -> " , "completion" : " positive " }
{ "prompt" : " @lakers disappoint for a third straight night -> " , "completion" : " negative " }
dan lewati jalur (atau objek Stringio) ke client.files.upload
untuk mengunggahnya ke OpenAi, dan kemudian berinteraksi dengannya:
client . files . upload ( parameters : { file : "path/to/sentiment.jsonl" , purpose : "fine-tune" } )
client . files . list
client . files . retrieve ( id : "file-123" )
client . files . content ( id : "file-123" )
client . files . delete ( id : "file-123" )
Anda dapat mengirim jalur file:
client . files . upload ( parameters : { file : "path/to/file.pdf" , purpose : "assistants" } )
atau objek file
my_file = File . open ( "path/to/file.pdf" , "rb" )
client . files . upload ( parameters : { file : my_file , purpose : "assistants" } )
Lihat jenis file yang didukung pada dokumentasi API.
Unggah data fine-tuning Anda di file .jsonl
seperti di atas dan dapatkan ID-nya:
response = client . files . upload ( parameters : { file : "path/to/sarcasm.jsonl" , purpose : "fine-tune" } )
file_id = JSON . parse ( response . body ) [ "id" ]
Anda kemudian dapat menggunakan ID file ini untuk membuat pekerjaan tuning fine:
response = client . finetunes . create (
parameters : {
training_file : file_id ,
model : "gpt-4o"
} )
fine_tune_id = response [ "id" ]
Itu akan memberi Anda ID fine-tune. Jika Anda membuat kesalahan, Anda dapat membatalkan model fine-tune sebelum diproses:
client . finetunes . cancel ( id : fine_tune_id )
Anda mungkin perlu menunggu waktu yang singkat untuk diproses. Setelah diproses, Anda dapat menggunakan daftar atau mengambil untuk mendapatkan nama model fine-tuned:
client . finetunes . list
response = client . finetunes . retrieve ( id : fine_tune_id )
fine_tuned_model = response [ "fine_tuned_model" ]
Nama model yang disetel ini kemudian dapat digunakan dalam penyelesaian obrolan:
response = client . chat (
parameters : {
model : fine_tuned_model ,
messages : [ { role : "user" , content : "I love Mondays!" } ]
}
)
response . dig ( "choices" , 0 , "message" , "content" )
Anda juga dapat menangkap acara untuk suatu pekerjaan:
client . finetunes . list_events ( id : fine_tune_id )
Objek penyimpanan vektor memberi alat pencarian file kemampuan untuk mencari file Anda.
Anda dapat membuat toko vektor baru:
response = client . vector_stores . create (
parameters : {
name : "my vector store" ,
file_ids : [ "file-abc123" , "file-def456" ]
}
)
vector_store_id = response [ "id" ]
Diberikan vector_store_id
Anda dapat retrieve
nilai bidang saat ini:
client . vector_stores . retrieve ( id : vector_store_id )
Anda bisa mendapatkan list
semua toko vektor yang saat ini tersedia di bawah organisasi:
client . vector_stores . list
Anda dapat memodifikasi toko vektor yang ada, kecuali untuk file_ids
:
response = client . vector_stores . modify (
id : vector_store_id ,
parameters : {
name : "Modified Test Vector Store" ,
}
)
Anda dapat menghapus toko vektor:
client . vector_stores . delete ( id : vector_store_id )
File toko vektor mewakili file di dalam toko vektor.
Anda dapat membuat file toko vektor baru dengan memasang file ke toko vektor.
response = client . vector_store_files . create (
vector_store_id : "vector-store-abc123" ,
parameters : {
file_id : "file-abc123"
}
)
vector_store_file_id = response [ "id" ]
Diberikan vector_store_file_id
Anda dapat retrieve
nilai bidang saat ini:
client . vector_store_files . retrieve (
vector_store_id : "vector-store-abc123" ,
id : vector_store_file_id
)
Anda bisa mendapatkan list
semua file toko vektor yang saat ini tersedia di bawah toko vektor:
client . vector_store_files . list ( vector_store_id : "vector-store-abc123" )
Anda dapat menghapus file toko vektor:
client . vector_store_files . delete (
vector_store_id : "vector-store-abc123" ,
id : vector_store_file_id
)
Catatan: Ini akan menghapus file dari toko vektor tetapi file itu sendiri tidak akan dihapus. Untuk menghapus file, gunakan titik akhir hapus file.
Batch file toko vektor mewakili operasi untuk menambahkan beberapa file ke toko vektor.
Anda dapat membuat batch file toko vektor baru dengan melampirkan beberapa file ke toko vektor.
response = client . vector_store_file_batches . create (
vector_store_id : "vector-store-abc123" ,
parameters : {
file_ids : [ "file-abc123" , "file-def456" ]
}
)
file_batch_id = response [ "id" ]
Diberikan file_batch_id
Anda dapat retrieve
nilai bidang saat ini:
client . vector_store_file_batches . retrieve (
vector_store_id : "vector-store-abc123" ,
id : file_batch_id
)
Anda bisa mendapatkan list
semua file toko vektor dalam batch yang saat ini tersedia di bawah toko vektor:
client . vector_store_file_batches . list (
vector_store_id : "vector-store-abc123" ,
id : file_batch_id
)
Anda dapat membatalkan batch file toko vektor (ini berupaya membatalkan pemrosesan file dalam batch ini sesegera mungkin):
client . vector_store_file_batches . cancel (
vector_store_id : "vector-store-abc123" ,
id : file_batch_id
)
Asisten adalah aktor stateful yang dapat melakukan banyak percakapan dan menggunakan alat untuk melakukan tugas (lihat ikhtisar asisten).
Untuk membuat asisten baru:
response = client . assistants . create (
parameters : {
model : "gpt-4o" ,
name : "OpenAI-Ruby test assistant" ,
description : nil ,
instructions : "You are a Ruby dev bot. When asked a question, write and run Ruby code to answer the question" ,
tools : [
{ type : "code_interpreter" } ,
{ type : "file_search" }
] ,
tool_resources : {
code_interpreter : {
file_ids : [ ] # See Files section above for how to upload files
} ,
file_search : {
vector_store_ids : [ ] # See Vector Stores section above for how to add vector stores
}
} ,
"metadata" : { my_internal_version_id : "1.0.0" }
}
)
assistant_id = response [ "id" ]
Diberikan assistant_id
Anda dapat retrieve
nilai bidang saat ini:
client . assistants . retrieve ( id : assistant_id )
Anda bisa mendapatkan list
semua asisten yang saat ini tersedia di bawah organisasi:
client . assistants . list
Anda dapat memodifikasi asisten yang ada menggunakan ID asisten (lihat dokumentasi API):
response = client . assistants . modify (
id : assistant_id ,
parameters : {
name : "Modified Test Assistant for OpenAI-Ruby" ,
metadata : { my_internal_version_id : '1.0.1' }
}
)
Anda dapat menghapus asisten:
client . assistants . delete ( id : assistant_id )
Setelah Anda membuat asisten seperti yang dijelaskan di atas, Anda perlu menyiapkan Thread
Messages
untuk dikerjakan asisten (lihat Pendahuluan pada Asisten). Misalnya, sebagai pengaturan awal yang dapat Anda lakukan:
# Create thread
response = client . threads . create # Note: Once you create a thread, there is no way to list it
# or recover it currently (as of 2023-12-10). So hold onto the `id`
thread_id = response [ "id" ]
# Add initial message from user (see https://platform.openai.com/docs/api-reference/messages/createMessage)
message_id = client . messages . create (
thread_id : thread_id ,
parameters : {
role : "user" , # Required for manually created messages
content : "Can you help me write an API library to interact with the OpenAI API please?"
}
) [ "id" ]
# Retrieve individual message
message = client . messages . retrieve ( thread_id : thread_id , id : message_id )
# Review all messages on the thread
messages = client . messages . list ( thread_id : thread_id )
Untuk membersihkan setelah utas tidak lagi diperlukan:
# To delete the thread (and all associated messages):
client . threads . delete ( id : thread_id )
client . messages . retrieve ( thread_id : thread_id , id : message_id ) # -> Fails after thread is deleted
Untuk mengirimkan utas yang akan dievaluasi dengan model asisten, buat Run
sebagai berikut:
# Create run (will use instruction/model/tools from Assistant's definition)
response = client . runs . create (
thread_id : thread_id ,
parameters : {
assistant_id : assistant_id ,
max_prompt_tokens : 256 ,
max_completion_tokens : 16
}
)
run_id = response [ 'id' ]
Anda dapat mengalirkan potongan pesan saat mereka datang:
client . runs . create (
thread_id : thread_id ,
parameters : {
assistant_id : assistant_id ,
max_prompt_tokens : 256 ,
max_completion_tokens : 16 ,
stream : proc do | chunk , _bytesize |
if chunk [ "object" ] == "thread.message.delta"
print chunk . dig ( "delta" , "content" , 0 , "text" , "value" )
end
end
}
)
Untuk mendapatkan status lari:
response = client . runs . retrieve ( id : run_id , thread_id : thread_id )
status = response [ 'status' ]
Respons status
dapat mencakup string berikut queued
, in_progress
, requires_action
, cancelling
, cancelled
, failed
, completed
, atau expired
yang dapat Anda tangani sebagai berikut:
while true do
response = client . runs . retrieve ( id : run_id , thread_id : thread_id )
status = response [ 'status' ]
case status
when 'queued' , 'in_progress' , 'cancelling'
puts 'Sleeping'
sleep 1 # Wait one second and poll again
when 'completed'
break # Exit loop and report result to user
when 'requires_action'
# Handle tool calls (see below)
when 'cancelled' , 'failed' , 'expired'
puts response [ 'last_error' ] . inspect
break # or `exit`
else
puts "Unknown status response: #{ status } "
end
end
Jika respons status
menunjukkan bahwa run
completed
, thread
terkait akan memiliki satu atau lebih messages
baru terlampir:
# Either retrieve all messages in bulk again, or...
messages = client . messages . list ( thread_id : thread_id , parameters : { order : 'asc' } )
# Alternatively retrieve the `run steps` for the run which link to the messages:
run_steps = client . run_steps . list ( thread_id : thread_id , run_id : run_id , parameters : { order : 'asc' } )
new_message_ids = run_steps [ 'data' ] . filter_map do | step |
if step [ 'type' ] == 'message_creation'
step . dig ( 'step_details' , "message_creation" , "message_id" )
end # Ignore tool calls, because they don't create new messages.
end
# Retrieve the individual messages
new_messages = new_message_ids . map do | msg_id |
client . messages . retrieve ( id : msg_id , thread_id : thread_id )
end
# Find the actual response text in the content array of the messages
new_messages . each do | msg |
msg [ 'content' ] . each do | content_item |
case content_item [ 'type' ]
when 'text'
puts content_item . dig ( 'text' , 'value' )
# Also handle annotations
when 'image_file'
# Use File endpoint to retrieve file contents via id
id = content_item . dig ( 'image_file' , 'file_id' )
end
end
end
Anda juga dapat memperbarui metadata pada pesan, termasuk pesan yang berasal dari asisten.
metadata = {
user_id : "abc123"
}
message = client . messages . modify (
id : message_id ,
thread_id : thread_id ,
parameters : { metadata : metadata } ,
)
Kapan saja Anda dapat mencantumkan semua proses yang telah dilakukan pada utas tertentu atau sedang berjalan:
client . runs . list ( thread_id : thread_id , parameters : { order : "asc" , limit : 3 } )
Anda juga dapat membuat utas dan menjalankan dalam satu panggilan seperti ini:
response = client . runs . create_thread_and_run ( parameters : { assistant_id : assistant_id } )
run_id = response [ 'id' ]
thread_id = response [ 'thread_id' ]
Anda dapat memasukkan gambar di utas dan akan dijelaskan & dibaca oleh LLM. Dalam contoh ini saya menggunakan file ini:
require "openai"
# Make a client
client = OpenAI :: Client . new (
access_token : "access_token_goes_here" ,
log_errors : true # Don't log errors in production.
)
# Upload image as a file
file_id = client . files . upload (
parameters : {
file : "path/to/example.png" ,
purpose : "assistants" ,
}
) [ "id" ]
# Create assistant (You could also use an existing one here)
assistant_id = client . assistants . create (
parameters : {
model : "gpt-4o" ,
name : "Image reader" ,
instructions : "You are an image describer. You describe the contents of images." ,
}
) [ "id" ]
# Create thread
thread_id = client . threads . create [ "id" ]
# Add image in message
client . messages . create (
thread_id : thread_id ,
parameters : {
role : "user" , # Required for manually created messages
content : [
{
"type" : "text" ,
"text" : "What's in this image?"
} ,
{
"type" : "image_file" ,
"image_file" : { "file_id" : file_id }
}
]
}
)
# Run thread
run_id = client . runs . create (
thread_id : thread_id ,
parameters : { assistant_id : assistant_id }
) [ "id" ]
# Wait until run in complete
status = nil
until status == "completed" do
sleep ( 0.1 )
status = client . runs . retrieve ( id : run_id , thread_id : thread_id ) [ 'status' ]
end
# Get the response
messages = client . messages . list ( thread_id : thread_id , parameters : { order : 'asc' } )
messages . dig ( "data" , - 1 , "content" , 0 , "text" , "value" )
=> "The image contains a placeholder graphic with a tilted, stylized representation of a postage stamp in the top part, which includes an abstract landscape with hills and a sun. Below the stamp, in the middle of the image, there is italicized text in a light golden color that reads, " This is just an example. " The background is a light pastel shade, and a yellow border frames the entire image."
Jika Anda mengizinkan asisten untuk mengakses alat function
(mereka didefinisikan dengan cara yang sama seperti fungsi selama penyelesaian obrolan), Anda mungkin mendapatkan kode status requires_action
ketika asisten ingin Anda mengevaluasi satu atau lebih alat fungsi:
def get_current_weather ( location : , unit : "celsius" )
# Your function code goes here
if location =~ /San Francisco/i
return unit == "celsius" ? "The weather is nice ? at 27°C" : "The weather is nice ? at 80°F"
else
return unit == "celsius" ? "The weather is icy ? at -5°C" : "The weather is icy ? at 23°F"
end
end
if status == 'requires_action'
tools_to_call = response . dig ( 'required_action' , 'submit_tool_outputs' , 'tool_calls' )
my_tool_outputs = tools_to_call . map { | tool |
# Call the functions based on the tool's name
function_name = tool . dig ( 'function' , 'name' )
arguments = JSON . parse (
tool . dig ( "function" , "arguments" ) ,
{ symbolize_names : true } ,
)
tool_output = case function_name
when "get_current_weather"
get_current_weather ( ** arguments )
end
{
tool_call_id : tool [ 'id' ] ,
output : tool_output ,
}
}
client . runs . submit_tool_outputs (
thread_id : thread_id ,
run_id : run_id ,
parameters : { tool_outputs : my_tool_outputs }
)
end
Perhatikan bahwa Anda memiliki 10 menit untuk mengirimkan output alat Anda sebelum menjalankan berakhir.
Tarik napas dalam -dalam. Anda mungkin membutuhkan minuman untuk yang satu ini.
Dimungkinkan bagi OpenAI untuk membagikan potongan apa yang digunakannya dalam pipa rag internalnya untuk membuat hasil penelitian file -nya.
Contoh spek dapat ditemukan di sini yang melakukan ini, supaya Anda tahu itu mungkin.
Inilah cara mendapatkan potongan yang digunakan dalam pencarian file. Dalam contoh ini saya menggunakan file ini:
require "openai"
# Make a client
client = OpenAI :: Client . new (
access_token : "access_token_goes_here" ,
log_errors : true # Don't log errors in production.
)
# Upload your file(s)
file_id = client . files . upload (
parameters : {
file : "path/to/somatosensory.pdf" ,
purpose : "assistants"
}
) [ "id" ]
# Create a vector store to store the vectorised file(s)
vector_store_id = client . vector_stores . create ( parameters : { } ) [ "id" ]
# Vectorise the file(s)
vector_store_file_id = client . vector_store_files . create (
vector_store_id : vector_store_id ,
parameters : { file_id : file_id }
) [ "id" ]
# Check that the file is vectorised (wait for status to be "completed")
client . vector_store_files . retrieve ( vector_store_id : vector_store_id , id : vector_store_file_id ) [ "status" ]
# Create an assistant, referencing the vector store
assistant_id = client . assistants . create (
parameters : {
model : "gpt-4o" ,
name : "Answer finder" ,
instructions : "You are a file search tool. Find the answer in the given files, please." ,
tools : [
{ type : "file_search" }
] ,
tool_resources : {
file_search : {
vector_store_ids : [ vector_store_id ]
}
}
}
) [ "id" ]
# Create a thread with your question
thread_id = client . threads . create ( parameters : {
messages : [
{ role : "user" ,
content : "Find the description of a nociceptor." }
]
} ) [ "id" ]
# Run the thread to generate the response. Include the "GIVE ME THE CHUNKS" incantation.
run_id = client . runs . create (
thread_id : thread_id ,
parameters : {
assistant_id : assistant_id
} ,
query_parameters : { include : [ "step_details.tool_calls[*].file_search.results[*].content" ] } # incantation
) [ "id" ]
# Get the steps that happened in the run
steps = client . run_steps . list (
thread_id : thread_id ,
run_id : run_id ,
parameters : { order : "asc" }
)
# Retrieve all the steps. Include the "GIVE ME THE CHUNKS" incantation again.
steps = steps [ "data" ] . map do | step |
client . run_steps . retrieve (
thread_id : thread_id ,
run_id : run_id ,
id : step [ "id" ] ,
parameters : { include : [ "step_details.tool_calls[*].file_search.results[*].content" ] } # incantation
)
end
# Now we've got the chunk info, buried deep. Loop through the steps and find chunks if included:
chunks = steps . flat_map do | step |
included_results = step . dig ( "step_details" , "tool_calls" , 0 , "file_search" , "results" )
next if included_results . nil? || included_results . empty?
included_results . flat_map do | result |
result [ "content" ] . map do | content |
content [ "text" ]
end
end
end . compact
# The first chunk will be the closest match to the prompt. Finally, if you want to view the completed message(s):
client . messages . list ( thread_id : thread_id )
Hasilkan gambar menggunakan Dall · E 2 atau Dall · E 3!
Untuk Dall · E 2 Ukuran gambar yang dihasilkan harus merupakan salah satu dari 256x256
, 512x512
atau 1024x1024
- jika tidak ditentukan gambar akan default ke 1024x1024
.
response = client . images . generate (
parameters : {
prompt : "A baby sea otter cooking pasta wearing a hat of some sort" ,
size : "256x256" ,
}
)
puts response . dig ( "data" , 0 , "url" )
# => "https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhh..."
Untuk Dall · E 3 Ukuran gambar yang dihasilkan harus merupakan salah satu dari 1024x1024
, 1024x1792
atau 1792x1024
. Selain itu, kualitas gambar dapat ditentukan untuk standard
atau hd
.
response = client . images . generate (
parameters : {
prompt : "A springer spaniel cooking pasta wearing a hat of some sort" ,
model : "dall-e-3" ,
size : "1024x1792" ,
quality : "standard" ,
}
)
puts response . dig ( "data" , 0 , "url" )
# => "https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhh..."
Isi bagian transparan gambar, atau unggah topeng dengan bagian transparan untuk menunjukkan bagian -bagian gambar yang dapat diubah sesuai dengan prompt Anda ...
response = client . images . edit (
parameters : {
prompt : "A solid red Ruby on a blue background" ,
image : "image.png" ,
mask : "mask.png" ,
}
)
puts response . dig ( "data" , 0 , "url" )
# => "https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhh..."
Buat n variasi gambar.
response = client . images . variations ( parameters : { image : "image.png" , n : 2 } )
puts response . dig ( "data" , 0 , "url" )
# => "https://oaidalleapiprodscus.blob.core.windows.net/private/org-Rf437IxKhh..."
Lewati string untuk memeriksa apakah itu melanggar kebijakan konten Openai:
response = client . moderations ( parameters : { input : "I'm worried about that." } )
puts response . dig ( "results" , 0 , "category_scores" , "hate" )
# => 5.505014632944949e-05
Whisper adalah model pidato ke teks yang dapat digunakan untuk menghasilkan teks berdasarkan file audio:
API Terjemahan mengambil sebagai masukan file audio dalam salah satu bahasa yang didukung dan menyalin audio ke dalam bahasa Inggris.
response = client . audio . translate (
parameters : {
model : "whisper-1" ,
file : File . open ( "path_to_file" , "rb" ) ,
}
)
puts response [ "text" ]
# => "Translation of the text"
API transkripsi mengambil sebagai masukan file audio yang ingin Anda transkrip dan mengembalikan teks dalam format file output yang diinginkan.
Anda dapat melewati bahasa file audio untuk meningkatkan kualitas transkripsi. Bahasa yang didukung tercantum di sini. Anda perlu memberikan bahasa sebagai kode ISO-639-1, misalnya. "en" untuk bahasa Inggris atau "ne" untuk nepal. Anda dapat mencari kode di sini.
response = client . audio . transcribe (
parameters : {
model : "whisper-1" ,
file : File . open ( "path_to_file" , "rb" ) ,
language : "en" , # Optional
}
)
puts response [ "text" ]
# => "Transcription of the text"
API pidato dianggap sebagai masukan teks dan suara dan mengembalikan konten file audio yang dapat Anda dengarkan.
response = client . audio . speech (
parameters : {
model : "tts-1" ,
input : "This is a speech test!" ,
voice : "alloy" ,
response_format : "mp3" , # Optional
speed : 1.0 , # Optional
}
)
File . binwrite ( 'demo.mp3' , response )
# => mp3 file that plays: "This is a speech test!"
Kesalahan HTTP dapat ditangkap seperti ini:
begin
OpenAI :: Client . new . models . retrieve ( id : "gpt-4o" )
rescue Faraday :: Error => e
raise "Got a Faraday error: #{ e } "
end
Setelah memeriksa repo, jalankan bin/setup
untuk menginstal dependensi. Anda dapat menjalankan bin/console
untuk prompt interaktif yang akan memungkinkan Anda untuk bereksperimen.
Untuk menginstal permata ini ke mesin lokal Anda, jalankan bundle exec rake install
.
Untuk menjalankan semua tes, jalankan bundle exec rake
, yang juga akan menjalankan linter (rubocop). Repositori ini menggunakan VCR untuk mencatat permintaan API.
Peringatan
Jika Anda memiliki OPENAI_ACCESS_TOKEN
di ENV
Anda, menjalankan spesifikasi akan menggunakan ini untuk menjalankan spesifikasi terhadap API yang sebenarnya, yang akan lambat dan biaya uang Anda - 2 sen atau lebih! Hapus dari lingkungan Anda dengan unset
atau serupa jika Anda hanya ingin menjalankan spesifikasi terhadap respons VCR yang disimpan.
Pertama jalankan spesifikasi tanpa VCR sehingga mereka benar -benar mencapai API. Ini akan menelan biaya 2 sen atau lebih. Setel openai_access_token di lingkungan Anda atau lewati seperti ini:
OPENAI_ACCESS_TOKEN=123abc bundle exec rspec
Kemudian perbarui nomor versi di version.rb
, perbarui CHANGELOG.md
, jalankan bundle install
untuk memperbarui gemfile.lock, dan kemudian jalankan bundle exec rake release
, yang akan membuat tag git untuk versi, dorong komitmen dan tag, dan tekan file .gem
ke rubygems.org.
Laporan bug dan permintaan tarik dipersilakan di GitHub di https://github.com/alexrudall/ruby-openai. Proyek ini dimaksudkan untuk menjadi ruang yang aman dan ramah untuk kolaborasi, dan kontributor diharapkan untuk mematuhi kode etik.
Permata tersedia sebagai open source di bawah ketentuan lisensi MIT.
Semua orang yang berinteraksi dalam basis kode proyek Ruby Openai, pelacak masalah, ruang obrolan, dan milis diharapkan mengikuti kode etik.