mcpField
P
phoenix-cli

phoenix-cli

github.com/github测试与质量40.6k1.0k 次安装1 天前更新
代码仓库

关于 phoenix-cli

phoenix-cli 是用于检查 Phoenix 项目、Trace、Span、会话、数据集、实验和提示词的命令行技能,也通过笔记和故障分类指导 LLM 流量分析。

主要功能

  1. 01检查 Trace、Span 和会话
  2. 02为记录添加标注和笔记
  3. 03管理数据集、实验和提示词
  4. 04使用 GraphQL 查询 Phoenix
  5. 05创建本地分析旁文件

适用场景

  1. 01调查抽样 LLM Trace 中的错误
  2. 02将观察结果归纳为故障类别
  3. 03检查数据集和实验结果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/github/awesome-copilot --skill phoenix-cli

安装后在 Claude Code 中输入/phoenix-cli确认已加载。

附带文件references/axial-coding.mdreferences/open-coding.md

详细介绍

Phoenix CLI

调用

px <resource> <action>                          # if installed globally
npx @arizeai/phoenix-cli <resource> <action>    # no install required

CLI 使用单数形式的资源命令,并带有 list 和 get 等子命令:

px trace list
px trace get <trace-id>
px trace annotate <trace-id>
px trace add-note <trace-id>
px trace-annotations delete
px span list
px span annotate <span-id>
px span add-note <span-id>
px span-annotations delete
px session list
px session get <session-id>
px session annotate <session-id>
px session add-note <session-id>
px session-annotations delete
px dataset list
px dataset get <name>
px project list
px project get <name>
px annotation-config list
px auth status
px profile list
px profile show [name]
px profile create <name>
px profile use <name>
px profile edit <name>
px profile delete <name>

设置

export PHOENIX_HOST=http://localhost:6006
export PHOENIX_PROJECT=my-project
export PHOENIX_API_KEY=your-api-key  # if auth is enabled

在通过管道传给 jq 时,始终使用 --format raw --no-progress。

快速参考

任务文件
查看采样的 trace、span 或 session,并针对出了什么问题写下具体笔记(尚无分类体系)references/open-coding
将这些笔记归入结构化的失败分类体系,并量化哪些内容重要references/axial-coding

两个阶段都会为每个产物打上一个共享的 编码标注标识符(描述性形态,例如 coding-run:chatbot-context-loss-2026-05-06),以便该次运行可查询、可回滚,并能作为一个整体查看。在每次 px 调用时都显式传入 --identifier <value> —— 在不同 Agent harness 之间,shell 继承并不可靠。开放编码通过 px ... add-note 写入笔记,并在 .px/coding/<sanitized-identifier>.jsonl 记录一个小型本地 JSONL sidecar;轴向编码读取该 sidecar 作为确定性的交接,并在 .px/coding/<sanitized-identifier>-axial.jsonl 中记录标签。每次运行只选取一次标识符(见 references/open-coding.md),然后在总结部分分享 Phoenix UI 链接。回滚是选择加入的,并且只有在用户明确确认后才会执行三个绑定标识符的 DELETE。

工作流术语 vs. 服务端标注名称。 技能文档将此值称为 编码标注标识符(shell 变量提示:CODING_ANNOTATION_IDENTIFIER)。用于 UI 过滤的服务端标注名称保持不变 —— coding_session_id —— 以便与先前运行已写入的行保持数据兼容。不要尝试重命名服务端标注;请将此不对称视为关键设计。

工作流

"插桩之后我该做什么?" / "我该关注哪里?" / "出了什么问题?" open-coding → axial-coding → 为排名靠前的类别构建 eval。

参考类别

前缀描述
references/open-coding针对采样的 trace、span 或 session 的自由形式笔记 —— 每当用户想要理解 LLM 流量但尚无失败类别时,就该用它。包含一个分析单元诊断,使工作流在失败模式实际所在的层级运行(无状态单次调用用 trace,多轮 Agent 用 session,机械性/孤立失败用 span)。
references/axial-coding将笔记归纳分组为带计数的 MECE 分类体系 —— 每当用户已有观察结果并需要类别或 eval 目标时,就该用它

认证

px auth status                                # check connection and authentication
px auth status --endpoint http://other:6006   # check a specific endpoint
px auth status --profile staging              # check a named profile's connection

配置档案

命名配置档案让你可以在多个 Phoenix 实例(本地、staging、云端)之间切换,而无需在环境变量之间来回折腾。配置档案存储在 ~/.px/settings.json(或 $XDG_CONFIG_HOME/px/settings.json)。

配置优先级(从高到低):CLI 标志 > 环境变量 > 活动配置档案 > 内置默认值。

px profile list                              # list all profiles (shows active profile)
px profile show                              # show the active profile's settings
px profile show staging                      # show a named profile's settings
px profile create prod --endpoint https://app.phoenix.arize.com --api-key <key> --activate
px profile create local --endpoint http://localhost:6006 --project my-app
px profile use prod                          # switch the active profile
px profile edit prod                         # open profile JSON in $EDITOR (validates on save)
px profile delete prod --yes                 # delete a profile (--yes skips confirmation)

