Skip to content
/

Multi-agent crews

Your first crewChapter 8 of 144 min read

Coordinate three specialized agents into a sequential pipeline: one extracts key terms, one evaluates financial risks, and one audits the final memo against the source agreement.


The review team#

Drawing diagram…
InputAgentResultData flows sequentially between agents; dashed lines indicate file reads.

The pipeline separates extraction, evaluation, and verification:

  1. Contract analyst: Extracts commercial terms line by line, citing exact section numbers.
  1. Risk analyst: Analyzes extracted terms from the buyer's perspective and drafts a risk memo.
  1. Fact-checker: Audits every citation, number, and date against the original contract text.

Build the crew#

Implement the multi-agent pipeline in review_crew.py:

review_crew.py
# review_crew.py

from crewai import Agent, Crew, Process, Task
from crewai_tools import FileReadTool
from dotenv import load_dotenv

load_dotenv()

read_file = FileReadTool()

# agents

reader = Agent(
    role="Contract analyst",
    goal="Pull every commercially important term out of a contract, with its section number",
    backstory=(
        "You read contracts line by line for a procurement team. You quote "
        "the contract rather than paraphrase it, and you always note the "
        "section a term comes from."
    ),
    tools=[read_file],
    verbose=True,
)

risk_analyst = Agent(
    role="Commercial risk analyst",
    goal="Spot the deadlines, costs, and one-sided terms that could hurt {customer}",
    backstory=(
        "You have reviewed hundreds of software agreements from the buyer's "
        "side. You know which clauses cost customers money: automatic "
        "renewals, price increases, short claim windows, and terms the "
        "vendor can change on its own."
    ),
    verbose=True,
)

fact_checker = Agent(
    role="Contract fact-checker",
    goal="Make sure every claim in a contract memo matches the contract word for word",
    backstory=(
        "You are the last reviewer before a memo goes to the finance team. "
        "You check every number, date, and section reference against the "
        "source document and fix anything that does not match."
    ),
    tools=[read_file],
    verbose=True,
)

# tasks

extract_terms = Task(
    description=(
        "Read the contract at {contract_path}. List its key terms: parties, "
        "dates, term and renewal, fees and payment, service levels, data "
        "handling, termination, liability, and any clause that lets one "
        "party change the deal on its own."
    ),
    expected_output="A bulleted list of key terms. Each bullet quotes the contract and ends with its section number.",
    agent=reader,
)

assess_risks = Task(
    description=(
        "Using the key terms, write a risk memo for {customer}. Pick the five "
        "terms most likely to cost them money or catch them out, and say what "
        "they should do about each one."
    ),
    expected_output=(
        "A Markdown memo of no more than 350 words: a two-sentence summary, then "
        "a numbered list of five risks. Each risk has a section number, why it "
        "matters, and a recommended action."
    ),
    agent=risk_analyst,
)

fact_check = Task(
    description=(
        "Check every claim in the risk memo against the contract at {contract_path}. "
        "Fix any number, date, or section reference that does not match the "
        "contract, and remove anything the contract does not say."
    ),
    expected_output="The corrected memo in Markdown, followed by a 'Corrections' section that lists each change you made, or says 'None'.",
    agent=fact_checker,
)

crew = Crew(
    agents=[reader, risk_analyst, fact_checker],
    tasks=[extract_terms, assess_risks, fact_check],
    process=Process.sequential,
    verbose=True,
)

if __name__ == "__main__":
    result = crew.kickoff(
        inputs={
            "contract_path": "contracts/acme-saas-agreement.md",
            "customer": "Northwind Traders",
        }
    )
    print(result.raw)

Architecture highlights:

  1. Dynamic variables: Placeholders like {customer} resolve across both agent goals and task descriptions.
  1. Selective tool provisioning: Only reader and fact_checker receive read_file; the risk_analyst operates strictly on intermediate context.
  1. Sequential pipeline: Process.sequential chains tasks in declaration order, passing each output to the subsequent agent.

Run the crew#

Execute the multi-agent pipeline:

Terminal
(env)$ python review_crew.py

Review the final memo and corrections section:

Output
### 5. Limited Liability Cap (Section 7.1)Why it matters: Acme Analytics' liability is capped at the fees paid in the 12 monthsbefore a claim—meaning if the service fails catastrophically (e.g., data breach, systemcollapse), Northwind Traders is limited to $18,000 in damages, regardless of actuallosses....
Corrections:- None. All claims in the memo match the contract word for word.

The crew correctly flags the $18,000 liability cap. However, notice that the fact-checker reports "Corrections: None" despite potential date and calculation risks. In later chapters, you reinforce validation with deterministic Python tools.