🔥 0
0
Lesson 6 of 10 22 min +200 XP

Customer Feedback Analysis Crew

Customer reviews are a goldmine of insights - but manually reading thousands of reviews is impossible at scale. A single product might receive 50+ reviews per day across multiple platforms.

Let's build a Customer Feedback Crew that automatically analyzes reviews, extracts insights, and drafts appropriate responses.

The Review Analysis Challenge

THE PROBLEM

  • Hundreds of reviews daily
  • Multiple platforms to monitor
  • Negative reviews need fast response
  • Patterns hidden in volume
  • Product issues discovered late

THE SOLUTION

  • Automated review processing
  • Cross-platform aggregation
  • Priority alerts for critical reviews
  • Pattern recognition at scale
  • Early warning for issues

Feedback Crew Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                  CUSTOMER FEEDBACK CREW                             │
│                                                                     │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐          │
│  │   Review     │───▶│  Sentiment   │───▶│   Insight    │          │
│  │  Collector   │    │   Analyst    │    │  Synthesizer │          │
│  └──────────────┘    └──────────────┘    └──────────────┘          │
│                                                 │                   │
│                                                 ▼                   │
│                                       ┌──────────────┐              │
│                                       │   Response   │              │
│                                       │   Drafter    │              │
│                                       └──────────────┘              │
│                                                 │                   │
│                           ┌─────────────────────┼─────────────────┐ │
│                           ▼                     ▼                 ▼ │
│                      Insights            Draft              Priority │
│                      Report            Responses             Alerts  │
└─────────────────────────────────────────────────────────────────────┘

Complete Implementation

Step 1: Review Collection Tools

from crewai import Agent, Task, Crew, Process
from crewai.tools import tool
from typing import List, Dict, Optional
from datetime import datetime
import json

@tool("Review Fetcher")
def fetch_product_reviews(
    product_id: str,
    days: int = 7,
    min_rating: Optional[int] = None
) -> str:
    """
    Fetches customer reviews for a product from all platforms.

    Args:
        product_id: Product identifier
        days: Number of days of reviews to fetch
        min_rating: Optional filter for minimum star rating

    Returns:
        JSON with reviews including rating, text, date, platform, and verified status.
    """
    reviews = [
        {
            "id": "REV-001",
            "rating": 5,
            "title": "Best headphones I've owned!",
            "text": "The noise cancellation is incredible. I use them daily for work calls and they block out my noisy neighbors completely. Battery lasts forever - I charge once a week. Sound quality is crisp and clear. Worth every penny!",
            "date": "2025-03-18",
            "platform": "Amazon",
            "verified_purchase": True,
            "helpful_votes": 23
        },
        {
            "id": "REV-002",
            "rating": 4,
            "title": "Great sound, minor comfort issue",
            "text": "Sound quality is excellent and ANC works well. My only complaint is that after about 3 hours of use, the ear cups start to feel tight. I have a larger head so this might just be me. Otherwise fantastic product.",
            "date": "2025-03-17",
            "platform": "Amazon",
            "verified_purchase": True,
            "helpful_votes": 15
        },
        {
            "id": "REV-003",
            "rating": 2,
            "title": "Stopped working after 2 months",
            "text": "Left earcup stopped producing sound after 2 months of normal use. Tried resetting, updating firmware - nothing works. Very disappointed for a $150 product. Customer service said I'm outside the return window. Will not buy again.",
            "date": "2025-03-16",
            "platform": "Amazon",
            "verified_purchase": True,
            "helpful_votes": 47
        },
        {
            "id": "REV-004",
            "rating": 1,
            "title": "DANGEROUS - Battery overheated!",
            "text": "After 3 weeks of use, the right earcup became extremely hot while charging. I could smell burning plastic. This is a serious safety hazard! I've reported this to the company. Please investigate this issue before someone gets hurt.",
            "date": "2025-03-15",
            "platform": "Direct Website",
            "verified_purchase": True,
            "helpful_votes": 89
        },
        {
            "id": "REV-005",
            "rating": 5,
            "title": "Perfect for remote work",
            "text": "Working from home with two kids is chaotic, but these headphones are a lifesaver. The ANC blocks out almost everything. Microphone quality is good for video calls - colleagues say I sound clear. Highly recommend for WFH setups!",
            "date": "2025-03-15",
            "platform": "Best Buy",
            "verified_purchase": True,
            "helpful_votes": 31
        },
        {
            "id": "REV-006",
            "rating": 3,
            "title": "Good but not great",
            "text": "Sound is decent, noise cancellation is okay. For the price, I expected better. My old Sony headphones at the same price had better bass. The folding design is convenient though. App is a bit clunky.",
            "date": "2025-03-14",
            "platform": "Amazon",
            "verified_purchase": True,
            "helpful_votes": 8
        },
        {
            "id": "REV-007",
            "rating": 5,
            "title": "Exceeded expectations",
            "text": "Bought these based on reviews and they deliver. Comfortable for long flights, battery lasted my entire LA to Tokyo trip. The app EQ customization is nice. Only wish - would love a carrying case included.",
            "date": "2025-03-13",
            "platform": "Direct Website",
            "verified_purchase": True,
            "helpful_votes": 19
        },
        {
            "id": "REV-008",
            "rating": 4,
            "title": "Shipping damage",
            "text": "The headphones are great! But they arrived with the box crushed and the headband slightly bent. They still work fine but disappointing for a new product. Please improve your packaging.",
            "date": "2025-03-12",
            "platform": "Amazon",
            "verified_purchase": True,
            "helpful_votes": 5
        }
    ]

    if min_rating:
        reviews = [r for r in reviews if r["rating"] >= min_rating]

    summary = {
        "product_id": product_id,
        "period": f"Last {days} days",
        "total_reviews": len(reviews),
        "average_rating": round(sum(r["rating"] for r in reviews) / len(reviews), 1),
        "rating_distribution": {
            "5_star": len([r for r in reviews if r["rating"] == 5]),
            "4_star": len([r for r in reviews if r["rating"] == 4]),
            "3_star": len([r for r in reviews if r["rating"] == 3]),
            "2_star": len([r for r in reviews if r["rating"] == 2]),
            "1_star": len([r for r in reviews if r["rating"] == 1])
        },
        "reviews": reviews
    }

    return json.dumps(summary, indent=2)


@tool("Previous Response Checker")
def check_existing_responses(review_ids: List[str]) -> str:
    """
    Checks if reviews already have responses.

    Args:
        review_ids: List of review IDs to check

    Returns:
        JSON indicating which reviews have/need responses.
    """
    # In production, check your review management system
    response_status = {
        "REV-001": {"has_response": True, "response_date": "2025-03-18"},
        "REV-002": {"has_response": False},
        "REV-003": {"has_response": False},
        "REV-004": {"has_response": True, "response_date": "2025-03-15", "escalated": True},
        "REV-005": {"has_response": False},
        "REV-006": {"has_response": False},
        "REV-007": {"has_response": False},
        "REV-008": {"has_response": False}
    }

    return json.dumps(response_status, indent=2)


@tool("Brand Response Templates")
def get_response_templates(scenario_type: str) -> str:
    """
    Retrieves approved response templates for different scenarios.

    Args:
        scenario_type: Type of review (positive, negative, neutral, safety)

    Returns:
        JSON with approved response templates and guidelines.
    """
    templates = {
        "positive": {
            "tone": "Warm, grateful, encouraging",
            "elements": [
                "Thank customer by name if available",
                "Express genuine appreciation",
                "Highlight specific point they mentioned",
                "Invite them to try related products"
            ],
            "example": "Thank you so much for your wonderful review, [Name]! We're thrilled that the noise cancellation is making your work-from-home life easier. Your feedback made our day! If you ever need anything, we're here to help."
        },
        "negative_quality": {
            "tone": "Empathetic, solution-oriented, professional",
            "elements": [
                "Apologize sincerely",
                "Acknowledge specific issue",
                "Offer concrete solution (replacement, refund, support)",
                "Provide direct contact for resolution"
            ],
            "example": "We're truly sorry to hear about this experience. A product failing after 2 months is unacceptable, and we want to make this right. Please contact us at support@brand.com with your order number - we'll arrange a replacement immediately, regardless of the return window."
        },
        "negative_shipping": {
            "tone": "Apologetic, proactive",
            "elements": [
                "Apologize for shipping issue",
                "Explain corrective action",
                "Offer replacement if damaged",
                "Thank them for feedback"
            ],
            "example": "We apologize that your order arrived damaged. This isn't the unboxing experience you deserved. We've flagged this with our fulfillment team to improve packaging. Please reach out to support@brand.com - we'll send a replacement in perfect condition."
        },
        "safety_critical": {
            "tone": "Serious, urgent, concerned",
            "elements": [
                "Express immediate concern for safety",
                "Request direct contact urgently",
                "Do NOT offer product exchange (liability)",
                "Document for quality team"
            ],
            "example": "We take safety extremely seriously, and your report concerns us greatly. Please stop using the product immediately and contact our safety team directly at safety@brand.com or call 1-800-XXX-XXXX. We need to investigate this urgently and ensure you're safe.",
            "escalation": "IMMEDIATE - Route to Safety Team and Legal"
        },
        "neutral_constructive": {
            "tone": "Appreciative, open",
            "elements": [
                "Thank for honest feedback",
                "Acknowledge valid points",
                "Share any relevant improvements",
                "Invite continued feedback"
            ],
            "example": "Thank you for sharing your honest thoughts! Your feedback about the bass response is valuable - our team is continuously working on audio improvements. We appreciate customers like you who help us get better."
        }
    }

    return json.dumps(templates.get(scenario_type, templates["positive"]), indent=2)

Step 2: Define Analysis Agents

# Agent 1: Review Collector
review_collector = Agent(
    role="Review Collection Specialist",

    goal="Gather and organize customer reviews from all platforms, "
         "identifying which reviews need attention",

    backstory="""You are a customer feedback specialist who has managed
    review collection for major e-commerce brands. You understand that
    reviews are scattered across platforms and need consolidation.

    Your responsibilities:
    - Collect reviews from all platforms
    - Identify unresponded reviews
    - Flag high-priority items (safety, major issues)
    - Organize reviews for efficient analysis

    You know that speed matters - a negative review without a response
    looks bad to other potential customers.""",

    tools=[fetch_product_reviews, check_existing_responses],
    verbose=True
)


# Agent 2: Sentiment Analyst
sentiment_analyst = Agent(
    role="Customer Sentiment Analyst",

    goal="Analyze review sentiment, identify themes, and categorize "
         "feedback into actionable categories",

    backstory="""You are a voice-of-customer analyst with expertise in
    NLP and sentiment analysis. You've analyzed millions of reviews for
    Fortune 500 companies.

    Your analysis goes beyond positive/negative:
    - Identify specific emotions (frustration, delight, disappointment)
    - Extract mentioned features and issues
    - Recognize patterns across reviews
    - Prioritize by business impact

    You believe every review tells a story - your job is to listen
    and translate that story into insights.""",

    verbose=True
)


# Agent 3: Insight Synthesizer
insight_synthesizer = Agent(
    role="Customer Insight Strategist",

    goal="Transform review analysis into strategic insights and "
         "actionable recommendations for product and service improvement",

    backstory="""You are a strategic analyst who bridges customer feedback
    and business decisions. You've driven product improvements that
    increased customer satisfaction by 30%.

    Your approach:
    - Identify trends before they become problems
    - Quantify the impact of issues
    - Prioritize by customer impact and business value
    - Connect feedback to specific actions

    You create insights that people actually act on.""",

    verbose=True
)


# Agent 4: Response Drafter
response_drafter = Agent(
    role="Customer Response Specialist",

    goal="Draft appropriate, on-brand responses for customer reviews "
         "that resolve issues and strengthen relationships",

    backstory="""You are a customer experience writer who has crafted
    thousands of review responses. You understand that a good response
    can turn a detractor into an advocate.

    Your response philosophy:
    - Personalize whenever possible
    - Acknowledge the specific issue
    - Offer concrete solutions, not platitudes
    - Know when to take it offline
    - Never be defensive

    You write responses that show customers they're heard.""",

    tools=[get_response_templates],
    verbose=True
)

Step 3: Define the Analysis Workflow

# Task 1: Collect and Organize Reviews
collection_task = Task(
    description="""
    Collect and organize customer reviews for product: {product_id}

    Your deliverables:
    1. Fetch all reviews from the past 7 days
    2. Check which reviews already have responses
    3. Flag any SAFETY-CRITICAL reviews for immediate escalation
    4. Organize reviews by priority (unresponded negative first)

    CRITICAL: If any review mentions safety issues (overheating, injury,
    hazards), immediately flag it as URGENT ESCALATION.
    """,

    expected_output="""
    Organized review collection:
    - Total reviews collected with source breakdown
    - List of unresponded reviews needing attention
    - Priority ranking (critical, high, medium, low)
    - Any urgent escalations flagged
    """,

    agent=review_collector
)


# Task 2: Sentiment and Theme Analysis
analysis_task = Task(
    description="""
    Analyze the collected reviews for sentiment, themes, and patterns.

    For each review, identify:
    1. Overall sentiment (positive/negative/neutral)
    2. Specific emotions expressed
    3. Features/issues mentioned
    4. Urgency level

    Across all reviews, identify:
    1. Common themes (quality, shipping, value, etc.)
    2. Recurring complaints
    3. Frequently praised features
    4. Emerging issues (new problems appearing)
    """,

    expected_output="""
    Sentiment analysis report:
    - Per-review sentiment classification with emotions
    - Theme frequency analysis
    - Top 3 complaints with frequency
    - Top 3 praises with frequency
    - Emerging issue alerts (if any)
    - Priority classification for response
    """,

    agent=sentiment_analyst,
    context=[collection_task]
)


