ARTICLE DETAIL

资讯详情

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

按讲式事实核查器:从语音到证据判断的实时工程实践

按讲式事实核查器:从语音到证据判断的实时工程实践 我把事实核查从文本框里搬到了手指上。按住空格键说一句话松开屏幕会在两秒内告诉你这句话里的断言有没有证据支撑。这就是我在业余时间完整实现的The Truth Machine: A Push-to-Talk Fact Checker——一个按讲式事实核查器。做这个项目的起因很简单纸面上的事实核查工具已经足够多了但它们都要求你先有一段成形的文字再手动选中那句可疑的话点按钮等结果切换标签页阅读来源。这套流程在写长文时没问题可一旦你身处真实对话中——采访嘉宾时听到一个惊人的数字、播客里朋友随口抛出一个断言、直播前快速回顾自己准备好的金句——文本工具根本来不及。你需要的是按住就查、松手出结果的瞬时反馈这就是按讲交互的价值。这篇文章会完整拆解这个工具从录音、转写、断言提取到证据检索与事实判断的落地过程包括那些真正让我头痛的失败案例。1. 按讲交互的底层逻辑为什么是按住说话而不是常驻监听绝大多数语音工具的第一反应是始终开着麦克风像智能音箱那样用一个唤醒词触发。我一开始也尝试过这个方案但在事实核查这个具体场景里常驻监听是致命的。1.1 让核查行为显式化反而更快按讲的本质是给系统一个非常明确的边界从按下到松开这段音频里的话是我要求核查的内容边界之外的噪音一律忽略。这个显式边界带来两个直接好处。第一不会误触发。记者在房间里走动、翻笔记本、和旁边同事说稍等这些杂音都不会被当成核查请求。唤醒词方案需要先检测嘿机器这种固定短语再等待后续指令任何口误或环境音都可能导致割裂造成用户心理上的不确定感。按讲则完全消灭了这个问题你按下去的那一刻机器就知道开始了。第二语境完整。事实核查最怕的是只抓到半句话。常驻监听从唤醒词出现才开始录音经常丢掉句子的前半段。而按讲允许用户自己控制录音的起止哪怕你要核查的是一个从句开头的内容也可以按着自己说完整了再松开。1.2 按讲 vs 文本输入 vs 常驻监听的取舍方案触发速度语境完整性误触发率适用场景文本输入慢需要键盘粘贴完整无长文核查、深度阅读常驻唤醒中唤醒词命令部分高通用助手不适合核查按讲快按下即录由用户控制极低对话场景、访谈、直播如果只是做网页里的一个按钮按讲还能进一步降低使用门槛。桌面端我用键盘的空格键做全局热键按住说话、松开提交移动端则用屏幕上的大按钮。整个交互模仿对讲机用户不需要学习任何新东西。1.3 一个容易被忽略的细节松开手时的音频裁剪我第一次用空格键触发时发现转写结果总是带上一小段奇怪的尾音。排查后发现用户松开按键到系统收到KeyUp事件之间会有几十毫秒的延迟而这几十毫秒正好是说话收尾期发音最容易含糊。一旦这段被录进去自动语音识别ASR就会强行解读经常解读出根本不存在的音节。解决办法是在音频缓冲层面做端点检测按键松开后不立即截断而是继续监听300到500毫秒的静音用静音作为真正的音频截止点。这个改动看似微小但显著降低了转写结果的尾部幻觉字也是我在交互设计上踩的第一个坑。2. 流水线第一干线从麦克风声音到候选断言的定位无论是桌面端还是移动端录音端到事实核查端的链路都是一致的先拿到干净的语音片段再转成文字再从文字里找到值得核查的断言。这条管线是所有功能的地基。2.1 录音与静音分段波形上的终止线我用的录音方案在桌面端是Web Audio API移动端则直接调用系统录音接口。这里有个技术选型细节Web Audio API拿到的原始PCM数据比MediaRecorder得到的压缩音频好处理得多。我需要自己计算音量所以PCM流是必要前提。音量检测用最简单的均方根RMS算法每20毫秒计算一次。静音阈值我会先做一次2秒的环境底噪采样底噪的音量加上一个偏移量作为阈值。移偏量设置很讲究太大则说话尾音被直接吞掉太小则键盘声和呼吸声也被当成有效声音。反复测试后我把默认偏移设在12dB环境嘈杂时再动态上调。录音过程中还有一个细节值得说前五分钟的原始音频我不会做任何压缩处理直接存成Float32的数组这样做端点检测和后续的特征分析都方便。移动端内存吃紧时再降级成16kHz单声道PCM能省接近一半空间且对语音转写的影响很小。2.2 Whisper转写延迟、准确率与模型档位语音转文字我选用的是Whisper系列模型。Whisper在抗噪和口语化表达上的表现比很多商业语音接口好很多尤其是在夹杂语气词、自我纠正、半截话的真实对话场景里。但Whisper也有很现实的取舍问题。完整版大模型准确率最高但我的目标是不能让用户等待超过两秒所以必须在模型档位上做实验。实测数据很清楚模型档位准确率标准数据集平均推理耗时一次性转写4秒语音tiny约78%0.3秒GPU/ 1.1秒CPUbase约85%0.5秒GPU/ 1.8秒CPUsmall约92%1.0秒GPU/ 4秒以上CPUmedium约96%2秒以上GPU/ 不可用CPU最终我默认用base档位配合一个可调的严谨模式选项严谨模式下切到small档。原因很实际事实核查依赖的是实体词、数字、日期的准确识别base在这些人名地名的识别上已经能用medium的提升不值得多等那1秒多的时间。2.3 候选断言的定位先分句再过滤拿到转写文本之后不能直接把整段话丢给核查模块。真实对话中一句话里可能只包含一个可验证的断言也可能一个都没有。我需要先对文本做粗粒度的句子切分再对每个句子做是否有可核查断言的判断。具体做法是先把转写文本按句号、问号、感叹号切成候选句。但这还不够因为Whisper转写的口语文本经常没有标点或者标点位置完全错误。所以我加了一个基于标点概率的辅助分句器用一个轻量序列模型预测每个词后面是句边界的概率超过0.5的才切分。这套混合方案理想情况下能处理真正零标点的连续说话。这一步的核心意义是减少后续计算量。如果一段10秒的语音转出来有3个句子但只有1个句子包含可核查事实我的流水线只需要对那1个句子做深度处理其余句子只做快速过滤。3. 断言提取区分可证实的话和纯粹的噪音事实核查器最容易被误解的地方就是它不应该核查每一句话。我觉得这个方案更好是主观观点这个方案节省了30%的时间才是可核查断言。断言提取模块要做的事情就是在口语流转写文本里找出后者。3.1 规则先行最快且最稳的过滤器我采用规则优先的策略因为口语转写文本噪声大先做规则硬过滤能大幅减少进入语义模型的句子量。规则层的关键信号包括数字与数量词百分比、金额、年份、里程、人数等。有这些词汇的句子大概率包含可核查事实。归属标记出现某公司宣布研究报告指出这位专家称等句式通常指向可验证的陈述。确定性动词是叫做来源于成立于这类表达确定论断的动词。专有名词知名机构名、品牌名、地名连续出现通常意味着一个可查询的事实点。我写了一个快速正则集合来标记这些信号。比如检测到百分之或者%就直接给句子加上数字型标签检测到成立于就加上时间归属型标签。这些标签不仅用于过滤还会在后面的证据检索阶段变成查询关键词的权重来源。3.2 语义层的值得核查程度打分器规则层会漏掉很多不含典型词汇的断言比如巴黎是法国的首都这类地名归属句或者这家公司目前是行业第一这类隐含排名的论断。所以我在规则层之后接了一个语义打分器。这个打分器本质上是一个微调的分类模型输入是分句后的文本输出0到1的可核查度。我用了2万条人工标注的数据来训练标注标准就三条句子是否陈述事实而非观点、事实是否具体到能被外部证据验证、句子是否包含不确定或模糊词汇。有个容易被新手忽略的地方模糊词汇要降权而不是直接清零。口语里大概差不多我记得很常见如果因为这些词就把句子判成不可核查会丢掉大量真实断言。我的模型处理方式是让模糊词降低可核查度分数但如果同时有强数字信号整体分数仍然能穿过阈值。3.3 如何从整段对话中切出核查单元Whisper转写的文本经常把口语中浓重的连接词、重复、自我纠正混在一起。在测试中我反复遇到这种句子这个产品呢呃实际上它是呃在2019年不对2020年上市的。这种句子不能直接拿去检索。处理口语自纠是我花了很多时间的地方。简单的办法是检测不对哦不我说错了等纠正词然后丢弃纠正词后面的那一小段。更稳妥的办法是伸展语义单元如果检测到不对其实准确来说这类词就放弃前面已经提取的实体和数字只保留纠正词之后的片段作为核查单元。在核查单元的意义上我认为一个句子最多输送给证据检索层两个候选断言超过两个就按可核查度分数取前两名。这么做是为了控制整体的检索成本也是让误判率可控的办法。4. 证据获取与事实判断别让模型直接拍板是真的确定了一个断言之后接下来的问题是要证明它。我见过太多把整段话丢给大模型、问一句这句话对吗的实现结果大模型经常一本正经地根据训练记忆回答而不是基于可溯源的证据。这完全违背了事实核查工具存在的意义。我的方案是把事实判断拆成三个独立步骤先生成检索式再去真实的知识源里捞证据段落最后用文本蕴含模型来判断证据和断言之间的关系。4.1 将断言转译成多条检索问题把断言变成检索词是提高证据质量最重要的一步。直接拿断言原文去搜索效果往往很差因为检索系统期望看到的是query而不是一个完整的陈述句。我的做法是基于断言结构和词性标签生成2到3个templated检索问题。举个例子如果断言是某公司在2023年发布了一款折叠屏手机我会生成这么几条query某公司 2023年 折叠屏手机某公司 折叠屏手机 发布时间某公司 折叠屏 2023 发布每一条query都用断言中最高置信度的实体词作为核心词再搭配数字和属性词做限定。生成之后并行发给检索接口取回来的页面段落去重后合并成一个证据集。这个并行请求的方式能把整体时延控制在1秒内而且能有效避免单个query被搜索引擎的错误表达带偏。4.2 找证据不等于用事实用文本蕴含做判断证据集到手后需要对证据是否支持断言做一个结构化判断。我用ROBERTa微调的NLI模型来完成这个判断输入的是断言和一段证据文本输出是三个概率蕴含、矛盾、中立。这里有个关键逻辑判断一粒证据不够要判断证据集。我会把证据按来源域分组比如权威百科类、新闻类、机构官网类每组分别做一次蕴含判断然后根据来源的可靠性加权。最后如果加权结果里矛盾概率最高则显示此断言与现有证据冲突如果蕴含概率最高则显示此断言有证据支持如果中立概率最高或者证据总量不足则显示证据不足暂无法判定。这个证据不足状态是我特意加上的。基于参考语料的经验事实核查最大的风险不是给错结论而是在证据不足时强行下判断。宁可让用户看到一条我找不到足够证据也比给一个误导性强但看似确定的结果好得多。4.3 是否引入大模型做终审我最终的选择很多朋友会问既然已经有大模型为什么不用它直接做最后裁决我认真试过发现大模型在事实核查场景里有两个难以接受的缺点。第一是记忆偏差模型会把训练期见到的信息当成事实输出即使检索到的证据与它的记忆矛盾它也更倾向于维持记忆中的说法。这在冷门但实际上不存在的主题上尤其危险。第二是幻觉补全当证据不足时大模型会倾向于生成一个合乎情理的答案来填补空缺这比承认不知道要严重得多。所以我的选择是让大模型只做叙事解释绝不直接输出判断。最终界面上展示的判断始终来自检索蕴含模型的管线大模型只负责把证据翻译成一段人话帮助用户快速理解为什么得出这个判断。这种分工既拿到了大模型的表达力又避开了它的不可靠。5. 实测中的失败模式那些真正咬到我的坑任何流水线在文档里看起来都顺理成章真正让它变好的是那些失败记录。这一节我把被真实用户反复踩中的问题都列出来顺序就是我从测试日志里看到频率的从高到低。5.1 转写错误如何顺着管道扩散成错误结论最典型的案例是一次小组测试。用户说这家公司在七月份推出了新款耳机考察的是月份信息。Whisper对七月份的识别率在正常语境下很高但当说话人语速偏快、前后词黏连时会把七月份转成新门店导致断言提取器根本检测不到时间型信号整句直接被过滤掉。这类问题的可怕之处在于它不是单一环节的失败而是错误信息被当成不变事实向下游传播。转写错一个词断言提取就抓错实体检索就查错对象哪怕检索和判断模型都正常工作最终结果依然是一本正经的胡说。这个坑我通过两条措施缓解一是在断言提取前做一遍时间/数字容错重写凡是转写置信度低于0.6且周围存在数字词的情况都会尝试用ASR的候选词列表替换再跑一次断言提取二是在界面上显示转写文本原文让用户第一眼就能发现转写错误当前没有下结论之前就可以决定中断交互。这是事实核查工具一个特别重要的坦率点——承认输入不可靠比假装输入可靠安全得多。5.2 口语中的自我纠正与停顿让断言边界反复横跳真实对话里最常见的情况是说了半截改口再说完。而我把用户从松手那一秒就固定了转写内容这本质上是对音频的一次快照采样没有撤销或缝合的机会。测试中有个合作者习惯说这家公司总部在旧金山呃不是是西雅图。系统如果只取后半句能得到正确的断言但完整转写包含前半和后半断言提取器会同时识别到旧金山和西雅图两个地点实体结果变成一条极难核查的矛盾断言。我在处理这个问题的路上试过几个办法。最有效的是在断言提取前检测否定修正模式。具体规则是如果句子中包含呃不是不对准确说等修正词就把修正词之前的实体从断言中剔除。但修正词在Whisper的转写里经常以呃或嗯的形式出现模型本身不确定它们算不算分隔符。后来我在标点分割器里专设了一个分数——嗯呃类语气词后如果紧接否定词则句边界概率上调45%这依赖会显著提升修正句的切分正确率。体验下来断言级数据出现完整矛盾的案例减少了大概60%。5.3 延迟的隐性成本用户在两秒外的焦虑事实核查最核心的竞争力就是快。但如果用户按住了、松开了接下来的反馈超过四五秒那么整个对讲机式即时感就崩塌了。在走查中我看到不少用户在三秒之后就开始自言自语是不是没录上要不要再说一遍这是很明显的信任流失信号。所以我对全流程设了一个3秒总预算录音和端点检测500毫秒Whisper转写1.2秒断言提取和查询生成200毫秒检索800毫秒NLI判断200毫秒总计约2.9秒。其中任何一个环节超时系统会先返回一个阶段性的正在检索证据状态让用户知道管道还在运作。这个状态展示不是装饰实验显示它能把用户在等待时的重置试操作次数减少70%。6. 让工具真正融入现实工作流的最后一公里管线本身稳定之后真正让这个工具从玩具变成工具的是那些围绕用户体验做的补充机制。这一节聊聊我最看重的三个功能点。6.1 核查历史的缓存策略别让同一句断言查两次记者和主播的实际工作特点是大量重复核查同一批声明。比如采访前的资料准备阶段同一个数据可能在多个场合出现。如果没有缓存用户会在半小时内对同一断言发起三次完全相同的检索每次照付完整的延迟。我的缓存设计以断言的语义哈希为键额外存了一组近似断言匹配。近似匹配的逻辑是把核心实体和数字做归一化比如把大约100万和100万左右映射到同一组把该公司和机构全称映射到同一实体ID。命中的缓存直接秒回附带缓存时间戳用户能一眼看出这是旧结果。这个机制看似不起眼但实测中它能命中30%的重复查询是提升整体体验性价比最高的一块。6.2 在嘈杂环境里用短界面做即时反馈真实环境中用户往往没有时间盯屏幕读长文本。所以我给界面设计了两条反馈路径一条是符合逻辑的一屏详情另一条是短暂显示的极简结论。极简结论只有一个色块加一个词绿色表示有证据支持红色表示证据冲突灰色表示证据不足。这个极简层在三次测评中得到的一致反馈是比任何详尽报告都重要。因为在对话里你的目光停留在对方脸上的时间远远超过屏幕一瞥之内就能决定是继续这个话题还是当场挑战。详情层永远只作为一个可选的折叠区域出现我甚至故意把详情入口做得不太显眼防止用户陷入阅读焦虑而错过对话节奏。6.3 离线与多语言的现实约束最后提一下部署层面的取舍。整套系统默认架构是端上录音渲染服务端跑Whisper和NLI。但在没有稳定网络的场景比如偏远地区的采访里服务端依赖是不行的。所以我又做了本地版用片上的Whisper tiny加一个压缩后的NLI蒸馏模型准确率有所下降但核心链路能完整跑通。多语言支持方面只要把Whisper切换成多语言模式并让断言提取器的数字规则去适配对应语言整套外部管线不需要改动。这是一个实际的工程取舍默认版本利用服务器上的充足算力换准确率离线版利用模型压缩换可用性。两者共用一个断言和交互骨架所以用户端操作是一致的。我个人在多次实测后的体会是事实核查工具的成败并不在于算法模型多精准而在于打断对话的成本有多低。按讲交互天然地把成本降到最低剩下的全是围绕它做的工程化优化。如果你也想做这类语音型工具我的建议是先解决松手后两秒内的体验再谈精度。因为用户不会因为模型有95%的准确率就原谅每次两秒以上的沉默而一次干净利落的证据不足反馈往往比一个可疑的完全正确更能建立信任。
返回列表