Spaces:
Sleeping
Sleeping
A newer version of the Streamlit SDK is available: 1.56.0
metadata
title: AI Personas for Urban Planning
emoji: ποΈ
colorFrom: blue
colorTo: purple
sdk: streamlit
sdk_version: 1.40.1
app_file: web_app.py
pinned: false
AI Personas for Urban Planning
A multi-phase persona simulation system for urban planning and built environment design, enabling stakeholder perspective analysis and opinion dynamics modeling.
Overview
This system allows users to:
- Phase 1 β : Query synthetic personas representing urban stakeholders and receive contextually-aware responses
- Phase 2 β : Generate response distributions from populations of persona variants
- Phase 3 β : Model multi-persona interactions to discover opinion equilibria using scale-free and small-world networks
Project Structure
AI_Personas/
βββ src/
β βββ personas/ # Persona data models and database
β βββ context/ # Environmental/built environment context
β βββ llm/ # LLM integration (Anthropic Claude)
β βββ pipeline/ # Phase 1: Query-response pipeline
β βββ population/ # Phase 2: Population sampling and analysis
β βββ influence/ # Phase 3: Social influence networks & equilibrium
βββ data/
β βββ personas/ # Persona JSON definitions
β βββ contexts/ # Environmental context data
βββ pages/
β βββ 1_π¬_Chat.py # Phase 1 web interface
β βββ 2_π_Population_Analysis.py # Phase 2 web interface
β βββ 3_π_Opinion_Equilibria.py # Phase 3 web interface
βββ tests/
βββ web_app.py # Main Streamlit app entry point
βββ requirements.txt # Python dependencies
βββ .env.example # Environment variable template
βββ README.md
π¨ Web UI (Multi-Page!)
Beautiful visual interface with three integrated pages:
# Launch the web interface
streamlit run web_app.py
Page 1: Chat with Personas π¬
Phase 1: Individual persona conversations
- π₯ Visual persona cards with avatars and color themes
- π¬ Chat-style conversation interface
- π Full conversation history
- π― Quick suggestion buttons
- π Contextual awareness (built environment, social context)
Page 2: Population Analysis π
Phase 2: Response distributions from persona populations
- π’ Query 100+ persona variants simultaneously
- π Position distribution visualizations (support/oppose/neutral)
- π Sentiment analysis across populations
- π·οΈ Theme extraction and clustering (affordability, equity, sustainability, etc.)
- π Interactive Plotly charts and statistical summaries
- βοΈ Configurable variation levels (Conservative/Moderate/Diverse)
- πΎ Export results as reports
Page 3: Opinion Equilibria π β¨ NEW!
Phase 3: Multi-persona influence and opinion dynamics
- πΈοΈ Scale-free and small-world network topologies (BarabΓ‘si-Albert, Watts-Strogatz)
- π Multi-round opinion dynamics simulation
- π Opinion evolution timeline visualization
- π― Equilibrium detection and convergence analysis
- π₯ Opinion cluster identification
- β Opinion leader detection (influence centrality)
- π Interactive network graph visualization
- π Consensus strength metrics
- πΎ Export equilibrium reports
Quick Start
1. Installation
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
2. Configuration
# Copy environment template
cp .env.example .env
# Edit .env and add your Anthropic API key
3. Run Example
# Phase 1: Single persona query
python examples/phase1_single_query.py
# Interactive CLI
python -m src.cli
Personas
The system includes 6 synthetic personas representing diverse urban planning stakeholders:
- Sarah Chen - Urban Planner (30s, progressive, sustainability-focused)
- Marcus Thompson - Local Business Owner (50s, pragmatic, economy-focused)
- Dr. Elena Rodriguez - Transportation Engineer (40s, data-driven, efficiency-focused)
- James O'Brien - Long-time Resident (65+, traditional, community-focused)
- Priya Patel - Housing Advocate (20s, activist, equity-focused)
- David Kim - Real Estate Developer (40s, market-driven, growth-focused)
Phase Roadmap
Phase 1: Single Persona Query-Response β COMPLETE
- β Query individual personas with contextual awareness
- β Anthropic Claude integration
- β Environmental context system
- β Beautiful chat interface with persona cards
- β Conversation history and quick suggestions
Phase 2: Population Response Distribution β COMPLETE
- β Generate persona variants with configurable variation levels
- β Parallel querying of persona populations (100+)
- β Response clustering and statistical analysis
- β Position detection (support/oppose/neutral)
- β Sentiment analysis and theme extraction
- β Interactive Plotly visualizations
- β Export functionality
Phase 3: Multi-Persona Influence & Equilibrium β COMPLETE
- β Scale-free network topology (BarabΓ‘si-Albert model)
- β Small-world network topology (Watts-Strogatz model)
- β Fully connected network option
- β Opinion dynamics simulation (multi-round interactions)
- β Influence weight calculation based on persona characteristics
- β Equilibrium detection algorithms
- β Opinion leader identification (centrality analysis)
- β Opinion cluster detection and stability metrics
- β Interactive network graph visualization
- β Consensus strength metrics
- β Opinion evolution timeline charts
- β Export equilibrium reports
Technology Stack
- Python 3.11+: Core language
- FastAPI: REST API layer
- SQLite/PostgreSQL: Persona and context storage
- Anthropic Claude: LLM (will support Be.FM from Stanford)
- Pydantic: Data validation
- NumPy/SciPy: Statistical analysis (Phase 2)
- NetworkX: Graph modeling (Phase 3)
Usage Examples
Query a Persona
from src.pipeline.query_engine import QueryEngine
engine = QueryEngine()
# Ask a persona about a planning issue
response = engine.query(
persona_id="sarah_chen",
question="What do you think about the proposed bike lane on Main Street?",
context={
"location": "downtown_district",
"time": "rush_hour",
"recent_events": ["community_meeting_last_week"]
}
)
print(response)
Get Population Distribution (Phase 2)
from src.population.sampler import PopulationSampler
sampler = PopulationSampler(base_persona="sarah_chen", n_variants=100)
distribution = sampler.query_population(
question="Rate your support for the bike lane (1-10)"
)
# distribution.mean, distribution.std, distribution.histogram
Model Opinion Dynamics (Phase 3)
from src.personas.database import PersonaDatabase
from src.llm.anthropic_client import AnthropicClient
from src.influence.dynamics import OpinionDynamicsEngine
from src.influence.equilibrium import EquilibriumDetector
from src.influence.network import InfluenceNetwork
# Initialize
persona_db = PersonaDatabase()
persona_db.load_from_directory("data/personas")
llm_client = AnthropicClient()
# Select personas for discussion
persona_ids = ["sarah_chen", "marcus_thompson", "david_kim"]
# Run opinion dynamics with scale-free network
engine = OpinionDynamicsEngine(persona_db, llm_client)
results = engine.run_dynamics(
persona_ids=persona_ids,
question="Should we allow high-rise development downtown?",
max_rounds=5,
network_type="scale_free", # or "small_world", "fully_connected"
)
# Analyze equilibrium
personas = [persona_db.get_persona(pid) for pid in persona_ids]
influence_network = InfluenceNetwork(personas, network_type="scale_free")
detector = EquilibriumDetector()
equilibrium = detector.analyze_equilibrium(results, influence_network, max_rounds=5)
# Results
print(f"Equilibrium reached: {equilibrium.reached_equilibrium}")
print(f"Consensus strength: {equilibrium.consensus_strength:.0%}")
print(f"Majority position: {equilibrium.majority_position.value}")
print(f"Opinion leaders: {[l['persona_name'] for l in equilibrium.opinion_leaders[:3]]}")
Contributing
This project is under active development. Contributions welcome!
License
MIT License