# Task 3: Synthesize Insights
insights_task = Task(
    description="""
    Transform the review analysis into strategic insights and recommendations.

    Create:
    1. EXECUTIVE SUMMARY: Key takeaways in 3 bullet points
    2. PRODUCT INSIGHTS: What customers love/hate about the product
    3. SERVICE INSIGHTS: Shipping, support, packaging issues
    4. RECOMMENDATIONS: Prioritized actions to address feedback
    5. TREND ALERT: Any concerning patterns requiring attention

    Make recommendations specific and actionable.
    """,

    expected_output="""
    Customer insights report:
    - Executive summary (3 key points)
    - Product feedback analysis with priorities
    - Service feedback analysis with priorities
    - 5 prioritized recommendations with expected impact
    - Trend alerts with recommended response
    """,

    agent=insight_synthesizer,
    context=[collection_task, analysis_task]
)


# Task 4: Draft Responses
response_task = Task(
    description="""
    Draft appropriate responses for reviews that need attention.

    Guidelines:
    1. SAFETY ISSUES: Urgent, concerned tone, request direct contact
    2. QUALITY COMPLAINTS: Empathetic, offer solution (replacement/refund)
    3. SHIPPING ISSUES: Apologetic, explain action taken
    4. POSITIVE REVIEWS: Grateful, personalized, invite continued engagement
    5. NEUTRAL FEEDBACK: Appreciative, acknowledge valid points

    Each response should:
    - Feel personal (not templated)
    - Address their specific concern
    - Include a concrete next step
    - Stay under 100 words

    DO NOT respond to reviews that already have responses.
    """,

    expected_output="""
    Draft responses document:
    - Response drafts for each unresponded review
    - Escalation notes for reviews requiring human review
    - Response priority order (most urgent first)
    - Estimated impact of responding promptly
    """,

    agent=response_drafter,
    context=[collection_task, analysis_task]
)

Step 4: Assemble the Feedback Crew

# Create the Customer Feedback Crew
feedback_crew = Crew(
    agents=[
        review_collector,
        sentiment_analyst,
        insight_synthesizer,
        response_drafter
    ],
    tasks=[
        collection_task,
        analysis_task,
        insights_task,
        response_task
    ],
    process=Process.sequential,
    verbose=True
)


def analyze_product_feedback(product_id: str) -> str:
    """Analyze customer feedback and generate responses."""
    result = feedback_crew.kickoff(
        inputs={"product_id": product_id}
    )
    return result


# Run the feedback crew
if __name__ == "__main__":
    report = analyze_product_feedback("PROD-12345")
    print("\n" + "="*60)
    print("CUSTOMER FEEDBACK ANALYSIS")
    print("="*60)
    print(report)

Sample Output

URGENT ESCALATION - Safety Issue

Review REV-004: Customer reports battery overheating and burning smell during charging. This requires immediate Safety Team review.

Drafted Response: "We take safety extremely seriously, and your report concerns us greatly. Please stop using the product immediately and contact our safety team directly at safety@brand.com or call 1-800-XXX-XXXX. We need to investigate this urgently."

Key Insights Summary

Top Praises:
  • Noise cancellation quality (5 mentions)
  • Battery life (3 mentions)
  • Work-from-home suitability (2 mentions)
Top Complaints:
  • Comfort for extended wear (2 mentions) - Consider larger ear cups
  • Quality defects (1 mention) - Review manufacturing QC
  • Packaging/shipping damage (1 mention) - Improve box padding
Recommendations:
  1. URGENT: Investigate battery overheating report
  2. Review comfort for large head sizes in next iteration
  3. Extend warranty exception for quality defects
  4. Work with fulfillment on protective packaging

Automating Review Monitoring

Set up continuous monitoring:

import schedule
import time

def daily_review_analysis():
    """Run daily review analysis for all active products."""
    products = get_active_products()

    for product_id in products:
        report = analyze_product_feedback(product_id)

        # Handle urgent escalations immediately
        if "URGENT ESCALATION" in report:
            send_urgent_alert(product_id, report)

        # Save insights for product team
        save_insights(product_id, report)

        # Queue responses for review/posting
        queue_responses(product_id, report)


# Schedule daily at 8 AM
schedule.every().day.at("08:00").do(daily_review_analysis)

while True:
    schedule.run_pending()
    time.sleep(60)

Key Takeaways

  • Prioritize safety issues - Always escalate safety concerns immediately
  • Go beyond sentiment - Extract themes, emotions, and specific issues
  • Personalize responses - Address specific concerns, not generic templates
  • Turn feedback into action - Connect insights to product improvements
  • Automate monitoring - Reviews don't wait for business hours

Next up: Marketing Content Generation Crew - Build agents that create multi-channel marketing content.

🧠 Quick Quiz

Test your understanding of this lesson.

1

What should the Sentiment Analyst agent identify beyond positive/negative?

2

Why is automated response generation for reviews valuable?

3

What type of reviews should the crew prioritize for immediate attention?

Dynamic Pricing Agent Crew