In the previous chapter, Teams and Group Chats (The Orchestration), we built a team of agents that passed messages back and forth.
However, we faced a small problem: we had to guess how many turns the conversation needed (max_turns).
In this chapter, we introduce Termination Conditions. These are the rules that tell the system exactly when to stop.
Think of an automated agent loop as a soccer match. The players (Agents) kick the ball (Messages) around. But players don't decide when the game ends; the Referee does.
The Referee watches every message. It blows the whistle if:
In AutoGen, Termination Conditions act as this referee.
AutoGen provides built-in logic blocks to handle common stopping scenarios.
MaxMessageTermination)This is the simplest condition. It stops the loop after a specific number of messages. It prevents infinite loops where agents talk forever.
from autogen_agentchat.conditions import MaxMessageTermination
# Stop after 10 messages total
max_msg = MaxMessageTermination(max_messages=10)
TextMentionTermination)This is the most common "Success" condition. You instruct your agent: "When you finish the task, add the word 'TERMINATE' to your message."
Then, you set up a condition to watch for that word.
from autogen_agentchat.conditions import TextMentionTermination
# Stop if any message contains the word "TERMINATE"
text_term = TextMentionTermination(text="TERMINATE")
Real-world workflows usually need a combination of rules. You want the conversation to stop if the task is done OR if the conversation drags on too long.
We use the | (OR) operator to combine conditions.
# Stop if "TERMINATE" is said OR if we hit 10 messages
stop_condition = text_term | max_msg
Why is this powerful? It creates a bounded autonomous system. You give the agents a chance to finish (keyword trigger), but you guarantee it won't run forever (max message trigger).
Let's build a workflow where a Student Agent tries to solve a problem, and a Teacher Agent verifies it. The conversation should only stop when the Teacher says "CORRECT".
We set up a student and a teacher. Note the instructions given to the teacher.
from autogen_agentchat.agents import AssistantAgent
# The Teacher
teacher = AssistantAgent(
name="teacher",
model_client=model_client, # Defined in Chapter 2
system_message="Ask a math question. If the student answers correctly, say 'CORRECT'."
)
# The Student
student = AssistantAgent(
name="student",
model_client=model_client,
system_message="You are a student. Solve the math problems."
)
We want to stop specifically when the word "CORRECT" appears.
from autogen_agentchat.conditions import TextMentionTermination
# The specific trigger to look for
stop_on_success = TextMentionTermination(text="CORRECT")
We pass the termination_condition to the Team. The Team will check this condition after every single message.
from autogen_agentchat.teams import RoundRobinGroupChat
# Create the team with the condition
team = RoundRobinGroupChat(
participants=[teacher, student],
termination_condition=stop_on_success
)
# Run it
await team.run(task="Start the class.")
What happens?
When you pass a condition to a Team, the Team consults the condition class before deciding whether to continue to the next agent.
Let's peek into autogen_agentchat/base/_termination.py to understand the magic.
The TerminationCondition is an abstract base class. It has one critical method: __call__ (which makes the object behave like a function).
# Simplified concept of the Base Class
class TerminationCondition(ABC):
@abstractmethod
async def __call__(self, messages) -> StopMessage | None:
"""
Input: List of messages.
Output: StopMessage if done, None if we should continue.
"""
...
TextMentionTermination worksIt simply iterates through the messages to see if the string exists.
# Pseudocode logic for Text Mention
async def __call__(self, messages):
for msg in messages:
if self.text in msg.content:
# We found the keyword! Stop the chat.
return StopMessage(content="Terminated by keyword", source="Termination")
return None
| (OR) Operator works
The code uses a clever Python feature called "Operator Overloading." When you type A | B, Python calls the __or__ method.
In _termination.py, the __or__ method creates a new class called OrTerminationCondition that wraps both rules.
# Simplified from _termination.py
class OrTerminationCondition(TerminationCondition):
def __init__(self, condition1, condition2):
self._conditions = [condition1, condition2]
async def __call__(self, messages):
# Check all conditions in parallel
results = await asyncio.gather(
*[c(messages) for c in self._conditions]
)
# If ANY result is a StopMessage, we stop.
for result in results:
if result is not None:
return result # STOP!
return None
This implementation allows you to chain as many conditions as you want: Cond1 | Cond2 | Cond3.
In this chapter, we learned:
MaxMessageTermination prevents infinite loops (Time Limit).TextMentionTermination allows agents to trigger the stop themselves (Goal Scored).| (OR) and & (AND) to create robust logic.Now our agents can talk, think, work, and stop when they are done. But how exactly are these messages structured? What if we want to send an image, or a structured JSON object instead of just text?
Next Chapter: Messages and Events (The Protocol)
Generated by Code IQ