Skip to content

Commit

Permalink
JSON mode
Browse files Browse the repository at this point in the history
  • Loading branch information
drnic committed Apr 20, 2024
1 parent 43dd4a1 commit da1284b
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 2 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ include Groq::Helpers
# => {"role"=>"assistant", "content"=>"Cat"}
```

JSON mode:

```ruby
response = @client.chat([
S("Reply with JSON. Use {\"number\": 7} for the answer."),
U("What's 3+4?")
], json: true)
# => {"role"=>"assistant", "content"=>"{\"number\": 7}"}

JSON.parse(response["content"])
# => {"number"=>7}
```

## Installation

Install the gem and add to the application's Gemfile by executing:
Expand Down Expand Up @@ -190,6 +203,28 @@ Assistant reply with model gemma-7b-it:
{"role"=>"assistant", "content"=>"Hello to you too! 👋🌎 It's great to hear from you. What would you like to talk about today? 😊"}
```

### JSON mode

JSON mode is a beta feature that guarantees all chat completions are valid JSON.

To use JSON mode:

1. Pass `json: true` to the `chat()` call
2. Provide a system message that contains `JSON` in the content, e.g. `S("Reply with JSON")`

A good idea is to provide an example JSON schema in the system message that you'd prefer to receive.

```ruby
response = @client.chat([
S("Reply with JSON. Use {\"number\": 7} for the answer."),
U("What's 3+4?")
], json: true)
# => {"role"=>"assistant", "content"=>"{\"number\": 7}"}

JSON.parse(response["content"])
# => {"number"=>7}
```

### Tools/Functions

LLMs are increasingly supporting deferring to tools or functions to fetch data, perform calculations, or store structured data. Groq Cloud in turn then supports their tool implementations through its API.
Expand Down
5 changes: 3 additions & 2 deletions lib/groq/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def initialize(config = {}, &faraday_middleware)
end

# TODO: support stream: true; or &stream block
def chat(messages, model_id: nil, tools: nil, max_tokens: nil, temperature: nil)
def chat(messages, model_id: nil, tools: nil, max_tokens: nil, temperature: nil, json: false)
unless messages.is_a?(Array) || messages.is_a?(String)
raise ArgumentError, "require messages to be an Array or String"
end
Expand All @@ -38,7 +38,8 @@ def chat(messages, model_id: nil, tools: nil, max_tokens: nil, temperature: nil)
messages: messages,
tools: tools,
max_tokens: max_tokens || @max_tokens,
temperature: temperature || @temperature
temperature: temperature || @temperature,
response_format: json ? {type: "json_object"} : nil
}.compact
response = post(path: "/openai/v1/chat/completions", body: body)
if response.status == 200
Expand Down
74 changes: 74 additions & 0 deletions test/fixtures/vcr_cassettes/llama3-8b-8192/chat_json_mode.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions test/groq/test_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ def test_chat_messages_with_U_A_helpers
end
end

def test_json_mode
VCR.use_cassette("llama3-8b-8192/chat_json_mode") do
client = Groq::Client.new(model_id: "llama3-8b-8192")
response = client.chat([
S("Reply with JSON. Use {\"number\": 7} for the answer."),
U("What's 3+4?")
], json: true)
assert_equal response, {"role" => "assistant", "content" => "{\"number\": 7}"}
end
end

def test_tools_weather_report
VCR.use_cassette("mixtral-8x7b-32768/chat_tools_weather_report") do
client = Groq::Client.new(model_id: "mixtral-8x7b-32768")
Expand Down

0 comments on commit da1284b

Please sign in to comment.