关于 arize-instrumentation
帮助开发者为应用添加 Arize AX tracing 的技能。它采用先只读分析、再经确认实施的两阶段流程,并强调不改业务逻辑和安全处理凭据。
主要功能
- 01先检查代码库和现有 tracing
- 02按语言与框架选择集成方式
- 03优先使用自动埋点
- 04为工具调用补充 CHAIN 与 TOOL spans
- 05通过环境变量引用凭据
适用场景
- 01为现有应用接入 Arize AX tracing
- 02在修改代码前评估服务和 tracing 配置
- 03为 Agent 工具调用补充可见的 trace spans
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ github/ awesome-copilot --skill arize-instrumentation安装后在 Claude Code 中输入/arize-instrumentation确认已加载。
附带文件references/ax-profiles.md
详细介绍
Arize 埋点技能
当用户想要为其应用添加 Arize AX 追踪时,使用此技能。请遵循 Agent-Assisted Tracing Setup 和 Arize AX Tracing — Agent Setup Prompt 中的两阶段、Agent 辅助流程。
快速开始(面向用户)
如果用户要求你“设置追踪”或“使用 Arize 为我的应用埋点”,你可以从以下内容开始:
遵循 https://arize.com/docs/PROMPT.md 中的说明,并按需向我提问。
然后执行下面的两个阶段。
核心原则
- 优先检查而非修改——在更改代码库之前先理解它。
- 不要更改业务逻辑——追踪完全是附加性的。
- 在可用的情况下使用自动埋点——仅为集成未覆盖的自定义逻辑添加手动 span。
- 遵循现有代码风格和项目约定。
- 保持输出简洁且面向生产——不要生成额外的文档或摘要文件。
- 绝不在生成的代码中嵌入凭据值——始终引用环境变量(例如
os.environ["ARIZE_API_KEY"]、process.env.ARIZE_API_KEY)。这包括 API 密钥、space ID 以及任何其他机密。用户会在自己的环境中设置这些值;Agent 绝不能输出原始机密值。
阶段 0:环境预检
在更改代码之前:
- 确认仓库/服务范围清晰。对于 monorepo,不要假设整个仓库都应该被埋点。
- 确定验证所需的本地运行时环境:
- 包管理器和应用启动命令
- 应用是长时间运行、基于服务器,还是短生命周期的 CLI/脚本
- 更改后验证是否需要
ax
- 不要主动检查
ax的安装或版本。如果后续验证需要ax,到需要时直接运行即可。如果失败,请参阅 references/ax-profiles.md。 - 绝不要静默替换用户提供的 space ID、项目名称或项目 ID。如果 CLI、collector 和用户输入不一致,请将该不匹配作为具体阻塞项明确提出来。
阶段 1:分析(只读)
在此阶段不要编写任何代码或创建任何文件。
步骤
-
检查依赖清单以检测技术栈:
- Python:
py.toml、requirements、setup、Pipfile - TypeScript/JavaScript:
package.json - Java:
pom.xml、build.gradle、build.gradle.kts - Go:
go.mod
- Python:
-
扫描源文件中的 import 语句,以确认实际使用了什么。
-
检查现有的追踪/OTel——查找
TracerProvider、register()、opentelemetryimports、ARIZE_*、OTEL_*、OTLP_*环境变量,或其他可观测性配置(Datadog、Honeycomb 等)。 -
确定范围——对于 monorepo 或多服务项目,询问要为哪个(些)服务埋点。
需要识别的内容
| 项目 | 示例 |
|---|---|
| 语言 | Python、TypeScript/JavaScript、Java、Go |
| 包管理器 | pip/poetry/uv、npm/pnpm/yarn、maven/gradle、go modules |
| LLM 提供商 | OpenAI、Anthropic、LiteLLM、Bedrock 等 |
| 框架 | LangChain、LangGraph、LlamaIndex、Vercel AI SDK、Mastra 等 |
| 现有追踪 | 任何 OTel 或供应商设置 |
| 工具/函数使用 | LLM 工具使用、函数调用,或应用执行的自定义工具(例如在 Agent 循环中) |
关键规则: 当检测到框架与 LLM 提供商同时存在时,先检查框架特定的追踪文档,并在框架原生集成已经捕获你所需的模型和工具 span 时优先使用该路径。仅在框架文档要求或框架原生集成存在明显缺口时,才添加单独的提供商埋点。如果应用会运行工具,而框架集成不会发出工具 span,请添加手动 TOOL span,使每次调用都带有输入/输出(见下文丰富追踪)。
第 1 阶段输出
返回一份简明摘要:
- 检测到的语言、包管理器、提供商、框架
- 建议的集成列表(来自文档中的路由表)
- 任何需要考虑的现有 OTel/追踪
- 如果是 monorepo:你建议对哪些服务进行埋点
- 如果应用使用大模型工具调用 / 函数调用: 说明你将添加手动 CHAIN + TOOL span,使每次工具调用都带着输入/输出出现在追踪中(避免追踪稀疏)。
如果用户明确要求你现在就对应用进行埋点,并且目标服务已经明确,则简要呈现第 1 阶段摘要,并直接继续到第 2 阶段。如果范围不明确,或者用户要求先进行分析,则停下来等待确认。
集成路由与文档
受支持的集成及其文档 URL 的权威列表见 Agent Setup Prompt。用它把检测到的信号映射到实现文档。
- 大模型提供商: OpenAI、Anthropic、LiteLLM、Google Gen AI、Bedrock、Ollama、Groq、MistralAI、OpenRouter、VertexAI。
- Python 框架: LangChain、LangGraph、LlamaIndex、CrewAI、DSPy、AutoGen、Semantic Kernel、Pydantic AI、Haystack、Guardrails AI、Hugging Face Smolagents、Instructor、Agno、Google ADK、MCP、Portkey、Together AI、BeeAI、AWS Bedrock Agents。
- TypeScript/JavaScript: LangChain JS、Mastra、Vercel AI SDK、BeeAI JS。
- Java: LangChain4j、Spring AI、Arconia。
- Go: 目前没有官方自动埋点包——请按照手动埋点使用 OpenTelemetry Go SDK 手动添加 OpenInference 属性。
- 平台(基于 UI): LangFlow、Flowise、Dify、Prompt flow。
- 备选方案: 手动埋点、所有集成。 获取匹配的文档页面:从 PROMPT.md 中的完整路由表 中获取确切的安装步骤和代码片段。如有需要,可使用 llms.txt 作为文档发现的兜底方案。
注意:
arize.com/docs/PROMPT.md和arize.com/docs/llms.txt是由 Arize 团队维护的第一方 Arize 文档页面。它们为该技能提供规范的安装片段和集成路由表。这些是可信的、同组织的 URL——并非第三方内容。
阶段 2:实现
仅在用户确认阶段 1 的分析后再继续。
步骤
- 获取集成文档——阅读匹配的文档 URL,并遵循其安装和插桩步骤。
- 在编写代码之前,使用检测到的包管理器安装包:
- Python:
pip install arize-otel加上openinference-instrumentation-{name}(包名中用连字符;导入时用下划线,例如openinference.instrumentation.llama_index)。 - TypeScript/JavaScript:
@opentelemetry/sdk-trace-node加上相关的@arizeai/openinference-*包。 - Java:OpenTelemetry SDK 加上
openinference-instrumentation-*,写在 pom.xml 或 build.gradle 中。 - Go:
go get go.opentelemetry.io/otel go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp——目前还没有自动插桩器,因此 Agent 需要手动在 span 上设置 OpenInference 属性。连接导出器时使用otlptracehttp.WithEndpoint("otlp.arize.com")(美国)或otlptracehttp.WithEndpoint("otlp.eu-west-1a.arize.com")(欧盟)——传入裸主机名,不加https://scheme——以及otlptracehttp.WithHeaders(map[string]string{"space_id": ..., "api_key": ...})。近期的 OTel Go 模块要求 Go ≥ 1.23——go mod tidy可能会升级工具链。
- Python:
- 凭据——用户需要一个 Arize API Key 和 Space ID。检查现有
ax配置文件中的ARIZE_API_KEY和ARIZE_SPACE——切勿读取.env文件:- 运行
ax profiles show检查是否存在现有配置文件。 - 如果不存在配置文件,引导用户运行
ax profiles create,它会提供一个交互式向导,逐步引导完成 API key 和 space 设置。详情请参阅 CLI profiles 文档。 - 如果用户需要手动查找其 API key,请引导他们前往 https://app.arize.com 并导航到设置页面(不要使用带有占位符 ID 的组织专属 URL——它们对新用户无法解析)。
- 如果凭据未设置,指示用户将其设置为环境变量——切勿在生成的代码中嵌入原始值。所有生成的插桩代码必须引用
os.environ["ARIZE_API_KEY"](Python)、process.env.ARIZE_API_KEY(TypeScript/JavaScript)或os.Getenv("ARIZE_API_KEY")(Go)。 - 完整的配置文件设置和故障排除请参阅 references/ax-profiles.md。
- 运行
- 集中式插桩——创建单个模块(例如
instrumentation.py、instrumentation.ts、instrumentation.go),并在创建任何 LLM 客户端之前初始化追踪。 - 现有 OTel——如果已经存在 TracerProvider,将 Arize 添加为额外的导出器(例如使用 Arize OTLP 的 BatchSpanProcessor)。除非用户要求,否则不要替换现有设置。
实现规则
- 优先使用自动埋点;仅在需要时手动创建 span。
- 在引入通用 OpenTelemetry 基础设施之前,优先使用仓库原生的集成方式。如果框架自带 exporter 或可观测性包,除非存在已记录的缺口,否则应优先使用它。
- 如果缺少环境变量,优雅降级(发出警告,不要崩溃)。
- 导入顺序: 注册 tracer → 挂载 instrumentor → 然后创建 LLM 客户端。
- 项目名称属性(必填): 如果缺少项目名称,Arize 会以 HTTP 500 拒绝 span —— 仅提供
service.name不被接受。将其设置为 TracerProvider 上的资源属性(推荐 —— 只需一处设置,应用于所有 span):- Python:
register(project_name="my-app")会自动处理(在资源上设置"openinference.project.name")。若要将 span 路由到不同项目,请使用arize.otel中的set_routing_context(space_id=..., project_name=...)。 - TypeScript: Arize 同时接受
"model_id"(官方 TS 快速入门中展示)和通过@arizeai/openinference-semantic-conventions中的SEMRESATTRS_PROJECT_NAME设置的"openinference.project.name"(手动埋点文档中展示)—— 两者均有效。 - Go: 将
attribute.String("openinference.project.name", "my")传入resource.New(...),并通过sdktrace.WithResource(res)应用。Go SDK 没有相应的辅助方法,因此必须在每个 TracerProvider 上设置。
- Python:
- CLI/脚本类应用 —— 退出前刷新: 必须在进程退出前调用
provider.shutdown()(TS)/provider.force_flush()然后provider.shutdown()(Python)/tp.Shutdown()(Go),否则 OTLP 导出会被丢弃,不会产生任何 trace。 - 当应用存在工具/函数执行时: 手动创建 CHAIN TOOL span(参见下文丰富 trace),以便 trace 树显示每次工具调用及其结果 —— 否则 trace 会显得稀疏(只有 LLM span,缺少工具输入/输出)。
丰富 trace:为工具使用和 Agent 手动创建 span
为什么自动埋点工具不处理这些?
服务商 instrumentor(Anthropic、OpenAI 等)只包装 LLM 客户端 —— 即发送 HTTP 请求和接收响应的代码。 它们只能看到:
- 每次 API 调用对应一个 span:请求(messages、系统提示词、工具)和响应(文本、tool_use 块等)。
它们无法看到响应之后在你的应用内部发生的事情:
- 工具执行 —— 你的代码解析响应,调用
run_tool("check_loan_eligibility", {...}),并获得结果。这运行在你的进程中;instrumentor 无法钩入你的run_tool()或实际的工具输出。下一次 API 调用(将工具结果发回)只是另一个messages.createspan —— instrumentor 不知道消息内容是工具结果,也不知道工具返回了什么。 - Agent/链边界 —— “一个用户轮次 → 多次 LLM 调用 + 工具调用”这一概念是应用层面的概念。instrumentor 只看到一个个独立的 API 调用;它不知道它们属于同一次逻辑上的 “run_agent” 运行。
因此,TOOL 和 CHAIN span 必须手动添加(或由了解工具和链的框架 instrumentor 如 LangChain/LangGraph 添加)。添加后,它们会与 LLM span 出现在同一个 trace 中,因为它们使用同一个 TracerProvider。
为了避免工具输入/输出缺失导致的稀疏 trace:
- 检测 Agent / 工具模式:一个循环,先调用大模型,然后运行一个或多个工具(按名称 + 参数),再用工具结果调用大模型。
- 添加手动 span,使用同一个 TracerProvider(例如在
register()之后调用opentelemetry.trace.get_tracer(...)):- CHAIN span — 包裹整个 Agent 运行过程(例如
run_agent):设置openinference.span.kind="CHAIN",input.value= 用户消息,output.value= 最终回复。 - TOOL span — 包裹每次工具调用:设置
openinference.span.kind="TOOL",input.value= 参数的 JSON,output.value= 结果的 JSON。使用工具名称作为 span 名称(例如check_loan_eligibility)。
- CHAIN span — 包裹整个 Agent 运行过程(例如
OpenInference 属性(使用这些属性,Arize 才能正确显示 span):
| 属性 | 用途 |
|---|---|
openinference.span.kind | 选择正确的值:原始提供商 API 调用(OpenAI、Anthropic 等)使用 "LLM";编排 / Agent 循环边界使用 "CHAIN";工具 / 函数执行使用 "TOOL";向量存储 / 搜索查询使用 "RETRIEVER";嵌入 API 调用使用 "EMBEDDING";嵌套在更大链路中的自主子 Agent 运行使用 "AGENT";重排序 API 调用使用 "RERANKER";护栏 / 策略检查使用 "GUARDRAIL";在线评估调用使用 "EVALUATOR"。 |
input.value | 字符串(例如用户消息或工具参数的 JSON) |
output.value | 字符串(例如最终回复或工具结果的 JSON) |
LLM span 属性(当 span 是实际的 LLM 调用时,除上述三个属性外还需设置这些):
| 属性 | 用途 |
|---|---|
llm.model_name | 模型标识符(例如 "gpt-4o-mini") |
llm.provider / llm.system | 提供商名称(例如 "openai"、"anthropic") |
llm.input_messages.{i}.message.role | 第 i 条输入消息的 "system" / "user" / "assistant" / "tool" |
llm.input_messages.{i}.message.content | 第 i 条输入消息的文本内容 |
llm.output_messages.{i}.message.role | 第 i 条输出消息的角色 |
llm.output_messages.{i}.message.content | 第 i 条输出消息的文本内容 |
llm.token_count.prompt | int — 提示词 / 输入 token 数 |
llm.token_count.completion | int — 补全 / 输出 token 数 |
llm.token_count.total | int — 总 token 数 |
在 Python 和 TypeScript 中,这些名称通过 openinference-semantic-conventions 包暴露;在 Go 中必须手动输入为上述字符串。
Python 模式: 获取全局 tracer(与 Arize 相同的提供商),然后使用上下文管理器,使工具 span 成为 CHAIN span 的子 span,并与 LLM span 出现在同一个 trace 中:
from opentelemetry.trace import get_tracer
tracer = get_tracer("my-app", "1.0.0")
# In your agent entrypoint:
with tracer.start_as_current_span("run_agent") as chain_span:
chain_span.set_attribute("openinference.span.kind", "CHAIN")
chain_span.set_attribute("input.value", user_message)
# ... LLM call ...
for tool_use in tool_uses:
with tracer.start_as_current_span(tool_use["name"]) as tool_span:
tool_span.set_attribute("openinference.span.kind", "TOOL")
tool_span.set_attribute("input.value", json.dumps(tool_use["input"]))
result = run_tool(tool_use["name"], tool_use["input"])
tool_span.set_attribute("output.value", result)
# ... append tool result to messages, call LLM again ...
chain_span.set_attribute("output.value", final_reply)
Go 模式: 从全局 TracerProvider(通过 otel.SetTracerProvider 注册)获取 tracer,然后使用 tracer.Start 嵌套 span,使工具 span 成为 CHAIN span 的子 span。
对短生命周期进程至关重要: span 启动后切勿调用
log.Fatalf/os.Exit—— 它们会跳过延迟执行的tp.Shutdown(ctx),导致进行中的 CHAIN / LLM span 永远不会刷新。请改用log.Printf+ 从mainreturn,并将tp.Shutdown(ctx)延迟到main顶部。
import (
"context"
"encoding/json"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
)
var tracer = otel.Tracer("my-app")
func runAgent(ctx context.Context, userMessage string) string {
ctx, chainSpan := tracer.Start(ctx, "run_agent")
defer chainSpan.End()
chainSpan.SetAttributes(
attribute.String("openinference.span.kind", "CHAIN"),
attribute.String("input.value", userMessage),
)
// ... LLM call ...
for _, toolUse := range toolUses {
ctx, toolSpan := tracer.Start(ctx, toolUse.Name)
argsJSON, err := json.Marshal(toolUse.Input)
if err != nil {
toolSpan.RecordError(err)
}
toolSpan.SetAttributes(
attribute.String("openinference.span.kind", "TOOL"),
attribute.String("input.value", string(argsJSON)),
)
result := runTool(toolUse.Name, toolUse.Input)
toolSpan.SetAttributes(attribute.String("output.value", result))
toolSpan.End()
// ... append tool result to messages, call LLM again ...
}
chainSpan.SetAttributes(attribute.String("output.value", finalReply))
return finalReply
}
有关更多 span 类型和属性,请参阅 手动埋点。
验证
仅当以下所有条件都成立时,才可视为埋点完成:
- 在加入追踪变更后,应用仍能构建或通过类型检查。
- 应用能使用新的追踪配置成功启动。
- 你触发了至少一个应产生 span 的真实请求或运行。
- 你要么在 Arize 中验证了生成的 trace,要么提供了明确的阻塞原因,以区分应用侧成功与 Arize 侧失败。
实现之后:
- 运行应用并触发至少一次 LLM 调用。
- 使用
arize-traceskill 确认 trace 已到达。如果为空,请稍后重试。验证 span 是否具有预期的openinference.span.kind、input.value/output.value以及父子关系。 - 如果没有 trace:验证
ARIZE_SPACE和ARIZE_API_KEY,确保 tracer 在 instrumentor 和客户端之前初始化,检查到otlp.arize.com:443的连通性,并检查应用/运行时 exporter 日志,以便判断 span 是在本地发出但被远程拒绝。调试时可设置GRPC_VERBOSITY=debug或向register()传入log_to_console=True。常见坑点:(a) 缺少项目名称资源属性会导致 HTTP 500 拒绝——仅service.name不够;Python:向register()传入project_name;TypeScript:在资源上设置"model_id"或SEMRESATTRS_PROJECT_NAME;Go:向resource.New(...)添加attribute.String("openinference.project.name", "my-app");(b) 命令行/脚本进程在 OTLP 导出刷写前退出——退出前调用provider.force_flush()然后调用provider.shutdown()(Python/TS)或tp.Shutdown(ctx)(Go);(c) 命令行可见的 space/project 可能与 collector 目标 space ID 不一致——应报告此不一致,而不是静默重写凭据。 - 如果应用使用了工具:确认 CHAIN 和 TOOL span 出现并带有
input.value/output.value,以便工具调用和结果可见。
当验证被命令行或账户问题阻塞时,以明确的状态结尾:
- 应用埋点状态
- 最新的本地 trace ID 或 run ID
- exporter 日志是否显示本地 span 发出
- 失败是凭据、space/project 解析、网络,还是 collector 拒绝
利用追踪助手(MCP)
如需在 IDE 内获得更深入的埋点指导,用户可以启用:
- Arize AX Tracing Assistant MCP —— 埋点指南、框架示例和支持。在 Cursor 中:Settings → MCP → Add 并使用:
"arize-tracing-assistant": { "command": "uvx", "args": ["arize-tracing-assistant@latest"] } - Arize AX Docs MCP —— 可搜索的文档。在 Cursor 中:
"arize-ax-docs": { "url": "https://arize.com/docs/mcp" }
然后用户就可以这样提问:“使用 Arize AX 为这个应用添加埋点”、“你能使用手动埋点让我对自己的 trace 有更多控制吗?”、“如何从我的 span 中脱敏敏感信息?”
完整设置请参见 Agent-Assisted Tracing Setup。
参考链接
| 资源 | URL |
|---|---|
| Agent-Assisted Tracing Setup | https://arize.com/docs/ax/alyx/tracing-assistant |
| Agent Setup Prompt(完整路由 + 阶段) | https://arize.com/docs/PROMPT.md |
| Arize AX Docs | https://arize.com/docs/ax |
| 完整集成列表 | https://arize.com/docs/ax/integrations |
| 文档索引(llms.txt) | https://arize.com/docs/llms.txt |
保存凭据供将来使用
参见 references/ax-profiles.md § 保存凭据供将来使用。