Skip to content

Repository files navigation

Vertrez Support Triage Agent

An agentic AI support-triage demo by Vertrez.

It watches an inbox of incoming support tickets, and for each one runs a multi-step pipeline that classifies the message, retrieves relevant help-doc passages, drafts a grounded reply, suggests an assignee team, finds similar tickets in the queue, and flags low-confidence cases for human review. A human always approves, edits, or rejects before anything ships — nothing is auto-sent.

It is built for SaaS support teams who feel the pinch between ticket volume and headcount, and want to see what agentic AI looks like wired into the real flow of work rather than a chat sidebar.

What this repo is for

This is a demo / reference implementation, not a production product. It runs locally, with zero infrastructure, on a free LLM tier. It exists to show the architecture and behaviour of a triage agent end-to-end so you can judge the approach before commissioning a production build. See "Production note" below for what changes when this gets wired into your actual stack.

Quick start

cp .env.example .env.local       # then add your free Gemini API key
npm install
npm run seed                     # embeds the help docs locally (~10s)
npm run dev                      # http://localhost:3000

Get a free Gemini API key at aistudio.google.com. The seed step computes embeddings entirely on-device via @huggingface/transformers — no embedding API is called.

How it works

   incoming ticket
        │
        ▼
  ┌──────────────┐
  │  1. Classify │   category · priority · sentiment · reasoning   (low-temp JSON)
  └──────┬───────┘
         │  (if body > 1400 chars, summarise first)
         ▼
  ┌──────────────┐
  │  2. Retrieve │   embed ticket → top-K passages from help docs
  └──────┬───────┘
         │
         ▼
  ┌──────────────┐
  │  3. Draft    │   reply grounded only in retrieved passages
  └──────┬───────┘   (escalates honestly when docs don't cover it)
         │
         ▼
  ┌──────────────┐
  │  4. Route    │   suggest assignee team + tags
  └──────┬───────┘
         │
         ▼
  ┌──────────────┐
  │  5. Flag     │   confidence band + SLA + similar tickets in queue
  └──────┬───────┘
         │
         ▼
  ┌────────────────────────┐
  │  Human in the loop     │   approve · edit · reject
  └────────────────────────┘

The pipeline lives in lib/triage.ts and reads as cleanly as the diagram above — every step is one named function, all of them typed.

Guardrails

  • Grounded answers only. The draft is generated against the retrieved doc passages. If the top retrieval similarity is below the threshold, the agent does not invent an answer — it writes an honest "we don't have this documented, escalating to a human" message instead.
  • Never auto-sends. Every draft is gated behind Approve / Edit / Reject. There is no automatic delivery path.
  • Human-in-the-loop by default. Low-confidence triage, missing context, and very low-info messages are explicitly flagged "Needs human review" and surfaced in the inbox.
  • Deterministic classification. The classifier runs at low temperature with a strict JSON schema, so the same ticket triages the same way every time.

Known limitations

This is intentionally a scoped demo. The things this codebase does NOT do (and which production needs):

  • No real inbox integration. Tickets are seeded from a JSON file. Production wires this to Gmail, Zendesk, Intercom, Front, etc.
  • In-memory state only. Tickets, decisions, and document embeddings live in the Node process. Nothing is persisted across restarts of the dev server (the doc embeddings are cached to data/seed-embeddings.json for speed).
  • No auth, no multi-tenancy. Single-user, single-process. Production adds auth, RBAC, and workspace scoping.
  • No analytics persistence. The summary strip is computed in memory from the current session.
  • No automated sending. Approve/Edit/Reject update local state — they do not actually email anything.
  • Single LLM call per pipeline step. No retries, no streaming. Adequate for demo; production wraps with retry and observability.
  • Deterministic demo data. The 15 seeded tickets are crafted to exercise the different code paths (escalation, frustration, low-info, long thread, etc.).

Architecture & swappable provider

app/                    Next.js 15 app router (UI + API routes)
components/             Inbox, TicketDetail, TriagePanel, Badges, SummaryStrip, TopBar
lib/
  config.ts             central thresholds (confidence, SLA, retrieval-k, models)
  embeddings.ts         local on-device embeddings via @huggingface/transformers
  chunker.ts            paragraph-aware chunking
  vectorStore.ts        in-memory doc store with cosine search
  ticketStore.ts        in-memory ticket store
  llm.ts                provider-agnostic LLM module — see below
  triage.ts             the pipeline
scripts/seed.ts         embeds help docs and writes data/seed-embeddings.json
data/seed-docs/         markdown help docs (Lumora demo)
data/seed-tickets.json  the seeded inbox
types/                  shared types

lib/llm.ts exposes typed functions (classifyTicket, draftReply, summarizeThread) and is the only place that talks to a generation model. The demo uses Google Gemini's free tier. For production, this file is swapped (or its body replaced) with the Anthropic Claude SDK — every caller stays unchanged because the function signatures are stable.

Production note

The production version of this agent connects to your real inbox (Gmail / Zendesk / Intercom / Front), persists tickets and decisions to a real datastore, runs generation on Claude with prompt caching and observability, adds auth, multi-tenancy, audit logging, and your brand voice. Built by Vertrezvertrez.dev. If you want this wired into your actual support stack, say hi.

License

MIT.

About

Agentic AI support-triage demo by Vertrez. Classifies, retrieves, drafts and routes tickets with a human-in-the-loop. Local-only, free to run.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages