Skip to content

mmwady/ai_noc_assistant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🛰️ VSAT AIOps Nexus — Offline NOC Diagnostic Assistant

A multi-agent LLM diagnostic pipeline for satellite Network Operations Centers, designed to run fully offline in air-gapped environments.

License: MIT Python 3.10+ LangGraph FastAPI Ollama Air-Gapped

VSAT NOC Assistant Live Demo


🎯 What is this?

VSAT AIOps Nexus is an agentic diagnostic assistant for VSAT (Very Small Aperture Terminal) network operations. A NOC engineer describes a network symptom in natural language, and the system:

  1. Extracts specific technical symptoms from the input
  2. Retrieves candidate diagnoses from a local vector knowledge base (RAG)
  3. Investigates the issue by calling SNMP-style tools to gather evidence
  4. Scores every candidate against the accumulated evidence
  5. Critiques its own reasoning to catch logical contradictions and hallucinations
  6. Returns a structured incident report with confidence scoring and recovery steps

Everything runs locally. No external API calls. No data leaves the network. No cloud dependencies.

This is a public, sanitized demo of a system originally architected for civil aviation NOC operations, where strict air-gap compliance and data sovereignty are mandatory by regulation.


🤔 Why does this exist?

Most "AI for ops" projects assume unlimited cloud access. In civil aviation, defense, and other regulated environments, that assumption is illegal. Real-world constraints look like this:

Constraint Implication
Air-gapped network No outbound internet. No OpenAI, no Claude, no Gemini API calls.
Data sovereignty Telemetry, configuration, and incident data cannot leave the perimeter.
Regulated SLAs Mean Time To Repair must be measurable and auditable.
No model retraining Models must work out-of-the-box on edge hardware.

This demo demonstrates one viable answer: a local quantized LLM (Qwen2.5) orchestrated by LangGraph, grounded in a curated RAG knowledge base, validated by a self-critic node — all running on a single workstation.


🏗️ Architecture

System Overview

flowchart LR
    Engineer([👨‍💻 NOC Engineer]) -->|Natural language symptom| UI[Flutter Desktop UI]
    UI -->|HTTP / SSE Stream| API[FastAPI Backend]
    API --> Graph[LangGraph<br>Agent Pipeline]

    Graph -->|Semantic search| Chroma[(ChromaDB<br>Knowledge Base)]
    Graph -->|Tool calls| SNMP[SNMP Mock Tools<br>buc / lnb / pvc / snr / ...]
    Graph -->|Local inference| Ollama[Ollama<br>Qwen2.5:14b]

    Telemetry[Telemetry Monitor<br>Z-Score Anomaly Detection] -->|Auto-trigger| API

    style Graph fill:#0e7490,color:#fff
    style Ollama fill:#1f2937,color:#fff
    style Chroma fill:#7c3aed,color:#fff
Loading

Diagnostic Agent Flow

The agent is a LangGraph state machine with 8 nodes and conditional routing. Loops are bounded — investigation max 3 rounds, critic max 2 rounds — to guarantee termination.

flowchart TD
    START([START]) --> SE[🩺 Symptom Extractor]

    SE -->|General chat| RESP[🗣️ Responder]
    SE -->|Technical issue| TR[🔍 Triage Retriever<br>ChromaDB Semantic Search]

    TR --> INV[🕵️ Investigator<br>Plans next tools]
    INV --> EXEC[⚙️ Execute Tools<br>SNMP queries]
    EXEC --> EVAL[⚖️ Evaluator<br>Score candidates 0–100]

    EVAL -->|Score < 70 AND loop < 3| INV
    EVAL -->|Score ≥ 70 OR loop = 3| CRITIC[🔬 Critic<br>Hard contradiction check]

    CRITIC -->|REJECT| EVAL
    CRITIC -->|CONFIRMED| RES[🎯 Resolution Retriever<br>Fetch fix steps]

    RES --> RESP
    RESP --> END([END])

    style SE fill:#0891b2,color:#fff
    style EVAL fill:#7c3aed,color:#fff
    style CRITIC fill:#dc2626,color:#fff
    style RESP fill:#059669,color:#fff
Loading

