CommunityCodierung & Entwicklunggithub.com

multi-agent-orchestrator

Entwickelt und verwaltet Multi-Agent-Kooperationssysteme mit Fokus auf Aufgabenverteilung, Nachrichtenrouting und Zustandsmanagement.

Was ist multi-agent-orchestrator?

Dieses Skill, 'Multi-Agent Orchestrator', ist ein professioneller Assistent für das Design und die Verwaltung von Multi-Agent-Kollaborationssystemen. Es bietet eine vollständige Architektur für die Koordination mehrerer KI-Agenten, einschließlich eines Orchestrators zur Aufgabenzerlegung, eines Message Bus für die lose gekoppelte Kommunikation und eines State Managers zur Verfolgung des Agentenlebenszyklus. Entwickler können mit diesem Skill schnell skalierbare Multi-Agent-Systeme implementieren, die Muster wie Rollenspiele (Role Play) und Debatten (Debate) unterstützen. Der Skill läuft auf der OpenClaw-Plattform und wurde für den Einsatz mit LLMs wie GPT-4 optimiert. Er umfasst Agent-Basisklassen, einen DAG-basierten Task-Graphen, einen konfigurierbaren Scheduler mit Parallelitätskontrolle und wiederverwendbare Typen für Aufgaben, Ergebnisse und Nachrichten. Die Skill-Dokumentation enthält detaillierte Codebeispiele in TypeScript sowie Best Practices für Fehlertoleranz, Observability und Fehlerbehandlung.

Funktioniert mit~Claude Code✓Codex CLI~Cursor
npx skills add SKY-lv/skylv-multi-agent-orchestrator

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Multi-Agent Orchestrator

Funktionsbeschreibung

Entwerfen und Verwalten von Multi-Agent-Kollaborationssystemen.

Architekturmuster

┌─────────────┐
│ Orchestrator │ ← Aufgabenzerlegung, Koordination
└──────┬──────┘
       │
   ┌───┼───┐
   ▼   ▼   ▼
 ┌───┐┌───┐┌───┐
 │ A ││ B ││ C │ ← Spezialisierte Agents
 └───┘└───┘└───┘

Kernimplementierung

1. Agenten-Basisklasse

interface AgentConfig {
  name: string;
  role: string;
  capabilities: string[];
  llm: LLMConfig;
  tools: Tool[];
  instructions: string;
}

class BaseAgent {
  protected config: AgentConfig;
  protected memory: AgentMemory;
  
  constructor(config: AgentConfig) {
    this.config = config;
    this.memory = new AgentMemory(config.name);
  }
  
  async think(task: Task): Promise<Response> {
    const context = await this.memory.buildContext(task.description);
    const prompt = this.buildPrompt(task, context);
    const response = await this.callLLM(prompt);
    await this.memory.add({ type: 'semantic', content: task.description + ' -> ' + response.content, importance: 8 });
    return response;
  }
  
  protected buildPrompt(task: Task, context: string): Message[] {
    return [
      { role: 'system', content: this.config.instructions },
      { role: 'system', content: context },
      { role: 'user', content: task.description }
    ];
  }
  
