Repository files navigation

🛣️ RoadSense AI

Civic Signal Intelligence — Detecting road damage from public chatter, before anyone files a complaint.

Built by Team Iceberg · AI for Bharat Hackathon · February 2026


The Problem

India has 6.4 million km of roads. Over 150,000 people die in road accidents every year — a significant share caused by potholes, cave-ins, and waterlogged stretches that go unreported for weeks.

Municipal repair systems are complaint-driven. A pothole only gets fixed after enough citizens call a helpline, tweet at an official, or fill out an online form. By then, someone may have already been hurt.

The signals exist. Nobody is listening.

Every day, thousands of Indians post about broken roads on Reddit, complain in YouTube comments, and get covered by local news — in Hindi, Tamil, Telugu, Kannada, and a dozen other languages. Weather data predicts exactly where flooding will make things worse. All of this is public, free, and real-time.

No one is connecting these dots. Until now.


The Solution

RoadSense AI is a passive early-warning system that monitors public signals — Reddit posts, news articles, YouTube comments, and weather data — and uses a multi-agent AI pipeline to detect emerging road infrastructure damage before complaints are filed.

What it does:

  • Scrapes 4 public sources every hour — zero citizen effort required
  • Translates 10+ Indian languages to English automatically
  • Filters noise, sarcasm, and speculation using Amazon Nova Micro
  • Clusters related signals by geography (500m) and time (7 days)
  • Computes confidence scores (0–100) with explainable reasoning
  • Surfaces prioritized incidents on an Authority Dashboard

What it replaces:

  • ❌ Waiting for complaint volume to reach a threshold
  • ❌ Requiring citizens to install an app
  • ❌ Manual triage of social media by officials
  • ❌ Language barriers blocking non-English reports
  • ❌ Weather damage going undetected until inspection

Target Outcomes

MetricImpact
Complaint-to-response lag40–60% reduction
Early detection rate25–35% increase
Maintenance costsSignificant savings (proactive vs. reactive)
Signal classification accuracy≥ 85%

Architecture

Fully serverless and event-driven on AWS. No servers to manage, scales to zero when idle.

 ┌──────────────────────────────────────┐
│ PUBLIC SIGNALS │
│ Reddit · News RSS · YouTube · Weather│
└──────────────┬───────────────────────┘
│
EventBridge (hourly cron)
│
▼
┌─────────────────────┐
│ Scraper Lambda │
│ 4 scrapers in 1 fn │
└──────────┬──────────┘
│
┌────────────▼────────────┐
│ AWS Translate │
│ hi/ta/te/kn/bn → en │
│ + PII anonymisation │
│ + Deduplication │
└────────────┬─────────────┘
│
POST /ingest-signal (API Gateway)
│
▼
┌────────────────────────────────────┐
│ INFERENCE LAMBDA │
│ │
│ ┌─ Classification Agent (Nova Micro)│
│ │ Road-related? Damage type? │
│ │ │
│ ├─ Intent Agent (Nova Micro) │
│ │ Sarcasm? Speculation? Urgency? │
│ │ │
│ ├─ Correlation Agent (Titan V2) │
│ │ Geo + temporal clustering │
│ │ │
│ ├─ Inference Agent (scoring) │
│ │ Confidence 0–100 + severity │
│ │ │
│ └─ Explanation Agent (Nova Lite) │
│ Human-readable AI reasoning │
└──────────────┬─────────────────────┘
│
┌──────────────▼──────────────┐
│ DynamoDB │
│ Incidents + Signals │
└──────────────┬──────────────┘
│
API Gateway (REST)
│
▼
┌──────────────────────────────┐
│ Authority Dashboard │
│ React · S3 · CloudFront │
│ Map + Incidents + Feedback │
└──────────────────────────────┘

The AI Pipeline — 5 Agents, 3 Models

Every signal passes through a sequential agent pipeline. Each agent adds structured metadata. No agent makes a final decision alone.

#AgentModelInputOutputCost Control
1ClassificationNova MicroRaw English textis_road_related, damage_type, confidenceCheapest model; simple task
2Intent & ContextNova MicroClassified signalis_problem_report, urgency_level, context_typeFilters noise before expensive steps
3CorrelationTitan Embeddings V2All recent signalsSignal clusters (500m radius, 7-day window)Embeddings, not generation
4InferenceNone (deterministic)Signal clustersconfidence_score (0–100), severity_levelNo model call — pure math
5ExplanationNova LiteScored incidentsHuman-readable summaryCalled once per incident, not per signal

Plus a Feedback Agent (no model) that processes ground-truth validation from municipal authorities and recalibrates confidence scores.

Confidence Scoring (Inference Agent)

The confidence score is a weighted composite — no single signal can create a high-confidence incident alone:

FactorMax PointsWhy
Source diversity (Reddit + News + YouTube + Weather)30Multiple independent sources = higher trust
Signal count in cluster20More reports = more likely real
Urgency level consensus20Consistent urgency across signals
Classification confidence20How sure the AI is about damage type
Recency (time decay)10Recent signals weighted higher
Weather correlation10Rain + pothole reports = likely flooding
Total (clamped)100
  • Incident created when confidence > 60
  • Incident archived when confidence < 30
  • Confidence decays over time if no new signals arrive

Model Selection Rationale

Model$/1K tokensUsed ForWhy Not Something Else?
Amazon Nova Micro$0.000035/$0.00014Classification + Intent (per signal)Cheapest Nova model; no access approval needed; fast structured output
Amazon Nova Lite$0.00006/$0.00024Explanation (per incident)Better prose quality; only called once per incident, not per signal
Titan Embeddings V2$0.00002Correlation clusteringNative to Bedrock; no cross-service latency; optimized for similarity

Data Sources

The Scraper Lambda runs every hour via EventBridge and pulls from four free, public sources:

SourceLibraryWhat It CapturesSubreddits / Feeds
RedditPRAWCitizen complaints, photos, rantsr/bangalore, r/mumbai, r/delhi, r/chennai, r/hyderabad
News RSSfeedparserStructured reporting on road conditionsTimes of India, NDTV, The Hindu, Deccan Herald
YouTubegoogle-api-python-clientVideo titles + top comments on pothole/flooding videosSearch: pothole road damage india {city}
Weatherurllib (OpenWeatherMap API)Rainfall, flooding alerts — contextual correlationBangalore, Mumbai, Delhi, Chennai, Hyderabad

Search keywords: pothole road flood traffic damage gaddha sadak saalai rasta (English + Hindi + Tamil + Telugu)


Multilingual Processing

India has 22 official languages. Road complaints don't come in English.

"MG Road par bahut bada gaddha hai" → AWS Translate → "There is a large pothole on MG Road"
(Hindi) (auto-detect) (English — ready for AI agents)
  • AWS Translate auto-detects language and translates to English before any agent processing
  • Original text and detected language are preserved in metadata for audit
  • Supported: Hindi, Tamil, Telugu, Kannada, Bengali, Marathi, Malayalam, Gujarati, Punjabi, Urdu, and 60+ more
  • Free tier: 2M characters/month

Privacy & Ethics

RoadSense AI is designed to be trustworthy by default:

PrincipleImplementation
Public data onlyScrapes only publicly visible posts — no private messages, DMs, or login-required content
No individual profilingOutputs are aggregate geographic intelligence, never about specific people
PII anonymisationReddit usernames (u/), YouTube handles (@), emails, Indian phone numbers — all stripped before storage (pii.py)
DeduplicationContent-hash based dedup prevents double-counting from RSS re-serves and repeat scrapes (dedup.py)
Explainable AIEvery incident includes a Nova Lite-generated explanation of the evidence chain
Human-in-the-loopMunicipal authorities can validate or dismiss incidents via the Feedback Agent
Zero citizen effortNo app to install, no form to fill, no account to create

Data Models

Signal (click to expand)
{
"signal_id": "uuid",
"content": "English text (translated if needed)",
"original_content": "raw text in source language",
"translated_content": "English text from AWS Translate",
"detected_language": "hi",
"source": "reddit | news | youtube | weather",
"timestamp": "2026-02-01T10:00:00Z",
"location": {
"coordinates": { "lat": 12.9716, "lon": 77.5946 },
"accuracy_meters": 100,
"address": "MG Road, Bangalore"
},
"classification": {
"is_road_related": true,
"damage_type": "pothole | surface_wear | flooding | general",
"confidence": 0.92
},
"intent": {
"is_problem_report": true,
"urgency_level": "low | medium | high | critical",
"context_type": "direct_report | complaint | warning | news_coverage | ..."
}
}
Incident (click to expand)
{
"incident_id": "uuid",
"location": {
"center_coordinates": { "lat": 12.9716, "lon": 77.5946 },
"radius_meters": 500,
"address": "MG Road, Bangalore"
},
"damage_type": "pothole",
"confidence_score": 78,
"severity_level": "low | medium | high | critical",
"status": "active | monitoring | archived",
"explanation": "AI-generated summary referencing source types and languages",
"signal_ids": ["uuid1", "uuid2", "uuid3"],
"created_at": "2026-02-01T10:00:00Z",
"updated_at": "2026-02-02T14:30:00Z",
"confidence_history": [
{ "timestamp": "2026-02-01T10:00:00Z", "score": 65 },
{ "timestamp": "2026-02-02T14:30:00Z", "score": 78 }
]
}

API Reference

Full OpenAPI 3.0 spec: openapi.yaml

MethodEndpointDescription
POST/ingest-signalSubmit a signal for AI processing
GET/incidentsList all active incidents
GET/confidence/{id}Get confidence score + history for an incident
POST/feedbackSubmit ground-truth validation from authorities
GET/exportExport incidents as JSON (CSV planned)
curl examples (click to expand)
# Ingest a Hindi signal
curl -X POST https://api.roadsense.dev/ingest-signal \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "MG Road par bahut bada gaddha hai", "source": "reddit", "timestamp": "2026-02-01T10:00:00Z", "location": { "latitude": 12.9716, "longitude": 77.5946, "address": "MG Road, Bangalore" } }'# Get active incidents
curl https://api.roadsense.dev/incidents -H "x-api-key: $API_KEY"# Check confidence for a specific incident
curl https://api.roadsense.dev/confidence/incident-123 -H "x-api-key: $API_KEY"# Submit feedback from field inspection
curl -X POST https://api.roadsense.dev/feedback \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "incident_id": "incident-123", "feedback_value": "confirmed", "notes": "Pothole verified, ~2ft wide" }'# Export all incidents
curl https://api.roadsense.dev/export -H "x-api-key: $API_KEY"

Project Structure

roadsense-ai/
├── agents/
│ ├── classification_agent.py # Road-related? What damage type? (Nova Micro)
│ ├── intent_agent.py # Sarcasm/speculation filter + urgency (Nova Micro)
│ ├── correlation_agent.py # Geo+temporal clustering (Titan Embeddings V2)
│ ├── inference_agent.py # Confidence scoring (deterministic)
│ ├── explanation_agent.py # Human-readable summaries (Nova Lite)
│ └── feedback_agent.py # Ground-truth recalibration
├── scraper/
│ ├── reddit_scraper.py # PRAW — Indian city subreddits
│ ├── rss_scraper.py # feedparser — Times of India, NDTV, The Hindu, Deccan Herald
│ ├── youtube_scraper.py # YouTube Data API v3 — video titles + comments
│ └── weather_scraper.py # OpenWeatherMap — rainfall + flood alerts
├── data/
│ ├── generate_signals.py # Synthetic dataset generator
│ ├── signals.json # 1,050 signals (850 EN + 200 multilingual)
│ └── synthetic_incidents.json # 10 mock incidents for dashboard development
├── tests/
│ ├── test_properties.py # 50 property-based tests (Hypothesis)
│ ├── test_intent_agent.py # 45 unit tests — Intent & Context Agent
│ ├── test_inference_agent.py # 55 unit tests — Inference Agent
│ ├── test_api_integration.py # 30 integration tests (skip when API offline)
│ └── test_translate.py # 5 unit tests — AWS Translate wrapper
├── translate.py # AWS Translate wrapper — auto-detect + translate
├── pii.py # PII anonymisation (usernames, emails, phones)
├── dedup.py # Content-hash deduplication
├── location_normaliser.py # Normalise location formats across sources
├── locustfile.py # Load test config — 1,000 signals/hour target
├── openapi.yaml # OpenAPI 3.0 specification
└── .gitignore

Testing

185 tests across 5 test suites. Zero failures.

$ pytest tests/ -v --tb=short
155 passed, 0 failed, 30 skipped ✓

(30 skipped = API integration tests; dev API not yet deployed)

SuiteTestsWhat It Validates
Property-based (test_properties.py)5035 correctness properties via Hypothesis — confidence bounds, thresholds, severity ordering, decay monotonicity, scoring weights
Intent Agent (test_intent_agent.py)45Prompt construction, response parsing, sarcasm/speculation handling, weather pre-classification, fallback logic, Lambda handler
Inference Agent (test_inference_agent.py)55Confidence scoring, severity computation, incident creation/archival thresholds, time decay, cluster processing
API Integration (test_api_integration.py)30End-to-end ingestion, incident retrieval, confidence checks, export, error handling (auto-skipped when API unreachable)
Translate (test_translate.py)5Hindi/Tamil/Telugu translation, English passthrough, empty content handling

Run Tests

# All tests
pytest tests/ -v
# Property-based tests only
pytest tests/test_properties.py -v --hypothesis-seed=0
# Load test (Locust) — requires live API
locust -f locustfile.py --host=https://api.roadsense.dev
# Opens http://localhost:8089 — configure users and spawn rate# Headless: locust -f locustfile.py --host=https://api.roadsense.dev --users 10 --spawn-rate 2 --run-time 5m --headless

Synthetic Dataset

signals.json1,050 signals for development and testing:

CategoryCountPurpose
Road-related (genuine reports)350True positives — potholes, flooding, surface wear
Non-road (noise)250True negatives — traffic jams, politics, unrelated
Sarcastic100Adversarial — "Oh wow another beautiful pothole"
Ambiguous100Edge cases — could be road-related, unclear
Multilingual (hi/ta/te)200Hindi (69), Tamil (70), Telugu (61) — translation pipeline testing
Edge cases50Empty content, missing fields, extreme coordinates

Plus synthetic_incidents.json10 mock incidents across Bangalore locations (Electronic City, MG Road, Silk Board, Whitefield, Koramangala, Indiranagar) for the Authority Dashboard.


Technology Stack

LayerServiceDetail
ScrapingLambda + EventBridgeHourly cron; PRAW, feedparser, google-api-python-client, urllib
TranslationAWS TranslateAuto-detect → English; 10+ Indian languages; 2M chars/month free
IngestionAPI Gateway + LambdaREST endpoint; JSON validation; S3 raw storage
AI ReasoningAmazon BedrockAmazon Nova Micro, Amazon Nova Lite, Titan Embeddings V2
Vector StoreChromaDBSemantic similarity for signal correlation
StorageDynamoDB + S3Incident state in DynamoDB; raw signals archived in S3
APIAPI GatewayREST/JSON; API key auth; 5 endpoints
FrontendReact + S3 + CloudFrontMap view, incident cards, confidence gauges, feedback forms
Testingpytest + Hypothesis + LocustProperty-based, unit, integration, and load testing
CI/CDSAM CLIsam build && sam deploy --guided

Prerequisites

RequirementNotes
Python 3.11+Agent code + scrapers
Node.js 18+React dashboard
AWS CLIConfigured with IAM permissions for Lambda, Bedrock, Translate, DynamoDB, S3, CloudFront
Bedrock model accessNova Micro, Nova Lite, and Titan Embeddings V2 are available in us-east-1 without manual approval
Reddit API credentialsreddit.com/prefs/apps — free, instant
YouTube Data API v3 keyGoogle Cloud Console — free under 10K units/day
OpenWeatherMap API keyopenweathermap.org/api — free tier, 1000 calls/day

Local Setup

# Clone
git clone https://github.com/Sujith-RMD/RoadSense-AI.git
cd RoadSense-AI
# Python environment
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows# Install dependencies
pip install boto3 praw feedparser google-api-python-client chromadb
pip install pytest hypothesis locust # testing# Environment variablesexport REDDIT_CLIENT_ID=...
export REDDIT_CLIENT_SECRET=...
export YOUTUBE_API_KEY=...
export OPENWEATHERMAP_API_KEY=...
export AWS_DEFAULT_REGION=ap-south-1
# Run tests (no AWS credentials needed)
pytest tests/ -v

Deployment

# Backend — Lambda + API Gateway + DynamoDB
sam build
sam deploy --guided
# Frontend — React dashboardcd dashboard
npm install && npm run build
aws s3 sync ./build s3://<frontend-bucket> --delete
# CloudFront distribution URL → hackathon submission link

Team Iceberg

NameRoleOwns
⚙️SrikarAWS & BackendAPI Gateway, Lambda, S3, DynamoDB, CloudFront, Bedrock access, IAM, CloudWatch, bedrock_client.py
🤖DurvaAI Pipeline & DataAll 4 scrapers, AWS Translate integration, 5 AI agents, PII anonymisation, deduplication
🎨NishitaFrontend & UXFigma design system, Authority Dashboard (React), map view, incident detail, confidence gauge, feedback form
🧪SujithQA & Documentation1,050-signal synthetic dataset, 185 tests (property-based + unit + integration + load), OpenAPI spec, README, demo script

Glossary

TermDefinition
SignalAny unstructured text from a public source that may contain road condition information
IncidentA geo-located road infrastructure problem detected by the system, with a confidence score and AI explanation
Confidence Score0–100 composite metric reflecting the system's certainty about detected road damage
Source DiversityNumber of distinct source types (Reddit, news, YouTube, weather) contributing evidence — higher diversity = higher confidence
Temporal DensityConcentration of related signals within a time window — rapid signal bursts indicate active/worsening problems
Ground TruthPost-detection validation by municipal authorities — used to recalibrate confidence scoring
Authority DashboardReact web app for municipal officials to view, prioritize, and provide feedback on detected incidents

RoadSense AI — Team Iceberg · AI for Bharat Hackathon 2026
Detecting the potholes nobody reported — from the signals everyone already posted.

About

RoadSense AI monitors Reddit, news, YouTube, and weather data to detect road damage before complaints are filed. A multi agent AI pipeline translates 10+ Indian languages, filters sarcasm, clusters signals geographically, and surfaces prioritized incidents with confidence scores, zero citizen effort required.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

