Systems Library / Operations & Admin / How to Build an AI Employee Satisfaction Survey System
Operations & Admin hr people

How to Build an AI Employee Satisfaction Survey System

Deploy surveys and analyze results with AI to identify sentiment trends.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

Employee satisfaction surveys collect data. But most companies never do anything useful with the responses. I built an ai employee satisfaction survey analysis system that deploys surveys, processes open-ended answers with AI, and surfaces the actual patterns hiding in the feedback.

The AI does what a human analyst would take days to do. It reads every response, groups themes, and flags urgent issues.

What You Need Before Starting

Step 1: Design the Survey Template

SURVEY_TEMPLATE = {
    "title": "Q1 2025 Employee Satisfaction",
    "questions": [
        {"id": "q1", "type": "rating", "text": "How satisfied are you with your role? (1-10)"},
        {"id": "q2", "type": "rating", "text": "How well does your manager support you? (1-10)"},
        {"id": "q3", "type": "rating", "text": "How likely are you to recommend working here? (1-10)"},
        {"id": "q4", "type": "open", "text": "What is working well right now?"},
        {"id": "q5", "type": "open", "text": "What would you change if you could?"},
        {"id": "q6", "type": "open", "text": "Is there anything you need that you do not have?"}
    ],
    "anonymous": True
}

Step 2: Store Responses

import sqlite3
import json

def init_survey_db(db_path="surveys.db"):
    conn = sqlite3.connect(db_path)
    conn.execute("""
        CREATE TABLE IF NOT EXISTS responses (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            survey_id TEXT,
            department TEXT,
            answers_json TEXT,
            submitted_at TEXT
        )
    """)
    conn.commit()
    return conn

def save_response(conn, survey_id, department, answers):
    from datetime import datetime
    conn.execute(
        "INSERT INTO responses (survey_id, department, answers_json, submitted_at) VALUES (?,?,?,?)",
        (survey_id, department, json.dumps(answers), datetime.now().isoformat())
    )
    conn.commit()

Step 3: Analyze Open-Ended Responses with AI

import anthropic

client = anthropic.Anthropic()

def analyze_open_responses(responses):
    all_text = ""
    for r in responses:
        answers = json.loads(r[3])
        for key, value in answers.items():
            if isinstance(value, str) and len(value) > 10:
                all_text += f"- {value}\n"

    prompt = f"""Analyze these anonymous employee survey responses.

Responses:
{all_text[:4000]}

Return a JSON report:
{{
    "top_themes": ["list of 5 recurring themes"],
    "positive_highlights": ["what employees appreciate most"],
    "concerns": ["issues that need attention, ranked by frequency"],
    "urgent_flags": ["anything suggesting immediate action needed"],
    "sentiment_score": 0-100,
    "recommended_actions": ["3-5 specific actions leadership should take"]
}}"""

    message = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=2048,
        messages=[{"role": "user", "content": prompt}]
    )
    return json.loads(message.content[0].text)

Step 4: Calculate Quantitative Scores

def calculate_scores(conn, survey_id):
    rows = conn.execute(
        "SELECT department, answers_json FROM responses WHERE survey_id=?",
        (survey_id,)
    ).fetchall()

    dept_scores = {}
    for dept, answers_json in rows:
        answers = json.loads(answers_json)
        if dept not in dept_scores:
            dept_scores[dept] = {"ratings": [], "count": 0}

        for key, value in answers.items():
            if isinstance(value, (int, float)):
                dept_scores[dept]["ratings"].append(value)
                dept_scores[dept]["count"] += 1

    for dept in dept_scores:
        ratings = dept_scores[dept]["ratings"]
        dept_scores[dept]["average"] = round(sum(ratings) / len(ratings), 1) if ratings else 0

    return dept_scores

Step 5: Generate the Executive Summary

def generate_summary(quantitative, qualitative):
    report = "# Employee Satisfaction Report\n\n"
    report += "## Scores by Department\n\n"
    report += "| Department | Avg Score | Responses |\n|---|---|---|\n"

    for dept, data in quantitative.items():
        report += f"| {dept} | {data['average']}/10 | {data['count']} |\n"

    report += f"\n## Sentiment Score: {qualitative['sentiment_score']}/100\n\n"
    report += "## Key Themes\n\n"
    for theme in qualitative["top_themes"]:
        report += f"- {theme}\n"

    report += "\n## Recommended Actions\n\n"
    for action in qualitative["recommended_actions"]:
        report += f"1. {action}\n"

    return report

What to Build Next

Add trend tracking that compares this quarter's results to last quarter. Plot sentiment over time so you can see whether changes you made actually improved anything. The survey is just input. The trend line is the insight.

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems