更新时间:2026-06-12 GMT+08:00
分享

Metric数据上报

Metric 数据用于统计聚合信息,如请求次数、Token消耗量、成功率等。

下面以Python语言开发的智能体为例,介绍如何将Metric数据上报至AgentArts观测平台。

第三方智能体上报的Metric指标数据将写入您的华为云应用运维管理AOM服务。AOM会根据指标上报的数量按需计费。在生产环境部署前,请仔细阅读AOM计费说明

安装依赖库

安装OpenTelemetry Python SDK及相关依赖库。要求Python 3.9或以上版本。

pip install opentelemetry-distro==0.62b1
pip install opentelemetry-api==1.41.1
pip install opentelemetry-exporter-otlp==1.41.1
pip install traceloop-sdk==0.60.0

获取上报参数

  1. 在AgentArts平台左侧导航栏中选择“运营运维 > 观测”,并进入“智能体列表”页面。
  2. 单击“智能体接入”,填写智能体名称,并选择类型。类型按实际选择。

    图1 智能体接入

  3. 填写完成后,单击“创建”等待平台自动创建接入信息,记录接入地址、鉴权信息、智能体ID等信息。请妥善保管该信息。

    表1 接入信息说明

    参数

    说明

    agent_id

    智能体ID。

    metric_endpoint

    Metric数据接入地址。

    metric_token

    Metric上报鉴权Token。

    project_id

    华为云项目ID,报Metric数据时使用。在AgentArts页面获取。

    promID

    上报Metric数据时使用。在AgentArts页面获取。

    图2 获取接入地址、鉴权信息、智能体ID等信息

上报Metric数据

配置参数信息:

在上报Metric数据前,需配置环境变量。服务名称(OTEL_SERVICE_NAME)必须遵循AgentArts.{{智能体ID}}.{{版本号}} 的格式(版本号默认填写default)。

OTEL_EXPORTER_OTLP_METRICS_HEADERS=Authorization=Bearer {metric_token},projectID={project_id},promID={prom_id},Content-Type=application/x-protobuf
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT={metric_endpoint}
OTEL_EXPORTER_OTLP_METRICS_INSECURE=true

上报Metric数据示例代码:

本示例用于首次接入平台时,验证上报网络、鉴权和配置是否正确。此阶段使用手动构造的静态数据。

示例中gen_ai.domain.id、gen_ai.user.id的取值请按实际进行替换,请登录“我的凭证 > API凭证”页面获取。

图3 获取domain id、user id
import os
import time
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry import metrics

# 1. 替换为您的真实接入凭证
AGENT_ID = "您的智能体ID"
METRIC_ENDPOINT = "您的Metric接入地址"
METRIC_TOKEN = "您的Metric鉴权Token"
PROJECT_ID = "您的ProjectID"
PROM_ID = "您的PromID"

# 2. 配置 OTel Metric 环境变量 (注意 Headers 格式与 Trace 不同)
os.environ["OTEL_SERVICE_NAME"] = f"AgentArts.{AGENT_ID}.default"
os.environ["OTEL_EXPORTER_OTLP_METRICS_HEADERS"] = f"Authorization={METRIC_TOKEN},projectID={PROJECT_ID},promID={PROM_ID},Content-Type=application/x-protobuf"
os.environ["OTEL_EXPORTER_OTLP_METRICS_ENDPOINT"] = METRIC_ENDPOINT
os.environ["OTEL_EXPORTER_OTLP_METRICS_INSECURE"] = "true"

# 3. 初始化 Metric Provider,设置上报周期为 60000 毫秒(60秒)
metric_reader = PeriodicExportingMetricReader(
    OTLPMetricExporter(),
    export_interval_millis=60000
)
meter_provider = MeterProvider(metric_readers=[metric_reader])
metrics.set_meter_provider(meter_provider)

def report_metrics():
    meter = metrics.get_meter(__name__)

    # 定义一个计数器 (Counter),用于统计模型请求总数
    request_counter = meter.create_counter(
        name="gen_ai.total.requests",
        unit="1",
        description="Number of requests to GenAI",
    )

    # 定义指标的关联维度 (Attributes)
    # 【注意】gen_ai.resource.id 必须与平台生成的智能体 ID 严格一致,注意替换gen_ai.domain.id、gen_ai.user.id的值
    attributes = {
        "gen_ai.resource.id": AGENT_ID,
        "gen_ai.resource.type": "agent",
        "gen_ai.model.id": "deepseek-v4-pro",
        "gen_ai.session.id": "session-001",
        "gen_ai.domain.id": "your_domain_id",
        "gen_ai.project.id": PROJECT_ID,
        "gen_ai.user.id": "your_user_id",
        "gen_ai.call.status": True,
        "gen_ai.space.id": "default"
    }

    # 业务发生时,计数器累加 1
    request_counter.add(1, attributes=attributes)

