ActiveAI
AI AS COMPUTE
Artificial Intelligence the Rails way.
Supported by gamebreakers community - AI is for everyone <3
Usage
L0: Interacting directly with neural networks
GPT3
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.'
TODO: others
L1: Using behavior patterns to interact with neural networks
With structured examples
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'
Behavior: WriteFunctionCall
TODO
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.
TODO: with other patterns
TODO: auto-detected behavior pattern from config
L2: Rails magic for neural networks
This is the fun part!
Suppose you have the following files:
config/routes/bank.yml
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
controllers/bank_controller.rb
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
How to use it
Running a controller directly
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
Routing an unknown request with multiple controllers
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
Please help make this better!
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!