How to Build a Manager-Worker Multi-Agent System#

With the advent of increasingly powerful Large Language Models (LLMs), multi-agent systems are becoming more relevant and are expected to be particularly valuable in scenarios requiring high-levels of autonomy and/or processing of diverse sources of information.

There are various types of multi-agent systems, each serving different purposes and applications. Some notable examples include hierarchical structures, agent swarms, and mixtures of agents.

A hierarchical multi-agent system (also known as manager-worker or orchestrator-worker pattern) is a multi-agent pattern in which a central manager coordinates one or more worker agents by assigning tasks, and aggregating results.

When to use the Manager-Worker pattern?

Manager-Worker pattern is particularly suitable when tasks can be decomposed into specialized subtasks that benefit from dedicated agents with distinct expertise or tools. Compared to the Swarm pattern, the manager-worker pattern provides centralized coordination and explicit control flow between agents, making it more effective for workflows that require maintaining global context and aggregated results.

In the hierarchical pattern, a route User → Manager → Worker → Manager → User will require:

  • The manager to analyze the user request and decide which worker agent should handle it.

  • The selected worker agent to process the assigned subtask.

  • The worker to return its output to the manager.

  • The manager to consolidate and deliver the final response back to the user.


This guide demonstrates an example of a hierarchical multi-agent system for customer service automation, where a Customer Service Manager agent manages a team of two specialized agents — the Refund Specialist for processing refunds and the Satisfaction Surveyor for collecting feedback.

It will walk you through the following steps:

  1. Define the configuration of an LLM model

  2. Define expert agents equipped with tools

  3. Define a manager agent

  4. Define a ManagerWorkers of the defined agents

Basic implementation#

1. Define the LLM model#

The decision mechanism of Agents is powered by a Large Language Model. Defining the agent with Agent Spec requires to pass the configuration for the LLM. There are several options such as using OCI GenAI Service or self hosting a model with vLLM.

Start by defining the LLM configuration to be shared across all agents.

from pyagentspec.llms import OciGenAiConfig
from pyagentspec.llms.ociclientconfig import OciClientConfigWithApiKey

client_config = OciClientConfigWithApiKey(
    name="Oci Client Config",
    service_endpoint="https://url-to-service-endpoint.com",
    auth_profile="DEFAULT",
    auth_file_location="~/.oci/config"
)

llm_config = OciGenAiConfig(
    name="Oci GenAI Config",
    model_id="provider.model-id",
    compartment_id="compartment-id",
    client_config=client_config,
)

2. Define expert agents#

Refund specialist agent#

The refund specialist agent is equipped with two tools.

from pyagentspec.property import (
    BooleanProperty,
    StringProperty,
    NumberProperty,
    DictProperty,
    UnionProperty,
    IntegerProperty,
    NullProperty,
)
from pyagentspec.tools import ServerTool

check_refund_eligibility = ServerTool(
    name="Check refund eligibility",
    description="Checks if a given order is eligible for a refund based on company policy.",
    inputs=[StringProperty(title="order_id"), StringProperty(title="customer_id")],
    outputs=[
        DictProperty(
            title="refund_eligibility",
            value_type=UnionProperty(
                any_of=[BooleanProperty(), NumberProperty(), StringProperty()]
            ),
        )
    ],
)

process_refund = ServerTool(
    name="Process refund",
    description="Processes a refund for a specific order and amount.",
    inputs=[
        StringProperty(title="order_id"),
        NumberProperty(title="amount"),
        StringProperty(title="reason"),
    ],
    outputs=[
        DictProperty(
            title="refund_status",
            value_type=UnionProperty(any_of=[StringProperty(), BooleanProperty()]),
        )
    ],
)

API Reference: ServerTool

The first tool is used to check whether a given order is eligible for a refund, while the second is used to process the specific refund.

Note

To require user confirmation for a tool, set requires_confirmation=True (see Tool). This signals that execution environments should require user approval before running the tool, which is useful for tools performing sensitive actions.