在任何命令上使用 --profile <name>,即可在不更改活动配置档案的情况下定位到特定配置档案:

px trace list --profile staging --limit 10 --format raw --no-progress | jq .
px auth status --profile prod

px profile create 选项:--endpoint <url>、--project <name>、--api-key <key>、--header <key=value>(可重复)、--activate。

项目

px project list                                            # list all projects (table view)
px project list --format raw --no-progress | jq '.[].name' # project names as JSON
px project get my-project --format raw --no-progress       # single record by exact name
px project get my-project --format raw --no-progress | jq -r '.id'  # extract project id

project get 在名称未命中时以 ExitCode.FAILURE(1)退出,并在 --format json|raw 下向 stderr 写入 StructuredError {error, code: "FAILURE", hint}。

Trace

px trace list --limit 20 --format raw --no-progress | jq .
px trace list --last-n-minutes 60 --limit 20 --format raw --no-progress | jq '.[] | select(.status == "ERROR")'
px trace list --since 2025-01-15T00:00:00Z --limit 50 --format raw --no-progress | jq .
px trace list --format raw --no-progress | jq 'sort_by(-.duration) | .[0:5]'
px trace list --include-notes --format raw --no-progress | jq '.[].notes'
px trace get <trace-id> --format raw | jq .
px trace get <trace-id> --format raw | jq '.spans[] | select(.status_code != "OK")'
px trace get <trace-id> --include-notes --format raw | jq '.notes'
px trace annotate <trace-id> --name reviewer --label pass
px trace annotate <trace-id> --name reviewer --score 0.9 --format raw --no-progress
px trace annotate <trace-id> --name reviewer --label pass --identifier "<coding-annotation-id>"  # tag with a coding annotation identifier
px trace add-note <trace-id> --text "needs follow-up"
px trace add-note <trace-id> --text "needs follow-up" --identifier "<coding-annotation-id>"  # tag + upsert on identifier
px trace-annotations delete --identifier "<coding-annotation-id>" --all -y            # nuke every annotation tied to this coding annotation identifier

px <entity>-annotations delete 需要 --all 或同时提供 --start-time 和 --end-time,并在成功时输出 {deleted: true, target, filter}。

Trace JSON 形态
Trace
  traceId, status ("OK"|"ERROR"), duration (ms), startTime, endTime
  annotations[] (with --include-annotations, excludes note)
    name, result { score, label, explanation }
  notes[] (with --include-notes)
    name="note", result { explanation }
  rootSpan  — top-level span (parent_id: null)
  spans[]
    name, span_kind ("LLM"|"CHAIN"|"TOOL"|"RETRIEVER"|"EMBEDDING"|"AGENT"|"RERANKER"|"GUARDRAIL"|"EVALUATOR"|"UNKNOWN")
    status_code ("OK"|"ERROR"|"UNSET"), parent_id, context.span_id
    notes[] (with --include-notes)
      name="note", result { explanation }
    attributes
      input.value, output.value          — raw input/output
      llm.model_name, llm.provider
      llm.token_count.prompt/completion/total
      llm.token_count.prompt_details.cache_read
      llm.token_count.completion_details.reasoning
      llm.input_messages.{N}.message.role/content
      llm.output_messages.{N}.message.role/content
      llm.invocation_parameters          — JSON string (temperature, etc.)
      exception.message                  — set if span errored

Span

px span list --limit 20                                    # recent spans (table view)
px span list --last-n-minutes 60 --limit 50                # spans from last hour
px span list --since 2025-01-15T00:00:00Z --limit 50       # spans since a timestamp
px span list --span-kind LLM --limit 10                    # only LLM spans
px span list --status-code ERROR --limit 20                # only errored spans
px span list --name chat_completion --limit 10             # filter by span name
px span list --trace-id <id> --format raw --no-progress | jq .   # all spans for a trace
px span list --parent-id null --limit 10                   # only root spans
px span list --parent-id <span-id> --limit 10              # only children of a span
px span list --include-annotations --limit 10              # include annotation scores
px span list --include-notes --limit 10                    # include span notes
px span list --attribute llm.model_name:gpt-4 --limit 10  # filter by string attribute
px span list --attribute llm.token_count.total:500 --limit 10  # filter by numeric attribute
px span list --attribute 'user.id:"12345"' --limit 10     # force string match for numeric-looking value
px span list --attribute session.id:sess:abc:123 --limit 20  # colon in value OK (split on first colon only)
px span list --attribute llm.model_name:gpt-4 --attribute session.id:abc --limit 10  # AND multiple filters
px span list output.json --limit 100                       # save to JSON file
px span list --format raw --no-progress | jq '.[] | select(.status_code == "ERROR")'
px span annotate <span-id> --name reviewer --label pass
px span annotate <span-id> --name checker --score 1 --annotator-kind CODE
px span annotate <span-id> --name reviewer --label pass --identifier "<coding-annotation-id>"  # tag with a coding annotation identifier
px span add-note <span-id> --text "verified by agent"
px span add-note <span-id> --text "verified by agent" --identifier "<coding-annotation-id>"  # tag + upsert on identifier
px span-annotations delete --identifier "<coding-annotation-id>" --all -y           # nuke every annotation tied to this coding annotation identifier
Span JSON 形态
Span
  name, span_kind ("LLM"|"CHAIN"|"TOOL"|"RETRIEVER"|"EMBEDDING"|"AGENT"|"RERANKER"|"GUARDRAIL"|"EVALUATOR"|"UNKNOWN")
  status_code ("OK"|"ERROR"|"UNSET"), status_message
  context.span_id, context.trace_id, parent_id
  start_time, end_time
  attributes
    input.value, output.value          — raw input/output
    llm.model_name, llm.provider
    llm.token_count.prompt/completion/total
    llm.input_messages.{N}.message.role/content
    llm.output_messages.{N}.message.role/content
    llm.invocation_parameters          — JSON string (temperature, etc.)
    exception.message                  — set if span errored
  annotations[] (with --include-annotations, excludes note)
    name, result { score, label, explanation }
  notes[] (with --include-notes)
    name="note", result { explanation }

