To install crewai first crew n4n.ai, you need a Python 3.10+ environment and a gateway API key. This guide builds a minimal two-agent research-and-write crew that talks to an OpenAI-compatible inference endpoint, and shows exactly how to verify the run succeeded. We skip the toy examples and use a configuration that survives contact with real pipelines.
Step 1: Create an isolated environment
CrewAI pulls a wide dependency tree, including litellm, pydantic, and often pandas or numpy transitive imports. Running it in a clean venv avoids clobbering system packages and makes reproducibility auditable.
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
If you are on Windows, use .venv\Scripts\activate. Confirm the interpreter with which python (or where python). Do not use sudo pip install—that defeats the isolation and will break when CrewAI pins a conflicting pydantic version.
Step 2: Install CrewAI and lock the version
The core package is crewai. The crewai[tools] extra adds file and web utilities, but for a first crew you do not need them and they drag in heavy optional deps. Pin a minor version to avoid surprise breaking changes across the rapid release cadence.
pip install crewai==0.28.0
At the time of writing, CrewAI’s programmatic API is stable but the CLI (crewai create) scaffolds opinionated project layouts that hide the mechanics. We use the library directly. Verify the import before writing agents:
from crewai import Agent, Task, Crew, LLM
print("crewai imported")
If that raises ModuleNotFoundError, your venv is not active or the install failed. Run pip show crewai to confirm the installed location matches your venv path.
Step 3: Point the LLM at the gateway
CrewAI delegates model calls to litellm, which speaks the OpenAI client protocol. We will route through n4n.ai, an OpenAI-compatible gateway that exposes one endpoint covering 240+ models and automatically falls back when a provider is rate-limited or degraded. Set the base URL and key via environment variables so they never hit your source tree.
export OPENAI_API_KEY="sk-your-n4n-gateway-key"
export OPENAI_API_BASE="https://api.n4n.ai/v1"
In code, instantiate the LLM with an explicit model slug. The slug format is provider/model because litellm interprets it. For a cheap, fast default use a small OpenAI model; the gateway forwards cache-control hints and meters per token without extra client config.
import os
from crewai import LLM
llm = LLM(
model="openai/gpt-4o-mini",
api_key=os.environ["OPENAI_API_KEY"],
base_url=os.environ["OPENAI_API_BASE"],
temperature=0.2,
timeout=60,
)
If you omit base_url, CrewAI hits OpenAI directly. For this walkthrough the gateway is mandatory because we rely on its single-endpoint model routing. The temperature=0.2 keeps outputs deterministic enough for tests; raise it later for creative tasks.
Step 4: Define agents with narrow roles
Agents need a role, goal, and backstory. Keep allow_delegation=False on your first run; delegation spawns extra calls that obscure what actually happened and can loop. Set verbose=True to stream thoughts to stdout—without it, a silent failure looks identical to a slow network.
from crewai import Agent
researcher = Agent(
role="Senior Research Analyst",
goal="Find three concrete facts about vector databases",
backstory="You read papers and docs all day, and cite sources.",
llm=llm,
verbose=True,
allow_delegation=False,
)
writer = Agent(
role="Technical Writer",
goal="Turn research into a 100-word plain-English summary",
backstory="You write docs for backend engineers.",
llm=llm,
verbose=True,
allow_delegation=False,
)
The backstory is not flavor text—litellm packs it into the system prompt. A vague backstory yields vague tool use. Spend a sentence grounding the agent in a persona that matches the task.
Step 5: Define tasks and wire dependencies
Tasks reference an agent, a description, and an expected_output. CrewAI runs them in the order you pass to the crew, but you can also express context dependencies. We keep it linear so the writer receives the researcher’s exact bullet list.
from crewai import Task
research_task = Task(
description="Research vector databases. Identify three facts: a use case, a tradeoff, and a popular library.",
expected_output="Bullet list of three facts with one-line explanations.",
agent=researcher,
)
write_task = Task(
description="Using the research, write a 100-word summary for engineers new to vectors.",
expected_output="A concise paragraph under 120 words.",
agent=writer,
context=[research_task],
)
The context array feeds the first task’s output into the second. Without it, the writer guesses and you lose traceability. The expected_output string is used by the agent to self-check; make it specific or the model will ramble.
Step 6: Assemble and kick off the crew
The Crew object takes agents and tasks. Set process="sequential" explicitly; the default is sequential but being explicit prevents confusion when you later add parallelism with process="hierarchical".
from crewai import Crew
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task],
process="sequential",
verbose=True,
)
result = crew.kickoff()
print("CREW RESULT:", result.raw)
Run the file with python main.py. The first agent will call the gateway, the second will call it again. Expect roughly two LLM round-trips per agent plus internal parsing. If you need concurrency, crew.kickoff_async() exists but adds event-loop constraints—avoid it until the sequential path is green.
Step 7: Verify the run succeeded
Success is not just “no exception”. Check three things:
- Stdout shows agent reasoning – with
verbose=Trueyou should see> Entering new AgentExecutor chain...and tool/text logs. - The final
result.rawis non-empty and on-topic – if it isNoneor an error string, the second task failed silently. - Gateway usage registered – your inference gateway dashboard should show two distinct completions with token counts. Because the gateway meters per token, you can reconcile the spend against the model slug used.
A minimal assertion block:
assert result.raw, "Crew produced no output"
assert "vector" in result.raw.lower(), "Output missing expected topic"
print("Verification passed")
If assertions fail, raise CrewAI logging: export CREWAI_LOG_LEVEL=DEBUG. The debug log prints the exact payload sent to the LLM, which is the fastest way to spot a malformed base_url or missing api_key.
Step 8: Common pitfalls and fixes
Model slug not found. Litellm expects provider/model. If you pass gpt-4o-mini without openai/, the gateway may reject it. Prefix correctly.
Environment variable leakage. If OPENAI_API_BASE is set globally to OpenAI’s URL, your crew bypasses the gateway. Use a .env file with python-dotenv in real projects and load it before constructing the LLM.
Timeouts on long tasks. Default agent timeout is 60s. Research tasks that trigger web tools can exceed it. Bump timeout on the LLM and set max_retry_limit on agents to 3–5.
Hidden delegation loops. With allow_delegation=True, an agent can spin up sub-agents that call the LLM recursively. For a first crew, disable it. You can enable it later behind a unit test that caps total token spend.
Pydantic version conflicts. CrewAI 0.28.x requires pydantic v2. If you see TypeError: isinstance() arg 2 must be a type, you have a stray pydantic v1 install. Recreate the venv.
Step 9: Extend the skeleton
Swap the model slug to any of the 240+ available behind the same endpoint—no client change beyond the string. Add crewai[tools] and give the researcher a SerperDevTool for live search. For production, move the gateway key to a secrets manager and set base_url from config, not env shells.
The install crewai first crew n4n.ai workflow is now reproducible: venv, pin, point LLM, define narrow agents, link tasks, kick off, assert. That is the whole skeleton; everything else is prompt engineering and tool wiring.