Phoenix TypeScript SDK 注解模式实践:为 Span、Trace、文档与会话注入可观测反馈
可观测性AI 评测LLMOpsAI 应用人工智能【免费下载链接】phoenixAI Observability Evaluation项目地址https://gitcode.com/gh_mirrors/phoenix13/phoenix点击查看免费下载本文以 Phoenix 官方 TypeScript 客户端为对象系统讲解如何通过arizeai/phoenix-client为 Span、Trace、检索文档与多轮会话写入结构化反馈标注/评分与自由文本备注。你将掌握addSpanAnnotation、addSpanNote、addDocumentAnnotation、addTraceAnnotation、addSessionAnnotation等全部注解 API 的完整参数语义、底层 REST 端点与批量写入用法并能直接在一套 RAG 流水线上落地「文档相关性 → LLM 回答忠实度 → 整条 Trace 正确性」的分层评测方案。概述什么是 Phoenix 注解Annotations在 Phoenix 的评测体系中「注解」是对已采集追踪数据的事后评价——既可以是人类标注HUMAN也可以是 LLM 作为裁判的自动打分LLM或代码规则判定CODE。TypeScript 客户端把这一能力封装为一组独立的函数式 API按作用对象分为四类作用对象单条写入函数批量写入函数底层 REST 端点Span单个步骤addSpanAnnotationlogSpanAnnotations/v1/span_annotationsSpan 内文档RETRIEVER 检索结果addDocumentAnnotationlogDocumentAnnotations/v1/document_annotationsTrace完整调用链addTraceAnnotationlogTraceAnnotations/v1/trace_annotationsSession多轮会话addSessionAnnotationlogSessionAnnotations/v1/session_annotations所有注解共享同一套结果模型label离散标签、score数值分数、explanation解释文本并允许携带任意metadata与用于幂等更新的identifier。这些能力在 js/packages/phoenix-client/src/types/annotations.ts 中统一定义而各端点的请求体转换与校验逻辑分散在 spans/types.ts、traces/types.ts 与 sessions/types.ts 中。客户端初始化所有注解函数都接受可选的client参数不传时内部会自动通过createClient()创建默认实例指向本地 Phoenix 服务的http://localhost:6006import { createClient } from arizeai/phoenix-client; const client createClient(); // 默认: http://localhost:6006从源码实现看如 addSpanAnnotation.tsclient: _client为空时统一走_client ?? createClient()的兜底逻辑因此你既可以在应用入口创建单例client复用于所有调用也可以在函数调用中省略client直接使用默认实例。若 Phoenix 服务部署在其他地址请将自定义端点传入createClient的配置项。注解的统一数据模型与幂等语义在 types/annotations.ts 中Annotation是所有注解类型的公共基类字段类型说明namestring注解名称例如quality、relevance、faithfulnesslabelstring?离散标签如high_quality、relevant、correctscorenumber?数值分数一般取0~1区间explanationstring?对判定结果的解释或依据identifierstring?注解标识符。若提供且该标识已存在则覆盖更新旧注解metadataRecordstring, unknown?任意元数据如评审人、模型名等注解结果label/score/explanation的写入有两条在 spans/types.ts 中由buildAnnotationResult强制执行的规则值得特别留意三者至少提供其一若label、score、explanation全部为空客户端会直接抛出At least one of label, score, or explanation must be provided...错误字符串自动去空白label与explanation在发送前会执行trim()若 trim 后为空字符串则归一化为null。annotatorKind取值为HUMAN、LLM、CODE三者之一默认值为HUMAN见 spans/types.ts 的toSpanAnnotationData。identifier未被显式提供时会被归一化为空字符串。Span 注解给单个步骤打分addSpanAnnotation将反馈绑定到单个 Span例如一次 LLM 调用、一次工具执行。spanId必须是 OpenTelemetry 格式的十六进制 Span ID不带0x前缀import { addSpanAnnotation } from arizeai/phoenix-client/spans; await addSpanAnnotation({ client, spanAnnotation: { spanId: abc123, name: quality, annotatorKind: HUMAN, label: high_quality, score: 0.95, explanation: Accurate and well-formatted, metadata: { reviewer: alice } }, sync: true });底层实现addSpanAnnotation.ts将请求 POST 到/v1/span_annotations并通过查询参数sync控制执行模式sync: true同步处理请求函数返回新注解的{ id: string }便于立即拿到注解 ID 做后续关联sync: false默认异步处理返回null适合高吞吐的评测批处理场景避免阻塞主流程。若提供了identifier同一(spanId, name, identifier)上的重复调用会覆盖更新旧注解——这是实现「按评审人、按批次、按模型版本分别打分」的天然手段。此外客户端还提供logSpanAnnotations批量写入接口同样指向/v1/span_annotations用于一次请求写入多条 Span 注解。Span 备注面向开放编码的自由文本备注Notes是注解的一个特殊变体专为尚未建立评分标准的早期定性观察设计——评审人可以先用自然语言留下观察之后再聚合、蒸馏为结构化标签或分数。import { addSpanNote } from arizeai/phoenix-client/spans; await addSpanNote({ client, spanNote: { spanId: abc123, note: This span shows unexpected behavior, needs review } });从 addSpanNote.ts 的实现可以看到备注写入/v1/span_notes端点其幂等语义与结构化注解不同默认追加append-only不传identifier时服务端为每条备注自动生成px-span-note:uuid形式的唯一标识因此对同一 Span 多次调用会自然累积多条备注显式标识则覆盖传入非空identifier时备注以(spanId, namenote, identifier)为键做 upsert——相同标识的重复调用覆盖旧备注。注意该能力有服务端版本门槛客户端会通过ensureServerCapability检查ADD_SPAN_NOTE_IDENTIFIER能力位不满足时抛出错误。这也解释了结构化注解的键空间设计普通注解以(name, spanId, identifier)为键你可以通过提供不同identifier例如每个评审人一个在同一 Span 上写入多条同名注解而备注天然就是多条累积的。文档注解对 RETRIEVER 检索结果逐条打分在 RAG 场景中检索 Span 通常会附带多篇检索文档。addDocumentAnnotation允许你针对单个文档通过 0 基的documentPosition定位写入相关性评分import { addDocumentAnnotation } from arizeai/phoenix-client/spans; await addDocumentAnnotation({ client, documentAnnotation: { spanId: retriever_span, documentPosition: 0, // 0-based index name: relevance, annotatorKind: LLM, label: relevant, score: 0.95 } });当需要批量标注多篇文档时应使用logDocumentAnnotationslogDocumentAnnotations.ts。它在单次请求中向/v1/document_annotations提交整个数组返回创建注解的 ID 列表每条文档注解同样受「label/score/explanation 至少其一」的校验约束并共享sync参数语义import { logDocumentAnnotations } from arizeai/phoenix-client/spans; await logDocumentAnnotations({ client, documentAnnotations: [ { spanId: retriever_span, documentPosition: 0, name: relevance, annotatorKind: LLM, label: relevant, score: 0.95 }, { spanId: retriever_span, documentPosition: 1, name: relevance, annotatorKind: LLM, label: relevant, score: 0.80 } ] });documentPosition对应 Span 中input.value里检索文档数组的下标是定位被评文档的唯一索引必须与 Span 内实际文档顺序一致才能保证评分对位。Trace 注解评价整条调用链Trace 级注解把评价粒度从单步提升到完整调用链适合给出「整体是否正确」「整体是否令人满意」这类全局结论import { addTraceAnnotation } from arizeai/phoenix-client/traces; await addTraceAnnotation({ client, traceAnnotation: { traceId: trace_abc, name: correctness, annotatorKind: HUMAN, label: correct, score: 1.0 } });traceId同样使用不带0x前缀的十六进制 OpenTelemetry Trace ID。值得注意的一个细节在 traces/types.ts 中注解名note是被保留的——若你把name设为notetoTraceAnnotationData会直接抛出The name note is reserved for trace and span notes. Use addTraceNote instead.引导你改用专用的备注 API。Trace 备注为整条调用链留下跟进记录import { addTraceNote } from arizeai/phoenix-client/traces; await addTraceNote({ client, traceNote: { traceId: abc123def456, note: Needs follow-up — unexpected tool call sequence } });Trace 备注addTraceNote.ts与 Span 备注遵循完全相同的设计默认追加服务端生成px-trace-note:uuid传入identifier则按(traceId, namenote, identifier)upsert。由于 trace note 是较新的能力客户端在调用前会先校验ADD_TRACE_NOTE服务端能力位使用自定义identifier时还需ADD_TRACE_NOTE_IDENTIFIER。Session 注解评估多轮对话整体体验Session 维度用于评价跨多轮的用户与助手交互整体质量如满意度、任务完成度import { addSessionAnnotation } from arizeai/phoenix-client/sessions; await addSessionAnnotation({ client, sessionAnnotation: { sessionId: session_xyz, name: user_satisfaction, annotatorKind: HUMAN, label: satisfied, score: 0.85 } });从 addSessionAnnotation.ts 的实现可见该调用写入/v1/session_annotations端点且对服务端版本有明确要求——代码会先通过ensureServerCapability检查ANNOTATE_SESSIONS能力位其 docstring 标注为requires Phoenix server 12.0.0。这意味着在旧版 Phoenix 服务上调用会话注解会直接报错升级前需要评估服务端版本。同一目录下还提供addSessionNote与logSessionAnnotations分别用于会话级备注与批量写入。综合示例RAG 流水线分层评测将上述 API 组合起来可以在一条 RAG 调用链上实现「文档相关性 → 生成忠实度 → 全链正确性」的三层评测。整套流程先对检索结果批量打相关性分再对生成 Span 打忠实度分最后对整条 Trace 打正确性分import { createClient } from arizeai/phoenix-client; import { logDocumentAnnotations, addSpanAnnotation } from arizeai/phoenix-client/spans; import { addTraceAnnotation } from arizeai/phoenix-client/traces; const client createClient(); // 1. 文档相关性批量LLM 裁判 await logDocumentAnnotations({ client, documentAnnotations: [ { spanId: retriever_span, documentPosition: 0, name: relevance, annotatorKind: LLM, label: relevant, score: 0.95 }, { spanId: retriever_span, documentPosition: 1, name: relevance, annotatorKind: LLM, label: relevant, score: 0.80 } ] }); // 2. LLM 回答忠实度 await addSpanAnnotation({ client, spanAnnotation: { spanId: llm_span, name: faithfulness, annotatorKind: LLM, label: faithful, score: 0.90 } }); // 3. 整条 Trace 正确性人工复核 await addTraceAnnotation({ client, traceAnnotation: { traceId: trace_123, name: correctness, annotatorKind: HUMAN, label: correct, score: 1.0 } });这套模式的价值在于不同层次的评价服务于不同目的——文档级相关性分数直接驱动检索质量调优Span 级忠实度分数暴露幻觉风险Trace 级正确性分数则为整体发布决策提供依据。由于写入均为异步模式未传sync评测流水线可以在推理完成后以低侵入方式批量回填不影响在线服务吞吐。最佳实践与注意事项综合源码实现以下是落地注解功能时应遵循的关键约定结果字段至少提供一个label、score、explanation不能全空否则客户端在发送前即抛错见 spans/types.tsidentifier是幂等更新的钥匙需要反复覆盖同一注解如人工复核修正时务必提供稳定标识否则每次调用都会新建注解备注用于早期定性、注解用于后期量化项目初期用addSpanNote/addTraceNote收集自由文本沉淀出评分标准后再用结构化注解蒸馏为label/score避开保留名note结构化注解的名称不能使用note此类需求一律走专用的 note APItraces/types.ts注意服务端版本门槛Session 注解要求 Phoenix server ≥ 12.0.0span/trace note 的自定义identifier也需要较新服务端支持低版本环境会触发能力位校验错误批量优先需要写入多条同类型注解时使用logDocumentAnnotations/logSpanAnnotations/logTraceAnnotations/logSessionAnnotations一次请求即可完成显著减少网络往返。延伸阅读本文所述全部 API 的实现与类型定义均位于 js/packages/phoenix-client/src 目录下可对照阅读types/annotations.ts公共注解模型Annotation与AnnotatorKind定义spans/addSpanAnnotation.ts、spans/addSpanNote.ts、spans/addDocumentAnnotation.ts、spans/logDocumentAnnotations.tsSpan 与文档注解的端点调用、sync语义与校验逻辑traces/addTraceAnnotation.ts、traces/addTraceNote.tsTrace 级注解与备注含note保留名约束与能力位校验sessions/addSessionAnnotation.tsSession 级注解含ANNOTATE_SESSIONS能力位校验≥ 12.0.0client.tscreateClient客户端工厂与默认端点配置。若需了解注解在服务端如何持久化与聚合含 Python 侧等价 API可进一步查看 packages/phoenix-client/src/phoenix/client/utils/annotation_helpers.py 及 docs/phoenix/evaluation 下的评测文档。赞分享可观测性AI 评测LLMOpsAI 应用人工智能【免费下载链接】phoenixAI Observability Evaluation项目地址https://gitcode.com/gh_mirrors/phoenix13/phoenix点击查看免费下载相关推荐Phoenix Python SDK 注解模式为 Span、Trace、文档与会话添加反馈标注的完整指南Phoenix Python SDK 注解模式为 Span、Trace、文档与会话添加反馈标注的完整指南 Phoenix 的 Annotation注解机制可观测性AI 评测LLMOpsAI 应用人工智能Yuxi 接入 Langfuse 可观测性AgentRun 全链路 Trace 与用户反馈评分实践Yuxi 接入 Langfuse 可观测性AgentRun 全链路 Trace 与用户反馈评分实践 本指南面向在 Yuxi 平台上部署 Langfuse 观测人工智能大模型AI AgentRAG多智能体知识图谱后端前端Opik TypeScript SDK 通用规则实战配置、Trace→Span 追踪模式与最佳实践Opik TypeScript SDK 通用规则实战配置、Trace→Span 追踪模式与最佳实践 Opik TypeScript SDK 是 Opik 平台人工智能LLMOps模型评测可观测性AI AgentAI 应用后端前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考