The system prompt is defined as follows:

REFUND_SPECIALIST_SYSTEM_PROMPT = """
You are a Refund Specialist agent whose objective is to process customer refund requests accurately and efficiently based on company policy.

# Instructions
- Receive the refund request details (e.g., order ID, customer ID, reason) from the 'CustomerServiceManager'.
- Use the `check_refund_eligibility` tool to verify if the request meets the refund policy criteria using the provided order and customer IDs.
- If the check indicates eligibility, determine the correct refund amount (up to the maximum allowed from the eligibility check).
- If eligible, use the `process_refund` tool to execute the refund for the determined amount, providing order ID and reason.
- If ineligible based on the check, clearly note the reason provided by the tool.
- Report the final outcome (e.g., "Refund processed successfully, Refund ID: [ID], Amount: [Amount]", or "Refund denied: [Reason from eligibility check]") back to the 'CustomerServiceManager'.
- Do not engage in general conversation; focus solely on the refund process.
""".strip()

Building the agent:

from pyagentspec.agent import Agent

refund_specialist_agent = Agent(
    name="RefundSpecialist",
    description="Specializes in processing customer refund requests by verifying eligibility and executing the refund transaction using available tools.",
    llm_config=llm_config,
    system_prompt=REFUND_SPECIALIST_SYSTEM_PROMPT,
    tools=[check_refund_eligibility, process_refund],
)

API Reference: Agent

Statisfaction surveyor agent#

The statisfaction surveyor agent is equipped with one tool.

record_survey_response = ServerTool(
    name="Record survey response",
    description="Records the customer's satisfaction survey response.",
    inputs=[
        StringProperty(title="customer_id"),
        UnionProperty(
            title="satisfaction_score",
            any_of=[IntegerProperty(), NullProperty()],
            default=None,
        ),
        UnionProperty(
            title="comments",
            any_of=[StringProperty(), NullProperty()],
            default=None,
        ),
    ],
    outputs=[
        DictProperty(
            title="recording_status",
            value_type=UnionProperty(any_of=[BooleanProperty(), StringProperty()]),
        )
    ],
)

The record_survey_response tool is simulating the recording of user feedback data.

System prompt:

SURVEYOR_SYSTEM_PROMPT = """
You are a Satisfaction Surveyor agent tasked with collecting customer feedback about their recent service experience in a friendly manner.

# Instructions
- Receive the trigger to conduct a survey from the 'CustomerServiceManager', including context like the customer ID and the nature of the interaction if provided.
- Politely ask the customer if they have a moment to provide feedback on their recent interaction.
- If the customer agrees, ask 1-2 concise questions about their satisfaction (e.g., "On a scale of 1 to 5, where 5 is highly satisfied, how satisfied were you with the resolution provided today?", "Is there anything else you'd like to share about your experience?").
- Use the `record_survey_response` tool to log the customer's feedback, including the satisfaction score and any comments provided. Ensure you pass the correct customer ID.
- If the customer declines to participate, thank them for their time anyway. Do not pressure them. Use the `record_survey_response` tool to log the declination if possible (e.g., score=None, comments="Declined survey").
- Thank the customer for their participation if they provided feedback.
- Report back to the 'CustomerServiceManager' confirming that the survey was attempted and whether it was completed or declined.
""".strip()

Building the agent:

surveyor_agent = Agent(
    name="SatisfactionSurveyor",
    description="Conducts brief surveys to gather feedback on customer satisfaction following service interactions.",
    llm_config=llm_config,
    system_prompt=SURVEYOR_SYSTEM_PROMPT,
    tools=[record_survey_response],
)

3. Define the manager agent#

In the built-in ManagerWorkers component, we allow passing an Agent as the group manager. Therefore, we just need to define an agent as usual.

In this example, our manager agent will be a Customer Service Manager.

System prompt:

