> ## Documentation Index
> Fetch the complete documentation index at: https://docs.veadk.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# APMPlus

`APMPlusExporter` 将 span 数据以 OTLP（gRPC）协议上报至火山引擎 APMPlus 平台。除追踪链路外，它还会通过内置的指标上报器采集模型调用次数、token 用量、操作耗时、异常次数、工具耗时以及技能下载与加载次数等指标，写入 APMPlus 的指标面板。

> [!NOTE]
>
> 启用内容追踪时，模型输出中的推理内容以 `reasoning` 类型标注，与普通文本内容区分，便于在 APMPlus 中单独查看推理过程。

> [!NOTE]
>
> token 用量指标按 `input`、`output` 和 `cache_read` 三个维度分别记录。`cache_read` 表示命中的缓存输入 token 数量，是 `input` 的子集而非额外用量。

> [!NOTE]
>
> 技能下载与加载次数通过 `gen_ai_skill_download_count` 和 `gen_ai_skill_load_count` 两个 OTEL 计数器记录，单位为 `1`。`gen_ai_skill_download_count` 统计技能包下载次数（含缓存命中与失败），维度包括 `skill_source`、`skill_id`、`skill_name`、`skill_version` 和 `skill_space_id`。`gen_ai_skill_load_count` 统计技能指令成功加载次数，维度与下载计数器一致。技能下载过程同时生成 `download_skill {skill_name}` span，标注技能来源、ID、名称、版本、空间、消费者、结果与缓存命中等属性；结果（`success` 或 `error`）仅记录在 Span 上，不作为计数器维度。技能指令加载成功时将既有工具 Span 命名为 `load_skill {skill_name}`，并添加技能来源、ID、名称、版本、空间与消费者属性。

## 何时使用

* 需要在火山引擎 APMPlus 平台上统一观测智能体的调用链路；
* 需要模型级别的指标分析，如 token 消耗、调用延迟与错误率；
* 生产环境中需要成本追踪与性能监控。

## 接入前准备