🛣️ RoadSense AI

Civic Signal Intelligence — Detecting road damage from public chatter, before anyone files a complaint.

Built by Team Iceberg · AI for Bharat Hackathon · February 2026


The Problem

India has 6.4 million km of roads. Over 150,000 people die in road accidents every year — a significant share caused by potholes, cave-ins, and waterlogged stretches that go unreported for weeks.

Municipal repair systems are complaint-driven. A pothole only gets fixed after enough citizens call a helpline, tweet at an official, or fill out an online form. By then, someone may have already been hurt.

The signals exist. Nobody is listening.

Every day, thousands of Indians post about broken roads on Reddit, complain in YouTube comments, and get covered by local news — in Hindi, Tamil, Telugu, Kannada, and a dozen other languages. Weather data predicts exactly where flooding will make things worse. All of this is public, free, and real-time.

No one is connecting these dots. Until now.


The Solution

RoadSense AI is a passive early-warning system that monitors public signals — Reddit posts, news articles, YouTube comments, and weather data — and uses a multi-agent AI pipeline to detect emerging road infrastructure damage before complaints are filed.

What it does:

  • Scrapes 4 public sources every hour — zero citizen effort required
  • Translates 10+ Indian languages to English automatically
  • Filters noise, sarcasm, and speculation using Amazon Nova Micro
  • Clusters related signals by geography (500m) and time (7 days)
  • Computes confidence scores (0–100) with explainable reasoning
  • Surfaces prioritized incidents on an Authority Dashboard

What it replaces:

  • ❌ Waiting for complaint volume to reach a threshold
  • ❌ Requiring citizens to install an app
  • ❌ Manual triage of social media by officials
  • ❌ Language barriers blocking non-English reports
  • ❌ Weather damage going undetected until inspection

Target Outcomes

MetricImpact
Complaint-to-response lag40–60% reduction
Early detection rate25–35% increase
Maintenance costsSignificant savings (proactive vs. reactive)
Signal classification accuracy≥ 85%

Architecture

Fully serverless and event-driven on AWS. No servers to manage, scales to zero when idle.

 ┌──────────────────────────────────────┐
│ PUBLIC SIGNALS │
│ Reddit · News RSS · YouTube · Weather│
└──────────────┬───────────────────────┘
│
EventBridge (hourly cron)
│
▼
┌─────────────────────┐
│ Scraper Lambda │
│ 4 scrapers in 1 fn │
└──────────┬──────────┘
│
┌────────────▼────────────┐
│ AWS Translate │
│ hi/ta/te/kn/bn → en │
│ + PII anonymisation │
│ + Deduplication │
└────────────┬─────────────┘
│
POST /ingest-signal (API Gateway)
│
▼
┌────────────────────────────────────┐
│ INFERENCE LAMBDA │
│ │
│ ┌─ Classification Agent (Nova Micro)│
│ │ Road-related? Damage type? │
│ │ │
│ ├─ Intent Agent (Nova Micro) │
│ │ Sarcasm? Speculation? Urgency? │
│ │ │
│ ├─ Correlation Agent (Titan V2) │
│ │ Geo + temporal clustering │
│ │ │
│ ├─ Inference Agent (scoring) │
│ │ Confidence 0–100 + severity │
│ │ │
│ └─ Explanation Agent (Nova Lite) │
│ Human-readable AI reasoning │
└──────────────┬─────────────────────┘
│
┌──────────────▼──────────────┐
│ DynamoDB │
│ Incidents + Signals │
└──────────────┬──────────────┘
│
API Gateway (REST)
│
▼
┌──────────────────────────────┐
│ Authority Dashboard │
│ React · S3 · CloudFront │
│ Map + Incidents + Feedback │
└──────────────────────────────┘

The AI Pipeline — 5 Agents, 3 Models

Every signal passes through a sequential agent pipeline. Each agent adds structured metadata. No agent makes a final decision alone.

#AgentModelInputOutputCost Control
1ClassificationNova MicroRaw English textis_road_related, damage_type, confidenceCheapest model; simple task
2Intent & ContextNova MicroClassified signalis_problem_report, urgency_level, context_typeFilters noise before expensive steps
3CorrelationTitan Embeddings V2All recent signalsSignal clusters (500m radius, 7-day window)Embeddings, not generation
4InferenceNone (deterministic)Signal clustersconfidence_score (0–100), severity_levelNo model call — pure math
5ExplanationNova LiteScored incidentsHuman-readable summaryCalled once per incident, not per signal

Plus a Feedback Agent (no model) that processes ground-truth validation from municipal authorities and recalibrates confidence scores.

Confidence Scoring (Inference Agent)

The confidence score is a weighted composite — no single signal can create a high-confidence incident alone:

FactorMax PointsWhy
Source diversity (Reddit + News + YouTube + Weather)30Multiple independent sources = higher trust
Signal count in cluster20More reports = more likely real
Urgency level consensus20Consistent urgency across signals
Classification confidence20How sure the AI is about damage type
Recency (time decay)10Recent signals weighted higher
Weather correlation10Rain + pothole reports = likely flooding
Total (clamped)100
  • Incident created when confidence > 60
  • Incident archived when confidence < 30
  • Confidence decays over time if no new signals arrive

Model Selection Rationale

Model$/1K tokensUsed ForWhy Not Something Else?
Amazon Nova Micro$0.000035/$0.00014Classification + Intent (per signal)Cheapest Nova model; no access approval needed; fast structured output
Amazon Nova Lite$0.00006/$0.00024Explanation (per incident)Better prose quality; only called once per incident, not per signal
Titan Embeddings V2$0.00002Correlation clusteringNative to Bedrock; no cross-service latency; optimized for similarity

Data Sources

The Scraper Lambda runs every hour via EventBridge and pulls from four free, public sources:

SourceLibraryWhat It CapturesSubreddits / Feeds
RedditPRAWCitizen complaints, photos, rantsr/bangalore, r/mumbai, r/delhi, r/chennai, r/hyderabad
News RSSfeedparserStructured reporting on road conditionsTimes of India, NDTV, The Hindu, Deccan Herald
YouTubegoogle-api-python-clientVideo titles + top comments on pothole/flooding videosSearch: pothole road damage india {city}
Weatherurllib (OpenWeatherMap API)Rainfall, flooding alerts — contextual correlationBangalore, Mumbai, Delhi, Chennai, Hyderabad

Search keywords: pothole road flood traffic damage gaddha sadak saalai rasta (English + Hindi + Tamil + Telugu)


Multilingual Processing

India has 22 official languages. Road complaints don't come in English.

"MG Road par bahut bada gaddha hai" → AWS Translate → "There is a large pothole on MG Road"
(Hindi) (auto-detect) (English — ready for AI agents)
  • AWS Translate auto-detects language and translates to English before any agent processing
  • Original text and detected language are preserved in metadata for audit
  • Supported: Hindi, Tamil, Telugu, Kannada, Bengali, Marathi, Malayalam, Gujarati, Punjabi, Urdu, and 60+ more
  • Free tier: 2M characters/month

Privacy & Ethics

RoadSense AI is designed to be trustworthy by default:

PrincipleImplementation
Public data onlyScrapes only publicly visible posts — no private messages, DMs, or login-required content
No individual profilingOutputs are aggregate geographic intelligence, never about specific people
PII anonymisationReddit usernames (u/), YouTube handles (@), emails, Indian phone numbers — all stripped before storage (pii.py)
DeduplicationContent-hash based dedup prevents double-counting from RSS re-serves and repeat scrapes (dedup.py)
Explainable AIEvery incident includes a Nova Lite-generated explanation of the evidence chain
Human-in-the-loopMunicipal authorities can validate or dismiss incidents via the Feedback Agent
Zero citizen effortNo app to install, no form to fill, no account to create

Data Models

Signal (click to expand)
{
"signal_id": "uuid",
"content": "English text (translated if needed)",
"original_content": "raw text in source language",
"translated_content": "English text from AWS Translate",
"detected_language": "hi",
"source": "reddit | news | youtube | weather",
"timestamp": "2026-02-01T10:00:00Z",
"location": {
"coordinates": { "lat": 12.9716, "lon": 77.5946 },
"accuracy_meters": 100,
"address": "MG Road, Bangalore"
},
"classification": {
"is_road_related": true,
"damage_type": "pothole | surface_wear | flooding | general",
"confidence": 0.92
},
"intent": {
"is_problem_report": true,
"urgency_level": "low | medium | high | critical",
"context_type": "direct_report | complaint | warning | news_coverage | ..."
}
}
Incident (click to expand)
{
"incident_id": "uuid",
"location": {
"center_coordinates": { "lat": 12.9716, "lon": 77.5946 },
"radius_meters": 500,
"address": "MG Road, Bangalore"
},
"damage_type": "pothole",
"confidence_score": 78,
"severity_level": "low | medium | high | critical",
"status": "active | monitoring | archived",
"explanation": "AI-generated summary referencing source types and languages",
"signal_ids": ["uuid1", "uuid2", "uuid3"],
"created_at": "2026-02-01T10:00:00Z",
"updated_at": "2026-02-02T14:30:00Z",
"confidence_history": [
{ "timestamp": "2026-02-01T10:00:00Z", "score": 65 },
{ "timestamp": "2026-02-02T14:30:00Z", "score": 78 }
]
}

API Reference

Full OpenAPI 3.0 spec: openapi.yaml

MethodEndpointDescription
POST/ingest-signalSubmit a signal for AI processing
GET/incidentsList all active incidents
GET/confidence/{id}Get confidence score + history for an incident
POST/feedbackSubmit ground-truth validation from authorities
GET/exportExport incidents as JSON (CSV planned)
curl examples (click to expand)
# Ingest a Hindi signal
curl -X POST https://api.roadsense.dev/ingest-signal \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "MG Road par bahut bada gaddha hai", "source": "reddit", "timestamp": "2026-02-01T10:00:00Z", "location": { "latitude": 12.9716, "longitude": 77.5946, "address": "MG Road, Bangalore" } }'# Get active incidents
curl https://api.roadsense.dev/incidents -H "x-api-key: $API_KEY"# Check confidence for a specific incident
curl https://api.roadsense.dev/confidence/incident-123 -H "x-api-key: $API_KEY"# Submit feedback from field inspection
curl -X POST https://api.roadsense.dev/feedback \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "incident_id": "incident-123", "feedback_value": "confirmed", "notes": "Pothole verified, ~2ft wide" }'# Export all incidents
curl https://api.roadsense.dev/export -H "x-api-key: $API_KEY"

Project Structure

roadsense-ai/
├── agents/
│ ├── classification_agent.py # Road-related? What damage type? (Nova Micro)
│ ├── intent_agent.py # Sarcasm/speculation filter + urgency (Nova Micro)
│ ├── correlation_agent.py # Geo+temporal clustering (Titan Embeddings V2)
│ ├── inference_agent.py # Confidence scoring (deterministic)
│ ├── explanation_agent.py # Human-readable summaries (Nova Lite)
│ └── feedback_agent.py # Ground-truth recalibration
├── scraper/
│ ├── reddit_scraper.py # PRAW — Indian city subreddits
│ ├── rss_scraper.py # feedparser — Times of India, NDTV, The Hindu, Deccan Herald
│ ├── youtube_scraper.py # YouTube Data API v3 — video titles + comments
│ └── weather_scraper.py # OpenWeatherMap — rainfall + flood alerts
├── data/
│ ├── generate_signals.py # Synthetic dataset generator
│ ├── signals.json # 1,050 signals (850 EN + 200 multilingual)
│ └── synthetic_incidents.json # 10 mock incidents for dashboard development
├── tests/
│ ├── test_properties.py # 50 property-based tests (Hypothesis)
│ ├── test_intent_agent.py # 45 unit tests — Intent & Context Agent
│ ├── test_inference_agent.py # 55 unit tests — Inference Agent
│ ├── test_api_integration.py # 30 integration tests (skip when API offline)
│ └── test_translate.py # 5 unit tests — AWS Translate wrapper
├── translate.py # AWS Translate wrapper — auto-detect + translate
├── pii.py # PII anonymisation (usernames, emails, phones)
├── dedup.py # Content-hash deduplication
├── location_normaliser.py # Normalise location formats across sources
├── locustfile.py # Load test config — 1,000 signals/hour target
├── openapi.yaml # OpenAPI 3.0 specification
└── .gitignore

Testing

185 tests across 5 test suites. Zero failures.

$ pytest tests/ -v --tb=short
155 passed, 0 failed, 30 skipped ✓

(30 skipped = API integration tests; dev API not yet deployed)

SuiteTestsWhat It Validates
Property-based (test_properties.py)5035 correctness properties via Hypothesis — confidence bounds, thresholds, severity ordering, decay monotonicity, scoring weights
Intent Agent (test_intent_agent.py)45Prompt construction, response parsing, sarcasm/speculation handling, weather pre-classification, fallback logic, Lambda handler
Inference Agent (test_inference_agent.py)55Confidence scoring, severity computation, incident creation/archival thresholds, time decay, cluster processing
API Integration (test_api_integration.py)30End-to-end ingestion, incident retrieval, confidence checks, export, error handling (auto-skipped when API unreachable)
Translate (test_translate.py)5Hindi/Tamil/Telugu translation, English passthrough, empty content handling

Run Tests

# All tests
pytest tests/ -v
# Property-based tests only
pytest tests/test_properties.py -v --hypothesis-seed=0
# Load test (Locust) — requires live API
locust -f locustfile.py --host=https://api.roadsense.dev
# Opens http://localhost:8089 — configure users and spawn rate# Headless: locust -f locustfile.py --host=https://api.roadsense.dev --users 10 --spawn-rate 2 --run-time 5m --headless

Synthetic Dataset

signals.json1,050 signals for development and testing:

CategoryCountPurpose
Road-related (genuine reports)350True positives — potholes, flooding, surface wear
Non-road (noise)250True negatives — traffic jams, politics, unrelated
Sarcastic100Adversarial — "Oh wow another beautiful pothole"
Ambiguous100Edge cases — could be road-related, unclear
Multilingual (hi/ta/te)200Hindi (69), Tamil (70), Telugu (61) — translation pipeline testing
Edge cases50Empty content, missing fields, extreme coordinates

Plus synthetic_incidents.json10 mock incidents across Bangalore locations (Electronic City, MG Road, Silk Board, Whitefield, Koramangala, Indiranagar) for the Authority Dashboard.


Technology Stack

LayerServiceDetail
ScrapingLambda + EventBridgeHourly cron; PRAW, feedparser, google-api-python-client, urllib
TranslationAWS TranslateAuto-detect → English; 10+ Indian languages; 2M chars/month free
IngestionAPI Gateway + LambdaREST endpoint; JSON validation; S3 raw storage
AI ReasoningAmazon BedrockAmazon Nova Micro, Amazon Nova Lite, Titan Embeddings V2
Vector StoreChromaDBSemantic similarity for signal correlation
StorageDynamoDB + S3Incident state in DynamoDB; raw signals archived in S3
APIAPI GatewayREST/JSON; API key auth; 5 endpoints
FrontendReact + S3 + CloudFrontMap view, incident cards, confidence gauges, feedback forms
Testingpytest + Hypothesis + LocustProperty-based, unit, integration, and load testing
CI/CDSAM CLIsam build && sam deploy --guided

Prerequisites

RequirementNotes
Python 3.11+Agent code + scrapers
Node.js 18+React dashboard
AWS CLIConfigured with IAM permissions for Lambda, Bedrock, Translate, DynamoDB, S3, CloudFront
Bedrock model accessNova Micro, Nova Lite, and Titan Embeddings V2 are available in us-east-1 without manual approval
Reddit API credentialsreddit.com/prefs/apps — free, instant
YouTube Data API v3 keyGoogle Cloud Console — free under 10K units/day
OpenWeatherMap API keyopenweathermap.org/api — free tier, 1000 calls/day

Local Setup

# Clone
git clone https://github.com/Sujith-RMD/RoadSense-AI.git
cd RoadSense-AI
# Python environment
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows# Install dependencies
pip install boto3 praw feedparser google-api-python-client chromadb
pip install pytest hypothesis locust # testing# Environment variablesexport REDDIT_CLIENT_ID=...
export REDDIT_CLIENT_SECRET=...
export YOUTUBE_API_KEY=...
export OPENWEATHERMAP_API_KEY=...
export AWS_DEFAULT_REGION=ap-south-1
# Run tests (no AWS credentials needed)
pytest tests/ -v

Deployment

# Backend — Lambda + API Gateway + DynamoDB
sam build
sam deploy --guided
# Frontend — React dashboardcd dashboard
npm install && npm run build
aws s3 sync ./build s3://<frontend-bucket> --delete
# CloudFront distribution URL → hackathon submission link

Team Iceberg

NameRoleOwns
⚙️SrikarAWS & BackendAPI Gateway, Lambda, S3, DynamoDB, CloudFront, Bedrock access, IAM, CloudWatch, bedrock_client.py
🤖DurvaAI Pipeline & DataAll 4 scrapers, AWS Translate integration, 5 AI agents, PII anonymisation, deduplication
🎨NishitaFrontend & UXFigma design system, Authority Dashboard (React), map view, incident detail, confidence gauge, feedback form
🧪SujithQA & Documentation1,050-signal synthetic dataset, 185 tests (property-based + unit + integration + load), OpenAPI spec, README, demo script

Glossary

TermDefinition
SignalAny unstructured text from a public source that may contain road condition information
IncidentA geo-located road infrastructure problem detected by the system, with a confidence score and AI explanation
Confidence Score0–100 composite metric reflecting the system's certainty about detected road damage
Source DiversityNumber of distinct source types (Reddit, news, YouTube, weather) contributing evidence — higher diversity = higher confidence
Temporal DensityConcentration of related signals within a time window — rapid signal bursts indicate active/worsening problems
Ground TruthPost-detection validation by municipal authorities — used to recalibrate confidence scoring
Authority DashboardReact web app for municipal officials to view, prioritize, and provide feedback on detected incidents

RoadSense AI — Team Iceberg · AI for Bharat Hackathon 2026
Detecting the potholes nobody reported — from the signals everyone already posted.

About

RoadSense AI monitors Reddit, news, YouTube, and weather data to detect road damage before complaints are filed. A multi agent AI pipeline translates 10+ Indian languages, filters sarcasm, clusters signals geographically, and surfaces prioritized incidents with confidence scores, zero citizen effort required.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🛣️ RoadSense AI

