新闻详情

新闻详情

首页 / 资讯中心 / 详情

一个客户裂成两个身份:形近字归一化越界污染白名单,4/4 复现后我拆掉了整条自动纠错链

发布时间:2026/9/28 4:40:40来源:尧图网络
一个客户裂成两个身份:形近字归一化越界污染白名单,4/4 复现后我拆掉了整条自动纠错链
我们这套微信自动回复工具里有一块很小、平时没人注意的代码:客户名归一化。它的职责说起来只有一句话——OCR 把客户名片上的「李文宇」读成「李文字」时,把误读纠回真名。上线三个月没出过事,出事是在一个周四的晚上:值班同事反馈「有个客户的消息永远不回」。排查下去的结果是,同一个人的消息被系统当成两个人轮着说,而会话切换判据每轮都判定「这个人切走了」,于是永久漏回。更难看的是第二个反馈:一个老板投诉说系统把「李女士」自动改成了「李先生」。当天夜里我们复盘时发现,这两件事的根子在一条链上——纠错结果被写进了白名单。一周之后,整条自动纠错链被拆掉,只留下一个收得很紧的保守版本。这篇文章把排查过程、错误判据为什么看起来总是对的、以及防线怎么重新摆位置讲清楚。## 1. 背景:为什么会有自动纠错这件事### 1.1 名字要过三道工序才成为判据客户给我们发消息时,系统需要先回答「这是名单里的谁」。数据链路是这样跑的:text名片截图 / 聊天窗口截图 │ ▼ OCR 引擎(tesseract + 自定义字符白名单) │ 原始识别文本,含误读 ▼ normalize_name() ← 形近字归一化,翻车主体 │ ▼ whitelist 精确 / 模糊匹配 │ ▼ 会话状态机(判断“这个客户切走了 / 切回来了”)形近字问题的来源是汉字本身:宇与字、己与已、未与末、氏与氐,OCR 置信度掉到 0.85 以下时读错很常见。而「名字是不是名单里那个人」又是一个硬判定——判对了正常回复,判错了要么冷场要么串聊。所以我们顺理成章地加了归一化这一步:把疑似误读纠正回真名,让匹配能命中。### 1.2 白名单:身份信息的来源白名单是一份本地 JSON,同时充当两件事的基准:哪些人算「我们的客户」,以及会话状态机的身份键。rustpub struct WhitelistEntry { /// 客户登记的真实姓名,纠错的目标基准 pub real_name: String, /// 微信 wxid,比名字更稳定的身份锚点 pub wxid: String, /// 备注来源: manual(人工录入) / learned(系统学习) pub source: Source,}设计约定很朴素:real_name只能由人工修改,系统的纠错只是「识别阶段的一次查询」,不改名单。现在回头看,这条约定被「让它自动回复」这个交互按钮轻易绕过去了——这是后面所有事的起点。另一个三个月没人注意这道工序的原因:归一化出错的代价不体现在报错日志里。纠错了名字,系统不抛异常,它只是「信心十足地匹配到了另一个人」。监控只看回复率和延迟,聚合指标一路健康,直到事故那晚才头一回变红。这是排查教会我的头一课:失败模式是静默的,就一定会等到人来反馈才暴露。## 2. 翻车一:等长形近字表把「李女士」改成了「李先生」### 2.1 一次数据重建里的巧合字表起初是人工整理的形近对。后来有一次白名单数据重建,为了省事,我们写了一段脚本从名单里「自动发现」候选纠错对:pythondef whitelist_reconstruct(old_path: str, new_path: str): old = json.load(open(old_path)) new = {} for e in old["entries"]: key = e["real_name"] # 把同一个人的多条记录折叠成一条 new[key] = e # 顺带“学习”:两两比对,发现只差一个字且都在 2~4 字内的, # 视为形近对,自动写入 homoglyph.json names = list(new.keys()) for a in names: for b in names: if a != b and one_char_diff(a, b) and same_len(a, b): homoglyph_pairs.add((b, a)) # b 视作 a 的误读 json.dump(...)问题出在one_char_diff + same_len这对判据上。名单里存在「张女士」「张先生」这样的称呼型条目——登记客户本人时用了「李女士」,客户配偶又登记了「李先生」,这在销售团队里非常常见。它们等长、只差一个字,被脚本当成形近对收了进去。女和宇、李和季这类真形近对混在里面,肉眼核对 700 多条字表时根本看不出来。### 2.2 「自动纠错」变成了「自动混淆」翻车后的归一化函数是这样工作的:pythondef load_homoglyph(path="config/homoglyph.json"): raw = json.load(open(path)) table = {}
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

PON全光网络深度解析:从GPON到XG-PON的配置与排障实战 2026/9/28 5:44:18

PON全光网络深度解析:从GPON到XG-PON的配置与排障实战

以前给朋友排查宽带问题,发现一个挺普遍的现象:家里明明升级了千兆宽带,光猫也换成了千兆口,可一到晚上用网高峰,测速还是跑不满,游戏延迟忽高忽低。路由器换了好几台,网线也全部换成六类线&…

阅读更多 →
做app网站需要什么条件:5万块避坑,拒绝被黑挂马 2026/9/28 5:44:18

做app网站需要什么条件:5万块避坑,拒绝被黑挂马

做app网站需要什么条件:5万块避坑,拒绝被黑挂马 上周一个做跨境电商的朋友半夜给我打电话,声音都劈了。他那个刚上线不到一周的官网,首页突然变成了一片黑色,中间跳出一行血红色的字:“你的服务器已中毒,点击购买解药”。后台更是乱成一锅粥,数据…

阅读更多 →
Emacs核心能力拆解:从Lisp到org-mode,打造高效文本处理工作流 2026/9/28 5:44:18

Emacs核心能力拆解:从Lisp到org-mode,打造高效文本处理工作流

如果你点进这篇文章,说明你多半已经听人提过 Emacs,或者正处在“想认真挑一个编辑器”的十字路口。再直白一点,你可能真的好奇:在 VS Code、Cursor、Jupyter 满天飞的 2020 年代,为什么还有人抱着一个 1980 年代诞生的…

阅读更多 →
一人创业工具链怎么搭?用 TaoToken 统一 Key 打通内容、开发与客户跟进 2026/9/28 5:44:18

一人创业工具链怎么搭?用 TaoToken 统一 Key 打通内容、开发与客户跟进

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
工作流核心原理与AI工作流实战:从节点要素到工具选型 2026/9/28 5:44:18

工作流核心原理与AI工作流实战:从节点要素到工具选型

工作流,Workflow,这个名词这几年几乎随处可见。不管你是后端工程师、运营、设计师,还是做跨境电商,总能听到“搭一个工作流”“把流程做成 workflow”的说法。尤其是 AI 工作流爆火之后,Dify、Coze、n8n、ComfyUI 这些…

阅读更多 →
电池健康度模型实战:从充放电曲线到SOH预测器 2026/9/28 5:44:11

电池健康度模型实战:从充放电曲线到SOH预测器

简介:这份资源围绕锂离子电池健康度(SOH)估算展开,利用神经网络与实测数据集训练电池老化模型,适合计算机、人工智能、自动化、电子信息等专业的在校学生、教师及企业员工学习,也可作为毕设、课程设计或项目…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