先完成[安装](https://docs.veadk.xyz/productions/veadk/preview/zh/get-started/installation.md)和[模型配置](https://docs.veadk.xyz/productions/veadk/preview/zh/components/agent/model.md)，再设置以下环境变量。占位符需要替换为有权限访问的实际资源和凭证；在启动 Python 前完成配置

> [!WARNING]
>
> APMPlus 会接收链路与指标数据。建议显式设置 App Key；省略时会使用云凭证调用平台接口获取令牌。当前 gRPC 上报连接未加密，应在符合部署要求的网络中使用

```bash lines theme={null}
export OBSERVABILITY_OPENTELEMETRY_APMPLUS_ENDPOINT="http://apmplus-cn-beijing.volces.com:4317"
export OBSERVABILITY_OPENTELEMETRY_APMPLUS_API_KEY="your-apmplus-app-key"
export OBSERVABILITY_OPENTELEMETRY_APMPLUS_SERVICE_NAME="apmplus_veadk_demo"
```

## 使用示例

保存为 `app.py`，运行 `python app.py`。示例复用已有资源，完成一次模型调用后刷新待导出的链路数据

```python title="app.py" lines theme={null}
import asyncio

from veadk import Agent, Runner
from veadk.tracing.telemetry.exporters.apmplus_exporter import APMPlusExporter
from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer

tracer = OpentelemetryTracer(exporters=[APMPlusExporter()])
agent = Agent(name="trace_demo", tracers=[tracer])
runner = Runner(agent=agent, app_name="trace_demo", user_id="demo-user")
response = asyncio.run(
    runner.run("用一句话解释智能体的用途", session_id="demo-session")
)
print(response)
tracer.force_export()
print("Trace ID:", tracer.trace_id)
```

也可以通过 `APMPlusExporterConfig` 显式传入连接参数：

```python lines theme={null}
import os

from veadk.tracing.telemetry.exporters.apmplus_exporter import (
    APMPlusExporter,
    APMPlusExporterConfig,
)

exporter = APMPlusExporter(
    config=APMPlusExporterConfig(
        endpoint="http://apmplus-cn-beijing.volces.com:4317",
        app_key=os.environ["OBSERVABILITY_OPENTELEMETRY_APMPLUS_API_KEY"],
        service_name="apmplus_veadk_demo",
    )
)
```

## 参数

### 构造参数

`APMPlusExporter` 的连接参数由 `config` 字段承载，类型为 `APMPlusExporterConfig`；不传时各字段自动从对应环境变量读取。

| 参数 | 类型 | 默认值 | 说明 |
| :- | :- | :- | :- |
| `config` | `APMPlusExporterConfig` | 自动从环境变量读取 | APMPlus 连接与认证配置。 |
| `resource_attributes` | `dict` | `{}` | 附加到 span 的资源属性；导出器会自动并入 `service.name`。 |
| `headers` | `dict` | `{}` | 附加的请求头；导出器会自动并入认证头 `x-byteapm-appkey`。 |

### APMPlus 连接配置

`config` 为 `APMPlusExporterConfig`，各字段默认从 `APMPlusConfig` 读取，环境变量如下：

| 配置项 | 环境变量 | 类型 | 默认值 | 说明 |
| :- | :- | :- | :- | :- |
| `endpoint` | `OBSERVABILITY_OPENTELEMETRY_APMPLUS_ENDPOINT` | `str` | 根据云服务商与地域自动生成 | APMPlus OTLP 接入点（gRPC），格式为 `http://apmplus-{region}.volces.com:4317`。 |
| `app_key` | `OBSERVABILITY_OPENTELEMETRY_APMPLUS_API_KEY`、`TENANT_APMPLUS_APPKEY` | `str` | 未设置时自动获取 APMPlus 令牌 | 应用程序密钥，用于认证。依次读取 `OBSERVABILITY_OPENTELEMETRY_APMPLUS_API_KEY` 与 `TENANT_APMPLUS_APPKEY`，均未设置时根据云凭证自动获取 APMPlus 令牌。 |
| `service_name` | `OBSERVABILITY_OPENTELEMETRY_APMPLUS_SERVICE_NAME` | `str` | `veadk_tracing` | 服务名，显示在 APMPlus 控制台，用于标识来源。 |

> [!NOTE]
>
> AppKey 按以下优先级解析：先读取非空的 `OBSERVABILITY_OPENTELEMETRY_APMPLUS_API_KEY`，再读取非空的 `TENANT_APMPLUS_APPKEY`，两者均未设置时根据云服务商自动获取 APMPlus 令牌（火山引擎模式使用 `open.volcengineapi.com`，BytePlus 模式使用 `open.byteplusapi.com`，因此需要配置对应云服务商的有效凭证：火山引擎使用 `VOLCENGINE_ACCESS_KEY` / `VOLCENGINE_SECRET_KEY`，BytePlus 使用 `BYTEPLUS_ACCESS_KEY` / `BYTEPLUS_SECRET_KEY`；使用临时凭证时还需提供对应的 Session Token）。解析为懒加载，成功取到的值会在每个 `APMPlusConfig` 实例上缓存；解析失败不会缓存，也不会返回空 Key，而是抛出脱敏后的错误。`endpoint` 使用 gRPC 协议、以非加密方式连接。

> [!NOTE]
>
> `endpoint` 的默认值根据云服务商与地域动态生成。火山引擎模式下，地域依次取自 `REGION` 环境变量与默认值 `cn-beijing`；BytePlus 模式下，地域依次取自 `BYTEPLUS_REGION` 环境变量与默认值 `ap-southeast-1`。云服务商由 `AGENTKIT_CLOUD_PROVIDER` 或 `CLOUD_PROVIDER` 环境变量决定，默认为火山引擎。

也可以让 `Agent` 依据环境变量自动挂载 APMPlus 导出器，无需显式构造：

```bash lines theme={null}
export ENABLE_APMPLUS=true
```

> [!TIP]
>
> 设置 `ENABLE_APMPLUS=true` 后，即便智能体未显式提供 `tracers`，`Agent` 也会自动创建 `OpentelemetryTracer` 并挂载 `APMPlusExporter`。

> [!NOTE]
>
> 如果初始化 `OpentelemetryTracer` 时已存在全局 `TracerProvider`，VeADK 将复用该 provider，并跳过 `APMPlusExporter` 的链路注册。导出器对象仍在列表中；已有 provider 不一定配置了 APMPlus，需要自行确认上报目标。可通过 `apmplus_managed_externally` 属性确认此状态，详见[可观测概述](https://docs.veadk.xyz/productions/veadk/preview/zh/components/observability.md)。

> [!NOTE]
>
> 全局 `MeterProvider` 已由应用配置时，VeADK 会直接复用，不会将其指标导出目标自动改为 APMPlus。需在已有 provider 中配置指标上报；链路与指标使用各自的 provider，两者应分别核对

## 验证与排查

运行后在目标平台按本次 Trace ID 查询。模型回复成功只说明智能体完成了调用，不代表链路上传成功；找不到数据时依次检查端点和地域、凭证权限、目标资源以及进程退出前是否调用 `tracer.force_export()`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.