Felo API PlatformFelo API Platform

Wsparcie

Triażuj ticket wsparcia w szkic odpowiedzi z dowodami

Zamaskuj ticket, klasyfikuj intencję i priorytet z Chat, pobierz fragmenty odpowiadające z dokumentacji, sprawdź publiczne rozmowy o incydencie i zostaw routowany szkic do ludzkiego zatwierdzenia.

Czas20 minutPoziomŚredniZaktualizowano2026-10-30
Dla kogoLiderzy wsparciaHelpdesk AgentInżynierowie wsparcia

Skopiuj prompt

Podmień pola w nawiasach kwadratowych i wklej do Claude Code, Codex albo AI z dostępem do terminala. Instaluje skill Felo, pyta przed wydaniem kredytów i uruchamia workflow.

Zatriażuj ten ticket wsparcia i napisz szkic odpowiedzi do przeglądu przez człowieka: [wklej ticket po usunięciu imienia, e-maila, ID konta, danych płatności i innych informacji identyfikujących].

Obszar produktu: [produkt]. Plan lub region: [tylko jeśli potrzebne do odpowiedzi]. Źródło dokumentacji: [URL centrum pomocy lub LiveDoc short_id].
Ścieżka zatwierdzania: [kto przegląda]. Kolejka eskalacji: [zespół lub kanał].

Przygotuj:
1. Intencję: jedna kategoria i jedno zdanie uzasadnienia.
2. Priorytet: pilny / normalny / niski, z zastosowaną regułą.
3. Dowody: fragmenty dokumentacji odpowiadające na ticket, z tytułem i trafnością.
4. Sprawdzenie incydentu: czy publiczne raporty sugerują szeroką awarię? Link i data albo „brak publicznego sygnału”.
5. Routing: szkic, prośba o dodatkowe informacje lub eskalacja — i dlaczego.
6. Szkic odpowiedzi: dwa do czterech zdań, tylko na dowodach, z podaniem użytego źródła.

Zasady:
- Nie umieszczaj imion, e-maili, numerów zamówień, tokenów ani danych płatności w wywołaniach API i wynikach. Pracuj tylko na zamaskowanym tickecie.
- Odpowiadaj tylko z pobranej dokumentacji. Bez dowodów eskaluj, nie zgaduj.
- Nie obiecuj zwrotów, rabatów, terminów ani zmian konta; kieruj takie sprawy do eskalacji.
- Publiczne plotki o awarii to sygnał, nie dowód. Cytuj post i datę.
- Zanim zużyjesz kredyty, pokaż planowane wywołania i poczekaj na moją zgodę.
- Nie wysyłaj odpowiedzi, nie aktualizuj ticketu i nie wykonuj działań na koncie. Zwróć szkic do przeglądu.
- Zapisz wynik w ./support-triage.md i podsumuj go w czacie.

Kopia zawiera też kroki instalacji i zasady bezpieczeństwa.

Co otrzymujesz

Przykładowy wynik jednego uruchomienia. Nie generowanie na żywo.

Przykładowy triage (fragment)

Triage — przykładowy ticket

Intencja

Pytanie o rozliczenia / odnowienie. Klient pyta, dlaczego plan znów się odnowił.

Priorytet

Normalny. To pytanie o rozliczenia, nie awaria, a klient nie jest zablokowany.

Dowody

  • „najczęstsze pytania o rozliczenia” — termin odnowienia i ponowienia karty. Trafność: wysoka.
  • „Zmiany planu” — downgrade między odnowieniami. Trafność: średnia.

Kontrola incydentów

Brak publicznych zgłoszeń w ostatnich 48 godzinach.

Routing

Szkic. Dokumentacja obejmuje pytanie.

Szkic odpowiedzi

Cześć — Twój plan odnawia się pierwszego dnia miesiąca, a odrzucona karta jest ponawiana przez trzy dni, zanim miejsce zostanie wstrzymane. Kartę zmienisz w ustawieniach rozliczeń; najczęstsze pytania o rozliczenia ma kroki. Jeśli trzeba przesunąć datę odnowienia, odpowiedz, a eskalujemy do zespołu rozliczeń.

Notatka dla recenzenta

Zatwierdź, edytuj lub eskaluj do kolejki rozliczeń.

Dokładne wywołania

Dla deweloperów: ten sam workflow jako kod, w kolejności wykonania.

