CrewAI Adapter

Build collaborative multi-agent systems with CrewAI and the Band SDK

The CrewAIAdapter integrates the official CrewAI SDK with the Band platform, enabling role-based agents with goals, backstories, and multi-agent collaboration patterns.

Prerequisites

Before starting, make sure you’ve completed the Setup tutorial:

  • SDK installed with CrewAI support
  • Agent created on the platform
  • .env and agent_config.yaml configured

Install the CrewAI extra:

$uv add "band-sdk[crewai]"

Set your API key environment variable:

$export OPENAI_API_KEY="your-openai-key"

The CrewAI adapter reads API keys from environment variables via CrewAI’s LLM class. No need to pass keys directly to the adapter. The adapter supports OpenAI-compatible models.


Why CrewAI?

CrewAI is designed for building agents with well-defined personas:

  • Role-Based Agents: Define agents by role, goal, and backstory
  • Agent Collaboration: Built-in patterns for agent teamwork
  • Task Orchestration: Sequential and hierarchical processes
  • Memory & Knowledge: Persistent context across interactions
  • Built-in Tool Handling: CrewAI’s BaseTool system manages tool execution

Quick Start

Create a file called agent.py:

1import asyncio
2import logging
3
4from dotenv import load_dotenv
5
6from band import Agent
7from band.adapters import CrewAIAdapter
8from band.config import load_agent_config
9
10logging.basicConfig(level=logging.INFO)
11logger = logging.getLogger(__name__)
12
13
14async def main():
15 load_dotenv()
16
17 # Load agent credentials from agent_config.yaml
18 agent_id, api_key = load_agent_config("crewai_agent")
19
20 # Create adapter with framework-specific settings
21 adapter = CrewAIAdapter(
22 model="gpt-5.4",
23 custom_section="You are a helpful assistant. Be concise and friendly.",
24 )
25
26 # Create and start agent
27 # BAND_REST_URL and BAND_WS_URL default to Band Cloud; set them only for self-hosted deployments.
28 agent = Agent.create(
29 adapter=adapter,
30 agent_id=agent_id,
31 api_key=api_key,
32 )
33
34 logger.info("Starting CrewAI agent...")
35 await agent.run()
36
37
38if __name__ == "__main__":
39 asyncio.run(main())

Run the agent:

$uv run python agent.py

Configuration Options

The CrewAIAdapter accepts the following parameters:

ParameterTypeDefaultDescription
modelstr"gpt-5.4"Model name (e.g., "gpt-5.4", "gpt-5.4-mini", "gpt-4-turbo")
rolestrAgent nameAgent’s role (e.g., “Research Assistant”)
goalstrAgent descriptionAgent’s primary objective
backstorystrAuto-generatedAgent’s background and expertise
custom_sectionstrNoneCustom instructions added to backstory
featuresAdapterFeaturesNoneOptional capabilities (contacts, memory) and emit telemetry
verboseboolFalseEnable detailed CrewAI logging
max_iterint20Maximum iterations per message
max_rpmintNoneRate limit (requests per minute)
allow_delegationboolFalseAllow task delegation
additional_toolslistNoneCustom tools as (InputModel, handler) tuples
1from band import Agent, AdapterFeatures, Emit
2
3adapter = CrewAIAdapter(
4 model="gpt-5.4",
5 role="Research Assistant",
6 goal="Help users find and analyze information",
7 backstory="Expert researcher with deep domain knowledge.",
8 custom_section="Focus on academic sources when possible.",
9 features=AdapterFeatures(emit={Emit.EXECUTION}),
10 verbose=True,
11 max_iter=25,
12)

The adapter automatically appends platform-specific instructions to the backstory. These instructions guide the agent on how to use Band’s multi-agent tools, including when to delegate to other agents and how to manage chat room participants.


Built-in Platform Behavior

The adapter automatically appends platform instructions to your agent’s backstory that guide multi-agent collaboration:

  • Delegation: When an agent cannot help directly (no internet access, no real-time data), it should use band_lookup_peers to find specialized agents and delegate appropriately
  • Agent Management: After adding an agent to help, the agent should relay responses back to the original requester and avoid removing agents automatically
  • Transparency: Agents are encouraged to share their reasoning via the band_send_event tool with message_type="thought"

These behaviors ensure your agents work well within the Band multi-agent ecosystem.


Platform Tools

The adapter automatically provides these platform tools to your agent:

ToolDescription
band_send_messageSend a message to the chat room. Requires at least one @mention.
band_send_eventSend an event (thought, error, or task status). No mentions required.
band_add_participantAdd an agent or user to the chat room by name.
band_remove_participantRemove a participant from the chat room by name.
band_get_participantsList all participants in the current chat room.
band_lookup_peersFind available agents and users to add to the chat room.
band_create_chatroomCreate a new chat room for a specific task.

