End-to-end recipes for the most common patterns.
Run a crew once per input set; each input becomes its own Execution, grouped by a shared batch_id.
crew = RcrewAI::Rails::Crew.find_by(name: "research_team")
result = crew.execute_batch_sync([
{ topic: "AI in healthcare" },
{ topic: "AI in finance" }
])
result[:batch_id] # shared id for the batch
crew.batch_executions(result[:batch_id]) # the two Executions, in order
Validate and transform a task's output with a host class.
class JsonGuardrail
# Must return [ok, value_or_error]
def validate(output)
parsed = JSON.parse(output)
[true, parsed]
rescue JSON::ParserError => e
[false, "Invalid JSON: #{e.message}"]
end
end
task = crew.tasks.create!(
description: "Return the result as JSON",
expected_output: "A JSON object",
guardrail_class: "JsonGuardrail",
guardrail_method_name: "validate",
guardrail_max_retries: 3
)
Give an agent reference material to draw on.
agent = crew.agents.create!(name: "analyst", role: "Analyst", goal: "Answer from the docs")
agent.knowledge_sources.create!(source_type: "pdf", value: Rails.root.join("docs/handbook.pdf").to_s)
agent.knowledge_sources.create!(source_type: "url", value: "https://example.com/reference")
# Sources are embedded lazily when the crew runs.
Flow subclasses live in your app; the engine persists state and tracks runs.
class OnboardingFlow < RCrewAI::Flow
start :greet
def greet
state.step = "greeted"
end
end
run = RcrewAI::Rails::FlowRun.execute(OnboardingFlow, inputs: { user_id: 42 })
run.status # "completed"
run.result # { "step" => "greeted", ... }
Have multiple agents propose and vote on each task's answer.
crew = RcrewAI::Rails::Crew.create!( name: "review_board", process_type: "consensual", consensus_agents: 3 ) # add agents + tasks as usual, then: crew.execute_sync