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

# CrewAI

> Evaluate a CrewAI crew

Install:

```bash theme={null}
pip install agentx-python crewai
```

## Usage

```python theme={null}
from agentx import AgentX
from crewai import Agent, Task, Crew

client = AgentX.from_env()

support_agent = Agent(
    role="Support Specialist",
    goal="Resolve customer questions accurately and concisely",
    backstory="You are an experienced customer support specialist.",
)

def crewai_agent(case):
    task = Task(
        description=case.query,
        expected_output="A clear, accurate answer to the customer's question.",
        agent=support_agent,
    )
    crew = Crew(agents=[support_agent], tasks=[task])
    result = crew.kickoff()
    return {"output": str(result)}

run_context = (
    client.evaluations
    .run(dataset_id="...", subject={"kind": "custom_agent", "displayName": "Support Crew", "framework": "crewai"})
    .execute(crewai_agent)
    .finalize()
)
print(f"Average rating: {run_context.average_rating:.2f}")
```

## With tracing

Use [`AgentXCrewObserver`](/sdk/integrations/crewai) to get a full Execution Timeline per result. Its `observer.kickoff(...)` convenience wrapper is fire-and-forget and can't return a `trace_id`. Use `observer.observe(sync=True)` instead, which blocks until the trace is ingested:

```python theme={null}
from agentx import AgentX
from agentx.integrations.crewai import AgentXCrewObserver
from crewai import Agent, Task, Crew

client = AgentX.from_env()
observer = AgentXCrewObserver(client.tracer, name="support-crew")

support_agent = Agent(
    role="Support Specialist",
    goal="Resolve customer questions accurately and concisely",
    backstory="You are an experienced customer support specialist.",
)

def crewai_agent(case):
    task = Task(
        description=case.query,
        expected_output="A clear, accurate answer to the customer's question.",
        agent=support_agent,
    )
    crew = Crew(agents=[support_agent], tasks=[task])

    with observer.observe(input={"query": case.query}, sync=True, monitor=False) as span:
        result = crew.kickoff()
        span.output = str(result)

    return {"output": str(result), "trace_id": span.trace_id}
```

<Note>
  `observer.observe()` doesn't auto-populate per-task tool calls the way `kickoff()` does. Record them yourself with `span.add_tool_call(...)` if you need that detail. See the [CrewAI tracing integration](/sdk/integrations/crewai) for the full comparison.
</Note>

A complete working example is available as [`crewai_eval.py`](https://github.com/AgentX-ai/AgentX-Python/blob/main/examples/evaluations/crewai_eval.py) in the AgentX-Python repository.