Civic Signal Intelligence — Detecting road damage from public chatter, before anyone files a complaint.

Built by Team Iceberg · AI for Bharat Hackathon · February 2026


The Problem

India has 6.4 million km of roads. Over 150,000 people die in road accidents every year — a significant share caused by potholes, cave-ins, and waterlogged stretches that go unreported for weeks.

Municipal repair systems are complaint-driven. A pothole only gets fixed after enough citizens call a helpline, tweet at an official, or fill out an online form. By then, someone may have already been hurt.

The signals exist. Nobody is listening.

Every day, thousands of Indians post about broken roads on Reddit, complain in YouTube comments, and get covered by local news — in Hindi, Tamil, Telugu, Kannada, and a dozen other languages. Weather data predicts exactly where flooding will make things worse. All of this is public, free, and real-time.

No one is connecting these dots. Until now.


The Solution

RoadSense AI is a passive early-warning system that monitors public signals — Reddit posts, news articles, YouTube comments, and weather data — and uses a multi-agent AI pipeline to detect emerging road infrastructure damage before complaints are filed.

What it does:

  • Scrapes 4 public sources every hour — zero citizen effort required
  • Translates 10+ Indian languages to English automatically
  • Filters noise, sarcasm, and speculation using Amazon Nova Micro
  • Clusters related signals by geography (500m) and time (7 days)
  • Computes confidence scores (0–100) with explainable reasoning
  • Surfaces prioritized incidents on an Authority Dashboard

What it replaces:

  • ❌ Waiting for complaint volume to reach a threshold
  • ❌ Requiring citizens to install an app
  • ❌ Manual triage of social media by officials
  • ❌ Language barriers blocking non-English reports
  • ❌ Weather damage going undetected until inspection

Target Outcomes

MetricImpact
Complaint-to-response lag40–60% reduction
Early detection rate25–35% increase
Maintenance costsSignificant savings (proactive vs. reactive)
Signal classification accuracy≥ 85%

Architecture

Fully serverless and event-driven on AWS. No servers to manage, scales to zero when idle.

 ┌──────────────────────────────────────┐
│ PUBLIC SIGNALS │
│ Reddit · News RSS · YouTube · Weather│
└──────────────┬───────────────────────┘
│
EventBridge (hourly cron)
│
▼
┌─────────────────────┐
│ Scraper Lambda │
│ 4 scrapers in 1 fn │
└──────────┬──────────┘
│
┌────────────▼────────────┐
│ AWS Translate │
│ hi/ta/te/kn/bn → en │
│ + PII anonymisation │
│ + Deduplication │
└────────────┬─────────────┘
│
POST /ingest-signal (API Gateway)
│
▼
┌────────────────────────────────────┐
│ INFERENCE LAMBDA │
│ │
│ ┌─ Classification Agent (Nova Micro)│
│ │ Road-related? Damage type? │
│ │ │
│ ├─ Intent Agent (Nova Micro) │
│ │ Sarcasm? Speculation? Urgency? │
│ │ │
│ ├─ Correlation Agent (Titan V2) │
│ │ Geo + temporal clustering │
│ │ │
│ ├─ Inference Agent (scoring) │
│ │ Confidence 0–100 + severity │
│ │ │
│ └─ Explanation Agent (Nova Lite) │
│ Human-readable AI reasoning │
└──────────────┬─────────────────────┘
│
┌──────────────▼──────────────┐
│ DynamoDB │
│ Incidents + Signals │
└──────────────┬──────────────┘
│
API Gateway (REST)
│
▼
┌──────────────────────────────┐
│ Authority Dashboard │
│ React · S3 · CloudFront │
│ Map + Incidents + Feedback │
└──────────────────────────────┘

The AI Pipeline — 5 Agents, 3 Models

Every signal passes through a sequential agent pipeline. Each agent adds structured metadata. No agent makes a final decision alone.

#AgentModelInputOutputCost Control
1ClassificationNova MicroRaw English textis_road_related, damage_type, confidenceCheapest model; simple task
2Intent & ContextNova MicroClassified signalis_problem_report, urgency_level, context_typeFilters noise before expensive steps
3CorrelationTitan Embeddings V2All recent signalsSignal clusters (500m radius, 7-day window)Embeddings, not generation
4InferenceNone (deterministic)Signal clustersconfidence_score (0–100), severity_levelNo model call — pure math
5ExplanationNova LiteScored incidentsHuman-readable summaryCalled once per incident, not per signal

Plus a Feedback Agent (no model) that processes ground-truth validation from municipal authorities and recalibrates confidence scores.

Confidence Scoring (Inference Agent)

The confidence score is a weighted composite — no single signal can create a high-confidence incident alone:

FactorMax PointsWhy
Source diversity (Reddit + News + YouTube + Weather)30Multiple independent sources = higher trust
Signal count in cluster20More reports = more likely real
Urgency level consensus20Consistent urgency across signals
Classification confidence20How sure the AI is about damage type
Recency (time decay)10Recent signals weighted higher
Weather correlation10Rain + pothole reports = likely flooding
Total (clamped)100
  • Incident created when confidence > 60
  • Incident archived when confidence < 30
  • Confidence decays over time if no new signals arrive

Model Selection Rationale

Model$/1K tokensUsed ForWhy Not Something Else?
Amazon Nova Micro$0.000035/$0.00014Classification + Intent (per signal)Cheapest Nova model; no access approval needed; fast structured output
Amazon Nova Lite$0.00006/$0.00024Explanation (per incident)Better prose quality; only called once per incident, not per signal
Titan Embeddings V2$0.00002Correlation clusteringNative to Bedrock; no cross-service latency; optimized for similarity

Data Sources

The Scraper Lambda runs every hour via EventBridge and pulls from four free, public sources:

SourceLibraryWhat It CapturesSubreddits / Feeds
RedditPRAWCitizen complaints, photos, rantsr/bangalore, r/mumbai, r/delhi, r/chennai, r/hyderabad
News RSSfeedparserStructured reporting on road conditionsTimes of India, NDTV, The Hindu, Deccan Herald
YouTubegoogle-api-python-clientVideo titles + top comments on pothole/flooding videosSearch: pothole road damage india {city}
Weatherurllib (OpenWeatherMap API)Rainfall, flooding alerts — contextual correlationBangalore, Mumbai, Delhi, Chennai, Hyderabad

Search keywords: pothole road flood traffic damage gaddha sadak saalai rasta (English + Hindi + Tamil + Telugu)


Multilingual Processing

India has 22 official languages. Road complaints don't come in English.

"MG Road par bahut bada gaddha hai" → AWS Translate → "There is a large pothole on MG Road"
(Hindi) (auto-detect) (English — ready for AI agents)
  • AWS Translate auto-detects language and translates to English before any agent processing
  • Original text and detected language are preserved in metadata for audit
  • Supported: Hindi, Tamil, Telugu, Kannada, Bengali, Marathi, Malayalam, Gujarati, Punjabi, Urdu, and 60+ more
  • Free tier: 2M characters/month

Privacy & Ethics

RoadSense AI is designed to be trustworthy by default:

PrincipleImplementation
Public data onlyScrapes only publicly visible posts — no private messages, DMs, or login-required content
No individual profilingOutputs are aggregate geographic intelligence, never about specific people
PII anonymisationReddit usernames (u/), YouTube handles (@), emails, Indian phone numbers — all stripped before storage (pii.py)
DeduplicationContent-hash based dedup prevents double-counting from RSS re-serves and repeat scrapes (dedup.py)
Explainable AIEvery incident includes a Nova Lite-generated explanation of the evidence chain
Human-in-the-loopMunicipal authorities can validate or dismiss incidents via the Feedback Agent
Zero citizen effortNo app to install, no form to fill, no account to create

Data Models

Signal (click to expand)
{
"signal_id": "uuid",
"content": "English text (translated if needed)",
"original_content": "raw text in source language",
"translated_content": "English text from AWS Translate",
"detected_language": "hi",
"source": "reddit | news | youtube | weather",
"timestamp": "2026-02-01T10:00:00Z",
"location": {
"coordinates": { "lat": 12.9716, "lon": 77.5946 },
"accuracy_meters": 100,
"address": "MG Road, Bangalore"
},
"classification": {
"is_road_related": true,
"damage_type": "pothole | surface_wear | flooding | general",
"confidence": 0.92
},
"intent": {
"is_problem_report": true,
"urgency_level": "low | medium | high | critical",
"context_type": "direct_report | complaint | warning | news_coverage | ..."
}
}
Incident (click to expand)
{
"incident_id": "uuid",
"location": {
"center_coordinates": { "lat": 12.9716, "lon": 77.5946 },
"radius_meters": 500,
"address": "MG Road, Bangalore"
},
"damage_type": "pothole",
"confidence_score": 78,
"severity_level": "low | medium | high | critical",
"status": "active | monitoring | archived",
"explanation": "AI-generated summary referencing source types and languages",
"signal_ids": ["uuid1", "uuid2", "uuid3"],
"created_at": "2026-02-01T10:00:00Z",
"updated_at": "2026-02-02T14:30:00Z",
"confidence_history": [
{ "timestamp": "2026-02-01T10:00:00Z", "score": 65 },
{ "timestamp": "2026-02-02T14:30:00Z", "score": 78 }
]
}

API Reference

Full OpenAPI 3.0 spec: openapi.yaml

MethodEndpointDescription
POST/ingest-signalSubmit a signal for AI processing
GET/incidentsList all active incidents
GET/confidence/{id}Get confidence score + history for an incident
POST/feedbackSubmit ground-truth validation from authorities
GET/exportExport incidents as JSON (CSV planned)
curl examples (click to expand)
# Ingest a Hindi signal
curl -X POST https://api.roadsense.dev/ingest-signal \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "MG Road par bahut bada gaddha hai", "source": "reddit", "timestamp": "2026-02-01T10:00:00Z", "location": { "latitude": 12.9716, "longitude": 77.5946, "address": "MG Road, Bangalore" } }'# Get active incidents
curl https://api.roadsense.dev/incidents -H "x-api-key: $API_KEY"# Check confidence for a specific incident
curl https://api.roadsense.dev/confidence/incident-123 -H "x-api-key: $API_KEY"# Submit feedback from field inspection
curl -X POST https://api.roadsense.dev/feedback \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "incident_id": "incident-123", "feedback_value": "confirmed", "notes": "Pothole verified, ~2ft wide" }'# Export all incidents
curl https://api.roadsense.dev/export -H "x-api-key: $API_KEY"

Project Structure

roadsense-ai/
├── agents/
│ ├── classification_agent.py # Road-related? What damage type? (Nova Micro)
│ ├── intent_agent.py # Sarcasm/speculation filter + urgency (Nova Micro)
│ ├── correlation_agent.py # Geo+temporal clustering (Titan Embeddings V2)
│ ├── inference_agent.py # Confidence scoring (deterministic)
│ ├── explanation_agent.py # Human-readable summaries (Nova Lite)
│ └── feedback_agent.py # Ground-truth recalibration
├── scraper/
│ ├── reddit_scraper.py # PRAW — Indian city subreddits
│ ├── rss_scraper.py # feedparser — Times of India, NDTV, The Hindu, Deccan Herald
│ ├── youtube_scraper.py # YouTube Data API v3 — video titles + comments
│ └── weather_scraper.py # OpenWeatherMap — rainfall + flood alerts
├── data/
│ ├── generate_signals.py # Synthetic dataset generator
│ ├── signals.json # 1,050 signals (850 EN + 200 multilingual)
│ └── synthetic_incidents.json # 10 mock incidents for dashboard development
├── tests/
│ ├── test_properties.py # 50 property-based tests (Hypothesis)
│ ├── test_intent_agent.py # 45 unit tests — Intent & Context Agent
│ ├── test_inference_agent.py # 55 unit tests — Inference Agent
│ ├── test_api_integration.py # 30 integration tests (skip when API offline)
│ └── test_translate.py # 5 unit tests — AWS Translate wrapper
├── translate.py # AWS Translate wrapper — auto-detect + translate
├── pii.py # PII anonymisation (usernames, emails, phones)
├── dedup.py # Content-hash deduplication
├── location_normaliser.py # Normalise location formats across sources
├── locustfile.py # Load test config — 1,000 signals/hour target
├── openapi.yaml # OpenAPI 3.0 specification
└── .gitignore

Testing

185 tests across 5 test suites. Zero failures.

$ pytest tests/ -v --tb=short
155 passed, 0 failed, 30 skipped ✓

(30 skipped = API integration tests; dev API not yet deployed)

SuiteTestsWhat It Validates
Property-based (test_properties.py)5035 correctness properties via Hypothesis — confidence bounds, thresholds, severity ordering, decay monotonicity, scoring weights
Intent Agent (test_intent_agent.py)45Prompt construction, response parsing, sarcasm/speculation handling, weather pre-classification, fallback logic, Lambda handler
Inference Agent (test_inference_agent.py)55Confidence scoring, severity computation, incident creation/archival thresholds, time decay, cluster processing
API Integration (test_api_integration.py)30End-to-end ingestion, incident retrieval, confidence checks, export, error handling (auto-skipped when API unreachable)
Translate (test_translate.py)5Hindi/Tamil/Telugu translation, English passthrough, empty content handling

Run Tests

# All tests
pytest tests/ -v
# Property-based tests only
pytest tests/test_properties.py -v --hypothesis-seed=0
# Load test (Locust) — requires live API
locust -f locustfile.py --host=https://api.roadsense.dev
# Opens http://localhost:8089 — configure users and spawn rate# Headless: locust -f locustfile.py --host=https://api.roadsense.dev --users 10 --spawn-rate 2 --run-time 5m --headless

Synthetic Dataset

signals.json1,050 signals for development and testing:

CategoryCountPurpose
Road-related (genuine reports)350True positives — potholes, flooding, surface wear
Non-road (noise)250True negatives — traffic jams, politics, unrelated
Sarcastic100Adversarial — "Oh wow another beautiful pothole"
Ambiguous100Edge cases — could be road-related, unclear
Multilingual (hi/ta/te)200Hindi (69), Tamil (70), Telugu (61) — translation pipeline testing
Edge cases50Empty content, missing fields, extreme coordinates

Plus synthetic_incidents.json10 mock incidents across Bangalore locations (Electronic City, MG Road, Silk Board, Whitefield, Koramangala, Indiranagar) for the Authority Dashboard.


Technology Stack

LayerServiceDetail
ScrapingLambda + EventBridgeHourly cron; PRAW, feedparser, google-api-python-client, urllib
TranslationAWS TranslateAuto-detect → English; 10+ Indian languages; 2M chars/month free
IngestionAPI Gateway + LambdaREST endpoint; JSON validation; S3 raw storage
AI ReasoningAmazon BedrockAmazon Nova Micro, Amazon Nova Lite, Titan Embeddings V2
Vector StoreChromaDBSemantic similarity for signal correlation
StorageDynamoDB + S3Incident state in DynamoDB; raw signals archived in S3
APIAPI GatewayREST/JSON; API key auth; 5 endpoints
FrontendReact + S3 + CloudFrontMap view, incident cards, confidence gauges, feedback forms
Testingpytest + Hypothesis + LocustProperty-based, unit, integration, and load testing
CI/CDSAM CLIsam build && sam deploy --guided

Prerequisites

RequirementNotes
Python 3.11+Agent code + scrapers
Node.js 18+React dashboard
AWS CLIConfigured with IAM permissions for Lambda, Bedrock, Translate, DynamoDB, S3, CloudFront
Bedrock model accessNova Micro, Nova Lite, and Titan Embeddings V2 are available in us-east-1 without manual approval
Reddit API credentialsreddit.com/prefs/apps — free, instant
YouTube Data API v3 keyGoogle Cloud Console — free under 10K units/day
OpenWeatherMap API keyopenweathermap.org/api — free tier, 1000 calls/day

Local Setup

# Clone
git clone https://github.com/Sujith-RMD/RoadSense-AI.git
cd RoadSense-AI
# Python environment
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows# Install dependencies
pip install boto3 praw feedparser google-api-python-client chromadb
pip install pytest hypothesis locust # testing# Environment variablesexport REDDIT_CLIENT_ID=...
export REDDIT_CLIENT_SECRET=...
export YOUTUBE_API_KEY=...
export OPENWEATHERMAP_API_KEY=...
export AWS_DEFAULT_REGION=ap-south-1
# Run tests (no AWS credentials needed)
pytest tests/ -v

Deployment

# Backend — Lambda + API Gateway + DynamoDB
sam build
sam deploy --guided
# Frontend — React dashboardcd dashboard
npm install && npm run build
aws s3 sync ./build s3://<frontend-bucket> --delete
# CloudFront distribution URL → hackathon submission link

Team Iceberg

NameRoleOwns
⚙️SrikarAWS & BackendAPI Gateway, Lambda, S3, DynamoDB, CloudFront, Bedrock access, IAM, CloudWatch, bedrock_client.py
🤖DurvaAI Pipeline & DataAll 4 scrapers, AWS Translate integration, 5 AI agents, PII anonymisation, deduplication
🎨NishitaFrontend & UXFigma design system, Authority Dashboard (React), map view, incident detail, confidence gauge, feedback form
🧪SujithQA & Documentation1,050-signal synthetic dataset, 185 tests (property-based + unit + integration + load), OpenAPI spec, README, demo script

Glossary

TermDefinition
SignalAny unstructured text from a public source that may contain road condition information
IncidentA geo-located road infrastructure problem detected by the system, with a confidence score and AI explanation
Confidence Score0–100 composite metric reflecting the system's certainty about detected road damage
Source DiversityNumber of distinct source types (Reddit, news, YouTube, weather) contributing evidence — higher diversity = higher confidence
Temporal DensityConcentration of related signals within a time window — rapid signal bursts indicate active/worsening problems
Ground TruthPost-detection validation by municipal authorities — used to recalibrate confidence scoring
Authority DashboardReact web app for municipal officials to view, prioritize, and provide feedback on detected incidents

RoadSense AI — Team Iceberg · AI for Bharat Hackathon 2026
Detecting the potholes nobody reported — from the signals everyone already posted.

About

RoadSense AI monitors Reddit, news, YouTube, and weather data to detect road damage before complaints are filed. A multi agent AI pipeline translates 10+ Indian languages, filters sarcasm, clusters signals geographically, and surfaces prioritized incidents with confidence scores, zero citizen effort required.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🛣️ RoadSense AI

