ใช้ OpenAI API กับ Ruby! ?
สตรีมข้อความด้วย GPT-4O ถอดและแปลเสียงด้วยเสียงกระซิบหรือสร้างภาพด้วย Dall · E ...
จ้างฉันเพื่อสร้าง Rails+AI App | Rails AI | - Ruby AI Builders Discord | - x | - อัญมณีมานุษยวิทยา - อัญมณี Midjourney
เพิ่มบรรทัดนี้ใน 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.
)
สำหรับการตั้งค่าที่แข็งแกร่งยิ่งขึ้นคุณสามารถกำหนดค่า GEM ด้วยคีย์ API ของคุณได้เช่นในไฟล์ openai.rb
Initializer อย่าใช้ความลับรหัสฮาร์ดลงใน codebase ของคุณ - ใช้บางอย่างเช่น 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 เช่นในตัวอย่างนี้ organization_id, request_timeout ฯลฯ จะย้อนกลับไปที่ชุดใด ๆ ทั่วโลกโดยใช้ openai.configure โดยมีเพียง Access_Token Overridden:
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
Faraday::Error
S ใด ๆ ในขณะที่ดำเนินการคำขอเครือข่ายเพื่อหลีกเลี่ยงการรั่วไหลของข้อมูล (เช่น 400s, 500s, ข้อผิดพลาด SSL และอื่น ๆ สิ่งที่อาจทำให้พวกเขา)
หากคุณต้องการเปิดใช้งานฟังก์ชั่นนี้คุณสามารถตั้งค่า log_errors
เป็น true
เมื่อกำหนดค่าไคลเอนต์:
client = OpenAI :: Client . new ( log_errors : true )
คุณสามารถส่งมิดเดิลแวร์ฟาราเดย์ไปยังไคลเอนต์ในบล็อกได้เช่น เพื่อเปิดใช้งานการบันทึก verbose ด้วย logger ของ 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 ช่วยให้คุณใช้งาน LLM โอเพนซอร์สเช่น Llama 3 ในพื้นที่ มันมีความเข้ากันได้กับการแชทกับ OpenAI API
คุณสามารถดาวน์โหลด Ollama ได้ที่นี่ บน 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 Chat เข้ากันได้กับ 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 Parses ข้อความแจ้งลงในโทเค็นซึ่งเป็นคำหรือบางส่วนของคำ (โทเค็นเหล่านี้ไม่เกี่ยวข้องกับ 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
เพื่อรับกระแสของชิ้นที่เสร็จสมบูรณ์ตามที่สร้างขึ้น ทุกครั้งที่ได้รับชิ้นส่วนหนึ่งหรือมากกว่านั้น PROC จะถูกเรียกหนึ่งครั้งกับแต่ละก้อนแยกวิเคราะห์เป็นแฮช หาก 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."
กด OpenAI API เพื่อให้เสร็จสมบูรณ์โดยใช้รุ่น GPT-3 อื่น ๆ :
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 เพื่อรับเวกเตอร์ของตัวเลขที่แสดงถึงอินพุต จากนั้นคุณสามารถเปรียบเทียบเวกเตอร์เหล่านี้สำหรับอินพุตที่แตกต่างกันเพื่อตรวจสอบอย่างมีประสิทธิภาพว่าอินพุตนั้นคล้ายกันอย่างไร
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
(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 แล้วคุณสามารถสร้างแบตช์ใหม่ได้โดยการให้รหัสไฟล์ปลายทางและหน้าต่างเสร็จสมบูรณ์:
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
เมื่อมีแบทช์ ["เสร็จสมบูรณ์"] คุณสามารถดึงไฟล์เอาต์พุตหรือไฟล์ข้อผิดพลาด:
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" ]
จากนั้นคุณสามารถใช้รหัสไฟล์นี้เพื่อสร้างงานปรับแต่งได้อย่างละเอียด:
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 )
วัตถุ Vector Store ให้เครื่องมือค้นหาไฟล์สามารถค้นหาไฟล์ของคุณได้
คุณสามารถสร้างร้านค้าเวกเตอร์ใหม่:
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 )
ไฟล์ vector store แสดงไฟล์ภายในร้านค้าเวกเตอร์
คุณสามารถสร้างไฟล์ vector store ใหม่โดยแนบไฟล์ไปยังร้านค้าเวกเตอร์
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
ไฟล์ vector store ทั้งหมดที่มีอยู่ภายใต้ Vector Store:
client . vector_store_files . list ( vector_store_id : "vector-store-abc123" )
คุณสามารถลบไฟล์ vector store:
client . vector_store_files . delete (
vector_store_id : "vector-store-abc123" ,
id : vector_store_file_id
)
หมายเหตุ: สิ่งนี้จะลบไฟล์ออกจากที่เก็บเวกเตอร์ แต่ตัวเองจะไม่ถูกลบ ในการลบไฟล์ให้ใช้จุดสิ้นสุดไฟล์ลบ
Batches File Vector Store แสดงถึงการดำเนินการเพื่อเพิ่มหลายไฟล์ไปยัง Vector Store
คุณสามารถสร้างแบทช์ไฟล์ Vector Store ใหม่โดยแนบหลายไฟล์เข้ากับ Vector Store
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
ไฟล์ vector store ทั้งหมดในชุดที่มีอยู่ในปัจจุบันภายใต้ vector store:
client . vector_store_file_batches . list (
vector_store_id : "vector-store-abc123" ,
id : file_batch_id
)
คุณสามารถยกเลิกชุดไฟล์ vector store (ความพยายามในการยกเลิกการประมวลผลไฟล์ในชุดนี้โดยเร็วที่สุด):
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 )
เมื่อคุณสร้างผู้ช่วยตามที่อธิบายไว้ข้างต้นคุณต้องเตรียม Thread
Messages
เพื่อให้ผู้ช่วยทำงาน (ดูบทนำเกี่ยวกับผู้ช่วย) ตัวอย่างเช่นการตั้งค่าเริ่มต้นที่คุณสามารถทำได้:
# 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
ที่เกี่ยวข้องจะมี 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 } )
นอกจากนี้คุณยังสามารถสร้างเธรดและเรียกใช้ในสายเดียวเช่นนี้:
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
(พวกเขาถูกกำหนดในลักษณะเดียวกับฟังก์ชั่นในระหว่างการแชทเสร็จสิ้น) คุณอาจได้รับรหัสสถานะของ 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 จะแบ่งปันสิ่งที่ใช้ในท่อ RAG ภายในเพื่อสร้างผลลัพธ์การค้นหาไฟล์
ตัวอย่างข้อมูลจำเพาะสามารถพบได้ที่นี่ซึ่งทำสิ่งนี้เพื่อให้คุณรู้ว่าเป็นไปได้
นี่คือวิธีรับชิ้นที่ใช้ในการค้นหาไฟล์ ในตัวอย่างนี้ฉันใช้ไฟล์นี้:
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
, 512x512
หรือ 1024x1024
- หากไม่ได้ระบุภาพจะเริ่มต้นที่ 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
, 1024x1792
หรือ 1792x1024
นอกจากนี้คุณภาพของภาพสามารถระบุได้ทั้ง 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"
การถอดความ 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
หลังจากตรวจสอบ repo ให้เรียกใช้ bin/setup
เพื่อติดตั้งการพึ่งพา คุณสามารถเรียกใช้ bin/console
สำหรับพรอมต์แบบโต้ตอบที่จะช่วยให้คุณสามารถทดลองได้
ในการติดตั้งอัญมณีนี้ลงบนเครื่องในเครื่องของคุณให้เรียกใช้ bundle exec rake install
ในการเรียกใช้การทดสอบทั้งหมดให้ดำเนินการ bundle exec rake
ซึ่งจะเรียกใช้ linter (rubocop) ที่เก็บนี้ใช้ VCR เพื่อบันทึกการร้องขอ API
คำเตือน
หากคุณมี OPENAI_ACCESS_TOKEN
ใน ENV
ของคุณการเรียกใช้ข้อมูลจำเพาะจะใช้สิ่งนี้เพื่อเรียกใช้รายละเอียดกับ API จริงซึ่งจะช้าและเสียค่าใช้จ่าย - 2 เซนต์หรือมากกว่า! ลบออกจากสภาพแวดล้อมของคุณด้วย 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 สำหรับเวอร์ชัน ไฟล์ .gem
ถึง rubygems.org
รายงานข้อผิดพลาดและคำขอดึงยินดีต้อนรับบน GitHub ที่ https://github.com/alexrudall/ruby-openai โครงการนี้มีจุดประสงค์เพื่อเป็นพื้นที่ที่ปลอดภัยและเป็นมิตรสำหรับการทำงานร่วมกันและผู้สนับสนุนคาดว่าจะปฏิบัติตามจรรยาบรรณ
อัญมณีมีให้เป็นโอเพ่นซอร์สภายใต้ข้อกำหนดของใบอนุญาต MIT
ทุกคนมีปฏิสัมพันธ์ในรหัสฐานของโครงการ Ruby Openai, ตัวติดตามปัญหา, ห้องแชทและรายชื่อผู้รับจดหมายคาดว่าจะปฏิบัติตามจรรยาบรรณ