Skip to content

Deprecation

From version 0.9, the swarm functionality has been merged into a new group chat. The new group chat functionality supports all of the swarm capabilities, and more.

For this reason, we have deprecated the swarm code but you can still run it for now.

In this page, we will cover the difference between the swarm functionality and the new group chat and provide guidance on how to update your swarm code to either (a) the new group chat or (b) to continue to work with version 0.9.

Warning

There isn't a set date or version for the deprecated swarm code to be removed from the code base. We will endeavour to provide sufficient notice but advise you to change your code to the new group chat when possible.

You can find the documentation for the swarm in the 0.8.7 version of the documentation here.

How to keep running your Swarm code in v0.9 and up#

Here are the changes you'll need to make to your code to run your Swarm code in v0.9. You will be up and running with your existing code by making these two simple changes.

Imports#

The following functions are no longer available for importing directly from the autogen module (and shouldn't be used for the new group chat):

  • AFTER_WORK
  • AfterWork
  • AfterWorkOption
  • initiate_swarm_chat
  • ON_CONDITION
  • OnCondition
  • OnContextCondition
  • register_hand_off
  • SwarmAgent
  • SwarmResult

Update your imports to be from autogen.agentchat.contrib.swarm_agent:

from autogen.agentchat.contrib.swarm_agent import (
    AfterWork,
    AfterWorkOption,
    initiate_swarm_chat,
    OnCondition,
    OnContextCondition,
    register_hand_off,
    SwarmAgent,
    SwarmResult,
)

For ContextExpression and ContextStr, these are available to import from the new group module:

from autogen.agentchat.group import (
    ContextExpression,
    ContextStr,
)

Context Variables#

Prior to version 0.9, the context variables associated with a swarm (and the ConversableAgents in the swarm) were a dictionary (type: dict[str, Any]). This has now been put into a dedicated class called ContextVariables. When interacting with your context variables, this still appears as a dictionary.

To use the context variables on an agent instance, access them via the agent's context_variable attribute, e.g. triage_agent.context_variables.get("my_key").

The changes you will need to make are to (1) change the import location and (2) change your type references from dict[str, Any] to ContextVariables.

# Import the class
from autogen.agentchat.group import ContextVariables

# 1. Creating your context variables

# Prior to v0.9
my_context_variables = {
    "basic_agent_confidence": 0,
    "intermediate_agent_confidence": 0,
    "advanced_agent_confidence": 0,
}

# v0.9 and up - dictionary is wrapped with ContextVariables
my_context_variables = ContextVariables(data={
    # Agent-specific variables
    "basic_agent_confidence": 0,
    "intermediate_agent_confidence": 0,
    "advanced_agent_confidence": 0,
})

# 2. Functions used as tools

# Prior to v0.9
def my_function(location: str, context_variables: dict[str, Any]) -> SwarmResult:
    """Important docstring for my function."""
    return SwarmResult(agent=the_next_agent, context_variables=context_variables, values="The weather is very hot!")

# v0.9 and up - replace context_variables parameter type of dict[str, Any] with ContextVariables
def my_function(location: str, context_variables: ContextVariables) -> SwarmResult:
    """Important docstring for my function."""
    return SwarmResult(agent=the_next_agent, context_variables=context_variables, values="The weather is very hot!")

Migrate from Swarm code to the new Group Chat#

In this section we will cover the migration of existing Swarm code to the new Group Chat.

Changing imports#

Ensure you don't have any imports from autogen.agentchat.contrib.swarm_agent as there are a few classes that have the same name.

The new group chat classes can be imported from autogen.agentchat.group (primary), as well as autogen.agentchat.group.patterns and autogen.agentchat.group.targets.

For example:

from autogen.agentchat.group import (
    AgentNameTarget,
    AgentTarget,
    AskUserTarget,
    ContextExpression,
    ContextStr,
    ContextStrLLMCondition,
    ContextVariables,
    ExpressionAvailableCondition,
    ExpressionContextCondition,
    GroupChatConfig,
    GroupChatTarget,
    Handoffs,
    NestedChatTarget,
    OnCondition,
    OnContextCondition,
    ReplyResult,
    RevertToUserTarget,
    SpeakerSelectionResult,
    StayTarget,
    StringAvailableCondition,
    StringContextCondition,
    StringLLMCondition,
    TerminateTarget,
)

from autogen.agentchat.group.patterns (
    DefaultPattern,
    ManualPattern,
    AutoPattern,
    RandomPattern,
    RoundRobinPattern,

)

Context variables#

Context variables are no longer a dict[str, Any] type, they use a new class called ContextVariables. You can continue to interact with context variables like it is a dictionary.

The changes you will need to make are to (1) change the import location and (2) change your type references from dict[str, Any] to ContextVariables.

# Import the class
from autogen.agentchat.group import ContextVariables

# 1. Creating your context variables

# OLD
my_context_variables = {
    "basic_agent_confidence": 0,
    "intermediate_agent_confidence": 0,
    "advanced_agent_confidence": 0,
}

# NEW
my_context_variables = ContextVariables(data={
    # Agent-specific variables
    "basic_agent_confidence": 0,
    "intermediate_agent_confidence": 0,
    "advanced_agent_confidence": 0,
})

# 2. Functions used as tools

# OLD
def my_function(location: str, context_variables: dict[str, Any]) -> SwarmResult:
    """Important docstring for my function."""
    return SwarmResult(agent=the_next_agent, context_variables=context_variables, values="The weather is very hot!")

# NEW
def my_function(location: str, context_variables: ContextVariables) -> SwarmResult:
    """Important docstring for my function."""
    return SwarmResult(agent=the_next_agent, context_variables=context_variables, values="The weather is very hot!")

Replace SwarmResult with ReplyResult#

Functions attached to your agents should now return a ReplyResult instead of a SwarmResult.

A new concept introduced here is a Transition Target, which is what AG2 will transition to next. In a swarm you could transition to an agent by passing in the agent or the name of the agent, alternatively you could transition to an AfterWorkOption such as to terminate or revert to the user. In the new group chat all the possible transitions are Targets, such as AgentTarget, AgentNameTarget, and TerminateTarget.

# OLD
def check_order_id(order_id: str, context_variables: dict[str, Any]) -> SwarmResult:
    """Check if the order ID is valid"""
    ...
    return SwarmResult(
        agent=order_triage_agent,
        context_variables=context_variables,
        values=f"Order ID {order_id} is valid.",
    )

# NEW
# Now returning ReplyResult
# (and we make sure to use the ContextVariables type for context_variables, if needed)
def check_order_id(order_id: str, context_variables: ContextVariables) -> ReplyResult:
    """Check if the order ID is valid"""
    ...
    return ReplyResult(
        # Parameter now called target and we pass in a suitable TransitionTarget:
        target=AgentTarget(order_triage_agent),
        context_variables=context_variables,
        # Parameter now called message:
        message=f"Order ID {order_id} is valid.",
    )

Handoffs#

Handoffs are largely the same with the new group chat, except that they are handled directly on the agent (as opposed to using register_hand_off).

Handoffs have been split into LLM conditions (OnCondition), context variable based conditions (OnContextCondition), and the after work. You will generally be setting these separately.

New classes have been introduced for use with the condition and the available parameters to ensure compliance while giving flexibility to introduce new classes without changing the fundamental group chat mechanism.

For LLM-based conditions

# OLD
register_hand_off(
    agent=order_triage_agent,
    hand_to=[
        OnCondition(
            target=authentication_agent,
            condition="The customer is not logged in, authenticate the customer.",
            available="requires_login",
        ),
        OnCondition(
            target=order_mgmt_agent,
            condition="The customer is logged in, continue with the order triage.",
            available="logged_in",
        )
    ]
)

# NEW
# handoffs are added directly from the agent's handoffs attribute
order_triage_agent.handoffs.add_llm_conditions([
        OnCondition(
            target=AgentTarget(authentication_agent),
            condition=StringLLMCondition(prompt="The customer is not logged in,authenticate the customer."),
            available=StringAvailableCondition(context_variable="requires_login"),
        ),
        OnCondition(
            target=AgentTarget(agent=order_mgmt_agent),
            condition=StringLLMCondition(prompt="The customer is logged in, continue with the order triage."),
            available=StringAvailableCondition(context_variable="logged_in"),
        )
    ]
)

Context-based conditions:

# OLD
register_hand_off(
    agent=router_agent,
    hand_to=[
        OnContextCondition(
            target=tech_specialist,
            condition=ContextExpression(expression="${current_domain} == 'technology'"),
            available=ContextExpression(expression="!${question_answered}")
        ),
])

# NEW (you can use register_handoffs to register multiple conditions)
router_agent.register_handoffs(conditions=[
    OnContextCondition(
        target=AgentTarget(agent=tech_specialist),
        condition=ExpressionContextCondition(expression=ContextExpression(expression="${current_domain} == 'technology'")),
        available=ExpressionAvailableCondition(expression=ContextExpression(expression="!${question_answered}"))
    )
])

After works:

# OLD
register_hand_off(
    agent=order_triage_agent,
    hand_to=[
        AfterWork(AfterWorkOption.REVERT_TO_USER),
    ]
)

# NEW
order_triage_agent.handoffs.set_after_work(after_work=RevertToUserTarget())

Initiating the chat#

Another new concept arrives when we look to initiate the chat. With the new group chat we have introduced the concept of an orchestration Pattern and these are used to setup the base transitions for the agents.

So to initiate a chat you will choose and configure a pattern and then pass that into a new initiate chat function called initiate_group_chat.

To replicate the current swarm, you can use the base Pattern class and the parameters and types are largely the same as those of initiate_swarm_chat.

# OLD
chat_history = initiate_group_chat(
    initial_agent=order_triage_agent,
    agents=[order_triage_agent, authentication_agent, order_mgmt_agent],
    context_variables=workflow_context,
    messages="Can you help me with my order.",
    user_agent=user,
    max_rounds=40,
    after_work=AfterWork(target=AfterWorkOptionTarget(after_work_option="terminate")),
)

# NEW
# Create the pattern
agent_pattern = DefaultPattern(
  agents=[order_triage_agent, authentication_agent, order_mgmt_agent],
  initial_agent=order_triage_agent,
  context_variables=workflow_context,
  user_agent=user,
)

# Then initiate the chat with the pattern
result, final_context, last_agent = initiate_group_chat(
    pattern=agent_pattern,
    messages="Can you help me with my order.",
    max_rounds=40,
)