A sophisticated energy grid simulator featuring autonomous agents and Retrieval-Augmented Generation (RAG) to provide real-time, knowledge-grounded explanations of grid operations.
This project demonstrates how AI agents can intelligently manage an energy grid while leveraging domain-specific knowledge from historical documents and regulatory standards. The system combines:
- Grid Simulation: 24-hour realistic energy grid with multiple generator types
- Autonomous Agents: Grid operators and renewable aggregators that make real-time decisions
- RAG System: Contextual explanations grounded in ENTSO-E standards and grid codes
- Interactive Dashboard: Live visualization of grid state and AI explanations
Energy Grid Simulation
βββ Simulation Engine (simulation/)
β βββ grid.py - Main grid simulation loop
β βββ agents.py - Grid operator and renewable aggregator agents
β βββ generators.py - Wind, solar, thermal, hydro generator models
β βββ metrics.py - Grid state computation
βββ RAG System (rag/)
β βββ advisor.py - LLM-powered advisor with caching
β βββ retriever.py - Vector DB retrieval (ChromaDB)
β βββ ingest.py - Document ingestion pipeline
β βββ db/ - Persistent vector embeddings
βββ Dashboard (dashboard/)
β βββ app.py - Dash web interface
βββ Data (data/)
βββ load_profile.csv - Regional load patterns
βββ pdfs/ - Grid operation standards
- Python 3.8+
- pip or conda
- Clone/download this repository
- Install dependencies:
pip install -r requirements.txt- Set up environment variables:
export ANTHROPIC_API_KEY='your-key-here'Full Day Simulation + Dashboard:
python main.pyThis will:
- Run a 24-hour grid simulation (288 steps Γ 5 minutes)
- Generate AI explanations for critical events
- Launch a web dashboard at
http://127.0.0.1:8050
Quick Test:
python -c "
from simulation.grid import GridSimulation
sim = GridSimulation()
sim.run(steps=24) # 2 hours
sim.summary()
"The interactive dashboard displays:
- Grid Advisor Panel: Latest grid event with AI explanation
- Supply vs Demand: Real-time generation vs. load
- Generation Mix: Stacked area chart of renewable and thermal
- Grid Stability: Frequency tracking (target 50 Hz)
- Renewable Share: Percentage of clean energy
- Action Log: Complete record of agent actions with explanations
-
Generator Step: Each generator updates output based on time of day
- Solar: peaks at noon
- Wind: variable with ~50% capacity factor
- Thermal: controllable, ramping constraints
- Hydro: fast-response, energy-limited
-
Load Profile: Regional demand varies by hour (CSV-based)
-
Grid State Computation:
- Total generation vs. total load
- Frequency calculation (simplified physics model)
- Renewable share percentage
-
Agent Decision Making:
- Grid Operator: Activates thermal/hydro for supply shortfalls
- Renewable Aggregator: Curtails excess renewables
-
RAG Advisor: Explains significant actions using:
- Vector retrieval from ENTSO-E standards
- Claude LLM for natural language synthesis
- Caching to avoid duplicate LLM calls
The advisor uses a two-stage process:
Stage 1: Retrieval
- Query: "frequency deviation hydro response" (for example)
- Vector search against embedded grid standards
- Returns 3 most relevant document chunks
Stage 2: Generation
- Claude synthesizes explanation using:
- Current grid state (frequency, mismatch)
- Agent action that was taken
- Retrieved regulatory context
- German technical terminology
Example output:
"The GridOperator increased Hydro output by 30 MW to restore grid frequency
after it dropped below 49.95 Hz. Per ENTSO-E Article 3.1, PrimΓ€rregelleistung
must activate within 30 seconds when frequency deviates. Without this response,
frequency would continue falling toward the 49.2 Hz protection limit."
main.py- Entry point (simulation + dashboard)requirements.txt- Python dependenciessimulation/generators.py- Generator models (wind, solar, thermal, hydro)simulation/agents.py- Grid operator and renewable aggregator logicsimulation/grid.py- Main simulation loop and GridSimulation classrag/advisor.py- LLM advisor with cachingrag/retriever.py- Vector DB retrieval with singleton patternrag/ingest.py- Document ingestion (handles missing PDFs gracefully)dashboard/app.py- Dash application
data/load_profile.csv- Hourly demand patterns (0-23 hours)data/pdfs/- Grid standard documents (optional)rag/db/- ChromaDB persistent storage
Modify build_grid() to change:
- Generator capacity (MW)
- Number of generators
- Cost per MWh
- Target output levels
RESERVE_THRESHOLD_HZ: When to activate hydro (default: 49.95 Hz)EMERGENCY_THRESHOLD_HZ: Load shedding trigger (default: 49.2 Hz)RESERVE_DEADBAND_MW: Minimum mismatch to trigger actions (default: -5 MW)
n_results: Number of document chunks to retrieve (default: 3)max_tokens: LLM response length (default: 300)- Cache behavior: Explanation caching reduces API calls
The retriever uses a singleton pattern to avoid reloading the embedding model:
_model = None # Global cache
def _get_model():
global _model
if _model is None:
_model = SentenceTransformer("all-MiniLM-L6-v2")
return _modelAdvisor caches explanations by action type to reduce LLM calls during repeated actions.
- Missing PDFs: Falls back to synthetic training data
- Missing API Key: Generates plausible explanations based on domain rules
- Network errors: Simulation continues, log entries are recorded
# Test imports
python -c "from simulation.grid import GridSimulation; print('OK')"
# Test RAG retrieval
python -c "from rag.retriever import retrieve; print(len(retrieve('frequency')))"
# Test ingestion
python rag/ingest.pyThis simulator is based on German/European grid standards:
- ENTSO-E: Network Code for Requirements for Grid Connection
- BNA: Bundesnetzagentur Monitoring Reports
- TenneT: German TSO grid code
Key concepts:
- Frequency target: 50 Hz Β±0.2 Hz (normal operation)
- PrimΓ€rregelleistung (Primary Reserve): Activated when f β 50 Hz
- Einspeisemanagement (Feed-in Management): Renewable curtailment
- Lastabwurf (Load Shedding): Emergency frequency support
To extend this project:
- New Generator Types: Add class to
generators.py, updatebuild_grid() - New Agents: Inherit from agent pattern, implement
evaluate()method - Grid Metrics: Extend
GridStateclass andcompute_derived() - Dashboard Widgets: Add to
dashboard/app.pyusing Dash components
This project is for educational and research purposes.
This project demonstrates:
- Multi-agent systems: Coordinated decision-making
- Retrieval-Augmented Generation: Grounding AI outputs in domain knowledge
- Real-time visualization: Live dashboard with WebSocket-like updates
- Energy systems modeling: Physics-based grid simulation
- LLM integration: API usage, error handling, optimization
Dashboard won't launch:
- Check port 8050 is available:
lsof -i :8050(Linux/Mac) - Try different port in
main.py:app.run(port=8051)
Slow simulation:
- LLM calls are the bottleneck; reduce advisor frequency
- RAG retrieval caches models; first run is slower
- Run without advisor: comment out
self.advisorinitialization
Missing PDFs:
- Simulator gracefully handles missing documents
- Fallback synthetic text is used from
ingest.py - PDFs are optional for functionality
API Key Issues:
- Check
echo $ANTHROPIC_API_KEY - Advisor falls back to rule-based explanations if key is missing
- Simulation runs normally without LLM
For issues or questions:
- Check error messages in the console output
- Review the code comments in relevant files
- Examine the dashboard for hints from live data
Built with Python, Claude AI, ChromaDB, and Dash