if __name__ == "__main__":
    print(f"==================================================")
    print(f" 智能体持续指标上报测试已启动!")
    print(f" 我们将持续运行 3 分钟,每 10 秒模拟一次调用。")
    print(f" 请保持此窗口运行,2分钟后刷新 AgentArts 观测控制台。")
    print(f"==================================================")

    # 模拟持续运行 3 分钟 (180 秒),每 10 秒调用一次
    total_duration = 180
    interval = 10
    elapsed = 0

    while elapsed < total_duration:
        print(f"[{time.strftime('%H:%M:%S')}] 正在模拟第 {int(elapsed/interval) + 1} 次智能体业务调用...")
        report_metrics()

        time.sleep(interval)
        elapsed += interval

    # 测试结束,优雅关闭并强刷最后一批数据
    meter_provider.shutdown()
    print("==================================================")
    print(" 持续测试结束,指标数据已成功全部推送")
    print("==================================================")

为了保证您上报的Metric指标能够被 AgentArts 看板正确识别。您在代码中创建Meter时,指标名及关联的维度属性(Attributes)必须与平台标准严格对齐。关于所有可设置的Attribute字段及含义,请参考OpenTelemetry字段映射

表2 核心指标说明

指标名称

类型

说明

gen_ai.total.requests

Counter

用于统计智能体/大模型的累计调用总次数(每次成功/失败自增 1)。

gen_ai.usage.input_tokens

Counter

用于累计输入Token的总消耗,支撑平台“Token分析”中的Input消耗趋势图。

gen_ai.usage.output_tokens

Counter

用于累计输出Token的总生成量,支撑平台“Token分析”中的Output消耗趋势图。

表3 Attribute说明

Attribute

是非必填

说明

gen_ai.resource.id

智能体 ID(agent_id)。直接作为字符串写入。

gen_ai.resource.type

资源类型标识,默认写入 "agent"。

gen_ai.model.id

调用的模型名称(如 "deepseek-v4-pro")。

gen_ai.project.id

华为云的项目 ID(project_id),直接填入变量。

gen_ai.call.status

标识单次调用成功与否(True / False)。平台以此自动计算响应成功率趋势。

查看上报数据

上述示例代码中,定义了gen_ai.total.requests用于统计模型的请求总数。运行脚本后将触发模拟调用,调用完成后。在“运营运维 > 观测 > 智能体列表”页面,单击对应的智能体名称。可看到与模拟调用量相同的模型调用次数。

图4 查看上报数据

示例:真实对话中的Metric(指标)数据上报

本示例中的脚本创建了一个常驻的智能体服务。在对话的过程中,每次调用完大模型后,代码会自动把真实的Token数量累加到计数器中,并且保持后台进程运行,每隔60秒自动把指标打包上报到AgentArts服务中。

本地环境准备与依赖安装:

请在你的电脑终端(Windows的CMD或macOS/Linux 的Terminal)中执行以下命令,安装所需的Python依赖库:

pip install opentelemetry-api==1.41.1
pip install opentelemetry-sdk==1.41.1
pip install opentelemetry-exporter-otlp==1.41.1
pip install openai==1.14.0
pip install python-dotenv==1.0.0

配置环境变量:

安装完成后,在您的代码文件夹下创建一个名为.env的文本文件。填写华为云MaaS服务的模型API Key和AgentArts平台上获取的真实凭证:

# ==========================================
# 1. 智能体大模型的 API 凭证(以接入 MaaS 的 OpenAI 兼容接口为例)
# ==========================================
MODEL_NAME=deepseek-v4-pro
MODEL_URL=https://api.modelarts-maas.com/openai/v1
MODEL_API_KEY=换成你在MaaS上申请的模型API_Key

# ==========================================
# 2. 华为云 AgentArts 观测接入凭证
# ==========================================
AGENT_ID=换成智能体ID
DOMAIN_ID=换成华为云账号ID(在控制台右上角“我的凭证”中复制,不要填假数据,否则会被平台隔离过滤)
USER_ID=换成华为云IAM用户ID(在控制台右上角“我的凭证”中复制,不要填假数据,否则会被平台隔离过滤)

