核心技术特性
区别于传统 IVR 按键查询,AI 快递查询 Skill 通过状态机与大模型协同,实现真正自然语言驱动的全流程自动查询。
Skill 状态机架构
对话锁定在 express skill 内部,Branch A 负责锁定期间的日期追问,Branch B 负责首轮路由入口。状态与业务完全解耦,新增业务只需注册新 Skill 模块。
智能日期推断
System Prompt 自动注入当天日期。用户说「7月5号」,大模型结合上下文推断为当年日期,彻底消除跨年误判(如错误推断为2024年)。
查不到自动重问
日期无记录时返回 NEED_INFO 状态,保持 Skill 锁定,提示用户重新提供日期或结束查询,不会因为一次查询失败而退出流程。
防死锁 reject 计数器
锁定期间用户反复输入无关内容(投诉、闲聊等),达到 _REJECT_MAX=2 后自动解锁,清空 history,重走正常路由,彻底避免对话卡死。
关键词强制路由
「查快递」「物流查询」等高频关键词触发 _keyword_force_skill(),强制调用 by_phone 工具,补偿 qwen-plus 对短意图表达的路由不稳定性。
手机号零感知注入
来电手机号由系统 Context 自动传入所有工具调用,全程禁止向用户索取,客户无需手动报号,极大提升通话体验和查询效率。
完整业务流解析
从用户开口到查询完成,AI 自动完成以下全流程,无需任何人工节点介入:
关键词识别 · 进入 Skill
用户说「查快递」「包裹到哪了」等,关键词匹配或 LLM 意图识别触发 Branch B,调用 express_query_skill_by_phone。
查询日期列表 · 询问选择
系统按手机号查询数据库,返回有快递记录的日期列表,AI 播报给用户并询问「请问您想查哪一天的?」。Skill 进入锁定状态。
用户报日期 · 查询状态
用户说出日期(支持「7月5号」「第一个」「2026-07-05」等多种表达),LLM 推断标准日期后调用 express_query_skill_by_date,返回物流详情。
继续查询或结束
查到结果后询问「还需要继续查询吗?」,用户可继续报日期循环查询,或说「结束查询」触发 cancel_skill 解锁,返回正常 RAG 模式。
异常分支处理
系统内置多套异常处理机制,覆盖真实通话中的各类边界情况:
日期无记录
查询日期不存在时,返回 NEED_INFO 并保持锁定,提示「未找到该日期快递记录,请重新提供日期,或说"结束查询"」,不自动退出流程。
锁定期间插入无关话题
用户说投诉、闲聊等无关内容,locked prompt 拦截,LLM 不调工具,回复「请问您想查哪一天的快递呢?」,reject 计数 +1。
reject 计数耗尽 · 自动解锁
连续 2 次(_REJECT_MAX=2)无关输入后,系统自动解除 Skill 锁定,清空 history,重走 Branch B 正常路由,对话不卡死。
首轮直接给出日期
用户首句即说「查一下我7月10号的快递」,LLM 直接调用 by_date 跳过 by_phone 阶段,进入锁定并返回结果,减少不必要的交互轮次。
全功能矩阵
交互能力
口语化日期理解
「7月5号」「第一个」「下周一」「昨天」等自然表达均可正确解析为标准日期格式
序数词映射
用户说「第一个」「最后一个」时,结合 locked prompt 中的可选日期列表自动映射到具体日期
多轮连续查询
单次通话内可连续查询多个日期,每次查完后询问是否继续,用户说「结束」才退出
多种取消表达
「结束查询」「取消」「算了」「不查了」「没事了」等均可触发 cancel_skill 退出流程
系统能力
模块化注册架构
通过 register_skill(SkillModule(...)) 一行注册,新增业务无需修改路由总控文件 chat_skill.py
Tool Masking(工具掩蔽)
锁定期间只暴露 by_date 和 cancel_skill 两个工具,防止 LLM 在 Skill 流程中误触其他业务工具
History 隔离管理
进入 Skill 锁定时清空 history,防止历史消息污染当前 Skill 的 LLM 上下文判断
DB 接口预留
_query_dates() 和 _query_status_by_date() 函数独立封装,替换为真实数据库查询只需修改这两个函数
技术架构
AI 快递查询 Skill 在整体系统中的层级与调用关系:
Branch A(锁定):by_date · cancel_skill | Branch B(正常):by_phone · by_date
_query_dates() · _query_status_by_date() → 业务数据库
