Artificial Intelligence the Rails way.
Supported by gamebreakers community - AI is for everyone <3
gpt3 = ActiveAI::NeuralNetwork::GPT3.new(ENV['OPEN_AI_TOKEN'])
prompt = "Never gonna give you up, never gonna"
puts gpt3.complete(prompt: prompt)['choices'].first['text']
#=> 'let you down, never gonna run around and hurt you.'
llm = ActiveAI::NeuralNetwork::GPT3.new(ENV['OPEN_AI_TOKEN'], model: 'text-curie-001')
behavior = ActiveAI::Behavior::LLM::FollowStructuredExamples.new(llm, {
instruction: 'Write a comma-separated list of nouns in the following sentences:',
examples: [
{ sentence: 'I have some veggie burgers in the freezer!', nouns: 'burgers, freezer' }
# a couple of examples improves performance!
]
})
result = behavior.call({ sentence: 'My tomatoes are in bloom this summer, time for jam!' }, extract: %W[nouns])
puts result
#=> 'tomatoes, jam'
This lets you use code-davinci-002
or code-cushman-001
to run logic. The router uses this internally. Supply a list of example pairs that are a "description" and "code", and then you can complete another one.
This is the fun part!
Suppose you have the following files:
instruction:
For a given Match request, choose where to send it via the "Route" field and choose the params that fit best.
If nothing matches, the "Route" field should be None.
examples:
- Match: Check the weather
Route: none
- Match: Send R100 to Jomiro
Route: bank#transfer_money
Params: { beneficiaryId: 12345, amount: 100.0 }
- Match: Pay Mom R245 for groceries
Route: bank#transfer_money
Params: { beneficiaryId: 98765, amount: 245.0, reference: "Groceries <3" }
- Match: What's my bank balance?
Route: bank#check_balance
class BankController < ActiveAI::Controller
auto_load_routing # loads routing config from config/routes/bank.yml
load_routing(config) # alternatively, loads routing config from a hash
def check_balance
# Make an API request to GET bank.com/balance and return some useful data
end
def transfer_money
# Make an API request to POST bank.com/transfer with params and return some useful data
end
end
Using the routing yml file and an LLM, the controller will turn any text request into an action to run, with parameters to supply, and then execute it.
controller = BankController.new
controller.call("Pay Mom R127 for groceries")
# => responds with the result of an action that ran with params
It's possible to instantiate an ActiveAI::Router
, load up the examples from multiple controllers, and then have it handle many types of requests. It does this in a similar way to how the controller uses an LLM to map to action and params, but it concatenates all controller routing examples and strips out the parameter preparation step for efficiency, since the controller handles this.
router = ActiveAI::Router.new # TODO you need to add providers now.. should be optional?
# load all auto-detected routes:
router.auto_load_routing(Rails.root.join('config','routes')) # loads all .yml files as controller examples
# or, load config via path or manually from a config hash:
router.add_controller_routing_from_path(Rails.root.join("config", "routes", "bank.yml"))
slack_routing = YAML::load(File.read(Rails.root.join("config", "routes", "slack.yml"))
router.add_controller_routing(slack_routing)
Once the routes are loaded, requests will be passed to a matched controller, if any matches. You can match and run requests like this:
router.call("Send a Slack message saying 'Hey everyone!") # returns the successful action
router.call("Transfer R5,000 to savings") # returns the successful action
router.call("Visit grandma") # returns nil
Or if you just want to find the controller:
router.find_controller("Transfer money out of savings")
# => BankController
This is an experiment to push the boundaries of "AI as compute" and it would be awesome to have more eager explorers to play with!