
ai-agent-orchestrator
Orchestrates multi-agent AI systems with task delegation, agent communication, shared memory, and workflow coordination. Use when users request "multi-agent system", "agent orchestration", "AI agents", "agent coordination", or "autonomous agents".
- Installs
- 353
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/patricio0312rev/skills --skill ai-agent-orchestrator- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads ai-agent-orchestrator automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
AI Agent Orchestrator
Build coordinated multi-agent systems for complex task automation.
Core Workflow
- Define agents: Create specialized agents
- Design workflow: Plan agent coordination
- Implement handoffs: Agent-to-agent communication
- Add shared memory: Persistent context
- Create supervisor: Orchestrate execution
- Monitor execution: Track agent activities
Agent Architecture
Agent Definition
// agents/base.ts
import { ChatOpenAI } from '@langchain/openai';
import { SystemMessage, HumanMessage, AIMessage } from '@langchain/core/messages';
export interface AgentConfig {
name: string;
role: string;
systemPrompt: string;
tools?: Tool[];
model?: string;
}
export interface AgentResponse {
content: string;
toolCalls?: ToolCall[];
nextAgent?: string;
completed?: boolean;
}
export class Agent {
private model: ChatOpenAI;
private config: AgentConfig;
private messageHistory: BaseMessage[] = [];
constructor(config: AgentConfig) {
this.config = config;
this.model = new ChatOpenAI({
modelName: config.model || 'gpt-4-turbo-preview',
temperature: 0.7,
});
}
async execute(input: string, context?: Record<string, any>): Promise<AgentResponse> {
const systemMessage = new SystemMessage(
this.buildSystemPrompt(context)
);
const messages = [
systemMessage,
...this.messageHistory,
new HumanMessage(input),
];
const response = await this.model.invoke(messages, {
tools: this.config.tools,
});
this.messageHistory.push(new HumanMessage(input));
this.messageHistory.push(new AIMessage(response.content as string));
return this.parseResponse(response);
}
private buildSystemPrompt(context?: Record<string, any>): string {
let prompt = this.config.systemPrompt;
if (context) {
prompt += `\n\nContext:\n${JSON.stringify(context, null, 2)}`;
}
return prompt;
}
private parseResponse(response: any): AgentResponse {
// Parse tool calls and determine next actions
return {
content: response.content as string,
toolCalls: response.tool_calls,
completed: response.content?.includes('[TASK_COMPLETE]'),
};
}
clearHistory() {
this.messageHistory = [];
}
}
Specialized Agents
// agents/specialists.ts
import { Agent, AgentConfig } from './base';
export const ResearchAgent = new Agent({
name: 'researcher',
role: 'Research Specialist',
systemPrompt: `You are a research specialist. Your job is to:
- Search for and gather relevant information
- Analyze sources and extract key insights
- Summarize findings clearly
- Cite sources when possible
When you have gathered sufficient information, include [TASK_COMPLETE] in your response.
If you need help from another agent, specify: [HANDOFF:agent_name]`,
tools: [searchTool, webScrapeTool],
});
export const WriterAgent = new Agent({
name: 'writer',
role: 'Content Writer',
systemPrompt: `You are a professional content writer. Your job is to:
- Create engaging, well-structured content
- Adapt tone and style to the target audience
- Incorporate research and data effectively
- Edit and refine for clarity
Use the research provided to create compelling content.
When complete, include [TASK_COMPLETE].`,
});
export const ReviewerAgent = new Agent({
name: 'reviewer',
role: 'Quality Reviewer',
systemPrompt: `You are a quality reviewer. Your job is to:
- Review content for accuracy and clarity
- Check for errors and inconsistencies
- Suggest improvements
- Approve or request revisions
Provide specific feedback. If approved, include [APPROVED].
If revisions needed, include [REVISIONS_NEEDED] with specific changes.`,
});
export const PlannerAgent = new Agent({
name: 'planner',
role: 'Task Planner',
systemPrompt: `You are a task planner. Your job is to:
- Break down complex tasks into subtasks
- Identify which specialist agent should handle each subtask
- Create an execution order
- Track progress
Output a structured plan in JSON format:
{
"goal": "...",
"steps": [
{ "step": 1, "agent": "researcher", "task": "..." },
{ "step": 2, "agent": "writer", "task": "..." }
]
}`,
});
Orchestrator
Simple Sequential Orchestrator
// orchestrator/sequential.ts
import { Agent } from '../agents/base';
interface WorkflowStep {
agent: Agent;
task: string;
inputFrom?: string;
}
export class SequentialOrchestrator {
private agents: Map<string, Agent> = new Map();
private results: Map<string, string> = new Map();
registerAgent(name: string, agent: Agent) {
this.agents.set(name, agent);
}
async execute(workflow: WorkflowStep[]): Promise<Record<string, string>> {
for (const step of workflow) {
const agent = step.agent;
// Get input from previous step if specified
let input = step.task;
if (step.inputFrom && this.results.has(step.inputFrom)) {
input = `${step.task}\n\nPrevious output:\n${this.results.get(step.inputFrom)}`;
}
console.log(`Executing: ${agent.name} - ${step.task}`);
const result = await agent.execute(input);
this.results.set(agent.name, result.content);
console.log(`Completed: ${agent.name}`);
}
return Object.fromEntries(this.results);
}
}
// Usage
const orchestrator = new SequentialOrchestrator();
orchestrator.registerAgent('researcher', ResearchAgent);
orchestrator.registerAgent('writer', WriterAgent);
orchestrator.registerAgent('reviewer', ReviewerAgent);
const results = await orchestrator.execute([
{ agent: ResearchAgent, task: 'Research the latest AI trends in 2024' },
{ agent: WriterAgent, task: 'Write a blog post about AI trends', inputFrom: 'researcher' },
{ agent: ReviewerAgent, task: 'Review the blog post', inputFrom: 'writer' },
]);
Supervisor Orchestrator
// orchestrator/supervisor.ts
import { ChatOpenAI } from '@langchain/openai';
import { Agent } from '../agents/base';
interface AgentRegistry {
[name: string]: {
agent: Agent;
description: string;
};
}
export class SupervisorOrchestrator {
private supervisor: ChatOpenAI;
private agents: AgentRegistry = {};
private sharedContext: Record<string, any> = {};
private maxIterations = 10;
constructor() {
this.supervisor = new ChatOpenAI({
modelName: 'gpt-4-turbo-preview',
temperature: 0,
});
}
registerAgent(name: string, agent: Agent, description: string) {
this.agents[name] = { agent, description };
}
async execute(task: string): Promise<string> {
let iteration = 0;
let currentTask = task;
const history: string[] = [];
while (iteration < this.maxIterations) {
iteration++;
// Supervisor decides next action
const decision = await this.supervise(currentTask, history);
if (decision.complete) {
return decision.finalResponse!;
}
// Execute selected agent
const { agent } = this.agents[decision.nextAgent!];
const result = await agent.execute(decision.agentTask!, this.sharedContext);
// Update shared context
this.sharedContext[decision.nextAgent!] = result.content;
history.push(`${decision.nextAgent}: ${result.content}`);
// Check for handoff
if (result.nextAgent) {
currentTask = `Continue with: ${result.content}`;
}
}
throw new Error('Max iterations reached');
}
private async supervise(
task: string,
history: string[]
): Promise<{
complete: boolean;
finalResponse?: string;
nextAgent?: string;
agentTask?: string;
}> {
const agentList = Object.entries(this.agents)
.map(([name, { description }]) => `- ${name}: ${description}`)
.join('\n');
const prompt = `You are a supervisor coordinating AI agents.
Available agents:
${agentList}
Task: ${task}
History:
${history.join('\n')}
Decide the next action. Respond in JSON:
{
"thought": "your reasoning",
"complete": false,
"nextAgent": "agent_name",
"agentTask": "specific task for the agent"
}
Or if the task is complete:
{
"thought": "your reasoning",
"complete": true,
"finalResponse": "the final answer"
}`;
const response = await this.supervisor.invoke([{ role: 'user', content: prompt }]);
return JSON.parse(response.content as string);
}
}
Parallel Agent Execution
// orchestrator/parallel.ts
export class ParallelOrchestrator {
private agents: Map<string, Agent> = new Map();
async executeParallel(
tasks: Array<{ agentName: string; task: string }>
): Promise<Map<string, string>> {
const results = new Map<string, string>();
await Promise.all(
tasks.map(async ({ agentName, task }) => {
const agent = this.agents.get(agentName);
if (!agent) throw new Error(`Agent ${agentName} not found`);
const result = await agent.execute(task);
results.set(agentName, result.content);
})
);
return results;
}
async fanOutFanIn(
task: string,
agentNames: string[],
aggregator: Agent
): Promise<string> {
// Fan out: same task to multiple agents
const parallelResults = await this.executeParallel(
agentNames.map((name) => ({ agentName: name, task }))
);
// Fan in: aggregate results
const aggregatedInput = Array.from(parallelResults.entries())
.map(([name, result]) => `${name}:\n${result}`)
.join('\n\n---\n\n');
const finalResult = await aggregator.execute(
`Synthesize these perspectives:\n\n${aggregatedInput}`
);
return finalResult.content;
}
}
Shared Memory
// memory/shared.ts
import { Redis } from 'ioredis';
export class SharedMemory {
private redis: Redis;
private prefix: string;
constructor(sessionId: string) {
this.redis = new Redis(process.env.REDIS_URL!);
this.prefix = `agent:${sessionId}:`;
}
async set(key: string, value: any, ttl?: number): Promise<void> {
const serialized = JSON.stringify(value);
if (ttl) {
await this.redis.setex(this.prefix + key, ttl, serialized);
} else {
await this.redis.set(this.prefix + key, serialized);
}
}
async get<T>(key: string): Promise<T | null> {
const value = await this.redis.get(this.prefix + key);
return value ? JSON.parse(value) : null;
}
async append(key: string, item: any): Promise<void> {
const list = (await this.get<any[]>(key)) || [];
list.push(item);
await this.set(key, list);
}
async getConversation(): Promise<Message[]> {
return (await this.get<Message[]>('conversation')) || [];
}
async addMessage(message: Message): Promise<void> {
await this.append('conversation', message);
}
async getAgentOutputs(): Promise<Record<string, string>> {
return (await this.get<Record<string, string>>('outputs')) || {};
}
async setAgentOutput(agent: string, output: string): Promise<void> {
const outputs = await this.getAgentOutputs();
outputs[agent] = output;
await this.set('outputs', outputs);
}
async clear(): Promise<void> {
const keys = await this.redis.keys(this.prefix + '*');
if (keys.length > 0) {
await this.redis.del(...keys);
}
}
}
Event-Driven Agent Communication
// events/agent-events.ts
import { EventEmitter } from 'events';
export class AgentEventBus extends EventEmitter {
private static instance: AgentEventBus;
static getInstance(): AgentEventBus {
if (!this.instance) {
this.instance = new AgentEventBus();
}
return this.instance;
}
emitAgentMessage(from: string, to: string, message: any) {
this.emit(`message:${to}`, { from, message, timestamp: new Date() });
}
emitAgentComplete(agent: string, result: any) {
this.emit('agent:complete', { agent, result, timestamp: new Date() });
}
emitAgentError(agent: string, error: Error) {
this.emit('agent:error', { agent, error, timestamp: new Date() });
}
onMessage(agentName: string, handler: (message: any) => void) {
this.on(`message:${agentName}`, handler);
}
onAnyComplete(handler: (event: any) => void) {
this.on('agent:complete', handler);
}
}
// Usage
const eventBus = AgentEventBus.getInstance();
// Agent listens for messages
eventBus.onMessage('writer', async ({ from, message }) => {
console.log(`Writer received from ${from}:`, message);
const result = await WriterAgent.execute(message);
eventBus.emitAgentComplete('writer', result);
});
// Orchestrator listens for completions
eventBus.onAnyComplete(({ agent, result }) => {
console.log(`${agent} completed:`, result.content);
});
Workflow Definition
// workflows/definition.ts
interface WorkflowDefinition {
name: string;
description: string;
agents: string[];
steps: WorkflowStep[];
errorHandling: 'retry' | 'fallback' | 'abort';
}
const ContentCreationWorkflow: WorkflowDefinition = {
name: 'content-creation',
description: 'Create and publish content',
agents: ['planner', 'researcher', 'writer', 'reviewer'],
steps: [
{
id: 'plan',
agent: 'planner',
input: '{task}',
outputKey: 'plan',
},
{
id: 'research',
agent: 'researcher',
input: 'Research for: {plan.topic}',
outputKey: 'research',
parallel: true,
},
{
id: 'write',
agent: 'writer',
input: 'Write about {plan.topic} using research: {research}',
outputKey: 'draft',
dependsOn: ['research'],
},
{
id: 'review',
agent: 'reviewer',
input: 'Review: {draft}',
outputKey: 'review',
loop: {
condition: 'review.approved === false',
maxIterations: 3,
backTo: 'write',
},
},
],
errorHandling: 'retry',
};
Best Practices
- Single responsibility: Each agent has one clear role
- Clear handoffs: Explicit agent-to-agent communication
- Shared context: Use memory for persistent state
- Iteration limits: Prevent infinite loops
- Error handling: Graceful degradation
- Observability: Log all agent actions
- Testing: Test agents individually and together
- Timeout handling: Prevent stuck agents
Output Checklist
Every agent system should include:
- Agent base class with common functionality
- Specialized agents with clear roles
- Orchestrator for coordination
- Shared memory system
- Event-based communication
- Workflow definitions
- Error handling and retries
- Iteration limits
- Logging and monitoring
- Agent handoff protocol
FAQ
What does the ai-agent-orchestrator skill do?
Orchestrates multi-agent AI systems with task delegation, agent communication, shared memory, and workflow coordination. Use when users request "multi-agent system", "agent orchestration", "AI agents", "agent coordination", or "autonomous agents".
How do I install ai-agent-orchestrator?
Run npx skills add https://github.com/patricio0312rev/skills --skill ai-agent-orchestrator in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/ai-agent-orchestrator/ (personal) or .claude/skills/ai-agent-orchestrator/ (project).
Which AI agents can use ai-agent-orchestrator?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is ai-agent-orchestrator safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains ai-agent-orchestrator?
It is published by patricio0312rev in patricio0312rev/skills. It has 353 recorded installs.
More from patricio0312rev/skills
framer-motion-animator
patricio0312rev/skills
Creates smooth animations and micro-interactions using Framer Motion including page transitions, gestures, scroll-based animations, and orchestrated sequences. Use when users request "add animation", "framer motion", "page transition", "animate component", or "micro-interactions".
eslint-prettier-config
patricio0312rev/skills
Configures ESLint and Prettier for consistent code quality with TypeScript, React, and modern best practices. Use when users request "ESLint setup", "Prettier config", "linting configuration", "code formatting", or "lint rules".
postman-collection-generator
patricio0312rev/skills
Generates Postman collection JSON files from Express, Next.js, Fastify, Hono, or other API routes. Scans route definitions, extracts endpoints, methods, params, and creates importable collections. Use when users request "generate postman collection", "export to postman", "create postman file", or "postman import".
changelog-writer
patricio0312rev/skills
Generates changelogs and release notes from git commits, PR titles, and issue references. Organizes changes by impact type (breaking, features, fixes, improvements), formats according to Keep a Changelog standard, and provides version tagging and semantic versioning suggestions. Use when users request "create changelog", "write release notes", "document version changes", or "prepare release".
bruno-collection-generator
patricio0312rev/skills
Generates Bruno collection files (.bru) from Express, Next.js, Fastify, or other API routes. Creates organized collections with environments, authentication, and folder structure for the open-source Bruno API client. Use when users request "generate bruno collection", "bruno api testing", "create bru files", or "bruno import".
jsdoc-typescript-docs
patricio0312rev/skills
Documents TypeScript code with JSDoc comments, generates API documentation, and creates type-safe documentation. Use when users request "JSDoc", "code documentation", "API docs", "TypeDoc", or "inline documentation".
Popular ai & agents skills
google-agents-cli-publish
google/agents-cli
This skill should be used when the user wants to "publish an agent", "publish my ADK agent", "register an agent with Gemini", "publish to Gemini" (formerly Gemini Enterprise), or needs guidance on the agents-cli publish gemini command. Also use when the user wants to "manage agents in Agent Registry", "list/update/delete registered agents", or "register an MCP server". Covers ADK vs A2A registration modes, programmatic and interactive usage, flag reference, auto-detection from deployment metadata, Agent Registry fleet management, and troubleshooting. Part of the agents-cli skills suite. Do NOT use for deployment (use google-agents-cli-deploy).
google-agents-cli-eval
google/agents-cli
This skill should be used when the user wants to "run an evaluation", "evaluate my agent", "evaluate my ADK agent", "write an eval dataset", "analyze eval failures", "compare eval results", "optimize agent", or needs guidance on the Gemini platform eval methodology and the Quality Flywheel. Covers eval metrics, dataset schema, LLM-as-judge scoring, and common failure causes. Applies to any agents-cli project, whatever framework the agent is written in. Do NOT use for agent API code patterns (ADK: use google-agents-cli-adk-code), deployment (use google-agents-cli-deploy), or project scaffolding (use google-agents-cli-scaffold).
skill-creator
anthropics/skills
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
codex-pet
prime-skills/runcomfy-agent-skills
Codex Pet generator on RunComfy. Build a Codex-compatible Codex Pet spritesheet.webp + pet.json from a single reference image, drop it into ${CODEXHOME:-$HOME/.codex}/pets/ / and Codex picks it up as a custom Codex Pet next to the 8 built-ins. This skill produces the exact Codex Pet atlas Codex expects (1536x1872 PNG/WebP, 8 cols x 9 rows, 192x208 cells, 9 animation states — idle, running-right, running-left, waving, jumping, failed, waiting, running, review). Calls OpenAI GPT Image 2 edit ONCE via the local RunComfy CLI as runcomfy run openai/gpt-image-2/edit to produce a canonical Codex Pet pose, then assembles all 9 animation rows programmatically with ImageMagick micro-transforms — no Codex Pro, no $imagegen, no OPENAIAPIKEY required, only RUNCOMFYTOKEN. Triggers on "codex pet", "create codex pet", "make codex pet", "hatch codex pet", "/hatch image", "desktop pet codex", "codex pets", "spritesheet.webp", or any explicit ask to build a custom pet for OpenAI Codex.
full-output-enforcement
leonxlnx/taste-skill
Overrides default LLM truncation behavior. Enforces complete code generation, bans placeholder patterns, and handles token-limit splits cleanly. Apply to any task requiring exhaustive, unabridged output.
executing-plans
obra/superpowers
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available