RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Fredoline Eruo
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /How-to
  5. /How to Design Specialized Agent Roles
HOW-TO · RAG

How to Design Specialized Agent Roles

intermediate·20 min·By Fredoline Eruo
Target environment
Ubuntu 24.04 · Ollama 0.4.x
PREREQUISITES

Multi-agent system architecture planned, Python 3.10+

What this does

Specialized agent roles divide responsibilities across agents with distinct capabilities, prompts, and tools — enabling each agent to excel at a specific domain while the system handles complex multi-step tasks.

Steps

  • Define role boundaries. Each role has a clear responsibility, tool set, and prompt.
from dataclasses import dataclass, field

@dataclass
class AgentRole:
    name: str
    description: str
    system_prompt: str
    tools: list = field(default_factory=list)
    max_consecutive_failures: int = 3

RESEARCHER = AgentRole(
    name="researcher",
    description="Searches and gathers information from the web and documents",
    system_prompt="You are a research specialist. Find relevant, accurate information.",
    tools=["search_web", "fetch_page", "query_database"]
)

ANALYST = AgentRole(
    name="analyst",
    description="Analyzes data and produces insights",
    system_prompt="You are a data analyst. Interpret data and create summaries.",
    tools=["calculate", "analyze_data", "create_chart"]
)

WRITER = AgentRole(
    name="writer",
    description="Produces well-formatted final output",
    system_prompt="You are a technical writer. Produce clear, well-structured content.",
    tools=["format_text", "check_grammar", "export_document"]
)
  • Build a role-based agent factory. Instantiate agents from role definitions.
class AgentFactory:
    def __init__(self, llm_client, tool_registry):
        self.llm = llm_client
        self.tool_registry = tool_registry

    def create_agent(self, role: AgentRole) -> dict:
        return {
            "role": role,
            "llm": self.llm,
            "tools": [self.tool_registry.get(t) for t in role.tools],
            "state": {
                "conversation_history": [],
                "failures": 0,
                "current_task": None
            }
        }
  • Implement role-specific tool permissions. Restrict which tools each role can access.
class ToolGate:
    def __init__(self):
        self.permissions = {}

    def grant(self, role: str, tool_name: str):
        if role not in self.permissions:
            self.permissions[role] = set()
        self.permissions[role].add(tool_name)

    def can_call(self, role: str, tool_name: str) -> bool:
        return tool_name in self.permissions.get(role, set())

# Usage
gate = ToolGate()
gate.grant("researcher", "search_web")
gate.grant("writer", "export_document")
# analyst cannot call search_web or export_document
  • Configure escalation paths. When an agent cannot complete its task, it escalates to another role.
ESCALATION_MAP = {
    "researcher": "analyst",   # researcher passes findings to analyst
    "analyst": "writer",       # analyst passes insights to writer
    "writer": None              # writer is the final step
}

def determine_next_role(current_role: str, task_result: dict) -> str | None:
    return ESCALATION_MAP.get(current_role)
  • Test role isolation. Verify agents cannot access tools outside their role.
assert not gate.can_call("writer", "search_web")
assert gate.can_call("researcher", "search_web")

Verification

python -c "
from dataclasses import dataclass
@dataclass
class Role:
    name: str
    desc: str
r = Role(name='test', desc='A test role')
print(r.name)
# Expected: test
"

Common failures

  • Overlapping responsibilities. Two roles can handle the same task, causing confusion and redundant work. Define clear boundaries with no overlap.
  • Role isolation bypass. An agent with free-form prompts can ignore its role and call any tool. Enforce tool access at the infrastructure level, not by convention.
  • Missing escalation path. When a role fails, the task stalls. Always define a fallback or escalation for every role.
  • Version mismatch - The installed package or runtime differs from the command shown; check the version first and rerun the smallest verification command.
  • Local environment drift - Another service, virtual environment, model, or path is being used; print the active binary path and configuration before changing the guide steps.

Related guides

  • How to Build Multi-Agent Orchestration System
  • How to Implement Agent-to-Agent Communication
← All how-to guidesCourses →