This project contains the backend and the frontend for an AI ticketing system agent.
- Clone the repository
cd back-end- Install requirements:
pip install -r requirements.txt - Run the server:
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
- run
cd ../front-end - Install requirements:
npm install - Run the server :
npm run dev - You can interact with the agent , create tickets and send them via the url shown in the console , eg : http://localhost:3000
- Multi-document OCR - Supports PDF, TXT, and image file processing
- Intelligent Ticket Pipeline - Streamlined workflow for:
- Processing client tickets
- Responding based on knowledge base
- Escalating to human support with documented reasons
- Supports multiple languages
- Repo contains two FastAPI services (agentic-ai and back-end) sharing the same multi-agent ticket pipeline and two Next.js fronts (front-end and front-end/tc-front).
- This report summarizes exactly what is implemented: request flow, agent responsibilities, RAG/KB ingestion, caching, tests, and UI hooks. No unimplemented or inferred behavior is included.
- API entry: POST
/ticketacceptsticket_idandcontent, returningFinalResponse(agentic-ai/app/main.py). - Orchestrator routes the call through four stages (agentic-ai/app/agents/orchestrator.py):
- Analyze ticket text →
AnalysisResult(summary, keywords) - Retrieve context via RAG →
RagResult(context, sources, similarity_score) - Evaluate confidence/sentiment →
EvaluationResult(decision, confidence_score, reason) - If
APPROVE, generate final reply; else return escalated response.
- Analyze ticket text →
- Analyzer: LLM call is stubbed (
call_llmreturnsNone), so a deterministic fallback runs: cleans text, builds a 200-char summary, extracts up to 8 unique non-stopword tokens as keywords (agentic-ai/app/agents/analyzer.py). - RAG retrieval: Uses FAISS vector store with HuggingFace all-MiniLM-L6-v2. Retrieves top 5 docs with scores, inverts score for a simple rerank, normalizes to [0,1], concatenates snippets into
context, collectssources, and reports max normalized score assimilarity_score(agentic-ai/app/agents/rag.py). If no docs, returnsINSUFFICIENT_CONTEXTand zero score. - Evaluation: Averages provided snippet confidences (currently five copies of
similarity_score). Escalates if average < 0.6 or context containsINSUFFICIENT_CONTEXT. Attempts sentiment on summary via TextBlob; sentiment < -0.2 triggers escalation; exceptions also escalate. Otherwise approves with reason "Sufficient KB confidence and neutral/positive sentiment" (agentic-ai/app/agents/evaluator.py). - Responder: Calls Mistral chat model with a strict JSON contract (
response,escalate). Strips code fences, parses JSON, and returnsFinalResponse. If LLM saysescalate: true, marksescalated=Truewith reason "Insufficient information to answer the ticket." Otherwise marks answered by automation (agentic-ai/app/agents/responder.py). - LLM client: Uses
mistral-small-latestwith API key loaded from.envinapp/(MISTRAL_API_KEYrequired) (agentic-ai/app/utils/llm.py). - Vector store access: Lazily loads FAISS index from
vectorstore/withallow_dangerous_deserialization=True. Embedding cache sits in SQLiteembedding_cache.dbwith 24h TTL; cache key is SHA-256 of text (agentic-ai/app/rag/vectorstore.py, agentic-ai/app/rag/cache.py).
- Script scans
app/rag/docs/(subfolders:policies,faq,guide; others becomeuncategorized). - Supported formats:
.md,.txt,.pdf,.png/.jpg/.jpeg(PDF via pdfplumber, images via Tesseract OCR). - Markdown is split into logical blocks, then chunked to ~200 words with 50-word overlap; each chunk stored as a LangChain
Documentwith metadata (source,category,doc_type,chunk_id). - Builds FAISS index with normalized L2 embeddings (all-MiniLM-L6-v2) and saves to
vectorstore/(agentic-ai/app/rag/ingest.py).
flowchart TD
A[POST /ticket] --> B[Analyzer\nsummary + keywords]
B --> C[RAG retrieve\nFAISS top5]
C --> D[Evaluator\navg conf + sentiment]
D -- APPROVE --> E[Responder\nMistral JSON]
D -- ESCALATE --> F[Escalated FinalResponse]
E --> G[FinalResponse]
F --> G
- Mirrors the same orchestrator, agents, schemas, RAG, ingestion, and LLM code paths as
agentic-ai(back-end/app/main.py, back-end/app/agents, back-end/app/rag). - Adds FastAPI routers scaffolded under
/apifor auth/users/tickets/admin/dashboard, database settings (MySQL via SQLAlchemy), and password hashing helpers, but these routers and models are not wired into the ticket pipeline. The/ticketendpoint increate_appuses the sameprocess_ticketas above.
- front-end: Next.js app with a client form sending POST to
http://localhost:8000/ticketwith randomticket_idand prefixedcontent([TYPE] description). Displays theresponsefield only (front-end/app/page.tsx). Includes a static Sign-in page mock (front-end/app/Signin/page.tsx). - front-end/tc-front: Another Next.js app with the same styled ticket form but returns canned responses client-side; does not call the backend (front-end/tc-front/app/page.tsx).
- Batch API harness drives
/ticketfor 50 Arabic queries, expecting batch output format with team name and answers (agentic-ai/tests/test_agent_with_given_format.py). - Full system CLI harness exercises pipeline stages and prints summaries; note it references
rag_result.answerwhich is not present inRagResult(context is inrag_result.context) and callsevaluatewith a different signature, so this script will not run as-is without fixes (agentic-ai/tests/test_full_system.py). - Similarity unit test builds an in-memory FAISS from sample docs and asserts top-k similarity > 0.8 for a password-reset query (agentic-ai/tests/unit_tests.py).
- eng.json / fr.json capture sample expected QA outputs (batch format) for English and French variants.
- Analyzer relies on fallback heuristics because
call_llmis overridden to returnNone. - RAG filtering in the orchestrator attempts to drop snippets below
cosine_thresholdwhenrag_result.similaritiesexists, butRagResultcurrently has nosimilaritiesfield; the block is effectively skipped with the currentrag_answerimplementation. - Evaluator averages five copies of a single
similarity_score, which may overstate confidence when only one score is available. - Responder assumes the LLM outputs strict JSON; no retry or guardrails beyond minimal fence stripping.
- Vector store loading uses
allow_dangerous_deserialization=True; ensure index provenance is trusted. - Mistral API key is mandatory at import time; missing key raises immediately.
- API entry & orchestrator: agentic-ai/app/main.py, agentic-ai/app/agents/orchestrator.py
- Agents: analyzer, rag, evaluator, responder in agentic-ai/app/agents
- RAG plumbing & cache: agentic-ai/app/rag
- LLM client: agentic-ai/app/utils/llm.py
- Front-end wiring: front-end/app/page.tsx
- Parity copy in
back-endfor deployment scaffolding.