Towards Data Science

I Built a Claim-Checker for Writing With Codex. It Passed a Wrong Claim.

6.9内容质量

TL;DR · AI 摘要

I Built a Claim-Checker for Writing With Codex. It Passed a Wrong Claim. Towards Data Science LLM Applications I Built a...

核心要点

  • 主题聚焦:I Built a Claim-Checker for Writing With Codex.
  • 来源:Towards Data Science,建议结合原文判断细节。
  • AI 分析暂不可用,本条为保底评分与摘要。
#AI#编程#前端#安全#开源
打开原文

我为使用Codex写作构建了一个声明检查器。它通过了一个错误的声明。| Towards Data Science

LLM Applications

我为使用Codex写作构建了一个声明检查器。它通过了一个错误的声明。

该工具虽然找到了正确的段落,却忽略了不匹配之处,而审计结果展示了基于规则的检查为何会失效。

Benjamin Nweke

2026年10月16日

8分钟阅读

在Google上关注我们

分享

图片由Alex Kovshovik提供,来自Pexels。

我必须仔细思考技术成果的表述方式,尤其是在句子被改写以显得更简洁时。我见过的一个常见错误是将错误率降低20%表述为准确率提升20%。错误率减少20%只是将一个本就很小的剩余数字进一步缩小,因此准确率本身几乎不会发生变化。数字在改写后依然存在,但它所描述的内容却完全改变了。

这种错误足够微妙,以至于快速浏览时可能被忽略,因为句子中没有任何部分看起来不协调。召回率可能悄无声息地变成准确率,一个数字可能在不经意间偏离10个点,或者一个观察到的相关性可能在通往更简洁句子的途中被赋予因果动词。正是这类错误,促使我开发Evidence Desk来协助捕捉。

Evidence Desk是我使用Codex构建的浏览器工具。你只需提供草稿及其来源文件,它就会将草稿拆分为声明。对于每个声明,它会在来源中找到最接近的段落,并对其进行若干明确检查;最终返回三个标签之一:有支持依据、潜在不匹配或证据不足。

我使用Codex协助实现了界面、检查逻辑、测试以及围绕我已有构想的工作流程的其他部分。我的工作是决定工具应检查的内容,并审查其行为是否符合目标。

上述错误与准确率的示例来自工具内置的虚构样本,该样本围绕一个虚构的分类器Meridian展开,同时也恰好最清晰地展示了此类工具何时会失去可靠性。

检查与写作是不同的工作

一个写作能力出色的模型旨在生成可信的文本。而检查则关注关系:这些证据是否真的支持声明?这是一个比声明本身是否真实更小的问题。来源可能有误,而声明仍可能忠实于它,对于技术写作而言,这种忠实性通常是首先需要关注的部分。

你可以让第二个模型来审查第一个模型,这方法也有效。我并非反对这种方式。我看到的权衡是,审查者本身也是生成式的,其结论可能缺乏可以争论的依据。Evidence Desk选择更狭窄的路径,每个警告都会附带相关段落和原因,因此作者有具体的内容可以反驳。

工作流程

图1. Evidence Desk的审查流程。草稿中的每个声明都会匹配到来源中最接近的段落,并经过数值、指标和因果检查,最终由作者做出决定。图片由作者提供。

声明提取故意设计得较为粗略。它在句尾和空行处进行分割,忽略标题和少于五个词的内容,最多保留40个候选声明。所有处理均在浏览器端完成,审查流程不会发出任何网络请求。

高分证明不了什么

检索仅基于纯词汇重叠,足够简短,可在此展示(来自evidence.ts,行为未改变):

typescript

code
// 代码内容保持原样未翻译
code
// 声明中在段落中出现的唯一词的比例
// 未加权计算:'classifier' 与 '20%' 的权重相同
export function overlapScore(claim: string, passage: string) {
const want = new Set(words(claim));
if (!want.size) return 0;
const have = new Set(words(passage));
let hit = 0;
for (const w of want) if (have.has(w)) hit++;
return hit / want.size;
}

当重叠度达到 0.25 时,段落即可被视为证据;达到 0.48 时,声明可被判定为"Supported"(支持)。这两个阈值是人工设定的,未经过校准。这是一个词频比例,而非语义相似度,更不能代表声明为真的概率。

Meridian 的准确率声明展示了这种设计的局限性。在错误段落的测试中,该声明获得了 86 分,是所有段落中最高的,因为该草稿正是基于该段落编写。高分仅说明句子与来源的接近程度,而扭曲的改写在定义上也属于"接近"。检索系统找到了正确的段落,但无法察觉该段落内容存在矛盾。

检查机制的作用与局限

有三个检查机制位于顶层。数值检查会从声明和检索到的段落中提取数字,去除逗号和空格后,对段落中未包含的声明数字发出警告。指标检查会查找混淆的评估术语。因果检查则会在声明中查找"caused"和"led to"等词,并期望段落中也包含类似的因果表述。

数值检查具有实际价值。当声明称分类器达到了 95% 的召回率时,系统检索到了报告 85% 的句子,而警告"95% 在证据中未出现"是正确的。精确匹配虽然粗暴,但能捕捉到数字被篡改的情况。

这种粗暴性也存在反面影响,因为同样的检查机制可能对实际正确的声明产生误判。