Pokaż rzeczywiste wywołania API
  1. Zamaskuj i sklasyfikuj

    Usuń kodem e-mail, telefon i numer zamówienia, potem użyj Chat do intencji i priorytetu.

    triage.ts
    const BASE = "https://openapi.felo.ai";
    const headers = {
      Authorization: `Bearer ${process.env.FELO_API_KEY}`,
      "Content-Type": "application/json",
    };
    
    async function felo<T>(path: string, body?: unknown): Promise<T> {
      const res = await fetch(`${BASE}${path}`, {
        method: body ? "POST" : "GET",
        headers,
        body: body ? JSON.stringify(body) : undefined,
      });
      if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
      return res.json() as Promise<T>;
    }
    
    const redact = (text: string) =>
      text
        .replace(/[\w.+-]+@[\w.-]+\.\w+/g, "[email]")
        .replace(/\b(?:acct|account|order|invoice)[-_ ]?\w+\b/gi, "[id]")
        .replace(/\b(?:\d[ -]?){13,19}\b/g, "[card]");
    
    type Ticket = {
      id: string;
      product: string;
      subject: string;
      body: string;
      plan?: string;
      sensitive?: boolean;
    };
    
    const ticket: Ticket = {
      id: "T-1042",
      product: "Acme Workspace",
      subject: "Why did my plan renew?",
      body: "I was charged again and cannot find the renewal date on my account.",
      plan: "team",
    };
    
    const summary = redact(`${ticket.subject}\n\n${ticket.body}`).slice(0, 1500);
    
    type ChatData = {
      data: {
        answer: string;
        resources: { link: string; title: string; snippet: string }[];
      };
    };
    
    const triage = await felo<ChatData>("/v2/chat", {
      query: `Classify this support question by intent and priority, and list what is missing:\n\n${summary}`,
    });
    
    console.log(triage.data.answer);

    Przykładowy wynik

    {
      "answer": "Intent: billing / renewal question. Priority: normal. Missing: the renewal date the customer expects.",
      "resources": [
        { "link": "https://example.com/billing-faq", "title": "Billing FAQ", "snippet": "…" }
      ]
    }
  2. Pobierz dowody z dokumentacji

    Szukaj trafnych fragmentów w LiveDoc wsparcia, zachowując tytuły i wyniki.

    triage.ts
    type Hit = { title: string; content: string; score: number };
    
    const KB = process.env.SUPPORT_LIVEDOC_ID!; // the help-center LiveDoc short_id
    
    const retrieved = await felo<{ data: Hit[] }>(
      `/v2/livedocs/${KB}/resources/retrieve`,
      { query: summary },
    );
    
    const hits = retrieved.data.filter((hit) => hit.score >= 0.7).slice(0, 4);
    
    if (hits.length === 0) {
      console.log("No grounded evidence: escalate instead of drafting");
    }

    Przykładowy wynik

    [
      {
        "title": "Billing FAQ",
        "content": "Your plan renews on the first of the month; a failed card retries for three days…",
        "score": 0.91
      }
    ]
  3. Sprawdź publiczny incydent

    Szukaj na X produktu i słów jak „awaria/offline” w 48 godzinach, tylko jako publiczny sygnał.

    triage.ts
    type XData = {
      data: {
        tweets: {
          content: string;
          author: { username: string };
          created_at: string;
          url: string;
        }[];
      };
    };
    
    const since = Math.floor((Date.now() - 48 * 60 * 60 * 1000) / 1000);
    
    const incident = await felo<XData>("/v2/x/tweet/search", {
      query: `"${ticket.product}" (outage OR "not working" OR error)`,
      limit: 20,
      since_time: since,
    });
    
    const reports = incident.data.tweets.map((post) => ({
      text: post.content,
      handle: post.author.username,
      at: post.created_at.slice(0, 10),
      link: post.url,
    }));

    Przykładowy wynik

    [
      {
        "text": "Workspace login is failing for my whole team.",
        "handle": "example_user",
        "at": "2026-10-30",
        "link": "https://x.com/example_user/status/..."
      }
    ]
  4. Ustal ścieżkę i złóż odpowiedź

    Reguły decydują o kolejce; spakuj dowody, następny krok i szkic.

    triage.ts
    type Route = "draft" | "ask-customer" | "escalate";
    
    function decideRoute(): { route: Route; reason: string } {
      if (hits.length === 0) {
        return { route: "escalate", reason: "no grounded evidence in the knowledge base" };
      }
      if (ticket.sensitive) {
        return { route: "escalate", reason: "an account or billing action is requested" };
      }
      if (reports.length >= 3) {
        return { route: "escalate", reason: "public reports suggest a wider issue" };
      }
      if (!ticket.plan) {
        return { route: "ask-customer", reason: "the plan is needed to answer the question" };
      }
      return { route: "draft", reason: "the documentation covers the question" };
    }
    
    const decision = decideRoute();
    
    const packet = [
      `# Triage — ${ticket.id}`,
      "",
      `Route: ${decision.route} (${decision.reason})`,
      "",
      "## Intent and priority",
      triage.data.answer,
      "",
      "## Evidence",
      ...hits.map((hit) => `- ${hit.title} (score ${hit.score})`),
      "",
      "## Public signal",
      ...(reports.length
        ? reports.map((report) => `- @${report.handle} (${report.at}): ${report.text} — ${report.link}`)
        : ["No public reports in the last 48 hours."]),
      "",
      "## Reply draft",
      "[Written by the host Agent from the evidence above — human review required]",
    ].join("\n");
    
    console.log(packet);

    Przykładowy wynik

    # Triage — T-1042
    
    Route: draft (the documentation covers the question)
    
    ## Intent and priority
    Intent: billing / renewal question. Priority: normal.
    
    ## Evidence
    - Billing FAQ (score 0.91)
  5. Zapisz triaż

    Zapisz wynik w LiveDoc do przeglądu i audytu.

    triage.ts
    type LiveDocData = { data: { short_id: string } };
    
    const log = await felo<LiveDocData>("/v2/livedocs", {
      name: "Support triage log",
      description: "One document resource per triaged ticket",
    });
    
    await felo(`/v2/livedocs/${log.data.short_id}/resources/doc`, {
      title: `Triage — ${ticket.id}`,
      content: packet,
    });
    
    console.log(log.data.short_id); // reuse it for the next ticket

    Przykładowy wynik

    { "short_id": "PvyKouzJirXjFdst4uKRK3" }