# Metric 上报通道配置
METRIC_ENDPOINT=换成Metric数据接入地址(格式如 aom-access.cn-southwest-2.myhuaweicloud.com)
METRIC_TOKEN=Metric上报鉴权Token
PROJECT_ID=换成华为云项目ID
PROM_ID=换成promID
表4 环境变量说明

参数

说明

MODEL_NAME

华为云MaaS服务的模型名称。取值为OpenAI兼容接口中的model参数。

图5 模型名称

MODEL_URL

华为云MaaS服务的模型URL,采用OpenAI兼容接口。取值为:https://api.modelarts-maas.com/openai/v1。

MODEL_API_KEY

华为云MaaS服务的模型API Key,请登录MaaS服务获取。

图6 模型API Key

AGENT_ID

METRIC_ENDPOINT

METRIC_TOKEN

PROJECT_ID

PROM_ID

智能体ID、Metric数据接入地址、Metric上报鉴权Token、华为云项目ID、promID,从接入指南中获取。

图7 获取接入地址、鉴权信息、智能体ID等信息

DOMAIN_ID

USER_ID

华为云账号ID、华为云IAM用户ID,

请登录“我的凭证 > API凭证”页面获取。

图8 获取domain id、user id

编写智能体调用及数据上报脚本:

创建一个名为agent_metric.py的代码文件,并填写如下内容:

import os
import time
import uuid
from openai import OpenAI
from dotenv import load_dotenv
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry import metrics

# 自动加载同目录下的 .env 文件
load_dotenv()

# 读取配置参数
AGENT_ID = os.getenv("AGENT_ID")
METRIC_ENDPOINT = os.getenv("METRIC_ENDPOINT")
METRIC_TOKEN = os.getenv("METRIC_TOKEN")
PROJECT_ID = os.getenv("PROJECT_ID")
PROM_ID = os.getenv("PROM_ID")
DOMAIN_ID = os.getenv("DOMAIN_ID")
USER_ID = os.getenv("USER_ID")

# 配置标准 OTel Metric 环境变量 (Headers 中注意 projectID 和 promID 区分大小写)
os.environ["OTEL_SERVICE_NAME"] = f"AgentArts.{AGENT_ID}.default"
os.environ["OTEL_EXPORTER_OTLP_METRICS_HEADERS"] = f"Authorization={METRIC_TOKEN},projectID={PROJECT_ID},promID={PROM_ID},Content-Type=application/x-protobuf"
os.environ["OTEL_EXPORTER_OTLP_METRICS_ENDPOINT"] = METRIC_ENDPOINT
os.environ["OTEL_EXPORTER_OTLP_METRICS_INSECURE"] = "true"

# 初始化 OTel Metric 基础服务
metric_reader = PeriodicExportingMetricReader(OTLPMetricExporter(), export_interval_millis=60000)
meter_provider = MeterProvider(metric_readers=[metric_reader])
metrics.set_meter_provider(meter_provider)
meter = metrics.get_meter(__name__)

# ==============================================================================
# 注册标准业务指标项(需要是全局唯一单例,禁止在循环调用中重复注册!)
# ==============================================================================
request_counter = meter.create_counter(
    name="gen_ai.total.requests", unit="1", description="大模型调用次数统计"
)
input_tokens_counter = meter.create_counter(
    name="gen_ai.usage.input_tokens", unit="1", description="输入Token消耗统计"
)
output_tokens_counter = meter.create_counter(
    name="gen_ai.usage.output_tokens", unit="1", description="输出Token消耗统计"
)


