Skip to content

Commit

Permalink
Two agents talking to each other (#3)
Browse files Browse the repository at this point in the history
* Two agents talking to each other

* Try it
  • Loading branch information
drnic authored Apr 25, 2024
1 parent 463c102 commit 8d90413
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 3 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ env:
on:
push:
branches:
- develop
- 'develop'

# allow CI on any pull request
pull_request:
branches:
- '*'

jobs:
build:
Expand Down
26 changes: 26 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,29 @@ bundle exec examples/user-chat.rb --agent-prompt examples/agent-prompts/pizzeria
> The conversation started with a customer calling the pizzeria and speaking with an AI assistant. The assistant offered to help with menu inquiries or taking an order. The customer was considering ordering from the menu. The assistant presented the cheapest menu item, Garlic Knots, and asked if the customer wanted to add it to their order. The customer may have been interested in other options as well. The assistant then presented the cheapest pizza option, the Veggie Pizza, and asked if the customer wanted to order it along with the Garlic Knots. The customer agreed, and the assistant took note of the order, which consisted of a Veggie Pizza and 6 Garlic Knots for a total of $18. The assistant asked how the customer would like to pay for their order.
>
> 😋 exit
## Two Agents

Here is an example of two agents talking to each other, without any user input.

### Buying Pizza

```bash
bundle exec examples/groq-two-agents-chatting.rb --agent-prompt examples/agent-prompts/pizzeria-sales.yml --agent-prompt examples/agent-prompts/food-customer.yml
```

This will proceed for 10 turns, with the agents taking turns to speak. Pass the `-i 15` option to increase the number of turns.

> 🍕 Hello! Welcome to Pizza Palace. Thank you for reaching out to us. How can I assist you today?
>
> 😋 Hi! Thanks for having me. I'm actually pretty hungry, so I'm looking to order some food. Can you tell me a bit about your menu? What are some of your popular items?
>
> 🍕 I'd be happy to tell you more about our menu. We have a variety of delicious options to choose from. Our most popular items include our Margherita Pizza, Pepperoni Pizza, and BBQ Chicken Pizza. The Margherita is a classic with tomato sauce, mozzarella, and fresh basil. The Pepperoni Pizza is a crowd-pleaser with a generous layer of pepperoni on top. And our BBQ Chicken Pizza has a sweet and tangy BBQ sauce, topped with chicken, onions, and cilantro.
>
> We also have some great non-pizza options, such as our Garlic Knots, which are a favorite among our customers. And for dessert, our Cannoli are a must-try - they're filled with creamy ricotta cheese and chocolate chips.
>
> What sounds good to you? Would you like me to walk you through our entire menu or is there something specific you're in the mood for?
>
> 😋 Mmm, everything sounds delicious! I think I'll go for something a bit hearty. Can you tell me more about the BBQ Chicken Pizza? What kind of chicken is used? And is the pepperoni on the Pepperoni Pizza thick-cut or thin-cut?
>
> Also, how would you recommend ordering the Garlic Knots? Are they a side dish or can I get them as part of a combo?
12 changes: 12 additions & 0 deletions examples/agent-prompts/food-customer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
name: "Food Customer"
system_prompt: |-
You are a hungry customer looking to order some food.
You can ask about the menu, place an order, or inquire about delivery options.
When asked about delivery, you say you'll pick up.
When asked about payment, you confirm you'll pay when you pick up.
You have $25 to spend.
agent_emoji: "😋"
can_go_first: true
3 changes: 2 additions & 1 deletion examples/agent-prompts/helloworld.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
system: |-
name: "Hello World"
system_prompt: |-
I am a friendly agent who always replies to any prompt
with a pleasant "Hello" and wishing them well.
agent_emoji: "🤖"
Expand Down
3 changes: 2 additions & 1 deletion examples/agent-prompts/pizzeria-sales.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
system: |-
name: "Pizzeria Sales"
system_prompt: |-
You are a phone operator at a busy pizzeria. Your responsibilities include answering calls and online chats from customers who may ask about the menu, wish to place or change orders, or inquire about opening hours.
Here are some of our popular menu items:
Expand Down
124 changes: 124 additions & 0 deletions examples/groq-two-agents-chatting.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/env ruby
#
# This is a variation of groq-user-chat.rb but without any user prompting.
# Just two agents chatting with each other.

require "optparse"
require "groq"
require "yaml"

include Groq::Helpers

@options = {
model: "llama3-8b-8192",
# model: "llama3-70b-8192",
agent_prompt_paths: [],
timeout: 20,
interaction_count: 10 # total count of interactions between agents
}
OptionParser.new do |opts|
opts.banner = "Usage: ruby script.rb [options]"

opts.on("-m", "--model MODEL", "Model name") do |v|
@options[:model] = v
end

opts.on("-a", "--agent-prompt PATH", "Path to an agent prompt file") do |v|
@options[:agent_prompt_paths] << v
end

opts.on("-t", "--timeout TIMEOUT", "Timeout in seconds") do |v|
@options[:timeout] = v.to_i
end

opts.on("-d", "--debug", "Enable debug mode") do |v|
@options[:debug] = v
end

opts.on("-i", "--interaction-count COUNT", "Total count of interactions between agents") do |v|
@options[:interaction_count] = v.to_i
end
end.parse!

raise "New two --agent-prompt paths" if @options[:agent_prompt_paths]&.length&.to_i != 2

def debug?
@options[:debug]
end

# Will be instantiated from the agent prompt file
class Agent
def initialize(args = {})
args.each do |k, v|
instance_variable_set(:"@#{k}", v)
end
@messages = [S(@system_prompt)]
end
attr_reader :messages
attr_reader :name, :can_go_first, :user_emoji, :agent_emoji, :system_prompt
def can_go_first?
@can_go_first
end

def self.load_from_file(path)
new(YAML.load_file(path))
end
end

# Read the agent prompt from the file
agents = @options[:agent_prompt_paths].map do |agent_prompt_path|
Agent.load_from_file(agent_prompt_path)
end
go_first = agents.find { |agent| agent.can_go_first? } || agents.first

# check that each agent contains a system prompt
agents.each do |agent|
raise "Agent #{agent.name} is missing a system prompt" if agent.system_prompt.nil?
end

# Initialize the Groq client
@client = Groq::Client.new(model_id: @options[:model], request_timeout: @options[:timeout]) do |f|
if debug?
require "logger"

# Create a logger instance
logger = Logger.new($stdout)
logger.level = Logger::DEBUG

f.response :logger, logger, bodies: true # Log request and response bodies
end
end

puts "Welcome to a conversation between #{agents.map(&:name).join(", ")}. Our first speaker will be #{go_first.name}."
puts "You can quit by typing 'exit'."

agent_speaking_index = agents.index(go_first)
loop_count = 0

loop do
speaking_agent = agents[agent_speaking_index]
# Show speaking agent emoji immediately to indicate request going to Groq API
print("#{speaking_agent.agent_emoji} ")

# Use Groq to generate a response
response = @client.chat(speaking_agent.messages)

# Finish the speaking agent line on screen with message response
puts(message = response.dig("content"))

# speaking agent tracks its own message as the Assistant
speaking_agent.messages << A(message)

# other agent tracks the message as the User
other_agents = agents.reject { |agent| agent == speaking_agent }
other_agents.each do |agent|
agent.messages << U(message)
end

agent_speaking_index = (agent_speaking_index + 1) % agents.length
loop_count += 1
break if loop_count > @options[:interaction_count]
rescue Faraday::TooManyRequestsError
warn "...\n\nGroq API error: too many requests. Exiting."
exit 1
end

0 comments on commit 8d90413

Please sign in to comment.