Enneo

Events & Webhooks

Beispiel: Mehrere KI-Agenten und/oder Folgeantworten dunkelverarbeiten

Ansatz zur automatischen Ausführung mehrerer KI-Agenten und/oder bei Folgeantworten des Kunden

Szenario

Enneo führt standardmäßig die automatische Ausführung (Dunkelverarbeitung) von KI-Agenten nur bei der ersten eingehenden E-Mail eines Tickets durch und nur wenn genau ein KI-Agent erkannt wurde. In zwei Situationen greift die Standard-Dunkelverarbeitung daher nicht:

  1. Mehrere KI-Agenten erkannt: Ein Kunde stellt in einer E-Mail mehrere Anliegen gleichzeitig, z. B. eine Kündigung und einen Widerruf. Enneo erkennt zwar beide KI-Agenten, führt aber aus Sicherheitsgründen keinen automatisch aus.
  2. Folgeantworten: Ein Kunde antwortet erneut auf ein bestehendes Ticket. Die KI-Verarbeitung läuft zwar (Tags, KI-Agenten-Erkennung, Parameterextraktion), aber die automatische Ausführung wird nicht erneut ausgelöst.

In beiden Fällen wird das Ticket stattdessen einem menschlichen Bearbeiter zugewiesen. Mit einem Event Hook lässt sich dieses Verhalten anpassen.

Info

Diese Seite gilt für KI-Agenten im Standardmodus. Mit Smart Agent V2 deckt ein Lösungsplan alle Anliegen eines Tickets ab und wird von der Dunkelverarbeitung als Ganzes freigegeben, auch bei Folgeantworten. Der Hook wird dann nicht benötigt: Seine Positivliste sähe neben den Schritten auch den KI-Agenten des Plans, und einen Plan mit der Stufe Mit Freigabe gibt der Aufruf aus dem Hook nicht frei.

Lösungsmöglichkeit

Ein Event Hook reagiert auf eingehende Tickets bzw. Kundenantworten, prüft die erkannten KI-Agenten und löst die automatische Ausführung für alle gemeinsam aus. Der Kunde erhält eine gemeinsame Antwort auf alle Anliegen.

Schritt 1: Event Hook anlegen

Unter Einstellungen -> Integration in Umsysteme -> Events einen oder beide der folgenden Event Hooks erstellen:

  • TicketCreated — wird nach dem Empfang eines neuen Tickets und Abschluss der KI-Verarbeitung ausgelöst. Verwenden, wenn mehrere KI-Agenten auf der initialen E-Mail automatisch ausgeführt werden sollen.
  • TicketResponse — wird ausgelöst, wenn eine Antwort auf ein bestehendes Ticket vom Kunden empfangen und die KI-Verarbeitung abgeschlossen wurde. Verwenden, wenn KI-Agenten auch bei Folgeantworten automatisch ausgeführt werden sollen.

Der folgende Code kann für beide Events verwendet werden. Er prüft alle erkannten KI-Agenten (Intents) im Status ready und führt sie mit einem einzigen Aufruf gemeinsam aus:

POST /api/mind/ticket/:ticketId/autoexecute?allowMultipleIntents=true&allowWithReplies=true

Info

Der Parameter allowMultipleIntents=true ermöglicht die automatische Ausführung auch wenn mehrere KI-Agenten auf dem Ticket erkannt wurden. Ohne diesen Parameter wird die Ausführung bei mehreren erkannten Agenten aus Sicherheitsgründen abgelehnt.

Der Parameter allowWithReplies=true ermöglicht die automatische Ausführung auch wenn das Ticket bereits eingehende Kundenantworten enthält. Ohne diesen Parameter wird die Ausführung abgelehnt, sobald eine Kundenantwort auf dem Ticket existiert. Dieser Parameter ist nur für das TicketResponse-Event relevant.

Warning

