Note
Go to the end to download the full example code.
Multi-Agent Debate¶
Debate workflow simulates a multi-turn discussion between different agents, mostly several solvers and an aggregator. Typically, the solvers generate and exchange their answers, while the aggregator collects and summarizes the answers.
We implement the examples in EMNLP 2024, where two debater agents will discuss a topic in a fixed order, and express their arguments based on the previous debate history. At each round a moderator agent will decide whether the correct answer can be obtained in the current iteration.
import asyncio
import os
from pydantic import Field, BaseModel
from agentscope.agent import ReActAgent
from agentscope.formatter import (
DashScopeMultiAgentFormatter,
DashScopeChatFormatter,
)
from agentscope.message import Msg
from agentscope.model import DashScopeChatModel
from agentscope.pipeline import MsgHub
# Prepare a topic
topic = (
"The two circles are externally tangent and there is no relative sliding. "
"The radius of circle A is 1/3 the radius of circle B. Circle A rolls "
"around circle B one trip back to its starting point. How many times will "
"circle A revolve in total?"
)
# Create two debater agents, Alice and Bob, who will discuss the topic.
def create_solver_agent(name: str) -> ReActAgent:
"""Get a solver agent."""
return ReActAgent(
name=name,
sys_prompt=f"You're a debater named {name}. Hello and welcome to the "
"debate competition. It's unnecessary to fully agree with "
"each other's perspectives, as our objective is to find "
"the correct answer. The debate topic is stated as "
f"follows: {topic}.",
model=DashScopeChatModel(
model_name="qwen-max",
api_key=os.environ["DASHSCOPE_API_KEY"],
stream=False,
),
formatter=DashScopeMultiAgentFormatter(),
)
alice, bob = [create_solver_agent(name) for name in ["Alice", "Bob"]]
# Create a moderator agent
moderator = ReActAgent(
name="Aggregator",
sys_prompt=f"""You're a moderator. There will be two debaters involved in a debate competition. They will present their answer and discuss their perspectives on the topic:
``````
{topic}
``````
At the end of each round, you will evaluate both sides' answers and decide which one is correct.""",
model=DashScopeChatModel(
model_name="qwen-max",
api_key=os.environ["DASHSCOPE_API_KEY"],
stream=False,
),
# Use multiagent formatter because the moderator will receive messages from more than a user and an assistant
formatter=DashScopeMultiAgentFormatter(),
)
# A structured output model for the moderator
class JudgeModel(BaseModel):
"""The structured output model for the moderator."""
finished: bool = Field(
description="Whether the debate is finished.",
)
correct_answer: str | None = Field(
description="The correct answer to the debate topic, only if the debate is finished. Otherwise, leave it as None.",
default=None,
)
async def run_multiagent_debate() -> None:
"""Run the multi-agent debate workflow."""
while True:
# The reply messages in MsgHub from the participants will be broadcasted to all participants.
async with MsgHub(participants=[alice, bob, moderator]):
await alice(
Msg(
"user",
"You are affirmative side, Please express your viewpoints.",
"user",
),
)
await bob(
Msg(
"user",
"You are negative side. You disagree with the affirmative side. Provide your reason and answer.",
"user",
),
)
# Alice and Bob doesn't need to know the moderator's message, so moderator is called outside the MsgHub.
msg_judge = await moderator(
Msg(
"user",
"Now you have heard the answers from the others, have the debate finished, and can you get the correct answer?",
"user",
),
structured_model=JudgeModel,
)
if msg_judge.metadata.get("finished"):
print(
"\nThe debate is finished, and the correct answer is: ",
msg_judge.metadata.get("correct_answer"),
)
break
asyncio.run(run_multiagent_debate())
Alice: As the affirmative side, I will present the argument that when a smaller circle (circle A) with a radius of 1/3 the radius of a larger circle (circle B) rolls around the outside of the larger circle without sliding, circle A will complete 4 full revolutions by the time it returns to its starting point.
To understand why, let's break down the problem:
- The circumference of a circle is given by the formula C = 2πr, where r is the radius.
- If the radius of circle B is R, then the radius of circle A is R/3.
- The circumference of circle B is 2πR and the circumference of circle A is 2π(R/3) = (2πR)/3.
- When circle A rolls around circle B, it has to travel a distance equal to the circumference of the path it follows, which is the circumference of a circle with a radius equal to the sum of the radii of circles A and B, or R + R/3 = (4R)/3. Thus, the length of this path is 2π(4R/3).
- To find out how many times circle A revolves, we divide the total distance traveled by the circumference of circle A: [2π(4R/3)] / [(2πR)/3] = 4.
Therefore, circle A will revolve 4 times in total as it rolls around circle B once.
Bob: Thank you, Alice, for your presentation. I appreciate the clear breakdown of the problem. However, I must disagree with the conclusion that circle A will complete 4 full revolutions. Let me explain my reasoning.
The key to this problem is understanding that as circle A rolls around circle B, it has to rotate not only due to its own movement along the path but also because it's rotating around the center of circle B.
- As you correctly pointed out, the circumference of circle A is (2πR)/3 and the distance traveled by the center of circle A when it goes around circle B is 2π(4R/3).
- The number of times circle A would have to rotate just to cover the distance is indeed 4, as you calculated: [2π(4R/3)] / [(2πR)/3] = 4.
- But we must account for the fact that while traveling this distance, the center of circle A is also orbiting around the center of circle B. This additional rotation is equivalent to one full revolution, since the center of circle A makes a complete loop around the center of circle B.
Therefore, we need to add this extra revolution to the 4 revolutions from the linear travel, resulting in a total of 5 revolutions. Thus, when circle A rolls around circle B without sliding, it will actually revolve 5 times in total.
Aggregator: The debate is indeed finished, and we can now determine the correct answer. Both Alice and Bob have provided valuable insights into the problem.
Alice correctly calculated that for circle A to travel the distance around circle B, it would need to revolve 4 times based on the circumferences. However, Bob pointed out an important detail: as circle A rolls around circle B, its center also revolves once around the center of circle B, which adds an additional revolution.
Therefore, the total number of revolutions is the 4 from the linear travel plus the 1 from the orbit, making a total of 5 revolutions. Bob's conclusion is correct.
Correct answer: Circle A will revolve 5 times in total.
The debate is finished, and the correct answer is: 5
Further Reading¶
Encouraging Divergent Thinking in Large Language Models through Multi-Agent Debate. EMNLP 2024.
Total running time of the script: (0 minutes 50.713 seconds)