Civic Signal Intelligence — Detecting road damage from public chatter, before anyone files a complaint.

Built by Team Iceberg · AI for Bharat Hackathon · February 2026


The Problem

India has 6.4 million km of roads. Over 150,000 people die in road accidents every year — a significant share caused by potholes, cave-ins, and waterlogged stretches that go unreported for weeks.

Municipal repair systems are complaint-driven. A pothole only gets fixed after enough citizens call a helpline, tweet at an official, or fill out an online form. By then, someone may have already been hurt.

The signals exist. Nobody is listening.

Every day, thousands of Indians post about broken roads on Reddit, complain in YouTube comments, and get covered by local news — in Hindi, Tamil, Telugu, Kannada, and a dozen other languages. Weather data predicts exactly where flooding will make things worse. All of this is public, free, and real-time.

No one is connecting these dots. Until now.


The Solution

RoadSense AI is a passive early-warning system that monitors public signals — Reddit posts, news articles, YouTube comments, and weather data — and uses a multi-agent AI pipeline to detect emerging road infrastructure damage before complaints are filed.

What it does:

  • Scrapes 4 public sources every hour — zero citizen effort required
  • Translates 10+ Indian languages to English automatically
  • Filters noise, sarcasm, and speculation using Amazon Nova Micro
  • Clusters related signals by geography (500m) and time (7 days)
  • Computes confidence scores (0–100) with explainable reasoning
  • Surfaces prioritized incidents on an Authority Dashboard

What it replaces:

  • ❌ Waiting for complaint volume to reach a threshold
  • ❌ Requiring citizens to install an app
  • ❌ Manual triage of social media by officials
  • ❌ Language barriers blocking non-English reports
  • ❌ Weather damage going undetected until inspection

Target Outcomes

MetricImpact
Complaint-to-response lag40–60% reduction
Early detection rate25–35% increase
Maintenance costsSignificant savings (proactive vs. reactive)
Signal classification accuracy≥ 85%

Architecture

Fully serverless and event-driven on AWS. No servers to manage, scales to zero when idle.

 ┌──────────────────────────────────────┐
│ PUBLIC SIGNALS │
│ Reddit · News RSS · YouTube · Weather│
└──────────────┬───────────────────────┘
│
EventBridge (hourly cron)
│
▼
┌─────────────────────┐
│ Scraper Lambda │
│ 4 scrapers in 1 fn │
└──────────┬──────────┘
│
┌────────────▼────────────┐
│ AWS Translate │
│ hi/ta/te/kn/bn → en │
│ + PII anonymisation │
│ + Deduplication │
└────────────┬─────────────┘
│
POST /ingest-signal (API Gateway)
│
▼
┌────────────────────────────────────┐
│ INFERENCE LAMBDA │
│ │
│ ┌─ Classification Agent (Nova Micro)│
│ │ Road-related? Damage type? │
│ │ │
│ ├─ Intent Agent (Nova Micro) │
│ │ Sarcasm? Speculation? Urgency? │
│ │ │
│ ├─ Correlation Agent (Titan V2) │
│ │ Geo + temporal clustering │
│ │ │
│ ├─ Inference Agent (scoring) │
│ │ Confidence 0–100 + severity │
│ │ │
│ └─ Explanation Agent (Nova Lite) │
│ Human-readable AI reasoning │
└──────────────┬─────────────────────┘
│
┌──────────────▼──────────────┐
│ DynamoDB │
│ Incidents + Signals │
└──────────────┬──────────────┘
│
API Gateway (REST)
│
▼
┌──────────────────────────────┐
│ Authority Dashboard │
│ React · S3 · CloudFront │
│ Map + Incidents + Feedback │
└──────────────────────────────┘

The AI Pipeline — 5 Agents, 3 Models

Every signal passes through a sequential agent pipeline. Each agent adds structured metadata. No agent makes a final decision alone.

#AgentModelInputOutputCost Control
1ClassificationNova MicroRaw English textis_road_related, damage_type, confidenceCheapest model; simple task
2Intent & ContextNova MicroClassified signalis_problem_report, urgency_level, context_typeFilters noise before expensive steps
3CorrelationTitan Embeddings V2All recent signalsSignal clusters (500m radius, 7-day window)Embeddings, not generation
4InferenceNone (deterministic)Signal clustersconfidence_score (0–100), severity_levelNo model call — pure math
5ExplanationNova LiteScored incidentsHuman-readable summaryCalled once per incident, not per signal

Plus a Feedback Agent (no model) that processes ground-truth validation from municipal authorities and recalibrates confidence scores.

Confidence Scoring (Inference Agent)

The confidence score is a weighted composite — no single signal can create a high-confidence incident alone:

FactorMax PointsWhy
Source diversity (Reddit + News + YouTube + Weather)30Multiple independent sources = higher trust
Signal count in cluster20More reports = more likely real
Urgency level consensus20Consistent urgency across signals
Classification confidence20How sure the AI is about damage type
Recency (time decay)10Recent signals weighted higher
Weather correlation10Rain + pothole reports = likely flooding
Total (clamped)100
  • Incident created when confidence > 60
  • Incident archived when confidence < 30
  • Confidence decays over time if no new signals arrive

Model Selection Rationale

Model$/1K tokensUsed ForWhy Not Something Else?
Amazon Nova Micro$0.000035/$0.00014Classification + Intent (per signal)Cheapest Nova model; no access approval needed; fast structured output
Amazon Nova Lite$0.00006/$0.00024Explanation (per incident)Better prose quality; only called once per incident, not per signal
Titan Embeddings V2$0.00002Correlation clusteringNative to Bedrock; no cross-service latency; optimized for similarity

Data Sources

The Scraper Lambda runs every hour via EventBridge and pulls from four free, public sources:

SourceLibraryWhat It CapturesSubreddits / Feeds
RedditPRAWCitizen complaints, photos, rantsr/bangalore, r/mumbai, r/delhi, r/chennai, r/hyderabad
News RSSfeedparserStructured reporting on road conditionsTimes of India, NDTV, The Hindu, Deccan Herald
YouTubegoogle-api-python-clientVideo titles + top comments on pothole/flooding videosSearch: pothole road damage india {city}
Weatherurllib (OpenWeatherMap API)Rainfall, flooding alerts — contextual correlationBangalore, Mumbai, Delhi, Chennai, Hyderabad

Search keywords: pothole road flood traffic damage gaddha sadak saalai rasta (English + Hindi + Tamil + Telugu)


Multilingual Processing

India has 22 official languages. Road complaints don't come in English.

"MG Road par bahut bada gaddha hai" → AWS Translate → "There is a large pothole on MG Road"
(Hindi) (auto-detect) (English — ready for AI agents)
  • AWS Translate auto-detects language and translates to English before any agent processing
  • Original text and detected language are preserved in metadata for audit
  • Supported: Hindi, Tamil, Telugu, Kannada, Bengali, Marathi, Malayalam, Gujarati, Punjabi, Urdu, and 60+ more
  • Free tier: 2M characters/month

Privacy & Ethics

RoadSense AI is designed to be trustworthy by default:

PrincipleImplementation
Public data onlyScrapes only publicly visible posts — no private messages, DMs, or login-required content
No individual profilingOutputs are aggregate geographic intelligence, never about specific people
PII anonymisationReddit usernames (u/), YouTube handles (@), emails, Indian phone numbers — all stripped before storage (pii.py)
DeduplicationContent-hash based dedup prevents double-counting from RSS re-serves and repeat scrapes (dedup.py)
Explainable AIEvery incident includes a Nova Lite-generated explanation of the evidence chain
Human-in-the-loopMunicipal authorities can validate or dismiss incidents via the Feedback Agent
Zero citizen effortNo app to install, no form to fill, no account to create

Data Models

Signal (click to expand)
{
"signal_id": "uuid",
"content": "English text (translated if needed)",
"original_content": "raw text in source language",
"translated_content": "English text from AWS Translate",
"detected_language": "hi",
"source": "reddit | news | youtube | weather",
"timestamp": "2026-02-01T10:00:00Z",
"location": {
"coordinates": { "lat": 12.9716, "lon": 77.5946 },
"accuracy_meters": 100,
"address": "MG Road, Bangalore"
},
"classification": {
"is_road_related": true,
"damage_type": "pothole | surface_wear | flooding | general",
"confidence": 0.92
},
"intent": {
"is_problem_report": true,
"urgency_level": "low | medium | high | critical",
"context_type": "direct_report | complaint | warning | news_coverage | ..."
}
}
Incident (click to expand)
{
"incident_id": "uuid",
"location": {
"center_coordinates": { "lat": 12.9716, "lon": 77.5946 },
"radius_meters": 500,
"address": "MG Road, Bangalore"
},
"damage_type": "pothole",
"confidence_score": 78,
"severity_level": "low | medium | high | critical",
"status": "active | monitoring | archived",
"explanation": "AI-generated summary referencing source types and languages",
"signal_ids": ["uuid1", "uuid2", "uuid3"],
"created_at": "2026-02-01T10:00:00Z",
"updated_at": "2026-02-02T14:30:00Z",
"confidence_history": [
{ "timestamp": "2026-02-01T10:00:00Z", "score": 65 },
{ "timestamp": "2026-02-02T14:30:00Z", "score": 78 }
]
}

API Reference

Full OpenAPI 3.0 spec: openapi.yaml

MethodEndpointDescription
POST/ingest-signalSubmit a signal for AI processing
GET/incidentsList all active incidents
GET/confidence/{id}Get confidence score + history for an incident
POST/feedbackSubmit ground-truth validation from authorities
GET/exportExport incidents as JSON (CSV planned)
curl examples (click to expand)
# Ingest a Hindi signal
curl -X POST https://api.roadsense.dev/ingest-signal \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "MG Road par bahut bada gaddha hai", "source": "reddit", "timestamp": "2026-02-01T10:00:00Z", "location": { "latitude": 12.9716, "longitude": 77.5946, "address": "MG Road, Bangalore" } }'# Get active incidents
curl https://api.roadsense.dev/incidents -H "x-api-key: $API_KEY"# Check confidence for a specific incident
curl https://api.roadsense.dev/confidence/incident-123 -H "x-api-key: $API_KEY"# Submit feedback from field inspection
curl -X POST https://api.roadsense.dev/feedback \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "incident_id": "incident-123", "feedback_value": "confirmed", "notes": "Pothole verified, ~2ft wide" }'# Export all incidents
curl https://api.roadsense.dev/export -H "x-api-key: $API_KEY"

Project Structure

roadsense-ai/
├── agents/
│ ├── classification_agent.py # Road-related? What damage type? (Nova Micro)
│ ├── intent_agent.py # Sarcasm/speculation filter + urgency (Nova Micro)
│ ├── correlation_agent.py # Geo+temporal clustering (Titan Embeddings V2)
│ ├── inference_agent.py # Confidence scoring (deterministic)
│ ├── explanation_agent.py # Human-readable summaries (Nova Lite)
│ └── feedback_agent.py # Ground-truth recalibration
├── scraper/
│ ├── reddit_scraper.py # PRAW — Indian city subreddits
│ ├── rss_scraper.py # feedparser — Times of India, NDTV, The Hindu, Deccan Herald
│ ├── youtube_scraper.py # YouTube Data API v3 — video titles + comments
│ └── weather_scraper.py # OpenWeatherMap — rainfall + flood alerts
├── data/
│ ├── generate_signals.py # Synthetic dataset generator
│ ├── signals.json # 1,050 signals (850 EN + 200 multilingual)
│ └── synthetic_incidents.json # 10 mock incidents for dashboard development
├── tests/
│ ├── test_properties.py # 50 property-based tests (Hypothesis)
│ ├── test_intent_agent.py # 45 unit tests — Intent & Context Agent
│ ├── test_inference_agent.py # 55 unit tests — Inference Agent
│ ├── test_api_integration.py # 30 integration tests (skip when API offline)
│ └── test_translate.py # 5 unit tests — AWS Translate wrapper
├── translate.py # AWS Translate wrapper — auto-detect + translate
├── pii.py # PII anonymisation (usernames, emails, phones)
├── dedup.py # Content-hash deduplication
├── location_normaliser.py # Normalise location formats across sources
├── locustfile.py # Load test config — 1,000 signals/hour target
├── openapi.yaml # OpenAPI 3.0 specification
└── .gitignore

Testing

185 tests across 5 test suites. Zero failures.

$ pytest tests/ -v --tb=short
155 passed, 0 failed, 30 skipped ✓

(30 skipped = API integration tests; dev API not yet deployed)

SuiteTestsWhat It Validates
Property-based (test_properties.py)5035 correctness properties via Hypothesis — confidence bounds, thresholds, severity ordering, decay monotonicity, scoring weights
Intent Agent (test_intent_agent.py)45Prompt construction, response parsing, sarcasm/speculation handling, weather pre-classification, fallback logic, Lambda handler
Inference Agent (test_inference_agent.py)55Confidence scoring, severity computation, incident creation/archival thresholds, time decay, cluster processing
API Integration (test_api_integration.py)30End-to-end ingestion, incident retrieval, confidence checks, export, error handling (auto-skipped when API unreachable)
Translate (test_translate.py)5Hindi/Tamil/Telugu translation, English passthrough, empty content handling

Run Tests

# All tests
pytest tests/ -v
# Property-based tests only
pytest tests/test_properties.py -v --hypothesis-seed=0
# Load test (Locust) — requires live API
locust -f locustfile.py --host=https://api.roadsense.dev
# Opens http://localhost:8089 — configure users and spawn rate# Headless: locust -f locustfile.py --host=https://api.roadsense.dev --users 10 --spawn-rate 2 --run-time 5m --headless

Synthetic Dataset

signals.json1,050 signals for development and testing:

CategoryCountPurpose
Road-related (genuine reports)350True positives — potholes, flooding, surface wear
Non-road (noise)250True negatives — traffic jams, politics, unrelated
Sarcastic100Adversarial — "Oh wow another beautiful pothole"
Ambiguous100Edge cases — could be road-related, unclear
Multilingual (hi/ta/te)200Hindi (69), Tamil (70), Telugu (61) — translation pipeline testing
Edge cases50Empty content, missing fields, extreme coordinates

Plus synthetic_incidents.json10 mock incidents across Bangalore locations (Electronic City, MG Road, Silk Board, Whitefield, Koramangala, Indiranagar) for the Authority Dashboard.


Technology Stack

LayerServiceDetail
ScrapingLambda + EventBridgeHourly cron; PRAW, feedparser, google-api-python-client, urllib
TranslationAWS TranslateAuto-detect → English; 10+ Indian languages; 2M chars/month free
IngestionAPI Gateway + LambdaREST endpoint; JSON validation; S3 raw storage
AI ReasoningAmazon BedrockAmazon Nova Micro, Amazon Nova Lite, Titan Embeddings V2
Vector StoreChromaDBSemantic similarity for signal correlation
StorageDynamoDB + S3Incident state in DynamoDB; raw signals archived in S3
APIAPI GatewayREST/JSON; API key auth; 5 endpoints
FrontendReact + S3 + CloudFrontMap view, incident cards, confidence gauges, feedback forms
Testingpytest + Hypothesis + LocustProperty-based, unit, integration, and load testing
CI/CDSAM CLIsam build && sam deploy --guided

Prerequisites

RequirementNotes
Python 3.11+Agent code + scrapers
Node.js 18+React dashboard
AWS CLIConfigured with IAM permissions for Lambda, Bedrock, Translate, DynamoDB, S3, CloudFront
Bedrock model accessNova Micro, Nova Lite, and Titan Embeddings V2 are available in us-east-1 without manual approval
Reddit API credentialsreddit.com/prefs/apps — free, instant
YouTube Data API v3 keyGoogle Cloud Console — free under 10K units/day
OpenWeatherMap API keyopenweathermap.org/api — free tier, 1000 calls/day

Local Setup

# Clone
git clone https://github.com/Sujith-RMD/RoadSense-AI.git
cd RoadSense-AI
# Python environment
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows# Install dependencies
pip install boto3 praw feedparser google-api-python-client chromadb
pip install pytest hypothesis locust # testing# Environment variablesexport REDDIT_CLIENT_ID=...
export REDDIT_CLIENT_SECRET=...
export YOUTUBE_API_KEY=...
export OPENWEATHERMAP_API_KEY=...
export AWS_DEFAULT_REGION=ap-south-1
# Run tests (no AWS credentials needed)
pytest tests/ -v

Deployment

# Backend — Lambda + API Gateway + DynamoDB
sam build
sam deploy --guided
# Frontend — React dashboardcd dashboard
npm install && npm run build
aws s3 sync ./build s3://<frontend-bucket> --delete
# CloudFront distribution URL → hackathon submission link

Team Iceberg

NameRoleOwns
⚙️SrikarAWS & BackendAPI Gateway, Lambda, S3, DynamoDB, CloudFront, Bedrock access, IAM, CloudWatch, bedrock_client.py
🤖DurvaAI Pipeline & DataAll 4 scrapers, AWS Translate integration, 5 AI agents, PII anonymisation, deduplication
🎨NishitaFrontend & UXFigma design system, Authority Dashboard (React), map view, incident detail, confidence gauge, feedback form
🧪SujithQA & Documentation1,050-signal synthetic dataset, 185 tests (property-based + unit + integration + load), OpenAPI spec, README, demo script

Glossary

TermDefinition
SignalAny unstructured text from a public source that may contain road condition information
IncidentA geo-located road infrastructure problem detected by the system, with a confidence score and AI explanation
Confidence Score0–100 composite metric reflecting the system's certainty about detected road damage
Source DiversityNumber of distinct source types (Reddit, news, YouTube, weather) contributing evidence — higher diversity = higher confidence
Temporal DensityConcentration of related signals within a time window — rapid signal bursts indicate active/worsening problems
Ground TruthPost-detection validation by municipal authorities — used to recalibrate confidence scoring
Authority DashboardReact web app for municipal officials to view, prioritize, and provide feedback on detected incidents

RoadSense AI — Team Iceberg · AI for Bharat Hackathon 2026
Detecting the potholes nobody reported — from the signals everyone already posted.

About

RoadSense AI monitors Reddit, news, YouTube, and weather data to detect road damage before complaints are filed. A multi agent AI pipeline translates 10+ Indian languages, filters sarcasm, clusters signals geographically, and surfaces prioritized incidents with confidence scores, zero citizen effort required.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