MANAGER_SYSTEM_PROMPT = """
You are a Customer Service Manager agent tasked with handling incoming customer interactions and orchestrating the resolution process efficiently.

# Instructions
- Greet the customer politely and acknowledge their message.
- Analyze the customer's message to understand their core need (e.g., refund request, general query, feedback).
- Answer common informational questions (e.g., about shipping times, return policy basics) directly if you have the knowledge, before delegating.
- If the request is clearly about a refund, gather necessary details (like Order ID) if missing, and then assign the task to the 'RefundSpecialist' agent. Provide all relevant context.
- If the interaction seems successfully concluded (e.g., refund processed, query answered) and requesting feedback is appropriate, assign the task to the 'SatisfactionSurveyor' agent. Provide customer context.
- For general queries you cannot handle directly and that don't fit the specialist agents, state your limitations clearly and politely.
- Await responses or status updates from specialist agents you have assigned to.
- Summarize the final outcome or confirmation for the customer based on specialist agent reports.
- Maintain a helpful, empathetic, and professional tone throughout the interaction.

# Additional Context
Customer ID: {{customer_id}}
Company policies: {{company_policy_info}}
""".strip()

Building the agent:

customer_service_manager = Agent(
    name="CustomerServiceManager",
    description="Acts as the primary contact point for customer inquiries, analyzes the request, routes tasks to specialized agents (Refund Specialist, Satisfaction Surveyor), and ensures resolution.",
    llm_config=llm_config,
    system_prompt=MANAGER_SYSTEM_PROMPT,
)

4. Define the ManagerWorkers of Agents#

from pyagentspec.managerworkers import ManagerWorkers

assistant = ManagerWorkers(
    name="managerworkers",
    group_manager=customer_service_manager,
    workers=[refund_specialist_agent, surveyor_agent],
)

API Reference: ManagerWorkers

The ManagerWorkers has two main parameters:

  • group_manager The agent that is used as the group manager, responsible for coordinating and assigning tasks to the workers.

  • workers - List of agents These agents serve as the workers within the group and are coordinated by the manager agent.

    • Worker agents cannot interact with the end user directly.

    • When invoked, each worker can leverage its equipped tools to complete the assigned task and report the result back to the group manager.

Agent Spec Serialization#

You can export the assistant configuration using the AgentSpecSerializer.

from pyagentspec.serialization import AgentSpecSerializer

serialized_assistant = AgentSpecSerializer().to_json(assistant)

# you can print the serialized form or save it to a file
print(serialized_assistant)

Here is what the Agent Spec representation will look like ↓

