最近有朋友问我:市面上像合力亿捷这样的智能客服系统,集成大模型、覆盖十几条渠道、还能智能分配人工和机器人,到底是怎么实现的?今天我就以“AI写代码”的视角,手把手带大家从零搭建一套企业级智能客服系统的核心模块。全文干货,附关键代码片段和架构思路。

一、系统全景:不止是聊天框

一个完整的智能客服系统要解决三个核心问题:

  1. 多渠道统一接入​:网站、App、微信、抖音、邮件……消息要能汇聚到同一个工作台
  2. 人机协同​:AI处理80%标准问题,人工聚焦20%复杂场景
  3. 数据驱动​:访客轨迹实时追踪、意图预判、智能分配

下面我们逐层拆解实现方案。

二、多渠道消息网关:用适配器模式统一所有入口

不同渠道的API千差万别:微信使用XML+被动回复、抖音用Webhook+JSON、网站用WebSocket。核心思路是​建立统一的消息模型​。

# 统一消息模型 (message.py)
from pydantic import BaseModel
from enum import Enum
from typing import Optional, Dict

class ChannelType(str, Enum):
    WEB = "web"
    WECHAT = "wechat"
    DOUYIN = "douyin"
    APP = "app"

class UnifiedMessage(BaseModel):
    channel: ChannelType
    user_id: str          # 渠道内的唯一ID
    session_id: str       # 会话标识
    content_type: str     # text / image / voice / card
    content: Dict         # 结构化内容
    raw_payload: Optional[Dict] = None

然后为每个渠道写一个适配器:

# adapters/wechat_adapter.py
import xml.etree.ElementTree as ET
from .base import BaseAdapter

class WechatAdapter(BaseAdapter):
    def parse_incoming(self, xml_string: str) -> UnifiedMessage:
        root = ET.fromstring(xml_string)
        msg_type = root.find('MsgType').text
        return UnifiedMessage(
            channel=ChannelType.WECHAT,
            user_id=root.find('FromUserName').text,
            session_id=root.find('FromUserName').text, 
            content_type=msg_type,
            content={'text': root.find('Content').text if msg_type=='text' else {}}
        )
    
    def build_outgoing(self, message: UnifiedMessage) -> str:
        # 构造微信要求的XML回复
        return f"<xml><ToUserName><![CDATA[{message.user_id}]]>..."

AI写代码提示​:如果你用LangChain或Semantic Kernel,可以将每个适配器封装成一个Tool,让大模型自动选择调用哪个渠道的回复模板。

三、大模型意图识别与预判(核心干货)

文案中提到“意图预判与识别”,这通常需要两步:实时识别访客意图 + ​根据历史行为预判下一步​。我们直接上代码:

# intent_engine.py
import openai
from typing import List, Dict
from redis import Redis

class IntentRecognizer:
    def __init__(self):
        self.redis_client = Redis(decode_responses=True)
        self.intent_prompt = """
        你是一个客服意图分类器。从下面对话中识别用户意图,只能从以下类别中选择:
        ['售前咨询', '售后问题', '价格询问', '技术故障', '闲聊', '转人工']
        输出JSON格式:{"intent": "", "confidence": 0.0, "entities": {}}
        对话:{dialogue}
        """
    
    async def recognize(self, session_id: str, last_message: str) -> dict:
        # 1. 获取最近5轮对话历史
        history = self.redis_client.lrange(f"chat:{session_id}", -5, -1)
        dialogue = "\n".join(history + [last_message])
        
        # 2. 调用大模型(使用更便宜的模型如gpt-3.5-turbo)
        response = await openai.ChatCompletion.acreate(
            model="gpt-3.5-turbo",
            messages=[{"role": "user", "content": self.intent_prompt.format(dialogue=dialogue)}],
            temperature=0.1
        )
        result = json.loads(response.choices[0].message.content)
        
        # 3. 预判(根据意图+用户行为轨迹)
        if result["intent"] == "价格询问":
            # 自动预判下一个动作:推送价目表卡片
            self.redis_client.setex(f"preact:{session_id}", 300, "send_price_card")
        elif result["intent"] == "技术故障" and result["confidence"] > 0.8:
            # 高置信度故障 → 直接转人工并附带设备信息
            return self.trigger_human_transfer(session_id, reason="技术故障")
        return result

实际部署注意​:不要每条消息都调大模型(贵+慢)。用规则前置过滤掉“你好”“在吗”等无意图消息,只有置信度低于阈值时再调LLM。

四、智能分配引擎:5+13种规则怎么设计?

文案提到“5种基础分配+13种高级分配规则”,本质是一个​可配置的规则引擎​。我们用Python的rule_engine库实现:

# allocation_engine.py
import rule_engine
from typing import Callable, Dict

class SmartRouter:
    def __init__(self):
        # 定义规则库
        self.rules = [
            {
                "condition": "intent == '售前咨询' and source == '抖音'",
                "action": "assign_to_group('电商组')",
                "priority": 10
            },
            {
                "condition": "is_vip == True",
                "action": "assign_to_agent('vip_support', skill_level>4)",
                "priority": 100
            },
            {
                "condition": "intent == '技术故障' and history_count > 3",
                "action": "assign_to_human('tech_team')",
                "priority": 90
            }
        ]
        self.rule_engine = rule_engine.RuleEngine()
        
    def decide(self, context: Dict) -> str:
        # context包含:intent, source, is_vip, history_count, current_load等
        for rule in sorted(self.rules, key=lambda x: -x['priority']):
            if self.rule_engine.evaluate(rule['condition'], context):
                return self.execute_action(rule['action'])
        return "assign_to_default_ai()"  # 默认给AI机器人

AI写代码的技巧​:把分配规则存到配置中心(如Nacos或etcd),运营人员可以直接修改规则,不用重启服务。这样你就能实现“5种基础+13种高级”的灵活组合。

五、人机协同:无缝切换的核心技术

文案亮点:“重复问题由AI处理,复杂问题无缝切换至人工”。关键是​会话上下文继承​。

# handoff_manager.py
class HumanAICoordinator:
    def __init__(self):
        self.redis_session = Redis()
        
    async def handoff_to_human(self, session_id: str, reason: str):
        """将AI当前会话转给人工,并同步全部上下文"""
        # 1. 获取AI已经回复过的历史(避免人工重复问)
        history = self.redis_session.lrange(f"chat:{session_id}", 0, -1)
        # 2. 锁定会话,防止AI再回复
        self.redis_session.setex(f"lock:{session_id}", 60, "human_transfer")
        # 3. 推送到人工队列,附带意图摘要
        await queue.push({
            "session_id": session_id,
            "reason": reason,
            "history": history,
            "predicted_intent": self.redis_session.get(f"intent:{session_id}"),
            "user_trace": self.get_user_trace(session_id)  # 访问轨迹
        })
        # 4. 在聊天窗口插入系统消息
        await self.send_system_message(session_id, "正在为您转接人工客服,请稍候...")

人工客服接起后,工作台会自动展示​访问页面、行为轨迹、历史对话​(对应文案中的“全方位展示”)。这部分前端用Vue/React实现消息流即可。

六、实时数据大屏:WebSocket推送+Redis Stream

文案提到“多维数据报表、全局数据大屏”。要实现秒级刷新,推荐方案:

# dashboard/dashboard_service.py
import asyncio
from redis import Redis

class MetricsStreamer:
    def __init__(self):
        self.redis = Redis()
        self.websocket_connections = set()
        
    async def start_collecting(self):
        """每2秒聚合一次关键指标"""
        while True:
            # 从Redis获取原始计数(每个客服端上报)
            total_convs = self.redis.get("metric:total_conversations")
            avg_wait = self.redis.get("metric:avg_wait_seconds")
            ai_handled_rate = self.redis.get("metric:ai_handled_rate")
            
            payload = {
                "conversations": int(total_convs or 0),
                "avg_wait": float(avg_wait or 0),
                "ai_rate": float(ai_handled_rate or 0),
                "active_agents": len(self.get_online_agents()),
                "hot_intent": self.redis.zrevrange("intent_ranking", 0, 4, withscores=True)
            }
            # 广播给所有前端大屏
            await self.broadcast(payload)
            await asyncio.sleep(2)

前端用ECharts或AntV实时渲染,数据大屏瞬间高大上。

七、多端工作台与风格自定义(小白也能懂的实现)

文案中“可视化组件和万能调色板”本质是​CSS变量 + 主题配置​。前端代码示例:

/* 主题变量定义 */
:root {
  --primary-color: #3b82f6;
  --bubble-ai-bg: #f3f4f6;
  --bubble-human-bg: #dbeafe;
  --font-family: 'Inter', sans-serif;
}

后台给运营一个调色板组件,修改后通过API保存,前端动态加载:

// themeManager.js
async function applyTheme(themeId) {
  const response = await fetch(`/api/theme/${themeId}`);
  const { cssVars } = await response.json();
  Object.entries(cssVars).forEach(([key, value]) => {
    document.documentElement.style.setProperty(key, value);
  });
}

这样连设计稿都不用出,客户自己就能把聊天框变得和品牌色一致。

八、总结与避坑指南

AI写代码心得​:

  • 不要一上来就怼大模型​:80%的请求可以用关键词+Embedding检索搞定,大模型只处理模糊意图。
  • 多渠道一定要统一会话ID​:微信用户的unionId、抖音用户的openId,在系统内部映射成一个统一客户ID。
  • ​**人机协同必须加“锁”**​:防止AI和人工同时回复一个会话,体验极差。
  • 数据大屏注意性能​:千万别每次刷新都查数据库,用Redis计数器+流式聚合。

最后,这套架构跑通后,你就拥有了一套类似合力亿捷的智能客服底座。剩下的就是对接具体渠道API和打磨意图模型了。如果你想看完整代码(包括前端Vue3组件、大模型微调脚本、K8s部署文件),评论区告诉我,我让AI连夜生成。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