Den Endpunkt nicht einzeln pro KI-Agent mit executeAgentId aufrufen. Schon der erste Aufruf sendet die Antwort nur dieses KI-Agenten und schließt das Ticket; alle weiteren Aufrufe werden abgelehnt und die übrigen Anliegen bleiben unbeantwortet. Außerdem führt executeAgentId den KI-Agenten auch dann aus, wenn sein Fall auf der Seite Dunkelverarbeitung auf Aus steht.

Info

In diesem Code-Beispiel wird zur besseren Übersichtlichkeit bewusst auf das Fehlerhandling verzichtet.

<?php

use EnneoSDK\ApiEnneo;

require(getenv()['SDK'] ?? 'sdk.php');

/** @var stdClass $in - enthält alle definierten Eingabeparameter aus dem Event */

// Ticketdaten laden
$ticket = ApiEnneo::getTicket($in->ticketId);

// Nur offene Tickets verarbeiten
if ($ticket->status !== 'open') {
    echo json_encode(['autoExecute' => false, 'reason' => 'Ticket ist nicht offen']);
    return;
}

// Intents (erkannte KI-Agenten) laden
$intents = ApiEnneo::get(endpoint: '/api/mind/intent/byTicketId/' . $in->ticketId);

// Alle Intents im Status "ready" sammeln
$readyIntents = array_filter($intents->intents, fn($i) => $i->status === 'ready');

if (empty($readyIntents)) {
    echo json_encode(['autoExecute' => false, 'reason' => 'Keine Intents im Status ready gefunden']);
    return;
}

// Optional: Weitere Prüfungen, z. B. Kundenerkennung oder Tags
// if (!$ticket->contractId) {
//     echo json_encode(['autoExecute' => false, 'reason' => 'Kein Vertrag erkannt']);
//     return;
// }

// Optional: Nur ausführen, wenn alle erkannten KI-Agenten freigegeben sind.
// Der Aufruf führt immer alle aus, daher bei einem nicht freigegebenen KI-Agenten das ganze Ticket dem Bearbeiter überlassen.
// $allowedAgentIds = [4, 5, 12, 34];
// foreach ($readyIntents as $intent) {
//     if (!in_array($intent->aiAgentId, $allowedAgentIds)) {
//         echo json_encode(['autoExecute' => false, 'reason' => 'KI-Agent ' . $intent->aiAgentId . ' ist nicht freigegeben']);
//         return;
//     }
// }

// Alle erkannten KI-Agenten gemeinsam ausführen
$result = ApiEnneo::post(
    endpoint: '/api/mind/ticket/' . $in->ticketId . '/autoexecute?allowMultipleIntents=true&allowWithReplies=true',
    body: []
);

echo json_encode(['autoExecute' => $result->success, 'agentIds' => array_values(array_map(fn($i) => $i->aiAgentId, $readyIntents)), 'message' => $result->message]);
import importlib.util
import os
import json

file_path = os.getenv('SDK', 'sdk.py')
spec = importlib.util.spec_from_file_location('sdk', file_path)
sdk = importlib.util.module_from_spec(spec)
spec.loader.exec_module(sdk)

# Eingabeparameter aus dem Event laden
in_data = sdk.load_input_data()

# Ticketdaten laden
ticket = sdk.ApiEnneo.get_ticket(in_data['ticketId'])

# Nur offene Tickets verarbeiten
if ticket.get('status') != 'open':
    print(json.dumps({'autoExecute': False, 'reason': 'Ticket ist nicht offen'}))
    exit()

# Intents (erkannte KI-Agenten) laden
intents_response = sdk.ApiEnneo.get(endpoint=f'/api/mind/intent/byTicketId/{in_data["ticketId"]}')
intents = intents_response.get('intents', [])

# Alle Intents im Status "ready" sammeln
ready_intents = [i for i in intents if i.get('status') == 'ready']

if not ready_intents:
    print(json.dumps({'autoExecute': False, 'reason': 'Keine Intents im Status ready gefunden'}))
    exit()