当我在一篇文章上测试该工具时,包含 84% 和 60% 的句子触发了数值警告,原因很简单:检索到的段落只包含其中一个数值。该检查将缺失的数值直接视为不匹配,完全未考虑证据可能分布在两个段落中的可能性,而仓库中的规则仍然保持这种处理方式。

我更希望看到的工具是,当无法确认数值时明确表示无法确认,而不是自信地发出警告。我对界面是否给出判断结果的关注度,远低于对能否合理解释判断依据的关注度。

指标检查是设计的局限性所在。以下是来自 evidence.ts 的代码片段,行为保持不变:

code
const METRICS = /\b(accuracy|precision|recall|error|f1|auc)\b/i;
// 仅在声明提及的指标未在段落中出现时触发
const claimMetric = claim.match(METRICS)?.[1]?.toLowerCase();
if (claimMetric && METRICS.test(best.text) && !new RegExp(`\\b${claimMetric}\\b`, "i").test(best.text)) {
reasons.push("Possible metric confusion: ...");
}

该检查仅在声明中第一个指标词未出现在检索段落时触发。Meridian 段落在第二句提到了 accuracy,因此保持沉默,数值检查也因两边都有 20% 而未触发警告。

在样本草稿上运行引擎时,accuracy 声明获得 86 分,被判定为 Supported。数值与所衡量的指标之间没有关联:在原文中 20% 属于 error,在草稿中却属于 accuracy,而两个检查机制都将段落视为词和数字的集合。

我原本期望这个样本能快速展示检查器是否正常工作。但屏幕上的结果却与引擎对相同主张和来源的返回结果不一致。该样本包含存储的评审,因此显示“准确性主张存在潜在不匹配”,而将相同文本通过实际检查逻辑运行后却返回“支持”。

在一款旨在帮助人们验证主张的工具中发现这一问题令人尴尬。界面显示的是我期望看到的结果,却未显示引擎能够生成该结果。

因果检查本身也存在盲点。在样本中,主张“使用学习助手导致考试成绩提高”会调取关于分数差异的段落,而该段落中没有因果词,因此主张被标记。这看起来像是检查机制在正常工作。

实际上起决定作用的句子在下一段中,它指出“结果并未证明助手导致了差异”。因此,“导致”这个词确实存在,只是被否定语从句包裹。将主张重述为“助手导致了学生之间的分数差异”,检索会精准定位到该句子,因此主张以50%的置信度返回“支持”。

关键词匹配完全无法识别否定,而样本之所以能捕获因果主张,仅仅是因为某个段落恰好排名第一。

一个尚未纳入仓库的候选修复方案将进行三个小改动:分词时去除尾随标点、要求每个匹配的数字必须与主张的度量词位于同一句子、将否定从句中的因果关键词视为缺失。

该原型方案已能清除本文描述的所有失败案例,且现有三个测试仍能通过。它仍属于启发式方法,因为数字和度量词可能位于不同句子中。

表达“证据不足”

“支持”意味着最强匹配段落通过了检查。“潜在不匹配”意味着触发了检查或重叠度较弱。“证据不足”意味着没有段落达到0.25阈值,且绝不能被解读为“错误”。

当模型声称“在识别罕见案例方面表现更好”时,若来源显示少数类召回率从0.41提升至0.58,该主张将得分为零。工具会报告“未找到任何信息”,这是对无法解析的改写文本的诚实输出。

界面为每个主张显示匹配段落、前三候选段落及原因。它仍可能误导用户。重叠度在25-48之间的“潜在不匹配”会完全不显示原因,因为弱重叠规则未提供说明。

失效场景

词汇匹配完全无法识别改写,如那个零分案例所示。分词器会将句尾的句号保留在最后一个词上。以“students.”结尾的主张无法匹配段落中“students”的中间位置,这导致“飞行员包含84名学生”的主张检索到文档标题并因错误原因获得数值警告。

引擎完全没有夸大检查机制,“always achieved a recall of 85%”会被标记为“支持”。主张是单句结构,因此先前定义的代词或数字会丢失上下文,40条主张的限制也会截断长文稿的其余部分。

测试覆盖范围小于界面显示。目前只有三个测试,且未涉及度量检查、因果检查或阈值判断。没有基准衡量警告的准确率,我也不会假装存在这样的基准。

一个忠实的声明即使与错误的来源进行核对也能顺利通过,因为该工具仅将声明与提供的材料进行比对,不会考虑其他因素。

···

我从中得到的启示

撰写句子与核查证据是两个独立的步骤,它们的失败方式也各不相同。

高重叠分数仅表明草稿是基于某段文字撰写的,因此检索功能可能定位到正确的段落,却仍然会忽略其中存在矛盾。

单纯匹配数字也不够,因为一个数据必须与它所衡量的对象相关联,否则像将误差率替换为准确率这样的错误才可能发生。我宁愿部署一个能清晰说明这些局限性的核查工具,也不愿使用一个给出自信结论却存在误导的工具。

作为检查辅助工具,这类工具的价值在于将草稿缩小到值得重新阅读的声明部分。一旦有人将它的结论视为绝对真理,它就不再具有实用性。

代码托管在 GitHub 上,ShipAI 的操作指南展示了该工具的界面使用方式。

EvidenceDesk

一个基于 Codex 构建的声明核查工作空间:技术作者将草稿与原始资料并排展示,关键词和规则检查会标记出原始资料未支持的声明。

Benjamin Nweke · 1 min read