🛣️ RoadSense AI

Civic Signal Intelligence — Detecting road damage from public chatter, before anyone files a complaint.

Built by Team Iceberg · AI for Bharat Hackathon · February 2026


The Problem

India has 6.4 million km of roads. Over 150,000 people die in road accidents every year — a significant share caused by potholes, cave-ins, and waterlogged stretches that go unreported for weeks.

Municipal repair systems are complaint-driven. A pothole only gets fixed after enough citizens call a helpline, tweet at an official, or fill out an online form. By then, someone may have already been hurt.

The signals exist. Nobody is listening.

Every day, thousands of Indians post about broken roads on Reddit, complain in YouTube comments, and get covered by local news — in Hindi, Tamil, Telugu, Kannada, and a dozen other languages. Weather data predicts exactly where flooding will make things worse. All of this is public, free, and real-time.

No one is connecting these dots. Until now.


The Solution

RoadSense AI is a passive early-warning system that monitors public signals — Reddit posts, news articles, YouTube comments, and weather data — and uses a multi-agent AI pipeline to detect emerging road infrastructure damage before complaints are filed.

What it does:

  • Scrapes 4 public sources every hour — zero citizen effort required
  • Translates 10+ Indian languages to English automatically
  • Filters noise, sarcasm, and speculation using Amazon Nova Micro
  • Clusters related signals by geography (500m) and time (7 days)
  • Computes confidence scores (0–100) with explainable reasoning
  • Surfaces prioritized incidents on an Authority Dashboard

What it replaces:

  • ❌ Waiting for complaint volume to reach a threshold
  • ❌ Requiring citizens to install an app
  • ❌ Manual triage of social media by officials
  • ❌ Language barriers blocking non-English reports
  • ❌ Weather damage going undetected until inspection

Target Outcomes

MetricImpact
Complaint-to-response lag40–60% reduction
Early detection rate25–35% increase
Maintenance costsSignificant savings (proactive vs. reactive)
Signal classification accuracy≥ 85%

Architecture

Fully serverless and event-driven on AWS. No servers to manage, scales to zero when idle.

 ┌──────────────────────────────────────┐
│ PUBLIC SIGNALS │
│ Reddit · News RSS · YouTube · Weather│
└──────────────┬───────────────────────┘
│
EventBridge (hourly cron)
│
▼
┌─────────────────────┐
│ Scraper Lambda │
│ 4 scrapers in 1 fn │
└──────────┬──────────┘
│
┌────────────▼────────────┐
│ AWS Translate │
│ hi/ta/te/kn/bn → en │
│ + PII anonymisation │
│ + Deduplication │
└────────────┬─────────────┘
│
POST /ingest-signal (API Gateway)
│
▼
┌────────────────────────────────────┐
│ INFERENCE LAMBDA │
│ │
│ ┌─ Classification Agent (Nova Micro)│
│ │ Road-related? Damage type? │
│ │ │
│ ├─ Intent Agent (Nova Micro) │
│ │ Sarcasm? Speculation? Urgency? │
│ │ │
│ ├─ Correlation Agent (Titan V2) │
│ │ Geo + temporal clustering │
│ │ │
│ ├─ Inference Agent (scoring) │
│ │ Confidence 0–100 + severity │
│ │ │
│ └─ Explanation Agent (Nova Lite) │
│ Human-readable AI reasoning │
└──────────────┬─────────────────────┘
│
┌──────────────▼──────────────┐
│ DynamoDB │
│ Incidents + Signals │
└──────────────┬──────────────┘
│
API Gateway (REST)
│
▼
┌──────────────────────────────┐
│ Authority Dashboard │
│ React · S3 · CloudFront │
│ Map + Incidents + Feedback │
└──────────────────────────────┘

The AI Pipeline — 5 Agents, 3 Models

Every signal passes through a sequential agent pipeline. Each agent adds structured metadata. No agent makes a final decision alone.

#AgentModelInputOutputCost Control
1ClassificationNova MicroRaw English textis_road_related, damage_type, confidenceCheapest model; simple task
2Intent & ContextNova MicroClassified signalis_problem_report, urgency_level, context_typeFilters noise before expensive steps
3CorrelationTitan Embeddings V2All recent signalsSignal clusters (500m radius, 7-day window)Embeddings, not generation
4InferenceNone (deterministic)Signal clustersconfidence_score (0–100), severity_levelNo model call — pure math
5ExplanationNova LiteScored incidentsHuman-readable summaryCalled once per incident, not per signal

Plus a Feedback Agent (no model) that processes ground-truth validation from municipal authorities and recalibrates confidence scores.

Confidence Scoring (Inference Agent)

The confidence score is a weighted composite — no single signal can create a high-confidence incident alone:

FactorMax PointsWhy
Source diversity (Reddit + News + YouTube + Weather)30Multiple independent sources = higher trust
Signal count in cluster20More reports = more likely real
Urgency level consensus20Consistent urgency across signals
Classification confidence20How sure the AI is about damage type
Recency (time decay)10Recent signals weighted higher
Weather correlation10Rain + pothole reports = likely flooding
Total (clamped)100
  • Incident created when confidence > 60
  • Incident archived when confidence < 30
  • Confidence decays over time if no new signals arrive

Model Selection Rationale

Model$/1K tokensUsed ForWhy Not Something Else?
Amazon Nova Micro$0.000035/$0.00014Classification + Intent (per signal)Cheapest Nova model; no access approval needed; fast structured output
Amazon Nova Lite$0.00006/$0.00024Explanation (per incident)Better prose quality; only called once per incident, not per signal
Titan Embeddings V2$0.00002Correlation clusteringNative to Bedrock; no cross-service latency; optimized for similarity

Data Sources

The Scraper Lambda runs every hour via EventBridge and pulls from four free, public sources:

SourceLibraryWhat It CapturesSubreddits / Feeds
RedditPRAWCitizen complaints, photos, rantsr/bangalore, r/mumbai, r/delhi, r/chennai, r/hyderabad
News RSSfeedparserStructured reporting on road conditionsTimes of India, NDTV, The Hindu, Deccan Herald
YouTubegoogle-api-python-clientVideo titles + top comments on pothole/flooding videosSearch: pothole road damage india {city}
Weatherurllib (OpenWeatherMap API)Rainfall, flooding alerts — contextual correlationBangalore, Mumbai, Delhi, Chennai, Hyderabad

Search keywords: pothole road flood traffic damage gaddha sadak saalai rasta (English + Hindi + Tamil + Telugu)


Multilingual Processing

India has 22 official languages. Road complaints don't come in English.

"MG Road par bahut bada gaddha hai" → AWS Translate → "There is a large pothole on MG Road"
(Hindi) (auto-detect) (English — ready for AI agents)
  • AWS Translate auto-detects language and translates to English before any agent processing
  • Original text and detected language are preserved in metadata for audit
  • Supported: Hindi, Tamil, Telugu, Kannada, Bengali, Marathi, Malayalam, Gujarati, Punjabi, Urdu, and 60+ more
  • Free tier: 2M characters/month

Privacy & Ethics

RoadSense AI is designed to be trustworthy by default:

PrincipleImplementation
Public data onlyScrapes only publicly visible posts — no private messages, DMs, or login-required content
No individual profilingOutputs are aggregate geographic intelligence, never about specific people
PII anonymisationReddit usernames (u/), YouTube handles (@), emails, Indian phone numbers — all stripped before storage (pii.py)
DeduplicationContent-hash based dedup prevents double-counting from RSS re-serves and repeat scrapes (dedup.py)
Explainable AIEvery incident includes a Nova Lite-generated explanation of the evidence chain
Human-in-the-loopMunicipal authorities can validate or dismiss incidents via the Feedback Agent
Zero citizen effortNo app to install, no form to fill, no account to create

Data Models

Signal (click to expand)
{
"signal_id": "uuid",
"content": "English text (translated if needed)",
"original_content": "raw text in source language",
"translated_content": "English text from AWS Translate",
"detected_language": "hi",
"source": "reddit | news | youtube | weather",
"timestamp": "2026-02-01T10:00:00Z",
"location": {
"coordinates": { "lat": 12.9716, "lon": 77.5946 },
"accuracy_meters": 100,
"address": "MG Road, Bangalore"
},
"classification": {
"is_road_related": true,
"damage_type": "pothole | surface_wear | flooding | general",
"confidence": 0.92
},
"intent": {
"is_problem_report": true,
"urgency_level": "low | medium | high | critical",
"context_type": "direct_report | complaint | warning | news_coverage | ..."
}
}
Incident (click to expand)
{
"incident_id": "uuid",
"location": {
"center_coordinates": { "lat": 12.9716, "lon": 77.5946 },
"radius_meters": 500,
"address": "MG Road, Bangalore"
},
"damage_type": "pothole",
"confidence_score": 78,
"severity_level": "low | medium | high | critical",
"status": "active | monitoring | archived",
"explanation": "AI-generated summary referencing source types and languages",
"signal_ids": ["uuid1", "uuid2", "uuid3"],
"created_at": "2026-02-01T10:00:00Z",
"updated_at": "2026-02-02T14:30:00Z",
"confidence_history": [
{ "timestamp": "2026-02-01T10:00:00Z", "score": 65 },
{ "timestamp": "2026-02-02T14:30:00Z", "score": 78 }
]
}

API Reference

Full OpenAPI 3.0 spec: openapi.yaml

MethodEndpointDescription
POST/ingest-signalSubmit a signal for AI processing
GET/incidentsList all active incidents
GET/confidence/{id}Get confidence score + history for an incident
POST/feedbackSubmit ground-truth validation from authorities
GET/exportExport incidents as JSON (CSV planned)
curl examples (click to expand)
# Ingest a Hindi signal
curl -X POST https://api.roadsense.dev/ingest-signal \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "MG Road par bahut bada gaddha hai", "source": "reddit", "timestamp": "2026-02-01T10:00:00Z", "location": { "latitude": 12.9716, "longitude": 77.5946, "address": "MG Road, Bangalore" } }'# Get active incidents
curl https://api.roadsense.dev/incidents -H "x-api-key: $API_KEY"# Check confidence for a specific incident
curl https://api.roadsense.dev/confidence/incident-123 -H "x-api-key: $API_KEY"# Submit feedback from field inspection
curl -X POST https://api.roadsense.dev/feedback \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "incident_id": "incident-123", "feedback_value": "confirmed", "notes": "Pothole verified, ~2ft wide" }'# Export all incidents
curl https://api.roadsense.dev/export -H "x-api-key: $API_KEY"

Project Structure

roadsense-ai/
├── agents/
│ ├── classification_agent.py # Road-related? What damage type? (Nova Micro)
│ ├── intent_agent.py # Sarcasm/speculation filter + urgency (Nova Micro)
│ ├── correlation_agent.py # Geo+temporal clustering (Titan Embeddings V2)
│ ├── inference_agent.py # Confidence scoring (deterministic)
│ ├── explanation_agent.py # Human-readable summaries (Nova Lite)
│ └── feedback_agent.py # Ground-truth recalibration
├── scraper/
│ ├── reddit_scraper.py # PRAW — Indian city subreddits
│ ├── rss_scraper.py # feedparser — Times of India, NDTV, The Hindu, Deccan Herald
│ ├── youtube_scraper.py # YouTube Data API v3 — video titles + comments
│ └── weather_scraper.py # OpenWeatherMap — rainfall + flood alerts
├── data/
│ ├── generate_signals.py # Synthetic dataset generator
│ ├── signals.json # 1,050 signals (850 EN + 200 multilingual)
│ └── synthetic_incidents.json # 10 mock incidents for dashboard development
├── tests/
│ ├── test_properties.py # 50 property-based tests (Hypothesis)
│ ├── test_intent_agent.py # 45 unit tests — Intent & Context Agent
│ ├── test_inference_agent.py # 55 unit tests — Inference Agent
│ ├── test_api_integration.py # 30 integration tests (skip when API offline)
│ └── test_translate.py # 5 unit tests — AWS Translate wrapper
├── translate.py # AWS Translate wrapper — auto-detect + translate
├── pii.py # PII anonymisation (usernames, emails, phones)
├── dedup.py # Content-hash deduplication
├── location_normaliser.py # Normalise location formats across sources
├── locustfile.py # Load test config — 1,000 signals/hour target
├── openapi.yaml # OpenAPI 3.0 specification
└── .gitignore

Testing

185 tests across 5 test suites. Zero failures.

$ pytest tests/ -v --tb=short
155 passed, 0 failed, 30 skipped ✓

(30 skipped = API integration tests; dev API not yet deployed)

SuiteTestsWhat It Validates
Property-based (test_properties.py)5035 correctness properties via Hypothesis — confidence bounds, thresholds, severity ordering, decay monotonicity, scoring weights
Intent Agent (test_intent_agent.py)45Prompt construction, response parsing, sarcasm/speculation handling, weather pre-classification, fallback logic, Lambda handler
Inference Agent (test_inference_agent.py)55Confidence scoring, severity computation, incident creation/archival thresholds, time decay, cluster processing
API Integration (test_api_integration.py)30End-to-end ingestion, incident retrieval, confidence checks, export, error handling (auto-skipped when API unreachable)
Translate (test_translate.py)5Hindi/Tamil/Telugu translation, English passthrough, empty content handling

Run Tests

# All tests
pytest tests/ -v
# Property-based tests only
pytest tests/test_properties.py -v --hypothesis-seed=0
# Load test (Locust) — requires live API
locust -f locustfile.py --host=https://api.roadsense.dev
# Opens http://localhost:8089 — configure users and spawn rate# Headless: locust -f locustfile.py --host=https://api.roadsense.dev --users 10 --spawn-rate 2 --run-time 5m --headless

Synthetic Dataset

signals.json1,050 signals for development and testing:

CategoryCountPurpose
Road-related (genuine reports)350True positives — potholes, flooding, surface wear
Non-road (noise)250True negatives — traffic jams, politics, unrelated
Sarcastic100Adversarial — "Oh wow another beautiful pothole"
Ambiguous100Edge cases — could be road-related, unclear
Multilingual (hi/ta/te)200Hindi (69), Tamil (70), Telugu (61) — translation pipeline testing
Edge cases50Empty content, missing fields, extreme coordinates

Plus synthetic_incidents.json10 mock incidents across Bangalore locations (Electronic City, MG Road, Silk Board, Whitefield, Koramangala, Indiranagar) for the Authority Dashboard.


Technology Stack

LayerServiceDetail
ScrapingLambda + EventBridgeHourly cron; PRAW, feedparser, google-api-python-client, urllib
TranslationAWS TranslateAuto-detect → English; 10+ Indian languages; 2M chars/month free
IngestionAPI Gateway + LambdaREST endpoint; JSON validation; S3 raw storage
AI ReasoningAmazon BedrockAmazon Nova Micro, Amazon Nova Lite, Titan Embeddings V2
Vector StoreChromaDBSemantic similarity for signal correlation
StorageDynamoDB + S3Incident state in DynamoDB; raw signals archived in S3
APIAPI GatewayREST/JSON; API key auth; 5 endpoints
FrontendReact + S3 + CloudFrontMap view, incident cards, confidence gauges, feedback forms
Testingpytest + Hypothesis + LocustProperty-based, unit, integration, and load testing
CI/CDSAM CLIsam build && sam deploy --guided

Prerequisites

RequirementNotes
Python 3.11+Agent code + scrapers
Node.js 18+React dashboard
AWS CLIConfigured with IAM permissions for Lambda, Bedrock, Translate, DynamoDB, S3, CloudFront
Bedrock model accessNova Micro, Nova Lite, and Titan Embeddings V2 are available in us-east-1 without manual approval
Reddit API credentialsreddit.com/prefs/apps — free, instant
YouTube Data API v3 keyGoogle Cloud Console — free under 10K units/day
OpenWeatherMap API keyopenweathermap.org/api — free tier, 1000 calls/day

Local Setup

# Clone
git clone https://github.com/Sujith-RMD/RoadSense-AI.git
cd RoadSense-AI
# Python environment
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows# Install dependencies
pip install boto3 praw feedparser google-api-python-client chromadb
pip install pytest hypothesis locust # testing# Environment variablesexport REDDIT_CLIENT_ID=...
export REDDIT_CLIENT_SECRET=...
export YOUTUBE_API_KEY=...
export OPENWEATHERMAP_API_KEY=...
export AWS_DEFAULT_REGION=ap-south-1
# Run tests (no AWS credentials needed)
pytest tests/ -v

Deployment

# Backend — Lambda + API Gateway + DynamoDB
sam build
sam deploy --guided
# Frontend — React dashboardcd dashboard
npm install && npm run build
aws s3 sync ./build s3://<frontend-bucket> --delete
# CloudFront distribution URL → hackathon submission link

Team Iceberg

NameRoleOwns
⚙️SrikarAWS & BackendAPI Gateway, Lambda, S3, DynamoDB, CloudFront, Bedrock access, IAM, CloudWatch, bedrock_client.py
🤖DurvaAI Pipeline & DataAll 4 scrapers, AWS Translate integration, 5 AI agents, PII anonymisation, deduplication
🎨NishitaFrontend & UXFigma design system, Authority Dashboard (React), map view, incident detail, confidence gauge, feedback form
🧪SujithQA & Documentation1,050-signal synthetic dataset, 185 tests (property-based + unit + integration + load), OpenAPI spec, README, demo script

Glossary

TermDefinition
SignalAny unstructured text from a public source that may contain road condition information
IncidentA geo-located road infrastructure problem detected by the system, with a confidence score and AI explanation
Confidence Score0–100 composite metric reflecting the system's certainty about detected road damage
Source DiversityNumber of distinct source types (Reddit, news, YouTube, weather) contributing evidence — higher diversity = higher confidence
Temporal DensityConcentration of related signals within a time window — rapid signal bursts indicate active/worsening problems
Ground TruthPost-detection validation by municipal authorities — used to recalibrate confidence scoring
Authority DashboardReact web app for municipal officials to view, prioritize, and provide feedback on detected incidents

RoadSense AI — Team Iceberg · AI for Bharat Hackathon 2026
Detecting the potholes nobody reported — from the signals everyone already posted.

About

RoadSense AI monitors Reddit, news, YouTube, and weather data to detect road damage before complaints are filed. A multi agent AI pipeline translates 10+ Indian languages, filters sarcasm, clusters signals geographically, and surfaces prioritized incidents with confidence scores, zero citizen effort required.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🛣️ RoadSense AI

