关于 opik-diagnose
opik-diagnose 是用于筛选和排序 Opik 在线追踪记录及 Diagnostics 问题的只读技能。它生成带链接的精简清单,供后续 /opik-explain 分析,不修改代码,也不处理离线实验结果。
主要功能
- 01排序生产追踪记录清单
- 02汇总 Diagnostics 问题并提供追踪链接
- 03筛选错误、延迟、评分和回归
- 04Opik MCP 不可用时回退至 SDK
- 05只读分诊并交接至 /opik-explain
适用场景
- 01分诊近期生产错误
- 02查找延迟异常和工具调用失败
- 03检查较低的在线评估评分
- 04将追踪记录交给 /opik-explain 调查
MCP 相关
连接 Opik MCP 时,技能会读取项目数据和 Diagnostics 问题,并列出排序后的候选追踪记录。没有 MCP 时,可使用 Opik SDK REST 客户端。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ comet-ml/ opik-skills --skill opik-diagnose安装后在 Claude Code 中输入/opik-diagnose确认已加载。
详细介绍
诊断 — 找出值得关注的迹象
完成标准:列出值得关注的在线/生产环境迹象(以及 Diagnostics 问题),按优先级排序;每项都包含触发提示的信号和迹象 ID,范围限定在某个项目和近期时间窗口内,并可直接交给 /opik-explain。“值得关注”是指发生错误、速度慢、出现回归或在线评估分数低——不是倾倒所有迹象,更不能包含离线实验结果。如果无法读取项目,请停在第一个确实存在的阻碍处,并给出一个下一步操作。
操作:**基于实时数据按实际信号排序,找出少数值得查看的事项,将优先级最高的一项交给 /opik-explain——不要更改任何代码。**此技能按设计为只读。
输入
入口可以是 /opik-diagnose(当前项目)、/opik-diagnose <project>,或 /opik-diagnose <what to look for>(例如“慢速迹象”“今天的错误”)。推断其余信息;以下内容视为可选覆盖项:
- 项目(默认:根据配置/代码仓库推断)· 时间窗口(默认:近期)· 信号重点(默认:全部——错误、延迟、回归、低分)· 候选清单数量(默认:少量)
只有在确实存在无法推断的阻碍时才提问(见阻碍)。
激活 — 唯一适用的工作
1. 确定范围
项目(来自配置/代码仓库)+ 近期时间窗口。确认 Opik 可访问:如果 ~/.opik.config 存在或设置了 OPIK_API_KEY,则使用它。否则 → 阻碍(“运行 opik configure,然后重新运行”)。
2. 读取一次项目,了解本周情况
连接 Opik MCP 后,read('project', <name or id>) 只需一次调用,
便可回答本技能其余部分原本需要猜测的三个问题:是否存在问题(错误率和延迟与前 7 天相比——如果这一周情况平稳,就说明这一点并停止)、项目实际记录了哪些分数名称(之后值得按这些名称筛选;猜错名称会返回空结果,看起来像是好消息),以及项目包含哪些内容。
报告为 null 的比率表示该时间窗口内没有迹象,并非健康的零值。
如果时间窗口内数据稀少,请用 since="30d" 扩大范围,再得出结论。
3. 从 Diagnostics 问题入手
Opik 的 Diagnostics 已将项目中反复出现的故障归纳为按优先级排序的问题,每个问题都包含严重性、发生次数、原因、建议的修复方法和示例跟踪记录。先阅读此列表——它就是界面已计算出的“出了什么问题”的答案,因此不要从原始跟踪记录重新构建。
连接了 Opik MCP 时,agent_insights_issue 实体是首选路径:
list('agent_insights_issue', project_name='<project>') # open issues, ranked as the Diagnostics page ranks them
read('agent_insights_issue', '<issue id>', project_name='<project>')
# → {issue: {name, cause, suggested_fix, severity, status, …}, example_trace_ids: [...], details: [...],
# url: '<the issue's Diagnostics page>', trace_url_template: '<…/logs?trace={trace_id}>'}
每个未解决问题都会成为一个 signal=diagnostics 的候选项:trace_id 取自第一个 example_trace_ids 条目(读取前几个问题即可获取),trace_url 则由 trace_url_template 填入该 ID 得到;同时提及问题的 url,让用户可以打开 Diagnostics 页面本身。如果服务无法确定 UI 基础 URL 或工作区,则不会提供链接字段——此时改用会话说明中的跟踪记录链接模板(步骤 6)。保持列表顺序不变——这是 Diagnostics 页面的排序方式(最近出现的排在前面,其次是发生次数)。计数均为历史累计值,与界面保持一致;传入 since(例如 "7d")可缩小时间范围。
列表为空并不代表一切正常。 它会说明属于哪种情况,以及该怎么做。根据返回的说明采取行动:
| 列表说明 | 操作 |
|---|---|
没有未解决问题,最后扫描时间为 <time> | Diagnostics 正常运行,且未发现问题。继续步骤 3。 |
| 已启用但尚未扫描,或上次扫描时间超过一天 | write('agent_insights_job.trigger', {"project_name": "<project>"}),报告 Diagnostics 页面链接,然后继续步骤 3。无需询问:扫描不会更改任何数据。 |
| 此项目未启用,或已关闭 | 用一句话询问用户一次:“要为 <project> 启用每日 Diagnostics 吗?几分钟后会有首批结果。”如果用户同意:执行 enable,然后执行 trigger,报告链接并继续。如果用户不同意:继续,并说明候选列表是在未使用 Diagnostics 的情况下生成的。 |
| 此部署不提供该功能 | 继续,并说明此部署没有 Diagnostics。不要提出启用选项。 |
绝不要等待扫描完成或轮询扫描状态。提供页面链接,继续根据跟踪记录完成分诊,并说明分组报告会在几分钟后生成。如果你启动的扫描仍在运行时就生成了候选列表,请标记 source=diagnostics_pending。
非空列表也不代表答案完整。 列表末尾会注明报告覆盖范围:Report covers data through <time>,因为问题是由上次扫描归纳的。每日扫描通常不会包含当天的数据。如果这行接着列出未覆盖的时间尾段,说明用户要求的时间范围超出了报告范围,这部分缺口未包含在答案中:
| 覆盖范围说明 | 操作 |
|---|---|
Report covers data through <time>,没有其他内容 | 报告是最新的。照常继续步骤 3。 |
The last <N> are not in it: write('agent_insights_job.trigger', …) | 触发扫描,然后转到步骤 3,使用该行给出的 since 查询缺口。不要等待重新扫描,也不要声称这些问题覆盖了整个时间范围。标记 source=diagnostics_pending。 |
… a trigger rescans the last 24 hours, so it cannot close this gap | 跳过触发操作,直接转到步骤 3,使用该行给出的 since——重新扫描仍会漏掉缺口中间的部分,却会让人误以为问题已解决。 |
必要时,在报告中说明数据截至日期:如果用户询问的是一周的数据,而你拿到的问题只覆盖到昨天,应由你告知用户,而不是让他们自行发现。
分诊绝不会更改问题状态。agent_insights_issue.resolve、.close 和 .reopen 均可用,但只有在用户提出要求时才应调用:故障是否已处理由用户决定,而被标记为已解决的问题会从其他人查看的列表中移除。呈现问题是此技能的职责;关闭问题则不是。
未连接 MCP 时,SDK REST 客户端会读取相同的问题:
import opik
client = opik.Opik()
# Needs the project_id (a uuid), not the name — read it off any trace from
# search_traces (trace.project_id), or resolve it from the project name first.
issues = client.rest_client.agent_insights.find_agent_insights_issues(project_id=project_id)
4. 拉取候选追踪以填补空缺——优先使用 MCP,SDK 作为后备方案
Diagnostics 会报告最近一次运行中分组的内容。任何更新的内容,或低于其分组阈值的内容——单个延迟异常值、一个较低的在线评估分数、相较于上一时间窗口的回归——仍需扫描。跳过已包含在某个问题的 example_trace_ids 中的追踪;它们已列入该问题下的候选名单。
-
已连接 MCP: 每种信号调用一次
list。后端会进行筛选和排序,因此每次调用都会返回一页简短且已排名的结果——无需 SDK,也无需客户端排序。since可取"1h"、"24h"、"7d";filters是 OQL 字符串;sort的格式为"<field> [asc|desc]"(默认降序)。追踪列表会隐藏评估器/playground/实验追踪(source = "sdk"),除非你指定source。list(entity_type="trace", project_name="<project>", since="24h", filters="error_info is_not_empty", sort="start_time desc") # errored list(entity_type="span", project_name="<project>", since="24h", filters='type = "tool" AND error_info is_not_empty', sort="start_time desc") # failed tool calls list(entity_type="trace", project_name="<project>", since="24h", sort="duration desc") # latency outliers (ms) list(entity_type="trace", project_name="<project>", since="24h", filters="feedback_scores.<metric> < 0.5", sort="feedback_scores.<metric> asc") # low online-eval score list(entity_type="trace", project_name="<project>", since="7d", until="24h", sort="duration desc") # prior window, for regressions表格默认包含
duration、error_type和成本,以及你排序或筛选所依据的每个字段。如果筛选条件被拒绝,返回结果会说明如何修正;schema("list.trace")是完整的字段参考。 -
未连接 MCP: 改用 SDK。
traces = client.search_traces(project_name="<project>", max_results=200) # recent window # Narrow server-side with filter_string='error_info is_not_empty' when the volume is # large; otherwise rank client-side (step 5). Each trace carries the fields you rank # on: error info, duration, feedback_scores.
跳过已包含在某个问题的 example_trace_ids 中的追踪;它们已列入该问题下的候选名单。
5. 按信号对剩余追踪排序
为每个剩余候选项评分,并保留排名靠前的几项。优先级顺序:
- 发生错误——追踪或某个 span 捕获了异常。
- 工具调用失败——某个
toolspan 出错、返回了错误格式的结果,或重复了同一次调用(重试循环)。Agent 经常在这里失败,因此应将其作为单独的信号呈现:使用has_tool_spans查找候选项,然后扫描其toolspan,检查是否存在非空错误、看起来像错误/拒绝的输出,或连续重复的调用。 - 延迟异常值——时长远高于项目的典型值(以 p90/p99 为界)。
- 在线评估分数较低——反馈分数低于阈值(Answer Relevance、Hallucination 等)。
- 回归——相较于上一时间窗口有所恶化的信号。
将这些项目按上述信号顺序附加到 Diagnostics 项目之后。为每个入围项目标注触发它的那一个信号,并简要说明原因——每条追踪一项:当一条追踪符合多个信号时(例如出错的 tool span 也会导致追踪出错),保留优先级最高的信号,并在原因中提及其他信号。优先提供简短的排名列表,而不是冗长列表。
6. 保持范围
仅限在线/生产环境的追踪信号。不要呈现离线实验结果——这些是 /opik-evaluate 和 /opik-compare 的输出,不应在此重新发现。
7. 报告
返回排名后的候选列表和一个后续步骤。将每个项目作为可点击的 Opik UI 链接提供,绝不要只给裸 ID,以便用户可以打开并深入查看。不要臆造 URL 格式——猜出的链接看似正确,却会返回 404,比只给 ID 更糟。请使用服务器提供的链接:问题的 trace_url_template,或 MCP 在其会话指令中命名的追踪链接模板(<opik>/api/v1/session/redirect/projects/?trace_id={trace_id}&path=…)。该模板会根据 ID 解析项目和工作区,因此只需填入 ID。在 SDK 路径中,opik.url_helpers.get_project_url_by_trace_id(trace_id, url_override) 会生成相同的链接。每个项目都可直接用于 /opik-explain;自然的下一步是“解释排名第一的追踪”(见输出)。此技能负责发现并交接,不负责根因分析(那是 /opik-explain 的工作),也不会更改代码。
阻塞项
遇到最早的阻塞项时停止,并且只返回一个后续步骤:
- "运行
opik configure,然后重新运行/opik-diagnose。" - "我应该扫描哪个项目?请传入
/opik-diagnose <project>,或在 Opik 配置中设置项目。" - "此环境无法连接 Opik——请打开项目的追踪视图,按错误/时长排序,或在已配置 Opik 的环境中运行。"
输出
**面向用户:**一条简短的说明——排名后的候选列表(每条 trace 附带可点击的 Opik UI 链接、对应信号和一句原因,最差的排在最前),然后是唯一的下一步。不要输出所有 trace 的原始数据,也不要输出 JSON。
底层(用于组合 / 评估),采用一种格式:
status:found|empty|blockedscope:project、windowshortlist:由{trace_id, trace_url (the Opik UI link), signal (error|tool_call|latency|low_score|regression|diagnostics), why, rank}组成的列表source:sdk|mcp|diagnostics_pending(本次运行触发了扫描;候选列表来自 trace)next_step:恰好一个(通常是“解释排名第一的 trace”)
不变量:found 必须包含非空的 shortlist,且每项都包含 signal、trace_id 和可点击的 trace_url;empty 表示读取成功,但没有任何内容超过阈值;blocked 必须且只能包含一个 next_step;候选列表绝不包含离线实验结果;所有路径都不会更改代码库。
示例
对项目进行排查,已连接 MCP。 /opik-diagnose。list('agent_insights_issue', project_name=…) 返回两个未解决问题:一个高严重级别的工具调用循环(昨天发生 12 次),以及一个低严重级别的空答案问题。对第一个问题执行 read,可获得原因、三个示例 trace ID 和链接。接着,list('trace', since="24h", sort="duration desc") 找到一条耗时为 p90 的 5 倍、但未被任何问题涵盖的 trace。候选列表 = 工具调用循环(排名 1,diagnostics,第一个示例 trace)、延迟异常值(排名 2,latency)、空答案问题(排名 3,diagnostics);下一步 =“解释排名第一的 trace”。source=mcp。→ found。
对项目进行排查,仅使用 SDK。 /opik-diagnose。find_agent_insights_issues 尚无结果;对项目执行 search_traces,找到两条出错的 trace、一条耗时为 p90 的 5 倍的 trace,以及一条 Hallucination 得分为 0.2 的 trace。候选列表 = 两条出错的 trace(排名 1–2)、延迟异常值(排名 3)、低分 trace(排名 4),每项都标注对应的信号;下一步 =“解释排名第一的 trace”。source=sdk。→ found。
一切正常。 /opik-diagnose。读取正常,但没有 trace 出错、运行缓慢或得分偏低。→ empty:“近期窗口内没有 trace 超过阈值。”
受阻——缺少配置。 /opik-diagnose。没有 ~/.opik.config,也没有 OPIK_API_KEY。→ blocked:“运行 opik configure,然后重新运行 /opik-diagnose。”(未修改任何代码。)
反模式
倾倒所有 trace,而不是提供排名后的候选列表;当 agent_insights_issue(或 SDK agent_insights 客户端)已列出问题时,仍从原始 trace 重建 Diagnostics 排名;展示离线实验 / evaluate 结果(不在范围内);要求必须使用 MCP(SDK 的 agent_insights 路径无需 MCP);在此处追根溯源分析 trace(交给 /opik-explain);编辑代码(此技能只负责呈现问题);按时间新近程度而不是信号排名。
参考资料
SDK 和可观测性详情位于与本技能一同安装的 opik 技能中。直接阅读相关文件——路径相对于当前文件:../opik/SKILL.md(搜索 trace——MCP list 工具和 search_traces 共用的 OQL 筛选语法)、../opik/references/production.md(search_traces、Diagnostics、在线评估分数、错误 / 延迟分析)、../opik/references/tracing-python.md(SDK 读取 API)、../opik/references/observability.md(span / 分数模型)。如果宿主的技能目录结构不同,请找到 opik 技能的 references/ 目录。
如果未安装 opik 技能,请在报告中说明,并参考 https://www.comet.com/docs/opik/,不要凭记忆作答。