Ruby GigaChat
Installation
Bundler
Add this line to your application's Gemfile:
gem "gigachat"
And then execute:
$ bundle install
Gem install
Or install with:
$ gem install gigachat
and require with:
require "gigachat"
Usage
Get your API key from developers.sber.ru.
Quickstart
For a quick test you can pass your token directly to a new client:
client = GigaChat::Client.new(
api_type: "GIGACHAT_API_CORP", # or GIGACHAT_API_PERS, GIGACHAT_API_B2B
client_base64: "Yjgy...VhYw==" # your authorization data
)
With Config
For a more robust setup, you can configure the gem with your API keys, for example in an gigachat.rb
initializer file. Never hardcode secrets into your codebase - instead use something like dotenv to pass the keys safely into your environments.
GigaChat.configure do |config|
config.api_type = "GIGACHAT_API_CORP" # or GIGACHAT_API_PERS, GIGACHAT_API_B2B
config.client_base64 = ENV.fetch("GIGACHAT_CLIENT_KEY")
end
Then you can create a client like this:
client = GigaChat::Client.new
You can still override the config defaults when making new clients; any options not included will fall back to any global config set with GigaChat.configure. e.g. in this example the api_type, etc. will fallback to any set globally using GigaChat.configure, with only the client_base64 overridden:
client = GigaChat::Client.new(client_base64: "secret_token_goes_here")
Custom timeout or base URI
The default timeout for any request using this library is 120 seconds. You can change that by passing a number of seconds to the request_timeout
when initializing the client. You can also change the base URI used for all requests, eg. to use observability tools like Helicone, and add arbitrary other headers:
client = GigaChat::Client.new(
client_base64: "secret_token_goes_here",
uri_base: "https://oai.hconeai.com/",
uri_auth: "https://localhost:5362/",
request_timeout: 240,
extra_headers: {
"X-Proxy-TTL" => "43200",
"X-Proxy-Refresh": "true",
}
)
or when configuring the gem:
GigaChat.configure do |config|
config.client_base64 = ENV.fetch("GIGACHAT_CLIENT_KEY")
config.log_errors = true # Optional
config.uri_base = "https://oai.hconeai.com/" # Optional
config.request_timeout = 240 # Optional
config.extra_headers = {
"X-Proxy-TTL" => "43200",
"X-Proxy-Refresh": "true"
} # Optional
end
Extra Headers per Client
You can dynamically pass headers per client object, which will be merged with any headers set globally with GigaChat.configure:
client = GigaChat::Client.new(client_base64: "secret_token_goes_here")
client.add_headers("X-Proxy-TTL" => "43200")
Logging
Errors
By default, gigachat
does not log any Faraday::Error
s encountered while executing a network request to avoid leaking data (e.g. 400s, 500s, SSL errors and more - see here for a complete list of subclasses of Faraday::Error
and what can cause them).
If you would like to enable this functionality, you can set log_errors
to true
when configuring the client:
client = GigaChat::Client.new(log_errors: true)
Faraday middleware
You can pass Faraday middleware to the client in a block, eg. to enable verbose logging with Ruby's Logger:
client = GigaChat::Client.new do |f|
f.response :logger, Logger.new($stdout), bodies: true
end
Counting Tokens
GigaChat parses prompt text into tokens, which are words or portions of words. Counting tokens can help you estimate your costs. It can also help you ensure your prompt text size is within the max-token limits of your model's context window, and choose an appropriate max_tokens
completion parameter so your response will fit as well.
To estimate the token-count of your text:
GigaChat.rough_token_count("Your text")
If you need a more accurate count, try tiktoken_ruby.
Models
There are different models that can be used to generate text. For a full list and to retrieve information about a single model:
client.models.list
client.models.retrieve(id: "GigaChat-Pro")
Chat
GigaChat is a model that can be used to generate text in a conversational style. You can use it to generate a response to a sequence of messages:
response = client.chat(
parameters: {
model: "GigaChat-Pro", # Required.
messages: [{ role: "user", content: "Hello!"}], # Required.
temperature: 0.7,
})
puts response.dig("choices", 0, "message", "content")
# => "Hello! How may I assist you today?"
Streaming Chat
You can stream from the API in realtime, which can be much faster and used to create a more engaging user experience. Pass a Proc (or any object with a #call
method) to the stream
parameter to receive the stream of completion chunks as they are generated. Each time one or more chunks is received, the proc will be called once with each chunk, parsed as a Hash. If GigaChat returns an error, gigachat
will raise a Faraday error.
client.chat(
parameters: {
model: "GigaChat-Pro", # Required.
messages: [{ role: "user", content: "Describe a character called Anna!"}], # Required.
temperature: 0.7,
update_interval: 1,
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..."
Functions
You can describe and pass in functions and the model will intelligently choose to output a JSON object containing arguments to call them - eg., to use your method get_current_weather
to get the weather in a given location.
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: "GigaChat-Pro",
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"],
},
},
}
],
function_call: "none" # Optional, defaults to "auto"
# Can also put "none" or specific functions, see docs
},
)
You can learn more at this link.
Embeddings
You can use the embeddings endpoint to get a vector of numbers representing an input. You can then compare these vectors for different inputs to efficiently check how similar the inputs are.
response = client.embeddings(
parameters: {
model: "GigaChat",
input: "The food was delicious and the waiter..."
}
)
puts response.dig("data", 0, "embedding")
# => Vector representation of your embedding
Image Generation
GigaChat API will return an image if the #chat
method receives an appropriate message, for example, "Draw a pink cat". Images are generated in binary form in JPG format using the built-in text2image function.
In response, GigaChat returns the identifier of the created image, which can be downloaded using the POST /files/:file_id/content
request.
To create an image, the request must include the "function_call": "auto" parameter, which allows the model to determine the need to call the text2image function. When creating images using the built-in function, the model returns a response with the result "finish_reason": "stop"
.
You can learn more at this link.
Errors
HTTP errors can be caught like this:
begin
GigaChat::Client.new.models.retrieve(id: "GigaChat")
rescue Faraday::Error => e
raise "Got a Faraday error: #{e}"
end
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/neonix20b/gigachat. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Ruby OpenAI project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.