Civic Signal Intelligence — Detecting road damage from public chatter, before anyone files a complaint.

Built by Team Iceberg · AI for Bharat Hackathon · February 2026


The Problem

India has 6.4 million km of roads. Over 150,000 people die in road accidents every year — a significant share caused by potholes, cave-ins, and waterlogged stretches that go unreported for weeks.

Municipal repair systems are complaint-driven. A pothole only gets fixed after enough citizens call a helpline, tweet at an official, or fill out an online form. By then, someone may have already been hurt.

The signals exist. Nobody is listening.

Every day, thousands of Indians post about broken roads on Reddit, complain in YouTube comments, and get covered by local news — in Hindi, Tamil, Telugu, Kannada, and a dozen other languages. Weather data predicts exactly where flooding will make things worse. All of this is public, free, and real-time.

No one is connecting these dots. Until now.


The Solution

RoadSense AI is a passive early-warning system that monitors public signals — Reddit posts, news articles, YouTube comments, and weather data — and uses a multi-agent AI pipeline to detect emerging road infrastructure damage before complaints are filed.

What it does:

  • Scrapes 4 public sources every hour — zero citizen effort required
  • Translates 10+ Indian languages to English automatically
  • Filters noise, sarcasm, and speculation using Amazon Nova Micro
  • Clusters related signals by geography (500m) and time (7 days)
  • Computes confidence scores (0–100) with explainable reasoning
  • Surfaces prioritized incidents on an Authority Dashboard

What it replaces:

  • ❌ Waiting for complaint volume to reach a threshold
  • ❌ Requiring citizens to install an app
  • ❌ Manual triage of social media by officials
  • ❌ Language barriers blocking non-English reports
  • ❌ Weather damage going undetected until inspection

Target Outcomes

MetricImpact
Complaint-to-response lag40–60% reduction
Early detection rate25–35% increase
Maintenance costsSignificant savings (proactive vs. reactive)
Signal classification accuracy≥ 85%

Architecture

Fully serverless and event-driven on AWS. No servers to manage, scales to zero when idle.

 ┌──────────────────────────────────────┐
│ PUBLIC SIGNALS │
│ Reddit · News RSS · YouTube · Weather│
└──────────────┬───────────────────────┘
│
EventBridge (hourly cron)
│
▼
┌─────────────────────┐
│ Scraper Lambda │
│ 4 scrapers in 1 fn │
└──────────┬──────────┘
│
┌────────────▼────────────┐
│ AWS Translate │
│ hi/ta/te/kn/bn → en │
│ + PII anonymisation │
│ + Deduplication │
└────────────┬─────────────┘
│
POST /ingest-signal (API Gateway)
│
▼
┌────────────────────────────────────┐
│ INFERENCE LAMBDA │
│ │
│ ┌─ Classification Agent (Nova Micro)│
│ │ Road-related? Damage type? │
│ │ │
│ ├─ Intent Agent (Nova Micro) │
│ │ Sarcasm? Speculation? Urgency? │
│ │ │
│ ├─ Correlation Agent (Titan V2) │
│ │ Geo + temporal clustering │
│ │ │
│ ├─ Inference Agent (scoring) │
│ │ Confidence 0–100 + severity │
│ │ │
│ └─ Explanation Agent (Nova Lite) │
│ Human-readable AI reasoning │
└──────────────┬─────────────────────┘
│
┌──────────────▼──────────────┐
│ DynamoDB │
│ Incidents + Signals │
└──────────────┬──────────────┘
│
API Gateway (REST)
│
▼
┌──────────────────────────────┐
│ Authority Dashboard │
│ React · S3 · CloudFront │
│ Map + Incidents + Feedback │
└──────────────────────────────┘

The AI Pipeline — 5 Agents, 3 Models

Every signal passes through a sequential agent pipeline. Each agent adds structured metadata. No agent makes a final decision alone.

#AgentModelInputOutputCost Control
1ClassificationNova MicroRaw English textis_road_related, damage_type, confidenceCheapest model; simple task
2Intent & ContextNova MicroClassified signalis_problem_report, urgency_level, context_typeFilters noise before expensive steps
3CorrelationTitan Embeddings V2All recent signalsSignal clusters (500m radius, 7-day window)Embeddings, not generation
4InferenceNone (deterministic)Signal clustersconfidence_score (0–100), severity_levelNo model call — pure math
5ExplanationNova LiteScored incidentsHuman-readable summaryCalled once per incident, not per signal

Plus a Feedback Agent (no model) that processes ground-truth validation from municipal authorities and recalibrates confidence scores.

Confidence Scoring (Inference Agent)

The confidence score is a weighted composite — no single signal can create a high-confidence incident alone:

FactorMax PointsWhy
Source diversity (Reddit + News + YouTube + Weather)30Multiple independent sources = higher trust
Signal count in cluster20More reports = more likely real
Urgency level consensus20Consistent urgency across signals
Classification confidence20How sure the AI is about damage type
Recency (time decay)10Recent signals weighted higher
Weather correlation10Rain + pothole reports = likely flooding
Total (clamped)100
  • Incident created when confidence > 60
  • Incident archived when confidence < 30
  • Confidence decays over time if no new signals arrive

Model Selection Rationale

Model$/1K tokensUsed ForWhy Not Something Else?
Amazon Nova Micro$0.000035/$0.00014Classification + Intent (per signal)Cheapest Nova model; no access approval needed; fast structured output
Amazon Nova Lite$0.00006/$0.00024Explanation (per incident)Better prose quality; only called once per incident, not per signal
Titan Embeddings V2$0.00002Correlation clusteringNative to Bedrock; no cross-service latency; optimized for similarity

Data Sources

The Scraper Lambda runs every hour via EventBridge and pulls from four free, public sources:

SourceLibraryWhat It CapturesSubreddits / Feeds
RedditPRAWCitizen complaints, photos, rantsr/bangalore, r/mumbai, r/delhi, r/chennai, r/hyderabad
News RSSfeedparserStructured reporting on road conditionsTimes of India, NDTV, The Hindu, Deccan Herald
YouTubegoogle-api-python-clientVideo titles + top comments on pothole/flooding videosSearch: pothole road damage india {city}
Weatherurllib (OpenWeatherMap API)Rainfall, flooding alerts — contextual correlationBangalore, Mumbai, Delhi, Chennai, Hyderabad

Search keywords: pothole road flood traffic damage gaddha sadak saalai rasta (English + Hindi + Tamil + Telugu)


Multilingual Processing

India has 22 official languages. Road complaints don't come in English.

"MG Road par bahut bada gaddha hai" → AWS Translate → "There is a large pothole on MG Road"
(Hindi) (auto-detect) (English — ready for AI agents)
  • AWS Translate auto-detects language and translates to English before any agent processing
  • Original text and detected language are preserved in metadata for audit
  • Supported: Hindi, Tamil, Telugu, Kannada, Bengali, Marathi, Malayalam, Gujarati, Punjabi, Urdu, and 60+ more
  • Free tier: 2M characters/month

Privacy & Ethics

RoadSense AI is designed to be trustworthy by default:

PrincipleImplementation
Public data onlyScrapes only publicly visible posts — no private messages, DMs, or login-required content
No individual profilingOutputs are aggregate geographic intelligence, never about specific people
PII anonymisationReddit usernames (u/), YouTube handles (@), emails, Indian phone numbers — all stripped before storage (pii.py)
DeduplicationContent-hash based dedup prevents double-counting from RSS re-serves and repeat scrapes (dedup.py)
Explainable AIEvery incident includes a Nova Lite-generated explanation of the evidence chain
Human-in-the-loopMunicipal authorities can validate or dismiss incidents via the Feedback Agent
Zero citizen effortNo app to install, no form to fill, no account to create

Data Models

Signal (click to expand)
{
"signal_id": "uuid",
"content": "English text (translated if needed)",
"original_content": "raw text in source language",
"translated_content": "English text from AWS Translate",
"detected_language": "hi",
"source": "reddit | news | youtube | weather",
"timestamp": "2026-02-01T10:00:00Z",
"location": {
"coordinates": { "lat": 12.9716, "lon": 77.5946 },
"accuracy_meters": 100,
"address": "MG Road, Bangalore"
},
"classification": {
"is_road_related": true,
"damage_type": "pothole | surface_wear | flooding | general",
"confidence": 0.92
},
"intent": {
"is_problem_report": true,
"urgency_level": "low | medium | high | critical",
"context_type": "direct_report | complaint | warning | news_coverage | ..."
}
}
Incident (click to expand)
{
"incident_id": "uuid",
"location": {
"center_coordinates": { "lat": 12.9716, "lon": 77.5946 },
"radius_meters": 500,
"address": "MG Road, Bangalore"
},
"damage_type": "pothole",
"confidence_score": 78,
"severity_level": "low | medium | high | critical",
"status": "active | monitoring | archived",
"explanation": "AI-generated summary referencing source types and languages",
"signal_ids": ["uuid1", "uuid2", "uuid3"],
"created_at": "2026-02-01T10:00:00Z",
"updated_at": "2026-02-02T14:30:00Z",
"confidence_history": [
{ "timestamp": "2026-02-01T10:00:00Z", "score": 65 },
{ "timestamp": "2026-02-02T14:30:00Z", "score": 78 }
]
}

API Reference

Full OpenAPI 3.0 spec: openapi.yaml

MethodEndpointDescription
POST/ingest-signalSubmit a signal for AI processing
GET/incidentsList all active incidents
GET/confidence/{id}Get confidence score + history for an incident
POST/feedbackSubmit ground-truth validation from authorities
GET/exportExport incidents as JSON (CSV planned)
curl examples (click to expand)
# Ingest a Hindi signal
curl -X POST https://api.roadsense.dev/ingest-signal \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "MG Road par bahut bada gaddha hai", "source": "reddit", "timestamp": "2026-02-01T10:00:00Z", "location": { "latitude": 12.9716, "longitude": 77.5946, "address": "MG Road, Bangalore" } }'# Get active incidents
curl https://api.roadsense.dev/incidents -H "x-api-key: $API_KEY"# Check confidence for a specific incident
curl https://api.roadsense.dev/confidence/incident-123 -H "x-api-key: $API_KEY"# Submit feedback from field inspection
curl -X POST https://api.roadsense.dev/feedback \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "incident_id": "incident-123", "feedback_value": "confirmed", "notes": "Pothole verified, ~2ft wide" }'# Export all incidents
curl https://api.roadsense.dev/export -H "x-api-key: $API_KEY"

Project Structure

roadsense-ai/
├── agents/
│ ├── classification_agent.py # Road-related? What damage type? (Nova Micro)
│ ├── intent_agent.py # Sarcasm/speculation filter + urgency (Nova Micro)
│ ├── correlation_agent.py # Geo+temporal clustering (Titan Embeddings V2)
│ ├── inference_agent.py # Confidence scoring (deterministic)
│ ├── explanation_agent.py # Human-readable summaries (Nova Lite)
│ └── feedback_agent.py # Ground-truth recalibration
├── scraper/
│ ├── reddit_scraper.py # PRAW — Indian city subreddits
│ ├── rss_scraper.py # feedparser — Times of India, NDTV, The Hindu, Deccan Herald
│ ├── youtube_scraper.py # YouTube Data API v3 — video titles + comments
│ └── weather_scraper.py # OpenWeatherMap — rainfall + flood alerts
├── data/
│ ├── generate_signals.py # Synthetic dataset generator
│ ├── signals.json # 1,050 signals (850 EN + 200 multilingual)
│ └── synthetic_incidents.json # 10 mock incidents for dashboard development
├── tests/
│ ├── test_properties.py # 50 property-based tests (Hypothesis)
│ ├── test_intent_agent.py # 45 unit tests — Intent & Context Agent
│ ├── test_inference_agent.py # 55 unit tests — Inference Agent
│ ├── test_api_integration.py # 30 integration tests (skip when API offline)
│ └── test_translate.py # 5 unit tests — AWS Translate wrapper
├── translate.py # AWS Translate wrapper — auto-detect + translate
├── pii.py # PII anonymisation (usernames, emails, phones)
├── dedup.py # Content-hash deduplication
├── location_normaliser.py # Normalise location formats across sources
├── locustfile.py # Load test config — 1,000 signals/hour target
├── openapi.yaml # OpenAPI 3.0 specification
└── .gitignore

Testing

185 tests across 5 test suites. Zero failures.

$ pytest tests/ -v --tb=short
155 passed, 0 failed, 30 skipped ✓

(30 skipped = API integration tests; dev API not yet deployed)

SuiteTestsWhat It Validates
Property-based (test_properties.py)5035 correctness properties via Hypothesis — confidence bounds, thresholds, severity ordering, decay monotonicity, scoring weights
Intent Agent (test_intent_agent.py)45Prompt construction, response parsing, sarcasm/speculation handling, weather pre-classification, fallback logic, Lambda handler
Inference Agent (test_inference_agent.py)55Confidence scoring, severity computation, incident creation/archival thresholds, time decay, cluster processing
API Integration (test_api_integration.py)30End-to-end ingestion, incident retrieval, confidence checks, export, error handling (auto-skipped when API unreachable)
Translate (test_translate.py)5Hindi/Tamil/Telugu translation, English passthrough, empty content handling

Run Tests

# All tests
pytest tests/ -v
# Property-based tests only
pytest tests/test_properties.py -v --hypothesis-seed=0
# Load test (Locust) — requires live API
locust -f locustfile.py --host=https://api.roadsense.dev
# Opens http://localhost:8089 — configure users and spawn rate# Headless: locust -f locustfile.py --host=https://api.roadsense.dev --users 10 --spawn-rate 2 --run-time 5m --headless

Synthetic Dataset

signals.json1,050 signals for development and testing:

CategoryCountPurpose
Road-related (genuine reports)350True positives — potholes, flooding, surface wear
Non-road (noise)250True negatives — traffic jams, politics, unrelated
Sarcastic100Adversarial — "Oh wow another beautiful pothole"
Ambiguous100Edge cases — could be road-related, unclear
Multilingual (hi/ta/te)200Hindi (69), Tamil (70), Telugu (61) — translation pipeline testing
Edge cases50Empty content, missing fields, extreme coordinates

Plus synthetic_incidents.json10 mock incidents across Bangalore locations (Electronic City, MG Road, Silk Board, Whitefield, Koramangala, Indiranagar) for the Authority Dashboard.


Technology Stack

LayerServiceDetail
ScrapingLambda + EventBridgeHourly cron; PRAW, feedparser, google-api-python-client, urllib
TranslationAWS TranslateAuto-detect → English; 10+ Indian languages; 2M chars/month free
IngestionAPI Gateway + LambdaREST endpoint; JSON validation; S3 raw storage
AI ReasoningAmazon BedrockAmazon Nova Micro, Amazon Nova Lite, Titan Embeddings V2
Vector StoreChromaDBSemantic similarity for signal correlation
StorageDynamoDB + S3Incident state in DynamoDB; raw signals archived in S3
APIAPI GatewayREST/JSON; API key auth; 5 endpoints
FrontendReact + S3 + CloudFrontMap view, incident cards, confidence gauges, feedback forms
Testingpytest + Hypothesis + LocustProperty-based, unit, integration, and load testing
CI/CDSAM CLIsam build && sam deploy --guided

Prerequisites

RequirementNotes
Python 3.11+Agent code + scrapers
Node.js 18+React dashboard
AWS CLIConfigured with IAM permissions for Lambda, Bedrock, Translate, DynamoDB, S3, CloudFront
Bedrock model accessNova Micro, Nova Lite, and Titan Embeddings V2 are available in us-east-1 without manual approval
Reddit API credentialsreddit.com/prefs/apps — free, instant
YouTube Data API v3 keyGoogle Cloud Console — free under 10K units/day
OpenWeatherMap API keyopenweathermap.org/api — free tier, 1000 calls/day

Local Setup

# Clone
git clone https://github.com/Sujith-RMD/RoadSense-AI.git
cd RoadSense-AI
# Python environment
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows# Install dependencies
pip install boto3 praw feedparser google-api-python-client chromadb
pip install pytest hypothesis locust # testing# Environment variablesexport REDDIT_CLIENT_ID=...
export REDDIT_CLIENT_SECRET=...
export YOUTUBE_API_KEY=...
export OPENWEATHERMAP_API_KEY=...
export AWS_DEFAULT_REGION=ap-south-1
# Run tests (no AWS credentials needed)
pytest tests/ -v

Deployment

# Backend — Lambda + API Gateway + DynamoDB
sam build
sam deploy --guided
# Frontend — React dashboardcd dashboard
npm install && npm run build
aws s3 sync ./build s3://<frontend-bucket> --delete
# CloudFront distribution URL → hackathon submission link

Team Iceberg

NameRoleOwns
⚙️SrikarAWS & BackendAPI Gateway, Lambda, S3, DynamoDB, CloudFront, Bedrock access, IAM, CloudWatch, bedrock_client.py
🤖DurvaAI Pipeline & DataAll 4 scrapers, AWS Translate integration, 5 AI agents, PII anonymisation, deduplication
🎨NishitaFrontend & UXFigma design system, Authority Dashboard (React), map view, incident detail, confidence gauge, feedback form
🧪SujithQA & Documentation1,050-signal synthetic dataset, 185 tests (property-based + unit + integration + load), OpenAPI spec, README, demo script

Glossary

TermDefinition
SignalAny unstructured text from a public source that may contain road condition information
IncidentA geo-located road infrastructure problem detected by the system, with a confidence score and AI explanation
Confidence Score0–100 composite metric reflecting the system's certainty about detected road damage
Source DiversityNumber of distinct source types (Reddit, news, YouTube, weather) contributing evidence — higher diversity = higher confidence
Temporal DensityConcentration of related signals within a time window — rapid signal bursts indicate active/worsening problems
Ground TruthPost-detection validation by municipal authorities — used to recalibrate confidence scoring
Authority DashboardReact web app for municipal officials to view, prioritize, and provide feedback on detected incidents

RoadSense AI — Team Iceberg · AI for Bharat Hackathon 2026
Detecting the potholes nobody reported — from the signals everyone already posted.

About

RoadSense AI monitors Reddit, news, YouTube, and weather data to detect road damage before complaints are filed. A multi agent AI pipeline translates 10+ Indian languages, filters sarcasm, clusters signals geographically, and surfaces prioritized incidents with confidence scores, zero citizen effort required.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🛣️ RoadSense AI

