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:
Define the configuration of an LLM model
Define expert agents equipped with tools
Define a manager agent
Define a
ManagerWorkersof 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,
)
from pyagentspec.llms import VllmConfig
llm_config = VllmConfig(
name="Llama 3.1 8B instruct",
url="VLLM_URL",
model_id="model-id",
)
from pyagentspec.llms import OllamaConfig
llm_config = OllamaConfig(
name="Ollama Config",
model_id="model-id",
)
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_managerThe 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"
}
# Copyright © 2025 Oracle and/or its affiliates.
#
# This software is under the Apache License 2.0
# (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) or Universal Permissive License
# (UPL) 1.0 (LICENSE-UPL or https://oss.oracle.com/licenses/upl), at your option.
component_type: ManagerWorkers
id: 248045cb-ca6f-4d6f-9e22-d28b452a25da
name: managerworkers
description: null
metadata: {}
inputs: []
outputs: []
group_manager:
component_type: Agent
id: 62fced3a-6dbf-48e6-85c8-9d7aa28be2e9
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: company_policy_info
type: string
- title: customer_id
type: string
outputs: []
llm_config:
$component_ref: 38b523dd-b474-4273-a4aa-cd85ad3c526c
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}}'
tools: []
toolboxes: []
human_in_the_loop: true
workers:
- component_type: Agent
id: 32bddeaf-0e6e-482e-876f-d7db0faf1719
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: 38b523dd-b474-4273-a4aa-cd85ad3c526c
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.'
tools:
- component_type: ServerTool
id: 808f32a7-6421-4007-8f0c-45a9d273b0d6
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: 7e6e4b6b-547d-44f6-b461-a5b0a2ba0f4b
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: a81d4df1-a7af-4af8-bc9a-a3ca0f0c9a12
name: SatisfactionSurveyor
description: Conducts brief surveys to gather feedback on customer satisfaction
following service interactions.
metadata: {}
inputs: []
outputs: []
llm_config:
$component_ref: 38b523dd-b474-4273-a4aa-cd85ad3c526c
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.'
tools:
- component_type: ServerTool
id: 30c57d73-ef10-400b-903b-5aa658b01ff3
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:
38b523dd-b474-4273-a4aa-cd85ad3c526c:
component_type: VllmConfig
id: 38b523dd-b474-4273-a4aa-cd85ad3c526c
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.