ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

几家信源都在说你,AI 却拼成了两家:实体对齐排查

几家信源都在说你,AI 却拼成了两家:实体对齐排查 这篇是“生成式引擎可见性”笔记的第五篇。前四篇分别写了怎么复测、能不能被读到、能不能被摘走、旧话怎么换成新话。四篇解决的是同一个层面的事——单个页面够不够格被机器读、被摘、被更新。这篇补的是那四篇都绕过去的一层引擎实际作答时很少基于单独一页它读的是把多家信源按“指同一件事”聚合之后的那张实体卡片。卡片拼对了前面的功夫才结算拼歪了前四篇全白做。全文只讨论公开可验证的技术形态不针对某一家引擎的实现细节下断言。一、每个页面都对不代表引擎知道那是谁先看一个很常见的排查现场某个连锁品牌官网门店页、地图门店页、点评商户页、行业站的介绍页都有它单看任何一页信息完整、格式规范、第三篇要求的字段也都在。可用户问 AI“这片区哪家好”答案里出现的却是相邻片区的另一家同名店或者把两家店的营业信息混在一段里说出来。把现象翻译成链路语言引擎不是逐页阅读再挑选而是先做一次跨源的归并——从不同信源里抽出一堆候选片段判断哪些片段指向同一个现实世界的对象聚成一张卡片再基于这张卡片决定带不带它进答案。这一步在工程上叫实体对齐也叫共指消解或实体解析entity resolution / coreference resolution。环节做什么拼歪之后的表现候选抽取NER从各信源里标出可能是实体的片段根本没把你抽出来答案是“查无此人”实体对齐归并判断这些片段是不是同一个东西抽到了但归错人信息被混写、被合并、或被判成别家卡片聚合与采信聚成一张卡片决定要不要进候选与引用卡片残缺或属性互斥进不去答案或进了也被压到最后这里有一个反常识的判断单页写得再规范解决的是“这一份材料合不合格”能不能进答案取决于它在归并时有没有被判成“我们说的那个东西”。 前者是页面级工作量后者是跨源级问题。很多团队前四步都做完了却没效果卡点就在这一层而排查方法完全不同——你没法在自家页面里找到证据得把所有提到你的公开页面摊开比对。二、拼歪的四种典型样子按出错位置分常见的失败模式有四类每一类的成因和解法都不一样。第一种名称漂移。 全称是“某某区某某皮肤管理中心”抖音上写成“某某皮肤管理某某店”地图页写成“某某美学空间”行业站又多了一个“某某轻医美”。它们是同一个工商主体写法却有四种。推一步看为什么这会影响结果在没有稳定唯一标识的情况下对齐主要靠字符串相似度加上下文共现来扛。名字之间相似度掉到阈值以下系统就会把它当两个候选实体分别保留。你以为的“文案不统一是小事”在链路里恰恰是归并判断的主依据。第二种属性冲突。 同一个对象地址有两个版本一个旧址一个新址、号码一个旧一个新、营业时间各家写各家的。这一步的关键理解是属性不是补得越多越有利它是用来做交叉验证的一致性证据。 出现互斥取值时稳妥的工程处理是把置信度降下来或者两个都留着不裁决。结果是卡片里每一项都“有”但没有一项能被高置信采信进答案的概率反而比字段少但全对齐的对象低。少写不乱写优于多写互相打架。第三种同名不同主体。 连锁品牌同城有多家店共享品牌词或者行业里两家不同公司名字相近。这类问题的表现最容易被误判——团队看到答案里提到了品牌但指向别家第一反应是“品牌词铺得不够”于是继续加词。推一步就知道这条路走不通问题不在“提没提到品牌”而在“有没有把品牌加片区加具体门店绑成一个三元组”。 缺了地理这一维系统面对好几个同名候选时没有裁决依据只能按热度或体量随机落一个。此时继续添加品牌词等于给一个公共池子里继续倒水落到自己这家店的概率不会提高。正确的解法是在所有信源里注入同一套地理信号并给每一家店各自稳定的内部标识。第四种缺唯一标识。 第四篇写过 URL 是页面的主键放到跨源这一层实体的主键是靠结构化数据里的稳定 id、sameAs 这类外部权威指向建立的。没有它们系统只能靠名字猜。再推一步这一条的代价分配是不对称的给不了标识就等于把裁决权交给概率而概率在天平时默认倾向证据多、体量大的那个。 小体量实体在这类判断里天然吃亏——不是因为它不好是因为它的可用证据少。补一堆重复内容补不回这个差距能补的是一致、少而可信的那几个锚点字段。三、把链路落成可以执行的动作把上面的机制倒过来动作其实很具体动作具体做法对应解决定标准名与变体表全渠道只用一个 canonical name其余写法列入 alias 清单逐步收口名称漂移结构化数据填齐LocalBusiness 类补齐 name、address 层级、geo 坐标id 一经发布不再变缺唯一标识sameAs 指向权威页指向能证明“这是同一个对象”的稳定页官网门店页、地图门店页、工商信息公示页、公开词条缺唯一标识NAP 逐源比对把各信源的店名、地址、号码拉成一张表逐列比脚本见第四节属性冲突注入地理信号每家店绑定“城市加片区加门店”且各信源写法一致同名不同主体三条容易忽略的约束sameAs 不确认就别写指向错误权威源的代价远大于不写id 的稳定优先于好看它承担的是主键角色逐信源统一比逐个信源优化更值钱因为这一层衡量的是一致性不是单页的丰富度。四、一份能自己跑的一致性自查脚本前面四篇都给了可执行的检查这篇同样落成代码。它的用途很朴素把你自己留存的各信源快照读进来抽核心字段做归一比对输出冲突清单。纯本地运行不发请求不依赖任何第三方服务。-- coding: utf-8 --“”实体一致性自查多个信源指向同一对象时核心字段是否自洽。输入本地留存的 JSON 快照人工整理或后台导出结构为[{“source”: “…”, “name”: “…”, “address”: “…”, “phone”: “…”}, …]输出字段级冲突清单。不联网、不依赖第三方库。“”import jsonimport reimport difflibNAP Name / Address / Phone本地实体归一最常用的三字段NAP (“name”, “address”, “phone”)def norm_phone(s: str) - str:“”“号码归一只留数字去掉分隔符与分机写法差异。”“”return re.sub(r\D, “”, s or “”)def norm_text(s: str) - str:“”“文本归一去空白、去括号与常见分隔符、统一小写。”“”return re.sub(r[\s()·・-—_/\、,。], “”, (s or “”).lower())def sim(a: str, b: str) - float:“”“近似相似度0~1。同一写法为 1.0。”“”return difflib.SequenceMatcher(None, norm_text(a), norm_text(b)).ratio()def load(path: str) - list:with open(path, encoding“utf-8”) as f:return json.load(f)def check(records: list, th_name0.85, th_addr0.90) - list:“”“逐记录比对首条基准写法返回冲突项。”“”if not records:return []base records[0]issues []for rec in records[1:]:# 名称允许 Abbreviation 级别差异超阈值即视为漂移s sim(base.get(“name”, “”), rec.get(“name”, “”))if s th_name:issues.append((rec.get(“source”), “name”, round(s, 3),base.get(“name”), rec.get(“name”)))# 地址容差更严一个门牌号的差别就足以造成互斥s sim(base.get(“address”, “”), rec.get(“address”, “”))if s th_addr:issues.append((rec.get(“source”), “address”, round(s, 3),base.get(“address”), rec.get(“address”)))# 号码数字串必须完全一致partial match 也算冲突if norm_phone(base.get(“phone”, “”)) ! norm_phone(rec.get(“phone”, “”)):issues.append((rec.get(“source”), “phone”, “mismatch”,base.get(“phone”), rec.get(“phone”)))return issuesifname “main”:data load(“snapshots.json”)for src, field, score, a, b in check(data):print(f[冲突] 来源{src} 字段{field} 相似度{score}“)print(f” 基准: {a}“)print(f” 实际: {b}“)print(f检查完成共 {len(data)} 份快照。”)两个使用提醒第一相似度阈值是经验起点名称 0.85、地址 0.90各行业的命名习惯不同建议先跑几轮基线再定自己的值第二这份脚本只提示“字段不自洽”不裁决哪个版本正确裁决要回到权威源工商信息、地图门店页、官网稳定页以它们为准去修其余各处而不是反过来把自己的错误版本铺到更多地方。五、三件别做的事别为了覆盖更多写法去制造新变体。 搜索时代有句老话叫多写关键词多一次机会放到对齐层是反的每多一种写法就多一次分裂成两个候选的风险。要想收录某个别称放进 alias 清单做结构化声明而不是在正文里随手再写一种。别在各平台“择优”填写。 同一个对象在不同平台写不同营业信息看起来是因地制宜落到卡片上就是互斥取值互相打架。这一层的评价函数认的是自洽不是各自的优化。别把 sameAs 指向拿不准的页面。 这是唯一一个“写错比不写更糟”的字段——它在语法上的含义就是“我指向的那个对象和我这个对象是同一个”指错了等于主动替系统做出了错误归并。六、边界三条说清楚免得这套东西被用过头各引擎的实现与召回策略不同同一对象在不同产品上的归并结果注定不一致。结论要基于固定问法的多次复测这是第一篇的题目。对齐层只解决“能不能被正确识别是谁”它不替你的产品说话也不替你的服务背书。卡片拼对了用户看到的仍是真实信息真实信息本身不占优卡片的正确搬运也救不回来。证据密度的作用是裁决不是加分。 把字段铺满是补齐信息的一种手段前提是所有写法最终指向同一个对象否则铺得越开分裂越多。五篇串起来是一条完整的链能复测、读得到、摘得走、旧话能换新最后这一步是“归回到同一个‘我’”。每一步做的都是同一件事——把真实发生过的事放到机器够得着、读得懂、并且能确认“是同一个人”的地方。用一句话收束让认真做事的人被看见。 剩下的部分取决于引擎侧的策略与节奏不在我们的控制范围内。FAQ问前四篇都做完了还是没效果优先查哪一条先查 NAP 三字段在各信源是否一致尤其是地址。地址是判定本地实体归属时分量最重的字段一个门牌号或两个不同版本的写法足以让前面所有页面级优化都归不到同一个对象上。问连锁多店每家店都该建独立页面吗应该。一个页面揉多店等于让系统自己切分切错的代价比不建更大。每家店一个稳定页面加一个稳定标识再把“城市加片区加门店”在每个页面上写一致。问变体都收进 alias 了还能再多写几种简称吗可以收但要收在结构化数据的 alias 字段里而不是在正文各处散写。前者是给机器的一份声明清单后者是在增加归并时的候选噪音。问怎么验证对齐有没有修好回到第一篇的复测固定一组问法含品牌加片区、品类加片区两类看答案里提到的对象是不是你、属性是不是各版本一致的一次性多个值。单次波动正常看的是连续几周的趋势。
返回列表