Session

px session list --limit 10 --format raw --no-progress | jq .
px session list --order asc --format raw --no-progress | jq '.[].session_id'
px session list --include-annotations --include-notes --format raw --no-progress | jq '.[].notes'
px session get <session-id> --format raw | jq .
px session get <session-id> --include-annotations --format raw | jq '.session.annotations'
px session get <session-id> --include-notes --format raw | jq '.session.notes'
px session annotate <session-id> --name reviewer --label pass
px session annotate <session-id> --name reviewer --score 0.9 --format raw --no-progress
px session annotate <session-id> --name reviewer --label pass --identifier "<coding-annotation-id>"  # tag with a coding annotation identifier
px session add-note <session-id> --text "verified by agent"
px session add-note <session-id> --text "verified by agent" --identifier "<coding-annotation-id>"  # tag + upsert on identifier
px session-annotations delete --identifier "<coding-annotation-id>" --all -y              # nuke every annotation tied to this coding annotation identifier
Session JSON 形态
SessionData
  id, session_id, project_id
  start_time, end_time
  token_count_prompt, token_count_completion, token_count_total  — cumulative across all LLM spans in the session (int, default 0)
  annotations[] (with --include-annotations, excludes note)
    name, result { score, label, explanation }
  notes[] (with --include-notes)
    name="note", result { explanation }
  traces[]
    id, trace_id, start_time, end_time

Datasets / Experiments / Prompts

px dataset list --format raw --no-progress | jq '.[].name'
px dataset get <name> --format raw | jq '.examples[] | {input, output: .expected_output}'
px dataset get <name> --split train --format raw | jq .    # filter by split
px dataset get <name> --version <version-id> --format raw | jq .
px experiment list --dataset <name> --format raw --no-progress | jq '.[] | {id, name, failed_run_count}'
px experiment get <id> --format raw --no-progress | jq '.[] | select(.error != null) | {input, error}'
px prompt list --format raw --no-progress | jq '.[].name'
px prompt get <name> --format text --no-progress   # plain text, ideal for piping to AI

标注配置

px annotation-config list                                           # list all configs (table view)
px annotation-config list --format raw --no-progress | jq '.[].name' # config names as JSON

GraphQL

用于执行上述命令未覆盖的临时查询。输出为 {"data": {...}}。

px api graphql '{ projectCount datasetCount promptCount evaluatorCount }'
px api graphql '{ projects { edges { node { name traceCount tokenCountTotal } } } }' | jq '.data.projects.edges[].node'
px api graphql '{ datasets { edges { node { name exampleCount experimentCount } } } }' | jq '.data.datasets.edges[].node'
px api graphql '{ evaluators { edges { node { name kind } } } }' | jq '.data.evaluators.edges[].node'

# Introspect any type
px api graphql '{ __type(name: "Project") { fields { name type { name } } } }' | jq '.data.__type.fields[]'

主要根字段:projects、datasets、prompts、evaluators、projectCount、datasetCount、promptCount、evaluatorCount、viewer。

文档

下载 Phoenix 文档 markdown,供编码 Agent 在本地使用。

px docs fetch                                # fetch default workflow docs to .px/docs
px docs fetch --workflow tracing             # fetch only tracing docs
px docs fetch --workflow tracing --workflow evaluation
px docs fetch --dry-run                      # preview what would be downloaded
px docs fetch --refresh                      # clear .px/docs and re-download
px docs fetch --output-dir ./my-docs         # custom output directory

主要选项:--workflow(可重复,取值:tracing、evaluation、datasets、prompts、integrations、sdk、self-hosting、all)、--dry-run、--refresh、--output-dir(默认 .px/docs)、--workers(默认 10)。

评论

支持 Markdown