Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AutoTriage

AI-powered support-ticket classification and resolution, built on LangGraph.

AutoTriage ingests a support ticket, classifies it (category / urgency / complexity / confidence), routes it, retrieves grounding articles from a vector knowledge base, generates a grounded response, and runs guardrails before delivery — with a supervisor agent that can send the ticket back for re-classification or another retrieval pass. A FastAPI admin panel exposes ticket ingest, a live streaming chat, KB browsing, dataset seeding, and LLM-call analytics.

The repository runs three parallel triage pipelines over different datasetsbitext, tobi, and kaludi — each with its own agents, prompts, and per-project Mongo KB collection.


Architecture

AutoTriage architecture

Blue = API / ingress · green = LangGraph pipeline nodes · purple = model layer · grey = data & vector stores · orange = observability · red = human escalation. Solid edges are graph control flow; dashed edges are LLM / embedding calls and best-effort logging / tracing. Source: docs/architecture.dot (dot -Tpng -Gdpi=160 docs/architecture.dot -o docs/architecture.png); component table in docs/architecture.md.


Pipeline

Each ticket flows through a LangGraph state machine with an agentic-RAG retrieval stage and a supervisor correction loop:

ingest → classify ──(route)──┐
                             ├─ human_only → escalate → END
                             └─ else → retrieve_kb → supervisor ──┐
                                                                  ├─ ready       → resolve → guardrails → END
                                                                  ├─ reclassify  → classify     (loop)
                                                                  ├─ retry_rag   → retrieve_kb  (loop)
                                                                  └─ human_only  → escalate → END
  • classify — task-specialized NVIDIA NIM model returns structured classification; human_only routing escalates immediately.
  • retrieve_kbagentic RAG: an LLM expands the query into multiple variants → batch-embed → parallel category-scoped vector search → rerank → top articles.
  • supervisor — reviews the classification + retrieved context and returns ready, reclassify, or retry_rag; a retry counter breaks the loop at 3 attempts, and any unrecognized/error decision safely escalates to a human.
  • resolve — generates a grounded response from the retrieved articles.
  • guardrails — checks the response before it is marked closed.
  • escalate — routes the ticket to the human queue.

State is a TicketState TypedDict; every node persists progress to PostgreSQL.


LLM backends

Concern Backend
Classify / resolve / supervise / query-expand NVIDIA NIM (OpenAI-compatible, task-routed models)
Reranking NVIDIA NIM
Live chat streaming (SSE) Gemini primary, NVIDIA NIM fallback on quota/error
Embeddings nomic-embed-text-v1.5 via an external OpenAI-compatible endpoint
Legacy accuracy harness only Claude Agent SDK

Tech stack

  • Orchestration: LangGraph (agent graph, state, conditional routing)
  • API / UI: FastAPI + Jinja2 templates + Server-Sent Events
  • Vector store: MongoDB Atlas native Vector Search (per-project, category-scoped collections)
  • Relational store: PostgreSQL (tickets, chat messages, LLM call logs) via async SQLAlchemy
  • Cache / queue: Redis
  • Observability: self-hosted Langfuse (traces + token usage)
  • Lint / format: Ruff

Getting started

Docker Compose (recommended)

Brings up the app plus MongoDB Atlas Local (native vector search), PostgreSQL, Redis, and the Langfuse stack.

docker compose up --build          # app on http://localhost:8000

After the stack is up, seed a dataset from the /datasets admin page or via POST /seed/{project}.

Run the API without Docker

uvicorn api.main:app --host 0.0.0.0 --port 8000

(Requires reachable MongoDB, PostgreSQL, Redis, and the embedding endpoint — see environment variables below.)


Admin panel

Route Purpose
/ Ticket list (optionally filtered by project)
POST /ingest Ingest a ticket (Form or JSON) and run the matching pipeline in the background
/ticket/{id} Ticket detail
/chat/{session} + /chat/{session}/stream Live streaming support chat (SSE)
/datasets + POST /seed/{project} Dataset overview and KB seeding
/kb/{project} Browse a project's knowledge-base articles
/analytics LLM-call analytics (calls, latency, token usage per model)

Environment variables

Config is loaded from .env (.env is git-ignored). Template: autotriage/.env.example.

# NVIDIA NIM (primary reasoning engine)
NVIDIA_API_KEY=...
NVIDIA_BASE_URL=https://integrate.api.nvidia.com/v1
NVIDIA_MODEL=...

# Gemini (chat streaming)
GEMINI_API_KEY=...
GEMINI_MODEL=...

# MongoDB Atlas (vector store; per-project collections)
MONGODB_URI=mongodb://mongodb:27017/
MONGODB_DB_NAME=autotriage
MONGODB_VECTOR_INDEX_NAME=vector_index

# PostgreSQL (tickets, chat, LLM call logs)
POSTGRES_URI=postgresql://admin:password@postgres:5432/autotriage

# Redis
REDIS_URI=redis://redis:6379/0

# Embeddings (external OpenAI-compatible endpoint)
EMBEDDING_API_KEY=...
EMBEDDING_BASE_URL=http://embedding-srv:8000/v1
EMBEDDING_MODEL=nomic-embed-text-v1.5

# Langfuse (self-hosted tracing + token usage)
LANGFUSE_BASE_URL=http://localhost:3000
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...

Observability

The stack ships with a self-hosted Langfuse instance for distributed tracing and token-usage tracking.

Dashboard: http://localhost:3000. On first visit, create an admin account (first signup becomes admin), create a project, and copy its public/secret keys into your .env.

Every ticket processed by the active pipelines becomes a Langfuse trace tagged with the project name, and NVIDIA NIM token usage is captured. The existing Postgres LLMCallLog table and the /analytics view remain the in-app logging path; Langfuse is an additive layer. (Dollar cost shows $0 until NVIDIA model prices are registered as Langfuse custom prices — token counts are accurate, dollar pricing is deferred; and Gemini-answered chat turns do not yet carry token usage on their span.)


Project structure

api/                     FastAPI app, templates, SSE chat  (the running entry point)
projects/
  bitext_triage/         active pipeline + agents + prompts + loader (per dataset)
  tobi_triage/
  kaludi_triage/
core/
  llm_clients/           NVIDIA NIM, Gemini, Claude clients
  agents/                supervisor, agentic retriever
  kb/                    MongoDB Atlas vector store (seed / search)
  db/                    async PostgreSQL models, CRUD, session
  observability/         Langfuse integration
  schemas.py             Pydantic enums / models
autotriage/              legacy Milestone 1–2 single-dataset accuracy harness (not the live path)
infra/ , docker-compose.yml , Dockerfile

Two codebases: projects/* is the active path that api/main.py imports and runs. autotriage/ is the original single-dataset reference harness used for scored accuracy testing and is not wired into the API.


Development

  • Lint / format: ruff check --fix . && ruff format .
  • The three projects/* pipelines are intentional near-duplicates; changes to one usually need mirroring to the other two.
  • KB collections are per-project and category-scoped — a resolver only sees its own dataset's articles.

About

AI support-ticket triage: LangGraph pipeline with classification, agentic RAG, supervisor correction loop, and Langfuse observability.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages