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
- Noise cancellation quality (5 mentions)
- Battery life (3 mentions)
- Work-from-home suitability (2 mentions)
- 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
- URGENT: Investigate battery overheating report
- Review comfort for large head sizes in next iteration
- Extend warranty exception for quality defects
- 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.