def call_llm_and_report_metrics(user_query: str, session_id: str):
    client = OpenAI(
        api_key=os.getenv("MODEL_API_KEY"),
        base_url=os.getenv("MODEL_URL")
    )

    # 动态装配指标维度属性(Attributes)
    # 【注意】gen_ai.resource.id 必须与平台生成的智能体 ID 严格一致
    attributes = {
        "gen_ai.resource.id": AGENT_ID,
        "gen_ai.resource.type": "agent",
        "gen_ai.model.id": os.getenv("MODEL_NAME"),
        "gen_ai.session.id": session_id,
        "gen_ai.domain.id": DOMAIN_ID,
        "gen_ai.user.id": USER_ID,
        "gen_ai.project.id": PROJECT_ID,
        "gen_ai.call.status": True,
        "gen_ai.space.id": "default"
    }

    try:
        # 发起真实的对话调用并计时
        start_time = time.time()
        completion = client.chat.completions.create(
            model=os.getenv("MODEL_NAME"),
            messages=[{"role": "user", "content": user_query}]
        )
        duration = time.time() - start_time

        # 动态捕捉响应体中的真实 Token 消耗
        usage = completion.usage
        response_content = completion.choices[0].message.content

        # ======================================================================
        # 动态数据累加上报
        # ======================================================================
        # 作用说明:调用成功,大模型累计调用次数自增 1
        request_counter.add(1, attributes=attributes)

        # 作用说明:将本次对话真实消耗的输入 Token 数量累加到计数器中
        input_tokens_counter.add(usage.prompt_tokens, attributes=attributes)

        # 作用说明:将本次对话真实消耗的输出 Token 数量累加到计数器中
        output_tokens_counter.add(usage.completion_tokens, attributes=attributes)

        print(f"[{time.strftime('%H:%M:%S')}] Metrics calculated. Duration: {duration:.2f}s, Input Token: {usage.prompt_tokens}, Output Token: {usage.completion_tokens}")
        return response_content

    except Exception as e:
        # 调用发生异常,状态置为 False 并上报 1 次请求,以便看板统计成功率趋势
        error_attributes = attributes.copy()
        error_attributes["gen_ai.call.status"] = False
        request_counter.add(1, attributes=error_attributes)
        raise e


if __name__ == "__main__":
    current_session_id = f"sess-{uuid.uuid4().hex[:12]}"
    print(f"==================================================")
    print(f" Metrics Monitor Agent Started! Session ID: {current_session_id}")
    print(f" Notice: Metrics will be batch-sent every 60s in the background.")
    print(f" Please chat for 3+ minutes to generate solid graph curves.")
    print(f"==================================================")

    while True:
        user_input = input("\nUser: ")
        if user_input.strip().lower() in ["exit", "quit", "q"]:
            print("Forcing immediate metrics upload and exiting...")
            break

        try:
            reply = call_llm_and_report_metrics(user_input, current_session_id)
            print(f"Agent: {reply}")
        except Exception as err:
            print(f"Error occurred: {err}")

    # 将最后一批残留数据推送至平台
    meter_provider.shutdown()
    print("Metrics report completed!")

执行测试,验证上报数据:

在您的代码文件夹下,打开终端并运行:

python agent_metric.py

运行后,可与智能体进行会话,可通过Ctrl+C命令退出会话。退出后,登录AgentArts平台,在“运营运维 > 观测 > 智能体列表”页面,单击对应的智能体名称。在“概览”中可以看到模型调用数据。

图9 运行示例
图10 数据上报示例

常见问题

运行上报脚本时,出现Failed to export metrics... error code: StatusCode.UNAUTHENTICATED鉴权失败报错

检查脚本的请求参数是否填写正确,检查metric_token、project_id、prom_id、Content-Type=application/x-protobuf的值是否有拼写错误。尤其检查Authorization的值中是否填写了重复的Bearer 前缀。

脚本执行成功没有报错,但在AgentArts中却看不到任何数据和折线图

  • 原因一:

    原因分析:在您的指标属性中,“gen_ai.domain.id”如果填了“your_domain_id”这样的静态假数据,看板在采用您当前华为云真实账号进行查询时,会因为安全机制直接将非本租户的“数据”过滤掉。解决方案:gen_ai.domain.id、gen_ai.user.id需要按照您的真实信息填写。

  • 原因二:
  • 原因分析:

    原因分析:AOM底层计算QPS或请求量趋势图时,使用的是速率函数。这些函数在数学上必须在时间轴上至少有2个以上不同时间点的数据才能计算出斜率。如果您只执行了一次脚本并立即shutdown(),时序库里只有一个孤立的点,无法形成折线,在图表上就会显示空数据。解决方案:将代码改造成循环上报模式(例如在本地每10秒自动add 1次,持续运行3分钟以上),让数据形成连续的时序流。

  • 原因三:

    原因分析:您在代码中上报的指标与在AgentArts中看的页面不是同一个。例如代码中上报的是gen_ai.total.requests,该指标对应的是“大模型调用次数”,如果找错了看板位置,则看不到数据。

    解决方案:根据上报的具体指标查看平台看板。

相关文档