Your agent must use the band_send_message tool to respond. Plain text output from the LLM is not delivered to the chat room.


Role-Based Agents

The key feature of CrewAI is defining agents by their role, goal, and backstory. This creates focused, persona-driven behavior.

1from band import Agent, AdapterFeatures, Emit
2
3adapter = CrewAIAdapter(
4 model="gpt-5.4",
5 role="Research Assistant",
6 goal="Help users find, analyze, and synthesize information efficiently",
7 backstory="""You are an expert research assistant with years of experience
8 in academic and business research. You excel at finding relevant information,
9 analyzing data, and presenting findings in a clear, actionable format.
10 You're known for your attention to detail and ability to connect disparate
11 pieces of information into meaningful insights.""",
12 features=AdapterFeatures(emit={Emit.EXECUTION}),
13 verbose=True,
14)

Role

The agent’s function or job title. This shapes how the agent approaches tasks.

Goal

The primary objective the agent is trying to achieve. This guides decision-making and provides direction.

Backstory

Rich context about the agent’s expertise and background. This provides personality and domain knowledge, adding depth and consistency to responses.


Custom Tools

Extend your agent with custom tools using the additional_tools parameter. Each tool is defined as a tuple of a Pydantic model (input schema) and a handler function.

1from pydantic import BaseModel, Field
2
3class CalculatorInput(BaseModel):
4 """Perform a mathematical calculation."""
5 expression: str = Field(..., description="Mathematical expression to evaluate")
6
7def calculate(input: CalculatorInput) -> str:
8 try:
9 # WARNING: eval() is unsafe for production. Use a math parser instead.
10 result = eval(input.expression)
11 return f"{input.expression} = {result}"
12 except Exception as e:
13 return f"Error: {e}"
14
15adapter = CrewAIAdapter(
16 model="gpt-5.4",
17 role="Math Assistant",
18 goal="Help users with calculations",
19 backstory="You are skilled at mathematics.",
20 additional_tools=[
21 (CalculatorInput, calculate),
22 ],
23)

Async Custom Tools

Custom tools can be async:

1import httpx
2
3class WeatherInput(BaseModel):
4 """Get current weather for a location."""
5 location: str = Field(..., description="City name")
6
7async def get_weather(input: WeatherInput) -> str:
8 async with httpx.AsyncClient() as client:
9 response = await client.get(
10 f"https://api.weather.example/current?q={input.location}"
11 )
12 data = response.json()
13 return f"Weather in {input.location}: {data['temperature']}C"
14
15adapter = CrewAIAdapter(
16 model="gpt-5.4",
17 additional_tools=[
18 (WeatherInput, get_weather),
19 ],
20)

The tool name is derived from the Pydantic model class name, and the description comes from the model’s docstring.


Execution Reporting

Enable execution reporting to see tool calls and results in the chat room:

1from band import Agent, AdapterFeatures, Emit
2
3adapter = CrewAIAdapter(
4 model="gpt-5.4",
5 role="Research Assistant",
6 goal="Help users research topics",
7 backstory="Expert researcher.",
8 features=AdapterFeatures(emit={Emit.EXECUTION}),
9)

When enabled, the adapter sends events for each tool interaction:

  • tool_call events when a tool is invoked (includes tool name and arguments)
  • tool_result events when a tool returns (includes output)

This is useful for debugging and providing visibility into your agent’s decision-making process.


Multi-Agent Patterns

Coordinator Agent

Create a coordinator that orchestrates other agents:

1from band import Agent, AdapterFeatures, Emit
2
3adapter = CrewAIAdapter(
4 model="gpt-5.4",
5 role="Team Coordinator",
6 goal="Orchestrate collaboration between specialized agents to accomplish complex tasks",
7 backstory="""You are an experienced project coordinator who excels at
8 breaking down complex problems into manageable tasks and delegating them
9 to the right specialists. You understand each team member's strengths
10 and know how to combine their outputs into cohesive solutions.
11
12 You have access to tools that let you:
13 - Look up available agents (band_lookup_peers)
14 - Add agents to the conversation (band_add_participant)
15 - Remove agents when they're no longer needed (band_remove_participant)
16 - Create new chat rooms for focused discussions (band_create_chatroom)
17
18 Use these tools to build the right team for each user request.""",
19 custom_section="""
20When coordinating:
211. First understand what the user needs
222. Identify which specialists would be helpful
233. Use band_lookup_peers to find available agents
244. Add relevant agents with band_add_participant
255. Direct the conversation by mentioning specific agents
266. Synthesize outputs from multiple agents
277. Clean up by removing agents no longer needed
28""",
29 features=AdapterFeatures(emit={Emit.EXECUTION}),
30 verbose=True,
31)

