找出可能在问多个问题的架构属性——并排查看相互冲突的解读,在采集数据之前把每个属性锁定为单一含义。
Entity Enricher 把 LLM 当作可查询的知识库,而属性名称就是你提出的问题。当名称存在多种解读时,每个模型都会悄悄选定其中一种——于是公司上的 size 属性,有的模型返回员工人数,有的返回营收数字,还有的返回占地面积。模型并不是在某个事实上产生了分歧,而是回答了不同的问题,你的这一列现在混杂着各种答案,下游使用者根本无法区分。
锁定含义,才能让一次丰富化在不同模型之间可比、并随时间保持稳定。它也会理顺下游的一切:多模型融合不再把实为两个问题的差异当成冲突,基准测试对比也不再因为模型对你架构的解读与参考答案不同而惩罚它们。
事实随时间变化并不等于歧义。架构是一份长期契约,因此名称直白的 ceo 表示“富集时的 CEO”,明年重新运行该架构就应返回新任 CEO。该检查绝不会建议把某个日期固化进名称——那会让今后每一次运行都失效。
整项检查其实就是对每个属性提出的一个问题:在其父对象的语境下读它的名称,它可能在索取多少种不同的东西?这个数量就是判定结果。
| 解读 | 裁定结果 | 这意味着什么 |
|---|---|---|
| 有且仅有一种 | 清除 | 所有模型查的都是同一件事。没有标签,也无需修改。 |
| 两个或更多 | 有歧义 | 每个模型都按自己的解读作答,于是这一列悄悄混入了对不同问题的答案。该检查会指出相互冲突的解读,并给出只保留其中一种的措辞。 |
| 无 | 无法映射 | 该名称并未指向父对象拥有的任何东西,因此模型无法查到对应的值——它只能编造一个。列出的解读是分析器考虑后否决的那些,补救办法是重命名或删除:任何描述都无法让实体凭空拥有它并不具备的属性。 |
即使属性指向的事物唯一,只要取值缺乏框定,仍可能被标记——读者知道在问什么,却不知道答案会以何种形式返回。常见的情形有:
| 子情形 | 示例 | 未明确之处 |
|---|---|---|
| 指代对象不明确 | Companysize | 该名称同时指向父级确实拥有的多个不同事实——员工人数、收入、建筑面积。名称本身没有做出任何选择。 |
| 度量或单位不明确 | Companyannual_revenue | 只有一个事实,却没有货币、没有时间区间、也没有总额/净额口径——一个看似合理的答案可能相差三个数量级,却仍然“正确”。 |
| 量表或方向不明确 | Supplierrisk_score | 既未说明取值范围,也未说明方向性:是 0–10 还是 0–100?数值高代表更安全还是风险更高?两个模型可能给出完全相反的结果。 |
| 范围或边界不明确 | Companyemployees | 哪个子集、哪个汇总层级、以谁的视角——是整个集团还是本地点,是员工人数还是全职当量,外包人员计入还是排除。 |
| 无法映射 | Authorrelease_year | 作者没有发行年份——有发行年份的是他们的作品。模型无从查证,只能编造。请把它重命名为父对象确实拥有的属性,或移动到真正拥有它的对象上。 |
叙述型属性——description、summary、notes、bio——永远不会被标记。它们的措辞在不同模型之间显然各不相同,但所问的问题非常明确,而这正是本项检查唯一评判的内容。歧义针对的是问题本身,与答案之间有多相似无关。
只给出一个判定(“这里不清晰”),会让你去猜分析器究竟在想什么。因此每条结论都附带其解读列表:该属性可能对应的两到四种简短且互不相同的解读,最可能的排在最前。这份列表就是结论本身——如果分析器说不出两种解读,该结论会被当作噪声丢弃,而不会展示给你。
annual_revenue 在 Company 上与之一并给出的还有一条建议描述,它只保留其中一种解读——这里是“最近一个完整财年的集团总收入,以美元计,未扣除退货”。采用它没有任何代价:描述会与名称一样原样传给执行富集的模型,而属性名保持不变,因此数据契约不会发生变动。当名称本身就具有误导性时,该结论还会附带建议名称。
把各种解读逐一列出来,通常比任何解释都更快地敲定一个属性:你会认出自己想要的那一个,而其余的正是你一直在悄无声息地收到的东西。
生成样本后,分析器会检查其属性名称并返回一份歧义报告。对于 AI 自行生成的键,无歧义的重命名会自动应用(绝不会应用于你自己命名的字段),因此你看到的样本读起来已经更清晰。它还会标记过度特化的属性——这些特征来自示例实例,只适用于某个子类型(例如在通用的 Person 上出现运动员的奖牌)——并建议改用范围更窄的实体类型。身份界定检查随后作为一次独立调用在此运行:它会在你审阅样本之前确定关联条目的结构。基于附件文档生成的样本会被跳过——它们的取值来自源文档,而非模型的记忆。
生成的架构一经保存,后置流程会为每个属性标注歧义判定,并为仍存在歧义的属性建议重命名。此时关系位点已经完成标注——生成过程会在自身的某个步骤中判定其身份界定——因此后置流程只覆盖属性名称。该步骤为尽力而为:即使失败,也不会影响生成本身。
“重新检查”按钮会以两个并行调用运行这两项检查——属性名称和关系位点。这里是唯一一处建议改写描述而非重命名的地方。它只分析尚未标注的内容;一旦所有内容都已标注,就切换为全量重新分析。
你为创建架构而粘贴的示例 JSON 可以无状态地进行分析——你会得到一份报告,列出有歧义和无法映射的属性名称,以及把实体事实与配对事实混在一起的关联条目,而不会修改任何内容。
同一条发现,在一处建议重命名,在另一处却建议改描述,其中的原因值得了解。在生成阶段,描述还不是独立存在的——它是根据名称写出来的,因此只会重复同样的歧义。名称是唯一可以修正的东西,而且此时还没有任何东西依赖它。这就是为什么样本生成和架构生成的后置流程都建议重命名。
架构上线之后,重命名属性会移动列、破坏查询并为已同步的表重新设定键,而更精准的描述同样能直接传达给模型,却不会带来其他改动。所以规则很简单:在还没有任何东西依赖该架构之前,就重命名;一旦上线,则用描述锁定含义——并把重命名留给名称本身确实有问题的情形。
该检查仅供参考。不会有任何东西在后台分析你已保存的架构:它只在生成时运行,以及你按下“重新检查”时运行。它绝不会阻止生成,也绝不会拒绝一次丰富化,而且它的注解会从发送给丰富化模型的每一条提示词中剥离——它是提示你,而不是提示 AI。
被标记的属性会显示一个“存在歧义”标签,位于工作流编辑器中:若各种解读大体重合、只在边缘情况上有差异,标签为琥珀色;若相互冲突的解读会带来实质不同的数据,则为红色。判定清晰的属性不带标签。将鼠标悬停在标签上,会显示分析器的说明、它发现的冲突解读,以及建议的描述或名称——判定与修改方案就在同一个提示框中。
判定是针对属性的名称和描述整体做出的——因此重命名属性或修改其描述都会清除已有标注。编辑器会把这类属性标为已过期,并提供重新检查,只分析缺失的部分。在采用建议的修改之后,这正是你需要的:重新检查会确认新的措辞是否真正锁定了唯一解读。
身份界定是第二项检查,作为独立的模型调用与歧义检查一同运行,并一并报告。它会审视每一处关系位点——关联数组的项以及嵌套对象:当某一项把关联实体自身的事实(名称、国家)与配对关系的事实(在此父级下担任的角色、各父级专属的称谓)混在一起时,两者共用同一个身份——而重新扩充会跨父级覆盖配对关系的事实。此类位点会带有琥珀色的“事实混杂”标签,其提示框会给出推荐结构:把实体自身的字段嵌入一个子对象,配对关系的字段仍留在该项上。如果该项已包含这样的子对象,改动会更小——只需把放错位置的字段移入已有的子对象。
拆分会在样本生成期间、你批准样本之前应用:结构在第一个样本上确定,每个被重构的位置都会列入生成警告,该批次的其他样本则按已确定的结构生成。因此,由全新样本生成的架构通常不会有问题。基于附件文档的样本会保持其源文档所暗示的结构,转而带上该标签。
架构生成本身绝不会重构你已批准的样本——它只会判断同样的位置并报告发现的问题。因此,对于已有的或手写的架构,修复入口就在标签上:它提供一键拆分,重构样本并据此重新生成架构。结构即契约,因此只能通过从新样本重新生成来更改,绝不会就地修补。你选择不拆分的位置仍可正常工作——只是会保持一个共用身份,并保留该标签。当该项的字段集发生变化时,标签会自行消失。
该检查可在工作流编辑器的溢出菜单中按架构逐一关闭。关闭后,生成后的处理流程将被跳过,标记、“重新检查”按钮和过期警告都会隐藏,分析端点会返回 ambiguity_check_disabled 错误。已有的注解会被保留(只是隐藏);而对从未分析过的架构重新启用检查时,检查会自动运行。
每个生成的架构默认开启该检查,包括由附件文档生成的架构。歧义取决于架构的措辞方式,而非某次运行的取值来源:文档只是一次性确定了那些取值,而架构此后仍会被反复用于它从未覆盖的实体。文档真正改变的是示例环节——其属性名来自源文档自身的词汇,因此绝不会在代码中被重命名,检查转而由基于它们构建的架构承担。
“公司的年收入”并未提供名称之外的任何信息,因此分析器会把这类描述视为不存在,仅根据名称做出判断。描述只有明确了单位、周期、口径或边界,才真正有价值。
分析器的说明和解读以你的界面语言呈现——法语用户看到法语解读,日语用户看到日语解读。建议的属性名称保持英文,以符合架构命名规范。
每次分析都是一次真实(且低成本)的模型调用——当还有关系位点需要界定时,会并行发起两次调用。每次调用都会作为独立的提示词记录在该记录上,类型为 ambiguity_analysis,并像其他 AI 用量一样扣除积分。增量重新检查只会为实际分析的属性和位点付费。
样本生成和架构生成本身就被要求:每个属性只命名一件事,并在描述中写明单位、量表和边界;对于有争议的列表,则在描述中给出上限,而不是把数量硬塞进名称里。因此大多数架构生成出来就是干净的,分析器只需捕捉少数漏网之鱼。
该检查也可通过编程方式使用:
| 表层 | 描述 |
|---|---|
POST /api/schema/analyze-sample | 分析粘贴的样本 JSON——一次请求并行执行两项检查,无状态报告,不修改任何内容 |
POST /api/schema/saved/{id}/analyze | 分析已保存的架构并写入两项检查的注解——默认增量分析,force=true 则重新分析全部 |
POST /api/schema/scoping-split | 对样本集应用一次“混合事实”拆分——确定性、免费、不保存任何内容;将返回的样本重新用于架构生成 |
analyze_sample | MCP 工具——同样的无状态样本报告,包含两项检查,可从 Claude 或任意 MCP 客户端调用 |
analyze_schema | MCP 工具 —— 为已保存的架构添加注解;与 update_schema 配合使用,可应用建议的描述或重命名 |
返回的结论包含 kind(ambiguous 或 unmappable)、level、一条说明、interpretations 列表以及建议的修改。在已保存的架构中,它们以 ambiguity 的形式存储在每个属性上;样本生成则在 ambiguity_report 下返回它们。