Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions python/tracing/crewai/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
RESPAN_API_KEY=your-api-key-here
RESPAN_API_KEY=your-respan-api-key
RESPAN_BASE_URL=https://api.respan.ai/api
OPENAI_API_KEY=your-api-key-here
RESPAN_MODEL=gpt-4o-mini
50 changes: 50 additions & 0 deletions python/tracing/crewai/01_basic_crew.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""Basic CrewAI run with Respan tracing and gateway routing."""

from respan import workflow

from _shared import build_llm, create_respan, print_result, result_text, run_with_attributes

WORKFLOW_NAME = "crewai_01_basic_crew"


@workflow(name=WORKFLOW_NAME)
def run_basic_crew(context) -> str:
from crewai import Agent, Crew, Process, Task

llm = build_llm(context.settings)
researcher = Agent(
role="AI Researcher",
goal="Explain CrewAI and Respan in one practical paragraph",
backstory="You write concise technical explanations for Python developers.",
llm=llm,
verbose=False,
)
task = Task(
description="Explain how CrewAI and Respan work together for tracing.",
expected_output="One concise paragraph for Python developers.",
agent=researcher,
)
crew = Crew(
agents=[researcher],
tasks=[task],
process=Process.sequential,
verbose=False,
)
return result_text(crew.kickoff())


def main() -> None:
context = create_respan(
app_name="crewai-01-basic-crew",
example_name="01_basic_crew",
workflow_name=WORKFLOW_NAME,
)
output = run_with_attributes(context, lambda: run_basic_crew(context))
print_result("Crew output", output)
print_result("Workflow name", WORKFLOW_NAME)
print_result("Example run id", context.run_id)
context.respan.flush()


if __name__ == "__main__":
main()
78 changes: 78 additions & 0 deletions python/tracing/crewai/02_tool_use.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"""CrewAI tool-use example with Respan tracing."""

from respan import workflow

from _shared import build_llm, create_respan, print_result, result_text, run_with_attributes

WORKFLOW_NAME = "crewai_02_tool_use"


def lookup_city_weather(city: str) -> str:
"""Look up deterministic weather for a city."""
weather = {
"Paris": "Sunny, 22C",
"Tokyo": "Cloudy, 18C",
"New York": "Clear, 20C",
}
return weather.get(city, "Mild, 21C")


def lookup_city_population(city: str) -> str:
"""Look up deterministic population data for a city."""
populations = {
"Paris": "about 2.1 million people",
"Tokyo": "about 14 million people",
"New York": "about 8.3 million people",
}
return populations.get(city, "unknown population")


@workflow(name=WORKFLOW_NAME)
def run_tool_crew(context) -> str:
from crewai import Agent, Crew, Process, Task
from crewai.tools import tool

weather_tool = tool("lookup_city_weather")(lookup_city_weather)
population_tool = tool("lookup_city_population")(lookup_city_population)
llm = build_llm(context.settings)

researcher = Agent(
role="City Researcher",
goal="Use tools to gather city facts before answering",
backstory="You collect factual city details using available tools.",
tools=[weather_tool, population_tool],
llm=llm,
verbose=False,
)
task = Task(
description=(
"Research the weather and population for Paris, then summarize the "
"result in two short bullets. Use the provided tools."
),
expected_output="Two short bullets with weather and population details.",
agent=researcher,
)
crew = Crew(
agents=[researcher],
tasks=[task],
process=Process.sequential,
verbose=False,
)
return result_text(crew.kickoff())


def main() -> None:
context = create_respan(
app_name="crewai-02-tool-use",
example_name="02_tool_use",
workflow_name=WORKFLOW_NAME,
)
output = run_with_attributes(context, lambda: run_tool_crew(context))
print_result("Crew output", output)
print_result("Workflow name", WORKFLOW_NAME)
print_result("Example run id", context.run_id)
context.respan.flush()


if __name__ == "__main__":
main()
54 changes: 54 additions & 0 deletions python/tracing/crewai/03_attributes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""CrewAI example that attaches user, thread, and metadata attributes."""

from respan import workflow

from _shared import build_llm, create_respan, print_result, result_text, run_with_attributes

WORKFLOW_NAME = "crewai_03_attributes"


@workflow(name=WORKFLOW_NAME)
def run_attribute_crew(context) -> str:
from crewai import Agent, Crew, Process, Task

llm = build_llm(context.settings)
analyst = Agent(
role="Support Analyst",
goal="Classify a support request and suggest the next action",
backstory="You help support teams triage incoming tickets quickly.",
llm=llm,
verbose=False,
)
task = Task(
description=(
"A customer says: 'The dashboard loads slowly after I add a new "
"integration.' Classify the issue and suggest one next action."
),
expected_output="A category and one recommended next action.",
agent=analyst,
)
crew = Crew(
agents=[analyst],
tasks=[task],
process=Process.sequential,
verbose=False,
)
return result_text(crew.kickoff())


def main() -> None:
context = create_respan(
app_name="crewai-03-attributes",
example_name="03_attributes",
workflow_name=WORKFLOW_NAME,
metadata={"scenario": "support_triage"},
)
output = run_with_attributes(context, lambda: run_attribute_crew(context))
print_result("Crew output", output)
print_result("Workflow name", WORKFLOW_NAME)
print_result("Example run id", context.run_id)
context.respan.flush()


if __name__ == "__main__":
main()
55 changes: 55 additions & 0 deletions python/tracing/crewai/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# CrewAI Respan Integration Examples

These examples demonstrate CrewAI tracing with `respan-instrumentation-crewai`.
They initialize Respan before importing CrewAI, route OpenAI-compatible LLM calls
through the Respan gateway, and attach stable workflow metadata so each run is
easy to find in Respan.

## Setup

Install dependencies:

```bash
cd python/tracing/crewai
pip install -r requirements.txt
```

Use the repository root `.env` file. At minimum it should include:

```bash
RESPAN_API_KEY=your-respan-api-key
RESPAN_BASE_URL=https://api.respan.ai/api
```

`RESPAN_MODEL` is optional and defaults to `gpt-4o-mini`. The examples set
`OPENAI_API_KEY` and `OPENAI_BASE_URL` from the Respan values at runtime, so a
separate provider key is not required when using the Respan gateway.

## Examples

| Example | Workflow name | Description |
| --- | --- | --- |
| `01_basic_crew.py` | `crewai_01_basic_crew` | Single-agent CrewAI task with Respan tracing |
| `02_tool_use.py` | `crewai_02_tool_use` | CrewAI agent using deterministic Python tools |
| `03_attributes.py` | `crewai_03_attributes` | CrewAI task with customer, thread, and metadata attributes |

Run one example:

```bash
python 01_basic_crew.py
```

Run the full set in isolated Python processes:

```bash
python run_all.py
```

Each script prints its workflow name and `RESPAN_EXAMPLE_RUN_ID`. Use those
values to find the corresponding spans in Respan.

## Further reading

- [respan-instrumentation-crewai](https://pypi.org/project/respan-instrumentation-crewai/)
- [respan-ai](https://pypi.org/project/respan-ai/)
- [CrewAI documentation](https://docs.crewai.com/)
Loading