闲鱼监控项目:轻量多专家客服与 WebSocket 接入坑点
核心链路:连闲鱼 IM → 听买家消息 → 拉商品信息进 SQLite → 专家 Agent 生成回复 → 自动发回(可模拟打字延迟)。
核心工作流程
- 连接闲鱼消息通道:通过 WebSocket 连闲鱼 IM,用 Cookie 登录并维持长连接
- 监听买家消息:实时接收、解密并解析聊天消息
- 获取商品信息:按商品 ID 拉标题、描述、价格、SKU,缓存到本地 SQLite
SQLite = 内嵌在程序里的小型本地数据库,一个文件存结构化数据,适合客户端 / 本地缓存。- 数据在本地单机、结构化、要查询 / 分页 / 多表 → 用 SQLite
- 多机器共享、高并发写、集群部署 → 不用 SQLite
- 只是简单配置、少量键值 → 用 JSON / 配置文件即可
- AI 生成回复:结合对话历史和商品信息,调用大模型
- 自动发送:把回复发回买家,可选模拟人工打字延迟
大模型:多专家 Agent
采用「意图识别 → 专家分发」:不同场景由不同 Agent 处理。
| Agent | 职责 |
|---|---|
| ClassifyAgent | 意图分类(兜底路由) |
| PriceAgent | 议价:阶梯降价,议价次数越多温度越高,让步更灵活 |
| TechAgent | 技术咨询:参数、规格等,并开启联网搜索 |
| DefaultAgent | 通用客服:打招呼、物流、售后等 |
路由策略:关键词 / 正则优先(技术类 > 价格类)→ LLM 兜底分类。
主要业务功能
- 上下文感知对话:SQLite 持久化对话历史,作为 LLM 上下文
- 智能议价:按会话统计议价次数,动态调整回复策略
- 人工接管:卖家发特定关键词(默认「。」)可切换 AI / 人工;人工回复写入上下文
- 安全过滤:拦截微信、QQ、支付宝等引导线下交易的表述
- 订单状态感知:识别「等待付款」「交易关闭」「等待发货」等系统提醒并记日志
- 连接稳定性:心跳保活、Token 自动刷新、断线重连
轻量级多 Agent
架构优势:
- 轻量化:无复杂框架、无重型进程 / 会话管理,部署维护成本低
- 响应快:省去多 Agent 交互轮次,单链路执行,延迟更低
- 易管控:能力边界由 Prompt + 规则定义,行为可预期
- 迭代简单:新增专家只需补路由规则 + 对应 Prompt,不必改调度逻辑
重点:路由设计
一开始不调用 LLM 做语义分类
先跑硬规则:
- 关键词 / 正则匹配(如「型号」「参数」「多少钱」「便宜点」)快速判
tech或price - 所有硬规则都匹配不到时,才调
ClassifyAgent做语义分类
高频场景用规则分流,省 Token、降延迟;边缘模糊问题再交给 LLM 兜底。
为什么严格限制 LLM「只输出类别名」
把 ClassifyAgent 收成高稳定、低开销的文本分类器:
| 限制要求 | 解决的问题 | 收益 |
|---|---|---|
只输出类别名(如 tech / price / default / no_reply) |
避免额外解释文本、输出不可控 | 下游直接字符串匹配,路由不易因格式崩掉 |
| 不做复杂指令解析 / 多轮对话 | 降低任务复杂度,减少跑偏 | 分类更一致 |
| 短输出(单词) | 减少 Token | 兜底调用成本极低 |
若不限制,模型可能回「这个问题是关于商品价格的,应该交给 priceAgent」,还要再解析,格式一变就失败。
no_reply:无效请求过滤
no_reply 表示不需要回复,直接结束流程,避免主模型空转。
| 用户消息 | 为什么是 no_reply |
处理 | 收益 |
|---|---|---|---|
| 「你好,在吗?」 | 纯打招呼,无明确问题 | 直接结束 | 少发模板话术 |
| 「帮我看看这个链接怎么样?」 | 外部链接,超出当前商品范围 | 直接结束 | 避免编造或违规回复 |
| 「能介绍一下你自己吗?」 | 闲聊,与商品无关 | 直接结束 | 少耗 Token |
| 「帮我骂一下上一个卖家」 | 违规 / 情绪发泄 | 直接结束 | 降低合规风险 |
ClassifyAgent 返回 no_reply 时:不调专家、不发消息,只记日志,方便后续补规则。
可扩展点
- 规则分层细化:给售后、物流等补关键词 / 正则,减少 LLM 兜底
- 规则缓存:高频命中规则本地缓存,避免重复匹配
- LLM 分类降级:兜底用更小模型,甚至本地分类模型
主流程:路由 → 选 Agent → 生成回复
每次调 LLM 时,消息结构统一为:商品描述 + 历史对话 + 专家 prompt + 当前用户消息。
各专家差异
PriceAgent — 阶梯议价
议价轮次越多,temperature 越高(最多 0.9),回复更灵活、让步空间更大。配合 price_prompt_example.txt 里的梯度让步策略。
TechAgent — 联网搜索
技术类问题开启搜索(依赖 MaaS 平台是否支持该参数)。
DefaultAgent — 通用兜底
temperature 0.7,处理「在吗」「什么时候发货」等。
安全:所有 Agent 输出经 _safe_filter,拦截「微信、QQ、支付宝、线下交易」等,避免引导脱离平台。
所有新增功能必须配备独立开关,支持按灰度维度启用,出问题可快速回滚。多一个配置项 + 一层 if,换线上风险可控、故障止损、迭代更快。
桌面 SaaS 壳:技术分层
面向通用电商智能客服桌面端的一层拆法。
UI 壳层:Electron + React + Chakra UI + Framer Motion
- Electron:网页技术打包成独立桌面客户端;提供 IPC,让界面和后台互发指令
- React:页面、组件、交互与状态
- Chakra UI:现成组件库,快速搭规整界面
- Framer Motion:弹窗、列表、状态切换动效
业务中枢:Node.js + Express + Socket.IO + SQLite
- Node.js:本地后台运行环境
- Express:HTTP / REST,查配置、存设置、查日志
- Socket.IO:实时推送新聊天、运行日志、任务状态
- SQLite:本地文件库,存配置、聊天、日志、任务数据
极简运行流程
- 打开软件 → Electron 启窗口,加载 React + Chakra UI
- 用户操作 → Axios 调 Express
- Express 读写 SQLite,处理业务
- 底层抓到新消息 / 状态 → Socket.IO 推前端
- 前端刷新展示,Framer Motion 做过渡
WebSocket 使用:四个关键坑点
1. 分层鉴权:HTTP 取令牌 + WebSocket 注册
先 HTTP 换 current_token,再在已建立的 WebSocket 上发 /reg,完成设备与长连接绑定。HTTP 管短平快发令牌,WebSocket 管长连接绑定;少一步就收不到推送。
2. 注册时序:硬编码等待代替响应确认
发 /reg 后未等成功回执,只用 sleep(1) 就继续。网络一抖,后续 ackDiff 可能失败,收不到消息甚至被断开。应改成事件驱动:等成功回执再往下走,超时重试。
3. pts 不持久化:重连丢历史
pts 是消息同步游标,告诉服务端本地已同步到哪。每次启动 / 重连用当前时间当起点、不落盘,等于只从「现在」开始收。重启或闪断期间的离线消息会漏,自动回复场景会出现漏回。
4. 令牌刷新:过期后全链路重建
token_refresh_loop 发现过期或临近过期时 ws.close(),再完整走:取 token → 新建连接 → /reg → ackDiff。实现简单,但刷新会有短暂中断;再叠 pts 不持久化,丢消息概率更高。
可靠 IM 客户端最核心的工程坑:分层鉴权、时序可靠性、消息补全与幂等、令牌续期与重连。
流程与代码对应
| 能力 | 代码实现 |
|---|---|
| 实时监听买家消息 | async for message in websocket 长连接 |
| 解密、解析 | decrypt() + handle_message() |
| 按商品 ID 拉 Title / Desc / Price / SKU | XianyuApis.get_item_info() + build_item_description() |
| 缓存到本地 SQLite | context_manager.save_item_info() → data/chat_history.db |








