关于 opik-test
opik-test 可将 Opik 跟踪记录中的失败转为经过验证的测试套件条目,供跟踪回归的团队使用。它把记录的输入和可判定断言存入 Opik,不修改应用代码。
主要功能
- 01从 Opik 跟踪记录提取案例
- 02编写二元且针对失败的断言
- 03创建或复用项目测试套件
- 04按跟踪 ID 检查重复项
- 05读回条目以验证存储
- 06不修改应用代码
适用场景
- 01将跟踪记录中的失败转为回归案例
- 02根据失败描述创建测试
- 03避免重复录入同一跟踪记录
MCP 相关
该技能可使用 Opik 托管 MCP 的写入工具操作套件和条目,也可使用 Opik SDK;MCP 并非必需。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ comet-ml/ opik-skills --skill opik-test安装后在 Claude Code 中输入/opik-test确认已加载。
详细介绍
测试 — 将失败案例捕获为可重复检查
完成定义: Opik 中存在一个测试套件条目,可重现该故障 — 其 data 包含失败输入(以及已知时的预期输出),并且有一到两个二元断言,这些断言在错误轨迹上会失败,在正确轨迹上会通过。该条目位于一个限定到项目的命名套件中,已通过读取确认,并已准备好由 /opik-compare 运行。如果无法捕获案例,请在遇到第一个真正的阻碍时停止,并且只返回一个后续步骤。编写 pytest 文件或用文字描述测试都不算成功。
操作:从真实轨迹数据中提取案例,编写可由评判者判定为是或否的断言,将其存储在 /opik-compare 能找到的位置 — 不修改任何应用代码。 此技能会写入 Opik,不会写入代码仓库。
输入
入口可以是 /opik-test <trace-id>(捕获该轨迹)、/opik-test <describe the failure>(查找轨迹,或仅根据描述捕获),或在 /opik-explain 之后立即运行 /opik-test(捕获它刚刚解释的轨迹)。推断其余信息;将以下内容视为可选覆盖项:
- 套件名称(默认:
<project>-regressions) · 项目(默认:轨迹所属项目,否则使用已配置的项目) · 预期输出(默认:无 — 断言中包含预期) · 执行策略(默认:套件的策略;仅针对间歇性故障使用runs_per_item: 3, pass_threshold: 2)。
仅在遇到真正无法推断的阻碍时提问(参见阻碍)。
激活 — 唯一允许的工作范围
1. 确定案例
- 轨迹 ID(UUID 格式):该轨迹就是案例。
- 描述(“退款回复不正确”“它编造了配送时间”):在项目中使用
search_traces查找匹配的轨迹(错误、低分或自由文本匹配),并选取最合适的一条。如果没有匹配项,则仅根据描述捕获 — 将用户输入和预期作为条目内容。 - 确认 Opik 可访问:如果
~/.opik.config存在或设置了OPIK_API_KEY,则使用它。否则 → 阻碍(“运行opik configure,然后重新运行”)。
2. 读取轨迹(优先使用 SDK)
import opik
client = opik.Opik()
tid = "<trace_id>"
trace = client.get_trace_content(tid) # TracePublic: .input, .output, .project_id — NOT .project_name (accessing it raises)
project = client.rest_client.projects.get_project_by_id(trace.project_id).name
spans = client.search_spans(project_name=project, trace_id=tid) # root span (no parent_span_id) names the entrypoint the compare skill will call
# Pass project_name: without it search_spans looks in the configured default project and returns nothing.
准确提取轨迹记录的输入(根 span / 轨迹 input)、实际输出(出错之处)以及根 span 名称(入口点)。MCP 已连接时,read('trace', id) 是等效方式 — 方便但非必需。
3. 编写断言
断言是简单的英文陈述,大模型评判者会根据条目的 data 和候选输出给出通过/失败判断。规则:
- 每条断言只针对一种失败模式。 说明正确的输出会做什么,不要罗列多项质量标准。
- 在错误轨迹上本应失败。 对照刚才读取的实际输出进行检查;如果该断言会通过,那它就是错误的断言。
- 仅根据输出即可判定(若存在
expected_output,也可依据它)。不要使用“有帮助”之类的标准,也不要用李克特量表。 - 最多两条:一条正向预期;仅当错误输出具体做了某件错误的事时,再加一条负向断言(“不得声称……”)。优先采用正向表述:较小的评判模型可能会误读否定句(观察到的情况:“不得承诺 24 小时内退款”在某个明确承诺了这一点的输出上被判定为真)。如果负向要求很重要,就将其融入正向表述(“说明需要 5–7 个工作日,而不是 24 小时”)。
如果正确答案是确定的,应优先采用确定性检查,而不是评判者:也将它放入 data.expected_output,这样 /opik-compare 就能用启发式指标对其评分。
4. 保存用例(创建或追加)
套件命名:<project>-regressions,除非用户指定了名称。复用现有套件;同一项目绝不创建第二个套件。
suite = client.get_or_create_test_suite(
name="<project>-regressions",
project_name=project,
tags=["regression"],
)
# Dedupe on the source trace before inserting.
existing = suite.get_items(filter_string=f'data.source_trace_id = "{tid}"')
if not existing:
suite.insert([{
"data": {
"input": trace.input, # verbatim from the trace
"source_trace_id": tid,
# "expected_output": "...", # only when the correct answer is exact
},
"assertions": ["<positive assertion>", "<optional negative assertion>"],
"description": "Regression from trace <tid>: <one-line failure>. Entrypoint: <root span name>",
}])
description 中包含入口点(根跨度名称),因为 /opik-compare 需要知道调用哪个函数来运行用例;source_trace_id 键则用于避免在同一条轨迹上再次运行 /opik-test 时重复添加。
连接托管的 MCP 后,write 工具的 test_suite.create 和 test_suite_item.upsert 操作会执行相同的操作——调用 schema("test_suite_item.upsert") 获取确切的信封格式。无论使用哪种传输方式,最终都会写入同一个套件;SDK 路径不需要 MCP。
5. 验证
读回该用例——suite.get_items(filter_string=…) 会返回带有 id 的用例——并记录套件当前的版本(suite.get_current_version_name())。不要只凭插入调用就报告成功。
6. 报告
返回套件、用例、断言以及一个后续步骤(见输出)。自然的后续步骤是“修复完成后运行 /opik-compare <suite>”。此技能负责捕获;它不会运行套件(那是 /opik-compare 的工作),也不会更改代码。
阻塞情况
遇到最早的阻塞情况时停止,并且只返回一个后续步骤:
- “运行
opik configure,然后重新运行/opik-test <trace-id>。” - “在项目
<name>中未找到<id>对应的轨迹——请确认 ID 和项目,或者描述故障,我会据此捕获用例。” - “该轨迹没有记录的输入——请提供输入和预期行为,我会据此捕获用例。”
- “这里的行为哪里不对?请告诉我输出应该是什么样,我会据此编写断言。”
输出
面向用户:简短的自然语言消息——包含套件名称和版本、用例(输入用一行表示,断言原样呈现)、用例是新建的还是已存在,以及唯一的后续步骤。不是 JSON,也不是 pytest 文件。
底层(用于组合 / 评测)使用以下一种结构:
status:captured|exists|blockedsuite:name、project、versionitem:id、source_trace_id、input(存储时的内容)、assertions(列表)、expected_output(如果已设置)、entrypointsource:sdk|mcpnext_step:恰好一个(通常为“修复后运行/opik-compare <suite>”)
不变量:captured 和 exists 都包含带有非空 assertions 列表的 item 和一个 suite;每条断言都指明一种故障模式;exists 表示去重检查发现该轨迹已被捕获,且未插入任何内容;blocked 恰好包含一个 next_step;所有路径都不会更改代码库。
示例
来自已说明的轨迹。 /opik-explain 发现 retrieve 工具未返回任何内容,而回答却声称退款会在 24 小时内到账。/opik-test 019fd8a7-…:输入 =“what is your refund window?”,根跨度 = answer。断言:“Response states refunds take 5-7 business days”和“Response does not promise a refund within 24 hours”。创建套件 support-bot-regressions,插入用例,并读回为 v1。→ captured;后续步骤 = “修复 retrieve() 后运行 /opik-compare support-bot-regressions”。
已捕获。 再次使用同一条轨迹。source_trace_id 筛选条件找到了该用例。→ exists:“已存在于 support-bot-regressions 中(用例 …)——准备好后运行 /opik-compare。”
来自描述,没有轨迹。 /opik-test the bot should refuse to give legal advice。没有匹配的轨迹,因此用户的输入和预期会成为用例内容:输入 = 用户描述的提示词,断言 =“Response declines to give legal advice and points to a professional”。→ captured(未设置 source_trace_id)。
受阻——没有配置。 没有 ~/.opik.config,也没有 OPIK_API_KEY。→ blocked:“运行 opik configure,然后重新运行。”(未触碰代码。)
反模式
编写 pytest/vitest 文件,而不是套件条目(/opik-compare 运行的是套件,界面展示的也是套件);使用宽泛的断言(“响应不错”“响应准确且有帮助”);断言在失败的轨迹上也会通过;一次失败写五个断言;每条轨迹都新建一个套件;改写输入,而不是原样保存;在此处运行套件(那是 /opik-compare 的工作);编辑应用代码;顺带修复 bug。
参考资料
测试套件和数据集的详细信息位于与此技能一同安装的 opik 技能中。请直接阅读文件——路径相对于此文件:../opik/references/evaluation-test-suites.md(套件、条目、断言、执行策略、版本);../opik/references/evaluation-datasets.md(OQL 筛选语法、从轨迹创建数据集);../opik/references/production.md(search_traces)。关于如何编写可由裁判判定的断言,请参阅 ../opik-evaluate/references/write-judge-prompt.md。如果宿主采用了不同的技能目录结构,请找到 opik 技能的 references/ 目录。
如果未安装 opik 技能,请在报告中说明,并使用 https://www.comet.com/docs/opik/,不要凭记忆作答。