Civic Signal Intelligence — Detecting road damage from public chatter, before anyone files a complaint.

Built by Team Iceberg · AI for Bharat Hackathon · February 2026


The Problem

India has 6.4 million km of roads. Over 150,000 people die in road accidents every year — a significant share caused by potholes, cave-ins, and waterlogged stretches that go unreported for weeks.

Municipal repair systems are complaint-driven. A pothole only gets fixed after enough citizens call a helpline, tweet at an official, or fill out an online form. By then, someone may have already been hurt.

The signals exist. Nobody is listening.

Every day, thousands of Indians post about broken roads on Reddit, complain in YouTube comments, and get covered by local news — in Hindi, Tamil, Telugu, Kannada, and a dozen other languages. Weather data predicts exactly where flooding will make things worse. All of this is public, free, and real-time.

No one is connecting these dots. Until now.


The Solution

RoadSense AI is a passive early-warning system that monitors public signals — Reddit posts, news articles, YouTube comments, and weather data — and uses a multi-agent AI pipeline to detect emerging road infrastructure damage before complaints are filed.

What it does:

  • Scrapes 4 public sources every hour — zero citizen effort required
  • Translates 10+ Indian languages to English automatically
  • Filters noise, sarcasm, and speculation using Amazon Nova Micro
  • Clusters related signals by geography (500m) and time (7 days)
  • Computes confidence scores (0–100) with explainable reasoning
  • Surfaces prioritized incidents on an Authority Dashboard

What it replaces:

  • ❌ Waiting for complaint volume to reach a threshold
  • ❌ Requiring citizens to install an app
  • ❌ Manual triage of social media by officials
  • ❌ Language barriers blocking non-English reports
  • ❌ Weather damage going undetected until inspection

Target Outcomes

MetricImpact
Complaint-to-response lag40–60% reduction
Early detection rate25–35% increase
Maintenance costsSignificant savings (proactive vs. reactive)
Signal classification accuracy≥ 85%

Architecture

Fully serverless and event-driven on AWS. No servers to manage, scales to zero when idle.

 ┌──────────────────────────────────────┐
│ PUBLIC SIGNALS │
│ Reddit · News RSS · YouTube · Weather│
└──────────────┬───────────────────────┘
│
EventBridge (hourly cron)
│
▼
┌─────────────────────┐
│ Scraper Lambda │
│ 4 scrapers in 1 fn │
└──────────┬──────────┘
│
┌────────────▼────────────┐
│ AWS Translate │
│ hi/ta/te/kn/bn → en │
│ + PII anonymisation │
│ + Deduplication │
└────────────┬─────────────┘
│
POST /ingest-signal (API Gateway)
│
▼
┌────────────────────────────────────┐
│ INFERENCE LAMBDA │
│ │
│ ┌─ Classification Agent (Nova Micro)│
│ │ Road-related? Damage type? │
│ │ │
│ ├─ Intent Agent (Nova Micro) │
│ │ Sarcasm? Speculation? Urgency? │
│ │ │
│ ├─ Correlation Agent (Titan V2) │
│ │ Geo + temporal clustering │
│ │ │
│ ├─ Inference Agent (scoring) │
│ │ Confidence 0–100 + severity │
│ │ │
│ └─ Explanation Agent (Nova Lite) │
│ Human-readable AI reasoning │
└──────────────┬─────────────────────┘
│
┌──────────────▼──────────────┐
│ DynamoDB │
│ Incidents + Signals │
└──────────────┬──────────────┘
│
API Gateway (REST)
│
▼
┌──────────────────────────────┐
│ Authority Dashboard │
│ React · S3 · CloudFront │
│ Map + Incidents + Feedback │
└──────────────────────────────┘

The AI Pipeline — 5 Agents, 3 Models

Every signal passes through a sequential agent pipeline. Each agent adds structured metadata. No agent makes a final decision alone.

#AgentModelInputOutputCost Control
1ClassificationNova MicroRaw English textis_road_related, damage_type, confidenceCheapest model; simple task
2Intent & ContextNova MicroClassified signalis_problem_report, urgency_level, context_typeFilters noise before expensive steps
3CorrelationTitan Embeddings V2All recent signalsSignal clusters (500m radius, 7-day window)Embeddings, not generation
4InferenceNone (deterministic)Signal clustersconfidence_score (0–100), severity_levelNo model call — pure math
5ExplanationNova LiteScored incidentsHuman-readable summaryCalled once per incident, not per signal

Plus a Feedback Agent (no model) that processes ground-truth validation from municipal authorities and recalibrates confidence scores.

Confidence Scoring (Inference Agent)

The confidence score is a weighted composite — no single signal can create a high-confidence incident alone:

FactorMax PointsWhy
Source diversity (Reddit + News + YouTube + Weather)30Multiple independent sources = higher trust
Signal count in cluster20More reports = more likely real
Urgency level consensus20Consistent urgency across signals
Classification confidence20How sure the AI is about damage type
Recency (time decay)10Recent signals weighted higher
Weather correlation10Rain + pothole reports = likely flooding
Total (clamped)100
  • Incident created when confidence > 60
  • Incident archived when confidence < 30
  • Confidence decays over time if no new signals arrive

Model Selection Rationale

Model$/1K tokensUsed ForWhy Not Something Else?
Amazon Nova Micro$0.000035/$0.00014Classification + Intent (per signal)Cheapest Nova model; no access approval needed; fast structured output
Amazon Nova Lite$0.00006/$0.00024Explanation (per incident)Better prose quality; only called once per incident, not per signal
Titan Embeddings V2$0.00002Correlation clusteringNative to Bedrock; no cross-service latency; optimized for similarity

Data Sources

The Scraper Lambda runs every hour via EventBridge and pulls from four free, public sources:

SourceLibraryWhat It CapturesSubreddits / Feeds
RedditPRAWCitizen complaints, photos, rantsr/bangalore, r/mumbai, r/delhi, r/chennai, r/hyderabad
News RSSfeedparserStructured reporting on road conditionsTimes of India, NDTV, The Hindu, Deccan Herald
YouTubegoogle-api-python-clientVideo titles + top comments on pothole/flooding videosSearch: pothole road damage india {city}
Weatherurllib (OpenWeatherMap API)Rainfall, flooding alerts — contextual correlationBangalore, Mumbai, Delhi, Chennai, Hyderabad

Search keywords: pothole road flood traffic damage gaddha sadak saalai rasta (English + Hindi + Tamil + Telugu)


Multilingual Processing

India has 22 official languages. Road complaints don't come in English.

"MG Road par bahut bada gaddha hai" → AWS Translate → "There is a large pothole on MG Road"
(Hindi) (auto-detect) (English — ready for AI agents)
  • AWS Translate auto-detects language and translates to English before any agent processing
  • Original text and detected language are preserved in metadata for audit
  • Supported: Hindi, Tamil, Telugu, Kannada, Bengali, Marathi, Malayalam, Gujarati, Punjabi, Urdu, and 60+ more
  • Free tier: 2M characters/month

Privacy & Ethics

RoadSense AI is designed to be trustworthy by default:

PrincipleImplementation
Public data onlyScrapes only publicly visible posts — no private messages, DMs, or login-required content
No individual profilingOutputs are aggregate geographic intelligence, never about specific people
PII anonymisationReddit usernames (u/), YouTube handles (@), emails, Indian phone numbers — all stripped before storage (pii.py)
DeduplicationContent-hash based dedup prevents double-counting from RSS re-serves and repeat scrapes (dedup.py)
Explainable AIEvery incident includes a Nova Lite-generated explanation of the evidence chain
Human-in-the-loopMunicipal authorities can validate or dismiss incidents via the Feedback Agent
Zero citizen effortNo app to install, no form to fill, no account to create

Data Models

Signal (click to expand)
{
"signal_id": "uuid",
"content": "English text (translated if needed)",
"original_content": "raw text in source language",
"translated_content": "English text from AWS Translate",
"detected_language": "hi",
"source": "reddit | news | youtube | weather",
"timestamp": "2026-02-01T10:00:00Z",
"location": {
"coordinates": { "lat": 12.9716, "lon": 77.5946 },
"accuracy_meters": 100,
"address": "MG Road, Bangalore"
},
"classification": {
"is_road_related": true,
"damage_type": "pothole | surface_wear | flooding | general",
"confidence": 0.92
},
"intent": {
"is_problem_report": true,
"urgency_level": "low | medium | high | critical",
"context_type": "direct_report | complaint | warning | news_coverage | ..."
}
}
Incident (click to expand)
{
"incident_id": "uuid",
"location": {
"center_coordinates": { "lat": 12.9716, "lon": 77.5946 },
"radius_meters": 500,
"address": "MG Road, Bangalore"
},
"damage_type": "pothole",
"confidence_score": 78,
"severity_level": "low | medium | high | critical",
"status": "active | monitoring | archived",
"explanation": "AI-generated summary referencing source types and languages",
"signal_ids": ["uuid1", "uuid2", "uuid3"],
"created_at": "2026-02-01T10:00:00Z",
"updated_at": "2026-02-02T14:30:00Z",
"confidence_history": [
{ "timestamp": "2026-02-01T10:00:00Z", "score": 65 },
{ "timestamp": "2026-02-02T14:30:00Z", "score": 78 }
]
}

API Reference

Full OpenAPI 3.0 spec: openapi.yaml

MethodEndpointDescription
POST/ingest-signalSubmit a signal for AI processing
GET/incidentsList all active incidents
GET/confidence/{id}Get confidence score + history for an incident
POST/feedbackSubmit ground-truth validation from authorities
GET/exportExport incidents as JSON (CSV planned)
curl examples (click to expand)
# Ingest a Hindi signal
curl -X POST https://api.roadsense.dev/ingest-signal \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "MG Road par bahut bada gaddha hai", "source": "reddit", "timestamp": "2026-02-01T10:00:00Z", "location": { "latitude": 12.9716, "longitude": 77.5946, "address": "MG Road, Bangalore" } }'# Get active incidents
curl https://api.roadsense.dev/incidents -H "x-api-key: $API_KEY"# Check confidence for a specific incident
curl https://api.roadsense.dev/confidence/incident-123 -H "x-api-key: $API_KEY"# Submit feedback from field inspection
curl -X POST https://api.roadsense.dev/feedback \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "incident_id": "incident-123", "feedback_value": "confirmed", "notes": "Pothole verified, ~2ft wide" }'# Export all incidents
curl https://api.roadsense.dev/export -H "x-api-key: $API_KEY"

Project Structure

roadsense-ai/
├── agents/
│ ├── classification_agent.py # Road-related? What damage type? (Nova Micro)
│ ├── intent_agent.py # Sarcasm/speculation filter + urgency (Nova Micro)
│ ├── correlation_agent.py # Geo+temporal clustering (Titan Embeddings V2)
│ ├── inference_agent.py # Confidence scoring (deterministic)
│ ├── explanation_agent.py # Human-readable summaries (Nova Lite)
│ └── feedback_agent.py # Ground-truth recalibration
├── scraper/
│ ├── reddit_scraper.py # PRAW — Indian city subreddits
│ ├── rss_scraper.py # feedparser — Times of India, NDTV, The Hindu, Deccan Herald
│ ├── youtube_scraper.py # YouTube Data API v3 — video titles + comments
│ └── weather_scraper.py # OpenWeatherMap — rainfall + flood alerts
├── data/
│ ├── generate_signals.py # Synthetic dataset generator
│ ├── signals.json # 1,050 signals (850 EN + 200 multilingual)
│ └── synthetic_incidents.json # 10 mock incidents for dashboard development
├── tests/
│ ├── test_properties.py # 50 property-based tests (Hypothesis)
│ ├── test_intent_agent.py # 45 unit tests — Intent & Context Agent
│ ├── test_inference_agent.py # 55 unit tests — Inference Agent
│ ├── test_api_integration.py # 30 integration tests (skip when API offline)
│ └── test_translate.py # 5 unit tests — AWS Translate wrapper
├── translate.py # AWS Translate wrapper — auto-detect + translate
├── pii.py # PII anonymisation (usernames, emails, phones)
├── dedup.py # Content-hash deduplication
├── location_normaliser.py # Normalise location formats across sources
├── locustfile.py # Load test config — 1,000 signals/hour target
├── openapi.yaml # OpenAPI 3.0 specification
└── .gitignore

Testing

185 tests across 5 test suites. Zero failures.

$ pytest tests/ -v --tb=short
155 passed, 0 failed, 30 skipped ✓

(30 skipped = API integration tests; dev API not yet deployed)

SuiteTestsWhat It Validates
Property-based (test_properties.py)5035 correctness properties via Hypothesis — confidence bounds, thresholds, severity ordering, decay monotonicity, scoring weights
Intent Agent (test_intent_agent.py)45Prompt construction, response parsing, sarcasm/speculation handling, weather pre-classification, fallback logic, Lambda handler
Inference Agent (test_inference_agent.py)55Confidence scoring, severity computation, incident creation/archival thresholds, time decay, cluster processing
API Integration (test_api_integration.py)30End-to-end ingestion, incident retrieval, confidence checks, export, error handling (auto-skipped when API unreachable)
Translate (test_translate.py)5Hindi/Tamil/Telugu translation, English passthrough, empty content handling

Run Tests

# All tests
pytest tests/ -v
# Property-based tests only
pytest tests/test_properties.py -v --hypothesis-seed=0
# Load test (Locust) — requires live API
locust -f locustfile.py --host=https://api.roadsense.dev
# Opens http://localhost:8089 — configure users and spawn rate# Headless: locust -f locustfile.py --host=https://api.roadsense.dev --users 10 --spawn-rate 2 --run-time 5m --headless

Synthetic Dataset

signals.json1,050 signals for development and testing:

CategoryCountPurpose
Road-related (genuine reports)350True positives — potholes, flooding, surface wear
Non-road (noise)250True negatives — traffic jams, politics, unrelated
Sarcastic100Adversarial — "Oh wow another beautiful pothole"
Ambiguous100Edge cases — could be road-related, unclear
Multilingual (hi/ta/te)200Hindi (69), Tamil (70), Telugu (61) — translation pipeline testing
Edge cases50Empty content, missing fields, extreme coordinates

Plus synthetic_incidents.json10 mock incidents across Bangalore locations (Electronic City, MG Road, Silk Board, Whitefield, Koramangala, Indiranagar) for the Authority Dashboard.


Technology Stack

LayerServiceDetail
ScrapingLambda + EventBridgeHourly cron; PRAW, feedparser, google-api-python-client, urllib
TranslationAWS TranslateAuto-detect → English; 10+ Indian languages; 2M chars/month free
IngestionAPI Gateway + LambdaREST endpoint; JSON validation; S3 raw storage
AI ReasoningAmazon BedrockAmazon Nova Micro, Amazon Nova Lite, Titan Embeddings V2
Vector StoreChromaDBSemantic similarity for signal correlation
StorageDynamoDB + S3Incident state in DynamoDB; raw signals archived in S3
APIAPI GatewayREST/JSON; API key auth; 5 endpoints
FrontendReact + S3 + CloudFrontMap view, incident cards, confidence gauges, feedback forms
Testingpytest + Hypothesis + LocustProperty-based, unit, integration, and load testing
CI/CDSAM CLIsam build && sam deploy --guided

Prerequisites

RequirementNotes
Python 3.11+Agent code + scrapers
Node.js 18+React dashboard
AWS CLIConfigured with IAM permissions for Lambda, Bedrock, Translate, DynamoDB, S3, CloudFront
Bedrock model accessNova Micro, Nova Lite, and Titan Embeddings V2 are available in us-east-1 without manual approval
Reddit API credentialsreddit.com/prefs/apps — free, instant
YouTube Data API v3 keyGoogle Cloud Console — free under 10K units/day
OpenWeatherMap API keyopenweathermap.org/api — free tier, 1000 calls/day

Local Setup

# Clone
git clone https://github.com/Sujith-RMD/RoadSense-AI.git
cd RoadSense-AI
# Python environment
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows# Install dependencies
pip install boto3 praw feedparser google-api-python-client chromadb
pip install pytest hypothesis locust # testing# Environment variablesexport REDDIT_CLIENT_ID=...
export REDDIT_CLIENT_SECRET=...
export YOUTUBE_API_KEY=...
export OPENWEATHERMAP_API_KEY=...
export AWS_DEFAULT_REGION=ap-south-1
# Run tests (no AWS credentials needed)
pytest tests/ -v

Deployment

# Backend — Lambda + API Gateway + DynamoDB
sam build
sam deploy --guided
# Frontend — React dashboardcd dashboard
npm install && npm run build
aws s3 sync ./build s3://<frontend-bucket> --delete
# CloudFront distribution URL → hackathon submission link

Team Iceberg

NameRoleOwns
⚙️SrikarAWS & BackendAPI Gateway, Lambda, S3, DynamoDB, CloudFront, Bedrock access, IAM, CloudWatch, bedrock_client.py
🤖DurvaAI Pipeline & DataAll 4 scrapers, AWS Translate integration, 5 AI agents, PII anonymisation, deduplication
🎨NishitaFrontend & UXFigma design system, Authority Dashboard (React), map view, incident detail, confidence gauge, feedback form
🧪SujithQA & Documentation1,050-signal synthetic dataset, 185 tests (property-based + unit + integration + load), OpenAPI spec, README, demo script

Glossary

TermDefinition
SignalAny unstructured text from a public source that may contain road condition information
IncidentA geo-located road infrastructure problem detected by the system, with a confidence score and AI explanation
Confidence Score0–100 composite metric reflecting the system's certainty about detected road damage
Source DiversityNumber of distinct source types (Reddit, news, YouTube, weather) contributing evidence — higher diversity = higher confidence
Temporal DensityConcentration of related signals within a time window — rapid signal bursts indicate active/worsening problems
Ground TruthPost-detection validation by municipal authorities — used to recalibrate confidence scoring
Authority DashboardReact web app for municipal officials to view, prioritize, and provide feedback on detected incidents

RoadSense AI — Team Iceberg · AI for Bharat Hackathon 2026
Detecting the potholes nobody reported — from the signals everyone already posted.

About

RoadSense AI monitors Reddit, news, YouTube, and weather data to detect road damage before complaints are filed. A multi agent AI pipeline translates 10+ Indian languages, filters sarcasm, clusters signals geographically, and surfaces prioritized incidents with confidence scores, zero citizen effort required.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