Click here to see the assistant configuration.
{
    "component_type": "ManagerWorkers",
    "id": "4d3a0013-284f-4ec9-82e2-6e081eca7e39",
    "name": "managerworkers",
    "description": null,
    "metadata": {},
    "inputs": [],
    "outputs": [],
    "group_manager": {
        "component_type": "Agent",
        "id": "d78cbb31-9961-4f1a-ab63-75bed2920547",
        "name": "CustomerServiceManager",
        "description": "Acts as the primary contact point for customer inquiries, analyzes the request, routes tasks to specialized agents (Refund Specialist, Satisfaction Surveyor), and ensures resolution.",
        "metadata": {},
        "inputs": [
            {
                "title": "customer_id",
                "type": "string"
            },
            {
                "title": "company_policy_info",
                "type": "string"
            }
        ],
        "outputs": [],
        "llm_config": {
            "$component_ref": "2154580d-d991-4df9-9888-e4b69eea6922"
        },
        "system_prompt": "You are a Customer Service Manager agent tasked with handling incoming customer interactions and orchestrating the resolution process efficiently.\n\n# Instructions\n- Greet the customer politely and acknowledge their message.\n- Analyze the customer's message to understand their core need (e.g., refund request, general query, feedback).\n- Answer common informational questions (e.g., about shipping times, return policy basics) directly if you have the knowledge, before delegating.\n- If the request is clearly about a refund, gather necessary details (like Order ID) if missing, and then assign the task to the 'RefundSpecialist' agent. Provide all relevant context.\n- If the interaction seems successfully concluded (e.g., refund processed, query answered) and requesting feedback is appropriate, assign the task to the 'SatisfactionSurveyor' agent. Provide customer context.\n- For general queries you cannot handle directly and that don't fit the specialist agents, state your limitations clearly and politely.\n- Await responses or status updates from specialist agents you have assigned to.\n- Summarize the final outcome or confirmation for the customer based on specialist agent reports.\n- Maintain a helpful, empathetic, and professional tone throughout the interaction.\n\n# Additional Context\nCustomer ID: {{customer_id}}\nCompany policies: {{company_policy_info}}",
        "tools": [],
        "toolboxes": [],
        "human_in_the_loop": true
    },
    "workers": [
        {
            "component_type": "Agent",
            "id": "e455c3c6-bded-454c-8315-559c3e617ae1",
            "name": "RefundSpecialist",
            "description": "Specializes in processing customer refund requests by verifying eligibility and executing the refund transaction using available tools.",
            "metadata": {},
            "inputs": [],
            "outputs": [],
            "llm_config": {
                "$component_ref": "2154580d-d991-4df9-9888-e4b69eea6922"
            },
            "system_prompt": "You are a Refund Specialist agent whose objective is to process customer refund requests accurately and efficiently based on company policy.\n\n# Instructions\n- Receive the refund request details (e.g., order ID, customer ID, reason) from the 'CustomerServiceManager'.\n- Use the `check_refund_eligibility` tool to verify if the request meets the refund policy criteria using the provided order and customer IDs.\n- If the check indicates eligibility, determine the correct refund amount (up to the maximum allowed from the eligibility check).\n- If eligible, use the `process_refund` tool to execute the refund for the determined amount, providing order ID and reason.\n- If ineligible based on the check, clearly note the reason provided by the tool.\n- Report the final outcome (e.g., \"Refund processed successfully, Refund ID: [ID], Amount: [Amount]\", or \"Refund denied: [Reason from eligibility check]\") back to the 'CustomerServiceManager'.\n- Do not engage in general conversation; focus solely on the refund process.",
            "tools": [
                {
                    "component_type": "ServerTool",
                    "id": "ce0731ff-1dc3-4832-bcae-d5209f2f17bd",
                    "name": "Check refund eligibility",
                    "description": "Checks if a given order is eligible for a refund based on company policy.",
                    "metadata": {},
                    "inputs": [
                        {
                            "title": "order_id",
                            "type": "string"
                        },
                        {
                            "title": "customer_id",
                            "type": "string"
                        }
                    ],
                    "outputs": [
                        {
                            "title": "refund_eligibility",
                            "additionalProperties": {
                                "anyOf": [
                                    {
                                        "type": "boolean"
                                    },
                                    {
                                        "type": "number"
                                    },
                                    {
                                        "type": "string"
                                    }
                                ]
                            },
                            "properties": {},
                            "type": "object"
                        }
                    ]
                },
                {
                    "component_type": "ServerTool",
                    "id": "cfb441a2-647d-45ce-8a46-f7773d17dd85",
                    "name": "Process refund",
                    "description": "Processes a refund for a specific order and amount.",
                    "metadata": {},
                    "inputs": [
                        {
                            "title": "order_id",
                            "type": "string"
                        },
                        {
                            "title": "amount",
                            "type": "number"
                        },
                        {
                            "title": "reason",
                            "type": "string"
                        }
                    ],
                    "outputs": [
                        {
                            "title": "refund_status",
                            "additionalProperties": {
                                "anyOf": [
                                    {
                                        "type": "string"
                                    },
                                    {
                                        "type": "boolean"
                                    }
                                ]
                            },
                            "properties": {},
                            "type": "object"
                        }
                    ]
                }
            ],
            "toolboxes": [],
            "human_in_the_loop": true
        },
        {
            "component_type": "Agent",
            "id": "c048a72d-da2a-4288-b3c6-d5af7c1b5bd6",
            "name": "SatisfactionSurveyor",
            "description": "Conducts brief surveys to gather feedback on customer satisfaction following service interactions.",
            "metadata": {},
            "inputs": [],
            "outputs": [],
            "llm_config": {
                "$component_ref": "2154580d-d991-4df9-9888-e4b69eea6922"
            },
            "system_prompt": "You are a Satisfaction Surveyor agent tasked with collecting customer feedback about their recent service experience in a friendly manner.\n\n# Instructions\n- Receive the trigger to conduct a survey from the 'CustomerServiceManager', including context like the customer ID and the nature of the interaction if provided.\n- Politely ask the customer if they have a moment to provide feedback on their recent interaction.\n- If the customer agrees, ask 1-2 concise questions about their satisfaction (e.g., \"On a scale of 1 to 5, where 5 is highly satisfied, how satisfied were you with the resolution provided today?\", \"Is there anything else you'd like to share about your experience?\").\n- Use the `record_survey_response` tool to log the customer's feedback, including the satisfaction score and any comments provided. Ensure you pass the correct customer ID.\n- If the customer declines to participate, thank them for their time anyway. Do not pressure them. Use the `record_survey_response` tool to log the declination if possible (e.g., score=None, comments=\"Declined survey\").\n- Thank the customer for their participation if they provided feedback.\n- Report back to the 'CustomerServiceManager' confirming that the survey was attempted and whether it was completed or declined.",
            "tools": [
                {
                    "component_type": "ServerTool",
                    "id": "0db02ef0-4e9c-426b-8005-69b813dd32e9",
                    "name": "Record survey response",
                    "description": "Records the customer's satisfaction survey response.",
                    "metadata": {},
                    "inputs": [
                        {
                            "title": "customer_id",
                            "type": "string"
                        },
                        {
                            "title": "satisfaction_score",
                            "default": null,
                            "anyOf": [
                                {
                                    "type": "integer"
                                },
                                {
                                    "type": "null"
                                }
                            ]
                        },
                        {
                            "title": "comments",
                            "default": null,
                            "anyOf": [
                                {
                                    "type": "string"
                                },
                                {
                                    "type": "null"
                                }
                            ]
                        }
                    ],
                    "outputs": [
                        {
                            "title": "recording_status",
                            "additionalProperties": {
                                "anyOf": [
                                    {
                                        "type": "boolean"
                                    },
                                    {
                                        "type": "string"
                                    }
                                ]
                            },
                            "properties": {},
                            "type": "object"
                        }
                    ]
                }
            ],
            "toolboxes": [],
            "human_in_the_loop": true
        }
    ],
    "$referenced_components": {
        "2154580d-d991-4df9-9888-e4b69eea6922": {
            "component_type": "VllmConfig",
            "id": "2154580d-d991-4df9-9888-e4b69eea6922",
            "name": "vllm-llama-4-maverick",
            "description": null,
            "metadata": {},
            "default_generation_parameters": null,
            "url": "http://url.to.my.vllm.server/llama4mav",
            "model_id": "llama-4-maverick"
        }
    },
    "agentspec_version": "25.4.2"
}