Co zawiera

  • Intencja i priorytet po maskowaniu
  • Dowody z dokumentacji z wynikami
  • Sprawdzenie publicznego incydentu
  • Routowany szkic odpowiedzi
  • LiveDoc z zapisem triażu

Czego nie robi

  • Nie wysyła odpowiedzi, nie zamyka ticketu i nie wykonuje działań na koncie
  • Nie wysyłaj haseł, danych płatności ani pełnych danych klienta do API
  • Bez wyniku dokumentacji eskalacja jest obowiązkowa
  • X to publiczny sygnał incydentu, nie status systemu wsparcia
  • Zasady priorytetu są twoje; model tylko proponuje

Pytania

Jakie dane ticketu mogę wysłać?

Tylko potrzebny kontekst po maskowaniu: produkt, opis, plan i region. Bez haseł, płatności, pełnego adresu i prywatnej rozmowy.

Skąd odpowiedź?

Z fragmentów pobranych w LiveDoc dokumentacji. Bez wyników workflow eskaluje zamiast zgadywać.

Czy odpowiada lub zamyka ticket?

Nie. Tworzy tylko szkic i ścieżkę; wysyłkę i zamknięcie robi człowiek lub twój system.

Jak ustalany jest priorytet?

Twoimi regułami; model proponuje i uzasadnia, ścieżka potwierdza priorytet końcowy.

Jeśli dokumentacja nie pokrywa?

Eskalacja do ludzkiej kolejki z „brak pokrycia” w pakiecie triażu.

Ile kosztuje triaż?

Chat, wyszukiwanie i X Search są rozliczane według użycia; aktualne stawki na stronie cen, a prompt pyta o zgodę przed wydaniem.

Powiązane workflowy

Dostosuj

Ta sama receptura, dopasowana do tego, jak naprawdę dostarczasz.

Tylko klasyfikacja

Bez odpowiedzi: tylko intencja, priorytet i sugerowana kolejka.

Podłącz do systemu ticketów

Twoim webhookiem zapisz pakiet w tickecie bez automatycznej wysyłki.

Rozszerz do bazy wiedzy

Przy wynikach dokumentacji przejdź do workflow bazy wiedzy po pełniejszą odpowiedź.

Strony referencyjne za tą recepturą i kolejne kroki.