Support
Triageer een supportticket naar een onderbouwd antwoordconcept
Maskeer het ticket, classificeer intentie en prioriteit met Chat, haal de passages op die antwoorden uit de documentatie, controleer openbare incidentgesprekken en laat een gerouteerd concept achter voor menselijke goedkeuring.
Prompt kopiëren
Vervang de velden tussen blokhaken en plak in Claude Code, Codex of een AI met terminaltoegang. Die installeert de Felo-skill, vraagt voor credits en voert de workflow uit.
Triage dit supportticket en schrijf een antwoordconcept voor menselijke beoordeling: [plak het ticket nadat naam, e-mail, account-ID, betaalgegevens en andere identificerende informatie zijn verwijderd]. Productgebied: [product]. Plan of regio: [alleen als nodig voor het antwoord]. Documentatiebron: [helpdesk-URL of LiveDoc short_id]. Goedkeuringsroute: [wie beoordeelt]. Escalatiewachtrij: [team of kanaal]. Lever: 1. Intentie: één categorie en één zin onderbouwing. 2. Prioriteit: urgent / normaal / laag, met de toegepaste regel. 3. Bewijs: de documentatiepassages die het ticket beantwoorden, met titel en relevantie. 4. Incidentcheck: wijzen publieke meldingen op een brede storing? Link en datum, of ‘geen publiek signaal’. 5. Routing: concept, extra informatie vragen of escaleren — en waarom. 6. Antwoordconcept: twee tot vier zinnen, alleen op bewijs, met vermelding van de gebruikte bron. Regels: - Zet geen namen, e-mails, ordernummers, tokens of betaalgegevens in API-aanroepen of output. Werk alleen met het gemaskeerde ticket. - Antwoord alleen uit de opgehaalde documentatie. Zonder bewijs escaleer je in plaats van te raden. - Beloof geen terugbetalingen, kortingen, termijnen of accountwijzigingen; stuur die naar de escalatie. - Publieke storingsgeruchten zijn signalen, geen bewijs. Citeer de post en de datum. - Voordat er credits worden gebruikt, toon je de geplande aanroepen en wacht je op mijn goedkeuring. - Verstuur geen antwoord, werk het ticket niet bij en voer geen accountacties uit. Geef het concept terug voor beoordeling. - Schrijf het resultaat naar ./support-triage.md en vat het samen in de chat.
De kopie bevat ook de installatiestappen en veiligheidsregels.
Wat je krijgt
Voorbeelduitvoer van een run. Geen live generatie.
Triage — voorbeeldticket
Intentie
Facturatie-/verlengingsvraag. De klant vraagt waarom het plan opnieuw is verlengd.
Prioriteit
Normaal. Het is een facturatievraag, geen storing, en de klant is niet geblokkeerd.
Bewijs
- “veelgestelde vragen over facturatie” — verlengingsmoment en retries bij mislukte kaart. Relevantie: hoog.
- “Planwijzigingen” — downgrade tussen verlengingen. Relevantie: middel.
Incidentcheck
Geen publieke meldingen in de laatste 48 uur.
Route
Concept. De documentatie dekt de vraag.
Antwoordconcept
Hallo — je plan vernieuwt op de eerste van de maand en een mislukte kaart wordt drie dagen opnieuw geprobeerd voordat de seat wordt gepauzeerd. Je kunt de kaart wijzigen in Facturatie-instellingen; de veelgestelde vragen over facturatie heeft de stappen. Als de verlengingsdatum moet schuiven, antwoord en we escaleren naar het facturatieteam.
Opmerking voor reviewer
Goedkeuren, bewerken of escaleren naar de facturatiewachtrij.
De exacte aanroepen
Voor ontwikkelaars: dezelfde workflow als kopieerbare code in uitvoeringsvolgorde.
Exacte API-aanroepen tonen
Maskeer en classificeer
Verwijder per code e-mail, telefoon en ordernummer en bepaal daarna met Chat intentie en prioriteit.
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);Voorbeelduitvoer
{ "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": "…" } ] }Haal documentatiebewijs op
Zoek relevante passages in de support-LiveDoc en bewaar titels en scores.
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"); }Voorbeelduitvoer
[ { "title": "Billing FAQ", "content": "Your plan renews on the first of the month; a failed card retries for three days…", "score": 0.91 } ]Controleer openbaar incident
Zoek op X product en woorden als ‘storing/offline’ in de laatste 48 uur, alleen als openbaar signaal.
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, }));Voorbeelduitvoer
[ { "text": "Workspace login is failing for my whole team.", "handle": "example_user", "at": "2026-10-30", "link": "https://x.com/example_user/status/..." } ]Bepaal route en stel antwoord samen
Regels bepalen de wachtrij; bundel bewijs, volgende stap en antwoordconcept.
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);Voorbeelduitvoer
# 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)
Registreer de triage
Schrijf het resultaat in de LiveDoc voor terugblik en audit.
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 ticketVoorbeelduitvoer
{ "short_id": "PvyKouzJirXjFdst4uKRK3" }
Wat inbegrepen is
- Intentie en prioriteit na maskering
- Documentatiebewijs met scores
- Controle op openbaar incident
- Gerouteerd antwoordconcept
- LiveDoc met triageregistratie
Wat het niet doet
- Verstuurt geen antwoord, sluit geen ticket en voert geen accountacties uit
- Stuur geen wachtwoorden, betaalgegevens of volledige klantdata naar de API
- Zonder documentatietreffer is escalatie verplicht
- X is een openbaar incidentsignaal, niet de status van het supportsysteem
- Prioriteitsregels zijn van jou; het model doet alleen een voorstel
Vragen
Welke ticketdata mag ik sturen?
Alleen de nodige gemaskeerde context: product, probleem, plan en regio. Geen wachtwoorden, betaalgegevens, volledig adres of privégesprek.
Waar komt het antwoord vandaan?
Uit passages die in de LiveDoc zijn gevonden. Zonder treffer escaleert de workflow in plaats van te gissen.
Antwoordt of sluit het het ticket?
Nee. Het maakt alleen concept en route; verzenden en sluiten doen een mens of jouw systeem.
Hoe wordt prioriteit bepaald?
Door jouw regels; het model stelt voor en onderbouwt, de route bevestigt de eindprioriteit.
Wat als de documentatie niet dekt?
Escalatie naar de menselijke wachtrij met ‘niet gedekt’ in het triagepakket.
Wat kost een triage?
Chat, zoekopdracht en X Search worden op gebruik gefactureerd; actuele tarieven staan op de prijspagina en de prompt vraagt goedkeuring voor uitgaven.
Gerelateerde workflows
Beantwoord supportvragen vanuit je eigen documentatie
Maak een LiveDoc, laad het helpcenter en de interne runbook, haal de passages op die het ticket beantwoorden en laat het model alleen uit dat bewijs antwoorden.
Workflow openenContentMaak van socialgesprekken een wekelijkse luisterbrief
Zoek de X-posts van de afgelopen week over je merk en concurrenten, voeg onderbouwde webcontext toe, lees de pagina’s erachter en archiveer elke editie zodat de volgende week bij het bekende begint.
Workflow openenResearchMaak van één vraag een onderbouwde researchbrief
Vraag het web, bewaar de pagina’s achter het antwoord als Markdown, voeg toe wat practitioners op X zeggen en houd het bewijs in een LiveDoc dat je later opnieuw kunt doorzoeken.
Workflow openenMaak het van jou
Hetzelfde recept, aangepast aan hoe je echt oplevert.
Alleen classificatie
Zonder antwoord: alleen intentie, prioriteit en aanbevolen wachtrij.
Koppel aan ticketsysteem
Schrijf het pakket via je eigen webhook in het ticket, zonder automatische verzending.
Bouw door naar kennisbank
Bij documentatietreffers naar de kennisbankworkflow voor een vollediger antwoord.
Verder
De referentiepagina’s achter dit recept en de volgende stappen.