  protected async callLLM(messages: Message[]): Promise<Response> {
    const res = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}` },
      body: JSON.stringify({ model: this.config.llm.model, messages, tools: this.config.tools.map(t => t.definition) })
    });
    return res.json();
  }
}

2. Orchestrator

interface TaskResult {
  agentId: string;
  status: 'pending' | 'running' | 'done' | 'failed';
  output?: string;
  dependencies: string[];
  startTime?: number;
  endTime?: number;
}

class Orchestrator {
  private agents: Map<string, BaseAgent> = new Map();
  private taskGraph: DAG<Task>;
  
  constructor(private llmRouter: LLMRouter) {}
  
  registerAgent(agent: BaseAgent) {
    this.agents.set(agent.config.name, agent);
  }
  
  async execute(goal: string): Promise<string> {
    // 1. Aufgabenzerlegung
    const plan = await this.decompose(goal);
    
    // 2. DAG erstellen
    this.taskGraph = this.buildDAG(plan);
    
    // 3. Ausführung planen
    const results = await this.schedule();
    
    // 4. Ergebnisse zusammenfassen
    return this.summarize(goal, results);
  }
  
  private async decompose(goal: string): Promise<Task[]> {
    const response = await this.llmRouter.route({
      prompt: `Zerlege die folgende Aufgabe in ausführbare Teilaufgaben und gib ein JSON-Array zurück:
      
Ziel: ${goal}

Anforderungen:
- Jede Teilaufgabe wird von genau einem Agenten bearbeitet
- Abhängigkeiten zwischen Aufgaben klar angeben
- Rückgabeformat: [{"id":"t1","description":"...","agent":"researcher","depends":[]},...]`,
      system: 'Du bist ein Experte für Aufgabenzerlegung.'
    });
    
    return JSON.parse(response.content);
  }
  
  private async schedule(): Promise<Map<string, TaskResult>> {
    const results = new Map<string, TaskResult>();
    const pending = new Set(this.taskGraph.nodes);
    const running: Promise<void>[] = [];
    const maxConcurrent = 3;
    
    while (pending.size > 0 || running.length > 0) {
      // Starte parallel ausführbare Aufgaben
      while (running.length < maxConcurrent) {
        const next = this.findNextRunnable(pending, results);
        if (!next) break;
        
        pending.delete(next.id);
        const p = this.runTask(next, results).catch(console.error);
        running.push(p);
      }
      
      // Warte auf eine abgeschlossene Aufgabe
      await Promise.race(running);
      running.splice(running.findIndex(p => false), 1);
    }
    
    return results;
  }
  
  private async runTask(task: Task, results: Map<string, TaskResult>) {
    results.set(task.id, { agentId: task.agent, status: 'running', dependencies: task.depends || [], startTime: Date.now() });
    
    try {
      // Auf abhängige Aufgaben warten
      for (const depId of task.depends || []) {
        const dep = results.get(depId);
        if (dep?.status !== 'done') {
          await this.waitFor(depId, results);
        }
      }
      
      const agent = this.agents.get(task.agent);
      const context = this.buildContext(task, results);
      const response = await agent.think({ id: task.id, description: task.description, context });
      
      results.set(task.id, { ...results.get(task.id)!, status: 'done', output: response.content, endTime: Date.now() });
    } catch (error) {
      results.set(task.id, { ...results.get(task.id)!, status: 'failed', output: String(error), endTime: Date.now() });
    }
  }
  
  private buildContext(task: Task, results: Map<string, TaskResult>): string {
    return (task.depends || []).map(depId => {
      const dep = results.get(depId);
      return dep?.output || '';
    }).join('\n\n');
  }
}

3. Nachrichtenbus

class MessageBus {
  private subscriptions = new Map<string, Subscriber[]>();
  
  publish(channel: string, message: Message) {
    const subs = this.subscriptions.get(channel) || [];
    for (const sub of subs) {
      sub.handler(message);
    }
  }
  
  subscribe(channel: string, handler: (msg: Message) => void): () => void {
    if (!this.subscriptions.has(channel)) {
      this.subscriptions.set(channel, []);
    }
    const sub = { id: crypto.randomUUID(), handler };
    this.subscriptions.get(channel)!.push(sub);
    return () => this.unsubscribe(channel, sub.id);
  }
  
  unsubscribe(channel: string, subId: string) {
    const subs = this.subscriptions.get(channel) || [];
    const idx = subs.findIndex(s => s.id === subId);
    if (idx >= 0) subs.splice(idx, 1);
  }
}

// Nachrichtentyp
interface Message {
  id: string;
  type: 'request' | 'response' | 'broadcast' | 'event';
  from: string;
  to?: string;
  content: any;
  timestamp: number;
}

4. Zustandsmaschine

type AgentState = 'idle' | 'thinking' | 'waiting' | 'acting' | 'error';

interface AgentSession {
  id: string;
  agentId: string;
  state: AgentState;
  currentTask?: string;
  history: Turn[];
  sharedContext: Record<string, any>;
}

class StateManager {
  private sessions = new Map<string, AgentSession>();
  
  transition(sessionId: string, newState: AgentState) {
    const session = this.sessions.get(sessionId);
    if (!session) return;
    
    const oldState = session.state;
    session.state = newState;
    
    // Zustandsübergangs-Hooks
    this.onTransition(sessionId, oldState, newState);
  }
  
  // Zustandsübergangsregeln
  private canTransition(from: AgentState, to: AgentState): boolean {
    const rules: Record<AgentState, AgentState[]> = {
      idle: ['thinking'],
      thinking: ['waiting', 'acting', 'error', 'idle'],
      waiting: ['thinking', 'error', 'idle'],
      acting: ['thinking', 'error', 'idle'],
      error: ['idle', 'thinking']
    };
    return rules[from]?.includes(to) || false;
  }
}

Kommunikationsmuster

MusterBeschreibungAnwendungsszenario
BroadcastAlle Agents empfangenGlobale Benachrichtigungen
Point-to-PointBestimmter Agent empfängtAufgabenverteilung
Publish/SubscribeThemenbasierte VerteilungEreignisgesteuert
BlackboardGemeinsamer WissensraumKollaboratives Denken

Häufige Muster

Rollenspiel (Role Play)

class RolePlayOrchestrator extends Orchestrator {
  async execute(goal: string) {
    // Rollen zuweisen
    const planner = this.getAgent('planner');
    const executor = this.getAgent('executor');
    const critic = this.getAgent('critic');
    
    const plan = await planner.think({ description: goal });
    const result = await executor.think({ description: plan.output, context: '' });
    const review = await critic.think({ description: result.output, context: '' });
    
    return review.output;
  }
}

Debatte (Debate)

async debate(topic: string, rounds = 3) {
  const pro = this.getAgent('pro');
  const con = this.getAgent('con');
  const judge = this.getAgent('judge');
  
  let context = '';
  for (let i = 0; i < rounds; i++) {
    const proArg = await pro.think({ description: `Pro-Argument (Runde ${i+1}): ${topic}`, context });
    context += `\nPro: ${proArg.output}`;
    
    const conArg = await con.think({ description: `Contra-Argument (Runde ${i+1}): ${topic}`, context });
    context += `\nContra: ${conArg.output}`;
  }
  
  return judge.think({ description: `Urteil: ${topic}`, context });
}

Best Practices

  1. Einzelverantwortung: Jeder Agent hat einen klaren Fachbereich
  2. Lockere Kopplung: Kommunikation über Nachrichtenbus, direkte Abhängigkeiten vermeiden
  3. Zeitüberschreitungskontrolle: Verhindert, dass ein Agent hängen bleibt
  4. Unterbrechungsmechanismus: Automatische Herabstufung bei zu vielen Fehlern
  5. Beobachtbarkeit: Vollständige Protokollierung und Nachverfolgung

Nutzung

  1. Installieren Sie die Fähigkeit
  2. Konfigurieren Sie nach Bedarf
  3. Führen Sie mit OpenClaw aus

Verwandte Skills