Why these specific nodes?

Node Purpose Why it exists
Symptom Extractor Triages technical vs. general chat Avoids running expensive RAG on greetings
Triage Retriever Top-K vector search on ChromaDB Narrows the candidate space before reasoning
Investigator Plans which SNMP tools to run next Differentiates between candidates with minimal tool calls
Execute Tools Runs queued tools, dedupes Single point of side effects
Evaluator Scores candidates against all evidence Penalizes contradictions (-30), rewards confirmations (+15)
Critic Independent peer review Catches logical flaws the Evaluator missed (anti-hallucination guardrail)
Resolution Retriever Fetches the linked fix card Decoupled diagnosis from resolution for maintainability
Responder Generates the final incident report Adapts language (en/ar) and formats Markdown for the UI

🚀 Quickstart

Prerequisites

  • Python 3.10 or higher
  • Ollama installed and running
  • ~16 GB RAM (for qwen2.5:14b) or ~8 GB RAM (for qwen2.5:7b)

1. Install Ollama and pull the model

# Install Ollama (Linux / macOS)
curl -fsSL https://ollama.com/install.sh | sh

# Pull Qwen2.5 14B (recommended) — about 9 GB
ollama pull qwen2.5:14b

# OR pull the lighter 7B variant — about 5 GB
ollama pull qwen2.5:7b

2. Clone and set up the project

git clone https://github.com/mmwady/ai_noc_assistant.git
cd ai_noc_assistant/backend

# Create a virtual environment
python -m venv myvenv
source myvenv/bin/activate   # On Windows: myvenv\Scripts\activate

# Install Python dependencies
pip install -r requirements.txt

# Copy the example environment file and edit as needed
cp .env.example .env

3. Run the backend server

python run_server.py

The FastAPI server will start on http://localhost:8000. Visit http://localhost:8000/docs for the interactive Swagger UI. On first run, the local knowledge base (ChromaDB) is seeded with synthetic VSAT incident cards covering common failure modes (BUC failures, LNB alarms, PVC issues, SNR degradation, port outages, etc.).

4. Try it

# Send a diagnostic query
curl -X POST http://localhost:8000/ask-stream-all-at-once-tools \
  -H "Content-Type: application/json" \
  -d '{
    "message": "I have a problem with the voice service at SITE_001",
    "lang": "en",
    "thread_id": "demo-session",
    "site": "SITE_001"
  }'

You will see the agent stream its reasoning node-by-node via Server-Sent Events.


🧪 Try these example queries

Query What the agent should do
"No data service at SITE_002, modem shows red light" Extract symptoms → retrieve modem-related cards → check modem_status, pvc_status, snr → diagnose modem alarm
"Voice and data both down at SITE_003 since this morning" Multi-symptom case → retrieve broader candidates → verify with multiple tools → likely BUC or LNB hardware fault
"Hello, how are you today?" Symptom Extractor classifies as general chat → skip the entire pipeline → direct conversational reply
"SNR dropped to 4 dB at SITE_001" Auto-anomaly path: Z-score detector triggers diagnosis without operator input

🛠️ Tech Stack

Layer Technology
Agent Orchestration LangGraph — stateful multi-agent graphs with conditional edges
LLM Inference Ollama running Qwen2.5:14b (GGUF quantized)
Structured Outputs Pydantic + with_structured_output(method="json_schema")
Vector Search ChromaDB with BAAI/bge-small-en-v1.5 embeddings (FastEmbed)
Backend API FastAPI with async streaming via Server-Sent Events
Telemetry Persistence SQLite (incident cards) + Chroma (vectors)
Anomaly Detection Custom Z-score detector with rolling baseline rebuild
Frontend Flutter cross-platform desktop dashboard (see vsat_manager/)

📁 Project Structure

