# Terminal bundle add ruby-openai bin/rails credentials:edit bin/rails g mannequin merchandise identify inventory:integer bin/rails g controller assistants index
# config/initializers/openai.rb OpenAI.configure do |config| config.access_token = Rails.utility.credentials.dig(:openai, :access_token) finish
# config/routes.rb Rails.utility.routes.draw do sources :assistants, solely: [ :index, :create ] root to: "assistants#index" get "up" => "rails/well being#present", as: :rails_health_check finish
# Credentials File openai: access_token: YOURTOKEN
# app/controllers/assistants_controller.rb
class AssistantsController < ApplicationController
def index
finish
def create
@query = params[:question]
@reply = Assistant.new.ask(@query)
render :index, standing: :see_other
finish
finish
# app/views/assistants/index.html.erb
<div class="mx-auto mt-16 max-w-xl px-4">
<h1 class="text-2xl font-bold">Stock Assistant</h1>
<%= form_with url: assistants_path, technique: :submit, class: "mt-6 glex gap-2" do |kind| %>
<%= kind.text_field :query,
worth: @query,
placeholder: "What number of highway helmets do now we have?",
class: "flex-1 rounded border border-gray-300 px-3 py-2" %>
<%= kind.submit "Ask", class: "rounded bg-blue-600 px-4 py-2 font-medium text-white cursor-pointer" %>
<% finish %>
<% if @reply %>
<div class="mt-6 rounded border border-gray-200 bg-gray-50 p-4">
<%= @reply %>
</div>
<% finish %>
</div>
# app/fashions/assistant.rb
class Assistant
SYSTEM_PROMPT = "You're a listing assistant for our retailer. "
"All the time use the check_inventory instrument to reply questions on merchandise "
"and inventory ranges. Solely talk about merchandise that the instrument returns."
TOOLS = [
{
type: "function",
function: {
name: "check_inventory",
description: "Search the store's products by name and return matching products with their stock levels. Use a broad term like 'helmet' to list all helmets.",
parameters: {
type: "object",
properties: { product_name: { type: "string" } },
required: [ "product_name" ]
}
}
}
]
def initialize
@consumer = OpenAI::Shopper.new
finish
def ask(query)
messages = [
{ role: "system", content: SYSTEM_PROMPT },
{ role: "user", content: question }
]
message = chat(messages).dig("selections", 0, "message")
if (tool_call = message.dig("tool_calls", 0))
Rails.logger.data "✅✅✅✅✅✅ #{tool_call}"
messages << message
messages << tool_result(tool_call)
message = chat(messages).dig("selections", 0, "message")
finish
message["content"]
finish
personal
def chat(messages)
@consumer.chat(parameters: { mannequin: "gpt-4o-mini", messages:, instruments: TOOLS })
finish
def tool_result(tool_call)
args = JSON.parse(tool_call.dig("perform", "arguments"))
merchandise = Product.the place("identify LIKE ?", "%#{args["product_name"]}%")
{
position: "instrument",
tool_call_id: tool_call["id"],
content material: merchandise.any? ? merchandise.map { |p| "#{p.identify}: #{p.inventory} in inventory" }.be a part of("n") : "not discovered"
}
finish
finish

