核心链路:连闲鱼 IM → 听买家消息 → 拉商品信息进 SQLite → 专家 Agent 生成回复 → 自动发回(可模拟打字延迟)。

核心工作流程

  1. 连接闲鱼消息通道:通过 WebSocket 连闲鱼 IM,用 Cookie 登录并维持长连接
  2. 监听买家消息:实时接收、解密并解析聊天消息
  3. 获取商品信息:按商品 ID 拉标题、描述、价格、SKU,缓存到本地 SQLite
    SQLite = 内嵌在程序里的小型本地数据库,一个文件存结构化数据,适合客户端 / 本地缓存。
    • 数据在本地单机、结构化、要查询 / 分页 / 多表 → 用 SQLite
    • 多机器共享、高并发写、集群部署 → 不用 SQLite
    • 只是简单配置、少量键值 → 用 JSON / 配置文件即可
  4. AI 生成回复:结合对话历史和商品信息,调用大模型
  5. 自动发送:把回复发回买家,可选模拟人工打字延迟

大模型:多专家 Agent

采用「意图识别 → 专家分发」:不同场景由不同 Agent 处理。

Agent 职责
ClassifyAgent 意图分类(兜底路由)
PriceAgent 议价:阶梯降价,议价次数越多温度越高,让步更灵活
TechAgent 技术咨询:参数、规格等,并开启联网搜索
DefaultAgent 通用客服:打招呼、物流、售后等

路由策略:关键词 / 正则优先(技术类 > 价格类)→ LLM 兜底分类。

主要业务功能

  • 上下文感知对话:SQLite 持久化对话历史,作为 LLM 上下文
  • 智能议价:按会话统计议价次数,动态调整回复策略
  • 人工接管:卖家发特定关键词(默认「。」)可切换 AI / 人工;人工回复写入上下文
  • 安全过滤:拦截微信、QQ、支付宝等引导线下交易的表述
  • 订单状态感知:识别「等待付款」「交易关闭」「等待发货」等系统提醒并记日志
  • 连接稳定性:心跳保活、Token 自动刷新、断线重连

轻量级多 Agent

架构优势:

  1. 轻量化:无复杂框架、无重型进程 / 会话管理,部署维护成本低
  2. 响应快:省去多 Agent 交互轮次,单链路执行,延迟更低
  3. 易管控:能力边界由 Prompt + 规则定义,行为可预期
  4. 迭代简单:新增专家只需补路由规则 + 对应 Prompt,不必改调度逻辑

重点:路由设计

一开始不调用 LLM 做语义分类

先跑硬规则:

  1. 关键词 / 正则匹配(如「型号」「参数」「多少钱」「便宜点」)快速判 tech 或 price
  2. 所有硬规则都匹配不到时,才调 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:本地文件库,存配置、聊天、日志、任务数据

极简运行流程

  1. 打开软件 → Electron 启窗口,加载 React + Chakra UI
  2. 用户操作 → Axios 调 Express
  3. Express 读写 SQLite,处理业务
  4. 底层抓到新消息 / 状态 → Socket.IO 推前端
  5. 前端刷新展示,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