mcpField
O
opik-diagnose

opik-diagnose

github.com/comet-ml测试与质量887 次安装6 周前更新
代码仓库

关于 opik-diagnose

opik-diagnose 是用于筛选和排序 Opik 在线追踪记录及 Diagnostics 问题的只读技能。它生成带链接的精简清单,供后续 /opik-explain 分析,不修改代码,也不处理离线实验结果。

主要功能

  1. 01排序生产追踪记录清单
  2. 02汇总 Diagnostics 问题并提供追踪链接
  3. 03筛选错误、延迟、评分和回归
  4. 04Opik MCP 不可用时回退至 SDK
  5. 05只读分诊并交接至 /opik-explain

适用场景

  1. 01分诊近期生产错误
  2. 02查找延迟异常和工具调用失败
  3. 03检查较低的在线评估评分
  4. 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. 按信号对剩余追踪排序

为每个剩余候选项评分,并保留排名靠前的几项。优先级顺序:

  1. 发生错误——追踪或某个 span 捕获了异常。
  2. 工具调用失败——某个 tool span 出错、返回了错误格式的结果,或重复了同一次调用(重试循环)。Agent 经常在这里失败,因此应将其作为单独的信号呈现:使用 has_tool_spans 查找候选项,然后扫描其 tool span,检查是否存在非空错误、看起来像错误/拒绝的输出,或连续重复的调用。
  3. 延迟异常值——时长远高于项目的典型值(以 p90/p99 为界)。
  4. 在线评估分数较低——反馈分数低于阈值(Answer Relevance、Hallucination 等)。
  5. 回归——相较于上一时间窗口有所恶化的信号。

将这些项目按上述信号顺序附加到 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 | blocked
  • scope:project、window
  • shortlist:由 {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/,不要凭记忆作答。

评论

支持 Markdown