# Optional: Weitere Prüfungen, z. B. Kundenerkennung oder Tags
# if not ticket.get('contractId'):
#     print(json.dumps({'autoExecute': False, 'reason': 'Kein Vertrag erkannt'}))
#     exit()

# Optional: Nur ausführen, wenn alle erkannten KI-Agenten freigegeben sind.
# Der Aufruf führt immer alle aus, daher bei einem nicht freigegebenen KI-Agenten das ganze Ticket dem Bearbeiter überlassen.
# allowed_agent_ids = [4, 5, 12, 34]
# not_allowed = [i['aiAgentId'] for i in ready_intents if i['aiAgentId'] not in allowed_agent_ids]
# if not_allowed:
#     print(json.dumps({'autoExecute': False, 'reason': f'KI-Agenten nicht freigegeben: {not_allowed}'}))
#     exit()

# Alle erkannten KI-Agenten gemeinsam ausführen
try:
    result = sdk.ApiEnneo.post(
        endpoint=f'/api/mind/ticket/{in_data["ticketId"]}/autoexecute?allowMultipleIntents=true&allowWithReplies=true',
        body={}
    )
except Exception as e:
    # Lehnt enneo die Ausführung ab, wirft das SDK eine Exception
    print(json.dumps({'autoExecute': False, 'reason': str(e)}))
    exit()

print(json.dumps({'autoExecute': result.get('success') is True, 'agentIds': [i['aiAgentId'] for i in ready_intents], 'message': result.get('message')}))

Schritt 2: Automatische Verarbeitung durch enneo

Nach dem Aufruf des Autoexecute-Endpunkts prüft enneo zuerst, ob für jeden erkannten KI-Agenten der empfohlene Fall auf der Seite Dunkelverarbeitung auf Mit Freigabe oder Automatisch steht. Ist das für einen KI-Agenten nicht der Fall, wird nichts ausgeführt und das Ticket bleibt beim Bearbeiter. Andernfalls führt enneo folgende Schritte automatisch aus:

  1. Alle KI-Agenten werden ausgeführt.
  2. Ihre Antworten werden in eine E-Mail zusammengefasst und an den Kunden gesendet.
  3. Das Ticket wird geschlossen.
  4. Die Bearbeitung zählt in der Auswertung als vollautomatisiert (L5).

Schlägt einer der KI-Agenten fehl, wird keine E-Mail gesendet und das Ticket geht mit einer Notiz an den Bearbeiter. Aktionen der KI-Agenten, die vorher bereits ausgeführt wurden, bleiben ausgeführt.

Hinweise

  • Das TicketCreated-Event eignet sich für die initiale E-Mail mit mehreren Anliegen. Das TicketResponse-Event eignet sich für Folgeantworten. Beide Events können gleichzeitig mit demselben Code konfiguriert werden.
  • Der Parameter allowWithReplies=true ist notwendig, weil enneo standardmäßig die automatische Ausführung blockiert, sobald eine eingehende Kundenantwort auf dem Ticket existiert. Für das TicketCreated-Event ist dieser Parameter wirkungslos, da es noch keine Antworten gibt.
  • Der Parameter allowMultipleIntents=true ist notwendig, weil ohne ihn die Ausführung bei mehreren erkannten Agenten aus Sicherheitsgründen abgelehnt wird.
  • Der Aufruf aus dem Hook wartet weder auf eine Freigabe noch auf einen eingestellten Zeitversatz: Auch Fälle mit der Stufe Mit Freigabe werden sofort ausgeführt. Sollen sie weiterhin freigegeben werden, die betroffenen KI-Agenten nicht in die Positivliste (allowedAgentIds) aufnehmen.
  • Die Antworten der KI-Agenten werden nacheinander in dieselbe E-Mail-Vorlage eingefügt. Enthalten die Antworttexte selbst eine Anrede oder Grußformel, erscheint sie mehrfach.