RubyでOpenai APIを使用してください! ?
GPT-4Oでテキストをストリーミングし、オーディオをウィスパーで転写して翻訳するか、DALLの画像を作成します。
Rails+AIアプリを構築するために私を雇ってください| Rails ai | ? Ruby Ai Builders discord | ? x | ?人類の宝石| ? Midjourney Gem
この行をアプリケーションのGemfileに追加します。
gem "ruby-openai"
そして実行してください:
$ bundle install
またはインストール:
$ gem install ruby-openai
必要なのは次のとおりです。
require "openai"
簡単なテストのために、トークンを新しいクライアントに直接渡すことができます。
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.
)
より堅牢なセットアップの場合、APIキーを使用してGEMを構成できます。たとえば、 openai.rb
Initializerファイルで。コードベースにハードコードシークレットをハードコードしないでください - 代わりにdotenvのようなものを使用して、キーを安全に環境に渡します。
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
次に、次のようなクライアントを作成できます。
client = OpenAI :: Client . new
新しいクライアントを作成するときに、構成のデフォルトをオーバーライドできます。含まれていないオプションは、openai.configureを備えたグローバル構成セットに戻ります。たとえば、この例では、Openai.Configureを使用してGrabal.tokenのみを使用して、Grassion_id、request_timeoutなどが世界的に任意のセットにフォールバックします。
client = OpenAI :: Client . new ( access_token : "access_token_goes_here" )
request_timeout
に数秒渡すことで、それを変更できます。 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
}
)
または宝石を構成するとき:
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
クライアントオブジェクトごとのヘッダーを動的に渡すことができます。これは、openai.configureでグローバルに設定されたヘッダーとマージされます。
client = OpenAI :: Client . new ( access_token : "access_token_goes_here" )
client . add_headers ( "X-Proxy-TTL" => "43200" )
デフォルトでは、 ruby-openai
、データの漏れを避けるためにネットワークリクエストの実行中に遭遇したFaraday::Error
を記録しません(例:400S、500S、SSLエラーなど - Faraday::Error
とエラーそれらを引き起こす可能性があるもの)。
この機能を有効にしたい場合は、クライアントを構成するときにlog_errors
true
に設定できます。
client = OpenAI :: Client . new ( log_errors : true )
たとえば、ブロック内のクライアントにファラデーミドルウェアを渡すことができます。 Rubyのロガーで冗長ロギングを有効にするには:
client = OpenAI :: Client . new do | f |
f . response :logger , Logger . new ( $stdout ) , bodies : true
end
Azure Openai Service APIを使用するには、次のような宝石を構成できます。
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
ここで、 AZURE_OPENAI_URI
はhttps://custom-domain.openai.azure.com/openai/deployments/gpt-35-turbo
です
Ollamaを使用すると、Llama 3などのオープンソースLLMをローカルに実行できます。 Openai APIとのチャット互換性を提供します。
ここからオラマをダウンロードできます。 MacOSでは、このようにOllamaをインストールして実行できます。
brew install ollama
ollama serve
ollama pull llama3:latest # In new terminal tab.
Ollamaサーバーとプルモデルを使用してクライアントを作成し、会話を無料でストリーミングします。
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?
GROQ APIチャットは、Openai APIと広く互換性があり、いくつかのわずかな違いがあります。ここからアクセストークンを入手してください。
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は、単語または単語の一部であるトークンにテキストを促します。 (これらのトークンは、API Access_Tokenとは無関係です。)トークンをカウントすると、コストを見積もることができます。また、プロンプトのテキストサイズがモデルのコンテキストウィンドウの最大トークン制限内にあることを確認し、応答が適合するように適切なmax_tokens
完了パラメーターを選択するのに役立ちます。
テキストのトークンカウントを推定するには:
OpenAI . rough_token_count ( "Your text" )
より正確なカウントが必要な場合は、tiktoken_rubyをお試しください。
テキストを生成するために使用できるさまざまなモデルがあります。完全なリストと単一のモデルに関する情報を取得するには:
client . models . list
client . models . retrieve ( id : "gpt-4o" )
GPTは、会話スタイルでテキストを生成するために使用できるモデルです。これを使用して、一連のメッセージに対する応答を生成できます。
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?"
Rails 7とHotwireとのストリーミングチャットのクイックガイド
APIからリアルタイムでストリーミングできます。これは、はるかに高速になり、より魅力的なユーザーエクスペリエンスを作成するために使用できます。 Proc(または#call
メソッドのあるオブジェクト)をstream
パラメーターに渡して、生成されたまま完了チャンクのストリームを受信します。 1つ以上のチャンクを受信するたびに、Procは各チャンクで1回呼び出され、ハッシュとして解析されます。 Openaiがエラーを返した場合、 ruby-openai
ファラデーエラーを上げます。
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..."
注:使用情報を取得するには、 stream_options
パラメーターを提供することができ、Openaiは使用状況で最終的なチャンクを提供します。これが例です:
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}}
GPT-4 Visionモデルを使用して、画像の説明を生成できます。
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"
response_formatを設定して、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
# }
あなたもそれをストリーミングすることができます!
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"
# }
# }
# }
機能を記述して渡すことができます。モデルは、引数を含むJSONオブジェクトを出力することをインテリジェントに選択します。たとえば、メソッドget_current_weather
を使用して、特定の場所で天気を取得します。 Tool_Choiceはオプションですが、除外すると、モデルは関数を使用するかどうかを選択します(こちらを参照)。
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."
他のGPT-3モデルを使用して完了するためにOpenai APIを押します。
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"]
Embeddings Endpointを使用して、入力を表す数値のベクトルを取得できます。次に、これらのベクトルをさまざまな入力に対して比較して、入力の類似点を効率的に確認できます。
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
バッチエンドポイントを使用すると、APIリクエストの大きなバッチを作成および管理して、非同期に実行できます。現在、バッチのサポートされているエンドポイントは/v1/chat/completions
(チャット完了API)および/v1/embeddings
(埋め込みAPI)です。
バッチエンドポイントを使用するには、ファイルエンドポイントを使用してバッチ要求を含むJSONLファイルを最初にアップロードする必要があります。ファイルは、 batch
に設定された目的でアップロードする必要があります。 JSONLファイルの各行は単一のリクエストを表し、次の形式を持つ必要があります。
{
"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? " }
]
}
}
JSONLファイルをアップロードしたら、ファイルID、エンドポイント、および完了ウィンドウを提供して、新しいバッチを作成できます。
response = client . batches . create (
parameters : {
input_file_id : "file-abc123" ,
endpoint : "/v1/chat/completions" ,
completion_window : "24h"
}
)
batch_id = response [ "id" ]
IDを使用して、特定のバッチに関する情報を取得できます。
batch = client . batches . retrieve ( id : batch_id )
進行中のバッチをキャンセルするには:
client . batches . cancel ( id : batch_id )
すべてのバッチをリストすることもできます。
client . batches . list
バッチ["completed_at"]が存在すると、出力またはエラーファイルを取得できます。
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 )
これらのファイルはJSONL形式で、各行は単一のリクエストの出力またはエラーを表します。行は任意の順序で存在することができます:
{
"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. "
}
}
]
}
}
非HTTPエラーで要求が失敗した場合、エラーオブジェクトには障害の原因に関する詳細情報が含まれます。
データを次のように.jsonl
ファイルに入れます。
{ "prompt" : " Overjoyed with my new phone! -> " , "completion" : " positive " }
{ "prompt" : " @lakers disappoint for a third straight night -> " , "completion" : " negative " }
そして、パス(またはstringioオブジェクト)をclient.files.upload
に渡して、それをOpenaiにアップロードしてから対話します。
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" )
ファイルパスを送信できます。
client . files . upload ( parameters : { file : "path/to/file.pdf" , purpose : "assistants" } )
またはファイルオブジェクト
my_file = File . open ( "path/to/file.pdf" , "rb" )
client . files . upload ( parameters : { file : my_file , purpose : "assistants" } )
APIドキュメントのサポートされているファイルタイプを参照してください。
上記のように.jsonl
ファイルに微調整データをアップロードし、IDを取得します。
response = client . files . upload ( parameters : { file : "path/to/sarcasm.jsonl" , purpose : "fine-tune" } )
file_id = JSON . parse ( response . body ) [ "id" ]
その後、このファイルIDを使用して、微調整ジョブを作成できます。
response = client . finetunes . create (
parameters : {
training_file : file_id ,
model : "gpt-4o"
} )
fine_tune_id = response [ "id" ]
それはあなたに微調整IDを与えるでしょう。間違いを犯した場合、処理する前に微調整モデルをキャンセルできます。
client . finetunes . cancel ( id : fine_tune_id )
処理が完了するまで短時間待つ必要がある場合があります。処理されたら、リストまたは取得を使用して、微調整されたモデルの名前を取得できます。
client . finetunes . list
response = client . finetunes . retrieve ( id : fine_tune_id )
fine_tuned_model = response [ "fine_tuned_model" ]
この微調整されたモデル名は、チャットの完了で使用できます。
response = client . chat (
parameters : {
model : fine_tuned_model ,
messages : [ { role : "user" , content : "I love Mondays!" } ]
}
)
response . dig ( "choices" , 0 , "message" , "content" )
仕事のイベントをキャプチャすることもできます。
client . finetunes . list_events ( id : fine_tune_id )
ベクトルストアオブジェクトは、ファイル検索ツールにファイルを検索する機能を提供します。
新しいベクトルストアを作成できます。
response = client . vector_stores . create (
parameters : {
name : "my vector store" ,
file_ids : [ "file-abc123" , "file-def456" ]
}
)
vector_store_id = response [ "id" ]
vector_store_id
が与えられた場合、現在のフィールド値retrieve
できます。
client . vector_stores . retrieve ( id : vector_store_id )
組織の下で現在利用可能なすべてのベクトルストアのlist
を取得できます。
client . vector_stores . list
file_ids
を除き、既存のベクトルストアを変更できます。
response = client . vector_stores . modify (
id : vector_store_id ,
parameters : {
name : "Modified Test Vector Store" ,
}
)
ベクトルストアを削除できます。
client . vector_stores . delete ( id : vector_store_id )
ベクトルストアファイルは、ベクターストア内のファイルを表します。
ファイルをベクトルストアに添付して、新しいベクトルストアファイルを作成できます。
response = client . vector_store_files . create (
vector_store_id : "vector-store-abc123" ,
parameters : {
file_id : "file-abc123"
}
)
vector_store_file_id = response [ "id" ]
vector_store_file_id
が与えられた場合、現在のフィールド値retrieve
できます。
client . vector_store_files . retrieve (
vector_store_id : "vector-store-abc123" ,
id : vector_store_file_id
)
現在利用可能なすべてのベクトルストアファイルのlist
を取得できます。
client . vector_store_files . list ( vector_store_id : "vector-store-abc123" )
ベクトルストアファイルを削除できます。
client . vector_store_files . delete (
vector_store_id : "vector-store-abc123" ,
id : vector_store_file_id
)
注:これにより、Vectorストアからファイルが削除されますが、ファイル自体は削除されません。ファイルを削除するには、削除ファイルエンドポイントを使用します。
ベクトルストアファイルバッチは、操作を表して、ベクトルストアに複数のファイルを追加します。
複数のファイルをベクトルストアに添付して、新しいベクトルストアファイルバッチを作成できます。
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" ]
file_batch_id
が与えられた場合、現在のフィールド値retrieve
できます。
client . vector_store_file_batches . retrieve (
vector_store_id : "vector-store-abc123" ,
id : file_batch_id
)
ベクターストアで現在利用可能なバッチ内のすべてのベクトルストアファイルのlist
を取得できます。
client . vector_store_file_batches . list (
vector_store_id : "vector-store-abc123" ,
id : file_batch_id
)
ベクトルストアファイルバッチをキャンセルできます(これにより、このバッチ内のファイルの処理をできるだけ早くキャンセルしようとします):
client . vector_store_file_batches . cancel (
vector_store_id : "vector-store-abc123" ,
id : file_batch_id
)
アシスタントは、多くの会話を持ち、ツールを使用してタスクを実行できるステートフルな俳優です(アシスタントの概要を参照)。
新しいアシスタントを作成するには:
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" ]
assistant_id
を与えられた場合、現在のフィールド値retrieve
できます。
client . assistants . retrieve ( id : assistant_id )
組織の下で現在利用可能なすべてのアシスタントのlist
を取得できます。
client . assistants . list
アシスタントのIDを使用して既存のアシスタントを変更できます(APIドキュメントを参照):
response = client . assistants . modify (
id : assistant_id ,
parameters : {
name : "Modified Test Assistant for OpenAI-Ruby" ,
metadata : { my_internal_version_id : '1.0.1' }
}
)
アシスタントを削除できます:
client . assistants . delete ( id : assistant_id )
上記のようにアシスタントを作成したら、アシスタントが作業するためのMessages
のThread
を準備する必要があります(アシスタントの紹介を参照)。たとえば、最初のセットアップとして、次のことができます。
# 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 )
スレッドが不要になった後にクリーンアップするには:
# 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
アシスタントのモデルで評価されるスレッドを送信するには、次のようにRun
を作成します。
# 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' ]
メッセージチャンクが通過するときにストリーミングできます。
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
}
)
実行のステータスを取得するには:
response = client . runs . retrieve ( id : run_id , thread_id : thread_id )
status = response [ 'status' ]
status
応答には、次の文字queued
、 in_progress
、 requires_action
、 cancelling
、 cancelled
、 failed
、 completed
、またはexpired
をとることができます。
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
status
応答がrun
がcompleted
ことを示した場合、関連するthread
には1つ以上の新しいmessages
が添付されます。
# 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
また、アシスタントからのメッセージを含むメッセージでメタデータを更新することもできます。
metadata = {
user_id : "abc123"
}
message = client . messages . modify (
id : message_id ,
thread_id : thread_id ,
parameters : { metadata : metadata } ,
)
いつでも、特定のスレッドで実行されている、または現在実行中のすべての実行をリストできます。
client . runs . list ( thread_id : thread_id , parameters : { order : "asc" , limit : 3 } )
スレッドを作成して、次のような1回の呼び出しで実行することもできます。
response = client . runs . create_thread_and_run ( parameters : { assistant_id : assistant_id } )
run_id = response [ 'id' ]
thread_id = response [ 'thread_id' ]
画像をスレッドに含めることができ、LLMで説明および読み取りされます。この例では、このファイルを使用しています。
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."
アシスタントがfunction
ツールにアクセスできるようにする場合(チャットの完了時に機能と同じ方法で定義されます)、アシスタントが1つ以上の関数ツールを評価することを望んでいる場合、 requires_action
のステータスコードを取得する場合があります。
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
実行が期限切れになる前に、ツール出力を送信するのに10分かかることに注意してください。
深呼吸してください。これには飲み物が必要かもしれません。
OpenAIは、内部ラグパイプラインで使用したチャンクを共有して、Filesearchの結果を作成することができます。
これを行うスペックの例をここに見つけることができます。
ファイル検索で使用されるチャンクを取得する方法は次のとおりです。この例では、このファイルを使用しています。
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 )
Dall・E 2またはDall・E 3を使用して画像を生成します!
DALL・E 2の場合、生成された画像のサイズは256x256
、または1024x1024
512x512
いずれかでなければなりません - 指定されていない場合、画像はデフォルトで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..."
Dall・E 3の場合、生成された画像のサイズは、 1024x1024
または1792x1024
1024x1792
いずれかでなければなりません。さらに、画像の品質はstandard
または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..."
画像の透明な部分を入力するか、透明なセクションでマスクをアップロードして、プロンプトに応じて変更できる画像の部分を示してください...
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..."
画像のnバリエーションを作成します。
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..."
文字列を渡して、Openaiのコンテンツポリシーに違反しているかどうかを確認します。
response = client . moderations ( parameters : { input : "I'm worried about that." } )
puts response . dig ( "results" , 0 , "category_scores" , "hate" )
# => 5.505014632944949e-05
Whisperは、オーディオファイルに基づいてテキストを生成するために使用できるテキストモデルへのスピーチモデルです。
翻訳APIは、サポートされている言語のいずれかでオーディオファイルを入力し、オーディオを英語に転写します。
response = client . audio . translate (
parameters : {
model : "whisper-1" ,
file : File . open ( "path_to_file" , "rb" ) ,
}
)
puts response [ "text" ]
# => "Translation of the text"
Transcriptions APIは、転写するオーディオファイルを入力として取得し、目的の出力ファイル形式でテキストを返します。
オーディオファイルの言語を渡して、転写品質を向上させることができます。サポートされている言語はここにリストされています。言語をISO-639-1コードとして提供する必要があります。英語の「en」またはネパールの「ne」。ここでコードを調べることができます。
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は、テキストと音声を入力して、聞くことができるオーディオファイルのコンテンツを返します。
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!"
HTTPエラーは次のようにキャッチできます。
begin
OpenAI :: Client . new . models . retrieve ( id : "gpt-4o" )
rescue Faraday :: Error => e
raise "Got a Faraday error: #{ e } "
end
リポジトリをチェックアウトした後、 bin/setup
を実行して依存関係をインストールします。実験を可能にするインタラクティブなプロンプトのbin/console
を実行できます。
この宝石をローカルマシンにインストールするには、 bundle exec rake install
実行します。
すべてのテストを実行するには、コマンドbundle exec rake
を実行します。このリポジトリはVCRを使用してAPIリクエストを記録します。
警告
ENV
にOPENAI_ACCESS_TOKEN
がある場合、仕様を実行すると、これを使用して実際のAPIに対して仕様を実行します。保存unset
れているVCR応答に対して仕様を実行したい場合は、環境からそれを取り外してください。
最初にVCRなしで仕様を実行して、実際にAPIを押します。これには2セント以上かかります。 Openai_access_tokenを環境で設定するか、このように渡す:
OPENAI_ACCESS_TOKEN=123abc bundle exec rspec
次に、 version.rb
のバージョン番号を更新し、 CHANGELOG.md
を更新し、 bundle install
を実行してgemfile.lockを更新し、 bundle exec rake release
を実行します。これにより、バージョンのgitタグが作成され、gitコミットとタグを押し、プッシュします。 rubygems.orgへの.gem
ファイル。
バグレポートとプルリクエストは、https://github.com/alexrudall/ruby-openaiのGithubで大歓迎です。このプロジェクトは、コラボレーションのための安全で居心地の良いスペースであることを目的としており、貢献者は行動規範を遵守することが期待されています。
宝石は、MITライセンスの条件の下でオープンソースとして利用できます。
Ruby Openaiプロジェクトのコードベース、発行トラッカー、チャットルーム、メーリングリストで対話する全員が、行動規範に従うことが期待されています。