第16章 营销与客户服务MCP应用

27 阅读9分钟

第16章 营销与客户服务MCP应用

前言

客户是企业的生命线。本章展示如何通过MCP将Claude集成到营销和客户服务系统中,实现智能客服、自动化营销和客户关系管理的智能化升级。


16.1 案例1:智能客服系统

16.1.1 应用场景

graph TB
    A["客户服务需求"] --> B["来电/消息处理"]
    A --> C["工单管理"]
    A --> D["知识库查询"]
    A --> E["售后处理"]
    
    F["集成系统"] --> F1["客户管理CRM"]
    F --> F2["订单系统"]
    F --> F3["知识库"]
    F --> F4["工单系统"]
    
    G["Claude智能客服"] --> G1["自动应答"]
    G --> G2["问题分类"]
    G --> G3["知识推荐"]
    G --> G4["升级处理"]
    
    F --> G
    G --> H["客户满意度提升"]

16.1.2 核心组件实现

from typing import Dict, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
import json

class TicketStatus(Enum):
    """工单状态"""
    NEW = "new"
    IN_PROGRESS = "in_progress"
    WAITING = "waiting"
    RESOLVED = "resolved"
    CLOSED = "closed"


class TicketPriority(Enum):
    """工单优先级"""
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    URGENT = "urgent"


@dataclass
class CustomerProfile:
    """客户档案"""
    customer_id: str
    name: str
    email: str
    phone: str
    vip_level: int  # 0=普通, 1=银牌, 2=金牌, 3=钻石
    lifetime_value: float
    total_purchases: int
    last_purchase_date: Optional[datetime] = None
    preferred_contact: str = "email"
    tags: List[str] = field(default_factory=list)


@dataclass
class SupportTicket:
    """支持工单"""
    ticket_id: str
    customer_id: str
    title: str
    description: str
    status: TicketStatus
    priority: TicketPriority
    created_at: datetime
    updated_at: datetime
    category: str
    assigned_to: Optional[str] = None
    messages: List[Dict] = field(default_factory=list)
    resolution_notes: str = ""


class CustomerServiceAnalyzer:
    """客户服务分析器"""
    
    def __init__(self):
        self.customers: Dict[str, CustomerProfile] = {}
        self.tickets: Dict[str, SupportTicket] = {}
        self.knowledge_base: Dict[str, str] = {}
        self.service_metrics = {
            "avg_response_time": 0,
            "resolution_rate": 0,
            "satisfaction_score": 0,
            "tickets_by_category": {}
        }
    
    async def classify_inquiry(self, message: str) -> Dict:
        """
        分类客户询问
        
        Args:
            message: 客户消息
            
        Returns:
            分类结果
        """
        # 关键词匹配分类
        categories = {
            "billing": ["价格", "费用", "发票", "支付", "退款"],
            "technical": ["无法连接", "错误", "bug", "崩溃", "加载"],
            "order": ["订单", "发货", "物流", "收货", "退货"],
            "account": ["登录", "密码", "账户", "注册", "验证"],
            "product": ["功能", "特性", "如何使用", "说明书"]
        }
        
        message_lower = message.lower()
        scores = {}
        
        for category, keywords in categories.items():
            score = sum(1 for keyword in keywords if keyword in message_lower)
            scores[category] = score
        
        best_category = max(scores, key=scores.get) if scores else "general"
        confidence = scores.get(best_category, 0) / len(categories.get(best_category, []))
        
        return {
            "category": best_category,
            "confidence": min(confidence, 1.0),
            "suggested_response_type": self._get_response_type(best_category)
        }
    
    def _get_response_type(self, category: str) -> str:
        """获取建议的响应类型"""
        type_map = {
            "billing": "提供账单明细和支付选项",
            "technical": "提供故障排查步骤",
            "order": "追踪订单状态和物流信息",
            "account": "协助账户管理",
            "product": "查询产品文档和特性"
        }
        return type_map.get(category, "一般支持")
    
    async def find_knowledge_articles(self, category: str, 
                                     keywords: List[str]) -> List[Dict]:
        """
        查找知识库文章
        
        Args:
            category: 问题分类
            keywords: 关键词
            
        Returns:
            相关文章列表
        """
        relevant_articles = []
        
        for article_id, content in self.knowledge_base.items():
            content_lower = content.lower()
            
            # 计算匹配得分
            score = sum(1 for keyword in keywords if keyword.lower() in content_lower)
            
            if score > 0:
                relevant_articles.append({
                    "article_id": article_id,
                    "score": score,
                    "preview": content[:200]
                })
        
        # 按得分排序
        relevant_articles.sort(key=lambda x: x["score"], reverse=True)
        return relevant_articles[:5]
    
    async def generate_ticket(self, customer_id: str, message: str,
                            category: str) -> SupportTicket:
        """
        生成工单
        
        Args:
            customer_id: 客户ID
            message: 消息
            category: 分类
            
        Returns:
            工单对象
        """
        import uuid
        
        ticket_id = f"TKT_{uuid.uuid4().hex[:8].upper()}"
        now = datetime.now()
        
        # 根据客户VIP等级确定优先级
        customer = self.customers.get(customer_id)
        if customer and customer.vip_level >= 2:
            priority = TicketPriority.HIGH
        else:
            priority = TicketPriority.MEDIUM
        
        ticket = SupportTicket(
            ticket_id=ticket_id,
            customer_id=customer_id,
            title=message[:100],
            description=message,
            status=TicketStatus.NEW,
            priority=priority,
            created_at=now,
            updated_at=now,
            category=category
        )
        
        self.tickets[ticket_id] = ticket
        return ticket
    
    async def get_customer_context(self, customer_id: str) -> Dict:
        """
        获取客户上下文
        
        Args:
            customer_id: 客户ID
            
        Returns:
            客户上下文信息
        """
        customer = self.customers.get(customer_id)
        if not customer:
            return {"error": "Customer not found"}
        
        # 获取相关工单
        customer_tickets = [
            t for t in self.tickets.values() 
            if t.customer_id == customer_id
        ]
        
        # 按最近创建时间排序
        customer_tickets.sort(key=lambda x: x.created_at, reverse=True)
        
        return {
            "customer": {
                "name": customer.name,
                "vip_level": customer.vip_level,
                "lifetime_value": customer.lifetime_value,
                "total_purchases": customer.total_purchases,
                "preferred_contact": customer.preferred_contact
            },
            "recent_tickets": [
                {
                    "ticket_id": t.ticket_id,
                    "title": t.title,
                    "status": t.status.value,
                    "created_at": t.created_at.isoformat()
                }
                for t in customer_tickets[:5]
            ],
            "service_history": {
                "last_contact": customer_tickets[0].created_at.isoformat() if customer_tickets else None,
                "total_contacts": len(customer_tickets)
            }
        }


class CustomerServiceMCPServer:
    """客户服务MCP服务器"""
    
    def __init__(self, analyzer: CustomerServiceAnalyzer):
        self.analyzer = analyzer
    
    def get_tools(self) -> List[Dict]:
        """定义工具"""
        return [
            {
                "name": "classify_inquiry",
                "description": "分类客户询问",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "message": {"type": "string", "description": "客户消息"}
                    },
                    "required": ["message"]
                }
            },
            {
                "name": "find_kb_articles",
                "description": "查找知识库文章",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "category": {"type": "string"},
                        "keywords": {"type": "array", "items": {"type": "string"}}
                    },
                    "required": ["keywords"]
                }
            },
            {
                "name": "create_ticket",
                "description": "创建支持工单",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "customer_id": {"type": "string"},
                        "message": {"type": "string"},
                        "category": {"type": "string"}
                    },
                    "required": ["customer_id", "message", "category"]
                }
            },
            {
                "name": "get_customer_context",
                "description": "获取客户上下文",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "customer_id": {"type": "string"}
                    },
                    "required": ["customer_id"]
                }
            }
        ]
    
    async def call_tool(self, tool_name: str, arguments: Dict) -> str:
        """调用工具"""
        import json
        
        try:
            if tool_name == "classify_inquiry":
                result = await self.analyzer.classify_inquiry(arguments["message"])
            
            elif tool_name == "find_kb_articles":
                result = await self.analyzer.find_knowledge_articles(
                    arguments.get("category", ""),
                    arguments.get("keywords", [])
                )
            
            elif tool_name == "create_ticket":
                ticket = await self.analyzer.generate_ticket(
                    arguments["customer_id"],
                    arguments["message"],
                    arguments["category"]
                )
                result = {
                    "ticket_id": ticket.ticket_id,
                    "status": "created",
                    "message": "Support ticket created successfully"
                }
            
            elif tool_name == "get_customer_context":
                result = await self.analyzer.get_customer_context(
                    arguments["customer_id"]
                )
            
            else:
                return json.dumps({"error": f"Unknown tool: {tool_name}"})
            
            return json.dumps(result, ensure_ascii=False, indent=2)
        
        except Exception as e:
            return json.dumps({"error": str(e)})

16.2 案例2:营销活动智能助手

16.2.1 营销数据管理

@dataclass
class Campaign:
    """营销活动"""
    campaign_id: str
    name: str
    description: str
    start_date: datetime
    end_date: datetime
    target_audience: str
    budget: float
    channels: List[str]  # email, sms, social, web
    status: str


class MarketingAnalyticsEngine:
    """营销分析引擎"""
    
    def __init__(self):
        self.campaigns: Dict[str, Campaign] = {}
        self.performance_data: Dict[str, Dict] = {}
        self.segment_definitions: Dict[str, Dict] = {}
    
    async def analyze_campaign_performance(self, campaign_id: str) -> Dict:
        """
        分析营销活动性能
        
        Args:
            campaign_id: 活动ID
            
        Returns:
            性能分析结果
        """
        if campaign_id not in self.performance_data:
            return {"error": "Campaign not found"}
        
        perf = self.performance_data[campaign_id]
        campaign = self.campaigns.get(campaign_id)
        
        # 计算KPI
        roi = (perf.get("revenue", 0) - campaign.budget) / campaign.budget if campaign else 0
        conversion_rate = (perf.get("conversions", 0) / perf.get("clicks", 1)) * 100 if perf.get("clicks") else 0
        
        return {
            "campaign_id": campaign_id,
            "campaign_name": campaign.name if campaign else "Unknown",
            "metrics": {
                "impressions": perf.get("impressions", 0),
                "clicks": perf.get("clicks", 0),
                "conversions": perf.get("conversions", 0),
                "revenue": perf.get("revenue", 0)
            },
            "kpi": {
                "ctr": f"{(perf.get('clicks', 0) / perf.get('impressions', 1)) * 100:.2f}%" if perf.get("impressions") else "0%",
                "conversion_rate": f"{conversion_rate:.2f}%",
                "roi": f"{roi * 100:.1f}%",
                "aov": perf.get("revenue", 0) / perf.get("conversions", 1) if perf.get("conversions") else 0
            },
            "status": "performing_well" if roi > 0.2 else "needs_optimization"
        }
    
    async def segment_customers(self, criteria: Dict) -> Dict:
        """
        细分客户
        
        Args:
            criteria: 分段标准
            
        Returns:
            分段结果
        """
        return {
            "segments_created": 5,
            "total_customers": 10000,
            "segments": [
                {"name": "High-Value", "count": 1000, "priority": "high"},
                {"name": "Active", "count": 3000, "priority": "medium"},
                {"name": "At-Risk", "count": 2000, "priority": "high"},
                {"name": "New", "count": 3000, "priority": "medium"},
                {"name": "Dormant", "count": 1000, "priority": "low"}
            ],
            "recommendations": [
                "为高价值客户设计VIP计划",
                "对活跃客户进行交叉销售",
                "对风险客户进行重新激活活动"
            ]
        }
    
    async def generate_ab_test_recommendation(self, campaign_id: str) -> Dict:
        """
        生成A/B测试建议
        
        Args:
            campaign_id: 活动ID
            
        Returns:
            A/B测试建议
        """
        return {
            "campaign_id": campaign_id,
            "recommendations": [
                {
                    "test_name": "Subject Line Optimization",
                    "variants": ["原主题行", "更简短的主题行", "包含表情符号的主题行"],
                    "metric": "open_rate",
                    "duration_days": 7
                },
                {
                    "test_name": "CTA Button Color",
                    "variants": ["红色", "绿色", "蓝色"],
                    "metric": "click_rate",
                    "duration_days": 7
                },
                {
                    "test_name": "Send Time Optimization",
                    "variants": ["上午9点", "中午12点", "下午3点"],
                    "metric": "conversion_rate",
                    "duration_days": 14
                }
            ],
            "estimated_impact": "+15-25% conversion rate improvement"
        }
    
    async def predict_campaign_roi(self, campaign_id: str) -> Dict:
        """
        预测活动ROI
        
        Args:
            campaign_id: 活动ID
            
        Returns:
            ROI预测
        """
        campaign = self.campaigns.get(campaign_id)
        if not campaign:
            return {"error": "Campaign not found"}
        
        # 基于历史数据进行简单预测
        estimated_conversions = 500
        avg_order_value = 100
        estimated_revenue = estimated_conversions * avg_order_value
        roi = (estimated_revenue - campaign.budget) / campaign.budget
        
        return {
            "campaign_id": campaign_id,
            "campaign_name": campaign.name,
            "budget": campaign.budget,
            "estimated_metrics": {
                "reach": 50000,
                "conversions": estimated_conversions,
                "revenue": estimated_revenue
            },
            "predicted_roi": f"{roi * 100:.1f}%",
            "confidence": "medium",
            "recommendations": [
                "预测ROI为正,建议继续投资",
                "监控前3天的早期指标",
                "准备优化调整方案"
            ]
        }


class MarketingMCPServer:
    """营销MCP服务器"""
    
    def __init__(self, analytics: MarketingAnalyticsEngine):
        self.analytics = analytics
    
    def get_tools(self) -> List[Dict]:
        """定义工具"""
        return [
            {
                "name": "analyze_campaign",
                "description": "分析营销活动性能",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "campaign_id": {"type": "string"}
                    },
                    "required": ["campaign_id"]
                }
            },
            {
                "name": "segment_customers",
                "description": "细分客户",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "criteria": {"type": "object"}
                    },
                    "required": ["criteria"]
                }
            },
            {
                "name": "ab_test_recommendation",
                "description": "获取A/B测试建议",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "campaign_id": {"type": "string"}
                    },
                    "required": ["campaign_id"]
                }
            },
            {
                "name": "predict_roi",
                "description": "预测活动ROI",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "campaign_id": {"type": "string"}
                    },
                    "required": ["campaign_id"]
                }
            }
        ]
    
    async def call_tool(self, tool_name: str, arguments: Dict) -> str:
        """调用工具"""
        import json
        
        try:
            if tool_name == "analyze_campaign":
                result = await self.analytics.analyze_campaign_performance(
                    arguments["campaign_id"]
                )
            
            elif tool_name == "segment_customers":
                result = await self.analytics.segment_customers(
                    arguments.get("criteria", {})
                )
            
            elif tool_name == "ab_test_recommendation":
                result = await self.analytics.generate_ab_test_recommendation(
                    arguments["campaign_id"]
                )
            
            elif tool_name == "predict_roi":
                result = await self.analytics.predict_campaign_roi(
                    arguments["campaign_id"]
                )
            
            else:
                return json.dumps({"error": f"Unknown tool: {tool_name}"})
            
            return json.dumps(result, ensure_ascii=False, indent=2)
        
        except Exception as e:
            return json.dumps({"error": str(e)})

16.3 完整工作流示例

class CustomerServiceWorkflow:
    """客服工作流"""
    
    def __init__(self, service_analyzer: CustomerServiceAnalyzer):
        self.service = service_analyzer
    
    async def handle_customer_interaction(self, customer_id: str,
                                         message: str) -> Dict:
        """
        处理客户交互的完整工作流
        
        Args:
            customer_id: 客户ID
            message: 消息
            
        Returns:
            处理结果
        """
        workflow = {
            "customer_id": customer_id,
            "steps": [],
            "resolution": None
        }
        
        # 第1步:获取客户上下文
        workflow["steps"].append({"name": "Load Customer Context", "status": "running"})
        customer_context = await self.service.get_customer_context(customer_id)
        workflow["steps"][-1]["status"] = "completed"
        
        # 第2步:分类询问
        workflow["steps"].append({"name": "Classify Inquiry", "status": "running"})
        classification = await self.service.classify_inquiry(message)
        workflow["steps"][-1]["status"] = "completed"
        workflow["steps"][-1]["data"] = classification
        
        # 第3步:查找知识库文章
        workflow["steps"].append({"name": "Search Knowledge Base", "status": "running"})
        keywords = message.split()[:5]
        kb_articles = await self.service.find_knowledge_articles(
            classification["category"],
            keywords
        )
        workflow["steps"][-1]["status"] = "completed"
        workflow["steps"][-1]["data"] = kb_articles
        
        # 第4步:生成工单
        workflow["steps"].append({"name": "Create Support Ticket", "status": "running"})
        ticket = await self.service.generate_ticket(
            customer_id,
            message,
            classification["category"]
        )
        workflow["steps"][-1]["status"] = "completed"
        workflow["steps"][-1]["data"] = {"ticket_id": ticket.ticket_id}
        
        # 第5步:生成建议回应
        workflow["steps"].append({"name": "Generate Response", "status": "running"})
        response_suggestion = {
            "tone": "helpful",
            "include_kb_articles": len(kb_articles) > 0,
            "kb_articles_count": len(kb_articles),
            "offer_escalation": ticket.priority == TicketPriority.URGENT,
            "vip_treatment": customer_context.get("customer", {}).get("vip_level", 0) >= 2
        }
        workflow["steps"][-1]["status"] = "completed"
        workflow["steps"][-1]["data"] = response_suggestion
        
        workflow["resolution"] = {
            "status": "ready",
            "ticket_id": ticket.ticket_id,
            "category": classification["category"],
            "suggested_response": response_suggestion
        }
        
        return workflow

16.4 性能监控与优化

class CustomerServiceMetrics:
    """客服指标监控"""
    
    def __init__(self):
        self.interactions: List[Dict] = []
        self.satisfaction_scores: List[float] = []
        self.response_times: List[float] = []
    
    def record_interaction(self, ticket_id: str, resolution_time_minutes: float,
                         satisfaction_score: float):
        """记录交互"""
        self.interactions.append({
            "ticket_id": ticket_id,
            "timestamp": datetime.now().isoformat(),
            "resolution_time": resolution_time_minutes,
            "satisfaction": satisfaction_score
        })
        
        self.response_times.append(resolution_time_minutes)
        self.satisfaction_scores.append(satisfaction_score)
    
    def get_performance_summary(self) -> Dict:
        """获取性能总结"""
        if not self.interactions:
            return {"error": "No data"}
        
        avg_resolution_time = sum(self.response_times) / len(self.response_times)
        avg_satisfaction = sum(self.satisfaction_scores) / len(self.satisfaction_scores)
        
        return {
            "total_interactions": len(self.interactions),
            "avg_resolution_time_minutes": f"{avg_resolution_time:.1f}",
            "avg_satisfaction_score": f"{avg_satisfaction:.2f}/5.0",
            "satisfaction_rate": f"{(avg_satisfaction / 5 * 100):.1f}%",
            "resolution_efficiency": "excellent" if avg_resolution_time < 30 else "good" if avg_resolution_time < 60 else "needs_improvement",
            "trends": self._analyze_trends()
        }
    
    def _analyze_trends(self) -> Dict:
        """分析趋势"""
        if len(self.interactions) < 2:
            return {"status": "insufficient_data"}
        
        recent = self.interactions[-10:]
        older = self.interactions[:-10] if len(self.interactions) > 10 else self.interactions
        
        recent_avg_time = sum(i["resolution_time"] for i in recent) / len(recent)
        older_avg_time = sum(i["resolution_time"] for i in older) / len(older)
        
        return {
            "resolution_time_trend": "improving" if recent_avg_time < older_avg_time else "degrading",
            "direction": f"{abs(recent_avg_time - older_avg_time):.1f} minutes"
        }

本章总结

关键点说明
客户分类基于关键词的自动分类系统
知识推荐动态查找相关知识库文章
工单管理自动化工单生成和优先级分配
营销分析活动性能分析和ROI预测
客户分段多维度客户细分
A/B测试自动化测试建议
性能监控实时指标跟踪

常见问题

Q1: 如何提高客服满意度? A: 快速响应、知识推荐、VIP客户优先处理。

Q2: 如何优化营销活动ROI? A: 精准分段、A/B测试、持续监控优化。

Q3: 如何处理客户升级情况? A: 自动识别复杂问题、分配给专家、提供优先处理。

Q4: 如何管理多渠道客户服务? A: 统一工单系统、渠道适配器、一致的服务体验。

Q5: 如何评估营销团队效率? A: 活动效率、客户获取成本、转化率提升。


下一章预告:第17章将讲述财务与合规MCP应用