-
Notifications
You must be signed in to change notification settings - Fork 1
/
ruby-re-act.sh
executable file
·132 lines (102 loc) · 3.06 KB
/
ruby-re-act.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env ruby
#frozen_string_literal: true
require "bundler/inline"
gemfile do
source "https://rubygems.org"
ruby "3.1.1"
gem "byebug"
gem "dotenv"
gem "ruby-openai"
gem "wikipedia-client"
end
require "dotenv/load"
require "openai"
require "yaml"
require 'wikipedia'
require 'byebug'
class ReAct
require 'dotenv/load'
def initialize(agent_prompt: nil)
@client = OpenAI::Client.new(access_token: ENV["OPEN_AI_KEY"])
@messages = []
@known_actions = [
"wikipedia",
"calculate"
]
unless agent_prompt.nil?
@messages << { "role" => "system", "content" => agent_prompt }
end
end
def query(question, max_iterations)
next_prompt = question
max_iterations.times do |i|
result = execute(next_prompt)
print result
actions = result.split("\n").map{ |a| /^Action: (\w+): (.*)$/.match(a)}.compact.first
if actions
tool = actions[1]
action_input = actions[2]
unless @known_actions.include?(tool)
raise "Unknown Action: #{tool}"
end
puts " -- running #{tool} #{action_input}"
observation = send(tool, action_input)
puts "Observation: #{observation}"
next_prompt = "Observation: #{observation}"
else
return
end
end
end
def calculate(expr)
eval(expr)
end
def execute(question)
@messages << { "role" => "user", "content" => question }
response = @client.chat(
parameters: {
model: "gpt-3.5-turbo",
messages: @messages
}
)
result = response.dig("choices").first.dig("message").dig("content")
@messages << { "role" => "assistant", "content" => result }
result
end
end
def main
prompt = "You run in a loop of Thought, Action, PAUSE, Observation.
At the end of the loop you output an Answer
Use Thought to describe your thoughts about the question you have been asked.
Use Action to run one of the actions available to you - then return PAUSE.
Observation will be the result of running those actions.
Your available actions are:
calculate:
e.g. calculate: 4 * 7 / 3
Runs a calculation and returns the number - uses Ruby so be sure to use floating point syntax if necessary
wikipedia: (NOT IMPLEMENTED YET)
e.g. wikipedia: Ruby On Rails
Returns a summary from searching Wikipedia
Always look things up on Wikipedia if you have the opportunity to do so.
Example session:
Question: What is the capital of France?
Thought: I should look up France on Wikipedia
Action: wikipedia: France
PAUSE
You will be called again with this:
Observation: France is a country. The capital is Paris.
You then output:
Answer: The capital of France is Paris"
while true
print "input -> "
input = gets.chomp
agent = ReAct.new(agent_prompt: prompt)
if input.downcase == "exit"
break
else
response = agent.query(input, 5)
puts response
end
end
end
main if $PROGRAM_NAME == __FILE__