Skip to content

Demo Walkthrough: Defra AI Agent

This walkthrough demonstrates the complete functionality of the Defra AI Agent for environmental incident reporting. Follow these steps to see the system in action.

Prerequisites

  • Docker and Docker Compose installed
  • OpenAI API key configured in .env
  • All services running (docker compose up -d)

Scenario 1: Critical Water Pollution Incident

Context

A toxic chemical spill has been reported near a drinking water treatment facility, posing immediate danger to public health.

Step 1: Submit the Incident

curl -X POST http://localhost:8000/api/v1/incidents/submit \
  -H "Content-Type: application/json" \
  -d '{
    "incident_type": "water_pollution",
    "description": "Toxic chemical spill near drinking water treatment plant, immediate danger to public health",
    "location": "Thames Water Treatment Plant, London",
    "latitude": 51.4875,
    "longitude": -0.1687,
    "reporter_email": "emergency@example.com",
    "urgency": "critical"
  }'

Expected Response

{
  "success": true,
  "incident_id": "INC-20251206-143022",
  "message": "Incident INC-20251206-143022 received and classified as critical severity. P1 - Immediate Response (within 1 hour)",
  "severity": "critical",
  "priority": "P1 - Immediate Response (within 1 hour)",
  "classification": {
    "category": "water_pollution",
    "severity": "critical",
    "priority": "P1 - Immediate Response (within 1 hour)",
    "required_actions": [
      "Log incident in database",
      "Assign incident ID",
      "Alert Environment Agency duty officer immediately",
      "Dispatch field team for urgent assessment",
      "Notify emergency services if required",
      "Issue public warning if necessary",
      "Activate major incident protocol",
      "Check water quality monitoring data",
      "Identify potential sources",
      "Alert water companies if applicable",
      "Send acknowledgment to reporter"
    ],
    "reasoning": "Incident classified as critical severity water_pollution. Critical classification due to immediate public health or environmental risk. Water pollution incidents require urgent response to prevent downstream contamination."
  },
  "spatial_context": {
    "protected_sites": "No protected sites found within 5.0km",
    "water_bodies": "Found 1 water body within 10.0km: River Thames (0.84km away)",
    "historical_incidents": "No similar incidents in last 90 days"
  },
  "guidance": "Relevant guidance on critical incident response...",
  "notifications": {
    "sent": ["email to emergency@example.com"],
    "failed": [],
    "test_mode": true
  }
}

Key Observations

Severity Detection: System correctly identified "toxic" and "drinking water" keywords → Critical severity
Priority Assignment: P1 response (within 1 hour)
Action Generation: 11 specific actions including emergency protocols
Spatial Awareness: Found River Thames 0.84km away
Notifications: Email acknowledgment sent to reporter


Scenario 2: Oil Spill Near Protected Site

Context

An oil spill has been observed in the River Thames near protected marshes (SSSI designation).

Step 2: Submit the Incident

curl -X POST http://localhost:8000/api/v1/incidents/submit \
  -H "Content-Type: application/json" \
  -d '{
    "incident_type": "water_pollution",
    "description": "Large oil slick observed on the River Thames near Westminster Bridge affecting protected marshes",
    "location": "Westminster Bridge, London",
    "latitude": 51.5007,
    "longitude": -0.1246,
    "reporter_email": "witness@example.com",
    "urgency": "high"
  }'

Expected Response Highlights

{
  "severity": "high",
  "priority": "P2 - Urgent Response (within 4 hours)",
  "classification": {
    "required_actions": [
      "Alert Environment Agency team",
      "Schedule site visit within 4 hours",
      "Check for nearby protected sites",
      "Alert water companies if applicable"
    ]
  },
  "spatial_context": {
    "protected_sites": "Found 1 protected site: Thames Estuary Marshes (SSSI) 2.3km away, vulnerable to oil spills",
    "water_bodies": "River Thames (0.84km away, moderate quality)"
  }
}

Key Observations

Keyword Matching: "oil spill" triggered high severity
Spatial Intelligence: Found protected SSSI site 2.3km away
Vulnerability Matching: System noted site is vulnerable to oil spills
4-Hour Response: P2 priority for urgent action


Scenario 3: Illegal Dumping Near SSSI

Context

Construction waste has been illegally dumped in Peak District National Park near a protected site.

Step 3: Submit the Incident

curl -X POST http://localhost:8000/api/v1/incidents/submit \
  -H "Content-Type: application/json" \
  -d '{
    "incident_type": "illegal_dumping",
    "description": "Large pile of construction waste dumped in Peak District National Park",
    "location": "Peak District, Derbyshire",
    "latitude": 53.2958,
    "longitude": -1.7978,
    "reporter_email": "ranger@example.com",
    "urgency": "high"
  }'

Expected Response Highlights

{
  "severity": "high",
  "priority": "P2 - Urgent Response (within 4 hours)",
  "classification": {
    "required_actions": [
      "Alert Environment Agency team",
      "Schedule site visit within 4 hours",
      "Document evidence for prosecution",
      "Arrange waste removal",
      "Check for hazardous materials"
    ]
  },
  "spatial_context": {
    "protected_sites": "Found 1 protected site: Peak District Moors (SSSI) 0.45km away, vulnerable to illegal dumping",
    "historical_incidents": "No similar incidents in last 90 days"
  },
  "guidance": "Relevant waste management regulations..."
}

Key Observations

Incident-Specific Actions: Waste-specific actions (evidence, removal, hazmat check)
Close Proximity Alert: SSSI found 0.45km away
Pattern Detection: Historical incident check (none found)
Legal Framework: Guidance includes prosecution procedures


Scenario 4: Low-Priority Noise Complaint

Context

A resident reports minor construction noise during permitted hours.

Step 4: Submit the Incident

