# CrewAI框架
观测功能支持通过Python探针对CrewAI框架开发的智能体进行观测，Python探针是华为云AgentArts产品自研的Python语言的可观测采集探针，其基于OpenTelemetry标准实现了自动化埋点能力。
本章节针对使用CrewAI框架开发的第三方智能体应用，通过Python探针实现自动化埋点和数据上报。
#### 前提条件
- Python 环境版本 \>= 3.9
- CrewAI版本 \>= 1.15.0
- OpenTelemetry SDK版本 \>= 1.42.0
探针初始化需要在应用启动时完成，建议在导入CrewAI模块之前初始化。
![](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都是按需计费，并有一定量的免费额度，超出后按实际使用量收费。
 
#### 框架介绍
CrewAI是面向大语言模型应用的多智能体协作框架。它以"角色（Role）、目标（Goal）、任务（Task）"为核心抽象，通过编排多个具备独立职责的Agent、分配工具（Tool）与技能（Skill），协同完成复杂任务；内置规划（Planner）、任务委派与记忆（Memory）等能力，支持从单Agent到多Agent协作，以及基于事件驱动的Flow流程编排。
接入后，以下能力将被自动监控：
- Crew执行链路（crew kickoff）：Crew的完整生命周期，包括Agent编排和任务分配。
- Agent执行：每个Agent的角色执行和任务处理过程。
- Task执行：任务的分配、执行和结果汇总。
- LLM调用（chat）：模型名称、Token用量、输入/输出内容。
- 工具调用（execute_tool）：工具名称、输入参数、返回结果。
 
 #### 接入步骤
 #### 步骤一：获取接入参数
1. 登录[AgentArts 智能体平台](https://console.huaweicloud.com/agentarts/)。
2. 在左侧导航栏选择"观测与优化 \> 观测"。
3. 在"智能体列表"页面，单击"接入智能体"，按照页面指引填写名称、智能体类型，创建一个"CrewAI"框架的智能体，并获取各配置参数。 
   图1获取配置参数   
   ![](https://support.huaweicloud.com/ops-agentarts/zh-cn_image_0000002804617061.png "点击放大")
   
   
 
#### 步骤二：安装探针
1. 安装探针。 
   下载[CrewAI探针](https://obs-apm2-cn-southwest-2.obs.cn-southwest-2.myhuaweicloud.com/PYTHON/version.26.10.30/huaweicloud_opentelemetry_instrumentation_crewai-1.0.0-py3-none-any.whl)，探针下载到本地项目后执行安装。
   ```
   pip install huaweicloud_opentelemetry_instrumentation_crewai-1.0.0-py3-none-any.whl --force-reinstall
   ```
   
   
2. 配置环境变量。 
   您需要手动为Python应用添加以下环境变量，将参数值替换为[步骤一：获取接入参数]中获取的实际值。
   Linux环境
   ```
   # 为本 SHELL 中所有进程添加环境变量
   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 配置
   export agentarts_agentops_apm_token=<your-apm-token>             # APM 接入凭证 Token
   export agentarts_agentops_apm_exporter_endpoint=<endpoint>       # APM 数据上报地址
   # AOM 配置
   export agentarts_agentops_aom_access_code=<your-aom-access-code>         # AOM 接入凭证
   export agentarts_agentops_aom_exporter_endpoint=<endpoint>               # AOM 数据上报地址
   export agentarts_agentops_aom_prometheus_id=<your-prometheus-id>         # Prometheus 实例 ID
   ```
   Windows环境（PowerShell）
   ```
   # 为本 SHELL 中所有进程添加环境变量
   $env:agentarts_agentops_otel_agent_apm_enable="true"
   $env:agentarts_agentops_otel_agent_aom_enable="true"
   # 智能体信息配置
   $env:agent_domain_id="<your-domain-id>"
   $env:agentarts_project_id="<your-project-id>"
   $env:agent_resource_id="<your-resource-id>"
   $env:resource_type="agent"
   # APM 配置
   $env:agentarts_agentops_apm_token="<your-apm-token>"
   $env:agentarts_agentops_apm_exporter_endpoint="<endpoint>"
   # AOM 配置
   $env:agentarts_agentops_aom_access_code="<your-aom-access-code>"
   $env:agentarts_agentops_aom_exporter_endpoint="<endpoint>"
   $env:agentarts_agentops_aom_prometheus_id="<your-prometheus-id>"
   ```
   
   
3. 启动应用。 
   假设app.py为您的CrewAI应用入口文件，在配置好环境变量的终端中执行以下命令，通过探针启动应用：
   ```
   opentelemetry-instrument python app.py
   ```
   opentelemetry-instrument命令会自动发现并加载已安装的探针组件，对CrewAI应用进行无侵入式自动化埋点，无需修改业务代码。
   
   
 
#### 步骤三：验证数据上报
CrewAI应用启动并产生调用后，可通过以下方式确认数据上报是否成功。
**确认探针安装**
执行以下命令，确认探针已正确安装：
```
pip show huaweicloud-opentelemetry-instrumentation-crewai
```
输出中应包含探针名称和版本号，且entry point信息完整。
**日志确认**
查看CrewAI应用的启动日志，搜索opentelemetry或instrument关键字，确认探针已成功初始化。如果日志中出现探针加载相关的信息且无报错，说明探针已正常装配。
**AgentArts平台确认**
登录[AgentArts智能体平台](https://console.huaweicloud.com/agentarts/)，在"观测与优化 \> 观测"页面中找到已接入的智能体，查看各指标与会话数据。
#### 环境变量说明
表1环境变量说明 
| 环境变量                                       | 说明                               | 是否必填     | 示例值                    |
|:---|:---|:---|:---|
| agent_domain_id                           | 账号domain ID                      | 是         | your-domain-id         |
| agentarts_project_id                       | 华为云项目ID                            | 是         | your-project-id         |
| agent_resource_id                        | 智能体ID                            | 是        | your-agent-id         |
| resource_type                           | 智能体类型：agent，multiagents，workflow | 是         | agent                  |
| agentarts_agentops_otel_agent_apm_enable | 是否启用APM Trace                     | 是         | 默认false                |
| agentarts_agentops_otel_agent_aom_enable | 是否启用AOM Metrics                    | 是         | 默认false                |
| agentarts_agentops_apm_token             | APM接入凭证Token                    | APM启用时必填   | your-apm-token         |
| agentarts_agentops_apm_exporter_endpoint  | APM OTLP数据上报地址                   | APM启用时必填 | apm-endpoint           |
| agentarts_agentops_aom_access_code        | AOM接入凭证                           | AOM启用时必填  | your-aom-access-code |
| agentarts_agentops_aom_exporter_endpoint | AOM OTLP数据上报地址                   | AOM启用时必填 | aom-endpoint           |
| agentarts_agentops_aom_prometheus_id      | Prometheus实例ID                     | AOM启用时必填   | your-prometheus-id      |
   
表2可选环境变量 
| 环境变量                                             | 说明                | 默认值        |
|:---|:---|:---|
| OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT | 是否采集LLM 输入/输出内容 | true        |
| OTEL_DEPLOYMENT_ENV                                | 部署环境            | production |
| OTEL_EXPORTER_OTLP_PROTOCOL                          | OTLP协议，必须使用grpc | grpc       |
| OTEL_BSP_SCHEDULE_DELAY                            | Span批量上报延迟（毫秒）  | 30000        |
| OTEL_BSP_MAX_QUEUE_SIZE                            | Span队列最大长度     | 4096        |
| OTEL_METRIC_EXPORT_INTERVAL                        | Metrics上报间隔（毫秒）  | 60000       |
| resource_version                                    | 智能体版本            | default    |
| agent_name                                          | 智能体名称            | default      |
   
#### 示例代码
以下示例展示了一个基于CrewAI的单Agent应用，包含一个Agent和一个Task，并演示了如何通过OTel Baggage注入session_id和user_id：
示例中使用华为云MaaS服务提供的大模型接口，可登录华为云[MaaS服务控制台](https://console.huaweicloud.com/modelarts/#/model-studio/homepage)，创建API Key。在项目的.env文件中配置以下变量：
请提前确认已完成探针安装，详细操作详见[接入步骤]。
```
OPENAI_API_KEY=<MODEL_API_KEY>
OPENAI_MODEL_NAME=deepseek-v4.1-flash
OPENAI_API_BASE=https://api.modelarts-maas.com/openai/v1
```
Agent应用示例代码如下：
```
import os
import uuid
from crewai import Agent, Crew, Task
from dotenv import load_dotenv
from opentelemetry import baggage, context
load_dotenv()
def get_llm():
    from crewai import LLM
    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
        raise RuntimeError("未找到 OPENAI_API_KEY,请在 .env 中配置。")
    model = os.getenv("OPENAI_MODEL_NAME", "gpt-4o-mini")
    base = os.getenv("OPENAI_API_BASE")
    if base:
        return LLM(model=model, base_url=base, api_key=api_key)
    return LLM(model=model, api_key=api_key)
def main() -> None:
    # 1. 注入 OTel baggage：探针据此上报 gen_ai.conversation.id / user.id
    session_id = f"demo-session-{uuid.uuid4().hex[:8]}"
    ctx = baggage.set_baggage("session_id", session_id)
    ctx = baggage.set_baggage("user_id", "demo-user", context=ctx)
    token = context.attach(ctx)
    print(f"[demo] session_id = {session_id}")
    # 2. 业务代码：一个 Agent 写一句话
    agent = Agent(
        role="文案助理",
        goal="用一句话介绍某个主题",
        backstory="你是一名简洁的文案助理。",
        llm=get_llm(),
    )
    task = Task(
        description="围绕主题「{topic}」写一句话介绍。",
        expected_output="一句 20 字以内的中文介绍。",
        agent=agent,
    )
    crew = Crew(agents=[agent], tasks=[task])
    try:
        result = crew.kickoff(inputs={"topic": "AI 在医疗领域的应用"})
    finally:
        try:
            context.detach(token)
        except Exception:
            pass
    print("\n--- 输出 ---")
    print(result.raw)
if __name__ == "__main__":
    main()
```
将上方示例代码保存为app.py，在项目目录下打开终端，通过探针启动应用：
```
opentelemetry-instrument python app.py
```
探针会自动采集Crew执行链路中的所有LLM调用、工具调用等数据，无需修改任何业务代码。
#### 查看监控数据
数据上报成功后，可在 AgentArts 智能体平台的观测功能中查看监控数据。
1. 登录[AgentArts 智能体平台](https://console.huaweicloud.com/agentarts/)。
2. 在左侧导航栏选择"观测与优化 \> 观测"。
3. 在"智能体列表"页面，找到已接入的智能体，单击智能体名称进入详情页面。
**查看业务指标**
在"指标分析"页签中，可以查看关键业务指标：
- Tokens消耗：Input Tokens和Output Tokens的消耗总量
- 模型调用次数：应用调用大模型的累计次数
- 模型调用平均耗时：模型调用的平均响应时间
- 模型调用成功率：大模型调用成功的比例
- 会话数：应用产生的会话总数
- 响应成功率：服务响应的成功率
**查看调用链信息**
在"调用链分析"页签中，可以查看完整的Trace调用链路：
- 查看各Span类型的层级关系及各节点耗时
- 单击具体Span查看详细信息：
  - Crew节点：可查看Crew的Agent编排和任务分配情况
  
  - Agent节点：可查看Agent角色、目标、输入/输出消息
  
  - Task节点：可查看任务描述、执行过程和结果
  
  - LLM节点（chat）：可查看模型名称、输入/输出消息（Input/Output Messages）、Token消耗（Total tokens）
  
  - Tool节点：可查看工具名称、输入参数、返回结果
   
**查看会话分析**
在"会话分析"页签中，可以查看智能体与用户对话的历史数据：
- 追踪对话上下文
- 分析模型响应耗时
- 统计Token消耗
- 快速定位对话异常问题
 
 #### 更多参考
**控制内容采集**
默认情况下，探针会采集LLM的输入/输出内容。如需关闭：
```
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=false
```
**代码手动插桩**
如果无法使用opentelemetry-instrument命令自动插桩，也可以通过创建sitecustomize.py手动初始化：
```
# --- 关键:在 import crewai / 构造 Agent 之前完成接入 --------------------
from opentelemetry.instrumentation.huawei_crewai import auto_instrument
_auto_instrument_ok = auto_instrument()
# 下面这些 import 必须在 auto_instrument() 之后 —— crewai 模块被 patch 过,
# 晚 import 才能拿到被包装后的类。
from crewai import Agent, Crew, Task  
## ...
if __name__ == "__main__":
    main()
```
#### 常见问题
**无数据上报**
1. 确认agentarts_agentops_otel_agent_apm_enable和agentarts_agentops_otel_agent_aom_enable已设置为true，默认值为false不会上报任何数据。
2. 检查环境变量是否正确配置，特别是agentarts_agentops_apm_token、agentarts_agentops_apm_exporter_endpoint等关键参数是否完整且无多余空格。
3. 检查网络连接，确保运行环境能访问APM/AOM端点地址。可通过curl \<endpoint\>命令验证连通性。
4. 检查凭证是否有效且未过期，可在AgentArts平台的接入指南页面重新获取最新凭证。
5. 查看应用启动日志，搜索opentelemetry或instrument关键字，排查探针初始化是否报错。
**部分Span缺失**
1. 确认是否通过opentelemetry-instrument python app.py命令启动应用。直接使用python app.py启动将无法触发自动插桩，需改用探针命令启动或参考[代码手动插桩]进行初始化。
2. 确认CrewAI版本满足最低要求（\>= 1.15.0），低版本框架的内部接口可能与探针不兼容。
3. 如使用手动插桩方式，确认探针初始化代码（auto_instrument()）在import crewai之前执行。若CrewAI模块先于探针加载，插桩将无法生效，导致相关Span丢失。
**Token统计不准确**
1. 确保使用最新版本的探针。
2. 流式场景下确认模型返回了usage字段。
3. 模型在响应中不返回usage字段或返回的Token数为近似值，此为模型侧行为，非探针问题。可在AgentArts调用链详情中确认模型节点的usage字段是否为空。
 
