CrewAICrewAI 1.15 · Python 3.10 to 3.13
Dashboard
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
35 small wins to finish your pathNext lesson →

Inputs: one crew, many tickets

Inputs are the values kickoff fills into a task's placeholders, so one crew answers any ticket.

Last updated: 28 Sep, 2026 · CrewAI 1.15

The agent-prompt lesson showed the task's text becoming the user message. The first-crew lesson's task had the question typed into it; a support desk needs the same crew for every ticket, so the question becomes a placeholder.

Project files used on this pageThis lesson builds on a project from earlier lessons. The code below imports this file. Click a file to see its code, or follow the link to the lesson that wrote it. To run the code yourself, keep it in the same folder.
View the code here
shop_llm.py
import os
import re

from crewai import BaseLLM

os.environ["CREWAI_DISABLE_TELEMETRY"] = "true"
os.environ["CREWAI_TRACING_ENABLED"] = "false"
os.environ["CREWAI_DISABLE_VERSION_CHECK"] = "true"


class ShopLLM(BaseLLM):
    def call(self, messages, tools=None, **kwargs):
        if isinstance(messages, str):
            messages = [{"role": "user", "content": messages}]
        text = messages[-1]["content"]
        orders = re.findall(r"\b[A-Z]\d+\b", text)
        if orders:
            return f"I have no way to look up {orders[0]} yet."
        return "Hello. Which order is this about?"

A task with a placeholder

python
from crewai import Agent, Crew, Task
from shop_llm import ShopLLM

agent = Agent(
    role="Support agent",
    goal="Answer customers of a small online shop",
    backstory="You have worked the shop's support desk for years.",
    llm=ShopLLM(model="shop"),
)
task = Task(
    description="Answer the customer: {question}",
    expected_output="One short, friendly sentence.",
    agent=agent,
)
crew = Crew(agents=[agent], tasks=[task])

The description now contains {question}, a placeholder in curly braces. The agent is the one from the first-crew lesson.

Filling the placeholder

Example
result = crew.kickoff(inputs={"question": "Where is my order A17?"})
print(result.raw)

inputs is a dictionary. Before the crew runs, CrewAI puts each value in place of the placeholder with the same name, in task descriptions, expected outputs and the agent's role, goal and backstory.

Reporting a missing placeholder

Example
crew.kickoff(inputs={"q": "Where is my order A17?"})

A placeholder with no value in inputs stops the run before any model is called, and the error names the missing variable. Calling kickoff() with no inputs at all is different: nothing is filled in, and the agent is asked about the literal text {question}.

Running many tickets

Example
tickets = [
    {"question": "Where is my order A17?"},
    {"question": "Hello, can you help me?"},
]
for result in crew.kickoff_for_each(inputs=tickets):
    print(result.raw)

kickoff_for_each runs the crew once per dictionary and returns the results in the same order. The first ticket names an order; the second does not, so the model asks which one.

Reading the two runs

  • inputs is a dictionary; each value replaces the placeholder of the same name before the crew runs.
  • A missing name stops the run early, naming the variable, before any model is called.
  • kickoff_for_each runs once per ticket and returns the results in the same order.

kickoff vs kickoff_for_each

MethodRunsReturns
kickoff(inputs=...)onceone CrewOutput
kickoff_for_each(inputs=[...])once per dictionarya list of CrewOutputs

When placeholders pay off

  • One crew has to answer many tickets that differ only in their text.
  • You run a batch of inputs and want each result kept separate.
  • The same value belongs in more than one field, such as the goal and the task.
Watch out
Calling kickoff() with no inputs does not error; the literal text {question} is sent to the model. A wrong key does error and names the variable it could not fill.
Try it yourself
  • Put {question} in the agent's goal as well and run the first example.
  • Add a third ticket about C40 to the list.
  • Call crew.kickoff() with no inputs, then print task.description.

Little by little, you're building something great.