Skip to main content

Documentation Index

Fetch the complete documentation index at: https://arize-ax.mintlify.dev/docs/llms.txt

Use this file to discover all available pages before exploring further.

CrewAI is a Python framework for orchestrating role-playing autonomous agents — agents collaborate on tasks, hand off work, and call tools. Arize AX captures every CrewAI run — Crew / Agent / Task spans plus the underlying LLM calls — via the openinference-instrumentation-crewai package, paired with an LLM-level instrumentor matching the provider CrewAI routes to.
https://storage.googleapis.com/arize-phoenix-assets/assets/images/phoenix-docs-images/gc.ico

CrewAI Tracing Tutorial (Google Colab)

Prerequisites

  • Python 3.10+
  • An Arize AX account (sign up)
  • An OPENAI_API_KEY from the OpenAI Platform
  • CrewAI 1.0+ (this guide uses the native-SDK routing model introduced in 1.0; for 0.x see Troubleshooting)

Launch Arize AX

  1. Sign in to your Arize AX account.
  2. From Space Settings, copy your Space ID and API Key. You will set them as ARIZE_SPACE_ID and ARIZE_API_KEY below.

Install

pip install arize-otel \
  openinference-instrumentation-crewai \
  openinference-instrumentation-openai \
  crewai
CrewAI 1.0+ routes LLM calls based on the model-string prefix: openai/... and bare model names go to the native OpenAI SDK, anthropic/... goes to Anthropic, etc. The LLM-level instrumentor must match the provider CrewAI is actually calling. The example below uses openai/gpt-5 so it pairs openinference-instrumentation-crewai with openinference-instrumentation-openai. Other prefixes need a different pairing — see Which instrumentor do I need? below.

Which instrumentor do I need?

CrewAI 1.0+ routes LLM calls to different provider SDKs based on your model string. Match your LLM-level instrumentor to the provider CrewAI is actually calling:
Model stringProvider SDK usedInstrumentor package
openai/gpt-5, gpt-5, or no prefixOpenAI (native)openinference-instrumentation-openai
anthropic/claude-sonnet-4-6Anthropic (native)openinference-instrumentation-anthropic
Groq, Together, or other providers without a native CrewAI SDKLiteLLM (fallback)openinference-instrumentation-litellm
The CrewAI instrumentor (openinference-instrumentation-crewai) is always required regardless of provider — it captures Crew, Agent, and Task spans.

Configure credentials

export ARIZE_SPACE_ID="<your-space-id>"
export ARIZE_API_KEY="<your-api-key>"
export ARIZE_PROJECT_NAME="crewai-tracing-example"
export OPENAI_API_KEY="<your-openai-api-key>"

Setup tracing

# instrumentation.py
import os

from arize.otel import register
from openinference.instrumentation.crewai import CrewAIInstrumentor
from openinference.instrumentation.openai import OpenAIInstrumentor

tracer_provider = register(
    space_id=os.environ["ARIZE_SPACE_ID"],
    api_key=os.environ["ARIZE_API_KEY"],
    project_name=os.environ["ARIZE_PROJECT_NAME"],
)

# Both instrumentors monkey-patch their target libraries — they must run
# before any `from crewai import ...` or any LLM client construction.
CrewAIInstrumentor().instrument(tracer_provider=tracer_provider)
OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)
print("Arize AX tracing initialized for CrewAI.")

Run CrewAI

# example.py

# Importing instrumentation first ensures both instrumentors run before
# CrewAI is imported. Out-of-order imports silently drop spans.
from instrumentation import tracer_provider

from crewai import Agent, Crew, LLM, Task

# `openai/gpt-5` tells CrewAI 1.0+ to use the native OpenAI SDK, which
# OpenAIInstrumentor patches. It reads OPENAI_API_KEY from the env.
llm = LLM(model="openai/gpt-5")

researcher = Agent(
    role="Ocean researcher",
    goal="Explain ocean facts to a general audience.",
    backstory="You are a marine scientist who values brevity.",
    llm=llm,
    allow_delegation=False,
    verbose=False,
)

writer = Agent(
    role="Science writer",
    goal="Turn researcher notes into a clean two-sentence summary.",
    backstory="You write clear, concise prose for a general audience.",
    llm=llm,
    allow_delegation=False,
    verbose=False,
)

research_task = Task(
    description=(
        "Explain why the ocean is salty. List the two primary mechanisms."
    ),
    expected_output="A short factual paragraph naming the two mechanisms.",
    agent=researcher,
)

writeup_task = Task(
    description=(
        "Using the researcher's notes, produce exactly two sentences "
        "for a general reader. No preamble."
    ),
    expected_output="Exactly two sentences, no headings.",
    agent=writer,
)

crew = Crew(
    agents=[researcher, writer],
    tasks=[research_task, writeup_task],
    verbose=False,
)

result = crew.kickoff()
print(result)

Expected output

Arize AX tracing initialized for CrewAI.
The ocean is salty because rivers continuously dissolve mineral salts from rocks and soil and carry them to the sea, where they accumulate over millions of years. Water leaves the ocean through evaporation but the salts remain, steadily concentrating until reaching today's roughly 3.5% salinity.

Verify in Arize AX

  1. Open your Arize AX space and select project crewai-tracing-example.
  2. You should see a new trace within ~30 seconds with this shape: a Crew_<uuid>.kickoff root span (CHAIN) wraps Crew Created, per-agent <role>._execute_core (AGENT), and per-task Task Created / Task Execution spans. Each task’s Task Execution wraps a ChatCompletion LLM span (model gpt-5-2025-08-07, with prompt, response, and token usage attached).
  3. If no traces appear, see Troubleshooting.

Troubleshooting

  • No traces in Arize AX. Confirm ARIZE_SPACE_ID and ARIZE_API_KEY are set in the same shell that runs example.py. Enable OpenTelemetry debug logs with export OTEL_LOG_LEVEL=debug and re-run.
  • Crew / Agent / Task spans appear but no LLM spans. The LLM-level instrumentor doesn’t match the provider CrewAI is calling. CrewAI 1.0+ routes by model-string prefix:
    • openai/<model> (or no prefix) → install openinference-instrumentation-openai
    • anthropic/<model> → install openinference-instrumentation-anthropic
    • Groq / Together / providers without a native CrewAI SDK → install openinference-instrumentation-litellm (CrewAI falls back to LiteLLM for these)
  • All spans missing — no Crew, no LLM. This is almost always import order. CrewAIInstrumentor().instrument(...) and the LLM-level instrumentor both monkey-patch class methods or module functions; if crewai (or the LLM library) is imported before instrument() runs, the patches land on stale references and never fire. Make sure instrumentation.py is the first import in your entry point — and watch for transitive imports (importing your own crew.py module that has from crewai import ... at the top has the same effect).
  • 401 from OpenAI. Verify OPENAI_API_KEY is set and has access to gpt-5. Swap openai/gpt-5 in LLM(model=...) for a model your key can call.
  • Version-check error from CrewAIInstrumentor. If you’re on a CrewAI release candidate that’s outside the instrumentor’s supported range, escape-hatch with CrewAIInstrumentor().instrument(skip_dep_check=True, tracer_provider=tracer_provider).
  • You’re on CrewAI 0.x. 0.x routes every LLM call through LangChain or LiteLLM rather than provider-native SDKs. Pair the CrewAI instrumentor with both openinference-instrumentation-langchain and openinference-instrumentation-litellm instead of openinference-instrumentation-openai. The Setup tracing call list becomes CrewAIInstrumentor().instrument(...) + LangChainInstrumentor().instrument(...) + LiteLLMInstrumentor().instrument(...). Upgrade to 1.0+ when you can — the LiteLLM removal guide covers the migration.

Resources

CrewAI Documentation

CrewAI LLM Provider Routing

OpenInference CrewAI Instrumentor

CrewAI GitHub