ai_noc_assistant/
├── backend/                                  # Python backend (FastAPI + LangGraph agent)
│   ├── run_server.py                         # FastAPI entry point — starts the API server
│   ├── langGraph_design_function_tools.py    # LangGraph build + 8-node agent pipeline + SNMP mock tools
│   ├── telemetry_monitor.py                  # Z-score anomaly detection with rolling baseline
│   ├── test_noc_graph.py                     # Graph routing / node behavior tests
│   ├── patterns.json                         # Symptom/diagnosis pattern definitions
│   ├── RAG_System/                           # ChromaDB retrieval + ingestion logic
│   ├── saving_retrieving/                    # Card persistence (SQLite + Chroma CRUD)
│   ├── .env.example                          # Template for environment variables
│   ├── requirements.txt
│   └── database/
│       ├── cards/
│       │   ├── chroma_db/                     # Vector store for incident cards
│       │   └── sqlite_db/                     # Structured incident card storage
│       └── docs/
│           └── chroma_db/                     # Vector store for troubleshooting docs
│
└── vsat_manager/                             # Flutter cross-platform desktop frontend (NOC dashboard)

⚙️ Configuration

All configuration lives in backend/.env. The defaults work out of the box for local Ollama:

# LLM Provider — all options run locally
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL_LARGE=qwen2.5:14b      # For reasoning-heavy nodes
OLLAMA_MODEL_SMALL=qwen2.5           # For lightweight tasks

# Storage paths
CHROMA_CARDS_PATH=./database/cards/chroma_db
SQLITE_PATH=./database/cards/sqlite_db/cards.db
EMBEDDING_CACHE=./model_cache

# API server
HOST=0.0.0.0
PORT=8000

# Anomaly detector
ANOMALY_WINDOW_SIZE=30
ANOMALY_Z_THRESHOLD=5.0

🎨 What this demo demonstrates

This repository is intended to showcase several engineering patterns that I find under-discussed in typical "build an LLM app" tutorials:

  • Loop-bounded agentic graphs — every cycle has a hard cap; the system always terminates
  • Anti-hallucination via independent critic node — separate LLM instance reviews the Evaluator's verdict for hard contradictions
  • Fuzzy title matching for LLM scoring — LLMs sometimes return slightly mutated card titles; difflib.get_close_matches rescues the match
  • Two-stage extraction with bounded concurrencyasyncio.Semaphore keeps the LLM provider from being hammered
  • Structured outputs everywhere — every node returns a validated Pydantic model, never raw strings
  • Z-score anomaly detection with baseline rebuild — a real engineering subtlety: after a storm, you must purge the polluted history or the next reading will be wrongly flagged

⚠️ What this demo is NOT

To set honest expectations:

  • Not the full production system. Site names, service types, and routing topology have been genericized.
  • No real SNMP polling. The tool functions return deterministic mock values. Replacing them with real pysnmp calls is a one-line change per tool.
  • No production secrets, IPs, or device identifiers. Anything that could identify the original deployment environment has been removed.
  • Frontend is provided as-is. The Flutter desktop UI lives in vsat_manager/; the screenshot above shows it running against the backend.

🗺️ Roadmap

Things that would make this demo more useful that I plan to add over time:

  • Replace mock SNMP with real pysnmp polling against a Docker-simulated device
  • LangSmith integration for trace inspection
  • Expanded pytest suite covering all 8 node behaviors
  • GitHub Actions CI for linting + tests
  • Docker Compose stack (Ollama + API + ChromaDB persistent volume)
  • Evaluation harness with a small synthetic benchmark

👤 About the author

I am Mohamed Wady, an AI Engineer with 14+ years bridging satellite networks and modern software engineering. I architect production-grade offline LLM systems for regulated environments where the cloud is not an option.

If you are building agentic systems for regulated industries, air-gapped networks, or edge AI deployment, I would love to hear from you.


📄 License

This project is released under the MIT License. The original production system from which this demo was derived remains proprietary and is not part of this distribution.


🙏 Acknowledgments

  • The LangGraph team for building a primitive that finally made loop-bounded agentic systems sane to write
  • The Qwen team at Alibaba for releasing Qwen2.5 — the first local model in this size class that I trust on structured-output tasks
  • The Ollama project for making local LLM deployment a five-minute affair

About

Offline-first multi-agent LLM diagnostic assistant for air-gapped satellite NOCs — LangGraph 8-node agent pipeline + local Qwen2.5 + RAG, with a self-critic anti-hallucination guardrail.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors