背景痛点:传统客服系统为什么“扛不住”
过去两年,我帮三家电商公司升级客服系统,最怕的不是写代码,而是“一到大促就崩”。
传统客服架构基本是“人工+关键词机器人”:
- 并发一上来,WebSocket长连接把4C8G机器直接打满,CPU飙到90%,用户端出现“客服已读不回”。
- 意图识别靠正则,稍微换个问法就翻车,准确率常年60%徘徊,老板一句“还不如人工”就把项目判死刑。
- 多轮对话没有状态管理,用户问“那款红色连衣裙有L码吗?”→机器人答“有”→用户追问“那蓝色呢?”直接答非所问,体验原地爆炸。
痛点总结:高并发扛不住、NLU精度低、对话状态断片。想自己训大模型,GPU贵到哭;完全用云厂商SaaS,数据出域合规又过不了。于是我们把目光投向GitHub——用开源方案+CI/CD自己托管,成本可控,代码还能白嫖社区更新。
技术选型:Rasa vs LangChain vs MS Bot Framework
在GitHub上能直接拉到生产级的对话框架其实就这三位。
我把过去6个月的实测数据做成表格,统一在4C8G/10M公网带宽环境压测,QPS=Queries Per Second:
| 框架 | 冷启动时间 | 意图识别F1 | 多轮状态管理 | GitHub Star/月活PR | 备注 |
|---|---|---|---|---|---|
| Rasa 3.5 | 4.2s | 0.91 | 内置Tracker,对话回填顺滑 | 16.8k/180 | 需要写story,学习曲线陡 |
| LangChain 0.0.300 | 1.8s | 0.87 | 依赖Memory链,需自己写检查点 | 55k/600 | 链式调用灵活,版本迭代快 |
| MS Bot Framework | 6.5s | 0.89 | 依赖Bot State,云端优先 | 8k/40 | 国内网络延迟高,OAuth坑多 |
结论:
- 要“开箱即用”的高精度NLU→Rasa;
- 要“快速拼装”私有知识库→LangChain;
- 要“和Office365深度绑定”→MS Bot。
我们最终采用“Rasa负责对话状态+LangChain做意图embedding”的混合架构,GitHub Actions统一CI/CD,既保住精度,又能把迭代周期从2周缩到3天。
核心实现:三步把代码跑通
1. GitHub Actions CI/CD管道
在项目根目录建.github/workflows/bot-cicd.yml,push到main分支即自动打包镜像→部署到自托管服务器。
name: Bot-CI-CD on: push: branches: [ main ] workflow_dispatch: env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }}/bot-core jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # 1. 启动测试Redis & Postgres - name: Start services run: docker-compose -f tests/docker-compose.ci.yml up -d # 2. 跑Rasa数据验证 - name: Rasa data validate run: | docker run --rm -v $PWD:/app rasa/rasa:3.5-full \ rasa data validate --config /app/config.yml # 3. 单元测试+覆盖率 - name: Unit test run: | pip install -r requirements-test.txt pytest --cov=src --cov-report=xml - uses: codecov/codecov-action@v3 build-and-push: needs: test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@v4 with: context: . push: true tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} deploy: needs: build-and-push runs-on: [ self-hosted , prod ] steps: # 4. 服务器拉最新镜像并重启 - name: Deploy run: | docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} docker-compose -f prod/docker-compose.yml up -d bot-core2. LangChain意图识别模块
下面这段代码把用户问题转成向量,再检索FAQ库,返回Top-5候选意图给Rasa做最终排序,实测把意图F1从0.81提到0.91。
# src/intent_langchain.py from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import FAISS from langchain.schema import Document class LangChainClassifier: def __init__(self, model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"): # 多语言embedding,省显存 self.embeddings = HuggingFaceEmbeddings(model_name=model_name) # 载入离线FAQ向量库 self.db = FAISS.load_local("faq_index", self.embeddings) def predict(self, text: str, k=5) -> list[dict]: docs = self.db.similarity_search(text, k=k) # 把候选意图封装成Rasa可读的格式 return [{"name": d.metadata["intent"], "confidence": d.score} for d in docs]Rasa的config.yml里加一道自定义组件:
pipeline: - name: src.intent_langchain.LangChainClassifier name: langchain_intent - name: DIETClassifier epochs: 1003. Rasa对话状态管理最佳实践
- 用
RulePolicy兜底高频FAQ,减少故事量; - 用
TEDPolicy处理模糊分支,提升多轮泛化; - Tracker中打开
store_entities_as_slots=true,实体自动回填,省掉一堆slot_was_set。
故事文件示例:
version: "3.1" stories: - story: 订单查询路径 steps: - intent: order_query - action: action_order_search - intent: inform_order_id - action: action_order_detail性能优化:让机器人扛住双11
压力测试方案
用Locust写locustfile.py,模拟500并发,每个用户发10句随机问题,观察P99延迟。
from locust import HttpUser, task, between class BotUser(HttpUser): wait_time = between(1, 3) @task def ask(self): self.client.post("/webhooks/rest/webhook", json={"sender": "locust","message": "我的快递到哪了"})执行:
locust -f locustfile.py -H http://bot.example.com --users 500 --spawn-rate 50结果:
- 纯Rasa核心CPU占用78%,P99=540ms;
- 加上LangChain向量检索后,P99升到720ms,仍在1s内;
- 把FAISS索引预加载到内存,并开启
num_threads=4,P99降到610ms,符合生产要求。
冷启动问题
容器刚启动时,LangChain要加载transformers模型,耗时8s,Kubernetes就绪探针直接重启。解决思路:
- 在Dockerfile里加
RUN python -c "LangChainClassifier(),把模型先下载到镜像层; - 启动脚本里用
redis缓存FAQ索引,容器重启直接读缓存,无需重新建索引; - 配置
initialDelaySeconds=15,给足模型加载时间。
避坑指南:少踩三个坑,省两周加班
对话日志隐私合规
把用户手机号、地址用presidio脱敏后再落库;日志保留30天自动转储到冷存,满足GDPR最小化原则。多语言支持常见错误
中文+英文+粤语别用同一个embedding,否则“行”会被同时命中“行不行”和“银行”。做法:按语言路由到不同索引,LangChain里加语言检测fasttext-langdetect,准确率>97%。模型版本回滚策略
每次打镜像带git sha标签,Rasa的model文件存到GitHub Release;线上出问题,回滚只需docker tag <旧sha> latest && docker-compose up -d,2分钟搞定。
动手实验:把代码跑起来
- 打开示例仓库 https://github.com/your-org/rasa-langchain-bot
- Fork到自己账号→GitHub Actions会自动跑测试
- 把
prod/docker-compose.yml里的image改成你的ghcr.io地址 - 在
Settings-Secrets里配置服务器SSH_KEY、HOST,push main分支即自动部署 - 用Postman向
/webhooks/rest/webhook发一句“订单查询”,看到返回即成功
写在最后的碎碎念
整个方案跑下来,最贵的是时间,不是钱。开源组合+Rasa+LangChain,让三人的小团队也能在两周内交出生产级智能客服。
如果你也在为“并发高、意图飘、多轮断”头疼,不妨先fork仓库跑一遍,边踩坑边调参,很快就能看到“机器人终于听懂人话”的惊喜。祝各位上线不宕机,回滚不踩雷。