# Pi框架
观测功能支持对Pi框架（pi-agent-core / pi-coding-agent）开发的智能体进行可观测。Python探针是华为云AgentArts产品自研的Python语言的可观测采集探针，其基于 OpenTelemetry 标准实现了数据采集与上报能力。
本文介绍如何将Pi框架应用接入AgentArts的观测功能，以帮助用户实时了解AI应用运行状态。
**相关概念**
- Node进程：Pi框架应用本身是一个Node.js应用，运行在Node进程中。所谓"Node进程"，就是指用node或 npx tsx 启动的那个应用进程。
- Python进程：一个独立的Python程序，负责读取Node进程产生的事件文件，并把数据上报到华为云。它与Node进程互不干扰。
- TS探针：一段TypeScript代码，随Node进程一起启动，负责在Pi应用运行时把Agent、LLM、工具调用等事件写成JSONL文件。探针是指它像一根探针插到应用里，观察应用的运行状态，但不改变应用的行为。
- Python采集器（pi_collector）：一个Python程序，负责读取TS探针写出的JSONL文件，把零散的事件整理成完整的调用链（Trace）和指标（Metrics），再上传到华为云中。
Pi框架的可观测采用"Node 采集 + Python 上报"的跨进程架构：
- Node侧（TS探针）：运行在Pi应用进程内，负责采集Agent、LLM、Tool等执行事件，并把事件写成 JSONL 文件。
- Python侧（pi_collector）：作为独立进程运行，旁路读取JSONL事件文件，重建OpenTelemetry Span调用链，并通过OTLP上报到华为云AgentArts。
您可以理解为Pi应用负责"产生事件"，TS探针负责"记录事件到文件"，Python采集器负责"读文件、整理成调用链、上传到AgentArts。"
把TS探针挂载到Pi应用上有三种方式，后续步骤中会分别介绍：
- preload自动接入：在启动Pi应用时，通过Node的启动参数提前加载探针。应用代码完全不用改。
- 显式插桩：在应用代码里手动调用一次探针提供的函数，把Agent实例交给探针。需要改少量代码。
- Extension Hook：把探针作为Pi Coding Agent的一个扩展插件注册进去，由Pi框架自己调用。需要改配置文件。
安装Python探针wheel后，TypeScript探针的编译产物dist/src/\*.js已随包发布，无需单独执行npm安装或tsc编译。
#### 前提条件
- Python 环境版本 \>= 3.9
- Node.js 版本 \>= 20.6（TS探针在启动时使用了一个较新的顶层await语法，该语法要求Node.js 20.6或更高版本。）
- Pi 框架（pi-agent-core或pi-coding-agent）已配置开启事件输出，事件schema版本为1.0。
- TS探针运行在Pi应用进程内但不修改业务代码。Python采集器是一个独立进程，需要和Pi应用共享同一个文件系统，并且能读写事件输出目录。默认目录是.pi/events。
- 采集器用一个checkpoint文件记录读取进度，支持断点续传，程重启后不会重复上报已经读过的内容。AOM后端只接受Gauge类型指标，Gauge表示某个时间点的瞬时值，采集器已经统一按这个类型上报。
- 不要在同一个Pi应用进程里同时启用pi_agent_core和pi_coding_agent两套TS探针，否则会产生重复事件。auto模式下，Coding Extension会自动让Core探针停止写入。
建议先启动Python采集器，再启动Pi应用，这样事件一产生就能被及时处理。
![](https://support.huaweicloud.com/ops-agentarts/public_sys-resources/note_3.0-zh-cn.png)
- 在AgentArts观测界面查看数据不收费。
- 但数据上报会产生费用：
  - 调用链上报到APM（应用性能管理服务），费用明细请参考[APM计费说明](https://support.huaweicloud.com/price-apm2/apm_07_0019.html)。
  
  - 指标上报到AOM（应用运维管理服务），费用明细请参考[AOM计费说明](https://support.huaweicloud.com/price-aom2/aom_07_0004.html)。
   

- AOM和APM都是按需计费，并有一定量的免费额度，超出后按实际使用量收费。
 
#### 框架介绍
Pi框架是智能体开发框架，包含pi-agent-core与pi-coding-agent两种实现，提供了Agent编排、多轮对话（turn）、执行步骤（step）、大模型调用（LLM）、工具调用（Tool）等能力，并支持会话（session）级别的状态管理。Pi框架在运行时会将其内部执行过程以结构化事件的形式写入JSONL文件，供下游采集器消费。
pi_collector是Python探针提供的旁路采集组件。所谓"旁路"，是指它不参与Pi应用的业务逻辑，只是在一旁读取事件文件。它通过tail方式持续读取Pi框架输出的事件文件，依据事件的operation_id与parent_operation_id重建出完整的OpenTelemetrySpan调用链，并生成GenAI标准指标上报。
接入后，以下能力将被自动监控：
- Agent执行链路（agent/turn/step的层级关系及各节点耗时）。
- LLM调用（模型名称、Token用量、输入/输出内容、首Token耗时TTFT）。
- 工具调用（Tool name、参数、返回结果、调用耗时）。
- 会话生命周期（session.start/session.end）。
- 错误事件（error事件及is_error标记）。
 
#### 接入步骤
#### 接入探针
1. 安装探针。 
   下载[Pi探针](https://obs-apm2-cn-southwest-2.obs.cn-southwest-2.myhuaweicloud.com/PYTHON/version.26.9.7/huaweicloud_opentelemetry_instrumentation_pi-1.0.0-py3-none-any.whl)，探针下载到本地项目后执行安装。
   ```
   pip install huaweicloud_opentelemetry_instrumentation_pi-1.0.0-py3-none-any.whl --force-reinstall
   ```
   安装 OpenTelemetry 依赖包（版本要求与探针 pyproject.toml 声明一致）。
   ```
   pip install "opentelemetry-api>=1.39.1"
   pip install "opentelemetry-sdk>=1.39.1"
   pip install "opentelemetry-exporter-otlp>=1.39.1"
   pip install "opentelemetry-exporter-otlp-proto-grpc>=1.39.1"
   pip install "opentelemetry-semantic-conventions==0.60b1"
   ```
   wheel包内已附带编译好的TypeScript探针产物，位于opentelemetry/instrumentation/pi_node/目录下，无需额外执行npm install安装或tsc编译。
   
   
2. 配置环境变量。 
   您需要手动为Python应用添加以下环境变量，环境变量的具体值可以在平台中获取：
   环境变量同时作用于TS探针（Node进程）与Python采集器（Python进程）。建议在启动两个进程之前，先在同一个终端中统一设置。
   ```
   # === 采集模式与共享目录（TS 探针 + 采集器共用）===
   # TS 探针模式：auto / core / coding / off
   #   方式一（preload 接入 pi-agent-core）：core
   #   方式二（显式插桩 pi-agent-core）：core
   #   方式三（Extension 接入 pi-coding-agent）：coding
   #   不确定时可用 auto，探针会自动判断
   export PI_INSTRUMENTATION_MODE=auto                  # TS 探针模式：auto / core / coding / off
   export PI_JSONL_DIR=/var/lib/pi/events               # JSONL 事件输出目录（TS 探针写入，Python 采集器读取）
   export PI_CHECKPOINT=/var/lib/pi/collector-checkpoint.json  # 采集器断点续传文件路径，防止重复上报
   export PI_EXPORTER=otlp                              # 采集器上报后端：console（仅打印到屏幕，调试用）/ otlp（上报到云上）
   export PI_DEBUG=false                                # 是否输出探针内部错误日志
   # === 鉴权与上报地址（采集器上报使用）===
   export agentarts_agentops_otel_agent_apm_enable=true  # 启用 APM Trace，默认 false
   export agentarts_agentops_otel_agent_aom_enable=true  # 启用 AOM Metrics，默认 false
   # 智能体信息配置
   export agent_domain_id=<your-domain-id>          # 账号 domain ID
   export agentarts_project_id=<your-project-id>    # 账号 Project ID
   export agent_resource_id=<your-resource-id>      # 智能体 ID
   export resource_type=agent                       # 智能体类型：agent / multiagents / workflow
   # APM 配置（探针自动转换为标准 OTLP headers/endpoint，无需手动设置 OTEL_EXPORTER_OTLP_*）
   export agentarts_agentops_apm_token=<your-apm-token>             # APM 接入凭证 Token
   export agentarts_agentops_apm_exporter_endpoint=<apm-endpoint>   # APM 数据上报地址
   # AOM 配置（同上，探针自动转换）
   export agentarts_agentops_aom_access_code=<your-aom-access-code>  # AOM 接入凭证
   export agentarts_agentops_aom_exporter_endpoint=<aom-endpoint>    # AOM 数据上报地址
   export agentarts_agentops_aom_prometheus_id=<your-prometheus-id>  # Prometheus 实例 ID
   export OTEL_SERVICE_NAME=pi-collector
   ```
   上面这些agentarts_agentops_\*变量，探针会在启动时自动转换成 OpenTelemetry 标准的环境变量，比如：
   - OTEL_EXPORTER_OTLP_TRACES_HEADERS
   
   - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
   
   - OTEL_EXPORTER_OTLP_METRICS_HEADERS
   
   - OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
   
   
   pi_collector内部会读取这些标准变量来完成上报。因此您不需要手动设置OTEL_EXPORTER_OTLP_\*变量。
   环境变量的具体值可以在AgentArts平台中找到。
   图1获取环境变量信息   
   ![](https://support.huaweicloud.com/ops-agentarts/zh-cn_image_0000002803349533.png "点击放大")
   
   
3. 启动Python采集器。 
   TS探针写入JSONL后，需要运行pi_collector读取事件并上报。建议先启动采集器，再启动Pi应用。
   - **方式一：CLI 命令行启动（推荐）**
     使用 huaweicloud-instrument 命令启动。该命令是探针安装后提供的，作用是：先把 agentarts_agentops_\* 鉴权变量转换成标准OTLP配置，然后执行后面的采集器程序。命令如下：
     ```
     huaweicloud-instrument python -m opentelemetry.instrumentation.pi_collector --exporter otlp
     ```
     若已通过包安装注册了顶层sitecustomize.py，也可直接使用python -m opentelemetry.instrumentation.pi_collector --exporter otlp命令启动；命令结尾如果改为--exporter console，则表示调试模式无需鉴权，可直接用python -m启动。
     采集器支持的常用启动参数：
     表1启动参数说明 
     | 参数              | 说明                                 | 默认值                                        |
     |:---|:---|:---|
     | --input-dir   | Pi事件输出目录，采集器从这里读取JSONL文件           | PI_JSONL_DIR或.pi/events                    |
     | --checkpoint    | 断点续传文件路径，记录上次读取位置                   | PI_CHECKPOINT或.pi/collector-checkpoint.json |
     | --poll-interval | 轮询事件文件的间隔（秒）                       | 0.25                                         |
     | --exporter      | 上报后端：console（只打印，不上传）/ otlp（上传到云上） | PI_EXPORTER或console                       |
     | --once         | 只扫描一次事件目录，处理完已有事件后退出。用于调试，不常驻运行     | 否                                            |
     | --log-level    | 日志级别                               | PI_LOG_LEVEL或INFO                          |
        
     关于--once参数：默认情况下，采集器启动后会一直运行，每隔--poll-interval秒扫描一次事件目录，持续处理新产生的事件。加上--once后，采集器只扫描一次，处理完当前已有的所有事件后就退出，不会驻留。它主要用于调试，比如想快速确认"当前事件文件能不能被正确解析"时使用，不适合长期运行。
     单次扫描调试示例，该命令只扫描一次事件目录，把解析结果打印到屏幕（console模式），不向云上上报，不需要鉴权。
     ```
     python -m opentelemetry.instrumentation.pi_collector --once --exporter console
     ```
     
   
   - **方式二：Python 代码内嵌启动**
     方式一是把采集器作为独立进程运行。采集器是一个Python进程，Pi应用是一个Node进程，两个进程各跑各的。方式二则是把采集器嵌入到您自己的Python程序里运行，与Python程序共用一个Python进程。
     这种方式适合您已经在用Python写一些周边逻辑（比如批量处理、自动化脚本），不想再额外管理一个采集器进程的场景。注意：Pi应用本身仍然是Node进程，TS探针也仍在Node进程内，方式二只是把"读取JSONL并上报"这一步放到了您自己的Python进程里。
     ```
     from pathlib import Path
     from opentelemetry.instrumentation.pi_collector import PiCollector
     from opentelemetry.instrumentation.pi_collector.runtime import create_otel_runtime
     # 创建 OTel Runtime，使用 OTLP 上报（读取 OTEL_EXPORTER_OTLP_* 环境变量）
     runtime = create_otel_runtime("otlp")
     # 构建 PiCollector，读取 Pi 框架输出的事件文件
     collector = PiCollector(
         input_dir=Path("/var/lib/pi/events"),
         checkpoint_path=Path("/var/lib/pi/collector-checkpoint.json"),
         tracer=runtime.tracer,
         meter=runtime.meter,
         poll_interval=0.25,
     )
     try:
         # 持续轮询事件文件，转换为 OTel Span 与 Metrics 上报
         collector.run_forever()
     except KeyboardInterrupt:
         pass
     finally:
         collector.shutdown()
         runtime.shutdown()
     ```
     启动采集器进程：
     ```
     # OTLP 模式需通过 huaweicloud-instrument 启动，用以加载 sitecustomize 完成鉴权转换
     huaweicloud-instrument python collector_app.py
     ```
     如果仅用--exporter console调试，可以直接使用：
     ```
     python collector_app.py
     ```
     采集器启动后，会持续读取PI_JSONL_DIR目录下的JSONL事件。如果此时还没有事件文件，采集器会等待。
     
   
   
   
   
4. 启动Pi应用并加载TS探针。 
   Pi应用是Node.js应用，TS探针运行在Pi应用进程内。根据您使用的Pi框架，从下面三种方式中选一种。不要同时启用多种。
   先找到TS探针文件所在路径：
   ```
   # opentelemetry 是命名空间包，__file__ 为 None，需用 __path__ 取实际路径
   python -c "import opentelemetry; print(list(opentelemetry.__path__)[0])"
   ```
   输出示例：
   ```
   /opt/conda/lib/python3.11/site-packages/opentelemetry
   ```
   记住这个路径，下面用$OTEL_PY_HOME表示。TS探针的关键入口文件为：
   表2TS探针入口文件 
   | 探针                | 入口文件（相对 $OTEL_PY_HOME）                                  | 用途                                          |
   |:---|:---|:---|
   | pi_agent_core     | instrumentation/pi_node/pi_agent_core/dist/src/preload.js | 用于preload方式：通过Node启动参数提前加载，自动为Agent类附加事件记录能力。 |
   | pi_agent_core    | instrumentation/pi_node/pi_agent_core/dist/src/index.js    | 用于显式插桩方式：在代码中手动调用 instrumentAgent(agent)。    |
   | pi_coding_agent | instrumentation/pi_node/pi_coding_agent/dist/src/index.js  | 用于Extension方式：作为Pi Coding Agent的扩展插件注册。      |
      
   - **方式一：接入 pi-agent-core（preload 自动接入，推荐）**
     什么是preload：preload是指在应用正式代码执行之前，先加载一段指定代码。Node.js 20.6+提供了--import参数，可以在启动时指定一个预加载脚本。通过把TS探针的preload.js作为预加载脚本传入，Node就会在运行你的应用之前先执行它。这样，探针就有机会在应用代码运行之前，为Pi框架的Agent类附加事件记录能力。
     工作流程如下：
     1. 找到您的应用所使用的Pi框架包（默认是@earendil-works/pi-agent-core）。
     
     2. 给这个包中的Agent类增加事件记录能力。这里说的"增加事件记录能力"，是指在原有代码基础上附加记录功能，而不是修改原有代码本身。当Agent的prompt和continue方法被调用时，探针会自动捕获执行过程。
     
     3. 将捕获到的事件写入JSONL文件。
     
     
     整个过程对业务代码没有侵入，您不需要在应用代码中import任何探针模块。
     启动命令：
     ```
     # 设置采集模式与事件输出目录
     export PI_INSTRUMENTATION_MODE=core
     export PI_JSONL_DIR=/var/lib/pi/events
     # 启动 Pi 应用
     # 注意：file:// 后是 wheel 内 preload.js 的绝对路径
     # <app.mjs> 替换为用户实际的 Pi 框架应用入口文件
     node --import "file:///opt/conda/lib/python3.11/site-packages/opentelemetry/instrumentation/pi_node/pi_agent_core/dist/src/preload.js" <app.mjs>
     ```
     命令说明：
     - node：Node.js运行时。
     
     - --import "file://..."：Node.js的预加载参数。它表示"在运行应用代码之前，先执行这个参数指定的脚本"。它会先加载探针的preload.js，由探针完成对Agent类的处理。
     
     - \<app.mjs\>：用户自己开发的Pi框架应用入口文件（不是探针提供的文件），文件名与扩展名不限（.mjs / .js 均可），通常是用户创建Agent实例并调用prompt/continue的主文件。
     
     
     ![](https://support.huaweicloud.com/ops-agentarts/public_sys-resources/note_3.0-zh-cn.png)
     如果您的应用使用的包名不是默认的@earendil-works/pi-agent-core，需要提前设置：
     ```
     export PI_AGENT_CORE_PACKAGE=@your-org/pi-agent-core
     ```
     preload脚本不会阻止应用启动。即使它加载失败（例如找不到Pi框架包），应用仍然可以正常运行。但此时不会产生观测数据。如果设置了PI_DEBUG=true，可以在日志中看到失败原因。建议在接入阶段开启PI_DEBUG=true，确认preload正常工作后再关闭。
     如果您使用tsx运行TypeScript应用，可以通过NODE_OPTIONS传递--import：
     ```
     export NODE_OPTIONS="--import file:///opt/conda/lib/python3.11/site-packages/opentelemetry/instrumentation/pi_node/pi_agent_core/dist/src/preload.js"
     npx tsx src/app.ts
     ```
     这种方式与直接使用node --import等效。
     
   
   - **方式二：接入 pi-agent-core（显式插桩）**
     什么是显式插桩：在应用入口代码中手动调用探针提供的instrumentAgent函数，把Agent实例交给探针处理。相比preload，这种方式需要改一点代码，但好处是控制更明确、不依赖启动参数。
     如果不方便修改启动命令，也可以在应用入口代码中显式调用：
     ```
     import { Agent } from "@earendil-works/pi-agent-core";
     import { instrumentAgent } from "/opt/conda/lib/python3.11/site-packages/opentelemetry/instrumentation/pi_node/pi_agent_core/dist/src/index.js";
     const agent = new Agent({ /* Pi 配置 */ });
     instrumentAgent(agent);
     await agent.prompt("hello");
     ```
     显式插桩与preload二选一，避免重复处理。
     
   
   - **方式三：接入 pi-coding-agent（Extension Hook）**
     什么是Extension Hook：Pi Coding Agent支持通过配置文件加载扩展（Extension）。扩展可以在Pi框架运行过程中注册事件监听器，当指定事件发生时被调用。TS探针提供了一个Extension入口，把它注册到Pi Coding Agent的配置中，Pi框架就会在运行时自动调用它，达到记录事件的目的。
     将TS探针入口文件以绝对路径加入Pi Coding Agent配置目录下的settings.json。
     Pi Coding Agent的配置目录由Pi框架自身决定，常见为\~/.pi/ 或 \~/.config/pi/，具体路径以Pi框架官方文档为准。如果不确定，可以执行pi --help查看，或检查\~/.pi/下是否已有settings.json。
     示例：
     ```
     # 假设 Pi 配置目录为 ~/.pi/，将探针入口写入 settings.json（路径必须为绝对路径）
     cat > ~/.pi/settings.json <<'EOF'
     {
       "extensions": [
         "/opt/conda/lib/python3.11/site-packages/opentelemetry/instrumentation/pi_node/pi_coding_agent/dist/src/index.js"
       ]
     }
     EOF
     export PI_INSTRUMENTATION_MODE=coding
     pi
     ```
     这个Extension会在Pi Coding Agent中注册17种事件监听器，覆盖session、agent、turn、provider、message、tool等事件类型。当这些事件发生时，探针会自动记录。
     
   
   
   
   
5. 验证TS探针是否生效。 
   启动Pi应用并触发一次Agent/LLM/Tool调用后，检查PI_JSONL_DIR指向的目录下是否生成\*.jsonl事件文件：
   ```
   ls -la $PI_JSONL_DIR/
   # 应看到类似 pi-agent-core-<timestamp>.jsonl 的事件文件
   # 取其中一个文件查看首行
   head -1 $PI_JSONL_DIR/*.jsonl | python -m json.tool
   # 应输出含 schema_version=1.0、source=pi-agent-core 或 pi-coding-agent 的事件
   ```
   若文件未生成，请检查：
   1. 确认PI_INSTRUMENTATION_MODE不为off，检查命令如下：
      ```
      echo $PI_INSTRUMENTATION_MODE
      ```
      可选值为auto、core、coding、off。如果输出为空或为off，说明探针不会工作。需要重新设置（auto或core或coding），并确保这个环境变量在启动Pi应用的那个终端里生效。
      
   
   2. 确认--import路径是否正确，preload.js是否已加载。可设置PI_DEBUG=true查看探针自身日志。 第一步：确认 preload.js 文件是否存在。
      先执行以下命令获取Python包安装目录：
      ```
      python -c "import opentelemetry; print(list(opentelemetry.__path__)[0])"
      ```
      将输出与固定后缀拼接，得到实际路径：
      ```
      <Python包安装目录>/instrumentation/pi_node/pi_agent_core/dist/src/preload.js
      ```
      然后确认这个文件存在：
      ```
      ls -la <上一步拼接得到的实际路径>
      ```
      如果文件存在，命令会输出文件信息；如果输出类似No such file or directory信息，说明路径不对，或者wheel包未正确安装，需要重新检查安装步骤。
      第二步：确认preload是否被加载。
      设置环境变量并重新启动Pi应用：
      ```
      export PI_DEBUG=true
      ```
      然后启动Pi应用，观察启动日志：如果看到 \[huawei-pi\] bootstrap: Agent patched successfully，说明preload已经正常加载，并且成功为Agent类附加了事件记录能力；如果看到 failed to patch Agent，说明preload执行了，但处理Agent类时出错。根据错误信息进一步排查（比如目标框架包未安装、包名不匹配等）；如果完全没有看到任何日志，说明preload根本没有被加载。回到第一步，确认路径是否正确、--import 参数是否写在正确的位置。
      
   
   3. 确认Pi应用进程对PI_JSONL_DIR有写权限。
      ```
      touch $PI_JSONL_DIR/test_write && echo "write ok" && rm $PI_JSONL_DIR/test_write
      ```
      如果提示Permission denied，说明当前用户没有写权限。可以用ls -ld $PI_JSONL_DIR查看目录属主和权限，必要时用chmod或chown调整，或换一个当前用户可写的目录作为PI_JSONL_DIR。
      
   
   
   如果这一步验证通过，说明TS探针已经正常工作，事件文件正在生成，采集器会读取并上报。
   
   
 
#### 环境变量说明
表3环境变量说明 
| 环境变量                                             | 说明                                                                              | 适用进程      | 是否必填        | 默认值 / 示例                     |
|:---|:---|:---|:---|:---|
| PI_INSTRUMENTATION_MODE                          | TS探针工作模式：auto（自动判断）/ core（用于pi-agent-core）/ coding（用于pi-coding-agent）/ off（关闭） | Node     | 是          | auto                            |
| PI_JSONL_DIR                                      | JSONL事件输出目录。TS探针写入，Python采集器读取                                                 | 两者        | 是           | .pi/events                   |
| PI_AGENT_CORE_PACKAGE                           | pi-agent-core的目标包名，仅在preload方式下使用。用于告诉探针去哪个包找Agent类                            | Node    | 否            | @earendil-works/pi-agent-core |
| PI_CHECKPOINT                                      | 采集器断点续传文件路径。记录上次读取到哪个位置，重启后从该位置继续                                              | Python   | 是            | .pi/collector-checkpoint.json  |
| PI_EXPORTER                                      | 采集器上报后端：console（仅打印到屏幕，调试用）/ otlp（上报到云上）                                       | Python  | 是           | console                        |
| PI_DEBUG                                         | 是否输出探针内部错误日志。设为true时，探针在启动和处理过程中会打印详细日志，便于排查问题                                  | 两者      | 否            | false                           |
| OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT | 是否采集LLM的输入/输出内容。设为false时，上报的数据中不包含对话内容，只保留结构和统计信息，适用于对数据敏感的场景                   | Node    | 否            | false                          |
| PI_REDACT_SECRETS                                 | 是否对常见的敏感信息（如API Key、Token）做脱敏处理后再写入事件文件。设为true时，探针会将这些字段替换成占位符                | Node    | 否           | true                         |
| PI_MAX_STRING_BYTES                                | 事件中单个字符串的最大字节数。超过部分会被截断，防止单个字段过大                                               | Node   | 否            | 16384                         |
| PI_MAX_FILE_BYTES                                | 单个JSONL文件的分段大小。文件达到此大小后会滚动生成新文件                                               | Node    | 否          | 67108864                      |
| agent_domain_id                                     | 账号 domain ID                                                                  | Python | 是          | your-domain-id                 |
| agentarts_project_id                               | 华为云项目 ID                                                                        | Python | 是          | your-project-id               |
| agent_resource_id                                | 智能体 ID                                                                         | Python | 是          | your-agent-id                |
| resource_type                                    | 智能体类型：agent / multiagents / workflow                                            | Python   | 是          | agent                         |
| agentarts_agentops_otel_agent_apm_enable          | 是否启用 APM Trace                                                                | Python | 是            | 默认 false                       |
| agentarts_agentops_otel_agent_aom_enable          | 是否启用 AOM Metrics                                                              | Python | 是          | 默认 false                      |
| agentarts_agentops_apm_token                     | APM 接入凭证（自动转换为 OTEL_EXPORTER_OTLP_TRACES_HEADERS）                            | Python | APM 启用时必填   | your-apm-token                  |
| agentarts_agentops_apm_exporter_endpoint          | APM OTLP gRPC 上报地址（自动转换为 OTEL_EXPORTER_OTLP_TRACES_ENDPOINT）                     | Python | APM 启用时必填    | apm-endpoint                   |
| agentarts_agentops_aom_access_code                | AOM 接入凭证（自动转换为 Metrics headers 的 Bearer Token）                                | Python    | AOM 启用时必填 | your-aom-access-code          |
| agentarts_agentops_aom_exporter_endpoint         | AOM OTLP gRPC 上报地址（自动转换为 OTEL_EXPORTER_OTLP_METRICS_ENDPOINT）                 | Python | AOM 启用时必填     | aom-endpoint                 |
| agentarts_agentops_aom_prometheus_id              | Prometheus 实例 ID                                                              | Python  | AOM 启用时必填  | your-prometheus-id            |
| OTEL_SERVICE_NAME                                | 采集器服务名称                                                                        | Python | 否           | pi-collector                   |
| OTEL_SERVICE_VERSION                              | 采集器服务版本                                                                        | Python  | 否            | 0.1.0                          |
| OTEL_DEPLOYMENT_ENVIRONMENT                       | 部署环境名称                                                                           | Python | 否           | development                   |
| OTEL_METRIC_EXPORT_INTERVAL                       | 指标上报周期（毫秒）                                                                      | Python | 否          | 60000                          |
| PI_LOG_LEVEL                                      | 采集器日志级别                                                                       | Python  | 否           | INFO                         |
   
#### 示例代码
以下示例展示一个基于Pi Agent Core框架创建的Agent，并通过TS探针接入可观测。示例中配置了read_file和list_files两个工具。
示例中使用华为云MaaS服务提供的大模型接口，可登录华为云[MaaS服务控制台](https://console.huaweicloud.com/modelarts/#/model-studio/homepage)，创建API Key。
图2创建API Key   
![](https://support.huaweicloud.com/ops-agentarts/zh-cn_image_0000002787233467.png "点击放大")
**整体流程**
1. 创建项目目录和代码文件。
2. 安装Node.js依赖。
3. 修改代码中的配置项（API Key、探针路径等）。
4. 在终端中配置环境变量并启动Python采集器。
5. 在另一个终端中启动Pi Agent。
6. 验证事件文件是否生成。
7. 在AgentArts平台查看调用链和指标。
**代码目录结构**
按照以下目录要求创建文件夹及代码文件。
```
core_agent_demo/
├── src/
│   ├── app.ts          # Agent 主程序，放业务逻辑，不包含探针代码
│   └── tools.ts        # 工具定义（read_file, list_files）
├── bootstrap.mjs        # 探针预加载入口由NODE_OPTIONS=--import加载，在应用启动前为Agent类附加事件记录能力
├── package.json         # Node.js项目依赖配置文件。声明项目名称、依赖包和启动脚本
├── tsconfig.json        # TypeScript 编译配置
├── README.md            # 测试用文件（Agent 会读取）
└── run.bat              # 启动脚本（含 preload + 环境变量）
```
- package.json：项目依赖文件 这个文件告诉Node.js：项目叫什么、依赖哪些第三方包、用哪个命令启动。执行 npm install 时，npm会读取这个文件，自动下载其中声明的依赖包。
  ```
  {
    "name": "pi-core-agent-demo",
    "version": "1.0.0",
    "private": true,
    "type": "module",
    "scripts": {
      "start": "tsx src/app.ts"
    },
    "dependencies": {
      "@earendil-works/pi-agent-core": "^0.85.1",
      "@earendil-works/pi-ai": "^0.85.1"
    },
    "devDependencies": {
      "tsx": "^4.0.0",
      "typescript": "^5.9.0",
      "@types/node": "^22.0.0"
    }
  }
  ```
  
- src/tools.ts：工具定义文件 Pi Agent Core的工具是一个包含name、description、parameters（JSON Schema）、execute方法的对象。大模型会根据description和parameters自动决定什么时候调用工具、传什么参数。
  ```
  import * as fs from "node:fs";
  // ── read_file 工具 ──
  export const read_file = {
    name: "read_file",
    description: "读取指定路径的文件内容",
    parameters: {
      type: "object" as const,
      properties: {
        path: {
          type: "string",
          description: "要读取的文件路径",
        },
      },
      required: ["path"],
    },
    async execute(toolCallId: string, params: { path: string }) {
      try {
        const content = fs.readFileSync(params.path, "utf-8");
        const truncated = content.length > 4000
          ? content.substring(0, 4000) + "\n...[truncated]"
          : content;
        return {
          content: [{ type: "text" as const, text: truncated }],
        };
      } catch (err: any) {
        return {
          content: [{ type: "text" as const, text: `读取文件失败: ${err.message}` }],
          isError: true,
        };
      }
    },
  };
  // ── list_files 工具 ──
  export const list_files = {
    name: "list_files",
    description: "列出指定目录下的文件和子目录",
    parameters: {
      type: "object" as const,
      properties: {
        path: {
          type: "string",
          description: "要列出的目录路径，默认为当前目录",
        },
      },
      required: [],
    },
    async execute(toolCallId: string, params: { path?: string }) {
      try {
        const dir = params.path || ".";
        const entries = fs.readdirSync(dir, { withFileTypes: true });
        const items = entries.map((entry) => {
          const type = entry.isDirectory() ? "DIR " : "FILE";
          return `${type}  ${entry.name}`;
        });
        const result = items.length > 0 ? items.join("\n") : "(空目录)";
        return {
          content: [{ type: "text" as const, text: `${dir}:\n${result}` }],
        };
      } catch (err: any) {
        return {
          content: [{ type: "text" as const, text: `列目录失败: ${err.message}` }],
          isError: true,
        };
      }
    },
  };
  ```
  
- tsconfig.json：TypeScript编译配置文件 这个文件告诉TypeScript编译器：按什么规则编译 .ts 文件。这里的 module 和 moduleResolution 配置是为了让代码能与Pi框架和tsx运行时正确配合：
  - module: "ESNext"：使用最新的ES模块语法（import/export）。
  
  - moduleResolution: "bundler"：使用打包工具风格的模块解析方式，能正确处理Pi框架的subpath exports（即允许import ... from "@earendil-works/pi-ai/compat"这种带子路径的导入）。
  
  
  ```
  {
    "compilerOptions": {
      "target": "ES2022",
      "module": "ESNext",
      "moduleResolution": "bundler",
      "esModuleInterop": true,
      "strict": true,
      "skipLibCheck": true,
      "outDir": "dist"
    },
    "include": ["src/**/*.ts"]
  }
  ```
  
- src/app.ts：Agent智能体的主程序
  这是Agent的业务代码文件。它不包含任何探针相关代码，探针会在应用启动时通过bootstrap.mjs自动加载。
  ```
  import { Agent } from "@earendil-works/pi-agent-core";
  import { createProvider, envApiKeyAuth, openAICompletionsApi } from "@earendil-works/pi-ai/compat";
  import { read_file, list_files } from "./tools.js";
  // ── LLM 配置（华为云 MaaS 服务，OpenAI 兼容接口）──
  const LLM_BASE_URL = "https://api.modelarts-maas.com/openai/v1";
  const LLM_API_KEY = process.env.LLM_API_KEY || "";
  const LLM_MODEL_ID = "deepseek-v4.1-flash";
  // ── 1. 创建 Pi 标准 Provider ──
  const provider = createProvider({
    id: "maas",
    name: "Huawei Cloud MaaS",
    baseUrl: LLM_BASE_URL,
    auth: envApiKeyAuth("Huawei Cloud MaaS API key", ["LLM_API_KEY"]),
    models: [{
      id: LLM_MODEL_ID,
      name: "deepseek-v4.1-flash",
      api: "openai-completions" as const,
      provider: "maas",
      baseUrl: LLM_BASE_URL,
      reasoning: false,
      input: ["text"],
      cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
      contextWindow: 128000,
      maxTokens: 4096,
    }],
    api: openAICompletionsApi(),
  });
  const model = provider.getModels()[0];
  async function main() {
    // ── 校验 API Key ──
    if (!LLM_API_KEY) {
      console.error("[demo] 请设置环境变量 LLM_API_KEY（在华为云 MaaS 控制台创建 API Key）");
      process.exit(1);
    }
    // ── 2. 创建 Agent ──
    // 注意：streamFn 使用 .bind(provider) 确保 provider 上下文不丢失
    const agent = new Agent({
      streamFn: provider.streamSimple.bind(provider),
      initialState: {
        model: model,
        systemPrompt: "你是一个代码分析助手。你可以使用工具读取文件和列出目录内容。请用中文回答。",
        tools: [read_file, list_files],
      },
      sessionId: `core-demo-${Date.now()}`,
      getApiKey: async (providerName: string) => {
        if (providerName === "maas") return LLM_API_KEY;
        return undefined;
      },
    });
    // ── 3. 运行 Agent ──
    const task = process.argv[2] || "列出当前目录的文件，读取 README.md 并总结内容";
    console.log(`[demo] 用户: ${task}`);
    try {
      await agent.prompt(task);
      await agent.waitForIdle();
      console.log("[demo] Agent 运行完成");
    } catch (err: any) {
      console.log("[demo] Agent 运行出错:", err.message);
    }
  }
  main().catch((err) => {
    console.error("[demo] 运行失败:", err);
    process.exit(1);
  });
  ```
  - app.ts不会import任何探针代码。
  
  - streamFn: provider.streamSimple.bind(provider) 中，provider.streamSimple是provider对象上的方法。如果直接赋值给streamFn，会丢失this上下文，导致运行时内部访问this.baseUrl / this.models 等属性失败。使用.bind(provider)绑定上下文，确保方法内部this指向正确的provider实例。
    
- bootstrap.mjs：preload入口 这是探针的预加载入口，由NODE_OPTIONS=--import加载。它会在业务代码运行之前，找到Pi框架的Agent类，并给它附加事件记录能力。
  ```
  // bootstrap.mjs - 在用户代码 import 之前，先加载并 patch pi-agent-core
  // patchEntry 指向 wheel 内编译好的 patch.js
  // 通过 python -c "import opentelemetry; print(list(opentelemetry.__path__)[0])" 获取路径
  // Linux 示例: /opt/conda/lib/python3.11/site-packages/opentelemetry/instrumentation/pi_node/pi_agent_core/dist/src/patch.js
  // Windows 示例: C:/Users/xxx/site-packages/opentelemetry/instrumentation/pi_node/pi_agent_core/dist/src/patch.js
  // 路径中的空格用 %20 编码（如 Program%20Files）
  const patchEntry = "file:///<$OTEL_PY_HOME>/instrumentation/pi_node/pi_agent_core/dist/src/patch.js";
  try {
    // 使用动态 import 让 Node 模块解析自动处理路径，无需手动拼接 node_modules 路径
    const piModule = await import("@earendil-works/pi-agent-core");
    if (typeof piModule.Agent === "function") {
      const patchModule = await import(patchEntry);
      if (typeof patchModule.patchAgentClass === "function") {
        patchModule.patchAgentClass(piModule.Agent);
        if (process.env.PI_DEBUG === "true") {
          console.warn("[huawei-pi] bootstrap: Agent patched successfully");
        }
      } else {
        if (process.env.PI_DEBUG === "true") {
          console.warn("[huawei-pi] bootstrap: patchAgentClass not found in patch module");
        }
      }
    }
  } catch (error) {
    if (process.env.PI_DEBUG === "true") {
      console.warn("[huawei-pi] bootstrap: failed to patch Agent", error);
    }
  }
  ```
  \<$OTEL_PY_HOME\>需要替换为下面命令的实际输出路径：
  ```
  python -c "import opentelemetry; print(list(opentelemetry.__path__)[0])"
  ```
  
- README.md：创建一个简单的测试文件，内容随意，例如：
  ```
  # Pi Agent Core Demo
  这是一个用于测试 Pi 框架接入 AgentArts 观测的示例项目。
  ```
  
- run.sh / run.bat：启动脚本 脚本中各参数取值请按照实际填写。
  Linux/macOS系统
  ```
  #!/bin/bash
  # run.sh (Linux/macOS)
  cd "$(dirname "$0")"
  # JSONL 事件输出目录（与 Collector 共用）
  export PI_JSONL_DIR=/var/lib/pi/events
  # TS 探针调试日志
  export PI_DEBUG=true
  # 采集 LLM 输入/输出内容
  export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
  # LLM API Key（在华为云 MaaS 控制台创建）
  export LLM_API_KEY=<your-api-key>
  # Pi 业务属性（写入 JSONL resource 字段）
  export PI_DOMAIN_ID=<your-domain-id>
  export PI_PROJECT_ID=<your-project-id>
  export PI_GEN_AI_RESOURCE_ID=<your-agent-id>
  export PI_GEN_AI_RESOURCE_TYPE=agent
  export PI_USER_ID=pi-demo-user
  export PI_AGENT_NAME=pi-demo-agent
  export PI_RESOURCE_VERSION=default
  # 通过 bootstrap.mjs 预加载探针
  export NODE_OPTIONS="--import file:///path/to/core_agent_demo/bootstrap.mjs"
  npx tsx src/app.ts "$@"
  ```
  Windows系统
  ```
  @echo off
  REM run.bat (Windows)
  cd /d "%~dp0"
  set "PI_JSONL_DIR=F:\pi-demo\events"
  set "PI_DEBUG=true"
  set "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true"
  set "LLM_API_KEY=<your-api-key>"
  set "PI_DOMAIN_ID=<your-domain-id>"
  set "PI_PROJECT_ID=<your-project-id>"
  set "PI_GEN_AI_RESOURCE_ID=<your-agent-id>"
  set "PI_GEN_AI_RESOURCE_TYPE=agent"
  set "PI_USER_ID=pi-demo-user"
  set "PI_AGENT_NAME=pi-demo-agent"
  set "PI_RESOURCE_VERSION=default"
  REM Windows 路径含空格需用 %%20 编码
  set "NODE_OPTIONS=--import file:///F:/path/to/core_agent_demo/bootstrap.mjs"
  npx tsx src\app.ts %*
  ```
  Windows系统中.bat文件注意事项：.bat文件必须使用CRLF行尾（LF行尾会导致set命令解析失败）；路径中的空格用%20编码（%在.bat中需转义为%%）。
  
**安装依赖**
在项目根目录 core_agent_demo 下执行：
```
npm init -y
npm install @earendil-works/pi-agent-core@^0.85.1 @earendil-works/pi-ai@^0.85.1
npm install -D tsx@^4.0.0 typescript@^5.9.0 @types/node@^22.0.0
```
**修改代码配置**
1. 修改bootstrap.mjs中的patchEntry路径。 
   代码文件中的\<$OTEL_PY_HOME\>需要替换为下面命令的实际输出路径：
   ```
   python -c "import opentelemetry; print(list(opentelemetry.__path__)[0])"
   ```
   
   
2. 修改run.sh或run.bat中的环境变量。 
   - LLM_API_KEY：华为云MaaS模型的API Key。
   
   - PI_DOMAIN_ID、PI_PROJECT_ID、PI_GEN_AI_RESOURCE_ID：AgentArts平台创建的Pi框架智能体身份信息。
   
   - PI_JSONL_DIR：这个变量指定JSONL事件文件的输出目录。它的值由用户自己选择。代码示例中的值 /var/lib/pi/events（Linux/macOS）或 F:\\pi-demo\\events（Windows）只是一个示例，可以改成任意合适的目录。建议使用一个专门的空目录，避免与已有文件混在一起。
   
   - NODE_OPTIONS：这个路径必须替换为你项目中 bootstrap.mjs 的绝对路径，不能直接使用示例中的 /path/to/core_agent_demo/bootstrap.mjs。 获取方法：
     - Linux/macOS：在项目根目录执行 realpath bootstrap.mjs，输出的就是绝对路径。
     
     - Windows：右键单击bootstrap.mjs文件，选择"属性"，查看"位置"字段，与文件名拼接得到完整路径。注意路径中的反斜杠\\在NODE_OPTIONS中需要改为正斜杠/，且路径中的空格要用%20编码。
      
   
   
   
   
3. 给run.sh添加可执行权限（对于Linux / macOS系统）。 
   ```
   chmod +x run.sh
   ```
   
   
**启动Python采集器**
打开一个终端（假设为终端A），进入项目目录，执行以下命令。
```
huaweicloud-instrument python -m opentelemetry.instrumentation.pi_collector --exporter otlp
```
采集器会持续运行，读取PI_JSONL_DIR目录下的JSONL事件并上报。请保持此终端窗口运行，不要关闭。
**启动Pi Agent**
打开另一个终端（假设为终端B），进入项目目录core_agent_demo，执行：
```
# Linux / macOS用户执行：
./run.sh
# Windows 用户执行：
run.bat
```
预期输出：
```
[huawei-pi] bootstrap: Agent patched successfully
==================================================
Core Agent Demo (Pi Agent Core + DeepSeek-V4.1-Flash)
模型: DeepSeek-V4.1-Flash (华为云 MaaS)
工具: read_file, list_files
==================================================
[demo] 用户: 列出当前目录的文件，读取 README.md 并总结内容
（Agent 调用 list_files 列目录）
（Agent 调用 read_file 读取 README.md）
（Agent 综合结果输出总结）
[demo] Agent 运行完成
```
**验证事件文件**
在终端B中执行：
```
ls -la $PI_JSONL_DIR/
```
应看到类似pi-agent-core-\<pid\>-\<uuid\>-00000.jsonl的文件。
查看其中一个文件的首行：
```
head -1 $(ls $PI_JSONL_DIR/*.jsonl | head -1) | python -m json.tool
```
应输出包含schema_version=1.0、source=pi-agent-core的事件。
**在AgentArts查看调用链**
Agent运行后，Python采集器会自动读取JSONL事件并上报。在AgentArts平台的"观测 \> 调用链分析"中，可看到如下类似的调用链结构：
```
pi agent (AGENT)
└─ pi turn (WORKFLOW)
    ├─ chat deepseek-v4.1-flash (LLM) → execute_tool list_files (PLUGIN)
    └─ chat deepseek-v4.1-flash (LLM) → execute_tool read_file (PLUGIN)
        └─ chat deepseek-v4.1-flash (LLM) → 最终总结
```
#### 查看监控数据
数据上报成功后，可在AgentArts智能体平台的观测功能中查看监控数据。
1. 登录[AgentArts 智能体平台](https://console.huaweicloud.com/agentarts/)。
2. 在左侧导航栏选择"观测与优化 \> 观测"。
3. 在"智能体列表"页面，找到已接入的智能体，单击智能体名称进入详情页面。
**查看业务指标**
在"指标分析"页签中，可以查看关键业务指标：
- Tokens消耗：Input Tokens和Output Tokens的消耗总量
- 模型调用次数：应用调用大模型的累计次数
- 模型调用平均耗时：模型调用的平均响应时间
- 模型调用成功率：大模型调用成功的比例
- 会话数：应用产生的会话总数
- 响应成功率：服务响应的成功率
- 工具调用次数：Agent 调用工具的累计次数及平均耗时
- 事件采集延迟：采集器处理事件相对事件产生时间的延迟
**查看调用链信息**
在"调用链分析"页签中，可以查看完整的Trace调用链路：
- 查看Agent、Workflow、LLM、Plugin等Span类型的层级关系及各节点耗时
  - Agent节点对应 agent.start / agent.end
  
  - Workflow节点对应 turn 与 step 执行
  
  - LLM节点对应 llm.start / llm.end
  
  - Plugin节点对应工具调用 tool.start / tool.end
   
- 单击具体Span查看详细信息：
  - LLM节点：可查看模型名称、输入/输出消息（Input/Output Messages）、Token消耗（Total tokens）、首Token耗时（TTFT）
  
  - Tool节点：可查看工具名称、输入参数、返回结果、调用耗时
  
  - Agent节点：可查看会话级累计Token用量（含cache_read/cache_write/reasoning tokens）及总成本
   
**查看会话分析**
在"会话分析"页签中，可以查看智能体与用户对话的历史数据：
- 追踪对话上下文
- 分析模型响应耗时
- 统计Token消耗
- 快速定位对话异常问题
 
#### 更多参考
- **传递session_id与user_id**
  Pi框架在事件中已携带 session_id（事件必填字段）与 user_id（事件resource字段）。开发者需在Pi框架应用侧通过框架API设置会话标识与用户标识，这些信息会随事件写入JSONL文件，采集器自动关联到Span和指标上：
  ```
  # Pi 框架应用侧（伪代码，具体 API 以 Pi 框架文档为准）
  agent.run(
      session_id="session-01",
      user_id="pi_user",
      messages=[{"role": "user", "content": "你好"}],
  )
  ```
  - session_id：会话标识，用于关联同一会话内的多轮调用，会写入Span的gen_ai.conversation.id属性。
  
  - user_id：用户标识，用于按用户维度统计和过滤，会写入Span的gen_ai.user.id属性。
   
- **跨进程链路关联**
  Pi事件支持upstream_traceparent字段，用于将Pi框架产生的调用链与上游服务（如API网关、Web框架）的Trace上下文关联。若上游服务已接入OpenTelemetry，将W3C Traceparent字符串传入Pi框架事件即可实现跨进程链路串联。
  
- **控制内容采集**
  默认情况下，采集器会采集Pi事件中messages与output_messages字段的LLM 输入/输出内容。如需关闭内容采集，可在Pi框架应用侧配置不输出messages字段，事件中缺失该字段时采集器自动跳过；或设置OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=false。
  
 
#### 常见问题
**无数据上报**
1. 检查 PI_JSONL_DIR 指向的目录下是否存在 \*.jsonl 事件文件。执行 ls -la $PI_JSONL_DIR/。
2. 确认TS探针已加载。设置 PI_DEBUG=true 后重新启动Pi应用，观察Node侧日志。同时确认 PI_INSTRUMENTATION_MODE 不为 off。
3. 确认Python采集器已启动。执行 ps -ef \| grep pi_collector 查看 pi_collector 进程是否存在。
4. 检查 PI_EXPORTER 是否设置为 otlp，以及APM/AOM的endpoint是否正确。
5. 检查APM/AOM凭证（Token/Access Code）是否有效，可从AgentArts平台重新获取。
6. 查看采集器日志，寻找OTLP上报错误或事件解析错误。
**JSONL事件文件未生成**
1. 确认Pi框架应用已正常运行，并触发了Agent/LLM/Tool调用。
2. 确认TS探针已正确加载。检查preload路径是否正确、目标框架包 @earendil-works/pi-agent-core 是否可以正常解析（可执行 ls -la 检查文件是否存在，或设 PI_DEBUG=true 看日志）。
3. 确认 PI_JSONL_DIR 配置正确，且Pi应用进程对目录有写权限（可执行 touch $PI_JSONL_DIR/test_write 验证）。
**事件丢失或重复上报**
1. 采集器通过checkpoint文件记录进度，确认PI_CHECKPOINT路径可写且未被意外删除。
2. 事件去重依赖event_id，确认Pi框架生成的event_id全局唯一。
3. 若事件文件被截断或inode变化，采集器会自动重置offset重新读取。
**部分Span缺失或不完整**
1. Span重建依赖operation_id与parent_operation_id的父子关系，确认Pi事件字段完整。
2. 若父操作事件缺失，采集器会丢弃孤儿子操作的事件并在日志中告警。
3. 若采集器被强制终止，未关闭的Span会标记pi.incomplete=true后强制结束。
**指标上报失败（invalid temporality and type combination）**
1. AOM后端仅接受Gauge类型，采集器已统一使用Gauge，确认使用最新版本探针。
2. 检查OTEL_EXPORTER_OTLP_METRICS_ENDPOINT是否指向AOM的OTLP地址。
 
