Friday, September 4, 2026
HomeRuby On RailsOperate Calling | Drifting Ruby

Operate Calling | Drifting Ruby


# 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

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments