Opik Python SDK 中的 Contains 指标:零成本、确定性的子串包含评测实践 📅 发布时间:2026/9/13 17:09:51 👁 浏览次数: Opik Python SDK 中的 Contains 指标零成本、确定性的子串包含评测实践【免费下载链接】comet-llmDebug, evaluate, and monitor your LLM applications, RAG systems, and agentic workflows with comprehensive tracing, automated evaluations, and production-ready dashboards.项目地址: https://gitcode.com/GitHub_Trending/co/comet-llmContains是 Opik Python SDK 内置的一个轻量级启发式评测指标用于判断模型输出中是否包含某个参考字符串并以 1.0 / 0.0 的二值分数返回结果。它不依赖任何 LLM Judge 调用因此可以在离线评估流水线中以极低成本、完全确定性的方式运行适用于「答案必须包含某个关键词/实体/标记」这类可精确定义的验收条件。本文基于 SDK 源码与单元测试完整梳理其参数、判定逻辑、异常边界以及在evaluate()、AggregatedMetric中的组合用法。指标定位启发式指标家族中的一员在 Opik 的评测体系中指标按实现方式分为若干家族。Contains位于启发式heuristics子包中与Equals、RegexMatch、LevenshteinRatio、ROUGE、BLEU等规则型指标并列与需要调用大模型的 LLM Judge 指标形成互补。从源码结构看其导出链路为实现文件contains.py统一导出入口init.py 中from .heuristics.contains import Contains因此可直接从opik.evaluation.metrics导入无需深入子包路径。这类指标的共性是不调用外部模型、结果可复现、单次评分开销几乎为零。对于 CI 中的回归评估、大规模数据集的批量打分它们是控制成本与延迟的首选。核心语义与计分规则Contains的判定逻辑非常直接若参考字符串reference作为子串出现在输出字符串output中返回分数 1.0否则返回 0.0。其score()实现见 contains.pydef score( self, output: str, reference: Optional[str] None, **ignored_kwargs: Any ) - score_result.ScoreResult: # Use provided reference, else fall back to default ref reference if reference is not None else self._default_reference # Handle missing reference (None) separately if ref is None: raise ValueError( No reference string provided. Either pass reference to score() or set a default reference when creating the metric. ) # Handle empty string separately if ref : raise ValueError( Invalid reference string provided. Reference must be a non-empty string. ) value output if self._case_sensitive else output.lower() ref ref if self._case_sensitive else ref.lower() if ref in value: return score_result.ScoreResult(value1.0, nameself.name) return score_result.ScoreResult(value0.0, nameself.name)几个值得注意的行为细节默认大小写不敏感。case_sensitive默认值为False此时output与reference都会先做lower()归一化再比较。也就是说Contains(referenceWorld).score(hello, world!)得 1.0。需要精确匹配如区分ML与ml时必须显式传入case_sensitiveTrue。reference 的双重供给机制。构造时可设置默认reference调用score()时也可逐次覆盖。源码中ref reference if reference is not None else self._default_reference明确了优先级调用时传入 构造时默认。这正好契合评测场景中「一个指标实例、多行数据各带不同参考答案」的需求。两类明确的参数错误。reference最终解析为None既没传默认值也没在调用时传会抛出ValueError: No reference string provided...reference为空字符串会抛出ValueError: Invalid reference string provided...。这两处校验是刻意为之——因为空字符串in任意字符串都为True若不做拦截会静默产出全 1.0 的假分数这类错误在批量评估中极具迷惑性。**ignored_kwargs的宽容签名。score()会吞掉所有未声明的关键字参数。这一点与 Opik 评测框架的约定一致evaluate()在批量打分时会把数据集 item 的多个字段如input、reference、context等统一注入各指标的score()指标只需取自己关心的参数、忽略其余即可。这意味着Contains可以直接放入通用评估流水线而不会因多余字段报错而reference字段名恰好与数据集里存放标准答案的字段同名会被自动利用。构造参数详解构造函数签名为见 contains.pydef __init__( self, case_sensitive: bool False, reference: Optional[str] None, name: str contains_metric, track: bool True, project_name: Optional[str] None, ):参数类型默认值说明case_sensitiveboolFalse是否区分大小写。False时双方均转小写比较referenceOptional[str]None默认参考字符串。未设置时必须在score()调用时提供否则抛ValueErrornamestrcontains_metric指标名会写入分数结果与追踪记录一个实验中使用多个Contains实例时应赋予不同name以便区分trackboolTrue是否将评分过程作为 span 追踪上报到 Opikproject_nameOptional[str]None在无父级 span/trace 可继承项目名时指定上报到哪个项目仅在trackTrue时允许设置其中track与project_name的行为由基类 BaseMetric 统一处理if not track and project_name is not None: raise ValueError(project_name can be set only when track is set to True) if track and config.check_for_known_misconfigurations() is False: track_decorator opik.track(nameself.name, project_nameproject_name) self.score track_decorator(self.score) self.ascore track_decorator(self.ascore)即当trackTrue时score/ascore会被opik.track装饰器包裹每次评分自动落为一条 span可在 Opik 界面中查看评分的调用轨迹若希望指标静默运行例如在AggregatedMetric内部复用、或避免冗余 span可传trackFalse。基本用法独立调用from opik.evaluation.metrics import Contains # 初始化时提供默认 reference contains_metric Contains(referenceworld) # 命中1.0 result contains_metric.score(Hello, World!) print(result.value) # 1.0 # 调用时覆盖 reference未命中0.0 result contains_metric.score(Hello, World!, referencethere) print(result.value) # 0.0 # 大小写不敏感默认 Contains(referenceWorld).score(hello, world!) # value1.0 # 大小写敏感 Contains(referenceWorld, case_sensitiveTrue).score(hello, world!) # value0.0返回值是ScoreResult对象定义于 score_result.py底层为 Rust 侧_opik包中的ScoreResult除value外还携带name与指标实例的name保持一致便于在多指标场景下区分来源。基类还为每个指标提供了异步入口ascore()默认实现在工作线程中执行同步的score()见 base_metric.py因此Contains天然可以在异步评估流水线中以await metric.ascore(...)调用而不阻塞事件循环。异常边界以下两种用法会立即抛出ValueError而不是返回 0.0# 1) 完全没有 reference Contains().score(Hello) # ValueError: No reference string provided. Either pass reference to score() # or set a default reference when creating the metric. # 2) 空字符串 reference Contains(reference).score(Hello) # ValueError: Invalid reference string provided. Reference must be a non-empty string.设计成「快速失败」而非「静默得 0 分」可以防止配置疏漏污染整批实验的分数统计。典型适用场景答案校验RAG 回答必须包含某个实体名、数字、结论性短语格式约束检查输出中必须出现 JSON 标记、特定标签或免责声明拒绝话术识别安全测试中验证模型输出是否包含抱歉我无法等拒绝表述与 LLM Judge 组合先用Contains/RegexMatch等廉价指标做硬性门槛过滤再对通过样本执行高成本的模型评审。在 evaluate() 批量评估中的用法由于reference既可构造时设置、也可score()时按行覆盖Contains可以无缝嵌入opik.evaluate()数据集评估import opik from opik import evaluate from opik.evaluation.metrics import Contains # 每行数据集 item 携带各自的 reference 字段会被自动注入 score() contains_metric Contains(nameanswer_contains_key_entity) evaluate( taskstask_fn, datadataset, # 每行形如 {input: ..., reference: expected substring} metrics[contains_metric], )在evaluate()场景中reference正是 Opik 数据集中存放标准答案的保留字段名Contains的score(output, reference)签名与之天然对齐——数据集里每一行的参考答案会分别注入同一次score()调用无需为每行创建指标实例。与 AggregatedMetric 组合Contains也常被用作聚合指标中的一个分量。SDK 文档示例见 aggregated_metric.py 的 docstringfrom opik.evaluation.metrics import AggregatedMetric, Contains, RegexMatch metrics [Contains(trackFalse), RegexMatch(patternr\d, trackFalse)]组合时注意两点内部分量指标通常设置trackFalse以避免在聚合 span 之下产生冗余 span同时由于聚合内的多个指标共用同一个默认reference语义若各分量对 reference 的要求不同应在各自的score()调用链上分别处理。聚合层负责对多个ScoreResult做归并与加权Contains提供的 0.0/1.0 硬信号在其中充当「一票否决」或门槛条件非常合适。单元测试验证的行为SDK 单元测试 test_heuristics.py 对Contains覆盖的边界与本文描述一致可用作行为契约参考Contains(referenceworld, case_sensitiveFalse, trackFalse)命中与未命中的基本判定Contains(referenceWorld, case_sensitiveTrue, trackFalse)大小写敏感模式下world不再命中Contains(referenceworld, trackFalse)默认大小写不敏感路径Contains(trackFalse)无 reference 时score()抛错的路径Contains(referenceinvalid_ref, trackFalse)空字符串等非法 reference 的ValueError路径默认 reference 存在、调用时再传reference的覆盖优先级。这些测试均以trackFalse构造说明单元测试环境有意关闭上报装饰验证的是纯评分逻辑——生产使用中若未显式设置track默认为True评分 span 会照常上报。小结维度Contains的行为分数值域二值命中 1.0未命中 0.0大小写默认不敏感case_sensitiveTrue开启精确匹配reference 来源调用时传入 构造时默认两者皆无则ValueError空 reference直接ValueError防止空串恒真的假阳性追踪默认trackTrue每次评分落一条 span可trackFalse静默异步继承基类ascore()自动在 worker 线程执行Contains的价值在于用最小复杂度提供一条确定性的质量底线不烧 token、结果可复现、错误快速暴露。在 Opik 的评测栈中它通常与RegexMatch、Equals等启发式指标一起承担「硬规则检查」把 LLM Judge 的算力留给真正需要语义理解的部分。实现细节可进一步参阅 contains.py、base_metric.py 与 test_heuristics.py。【免费下载链接】comet-llmDebug, evaluate, and monitor your LLM applications, RAG systems, and agentic workflows with comprehensive tracing, automated evaluations, and production-ready dashboards.项目地址: https://gitcode.com/GitHub_Trending/co/comet-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考