🛣️ RoadSense AI

Civic Signal Intelligence — Detecting road damage from public chatter, before anyone files a complaint.

Built by Team Iceberg · AI for Bharat Hackathon · February 2026


The Problem

India has 6.4 million km of roads. Over 150,000 people die in road accidents every year — a significant share caused by potholes, cave-ins, and waterlogged stretches that go unreported for weeks.

Municipal repair systems are complaint-driven. A pothole only gets fixed after enough citizens call a helpline, tweet at an official, or fill out an online form. By then, someone may have already been hurt.

The signals exist. Nobody is listening.

Every day, thousands of Indians post about broken roads on Reddit, complain in YouTube comments, and get covered by local news — in Hindi, Tamil, Telugu, Kannada, and a dozen other languages. Weather data predicts exactly where flooding will make things worse. All of this is public, free, and real-time.

No one is connecting these dots. Until now.


The Solution

RoadSense AI is a passive early-warning system that monitors public signals — Reddit posts, news articles, YouTube comments, and weather data — and uses a multi-agent AI pipeline to detect emerging road infrastructure damage before complaints are filed.

What it does:

  • Scrapes 4 public sources every hour — zero citizen effort required
  • Translates 10+ Indian languages to English automatically
  • Filters noise, sarcasm, and speculation using Amazon Nova Micro
  • Clusters related signals by geography (500m) and time (7 days)
  • Computes confidence scores (0–100) with explainable reasoning
  • Surfaces prioritized incidents on an Authority Dashboard

What it replaces:

  • ❌ Waiting for complaint volume to reach a threshold
  • ❌ Requiring citizens to install an app
  • ❌ Manual triage of social media by officials
  • ❌ Language barriers blocking non-English reports
  • ❌ Weather damage going undetected until inspection

Target Outcomes

MetricImpact
Complaint-to-response lag40–60% reduction
Early detection rate25–35% increase
Maintenance costsSignificant savings (proactive vs. reactive)
Signal classification accuracy≥ 85%

Architecture

Fully serverless and event-driven on AWS. No servers to manage, scales to zero when idle.

 ┌──────────────────────────────────────┐
│ PUBLIC SIGNALS │
│ Reddit · News RSS · YouTube · Weather│
└──────────────┬───────────────────────┘
│
EventBridge (hourly cron)
│
▼
┌─────────────────────┐
│ Scraper Lambda │
│ 4 scrapers in 1 fn │
└──────────┬──────────┘
│
┌────────────▼────────────┐
│ AWS Translate │
│ hi/ta/te/kn/bn → en │
│ + PII anonymisation │
│ + Deduplication │
└────────────┬─────────────┘
│
POST /ingest-signal (API Gateway)
│
▼
┌────────────────────────────────────┐
│ INFERENCE LAMBDA │
│ │
│ ┌─ Classification Agent (Nova Micro)│
│ │ Road-related? Damage type? │
│ │ │
│ ├─ Intent Agent (Nova Micro) │
│ │ Sarcasm? Speculation? Urgency? │
│ │ │
│ ├─ Correlation Agent (Titan V2) │
│ │ Geo + temporal clustering │
│ │ │
│ ├─ Inference Agent (scoring) │
│ │ Confidence 0–100 + severity │
│ │ │
│ └─ Explanation Agent (Nova Lite) │
│ Human-readable AI reasoning │
└──────────────┬─────────────────────┘
│
┌──────────────▼──────────────┐
│ DynamoDB │
│ Incidents + Signals │
└──────────────┬──────────────┘
│
API Gateway (REST)
│
▼
┌──────────────────────────────┐
│ Authority Dashboard │
│ React · S3 · CloudFront │
│ Map + Incidents + Feedback │
└──────────────────────────────┘

The AI Pipeline — 5 Agents, 3 Models

Every signal passes through a sequential agent pipeline. Each agent adds structured metadata. No agent makes a final decision alone.

#AgentModelInputOutputCost Control
1ClassificationNova MicroRaw English textis_road_related, damage_type, confidenceCheapest model; simple task
2Intent & ContextNova MicroClassified signalis_problem_report, urgency_level, context_typeFilters noise before expensive steps
3CorrelationTitan Embeddings V2All recent signalsSignal clusters (500m radius, 7-day window)Embeddings, not generation
4InferenceNone (deterministic)Signal clustersconfidence_score (0–100), severity_levelNo model call — pure math
5ExplanationNova LiteScored incidentsHuman-readable summaryCalled once per incident, not per signal

Plus a Feedback Agent (no model) that processes ground-truth validation from municipal authorities and recalibrates confidence scores.

Confidence Scoring (Inference Agent)

The confidence score is a weighted composite — no single signal can create a high-confidence incident alone:

FactorMax PointsWhy
Source diversity (Reddit + News + YouTube + Weather)30Multiple independent sources = higher trust
Signal count in cluster20More reports = more likely real
Urgency level consensus20Consistent urgency across signals
Classification confidence20How sure the AI is about damage type
Recency (time decay)10Recent signals weighted higher
Weather correlation10Rain + pothole reports = likely flooding
Total (clamped)100
  • Incident created when confidence > 60
  • Incident archived when confidence < 30
  • Confidence decays over time if no new signals arrive

Model Selection Rationale

Model$/1K tokensUsed ForWhy Not Something Else?
Amazon Nova Micro$0.000035/$0.00014Classification + Intent (per signal)Cheapest Nova model; no access approval needed; fast structured output
Amazon Nova Lite$0.00006/$0.00024Explanation (per incident)Better prose quality; only called once per incident, not per signal
Titan Embeddings V2$0.00002Correlation clusteringNative to Bedrock; no cross-service latency; optimized for similarity

Data Sources

The Scraper Lambda runs every hour via EventBridge and pulls from four free, public sources:

SourceLibraryWhat It CapturesSubreddits / Feeds
RedditPRAWCitizen complaints, photos, rantsr/bangalore, r/mumbai, r/delhi, r/chennai, r/hyderabad
News RSSfeedparserStructured reporting on road conditionsTimes of India, NDTV, The Hindu, Deccan Herald
YouTubegoogle-api-python-clientVideo titles + top comments on pothole/flooding videosSearch: pothole road damage india {city}
Weatherurllib (OpenWeatherMap API)Rainfall, flooding alerts — contextual correlationBangalore, Mumbai, Delhi, Chennai, Hyderabad

Search keywords: pothole road flood traffic damage gaddha sadak saalai rasta (English + Hindi + Tamil + Telugu)


Multilingual Processing

India has 22 official languages. Road complaints don't come in English.

"MG Road par bahut bada gaddha hai" → AWS Translate → "There is a large pothole on MG Road"
(Hindi) (auto-detect) (English — ready for AI agents)
  • AWS Translate auto-detects language and translates to English before any agent processing
  • Original text and detected language are preserved in metadata for audit
  • Supported: Hindi, Tamil, Telugu, Kannada, Bengali, Marathi, Malayalam, Gujarati, Punjabi, Urdu, and 60+ more
  • Free tier: 2M characters/month

Privacy & Ethics

RoadSense AI is designed to be trustworthy by default:

PrincipleImplementation
Public data onlyScrapes only publicly visible posts — no private messages, DMs, or login-required content
No individual profilingOutputs are aggregate geographic intelligence, never about specific people
PII anonymisationReddit usernames (u/), YouTube handles (@), emails, Indian phone numbers — all stripped before storage (pii.py)
DeduplicationContent-hash based dedup prevents double-counting from RSS re-serves and repeat scrapes (dedup.py)
Explainable AIEvery incident includes a Nova Lite-generated explanation of the evidence chain
Human-in-the-loopMunicipal authorities can validate or dismiss incidents via the Feedback Agent
Zero citizen effortNo app to install, no form to fill, no account to create

Data Models

Signal (click to expand)
{
"signal_id": "uuid",
"content": "English text (translated if needed)",
"original_content": "raw text in source language",
"translated_content": "English text from AWS Translate",
"detected_language": "hi",
"source": "reddit | news | youtube | weather",
"timestamp": "2026-02-01T10:00:00Z",
"location": {
"coordinates": { "lat": 12.9716, "lon": 77.5946 },
"accuracy_meters": 100,
"address": "MG Road, Bangalore"
},
"classification": {
"is_road_related": true,
"damage_type": "pothole | surface_wear | flooding | general",
"confidence": 0.92
},
"intent": {
"is_problem_report": true,
"urgency_level": "low | medium | high | critical",
"context_type": "direct_report | complaint | warning | news_coverage | ..."
}
}
Incident (click to expand)
{
"incident_id": "uuid",
"location": {
"center_coordinates": { "lat": 12.9716, "lon": 77.5946 },
"radius_meters": 500,
"address": "MG Road, Bangalore"
},
"damage_type": "pothole",
"confidence_score": 78,
"severity_level": "low | medium | high | critical",
"status": "active | monitoring | archived",
"explanation": "AI-generated summary referencing source types and languages",
"signal_ids": ["uuid1", "uuid2", "uuid3"],
"created_at": "2026-02-01T10:00:00Z",
"updated_at": "2026-02-02T14:30:00Z",
"confidence_history": [
{ "timestamp": "2026-02-01T10:00:00Z", "score": 65 },
{ "timestamp": "2026-02-02T14:30:00Z", "score": 78 }
]
}

API Reference

Full OpenAPI 3.0 spec: openapi.yaml

MethodEndpointDescription
POST/ingest-signalSubmit a signal for AI processing
GET/incidentsList all active incidents
GET/confidence/{id}Get confidence score + history for an incident
POST/feedbackSubmit ground-truth validation from authorities
GET/exportExport incidents as JSON (CSV planned)
curl examples (click to expand)
# Ingest a Hindi signal
curl -X POST https://api.roadsense.dev/ingest-signal \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "MG Road par bahut bada gaddha hai", "source": "reddit", "timestamp": "2026-02-01T10:00:00Z", "location": { "latitude": 12.9716, "longitude": 77.5946, "address": "MG Road, Bangalore" } }'# Get active incidents
curl https://api.roadsense.dev/incidents -H "x-api-key: $API_KEY"# Check confidence for a specific incident
curl https://api.roadsense.dev/confidence/incident-123 -H "x-api-key: $API_KEY"# Submit feedback from field inspection
curl -X POST https://api.roadsense.dev/feedback \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "incident_id": "incident-123", "feedback_value": "confirmed", "notes": "Pothole verified, ~2ft wide" }'# Export all incidents
curl https://api.roadsense.dev/export -H "x-api-key: $API_KEY"

Project Structure

roadsense-ai/
├── agents/
│ ├── classification_agent.py # Road-related? What damage type? (Nova Micro)
│ ├── intent_agent.py # Sarcasm/speculation filter + urgency (Nova Micro)
│ ├── correlation_agent.py # Geo+temporal clustering (Titan Embeddings V2)
│ ├── inference_agent.py # Confidence scoring (deterministic)
│ ├── explanation_agent.py # Human-readable summaries (Nova Lite)
│ └── feedback_agent.py # Ground-truth recalibration
├── scraper/
│ ├── reddit_scraper.py # PRAW — Indian city subreddits
│ ├── rss_scraper.py # feedparser — Times of India, NDTV, The Hindu, Deccan Herald
│ ├── youtube_scraper.py # YouTube Data API v3 — video titles + comments
│ └── weather_scraper.py # OpenWeatherMap — rainfall + flood alerts
├── data/
│ ├── generate_signals.py # Synthetic dataset generator
│ ├── signals.json # 1,050 signals (850 EN + 200 multilingual)
│ └── synthetic_incidents.json # 10 mock incidents for dashboard development
├── tests/
│ ├── test_properties.py # 50 property-based tests (Hypothesis)
│ ├── test_intent_agent.py # 45 unit tests — Intent & Context Agent
│ ├── test_inference_agent.py # 55 unit tests — Inference Agent
│ ├── test_api_integration.py # 30 integration tests (skip when API offline)
│ └── test_translate.py # 5 unit tests — AWS Translate wrapper
├── translate.py # AWS Translate wrapper — auto-detect + translate
├── pii.py # PII anonymisation (usernames, emails, phones)
├── dedup.py # Content-hash deduplication
├── location_normaliser.py # Normalise location formats across sources
├── locustfile.py # Load test config — 1,000 signals/hour target
├── openapi.yaml # OpenAPI 3.0 specification
└── .gitignore

Testing

185 tests across 5 test suites. Zero failures.

$ pytest tests/ -v --tb=short
155 passed, 0 failed, 30 skipped ✓

(30 skipped = API integration tests; dev API not yet deployed)

SuiteTestsWhat It Validates
Property-based (test_properties.py)5035 correctness properties via Hypothesis — confidence bounds, thresholds, severity ordering, decay monotonicity, scoring weights
Intent Agent (test_intent_agent.py)45Prompt construction, response parsing, sarcasm/speculation handling, weather pre-classification, fallback logic, Lambda handler
Inference Agent (test_inference_agent.py)55Confidence scoring, severity computation, incident creation/archival thresholds, time decay, cluster processing
API Integration (test_api_integration.py)30End-to-end ingestion, incident retrieval, confidence checks, export, error handling (auto-skipped when API unreachable)
Translate (test_translate.py)5Hindi/Tamil/Telugu translation, English passthrough, empty content handling

Run Tests

# All tests
pytest tests/ -v
# Property-based tests only
pytest tests/test_properties.py -v --hypothesis-seed=0
# Load test (Locust) — requires live API
locust -f locustfile.py --host=https://api.roadsense.dev
# Opens http://localhost:8089 — configure users and spawn rate# Headless: locust -f locustfile.py --host=https://api.roadsense.dev --users 10 --spawn-rate 2 --run-time 5m --headless

Synthetic Dataset

signals.json1,050 signals for development and testing:

CategoryCountPurpose
Road-related (genuine reports)350True positives — potholes, flooding, surface wear
Non-road (noise)250True negatives — traffic jams, politics, unrelated
Sarcastic100Adversarial — "Oh wow another beautiful pothole"
Ambiguous100Edge cases — could be road-related, unclear
Multilingual (hi/ta/te)200Hindi (69), Tamil (70), Telugu (61) — translation pipeline testing
Edge cases50Empty content, missing fields, extreme coordinates

Plus synthetic_incidents.json10 mock incidents across Bangalore locations (Electronic City, MG Road, Silk Board, Whitefield, Koramangala, Indiranagar) for the Authority Dashboard.


Technology Stack

LayerServiceDetail
ScrapingLambda + EventBridgeHourly cron; PRAW, feedparser, google-api-python-client, urllib
TranslationAWS TranslateAuto-detect → English; 10+ Indian languages; 2M chars/month free
IngestionAPI Gateway + LambdaREST endpoint; JSON validation; S3 raw storage
AI ReasoningAmazon BedrockAmazon Nova Micro, Amazon Nova Lite, Titan Embeddings V2
Vector StoreChromaDBSemantic similarity for signal correlation
StorageDynamoDB + S3Incident state in DynamoDB; raw signals archived in S3
APIAPI GatewayREST/JSON; API key auth; 5 endpoints
FrontendReact + S3 + CloudFrontMap view, incident cards, confidence gauges, feedback forms
Testingpytest + Hypothesis + LocustProperty-based, unit, integration, and load testing
CI/CDSAM CLIsam build && sam deploy --guided

Prerequisites

RequirementNotes
Python 3.11+Agent code + scrapers
Node.js 18+React dashboard
AWS CLIConfigured with IAM permissions for Lambda, Bedrock, Translate, DynamoDB, S3, CloudFront
Bedrock model accessNova Micro, Nova Lite, and Titan Embeddings V2 are available in us-east-1 without manual approval
Reddit API credentialsreddit.com/prefs/apps — free, instant
YouTube Data API v3 keyGoogle Cloud Console — free under 10K units/day
OpenWeatherMap API keyopenweathermap.org/api — free tier, 1000 calls/day

Local Setup

# Clone
git clone https://github.com/Sujith-RMD/RoadSense-AI.git
cd RoadSense-AI
# Python environment
python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows# Install dependencies
pip install boto3 praw feedparser google-api-python-client chromadb
pip install pytest hypothesis locust # testing# Environment variablesexport REDDIT_CLIENT_ID=...
export REDDIT_CLIENT_SECRET=...
export YOUTUBE_API_KEY=...
export OPENWEATHERMAP_API_KEY=...
export AWS_DEFAULT_REGION=ap-south-1
# Run tests (no AWS credentials needed)
pytest tests/ -v

Deployment

# Backend — Lambda + API Gateway + DynamoDB
sam build
sam deploy --guided
# Frontend — React dashboardcd dashboard
npm install && npm run build
aws s3 sync ./build s3://<frontend-bucket> --delete
# CloudFront distribution URL → hackathon submission link

Team Iceberg

NameRoleOwns
⚙️SrikarAWS & BackendAPI Gateway, Lambda, S3, DynamoDB, CloudFront, Bedrock access, IAM, CloudWatch, bedrock_client.py
🤖DurvaAI Pipeline & DataAll 4 scrapers, AWS Translate integration, 5 AI agents, PII anonymisation, deduplication
🎨NishitaFrontend & UXFigma design system, Authority Dashboard (React), map view, incident detail, confidence gauge, feedback form
🧪SujithQA & Documentation1,050-signal synthetic dataset, 185 tests (property-based + unit + integration + load), OpenAPI spec, README, demo script

Glossary

TermDefinition
SignalAny unstructured text from a public source that may contain road condition information
IncidentA geo-located road infrastructure problem detected by the system, with a confidence score and AI explanation
Confidence Score0–100 composite metric reflecting the system's certainty about detected road damage
Source DiversityNumber of distinct source types (Reddit, news, YouTube, weather) contributing evidence — higher diversity = higher confidence
Temporal DensityConcentration of related signals within a time window — rapid signal bursts indicate active/worsening problems
Ground TruthPost-detection validation by municipal authorities — used to recalibrate confidence scoring
Authority DashboardReact web app for municipal officials to view, prioritize, and provide feedback on detected incidents

RoadSense AI — Team Iceberg · AI for Bharat Hackathon 2026
Detecting the potholes nobody reported — from the signals everyone already posted.

About

RoadSense AI monitors Reddit, news, YouTube, and weather data to detect road damage before complaints are filed. A multi agent AI pipeline translates 10+ Indian languages, filters sarcasm, clusters signals geographically, and surfaces prioritized incidents with confidence scores, zero citizen effort required.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages