一、客服系统概述
1.1 传统客服的痛点
erlang
┌─────────────────────────────────────────────────────────────────┐
│ 传统客服面临的问题 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 响应慢 │ │ 成本高 │ │ 效率低 │ │
│ │ │ │ │ │ │ │
│ │ 人工接待 │ │ 人工成本 │ │ 重复问题 │ │
│ │ 等待时间长 │ │ 培训成本 │ │ 效率低下 │ │
│ │ 用户体验差 │ │ 流失率高 │ │ 难以扩张 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 典型数据: │
│ ├── 平均响应时间:5-30分钟 │
│ ├── 人工成本:5000-10000元/人/月 │
│ ├── 问题解决率:60-70% │
│ └── 用户满意度:60-75% │
│ │
└─────────────────────────────────────────────────────────────────┘
1.2 智能客服的优势
| 对比维度 | 传统客服 | 智能客服 |
|---|---|---|
| 响应时间 | 5-30分钟 | 1-3秒 |
| 服务时间 | 8小时/天 | 24小时/天 |
| 单次成本 | ¥5-20 | ¥0.1-0.5 |
| 并发处理 | 1:1 | 1:N |
| 服务态度 | 波动大 | 稳定统一 |
| 数据积累 | 难以结构化 | 自动沉淀 |
二、系统架构设计
2.1 整体架构
scss
┌─────────────────────────────────────────────────────────────────┐
│ 智能客服系统架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 用户层 │
│ └────────────────────┬────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 接入层 (Load Balancer) │ │
│ └────────────────────┬────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 业务逻辑层 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 路由 │ │ 会话 │ │ 质检 │ │ 监控 │ │ │
│ │ │ 模块 │ │ 管理 │ │ 模块 │ │ 模块 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └────────────────────┬────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ AI能力层 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 意图 │ │ 知识 │ │ 对话 │ │ 情感 │ │ │
│ │ │ 识别 │ │ 库 │ │ 生成 │ │ 分析 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └────────────────────┬────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 数据层 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 会话 │ │ 用户 │ │ 工单 │ │ 报表 │ │ │
│ │ │ 存储 │ │ 画像 │ │ 管理 │ │ 数据 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
2.2 核心模块
python
from dataclasses import dataclass
from typing import List, Dict, Optional
from datetime import datetime
from enum import Enum
class SessionStatus(Enum):
"""会话状态"""
WAITING = "waiting"
IN_PROGRESS = "in_progress"
TRANSFERRED = "transferred"
COMPLETED = "completed"
EXPIRED = "expired"
@dataclass
class Message:
"""消息"""
message_id: str
session_id: str
sender: str # user / bot / agent
content: str
timestamp: datetime
message_type: str = "text"
@dataclass
class Session:
"""会话"""
session_id: str
user_id: str
status: SessionStatus
create_time: datetime
agent_id: Optional[str] = None
bot_id: Optional[str] = None
messages: List[Message] = None
tags: List[str] = None
priority: int = 0
def __post_init__(self):
if self.messages is None:
self.messages = []
if self.tags is None:
self.tags = []
class SessionManager:
"""会话管理器"""
def __init__(self):
self.sessions: Dict[str, Session] = {}
self.user_sessions: Dict[str, List[str]] = {}
def create_session(self, user_id: str, source: str = "wechat") -> Session:
"""创建新会话"""
session_id = self._generate_session_id()
session = Session(
session_id=session_id,
user_id=user_id,
status=SessionStatus.WAITING,
create_time=datetime.now()
)
self.sessions[session_id] = session
if user_id not in self.user_sessions:
self.user_sessions[user_id] = []
self.user_sessions[user_id].append(session_id)
return session
def get_session(self, session_id: str) -> Optional[Session]:
"""获取会话"""
return self.sessions.get(session_id)
def get_user_active_session(self, user_id: str) -> Optional[Session]:
"""获取用户活跃会话"""
session_ids = self.user_sessions.get(user_id, [])
for session_id in reversed(session_ids):
session = self.sessions.get(session_id)
if session and session.status in [SessionStatus.WAITING, SessionStatus.IN_PROGRESS]:
return session
return None
def add_message(self, session_id: str, sender: str, content: str, message_type: str = "text") -> Message:
"""添加消息"""
session = self.sessions.get(session_id)
if not session:
raise ValueError(f"Session not found: {session_id}")
message = Message(
message_id=self._generate_message_id(),
session_id=session_id,
sender=sender,
content=content,
timestamp=datetime.now(),
message_type=message_type
)
session.messages.append(message)
return message
def transfer_to_agent(self, session_id: str, agent_id: str):
"""转人工"""
session = self.sessions.get(session_id)
if session:
session.status = SessionStatus.TRANSFERRED
session.agent_id = agent_id
def close_session(self, session_id: str):
"""关闭会话"""
session = self.sessions.get(session_id)
if session:
session.status = SessionStatus.COMPLETED
def _generate_session_id(self) -> str:
"""生成会话ID"""
import uuid
return f"sess_{uuid.uuid4().hex[:16]}"
def _generate_message_id(self) -> str:
"""生成消息ID"""
import uuid
return f"msg_{uuid.uuid4().hex[:16]}"
三、智能路由系统
3.1 路由策略
python
from typing import List, Dict, Optional
from dataclasses import dataclass
@dataclass
class RoutingRule:
"""路由规则"""
rule_id: str
name: str
conditions: List[dict]
target_queue: str
priority: int = 0
class IntelligentRouter:
"""智能路由"""
def __init__(self, session_manager: SessionManager):
self.session_manager = session_manager
self.routing_rules: List[RoutingRule] = []
self.agent_queues: Dict[str, list] = {
"general": [],
"vip": [],
"technical": [],
"sales": []
}
def add_routing_rule(self, rule: RoutingRule):
"""添加路由规则"""
self.routing_rules.append(rule)
self.routing_rules.sort(key=lambda x: x.priority, reverse=True)
def route_session(self, session_id: str, context: dict = None) -> str:
"""路由会话"""
session = self.session_manager.get_session(session_id)
if not session:
return "general"
user_profile = context or {}
for rule in self.routing_rules:
if self._match_conditions(user_profile, rule.conditions):
return rule.target_queue
return self._default_route(user_profile)
def _match_conditions(self, context: dict, conditions: List[dict]) -> bool:
"""匹配条件"""
for condition in conditions:
field = condition.get("field")
operator = condition.get("operator")
value = condition.get("value")
context_value = context.get(field)
if not self._evaluate(context_value, operator, value):
return False
return True
def _evaluate(self, value, operator: str, target) -> bool:
"""评估条件"""
if operator == "equals":
return value == target
elif operator == "not_equals":
return value != target
elif operator == "contains":
return target in (value or [])
elif operator == "greater_than":
return value is not None and value > target
elif operator == "in":
return value in target
return False
def _default_route(self, context: dict) -> str:
"""默认路由"""
user_level = context.get("user_level", "normal")
if user_level == "vip":
return "vip"
return "general"
def assign_agent(self, queue_name: str) -> Optional[str]:
"""分配客服"""
queue = self.agent_queues.get(queue_name, [])
for agent_id in queue:
agent = self._get_agent(agent_id)
if agent and agent.get("status") == "online" and agent.get("current_load", 0) < agent.get("max_load", 10):
return agent_id
return None
def _get_agent(self, agent_id: str) -> Optional[dict]:
"""获取客服信息"""
return {"agent_id": agent_id, "status": "online", "current_load": 5, "max_load": 10}
四、知识库构建
4.1 知识库结构
python
from typing import List, Dict, Optional
from dataclasses import dataclass
@dataclass
class KnowledgeItem:
"""知识条目"""
kb_id: str
question: str
answer: str
category: str
tags: List[str]
similar_questions: List[str]
status: str = "active"
view_count: int = 0
helpful_count: int = 0
class KnowledgeBase:
"""知识库"""
def __init__(self):
self.items: Dict[str, KnowledgeItem] = {}
self.category_index: Dict[str, List[str]] = {}
self.tag_index: Dict[str, List[str]] = {}
def add_item(self, item: KnowledgeItem):
"""添加知识条目"""
self.items[item.kb_id] = item
if item.category not in self.category_index:
self.category_index[item.category] = []
self.category_index[item.category].append(item.kb_id)
for tag in item.tags:
if tag not in self.tag_index:
self.tag_index[tag] = []
self.tag_index[tag].append(item.kb_id)
def search(self, query: str, top_k: int = 5) -> List[KnowledgeItem]:
"""搜索知识"""
query_lower = query.lower()
scored_items = []
for item in self.items.values():
if item.status != "active":
continue
score = 0
if query_lower in item.question.lower():
score += 10
for similar in item.similar_questions:
if query_lower in similar.lower():
score += 5
for tag in item.tags:
if query_lower in tag.lower():
score += 3
if score > 0:
scored_items.append((item, score))
scored_items.sort(key=lambda x: x[1], reverse=True)
return [item for item, _ in scored_items[:top_k]]
def get_by_category(self, category: str) -> List[KnowledgeItem]:
"""按分类获取"""
kb_ids = self.category_index.get(category, [])
return [self.items[kb_id] for kb_id in kb_ids if kb_id in self.items]
def record_feedback(self, kb_id: str, helpful: bool):
"""记录反馈"""
item = self.items.get(kb_id)
if item:
item.view_count += 1
if helpful:
item.helpful_count += 1
五、对话管理
5.1 对话流程控制
python
from typing import Dict, List, Optional
import asyncio
class ConversationManager:
"""对话管理器"""
def __init__(self, llm_client, knowledge_base: KnowledgeBase):
self.llm = llm_client
self.kb = knowledge_base
self.conversation_contexts: Dict[str, dict] = {}
async def handle_user_message(self, session_id: str, user_message: str) -> str:
"""处理用户消息"""
context = self._get_or_create_context(session_id)
context["messages"].append({
"role": "user",
"content": user_message
})
intent = await self._recognize_intent(user_message)
if intent == "greeting":
response = await self._handle_greeting()
elif intent == "faq":
response = await self._handle_faq(user_message)
elif intent == "complaint":
response = await self._handle_complaint(user_message)
elif intent == "transfer":
response = await self._handle_transfer(session_id)
else:
response = await self._handle_general(user_message, context)
context["messages"].append({
"role": "assistant",
"content": response
})
return response
async def _recognize_intent(self, message: str) -> str:
"""识别意图"""
keywords = {
"greeting": ["你好", "在吗", "嗨", "hi", "hello"],
"faq": ["怎么", "如何", "是什么", "哪里", "为什么"],
"complaint": ["投诉", "不满", "太差", "垃圾", "问题"],
"transfer": ["人工", "客服", "真人", "转人工"]
}
message_lower = message.lower()
for intent, kws in keywords.items():
for kw in kws:
if kw in message_lower:
return intent
return "general"
async def _handle_greeting(self) -> str:
"""处理问候"""
greetings = [
"您好!有什么可以帮到您的?",
"Hi~ 请问有什么问题吗?",
"欢迎!请说出会您的问题~"
]
import random
return random.choice(greetings)
async def _handle_faq(self, question: str) -> str:
"""处理FAQ"""
results = self.kb.search(question, top_k=3)
if results:
best_match = results[0]
return f"您可能想了解:\n\n<b>{best_match.question}</b>\n\n{best_match.answer}\n\n还有其他问题吗?"
return "抱歉,我暂时没有找到相关信息。请问您可以详细描述一下您的问题吗?"
async def _handle_transfer(self, session_id: str) -> str:
"""处理转人工"""
return "好的,我为您转接人工客服,请稍候~"
async def _handle_general(self, message: str, context: dict) -> str:
"""处理通用问题"""
recent_messages = context["messages"][-5:]
prompt = f"""
你是智能客服助手。请根据对话历史回答用户问题。
对话历史:
{chr(10).join([f"{m['role']}: {m['content']}" for m in recent_messages])}
用户最新问题:{message}
请给出专业、友好的回答:
"""
messages = [{"role": "user", "content": prompt}]
response = await self.llm.chat(messages)
return response
def _get_or_create_context(self, session_id: str) -> dict:
"""获取或创建上下文"""
if session_id not in self.conversation_contexts:
self.conversation_contexts[session_id] = {
"session_id": session_id,
"messages": [],
"state": "initial",
"slots": {}
}
return self.conversation_contexts[session_id]
六、人工协作
6.1 人工客服工作台
python
class AgentWorkstation:
"""人工客服工作台"""
def __init__(self):
self.agent_id: str = ""
self.current_session: Optional[Session] = None
self.quick_replies: Dict[str, str] = {}
self.canned_responses: List[dict] = []
def load_quick_replies(self):
"""加载快捷回复"""
self.quick_replies = {
"greeting": "您好,请问有什么可以帮您?",
"acknowledge": "好的,我了解了。",
"waiting": "请您稍等,我帮您查询一下。",
"apologize": "非常抱歉给您带来不便。",
"thanks": "感谢您的理解和支持!",
"close": "请问还有其他问题吗?感谢您的咨询,再见!"
}
def load_canned_responses(self):
"""加载预设回复"""
self.canned_responses = [
{
"id": "order_inquiry",
"title": "订单查询",
"content": "您的订单号为{order_id},当前状态:{status}。"
},
{
"id": "refund_process",
"title": "退款流程",
"content": "退款申请已受理,预计1-3个工作日到账。"
},
{
"id": "product_info",
"title": "产品信息",
"content": "{product_name}的价格是¥{price},目前{stock_status}。"
}
]
def get_quick_reply(self, key: str) -> str:
"""获取快捷回复"""
return self.quick_replies.get(key, "")
def apply_canned_response(self, response_id: str, params: dict) -> str:
"""应用预设回复"""
for response in self.canned_responses:
if response["id"] == response_id:
content = response["content"]
return content.format(**params)
return ""
七、效果评估
7.1 客服质量指标
| 指标名称 | 计算方式 | 目标值 | 重要性 |
|---|---|---|---|
| 响应时间 | 首次响应时长 | <30秒 | ⭐⭐⭐⭐⭐ |
| 解决率 | 解决的问题数/总会话数 | >85% | ⭐⭐⭐⭐⭐ |
| 满意度 | 满意评价/总评价 | >90% | ⭐⭐⭐⭐⭐ |
| 转化率 | 产生购买/总会话数 | >15% | ⭐⭐⭐ |
| 接待量 | 人均日接待会话 | >100 | ⭐⭐⭐ |
7.2 数据报表
python
class ServiceMetrics:
"""服务指标"""
def __init__(self, db_client):
self.db = db_client
async def calculate_daily_metrics(self, date: datetime = None) -> dict:
"""计算日指标"""
if date is None:
date = datetime.now()
sessions = await self.db.query("sessions", {
"create_time": {"gte": date, "lt": date + timedelta(days=1)}
})
total_sessions = len(sessions)
completed_sessions = sum(1 for s in sessions if s["status"] == "completed")
transferred_sessions = sum(1 for s in sessions if s["status"] == "transferred")
messages = await self.db.query("messages", {
"timestamp": {"gte": date, "lt": date + timedelta(days=1)}
})
total_messages = len(messages)
bot_messages = sum(1 for m in messages if m["sender"] == "bot")
agent_messages = sum(1 for m in messages if m["sender"] == "agent")
avg_response_time = await self._calculate_avg_response_time(date)
satisfaction_rate = await self._calculate_satisfaction(date)
return {
"date": date.strftime("%Y-%m-%d"),
"total_sessions": total_sessions,
"completed_sessions": completed_sessions,
"transferred_sessions": transferred_sessions,
"completion_rate": f"{(completed_sessions/max(total_sessions,1))*100:.1f}%",
"total_messages": total_messages,
"bot_messages": bot_messages,
"agent_messages": agent_messages,
"avg_response_time": f"{avg_response_time:.1f}秒",
"satisfaction_rate": f"{satisfaction_rate*100:.1f}%"
}
async def _calculate_avg_response_time(self, date: datetime) -> float:
"""计算平均响应时间"""
return 25.5
async def _calculate_satisfaction(self, date: datetime) -> float:
"""计算满意度"""
return 0.92
八、总结
智能客服系统是微信机器人的重要应用场景:
- 会话管理:完整的会话生命周期管理
- 智能路由:基于规则和AI的智能分配
- 知识库:结构化知识管理与检索
- 人机协作:机器人与人工客服无缝切换
- 效果评估:数据驱动的服务质量监控
通过智能客服系统,可以大幅提升服务效率和质量,降低运营成本。
本文仅用于技术交流和学习目的。客服系统搭建需遵守相关法律法规和平台规则。