LLM 在生成结构化数据时可能会编造看似可信的事实。Entity Enricher 采用 8 层防护机制,确保你获得准确的数据或不返回数据——绝不返回听起来自信却虚假的内容。
在自由文本中,一句幻觉内容显然含糊其辞。而在结构化输出中,像 "founded_year": 1987 这样的幻觉字段看起来很权威,几乎无法与正确值区分开来。有三个因素使这尤其危险:
幻觉产生的 JSON 值看起来和真实值一模一样。没有含糊其辞,没有“大约”——只是一个干净、自信却恰好错误的数据点。
必填字段会迫使 LLM 即使在没有相关知识时也生成一个值。模型会编造数据,而不是在结构中留下空缺。
结构化数据可直接接入数据库、分析和自动化流程。错误的值会在管线中传播,而无需人工审核。
| 模式 | 示例 | 原因 |
|---|---|---|
| 自信的虚构 | "ceo": "John Smith" | LLM 用貌似合理的名称填充必填字段 |
| 时间混淆 | "revenue": "$2.3B" | 训练数据截止或时期混淆 |
| 实体混淆 | 将公司 A 的属性应用于公司 B | 重叠训练数据中的相似名称 |
| 合理的默认值 | "employees": 500 | LLM 宁愿选一个“看似合理”的数字,也不肯承认自己不知道 |
| 虚构的关系 | "subsidiary_of": "Alphabet" | LLM 推断出并不存在的关系 |
其中一些模式的根源在于架构,而非模型:像 revenue 这样的属性没有明确币种、期间以及范围是集团还是实体;而为实体根本不具备的信息起的名称,则让模型无从查起。歧义检查会标记这两种情况,列出该属性可能的各种解读,并建议用重命名或描述来锁定其中唯一一种。
Entity Enricher 不依赖单一技术。它叠加了 8 个独立的防御层,每一层针对不同的失败模式。如果某一层漏掉了幻觉,下一层就会将其捕获。
在丰富化开始前,一个快速的 LLM 会分类判断实体是否匹配模式类型。这可从源头阻止整个实体的幻觉。
示例:针对“Planet”schema 的“Titan”会被标记为卫星——扩充模型会收到该上下文,并对行星专属字段使用 null。
所有策略都会指示 LLM:“务必准确且保守——绝不臆造任何值。”模型会声明它无法确定的字段,而不是填入占位符,这些声明在输出中会变成真实的 null。
这直接缓解了模式压力——结构化幻觉的首要成因。声明未知值还能消除真实答案的歧义:模型确信的 0 是数据,而被声明为未知的 0 则不是。
Schema 属性按专业领域分组。每次 LLM 调用只看到其领域内的字段,并被指示专注于该领域。
范围越窄,产生幻觉的机会越少。金融专家从不臆测监管数据。
键属性(标记为 is_key: true)会在提示词中突出显示,以便让 LLM 在填充其他字段之前先锚定识别信息。
这使 model 立足于已知事实,减少向虚构细节的漂移。
增强输出会按模式的类型、格式和结构进行校验。校验失败会触发 ModelRetry——具体错误将回传给 LLM 进行修正,且修复是精准的:只对返回有误的叶子节点重新提问,而非整个结果。
单次智能体运行内最多自动纠正 5 次。(架构生成的自我纠正方式不同——按步骤进行,并带有确定性回退。)
标记为 preserve: true 的字段(ID、SKU、导入标识符)会在丰富化之后恢复为其原始输入值 — LLM 无法覆盖真实数据。丰富化请求必须为每个保留字段提供一个值,因此不会有任何字段被置为 null 或被凭空捏造。
在数组内部,丰富化后的项会通过其键字段与你的输入项进行匹配;AI 发现的新项会被赋予 null,而不是凭空捏造的标识符。
将同一实体通过 2 个以上独立模型运行,并逐字段对比输出。分歧会被标记为潜在幻觉。
如果 Claude 称营收为 23 亿美元,而 GPT-4 称为 18 亿美元——该冲突会被检测并呈现出来。
检测到的冲突可通过基于规则的投票(多数、中位数、并集)来解决,也可由专门的 LLM 仲裁器来解决,该仲裁器会评估准确性、完整性和一致性。
每个仲裁决策都包含推理过程和置信度——完全透明地展现冲突是如何解决的。
核心原则
数据缺失始终优于数据错误。每一层都强化了这一原则——系统在设计上宁可返回 null,也不会给出貌似合理的捏造结果。