Recap#

This guide covered how to define a manager-workers of agents in Agent Spec.

Below is the complete code from this guide.
  1# Copyright © 2025 Oracle and/or its affiliates.
  2#
  3# This software is under the Apache License 2.0
  4# (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) or Universal Permissive License
  5# (UPL) 1.0 (LICENSE-UPL or https://oss.oracle.com/licenses/upl), at your option.
  6# isort:skip_file
  7# mypy: ignore-errors
  8
  9# .. start-##_Define_the_LLM
 10from pyagentspec.llms import VllmConfig
 11
 12llm_config = VllmConfig(
 13    name="vllm-llama-4-maverick",
 14    model_id="llama-4-maverick",
 15    url="http://url.to.my.vllm.server/llama4mav",
 16)
 17# .. end-##_Define_the_LLM
 18
 19# .. start-##_Specialist_tools
 20from pyagentspec.property import (
 21    BooleanProperty,
 22    StringProperty,
 23    NumberProperty,
 24    DictProperty,
 25    UnionProperty,
 26    IntegerProperty,
 27    NullProperty,
 28)
 29from pyagentspec.tools import ServerTool
 30
 31check_refund_eligibility = ServerTool(
 32    name="Check refund eligibility",
 33    description="Checks if a given order is eligible for a refund based on company policy.",
 34    inputs=[StringProperty(title="order_id"), StringProperty(title="customer_id")],
 35    outputs=[
 36        DictProperty(
 37            title="refund_eligibility",
 38            value_type=UnionProperty(
 39                any_of=[BooleanProperty(), NumberProperty(), StringProperty()]
 40            ),
 41        )
 42    ],
 43)
 44
 45process_refund = ServerTool(
 46    name="Process refund",
 47    description="Processes a refund for a specific order and amount.",
 48    inputs=[
 49        StringProperty(title="order_id"),
 50        NumberProperty(title="amount"),
 51        StringProperty(title="reason"),
 52    ],
 53    outputs=[
 54        DictProperty(
 55            title="refund_status",
 56            value_type=UnionProperty(any_of=[StringProperty(), BooleanProperty()]),
 57        )
 58    ],
 59)
 60
 61# .. end-##_Specialist_tools
 62
 63# .. start-##_Specialist_prompt
 64REFUND_SPECIALIST_SYSTEM_PROMPT = """
 65You are a Refund Specialist agent whose objective is to process customer refund requests accurately and efficiently based on company policy.
 66
 67# Instructions
 68- Receive the refund request details (e.g., order ID, customer ID, reason) from the 'CustomerServiceManager'.
 69- Use the `check_refund_eligibility` tool to verify if the request meets the refund policy criteria using the provided order and customer IDs.
 70- If the check indicates eligibility, determine the correct refund amount (up to the maximum allowed from the eligibility check).
 71- If eligible, use the `process_refund` tool to execute the refund for the determined amount, providing order ID and reason.
 72- If ineligible based on the check, clearly note the reason provided by the tool.
 73- Report the final outcome (e.g., "Refund processed successfully, Refund ID: [ID], Amount: [Amount]", or "Refund denied: [Reason from eligibility check]") back to the 'CustomerServiceManager'.
 74- Do not engage in general conversation; focus solely on the refund process.
 75""".strip()
 76# .. end-##_Specialist_prompt
 77
 78# .. start-##_Specialist_agent
 79from pyagentspec.agent import Agent
 80
 81refund_specialist_agent = Agent(
 82    name="RefundSpecialist",
 83    description="Specializes in processing customer refund requests by verifying eligibility and executing the refund transaction using available tools.",
 84    llm_config=llm_config,
 85    system_prompt=REFUND_SPECIALIST_SYSTEM_PROMPT,
 86    tools=[check_refund_eligibility, process_refund],
 87)
 88# .. end-##_Specialist_agent
 89
 90# .. start-##_Surveyor_tools
 91record_survey_response = ServerTool(
 92    name="Record survey response",
 93    description="Records the customer's satisfaction survey response.",
 94    inputs=[
 95        StringProperty(title="customer_id"),
 96        UnionProperty(
 97            title="satisfaction_score",
 98            any_of=[IntegerProperty(), NullProperty()],
 99            default=None,
100        ),
101        UnionProperty(
102            title="comments",
103            any_of=[StringProperty(), NullProperty()],
104            default=None,
105        ),
106    ],
107    outputs=[
108        DictProperty(
109            title="recording_status",
110            value_type=UnionProperty(any_of=[BooleanProperty(), StringProperty()]),
111        )
112    ],
113)
114# .. end-##_Surveyor_tools
115
116# .. start-##_Surveyor_prompt
117SURVEYOR_SYSTEM_PROMPT = """
118You are a Satisfaction Surveyor agent tasked with collecting customer feedback about their recent service experience in a friendly manner.
119
120# Instructions
121- Receive the trigger to conduct a survey from the 'CustomerServiceManager', including context like the customer ID and the nature of the interaction if provided.
122- Politely ask the customer if they have a moment to provide feedback on their recent interaction.
123- If the customer agrees, ask 1-2 concise questions about their satisfaction (e.g., "On a scale of 1 to 5, where 5 is highly satisfied, how satisfied were you with the resolution provided today?", "Is there anything else you'd like to share about your experience?").
124- Use the `record_survey_response` tool to log the customer's feedback, including the satisfaction score and any comments provided. Ensure you pass the correct customer ID.
125- If the customer declines to participate, thank them for their time anyway. Do not pressure them. Use the `record_survey_response` tool to log the declination if possible (e.g., score=None, comments="Declined survey").
126- Thank the customer for their participation if they provided feedback.
127- Report back to the 'CustomerServiceManager' confirming that the survey was attempted and whether it was completed or declined.
128""".strip()
129# .. end-##_Surveyor_prompt
130
131# .. start-##_Surveyor_agent
132surveyor_agent = Agent(
133    name="SatisfactionSurveyor",
134    description="Conducts brief surveys to gather feedback on customer satisfaction following service interactions.",
135    llm_config=llm_config,
136    system_prompt=SURVEYOR_SYSTEM_PROMPT,
137    tools=[record_survey_response],
138)
139# .. end-##_Surveyor_agent
140
141# .. start-##_Manager_prompt
142MANAGER_SYSTEM_PROMPT = """
143You are a Customer Service Manager agent tasked with handling incoming customer interactions and orchestrating the resolution process efficiently.
144
145# Instructions
146- Greet the customer politely and acknowledge their message.
147- Analyze the customer's message to understand their core need (e.g., refund request, general query, feedback).
148- Answer common informational questions (e.g., about shipping times, return policy basics) directly if you have the knowledge, before delegating.
149- If the request is clearly about a refund, gather necessary details (like Order ID) if missing, and then assign the task to the 'RefundSpecialist' agent. Provide all relevant context.
150- If the interaction seems successfully concluded (e.g., refund processed, query answered) and requesting feedback is appropriate, assign the task to the 'SatisfactionSurveyor' agent. Provide customer context.
151- For general queries you cannot handle directly and that don't fit the specialist agents, state your limitations clearly and politely.
152- Await responses or status updates from specialist agents you have assigned to.
153- Summarize the final outcome or confirmation for the customer based on specialist agent reports.
154- Maintain a helpful, empathetic, and professional tone throughout the interaction.
155
156# Additional Context
157Customer ID: {{customer_id}}
158Company policies: {{company_policy_info}}
159""".strip()
160# .. end-##_Manager_prompt
161
162# .. start-##_Manager_agent
163customer_service_manager = Agent(
164    name="CustomerServiceManager",
165    description="Acts as the primary contact point for customer inquiries, analyzes the request, routes tasks to specialized agents (Refund Specialist, Satisfaction Surveyor), and ensures resolution.",
166    llm_config=llm_config,
167    system_prompt=MANAGER_SYSTEM_PROMPT,
168)
169# .. end-##_Manager_agent
170
171# .. start-##_Managerworkers_pattern
172from pyagentspec.managerworkers import ManagerWorkers
173
174assistant = ManagerWorkers(
175    name="managerworkers",
176    group_manager=customer_service_manager,
177    workers=[refund_specialist_agent, surveyor_agent],
178)
179# .. end-##_Managerworkers_pattern
180
181# .. start-##_Export_serialization
182from pyagentspec.serialization import AgentSpecSerializer
183
184serialized_assistant = AgentSpecSerializer().to_json(assistant)
185
186# you can print the serialized form or save it to a file
187print(serialized_assistant)
188# .. end-##_Export_serialization

Next steps#

Having learned how to define a manager-workers, you may now proceed to how to use the WayFlow runtime to execute it.