Skip to content

Getting Started

Francis edited this page Apr 21, 2023 · 2 revisions

Boxcars is a gem that enables you to create new systems with AI composability, using various concepts such as OpenAI, Search, SQL, Rails Active Record and more (including your concepts).

This work was inspired by the popular Python library Langchain. However, we wanted to give it a Ruby spin and make it more user-friendly for beginners to get started.

Concepts

All of these concepts are in a module named Boxcars:

  • Prompt: used by an Engine to generate text results.
  • Engine: an entity that generates text from a Prompt. OpenAI's LLM text generatory is the default Engine if no other is specified.
  • Boxcar: an encapsulation of a concept that performs something of interest (such as search, math, or SQL). A can use an Engine to do its work.
  • Train: Given a list of Boxcars and an optionally an Engine, a Train breaks down a problem into pieces for individual Boxcars to solve. The individual results are then combined until a final answer is found. ZeroShot is the only current implementation of Train, and you can either construct it directly or use Boxcars::train when you want to build a Train.

Installation

Add this line to your application's Gemfile:

gem 'boxcars'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install boxcars

Usage

We will be adding more examples soon, but here are a couple to get you started. First, you'll need to set up your environment variables for OpenAI and Google SERP (OPENAI_ACCESS_TOKEN, SERPAPI_API_KEY). If you prefer not to set these variables in your environment, you can pass them directly into the API.

In the examples below, we added one rubygem to load the environment at the first line, but depending on what you want, you might not need this.

require "dotenv/load"
require "boxcars"

Note: if you want to try out the examples below, run this command and then paste in the code segments of interest:

irb -r dotenv/load -r boxcars

Direct Boxcar Use

# run the calculator
engine = Boxcars::Openai.new(max_tokens: 256)
calc = Boxcars::Calculator.new(engine: engine)
puts calc.run "what is pi to the forth power divided by 22.1?"

Produces:

> Entering Calculator#run
what is pi to the forth power divided by 22.1?
RubyREPL: puts(Math::PI**4 / 22.1)
Answer: 4.407651178009159

4.407651178009159
< Exiting Calculator#run
4.407651178009159

Note that since Openai is currently the most used Engine, if you do not pass in an engine, it will default as expected. So, this is the equialent shorter version of the above script:

# run the calculator
calc = Boxcars::Calculator.new # just use the default Engine
puts calc.run "what is pi to the forth power divided by 22.1?"

Boxcars currently implemmented

Here is what we have so far, but please put up a PR with your new ideas.

  • GoogleSearch: uses the SERP API to do searches
  • WikipediaSearch: similar, but only searches Wikipedia (and you do not need a key)
  • Calculator: uses an Engine to generate ruby code to do math
  • SQL: given an ActiveRecord connection, it will generate and run sql statments from a prompt.
  • ActiveRecord: like the SQL Boxcar, uses ActiveRecord statement generation and running from a prompt.

Engines currently implemented

There are several new LLM's seeminly being released every week. If you have one you like, just copy the Openai engine and submit your PR. Here is what we currently have

  • Openai - the OpenAI API. You can pass the model you want to use, or let it default to gpt-3.5-turbo
  • Gpt4all_eng - Just added. Run your Boxcars locally.

Run a list of Boxcars

# run a Train for a calculator, and search using default Engine
boxcars = [Boxcars::Calculator.new, Boxcars::GoogleSearch.new]
train = Boxcars.train.new(boxcars: boxcars)
puts train.run "What is pi times the square root of the average temperature in Austin TX in January?"

Produces:

> Entering Zero Shot#run
What is pi times the square root of the average temperature in Austin TX in January?
Question: Average temperature in Austin TX in January
Answer: increase from 62°F to 64°F
#Observation: increase from 62°F to 64°F
> Entering Calculator#run
64°F x pi
RubyREPL: puts (64 * Math::PI).round(2)
Answer: 201.06

201.06
< Exiting Calculator#run
#Observation: 201.06
I now know the final answer
Final Answer: 201.06
< Exiting Zero Shot#run
201.06