Class: ReactAi::Agent

Inherits:
Object
  • Object
show all
Defined in:
lib/react_ai.rb

Instance Method Summary collapse

Constructor Details

#initialize(agent_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: 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") ⇒ Agent

Returns a new instance of Agent.



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
# File 'lib/react_ai.rb', line 12

def initialize(agent_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:
  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")
  @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

Instance Method Details

#calculate(expr) ⇒ Object



82
83
84
85
86
# File 'lib/react_ai.rb', line 82

def calculate(expr)
  # consider integrating dentaku instead of using eval() which is unsafe
  # https://github.com/rubysolo/dentaku
  eval(expr)
end

#execute(question) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/react_ai.rb', line 96

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

#query(question, max_iterations) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/react_ai.rb', line 57

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 # standard:disable Lint/NonLocalExitFromIterator
    end
  end
end

#wikipedia(query) ⇒ Object



88
89
90
91
92
93
94
# File 'lib/react_ai.rb', line 88

def wikipedia(query)
  uri = URI("https://en.wikipedia.org/w/api.php")
  params = {action: "query", list: "search", srsearch: query, format: "json"}
  uri.query = URI.encode_www_form(params)
  res = Net::HTTP.get_response(uri)
  JSON.parse(res.body)["query"]["search"][0]["snippet"]
end