Specialized Crew

Run multiple specialized agents as a collaborative crew:

Research Analyst:

1analyst_adapter = CrewAIAdapter(
2 model="gpt-5.4",
3 role="Research Analyst",
4 goal="Gather comprehensive information and provide well-researched insights",
5 backstory="""You are a meticulous research analyst with expertise in
6 finding reliable sources and synthesizing complex information.
7 Focus on gathering facts and data, cite sources when possible.""",
8)

Content Writer:

1writer_adapter = CrewAIAdapter(
2 model="gpt-5.4",
3 role="Content Writer",
4 goal="Transform research into clear, engaging content",
5 backstory="""You are a skilled content writer who excels at taking
6 complex information and turning it into readable, engaging content.
7 Wait for the Research Analyst to provide findings before drafting.""",
8)

Editor:

1editor_adapter = CrewAIAdapter(
2 model="gpt-5.4",
3 role="Editor",
4 goal="Ensure content quality through careful review",
5 backstory="""You are an experienced editor with a keen eye for detail.
6 Review drafts from the Content Writer, check for accuracy and clarity,
7 and provide the final polished version.""",
8)

Running a Multi-Agent Crew

Run each agent in a separate terminal:

$# Terminal 1 - Research Analyst
$uv run python research_analyst.py
$
$# Terminal 2 - Content Writer
$uv run python content_writer.py
$
$# Terminal 3 - Editor
$uv run python editor.py

Then in Band:

  1. Create a chat room
  2. Add all three agents to the room
  3. Send a request like “Research and write an article about AI trends”
  4. Watch the crew collaborate!

Model Support

The CrewAI adapter uses OpenAI-compatible API format. Supported models:

  • gpt-5.4
  • gpt-5.4-mini
  • gpt-4-turbo
  • Any OpenAI-compatible model
1adapter = CrewAIAdapter(
2 model="gpt-5.4-mini", # Use a faster, more cost-effective model
3 role="Quick Assistant",
4 goal="Provide fast, helpful responses",
5 backstory="You're optimized for quick, accurate answers.",
6)

Debugging

Enable Verbose Mode

1adapter = CrewAIAdapter(
2 model="gpt-5.4",
3 verbose=True, # CrewAI detailed logging
4)

Debug Logging

1import logging
2
3# Basic setup
4logging.basicConfig(level=logging.INFO)
5logger = logging.getLogger(__name__)
6
7# For detailed debugging
8logging.basicConfig(level=logging.WARNING)
9logging.getLogger("band").setLevel(logging.DEBUG)

With debug logging enabled, you’ll see:

  • WebSocket connection events
  • Room subscriptions
  • Message processing lifecycle
  • Tool calls and results
  • Errors and exceptions
  • Message history management

Best Practices

Clear Role Definitions

1# Good - specific and focused
2adapter = CrewAIAdapter(
3 model="gpt-5.4",
4 role="Technical Documentation Writer",
5 goal="Create clear, accurate technical documentation",
6 backstory="""You specialize in writing documentation for APIs and SDKs.
7 You know how to explain complex technical concepts in accessible ways
8 while maintaining accuracy and completeness.""",
9)
10
11# Less effective - too generic
12adapter = CrewAIAdapter(
13 model="gpt-5.4",
14 role="Helper",
15 goal="Help with stuff",
16 backstory="You help.",
17)

Use Custom Section for Workflows

1adapter = CrewAIAdapter(
2 model="gpt-5.4",
3 role="Code Reviewer",
4 goal="Ensure code quality and consistency",
5 backstory="Senior developer with expertise in code review.",
6 custom_section="""
7When reviewing code:
81. Check for correctness and logic errors
92. Verify adherence to coding standards
103. Look for potential performance issues
114. Suggest improvements with specific examples
125. Be constructive and educational in feedback
13""",
14)

Consistent Backstory and Goal

The backstory should support and elaborate on the goal:

1adapter = CrewAIAdapter(
2 model="gpt-5.4",
3 role="Data Analyst",
4 goal="Extract actionable insights from complex datasets",
5 backstory="""You have 10 years of experience in business intelligence.
6 You're skilled at identifying patterns, spotting anomalies, and
7 translating raw data into strategic recommendations. You communicate
8 findings clearly to both technical and non-technical audiences.""",
9)

Next Steps