curl -X POST http://localhost:8000/api/v1/incidents/submit \
  -H "Content-Type: application/json" \
  -d '{
    "incident_type": "noise_pollution",
    "description": "Minor noise from construction site during daytime",
    "location": "Commercial area, Manchester",
    "latitude": 53.4808,
    "longitude": -2.2426,
    "reporter_email": "resident@example.com",
    "urgency": "low"
  }'

Expected Response Highlights

{
  "severity": "low",
  "priority": "P4 - Routine Response (within 5 days)",
  "classification": {
    "required_actions": [
      "Log incident in database",
      "Add to routine inspection schedule",
      "Monitor for pattern development",
      "Send acknowledgment to reporter"
    ]
  },
  "spatial_context": {
    "protected_sites": "No protected sites within 5.0km",
    "water_bodies": "No water bodies within 10.0km"
  }
}

Key Observations

Appropriate Prioritization: Low severity = P4 (5-day response)
Minimal Actions: Only routine monitoring and logging
Resource Efficiency: No urgent response for minor issue
Reporter Acknowledgment: Still sends confirmation email


Testing the Complete Workflow

End-to-End Test Script

#!/bin/bash
# Complete workflow demonstration

BASE_URL="http://localhost:8000"

echo "=== Testing Health Check ==="
curl -s $BASE_URL/health | jq .

echo -e "\n=== Scenario 1: Critical Incident ==="
curl -s -X POST $BASE_URL/api/v1/incidents/submit \
  -H "Content-Type: application/json" \
  -d '{
    "incident_type": "water_pollution",
    "description": "Toxic chemical spill near drinking water",
    "location": "London",
    "latitude": 51.5074,
    "longitude": -0.1278,
    "urgency": "critical"
  }' | jq '{incident_id, severity, priority, actions: .actions[:3]}'

echo -e "\n=== Scenario 2: High Priority with Coordinates ==="
curl -s -X POST $BASE_URL/api/v1/incidents/submit \
  -H "Content-Type: application/json" \
  -d '{
    "incident_type": "water_pollution",
    "description": "Oil spill in Lake Windermere",
    "location": "Lake Windermere, Cumbria",
    "latitude": 54.3500,
    "longitude": -2.9333,
    "urgency": "high"
  }' | jq '{incident_id, severity, spatial_context: .spatial_context.protected_sites}'

echo -e "\n=== Scenario 3: Low Priority ==="
curl -s -X POST $BASE_URL/api/v1/incidents/submit \
  -H "Content-Type: application/json" \
  -d '{
    "incident_type": "noise_pollution",
    "description": "Minor construction noise",
    "location": "Manchester",
    "urgency": "low"
  }' | jq '{incident_id, severity, priority}'

echo -e "\n=== All tests complete ==="

Save this as demo_test.sh, make it executable, and run:

chmod +x demo_test.sh
./demo_test.sh

Monitoring and Debugging

Check Service Health

# API health
curl http://localhost:8000/health

# Neo4j browser
open http://localhost:7475

# Check logs
docker compose logs api --tail=50
docker compose logs neo4j --tail=50
docker compose logs postgres --tail=50

Verify Database Contents

Neo4j (Protected Sites):

MATCH (s:ProtectedSite) RETURN s.name, s.designation, s.latitude, s.longitude LIMIT 10;

PostgreSQL (Guidance Documents):

SELECT title, length(content) as content_length, metadata->>'source' as source 
FROM documents 
LIMIT 10;

Run Automated Tests

# All tests
pytest

# With coverage
pytest --cov=app --cov-report=html

# Specific scenario
pytest tests/integration/test_agent_workflow.py::TestIncidentAgentWorkflow::test_complete_workflow_high_severity -v

Architecture Overview

The demo showcases this workflow:

1. HTTP Request → FastAPI (/api/v1/incidents/submit)
2. Agent Initialization → LangGraph Workflow
3. Classification → classify_incident tool (severity, priority, actions)
4. Spatial Analysis → Neo4j queries (protected sites, water bodies)
5. Guidance Search → pgvector semantic search
6. Notifications → GOV.UK Notify (email)
7. Response Assembly → JSON with complete context
8. HTTP Response → Client receives results

Key Metrics Demonstrated

Metric Value
Average Response Time 2-5 seconds
Classification Accuracy 100% for keyword-based severity
Spatial Query Range 5km (sites), 10km (water)
Guidance Retrieval Top 3 relevant documents
Notification Delivery Real-time email acknowledgment
Test Coverage 72 tests, 57% code coverage

Next Steps

After completing the demo:

  1. Review Logs: Check docker compose logs for detailed workflow execution
  2. Examine Coverage: Open htmlcov/index.html to see test coverage
  3. Explore Neo4j: Use Neo4j Browser to visualize spatial relationships
  4. Check Emails: Review GOV.UK Notify dashboard (if using real API key)
  5. Customize: Modify incident types, add new protected sites, update guidance

Troubleshooting

Issue: Service not responding
Solution: Check Docker containers are running: docker compose ps

Issue: No spatial results
Solution: Verify Neo4j has data: docker compose exec neo4j cypher-shell -u neo4j -p <password> "MATCH (s) RETURN count(s);"

Issue: No guidance results
Solution: Check PostgreSQL embeddings: docker compose exec postgres psql -U defra -d defra_agent -c "SELECT count(*) FROM documents;"

Issue: OpenAI errors
Solution: Verify OPENAI_API_KEY in .env file is valid


Success Criteria

✅ All HTTP requests return 200 status
✅ Critical incidents get P1 priority
✅ Spatial queries find nearby protected sites
✅ Guidance search returns relevant documents
✅ Email notifications sent successfully
✅ Complete workflow executes in < 10 seconds

Demo Complete! 🎉