资讯动态

多源RAG幻觉与溯源难题:ProvenanceGuard的claim-to-source验证实战

发布时间:2026/10/8 16:41:34 来源:尧图企业网站定制
1. 多源RAG的验证困局与ProvenanceGuard的切入点做过RAG项目的人大概都有过这种体验系统上线跑了一段时间用户反馈某个回答是错的你回头去查发现检索回来的三段材料里有一段来自一份过期的PDF另一段来自某个论坛的二手转述还有一段干脆是模型自己脑补出来的。问题是你根本没法快速定位到底是哪一段出了问题因为整个链路里没有任何机制记录这句话到底是从哪来的。这就是多源RAG最要命的地方。单源RAG还好说知识库就一个检索范围可控出了问题大不了把整个库重新过一遍。但一旦接入多个数据源——比如同时挂了内部Wiki、产品文档、客服工单、第三方API返回的结构化数据——检索结果的来源就变得极其复杂。不同源的权威性不一样时效性不一样格式也不一样。模型把这些东西混在一起生成答案你拿到的就是一碗信息杂烩好吃不好吃全靠运气。ProvenanceGuard要解决的就是这个问题。它的核心思路不复杂在RAG的生成链路里加一层claim-to-source验证把模型生成的每一个事实性断言claim拆出来逐一回溯到具体的源片段source chunk然后判断这个claim是否真的被source支持。支持的标记为有据可查不支持的标记为存疑或无源最终在输出层面给出带溯源标注的答案。这个思路听起来简单但落地时会碰到一堆工程问题claim怎么拆拆到什么粒度source怎么匹配匹配的置信度怎么算多源冲突时怎么裁决这些才是真正花时间的地方。我接下来会围绕ProvenanceGuard这个项目把多源RAG场景下claim-to-source验证的完整设计思路、核心实现细节、实操踩坑经验都摊开讲一遍。适合正在做RAG项目、被幻觉和溯源问题折磨的工程师也适合想了解RAG进阶玩法、准备在自己的知识库系统里加验证层的朋友。2. 为什么多源RAG必须做claim级别的验证2.1 传统RAG的溯源粒度为什么不够用大部分RAG系统的溯源做到什么程度顶多在回答末尾附上几个参考文档的标题或链接。用户看到的是本回答参考了文档A、文档B、文档C但具体哪句话来自文档A哪句话来自文档B完全不知道。这种粗粒度溯源在单源场景下勉强能用因为反正都来自同一个库出错了一起改就行。多源场景就完全不一样了。假设你的知识库同时接了产品官方文档和用户社区帖子官方文档说该接口QPS上限为1000社区帖子说实测超过500就限流了。模型检索到这两段生成了一句该接口QPS上限约为500-1000。这句话到底算有据可查还是算幻觉从文档级别看两个源都引用了好像没问题。但从claim级别看约为500-1000这个表述既不完全被官方文档支持官方说的是1000也不完全被社区帖子支持帖子说的是500就限流它是一个模型自己调和出来的新断言。这种调和在很多时候是有价值的但你必须让用户知道这是调和结果而不是某个权威源的原始表述。注意claim-to-source验证的目标不是消灭模型的推理和调和能力而是让这些推理和调和变得可见。用户有权知道哪些是原文哪些是模型加工过的。2.2 多源冲突的三种典型形态在实际项目里多源冲突基本可以归为三类每类对验证策略的要求不同。第一类是事实性冲突。两个源对同一个事实给出了不同的值比如上面说的QPS上限。这类冲突需要引入源权威性评分来裁决权威性高的源优先但低权威源的异议也要保留在溯源信息里。第二类是时效性冲突。同一个源的不同版本或者新旧两个源对同一件事的描述不一致。比如旧文档说支持Python 3.6新文档说支持Python 3.8。这类冲突需要引入时间戳默认以最新为准但要在溯源里标注版本差异。第三类是粒度性冲突。一个源给出概括性描述另一个源给出细节性描述两者不矛盾但层级不同。比如概述文档说支持多种数据库细节文档列出了MySQL、PostgreSQL、SQLite。这类冲突不需要裁决而是需要在claim拆分时识别出粒度层级把概括claim和细节claim分别挂到对应的源上。ProvenanceGuard的设计里这三类冲突分别对应三套处理逻辑后面会详细展开。2.3 claim-to-source验证在链路中的位置从工程角度看claim-to-source验证应该放在生成之后、输出之前。具体来说RAG的完整链路是query理解 → 多源检索 → 上下文组装 → 生成 →claim拆分 → source匹配 → 验证裁决 → 带溯源的输出。加粗部分就是ProvenanceGuard介入的环节。为什么不放在生成之前因为claim是模型生成的产物没有生成就没有claim可拆。为什么不放在检索阶段做预验证因为检索阶段你还不知道模型会生成什么claim预验证只能做源质量过滤做不了claim级别的匹配。这个位置选择有一个隐含代价它增加了生成后的处理延迟。一次完整的claim-to-source验证如果claim数量在10-20个source chunk在50-100个用轻量级模型做匹配的话额外延迟大概在1-3秒。这个延迟在交互式场景下是可以接受的但在高并发场景下需要做异步化或缓存优化。我在实际项目里的做法是把验证结果缓存起来相同query的验证结果复用命中率大概能到40%左右。3. ProvenanceGuard的核心模块拆解3.1 claim拆分从一段话到原子断言claim拆分是整个验证链路的第一步也是最容易被低估的一步。很多人觉得拆分嘛按句子切就行了。实际做下来按句子切会出大问题。举个例子模型生成的一句话根据官方文档该接口的QPS上限为1000但社区实测在500左右就会出现限流建议生产环境按500配置。按句子切这是一个claim。但这个claim里其实包含了三个独立的断言官方文档说QPS上限1000社区实测500左右限流建议按500配置。这三个断言的source来源不同验证结果也可能不同必须拆开。ProvenanceGuard的claim拆分策略是基于语义角色的原子化拆分具体分三步走。第一步句子分割。用标点和连接词做粗切把长句切成短句。中文里重点关注的连接词包括但、然而、不过、因此、所以、建议、根据等。第二步断言识别。对每个短句判断是否包含可验证的事实性断言。描述性、建议性、过渡性的句子不算claim。比如综上所述不是claim建议按500配置是建议不是事实断言但社区实测500左右限流是事实断言。第三步原子化。对包含多个事实的短句继续拆分直到每个claim只包含一个可独立验证的事实。拆分的依据是主语、谓语、宾语、时间、地点、数值这些要素是否可以被独立验证。实际操作中我会用一个轻量级模型来做这三步prompt大概长这样CLAIM_SPLIT_PROMPT 将以下文本拆分为原子化的事实断言列表。每个断言只包含一个可独立验证的事实。 输出JSON格式[{claim: ..., type: fact|suggestion|description, entities: [...]}] 文本{text} 这里有个经验拆分粒度不要太细。我试过拆到主语谓语级别结果claim数量爆炸验证成本翻了三倍但准确率只提升了不到5%。后来稳定在一个事实断言级别平均每100字生成3-5个claim这个粒度比较平衡。3.2 source匹配从claim到chunk的召回与精排claim拆出来之后下一步是给每个claim找到它可能的source。这一步本质上是一个检索问题给定一个claim在source chunk集合里找到最相关的几个chunk。ProvenanceGuard用的是两阶段匹配粗召回 精排。粗召回阶段用BM25加向量检索的混合策略从所有source chunk里召回top-20候选。这里有个细节claim通常比query短而且包含具体的实体和数值所以BM25的权重可以调高一些。我在项目里的配置是BM25权重0.6向量权重0.4实测比纯向量召回在数值型claim上的准确率高不少。精排阶段用一个cross-encoder或者轻量级LLM对top-20候选逐一打分判断这个chunk是否支持这个claim。打分维度包括实体一致性claim里的实体是否在chunk里出现数值一致性claim里的数值是否与chunk一致或可推导语义蕴含chunk是否在语义上蕴含claim否定一致性claim的极性是否与chunk一致避免支持被匹配到不支持精排的输出是一个0-1的支持度分数。分数超过0.8的标记为强支持0.5-0.8标记为弱支持低于0.5标记为无支持。实操心得精排阶段一定要做否定一致性检查。我踩过一次坑claim是该功能支持批量导入匹配到的chunk是该功能不支持批量导入语义相似度很高但极性完全相反。后来在精排里加了一个极性检查模块这类错误就基本消失了。3.3 验证裁决多源冲突的处理逻辑当一个claim匹配到多个source且这些source的支持度或内容不一致时就需要裁决。ProvenanceGuard的裁决逻辑分三层。第一层是权威性裁决。每个source在入库时打一个权威性标签比如官方文档0.9内部Wiki 0.7社区帖子0.5第三方API 0.6。当多个source都强支持同一个claim但内容有细微差异时取权威性最高的source作为主源其他源作为辅源记录在溯源信息里。第二层是时效性裁决。每个source带时间戳当新旧source冲突时默认取最新的。但如果旧source的权威性显著高于新source比如官方旧文档vs社区新帖子则保留旧source为主源但在溯源里标注存在更新但权威性较低的信息。第三层是粒度性裁决。当概括性claim和细节性claim分别匹配到不同粒度的source时不做裁决而是建立层级关系。概括claim挂到概括source细节claim挂到细节source在输出时按层级展示。裁决结果最终会生成一个溯源图谱每个claim节点挂一到多个source节点边上标注支持度、权威性、时效性、粒度层级。这个图谱就是最终输出的溯源依据。3.4 输出层带溯源的答案呈现验证做完之后怎么把溯源信息呈现给用户也是一个需要设计的地方。ProvenanceGuard提供了三种输出模式。内联标注模式在答案的每个claim后面用上标标注source编号比如该接口QPS上限为1000[1]。适合需要精确溯源的场景比如技术文档问答。侧边栏模式答案保持干净溯源信息放在侧边栏用户点击某个claim时高亮对应的source。适合交互式应用。置信度模式不展示具体source只展示每个claim的置信度标签高/中/低低置信度的claim用不同颜色标出。适合对溯源细节不感兴趣、只想知道哪些话可信的用户。三种模式可以根据场景切换底层用的是同一套溯源图谱数据。4. 完整实操从零搭建一个claim-to-source验证流程4.1 环境准备与依赖安装先把环境搭起来。ProvenanceGuard的核心依赖不多主要是检索和模型推理相关的库。pip install rank_bm25 sentence-transformers faiss-cpu pip install openai # 或者你用的其他模型SDK pip install pydantic # 用于数据结构定义如果你要用本地模型做精排还需要装transformers和torch。我一般用BAAI/bge-reranker-base做精排效果和速度比较平衡。pip install transformers torch数据结构方面我用pydantic定义了几个核心类from pydantic import BaseModel from typing import List, Optional from datetime import datetime class SourceChunk(BaseModel): chunk_id: str content: str source_name: str authority: float # 0-1 timestamp: datetime granularity: str # overview | detail class Claim(BaseModel): claim_id: str text: str claim_type: str # fact | suggestion | description entities: List[str] class VerificationResult(BaseModel): claim_id: str support_level: str # strong | weak | none primary_source: Optional[str] supporting_sources: List[str] confidence: float这套数据结构看起来简单但实际用起来很顺手。特别是granularity字段在做粒度性裁决时非常关键。4.2 claim拆分的代码实现claim拆分的核心是一个LLM调用加后处理。我用的prompt经过了几轮迭代现在稳定在这个版本import json from openai import OpenAI client OpenAI() def split_claims(text: str) - List[Claim]: prompt f将以下文本拆分为原子化的事实断言。规则 1. 每个断言只包含一个可独立验证的事实 2. 建议性、过渡性、总结性语句不算断言 3. 输出JSON数组每个元素包含 claim, type, entities 三个字段 4. type 取值fact事实、suggestion建议、description描述 文本{text} 输出 response client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: prompt}], temperature0 ) raw response.choices[0].message.content # 清理可能的markdown代码块标记 raw raw.strip().removeprefix(json).removesuffix().strip() items json.loads(raw) claims [] for i, item in enumerate(items): if item[type] ! fact: continue claims.append(Claim( claim_idfc_{i}, textitem[claim], claim_typeitem[type], entitiesitem.get(entities, []) )) return claims这里有个细节我只保留fact类型的claim进入验证流程suggestion和description直接跳过。因为建议和描述本身不需要溯源到具体事实强行验证反而会增加噪音。注意LLM返回的JSON偶尔会带markdown代码块标记或者字段名有细微差异。一定要做健壮的解析和后处理不要直接json.loads就完事。我在生产环境里加了三层容错先尝试直接解析失败则清理代码块标记再解析再失败则用正则提取JSON部分。4.3 source匹配的完整流程source匹配分粗召回和精排两步。粗召回用BM25加向量的混合检索from rank_bm25 import BM25Okapi import numpy as np from sentence_transformers import SentenceTransformer class HybridRetriever: def __init__(self, chunks: List[SourceChunk]): self.chunks chunks self.tokenized [c.content for c in chunks] self.bm25 BM25Okapi([list(c.content) for c in chunks]) self.encoder SentenceTransformer(BAAI/bge-small-zh-v1.5) self.embeddings self.encoder.encode( [c.content for c in chunks], normalize_embeddingsTrue ) def retrieve(self, claim: str, top_k: int 20) - List[tuple]: # BM25 分数 bm25_scores self.bm25.get_scores(list(claim)) bm25_scores np.array(bm25_scores) if bm25_scores.max() 0: bm25_scores bm25_scores / bm25_scores.max() # 向量分数 claim_emb self.encoder.encode([claim], normalize_embeddingsTrue)[0] vec_scores self.embeddings claim_emb # 混合 hybrid 0.6 * bm25_scores 0.4 * vec_scores top_indices np.argsort(hybrid)[::-1][:top_k] return [(self.chunks[i], hybrid[i]) for i in top_indices]精排用一个cross-encoderfrom transformers import AutoTokenizer, AutoModelForSequenceClassification import torch class Reranker: def __init__(self): self.tokenizer AutoTokenizer.from_pretrained(BAAI/bge-reranker-base) self.model AutoModelForSequenceClassification.from_pretrained( BAAI/bge-reranker-base ) self.model.eval() def score(self, claim: str, chunk: str) - float: inputs self.tokenizer( claim, chunk, return_tensorspt, truncationTrue, max_length512 ) with torch.no_grad(): logits self.model(**inputs).logits return torch.sigmoid(logits).item()精排之后还要加一个极性检查。极性检查可以用一个简单的规则加模型判断如果claim里包含支持、可以、是等肯定词而chunk里对应位置包含不支持、不可以、不是等否定词则判定极性不一致支持度直接降为0。4.4 验证裁决与溯源图谱生成裁决逻辑的代码实现def adjudicate(claim: Claim, candidates: List[tuple]) - VerificationResult: scored [] for chunk, recall_score in candidates: rerank_score reranker.score(claim.text, chunk.content) polarity_ok check_polarity(claim.text, chunk.content) if not polarity_ok: rerank_score 0 scored.append((chunk, rerank_score)) scored.sort(keylambda x: x[1], reverseTrue) top scored[0] if scored else (None, 0) if top[1] 0.8: support_level strong elif top[1] 0.5: support_level weak else: support_level none # 多源裁决 supporting [c for c, s in scored if s 0.5] if len(supporting) 1: # 按权威性排序 supporting.sort(keylambda c: c.authority, reverseTrue) primary supporting[0] others supporting[1:] else: primary top[0] others [] return VerificationResult( claim_idclaim.claim_id, support_levelsupport_level, primary_sourceprimary.chunk_id if primary else None, supporting_sources[c.chunk_id for c in others], confidencetop[1] )溯源图谱的生成就是把所有claim的验证结果汇总构建成一个图结构。我用networkx来做import networkx as nx def build_provenance_graph(claims, results, chunks): G nx.DiGraph() chunk_map {c.chunk_id: c for c in chunks} for claim, result in zip(claims, results): G.add_node(claim.claim_id, typeclaim, textclaim.text) if result.primary_source: src chunk_map[result.primary_source] G.add_node(src.chunk_id, typesource, namesrc.source_name) G.add_edge(claim.claim_id, src.chunk_id, relationprimary, confidenceresult.confidence) for sid in result.supporting_sources: G.add_edge(claim.claim_id, sid, relationsupporting) return G这个图谱可以直接序列化成JSON前端拿到之后做可视化展示。4.5 输出层的三种模式实现内联标注模式的实现最简单就是把claim和source编号对应起来def render_inline(claims, results, chunks): chunk_map {c.chunk_id: c for c in chunks} source_index {} output_parts [] for claim, result in zip(claims, results): if result.primary_source: if result.primary_source not in source_index: source_index[result.primary_source] len(source_index) 1 idx source_index[result.primary_source] output_parts.append(f{claim.text}[{idx}]) else: output_parts.append(f{claim.text}[?]) answer .join(output_parts) references \n.join( f[{i}] {chunk_map[cid].source_name} for cid, i in sorted(source_index.items(), keylambda x: x[1]) ) return answer \n\n参考来源\n references置信度模式则是给每个claim打标签def render_confidence(claims, results): parts [] for claim, result in zip(claims, results): if result.support_level strong: tag 高 elif result.support_level weak: tag 中 else: tag 低 parts.append(f{claim.text}置信度{tag}) return .join(parts)5. 常见问题与排查技巧实录5.1 claim拆分粒度过粗或过细怎么调这是最常见的第一个问题。粒度过粗的表现是一个claim里包含多个事实验证时只能匹配到一个source其他事实的source丢失。粒度过细的表现是claim数量爆炸验证延迟高而且很多claim是碎片化的单独看没有意义。调整方法先看平均每100字生成的claim数量。低于2个说明过粗高于8个说明过细。正常范围是3-5个。如果过粗在prompt里加每个断言只包含一个事实的强调并给出反例。如果过细加不要拆分同一主语的并列谓语的约束。我踩过的坑是一开始用了一个很激进的拆分prompt把该接口支持GET和POST两种方法拆成了该接口支持GET方法和该接口支持POST方法两个claim。结果验证时两个claim都匹配到同一个source但输出时变成了两句话读起来很啰嗦。后来加了并列谓语不拆分的约束就好了。5.2 source匹配召回率低怎么办召回率低的表现是很多claim的验证结果是无支持但你人工检查发现source里明明有相关内容。排查思路分三步。第一步检查粗召回阶段看claim的top-20候选里有没有正确的source。如果没有说明粗召回有问题可能是BM25分词不对或者向量模型不适合你的领域。第二步如果粗召回有但精排没选上说明精排模型的问题可能需要换模型或者加训练数据。第三步如果精排选上了但分数低说明claim和source的表述差异大需要考虑做query改写或者同义词扩展。我在一个医疗领域的项目里遇到过这个问题claim用的是患者source用的是病人向量模型没匹配上。后来加了一个领域同义词表做query扩展召回率从60%提升到了85%。5.3 多源冲突裁决结果不符合预期裁决结果不符合预期通常是权威性标签或时效性标签设置有问题。排查时先把冲突的source列出来看它们的权威性和时间戳然后手动推演裁决逻辑看结果是否合理。常见问题是权威性标签太粗。比如把所有官方文档都标0.9但官方文档里也有核心文档和边缘文档的区别。我的做法是把权威性分成五个维度分别打分然后加权来源类型官方/社区/第三方、作者可信度、内容完整度、更新频率、被引用次数。加权后的分数更细裁决也更准。5.4 验证延迟过高怎么优化验证延迟主要花在三个地方claim拆分的LLM调用、精排的模型推理、多源裁决的排序。优化手段对应也有三个。claim拆分可以用更小的模型或者用规则加小模型的混合方案。我试过用规则做初拆只对复杂句子调LLM延迟降低了60%。精排可以用ONNX加速或者用更小的reranker模型。bge-reranker-base换成bge-reranker-v2-m3的量化版本延迟能降一半准确率只掉2个点。多源裁决的排序本身很快但如果source数量大可以用堆排序或者只保留top-5。还有一个整体优化把验证结果缓存起来。相同query的验证结果直接复用命中率能到40%左右。缓存key用query的hash加source集合的hash。5.5 常见问题速查表问题现象可能原因排查方法解决方案claim数量过多拆分prompt过于激进统计每100字claim数加并列谓语不拆分约束claim数量过少拆分prompt过于保守人工检查是否有遗漏事实加反例强调原子化召回率低分词或向量模型不匹配检查top-20候选换模型或加同义词扩展精排分数普遍偏低claim与source表述差异大对比claim和source文本query改写或领域微调极性判断错误否定词识别遗漏检查否定词表补充否定词加模型判断裁决结果异常权威性或时效性标签有误手动推演裁决逻辑细化权威性评分维度验证延迟高模型推理或LLM调用慢分阶段计时缓存、量化、小模型溯源图谱断裂source chunk被过滤检查chunk过滤逻辑保留被引用的chunk6. 多源RAG验证的进阶玩法与扩展方向6.1 与知识图谱结合做结构化验证纯文本的claim-to-source验证有一个天然局限它只能验证文本是否支持文本没法验证文本是否与结构化事实一致。如果你的知识库里同时有文本和知识图谱可以把两者结合起来。具体做法是对每个claim除了做文本匹配还尝试从知识图谱里抽取对应的三元组然后比对claim和三元组是否一致。比如claim是张三于2020年加入公司知识图谱里有(张三, 加入时间, 2020)两者一致验证通过。如果图谱里是(张三, 加入时间, 2019)则标记为冲突。这种结构化验证的准确率比纯文本验证高很多但前提是你的知识图谱覆盖度够。我在一个项目里试过图谱覆盖的claim验证准确率能到95%以上没覆盖的还是得走文本验证。6.2 用MCP做验证服务的标准化封装MCPModel Context Protocol最近很火它的核心价值是把各种能力封装成标准化的服务接口让模型可以按需调用。ProvenanceGuard完全可以封装成一个MCP服务对外暴露verify_claim、get_provenance_graph、render_with_sources这几个工具。这样做的好处是任何支持MCP的客户端都可以直接调用验证能力不用关心底层实现。比如你在CherryStudio里做RAG应用直接接入ProvenanceGuard的MCP服务就能给输出加上溯源标注。封装的时候注意几点工具的输入输出要用JSON Schema严格定义验证服务要做无状态化方便水平扩展溯源图谱的返回要做分页避免大图谱撑爆上下文。6.3 验证结果的反哺用溯源数据优化检索claim-to-source验证的结果不只是给用户看的还可以反哺检索环节。具体来说如果某个source被大量claim引用且验证通过说明这个source质量高可以在检索时给它加权。如果某个source经常被引用但验证不通过说明这个source可能有问题可以降权或者标记待审核。这个反哺机制我称之为溯源反馈闭环。实现上就是在source的元数据里加两个计数器cited_count和verified_count定期计算verified_count / cited_count作为质量分回写到检索的排序公式里。实测下来这个闭环跑几轮之后检索的准确率能提升5-10个点因为低质量source被自然降权了。6.4 多语言场景下的验证适配如果你的RAG系统支持多语言claim-to-source验证也要做多语言适配。核心难点是claim可能是中文source可能是英文跨语言匹配的准确率会下降。解决方案有两个。一是用多语言向量模型比如bge-m3它支持100多种语言的跨语言匹配。二是做翻译对齐把claim翻译成source的语言再做匹配。我一般用第一种因为翻译会引入额外误差。跨语言验证的阈值要调低一些。单语言场景下强支持的阈值是0.8跨语言场景下调到0.7比较合适因为跨语言匹配的分数普遍偏低。6.5 验证结果的可视化呈现溯源图谱如果只给JSON用户很难直观理解。做一个可视化呈现会大大提升体验。我一般用D3.js或者Cytoscape.js做前端渲染claim节点和source节点用不同颜色区分边的粗细表示支持度边的颜色表示关系类型主源/辅源。交互上支持点击claim高亮对应的source点击source高亮所有引用它的claim。这个交互在排查问题时特别有用一眼就能看出哪个source是问题源。如果不想做前端也可以用Graphviz生成静态图嵌入到报告里。虽然交互性差一些但胜在实现简单。7. 我在实际项目里踩过的几个坑第一个坑是过度依赖LLM做拆分。一开始我全部用LLM拆claim结果延迟高、成本高而且LLM偶尔会自作主张把一些不该拆的拆了。后来改成规则加LLM的混合方案简单句子用规则拆复杂句子才调LLM成本和延迟都降了一半。第二个坑是忽略source的粒度差异。早期版本里所有source一视同仁结果概括性source和细节性source混在一起裁决时经常出现概括claim匹配到细节source的错配。后来加了granularity字段做分层匹配错配率大幅下降。第三个坑是验证结果没有缓存。上线初期每次query都重新验证QPS一高就扛不住。后来加了Redis缓存相同query的验证结果复用命中率40%左右峰值QPS直接翻倍。第四个坑是溯源信息展示太复杂。第一版输出把完整的溯源图谱都塞给用户结果用户根本看不懂反馈说信息太多反而不知道看哪个。后来改成默认只展示主源辅源折叠起来用户需要时再展开体验好很多。第五个坑是没有做验证结果的质量监控。上线后一段时间发现验证准确率在缓慢下降排查发现是新接入的一个source质量很差拉低了整体指标。后来加了source质量监控每个source的验证通过率低于阈值就自动告警问题发现得早了很多。这些坑说到底都是一个道理claim-to-source验证不是一个做完就完事的功能它是一个需要持续运营和调优的系统。source在变query在变模型也在变验证策略必须跟着变。把它当成一个一次性的开发任务上线后大概率会慢慢失效。最后分享一个小技巧如果你刚开始做claim-to-source验证不要一上来就追求全链路自动化。先用人工标注一批claim-source对跑通验证逻辑确认准确率达标之后再逐步替换成自动化流程。这样能避免在自动化流程里埋下难以发现的系统性错误。我在第一个项目里就是先人工标了500对跑通之后才上的自动化省了很多返工的时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