Build an AI Corporate Legal Adviser
Orchestrate 3 AI agents with CrewAI and Gemini to analyze legal scenarios.
Introduction
30 Second Summary
When a company faces a legal question, it rarely goes to one person. A team of specialists researches the law, analyzes the risks, and drafts a recommendation.
In this project, you will build a multi-agent AI system that mirrors this process. Three specialized AI agents collaborate autonomously to produce a structured legal opinion for any corporate scenario you give them.
What You'll Build
A Corporate Legal Adviser powered by three AI agents built with CrewAI and Google Gemini that autonomously collaborate to produce professional legal analysis.
By the end of this project, you'll have:
- A working multi-agent system with three specialized AI agents that research laws, analyze risks, and write legal opinions.
- A custom tool that your agents use to search for relevant legal information.
- A structured legal opinion saved as a markdown file, complete with risk ratings and actionable recommendations.
- Secret Mission: Add a contract clause extraction agent that parses contract text and flags problematic clauses before the crew runs its analysis.
Do I need legal knowledge for this project?
No. The focus is on building and orchestrating AI agents, not on knowing the law. Your agents handle the legal reasoning using the LLM you connect them to. Basic Python knowledge is all you need to get started.
Before We Start
Before We Start...
Set Up Your Environment
Before you can build your multi-agent legal advisory system, you need a clean workspace with the right tools installed. CrewAI is the framework that makes it possible to orchestrate multiple AI agents as a team.
In this step, you will create a dedicated project folder, install CrewAI, connect it to Google's free Gemini API, and confirm everything works together.
In this step, get ready to:
- Install CrewAI and set up a Python virtual environment.
- Get a free Gemini API key and configure it as an environment variable.
- Create your project file and verify the connection works.
Install CrewAI and set up your project folder
You need an isolated Python environment so CrewAI's dependencies don't interfere with anything else on your machine. A virtual environment gives you that isolation.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type VS Code and press Enter to open it.
- Open the integrated terminal by pressing Ctrl+` (Windows) or Cmd+` (macOS).
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your project folder and move into it by running these commands:
mkdir legal-adviser
cd legal-adviser
- Confirm the folder exists by running:
ls
You should see the legal-adviser folder listed if you look one level up, and your terminal prompt should now show you are inside it.
- Create a Python virtual environment by running:
python -m venv venv
What is a virtual environment?
A virtual environment is an isolated copy of Python for your project. Packages you install inside it stay separate from your system Python, so different projects can use different package versions without conflicts.
- Activate your virtual environment:
macOS
- Run this command to activate:
source venv/bin/activate
Windows
- Run this command to activate:
venv\Scripts\Activate.ps1
Seeing an execution policy error?
If PowerShell blocks the script, run this command first to allow it:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Then try the activation command again.
You should see (venv) appear at the beginning of your terminal prompt. This confirms the virtual environment is active.
- Install CrewAI by running:
pip install crewai
What does this install?
This installs the CrewAI framework along with its dependencies, including LiteLLM (which handles connections to different AI providers like Gemini). The installation may take a minute as it downloads several packages.
- Verify the installation succeeded by running:
pip show crewai
You should see package information including the name crewai and a version number.
Not seeing package info?
Make sure your virtual environment is active (you see (venv) in your prompt). If the install failed, check your internet connection and try running pip install crewai again.
help me troubleshoot my CrewAI installation
Get your Gemini API key
CrewAI needs an AI model to power your agents. You will use Google's Gemini model, which offers a free tier with no charges.
- Open your browser and go to Google AI Studio.
- Sign in with your Google account.
- Click Get API key in the left sidebar.
- Click Create API key.
- Copy the generated key and save it somewhere safe (you will need it in a moment).
What is an API key?
An API key is a unique string that identifies your project to Google's servers. It lets your code send requests to the Gemini model. The free tier gives you enough tokens for this entire project at no cost.
Now set the API key as an environment variable so your Python code can access it without hardcoding the secret.
macOS
- In your VS Code terminal (with the virtual environment still active), run:
export GEMINI_API_KEY=your-api-key-here
Replace your-api-key-here with the key you just copied from Google AI Studio.
Windows
- In your VS Code terminal (with the virtual environment still active), run:
$env:GEMINI_API_KEY="your-api-key-here"
Replace your-api-key-here with the key you just copied from Google AI Studio.
This variable is session-only
The environment variable lasts only for this terminal session. If you close and reopen VS Code, you will need to set it again using the same command.
- Verify the variable is set by running:
macOS
echo $GEMINI_API_KEY
Windows
echo $env:GEMINI_API_KEY
You should see your API key printed in the terminal.
Seeing a blank output?
Double-check that you did not add extra spaces around the = sign in the export command. Also confirm you are running the verify command in the same terminal window where you set the variable.
help me set my GEMINI_API_KEY environment variable
Create your project file and test the connection
With CrewAI installed and your API key ready, you can create the main project file and confirm everything connects.
- In VS Code, click File in the top menu bar.
- Click Open Folder.
- Select the legal-adviser folder on your Desktop, then click Open.
Why open the folder?
Opening the folder as a workspace lets VS Code show your project files in the Explorer sidebar. It also sets the terminal's starting directory to your project folder automatically.
- Open a new terminal in VS Code by pressing Ctrl+` (Windows) or Cmd+` (macOS).
- Re-activate your virtual environment and re-set your API key (the new terminal is a fresh session):
macOS
source venv/bin/activate
export GEMINI_API_KEY=your-api-key-here
Windows
venv\Scripts\Activate.ps1
$env:GEMINI_API_KEY="your-api-key-here"
- In the VS Code Explorer sidebar on the left, hover over the folder name and click the New File icon.
- Name the file legal_crew.py and press Enter.
- Add the following imports to legal_crew.py:
import os
from crewai import Agent, Task, Crew, Process, LLM
from crewai.tools import tool
What does this code do?
import os gives you access to environment variables (like your API key).
from crewai import Agent, Task, Crew, Process, LLM brings in the five core building blocks of CrewAI: Agents (your AI workers), Tasks (their assignments), Crew (the team), Process (the workflow order), and LLM (the AI model connection).
from crewai.tools import tool imports the decorator you will use to create custom tools your agents can call.
- Save legal_crew.py.
- Run the file to confirm the imports work:
python legal_crew.py
You should see no output and no errors. A silent return to the command prompt means all imports resolved successfully.
Seeing a ModuleNotFoundError?
This means CrewAI is not installed in the active environment. Confirm you see (venv) in your terminal prompt. If not, re-activate the virtual environment and try again.
If the venv is active but you still see the error, run pip install crewai again inside the activated environment.
help me fix my ModuleNotFoundError for crewai
✔️ Awesome, I've got everything!
Great. Double check you have saved legal_crew.py and that running it produces no errors.
ⓧ I'd like to double check the full code
Here is what legal_crew.py should look like at this point:
import os
from crewai import Agent, Task, Crew, Process, LLM
from crewai.tools import tool
Your environment is locked and loaded. Next up, you will build a custom legal research tool that your AI agents can call to gather relevant laws and regulations.
Build Your Legal Research Tool
Your environment is set up and your Gemini connection is ready to go. Now it is time to give your agents something to work with.
In agentic AI, a tool is a function that an agent can call autonomously to gather information or take action. Your legal agents need a way to look up relevant laws and regulations. In this step, you will build a custom legal research tool and connect it to the CrewAI framework.
In this step, get ready to:
- Configure the Gemini LLM connection for your agents.
- Build a custom legal research tool using CrewAI's tool decorator.
- Test the tool independently to verify it returns useful legal context.
Configure the Gemini LLM connection
Before building the tool, you need to tell CrewAI which language model your agents will use. CrewAI uses LiteLLM under the hood to connect to different model providers.
- In VS Code, open legal_crew.py.
- Add the following code below the import lines:
# Configure the Gemini LLM
gemini_llm = LLM(
model="gemini/gemini-2.5-flash",
api_key=os.getenv("GEMINI_API_KEY"),
temperature=0.4,
)
What does this code do?
The LLM class is CrewAI's wrapper for connecting to any language model provider.
- model="gemini/gemini-2.5-flash" tells LiteLLM to route requests to Google's Gemini 2.5 Flash model. The gemini/ prefix identifies the provider.
- os.getenv("GEMINI_API_KEY") reads your API key from the environment variable you set in Step 1.
- temperature=0.4 keeps responses focused and consistent. Lower temperatures produce more predictable legal analysis.
- Save legal_crew.py.
Seeing an import error?
Make sure your virtual environment is active. You should see (venv) at the start of your terminal prompt. If not, reactivate it.
Also confirm CrewAI is installed in that environment by running pip show crewai.
Help me fix my CrewAI import error.
Create the custom legal research tool
Your agents need a way to look up legal information. In a production system, this tool might call a legal database API. For this project, you will build a simulated research tool that contains structured legal knowledge across five key areas.
Why a simulated tool instead of a real API?
Real legal research APIs cost money per query. A simulated tool teaches the same agentic pattern (the agent autonomously decides when and how to call it) without extra API costs or signups.
The agents do not know the tool is simulated. They call it the same way they would call a real API.
- In legal_crew.py, add the following code below the gemini_llm configuration. Leave one blank line between the LLM config and this new code:
# Custom Legal Research Tool
@tool("Legal Research Tool")
def legal_research_tool(query: str) -> str:
"""Searches for relevant legal information, regulations, and precedents
based on the provided legal query. Use this tool to find applicable laws,
regulatory frameworks, and legal principles relevant to the scenario."""
legal_knowledge = {
"gdpr": (
"GDPR (General Data Protection Regulation) - EU regulation effective May 2018. "
"Key principles: lawful basis for processing, data minimization, purpose limitation, "
"storage limitation, accountability. Fines up to 4% of annual global turnover or "
"20 million EUR. Requires explicit consent for data processing. Data subjects have "
"rights to access, rectification, erasure, portability. Data Protection Impact "
"Assessments required for high-risk processing."
),
"ccpa": (
"CCPA (California Consumer Privacy Act) - Effective January 2020, amended by CPRA 2023. "
"Applies to businesses with >$25M revenue, or processing 100k+ consumers' data, or "
"earning 50%+ revenue from selling personal info. Consumer rights: right to know, "
"right to delete, right to opt-out of sale, right to non-discrimination. "
"Fines: $2,500 per unintentional violation, $7,500 per intentional violation."
),
"employment": (
"Employment law key areas: At-will employment doctrine, wrongful termination, "
"discrimination (Title VII, ADA, ADEA), wage and hour laws (FLSA), "
"non-compete agreements (FTC 2024 rule), employee classification, "
"workplace safety (OSHA), family and medical leave (FMLA), "
"whistleblower protections, trade secret law (DTSA)."
),
"contract": (
"Contract law essentials: Offer, acceptance, consideration, capacity, legality. "
"Key clauses to review: indemnification, limitation of liability, termination, "
"intellectual property assignment, non-compete/non-solicitation, "
"confidentiality, dispute resolution (arbitration vs litigation), "
"governing law, force majeure, warranty disclaimers."
),
"ip": (
"Intellectual Property: Patents (utility, design, plant), Trademarks, "
"Copyrights, Trade Secrets. Key considerations: ownership assignment in "
"employment, work-for-hire doctrine, licensing terms, open source compliance, "
"patent infringement risks, trademark registration and enforcement."
),
}
query_lower = query.lower()
results = []
for topic, info in legal_knowledge.items():
if topic in query_lower or any(
keyword in query_lower
for keyword in topic.split()
):
results.append(info)
if not results:
results.append(
"General legal principle: Always consult jurisdiction-specific regulations. "
"Consider statutory requirements, case law precedents, regulatory guidance, "
"and industry best practices. Assess both civil and criminal liability exposure."
)
return "\n\n".join(results)
What does this code do?
This function has three main parts:
- @tool("Legal Research Tool") registers the function with CrewAI so agents can call it. The decorator name and the docstring are what the agent sees when deciding which tool to use.
- The legal_knowledge dictionary contains structured information about five legal areas: GDPR, CCPA, employment law, contracts, and intellectual property.
- The matching logic scans the query for relevant keywords and returns all matching entries. If no keywords match, it returns general legal guidance as a fallback.
- Save legal_crew.py.
Seeing a syntax error?
This is a large block of code. Double check that every opening parenthesis has a matching close, and every string uses consistent quotes. The dictionary entries use parentheses around multi-line strings for concatenation.
Help me find the syntax error in my legal research tool code.
Test the tool independently
Before handing this tool to an agent, you should verify it works on its own. You can call the function directly from a Python command to confirm it returns the right legal context.
- In your terminal, run this command to test the tool with a GDPR-related query:
python -c "from legal_crew import legal_research_tool; print(legal_research_tool.run('What are the GDPR implications?'))"
- You should see output containing GDPR information, including references to fines, data subject rights, and the Data Protection Impact Assessment requirement.
Why use .run() instead of calling it directly?
The @tool decorator wraps your function in a CrewAI tool object. Calling .run() executes the tool the same way an agent would. This confirms the tool is properly registered and callable.
Getting a ModuleNotFoundError?
Make sure you are running the command from inside your project folder (where legal_crew.py lives). Also confirm your virtual environment is still active.
Help me fix the ModuleNotFoundError when testing my tool.
✔️ Awesome, I've got everything!
Great. Double check you have saved legal_crew.py before moving on.
ⓧ I'd like to double check the full code
Here is the complete legal_crew.py file as it should look at the end of this step:
import os
from crewai import Agent, Task, Crew, Process, LLM
from crewai.tools import tool
# Configure the Gemini LLM
gemini_llm = LLM(
model="gemini/gemini-2.5-flash",
api_key=os.getenv("GEMINI_API_KEY"),
temperature=0.4,
)
# Custom Legal Research Tool
@tool("Legal Research Tool")
def legal_research_tool(query: str) -> str:
"""Searches for relevant legal information, regulations, and precedents
based on the provided legal query. Use this tool to find applicable laws,
regulatory frameworks, and legal principles relevant to the scenario."""
legal_knowledge = {
"gdpr": (
"GDPR (General Data Protection Regulation) - EU regulation effective May 2018. "
"Key principles: lawful basis for processing, data minimization, purpose limitation, "
"storage limitation, accountability. Fines up to 4% of annual global turnover or "
"20 million EUR. Requires explicit consent for data processing. Data subjects have "
"rights to access, rectification, erasure, portability. Data Protection Impact "
"Assessments required for high-risk processing."
),
"ccpa": (
"CCPA (California Consumer Privacy Act) - Effective January 2020, amended by CPRA 2023. "
"Applies to businesses with >$25M revenue, or processing 100k+ consumers' data, or "
"earning 50%+ revenue from selling personal info. Consumer rights: right to know, "
"right to delete, right to opt-out of sale, right to non-discrimination. "
"Fines: $2,500 per unintentional violation, $7,500 per intentional violation."
),
"employment": (
"Employment law key areas: At-will employment doctrine, wrongful termination, "
"discrimination (Title VII, ADA, ADEA), wage and hour laws (FLSA), "
"non-compete agreements (FTC 2024 rule), employee classification, "
"workplace safety (OSHA), family and medical leave (FMLA), "
"whistleblower protections, trade secret law (DTSA)."
),
"contract": (
"Contract law essentials: Offer, acceptance, consideration, capacity, legality. "
"Key clauses to review: indemnification, limitation of liability, termination, "
"intellectual property assignment, non-compete/non-solicitation, "
"confidentiality, dispute resolution (arbitration vs litigation), "
"governing law, force majeure, warranty disclaimers."
),
"ip": (
"Intellectual Property: Patents (utility, design, plant), Trademarks, "
"Copyrights, Trade Secrets. Key considerations: ownership assignment in "
"employment, work-for-hire doctrine, licensing terms, open source compliance, "
"patent infringement risks, trademark registration and enforcement."
),
}
query_lower = query.lower()
results = []
for topic, info in legal_knowledge.items():
if topic in query_lower or any(
keyword in query_lower
for keyword in topic.split()
):
results.append(info)
if not results:
results.append(
"General legal principle: Always consult jurisdiction-specific regulations. "
"Consider statutory requirements, case law precedents, regulatory guidance, "
"and industry best practices. Assess both civil and criminal liability exposure."
)
return "\n\n".join(results)
Your legal research tool is ready and tested. Next up, you will create the three specialized AI agents that will use this tool to analyze legal scenarios.
Create Your Three Legal Agents
Your legal research tool is ready. Now it's time to build the team that will use it.
In CrewAI, an agent is an autonomous unit with a specific role, goal, and backstory. Each agent decides independently how to accomplish its task. By giving each agent a distinct personality and expertise, you create specialists that produce better output than a single general-purpose prompt ever could.
In this step, get ready to:
- Define a Legal Researcher agent that uses the custom research tool.
- Define a Risk and Compliance Analyst agent that identifies legal risks.
- Define a Senior Legal Advisor agent that produces the final legal opinion.
Define the Legal Researcher agent
The Legal Researcher is the first agent in your pipeline. Its job is to gather all relevant laws, regulations, and precedents for a given scenario. This is the only agent that needs a tool, because it actively searches for legal information.
- In legal_crew.py, scroll to the bottom of the file (after the legal_research_tool function).
- Add the Legal Researcher agent by pasting this code at the end of the file:
# Agent 1: Legal Researcher
legal_researcher = Agent(
role="Senior Legal Researcher",
goal=(
"Research and identify all relevant laws, regulations, legal precedents, "
"and regulatory frameworks applicable to the given legal scenario"
),
backstory=(
"You are an experienced legal researcher with 15 years of experience across "
"corporate law, regulatory compliance, and contract law. You excel at finding "
"relevant statutes, case law, and regulatory guidance. You always cite specific "
"laws and regulations by name."
),
llm=gemini_llm,
tools=[legal_research_tool],
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
What does this code do?
Each CrewAI Agent takes a role, goal, and backstory. These three strings shape how the LLM behaves when acting as this agent. Think of them as the agent's job title, objective, and professional background.
- tools=[legal_research_tool] gives this agent access to the research tool you built in the previous step.
- allow_delegation=False prevents the agent from passing its work to another agent. Each agent must complete its own task.
- verbose=True prints the agent's reasoning steps to the terminal so you can watch it think.
Why roles, goals, and backstories?
This is the core difference between agentic AI and a simple chatbot. A chatbot receives a single prompt. An agent receives a persona, an objective, and context about its expertise. The LLM uses all three to decide what actions to take, what tools to call, and how to format its output.
The more specific the backstory, the more focused the agent's output becomes.
- You won't see a change yet. The next agent builds on this one.
Define the Risk and Compliance Analyst agent
The Risk Analyst receives the Legal Researcher's output and identifies risks, compliance gaps, and liabilities. It does not need a tool because it works purely with the research it receives from the previous agent.
- Add the Risk and Compliance Analyst agent below the legal_researcher definition:
# Agent 2: Risk and Compliance Analyst
risk_analyst = Agent(
role="Risk and Compliance Analyst",
goal=(
"Analyze the legal research findings and identify all potential risks, "
"compliance gaps, and liabilities with severity ratings"
),
backstory=(
"You are a meticulous risk analyst with a background in regulatory compliance "
"and corporate governance. You specialize in identifying legal exposure, rating "
"risks by severity (Critical, High, Medium, Low), and mapping compliance gaps "
"to specific regulatory requirements."
),
llm=gemini_llm,
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
What does this code do?
This agent has no tools parameter. It relies entirely on the context passed to it from the previous agent's output. Its backstory instructs it to rate risks by severity, which shapes the structure of what it produces.
- You won't see a change yet. One more agent to go.
Define the Senior Legal Advisor agent
The Senior Legal Advisor is the final agent in the chain. It takes the research and risk analysis from the first two agents and synthesizes everything into a structured legal opinion with actionable recommendations.
- Add the Senior Legal Advisor agent below the risk_analyst definition:
# Agent 3: Senior Legal Advisor
senior_advisor = Agent(
role="Senior Legal Advisor",
goal=(
"Synthesize the research and risk analysis into a clear, actionable legal "
"opinion with specific recommendations and next steps"
),
backstory=(
"You are a senior corporate counsel with 20 years of experience advising "
"companies on complex legal matters. You are known for providing clear, "
"practical legal opinions that balance legal risk with business objectives. "
"You always structure your opinions with an executive summary, detailed "
"analysis, risk ratings, and actionable recommendations."
),
llm=gemini_llm,
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
What does this code do?
This agent's backstory explicitly mentions structuring opinions with an executive summary, analysis, risk ratings, and recommendations. The LLM follows these structural cues when generating its output, giving you a consistently formatted legal opinion every time.
- Save legal_crew.py.
- Verify the file has no syntax errors by running this command in your terminal:
python legal_crew.py
- The script should finish silently with no error messages. If you see a clean return to the command prompt, your agents are defined correctly.
Seeing an error?
- If you see NameError: name 'Agent' is not defined, make sure your import line at the top of the file reads from crewai import Agent, Task, Crew, Process, LLM.
- If you see a SyntaxError, check that every opening parenthesis has a matching closing parenthesis. The Agent constructor spans multiple lines, so a missing comma or quote is easy to miss.
- If you see NameError: name 'gemini_llm' is not defined, make sure the gemini_llm variable is defined above your agent definitions (near the top of the file).
Why is my legal_crew.py throwing errors when I run it?
✔️ Awesome, I've got everything!
Great. Double check you've saved your file before moving on.
ⓧ I'd like to double check the full code
Here is the complete legal_crew.py file so far:
import os
from crewai import Agent, Task, Crew, Process, LLM
from crewai.tools import tool
# Configure the Gemini LLM
gemini_llm = LLM(
model="gemini/gemini-2.5-flash",
api_key=os.getenv("GEMINI_API_KEY"),
temperature=0.4,
)
# Custom Legal Research Tool
@tool("Legal Research Tool")
def legal_research_tool(query: str) -> str:
"""Searches for relevant legal information, regulations, and precedents
based on the provided legal query. Use this tool to find applicable laws,
regulatory frameworks, and legal principles relevant to the scenario."""
legal_knowledge = {
"gdpr": (
"GDPR (General Data Protection Regulation) - EU regulation effective May 2018. "
"Key principles: lawful basis for processing, data minimization, purpose limitation, "
"storage limitation, accountability. Fines up to 4% of annual global turnover or "
"20 million EUR. Requires explicit consent for data processing. Data subjects have "
"rights to access, rectification, erasure, portability. Data Protection Impact "
"Assessments required for high-risk processing."
),
"ccpa": (
"CCPA (California Consumer Privacy Act) - Effective January 2020, amended by CPRA 2023. "
"Applies to businesses with >$25M revenue, or processing 100k+ consumers' data, or "
"earning 50%+ revenue from selling personal info. Consumer rights: right to know, "
"right to delete, right to opt-out of sale, right to non-discrimination. "
"Fines: $2,500 per unintentional violation, $7,500 per intentional violation."
),
"employment": (
"Employment law key areas: At-will employment doctrine, wrongful termination, "
"discrimination (Title VII, ADA, ADEA), wage and hour laws (FLSA), "
"non-compete agreements (FTC 2024 rule), employee classification, "
"workplace safety (OSHA), family and medical leave (FMLA), "
"whistleblower protections, trade secret law (DTSA)."
),
"contract": (
"Contract law essentials: Offer, acceptance, consideration, capacity, legality. "
"Key clauses to review: indemnification, limitation of liability, termination, "
"intellectual property assignment, non-compete/non-solicitation, "
"confidentiality, dispute resolution (arbitration vs litigation), "
"governing law, force majeure, warranty disclaimers."
),
"ip": (
"Intellectual Property: Patents (utility, design, plant), Trademarks, "
"Copyrights, Trade Secrets. Key considerations: ownership assignment in "
"employment, work-for-hire doctrine, licensing terms, open source compliance, "
"patent infringement risks, trademark registration and enforcement."
),
}
query_lower = query.lower()
results = []
for topic, info in legal_knowledge.items():
if topic in query_lower or any(
keyword in query_lower
for keyword in topic.split()
):
results.append(info)
if not results:
results.append(
"General legal principle: Always consult jurisdiction-specific regulations. "
"Consider statutory requirements, case law precedents, regulatory guidance, "
"and industry best practices. Assess both civil and criminal liability exposure."
)
return "\n\n".join(results)
# Agent 1: Legal Researcher
legal_researcher = Agent(
role="Senior Legal Researcher",
goal=(
"Research and identify all relevant laws, regulations, legal precedents, "
"and regulatory frameworks applicable to the given legal scenario"
),
backstory=(
"You are an experienced legal researcher with 15 years of experience across "
"corporate law, regulatory compliance, and contract law. You excel at finding "
"relevant statutes, case law, and regulatory guidance. You always cite specific "
"laws and regulations by name."
),
llm=gemini_llm,
tools=[legal_research_tool],
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
# Agent 2: Risk and Compliance Analyst
risk_analyst = Agent(
role="Risk and Compliance Analyst",
goal=(
"Analyze the legal research findings and identify all potential risks, "
"compliance gaps, and liabilities with severity ratings"
),
backstory=(
"You are a meticulous risk analyst with a background in regulatory compliance "
"and corporate governance. You specialize in identifying legal exposure, rating "
"risks by severity (Critical, High, Medium, Low), and mapping compliance gaps "
"to specific regulatory requirements."
),
llm=gemini_llm,
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
# Agent 3: Senior Legal Advisor
senior_advisor = Agent(
role="Senior Legal Advisor",
goal=(
"Synthesize the research and risk analysis into a clear, actionable legal "
"opinion with specific recommendations and next steps"
),
backstory=(
"You are a senior corporate counsel with 20 years of experience advising "
"companies on complex legal matters. You are known for providing clear, "
"practical legal opinions that balance legal risk with business objectives. "
"You always structure your opinions with an executive summary, detailed "
"analysis, risk ratings, and actionable recommendations."
),
llm=gemini_llm,
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
Your legal team is assembled. Next up, you'll give each agent a specific task and wire them into a sequential crew so they collaborate automatically.
Define Tasks and Assemble the Crew
You now have three specialized agents, each with a distinct role, goal, and backstory. But agents on their own are just definitions. They need instructions on what to actually do.
In this step, you will create Task objects that tell each agent exactly what work to produce. Then you will assemble all three agents and their tasks into a Crew that orchestrates them in sequence.
In this step, get ready to:
- Create three Task objects with descriptions and expected outputs.
- Assemble a Crew that runs agents in sequential order.
- Save the final legal opinion to a markdown file automatically.
Create the three task objects
A Task in CrewAI defines a specific piece of work for an agent. Each task has a description (what to do), an expected output (what good looks like), and an assigned agent.
Your three tasks will chain together. The research task feeds context to the risk task, which feeds context to the opinion task.
- In legal_crew.py, scroll to the bottom of the file (below the senior_advisor agent definition).
- Add the research task by pasting the following code:
# Task 1: Legal Research
research_task = Task(
description=(
"Conduct thorough legal research on the following scenario:\n\n"
"{scenario}\n\n"
"Use the Legal Research Tool to find all applicable laws, regulations, "
"and legal precedents. Identify the relevant jurisdictions and regulatory "
"bodies. Provide a comprehensive research summary with specific citations."
),
expected_output=(
"A detailed legal research report containing: applicable laws and regulations "
"with specific citations, relevant jurisdictions, key legal principles that "
"apply, and any relevant precedents or regulatory guidance."
),
agent=legal_researcher,
)
What does this code do?
The description tells the agent exactly what work to perform. The {scenario} placeholder is a variable that gets filled in at runtime when you kick off the crew with real input.
The expected_output gives the agent a quality bar. It knows what shape its final answer should take.
The agent=legal_researcher assignment connects this task to the agent you built in the previous step.
- Below the research task, add the risk analysis task:
# Task 2: Risk Analysis
risk_task = Task(
description=(
"Based on the legal research provided, conduct a comprehensive risk and "
"compliance analysis. Identify all potential legal risks, compliance gaps, "
"and liabilities. Rate each risk by severity (Critical, High, Medium, Low) "
"and likelihood. Map each risk to the specific regulation or law it relates to."
),
expected_output=(
"A structured risk assessment containing: a risk matrix with severity and "
"likelihood ratings, specific compliance gaps identified, potential financial "
"exposure estimates where applicable, and regulatory penalties that could apply."
),
agent=risk_analyst,
)
How does context flow between tasks?
You do not need to pass the research output manually. When the Crew runs in sequential mode, each task automatically receives the previous task's output as context. The risk analyst sees everything the researcher produced.
- Below the risk task, add the final legal opinion task:
# Task 3: Legal Opinion
opinion_task = Task(
description=(
"Synthesize the legal research and risk analysis into a comprehensive legal "
"opinion. Structure it with: Executive Summary, Detailed Analysis (organized "
"by issue), Risk Ratings, Recommended Actions (prioritized), and Next Steps. "
"Make recommendations practical and actionable for a business audience."
),
expected_output=(
"A professionally structured legal opinion in markdown format with: "
"Executive Summary, Detailed Legal Analysis, Risk Assessment Summary, "
"Prioritized Recommendations, and Immediate Next Steps. Each recommendation "
"should include estimated timeline and responsible party."
),
agent=senior_advisor,
output_file="legal_opinion.md",
)
What does output_file do?
The output_file="legal_opinion.md" parameter tells CrewAI to automatically save this task's final output to a markdown file in your project folder. You get a permanent record of the legal opinion without any extra file-writing code.
- Save legal_crew.py.
Seeing a red underline on agent names?
Make sure each agent= value matches the exact variable name from Step 3: legal_researcher, risk_analyst, senior_advisor.
Also check that your task definitions are placed below the agent definitions in the file. Python reads top to bottom, so referencing a variable before it exists causes an error.
Help me fix a NameError for my agent variables.
Assemble the crew
A Crew is the orchestrator that coordinates your agents and tasks. You will configure it to run sequentially so each agent builds on the previous agent's work.
- Below the opinion_task definition, add the crew assembly:
# Assemble the Crew
legal_crew = Crew(
agents=[legal_researcher, risk_analyst, senior_advisor],
tasks=[research_task, risk_task, opinion_task],
process=Process.sequential,
verbose=True,
)
What does Process.sequential mean?
Sequential processing means agents run one after the other in the order you list them. The Legal Researcher finishes first, then the Risk Analyst starts (with the researcher's output as context), then the Senior Legal Advisor synthesizes everything.
The verbose=True flag prints each agent's reasoning to the terminal so you can watch them think, call tools, and produce output in real time.
- Save legal_crew.py.
- Confirm you see no red underlines or syntax errors in VS Code.
Seeing an import error for Process?
Check that your import line at the top of the file includes Process. It should read from crewai import Agent, Task, Crew, Process, LLM.
Help me fix my CrewAI Process import.
✔️ Awesome, I've got everything!
Great. Double check you have saved legal_crew.py with all three tasks and the crew assembled at the bottom.
ⓧ I'd like to double check the full code
import os
from crewai import Agent, Task, Crew, Process, LLM
from crewai.tools import tool
# Configure the Gemini LLM
gemini_llm = LLM(
model="gemini/gemini-2.5-flash",
api_key=os.getenv("GEMINI_API_KEY"),
temperature=0.4,
)
# Custom Legal Research Tool
@tool("Legal Research Tool")
def legal_research_tool(query: str) -> str:
"""Searches for relevant legal information, regulations, and precedents
based on the provided legal query. Use this tool to find applicable laws,
regulatory frameworks, and legal principles relevant to the scenario."""
legal_knowledge = {
"gdpr": (
"GDPR (General Data Protection Regulation) - EU regulation effective May 2018. "
"Key principles: lawful basis for processing, data minimization, purpose limitation, "
"storage limitation, accountability. Fines up to 4% of annual global turnover or "
"20 million EUR. Requires explicit consent for data processing. Data subjects have "
"rights to access, rectification, erasure, portability. Data Protection Impact "
"Assessments required for high-risk processing."
),
"ccpa": (
"CCPA (California Consumer Privacy Act) - Effective January 2020, amended by CPRA 2023. "
"Applies to businesses with >$25M revenue, or processing 100k+ consumers' data, or "
"earning 50%+ revenue from selling personal info. Consumer rights: right to know, "
"right to delete, right to opt-out of sale, right to non-discrimination. "
"Fines: $2,500 per unintentional violation, $7,500 per intentional violation."
),
"employment": (
"Employment law key areas: At-will employment doctrine, wrongful termination, "
"discrimination (Title VII, ADA, ADEA), wage and hour laws (FLSA), "
"non-compete agreements (FTC 2024 rule), employee classification, "
"workplace safety (OSHA), family and medical leave (FMLA), "
"whistleblower protections, trade secret law (DTSA)."
),
"contract": (
"Contract law essentials: Offer, acceptance, consideration, capacity, legality. "
"Key clauses to review: indemnification, limitation of liability, termination, "
"intellectual property assignment, non-compete/non-solicitation, "
"confidentiality, dispute resolution (arbitration vs litigation), "
"governing law, force majeure, warranty disclaimers."
),
"ip": (
"Intellectual Property: Patents (utility, design, plant), Trademarks, "
"Copyrights, Trade Secrets. Key considerations: ownership assignment in "
"employment, work-for-hire doctrine, licensing terms, open source compliance, "
"patent infringement risks, trademark registration and enforcement."
),
}
query_lower = query.lower()
results = []
for topic, info in legal_knowledge.items():
if topic in query_lower or any(
keyword in query_lower
for keyword in topic.split()
):
results.append(info)
if not results:
results.append(
"General legal principle: Always consult jurisdiction-specific regulations. "
"Consider statutory requirements, case law precedents, regulatory guidance, "
"and industry best practices. Assess both civil and criminal liability exposure."
)
return "\n\n".join(results)
# Agent 1: Legal Researcher
legal_researcher = Agent(
role="Senior Legal Researcher",
goal=(
"Research and identify all relevant laws, regulations, legal precedents, "
"and regulatory frameworks applicable to the given legal scenario"
),
backstory=(
"You are an experienced legal researcher with 15 years of experience across "
"corporate law, regulatory compliance, and contract law. You excel at finding "
"relevant statutes, case law, and regulatory guidance. You always cite specific "
"laws and regulations by name."
),
llm=gemini_llm,
tools=[legal_research_tool],
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
# Agent 2: Risk and Compliance Analyst
risk_analyst = Agent(
role="Risk and Compliance Analyst",
goal=(
"Analyze the legal research findings and identify all potential risks, "
"compliance gaps, and liabilities with severity ratings"
),
backstory=(
"You are a meticulous risk analyst with a background in regulatory compliance "
"and corporate governance. You specialize in identifying legal exposure, rating "
"risks by severity (Critical, High, Medium, Low), and mapping compliance gaps "
"to specific regulatory requirements."
),
llm=gemini_llm,
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
# Agent 3: Senior Legal Advisor
senior_advisor = Agent(
role="Senior Legal Advisor",
goal=(
"Synthesize the research and risk analysis into a clear, actionable legal "
"opinion with specific recommendations and next steps"
),
backstory=(
"You are a senior corporate counsel with 20 years of experience advising "
"companies on complex legal matters. You are known for providing clear, "
"practical legal opinions that balance legal risk with business objectives. "
"You always structure your opinions with an executive summary, detailed "
"analysis, risk ratings, and actionable recommendations."
),
llm=gemini_llm,
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
# Task 1: Legal Research
research_task = Task(
description=(
"Conduct thorough legal research on the following scenario:\n\n"
"{scenario}\n\n"
"Use the Legal Research Tool to find all applicable laws, regulations, "
"and legal precedents. Identify the relevant jurisdictions and regulatory "
"bodies. Provide a comprehensive research summary with specific citations."
),
expected_output=(
"A detailed legal research report containing: applicable laws and regulations "
"with specific citations, relevant jurisdictions, key legal principles that "
"apply, and any relevant precedents or regulatory guidance."
),
agent=legal_researcher,
)
# Task 2: Risk Analysis
risk_task = Task(
description=(
"Based on the legal research provided, conduct a comprehensive risk and "
"compliance analysis. Identify all potential legal risks, compliance gaps, "
"and liabilities. Rate each risk by severity (Critical, High, Medium, Low) "
"and likelihood. Map each risk to the specific regulation or law it relates to."
),
expected_output=(
"A structured risk assessment containing: a risk matrix with severity and "
"likelihood ratings, specific compliance gaps identified, potential financial "
"exposure estimates where applicable, and regulatory penalties that could apply."
),
agent=risk_analyst,
)
# Task 3: Legal Opinion
opinion_task = Task(
description=(
"Synthesize the legal research and risk analysis into a comprehensive legal "
"opinion. Structure it with: Executive Summary, Detailed Analysis (organized "
"by issue), Risk Ratings, Recommended Actions (prioritized), and Next Steps. "
"Make recommendations practical and actionable for a business audience."
),
expected_output=(
"A professionally structured legal opinion in markdown format with: "
"Executive Summary, Detailed Legal Analysis, Risk Assessment Summary, "
"Prioritized Recommendations, and Immediate Next Steps. Each recommendation "
"should include estimated timeline and responsible party."
),
agent=senior_advisor,
output_file="legal_opinion.md",
)
# Assemble the Crew
legal_crew = Crew(
agents=[legal_researcher, risk_analyst, senior_advisor],
tasks=[research_task, risk_task, opinion_task],
process=Process.sequential,
verbose=True,
)
Your crew is fully assembled. Three agents, three tasks, one sequential pipeline. Next up, you will run this system with a real legal scenario and watch the agents collaborate in real time.
Run the Legal Advisory Crew
You have three specialized agents, three tasks, and a fully assembled crew ready to go. Now it's time to wire up the entry point and watch the system come alive.
You'll add a __main__ block that accepts any legal scenario as input, then kicks off the sequential pipeline. Once running, you'll see each agent reason through its task, call tools, and hand off findings to the next agent in line.
In this step, get ready to:
- Add a main block that accepts a legal scenario and runs the crew.
- Run the system and observe multi-agent collaboration in action.
Add the main entry point
Python scripts use a if __name__ == "__main__": block to define what happens when you run the file directly from the terminal. This is where you'll prompt for a legal scenario and launch the crew.
- In legal_crew.py, scroll to the very bottom of the file (below the legal_crew = Crew(...) block).
- Add the following main block by copying this code at the end of the file:
if __name__ == "__main__":
scenario = input("Describe your legal scenario:\n> ")
if not scenario.strip():
scenario = (
"Our startup wants to collect and sell anonymized user browsing data "
"to third-party advertisers. We have users in the EU and California. "
"What are the legal implications and what do we need to comply with?"
)
print(f"\nUsing sample scenario: {scenario}\n")
print("\n" + "=" * 60)
print("CORPORATE LEGAL ADVISER - Multi-Agent Analysis")
print("=" * 60 + "\n")
result = legal_crew.kickoff(inputs={"scenario": scenario})
print("\n" + "=" * 60)
print("LEGAL OPINION COMPLETE")
print("=" * 60)
print("\nFull opinion saved to: legal_opinion.md")
print("\n--- EXECUTIVE SUMMARY ---\n")
print(result.raw[:2000] if len(result.raw) > 2000 else result.raw)
What does this code do?
- input() prompts the user to type a legal scenario. If they press Enter without typing anything, a sample GDPR/CCPA scenario is used automatically.
- legal_crew.kickoff(inputs={"scenario": scenario}) launches the entire crew. The inputs dictionary injects the scenario text into each task's {scenario} placeholder.
- result.raw[:2000] prints just the first 2000 characters of the final opinion to the terminal so you get a quick preview without flooding the screen.
- Save legal_crew.py.
Seeing a syntax error on save?
- Make sure the if __name__ block is at the same indentation level as your agent and task definitions (no extra indentation).
- Check that the f-string print(f"\nUsing sample scenario: {scenario}\n") has matching quotes and curly braces.
- help me fix a syntax error in my __main__ block
✔️ Awesome, I've got everything!
Great. Double check you've saved your file before moving on.
ⓧ I'd like to double check the full code
import os
from crewai import Agent, Task, Crew, Process, LLM
from crewai.tools import tool
# Configure the Gemini LLM
gemini_llm = LLM(
model="gemini/gemini-2.5-flash",
api_key=os.getenv("GEMINI_API_KEY"),
temperature=0.4,
)
# Custom Legal Research Tool
@tool("Legal Research Tool")
def legal_research_tool(query: str) -> str:
"""Searches for relevant legal information, regulations, and precedents
based on the provided legal query. Use this tool to find applicable laws,
regulatory frameworks, and legal principles relevant to the scenario."""
legal_knowledge = {
"gdpr": (
"GDPR (General Data Protection Regulation) - EU regulation effective May 2018. "
"Key principles: lawful basis for processing, data minimization, purpose limitation, "
"storage limitation, accountability. Fines up to 4% of annual global turnover or "
"20 million EUR. Requires explicit consent for data processing. Data subjects have "
"rights to access, rectification, erasure, portability. Data Protection Impact "
"Assessments required for high-risk processing."
),
"ccpa": (
"CCPA (California Consumer Privacy Act) - Effective January 2020, amended by CPRA 2023. "
"Applies to businesses with >$25M revenue, or processing 100k+ consumers' data, or "
"earning 50%+ revenue from selling personal info. Consumer rights: right to know, "
"right to delete, right to opt-out of sale, right to non-discrimination. "
"Fines: $2,500 per unintentional violation, $7,500 per intentional violation."
),
"employment": (
"Employment law key areas: At-will employment doctrine, wrongful termination, "
"discrimination (Title VII, ADA, ADEA), wage and hour laws (FLSA), "
"non-compete agreements (FTC 2024 rule), employee classification, "
"workplace safety (OSHA), family and medical leave (FMLA), "
"whistleblower protections, trade secret law (DTSA)."
),
"contract": (
"Contract law essentials: Offer, acceptance, consideration, capacity, legality. "
"Key clauses to review: indemnification, limitation of liability, termination, "
"intellectual property assignment, non-compete/non-solicitation, "
"confidentiality, dispute resolution (arbitration vs litigation), "
"governing law, force majeure, warranty disclaimers."
),
"ip": (
"Intellectual Property: Patents (utility, design, plant), Trademarks, "
"Copyrights, Trade Secrets. Key considerations: ownership assignment in "
"employment, work-for-hire doctrine, licensing terms, open source compliance, "
"patent infringement risks, trademark registration and enforcement."
),
}
query_lower = query.lower()
results = []
for topic, info in legal_knowledge.items():
if topic in query_lower or any(
keyword in query_lower
for keyword in topic.split()
):
results.append(info)
if not results:
results.append(
"General legal principle: Always consult jurisdiction-specific regulations. "
"Consider statutory requirements, case law precedents, regulatory guidance, "
"and industry best practices. Assess both civil and criminal liability exposure."
)
return "\n\n".join(results)
# Agent 1: Legal Researcher
legal_researcher = Agent(
role="Senior Legal Researcher",
goal=(
"Research and identify all relevant laws, regulations, legal precedents, "
"and regulatory frameworks applicable to the given legal scenario"
),
backstory=(
"You are an experienced legal researcher with 15 years of experience across "
"corporate law, regulatory compliance, and contract law. You excel at finding "
"relevant statutes, case law, and regulatory guidance. You always cite specific "
"laws and regulations by name."
),
llm=gemini_llm,
tools=[legal_research_tool],
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
# Agent 2: Risk and Compliance Analyst
risk_analyst = Agent(
role="Risk and Compliance Analyst",
goal=(
"Analyze the legal research findings and identify all potential risks, "
"compliance gaps, and liabilities with severity ratings"
),
backstory=(
"You are a meticulous risk analyst with a background in regulatory compliance "
"and corporate governance. You specialize in identifying legal exposure, rating "
"risks by severity (Critical, High, Medium, Low), and mapping compliance gaps "
"to specific regulatory requirements."
),
llm=gemini_llm,
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
# Agent 3: Senior Legal Advisor
senior_advisor = Agent(
role="Senior Legal Advisor",
goal=(
"Synthesize the research and risk analysis into a clear, actionable legal "
"opinion with specific recommendations and next steps"
),
backstory=(
"You are a senior corporate counsel with 20 years of experience advising "
"companies on complex legal matters. You are known for providing clear, "
"practical legal opinions that balance legal risk with business objectives. "
"You always structure your opinions with an executive summary, detailed "
"analysis, risk ratings, and actionable recommendations."
),
llm=gemini_llm,
verbose=True,
allow_delegation=False,
max_retry_limit=2,
)
# Task 1: Legal Research
research_task = Task(
description=(
"Conduct thorough legal research on the following scenario:\n\n"
"{scenario}\n\n"
"Use the Legal Research Tool to find all applicable laws, regulations, "
"and legal precedents. Identify the relevant jurisdictions and regulatory "
"bodies. Provide a comprehensive research summary with specific citations."
),
expected_output=(
"A detailed legal research report containing: applicable laws and regulations "
"with specific citations, relevant jurisdictions, key legal principles that "
"apply, and any relevant precedents or regulatory guidance."
),
agent=legal_researcher,
)
# Task 2: Risk Analysis
risk_task = Task(
description=(
"Based on the legal research provided, conduct a comprehensive risk and "
"compliance analysis. Identify all potential legal risks, compliance gaps, "
"and liabilities. Rate each risk by severity (Critical, High, Medium, Low) "
"and likelihood. Map each risk to the specific regulation or law it relates to."
),
expected_output=(
"A structured risk assessment containing: a risk matrix with severity and "
"likelihood ratings, specific compliance gaps identified, potential financial "
"exposure estimates where applicable, and regulatory penalties that could apply."
),
agent=risk_analyst,
)
# Task 3: Legal Opinion
opinion_task = Task(
description=(
"Synthesize the legal research and risk analysis into a comprehensive legal "
"opinion. Structure it with: Executive Summary, Detailed Analysis (organized "
"by issue), Risk Ratings, Recommended Actions (prioritized), and Next Steps. "
"Make recommendations practical and actionable for a business audience."
),
expected_output=(
"A professionally structured legal opinion in markdown format with: "
"Executive Summary, Detailed Legal Analysis, Risk Assessment Summary, "
"Prioritized Recommendations, and Immediate Next Steps. Each recommendation "
"should include estimated timeline and responsible party."
),
agent=senior_advisor,
output_file="legal_opinion.md",
)
# Assemble the Crew
legal_crew = Crew(
agents=[legal_researcher, risk_analyst, senior_advisor],
tasks=[research_task, risk_task, opinion_task],
process=Process.sequential,
verbose=True,
)
if __name__ == "__main__":
scenario = input("Describe your legal scenario:\n> ")
if not scenario.strip():
scenario = (
"Our startup wants to collect and sell anonymized user browsing data "
"to third-party advertisers. We have users in the EU and California. "
"What are the legal implications and what do we need to comply with?"
)
print(f"\nUsing sample scenario: {scenario}\n")
print("\n" + "=" * 60)
print("CORPORATE LEGAL ADVISER - Multi-Agent Analysis")
print("=" * 60 + "\n")
result = legal_crew.kickoff(inputs={"scenario": scenario})
print("\n" + "=" * 60)
print("LEGAL OPINION COMPLETE")
print("=" * 60)
print("\nFull opinion saved to: legal_opinion.md")
print("\n--- EXECUTIVE SUMMARY ---\n")
print(result.raw[:2000] if len(result.raw) > 2000 else result.raw)
Run the crew with a sample scenario
This is the moment where CrewAI takes over. Each agent will autonomously decide what to do, use its tools, and pass its output forward.
- Run your script by executing this command in your terminal:
python legal_crew.py
- When prompted with Describe your legal scenario:, press Enter without typing anything to use the built-in sample scenario.
What should I see?
Because verbose=True is set on the crew, you'll see detailed output from each agent as it works. The run may take 1-3 minutes depending on API response times.
- Agent 1 (Legal Researcher) starts first. You'll see it decide to use the Legal Research Tool, form a query, and receive legal information back.
- Agent 2 (Risk Analyst) receives the research output and begins identifying risks, rating them by severity, and mapping them to specific regulations.
- Agent 3 (Senior Advisor) synthesizes everything into a final legal opinion with an executive summary, risk ratings, and actionable recommendations.
Once the run finishes, you'll see LEGAL OPINION COMPLETE printed in the terminal along with a preview of the executive summary.
Verify the generated legal opinion
- Confirm the output file was created by running:
ls legal_opinion.md
- You should see legal_opinion.md listed in the output.
- Open legal_opinion.md in VS Code to read the full structured legal analysis. It should contain sections for the executive summary, detailed analysis, risk assessment, recommendations, and next steps.
Why is this different from a chatbot?
A regular chatbot sends one prompt to one model and returns one response. Your system just did something fundamentally different.
Each agent independently decided what actions to take based on its role and goal. The Legal Researcher chose to call the research tool. The Risk Analyst evaluated findings it had never seen before. The Senior Advisor structured everything into a professional opinion. No single prompt could produce this level of specialization.
Crew failed or timed out?
- If you see an authentication error, verify your GEMINI_API_KEY environment variable is still set in your current terminal session. Restarting the terminal clears it.
- If you see a rate limit error, wait 60 seconds and try again. The Gemini free tier has per-minute rate limits.
- If the script hangs for more than 5 minutes, press Ctrl+C to stop it, then run it again. Occasional timeouts happen with free-tier API calls.
- help me debug why my CrewAI crew is failing or timing out when running with Gemini
Secret mission
Add a Contract Clause Extractor
Your 3-agent crew already produces solid legal analysis. But what if it could parse raw contract text first, flagging problematic clauses before the research even begins? In this mission, you will add a fourth agent that extracts and rates dangerous clauses, then feeds that intelligence into the existing pipeline.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely locally with a free-tier API key, so there are no ongoing costs. Decide whether to keep your resources in place for future experiments, or delete them to free up disk space.
Resources you used:
- Local Python virtual environment (venv folder) and installed packages.
- Project files (legal_crew.py, legal_opinion.md).
- Gemini API key (free tier, no charges incurred).
- GEMINI_API_KEY environment variable on your system.
Keep everything running
No action needed. Choose this if you plan to keep experimenting with CrewAI, build more agents, or try different legal scenarios.
- Your virtual environment stays ready. Activate it again anytime with venv\Scripts\activate (Windows) or source venv/bin/activate (macOS/Linux).
- Your Gemini API key remains active and free to use.
- The GEMINI_API_KEY environment variable stays set for future projects.
Pause - I'll come back to this later
No persistent processes are running, so there is nothing to pause. Your files and virtual environment will be waiting for you when you return.
- If your terminal is still open with the virtual environment active, deactivate it by running:
deactivate
- Everything else stays in place at no cost.
Delete - I don't want to use this again
Remove all project resources and clean up your system. Follow all the steps below.
- Deactivate your virtual environment (if still active) by running:
deactivate
- Delete the virtual environment folder. On Windows, run:
rmdir /s /q venv
- On macOS/Linux, run:
rm -rf venv
- Delete the project files. On Windows, run:
del legal_crew.py
del legal_opinion.md
- On macOS/Linux, run:
rm legal_crew.py legal_opinion.md
- Remove the GEMINI_API_KEY environment variable. On Windows, search for "Environment Variables" in the Windows search bar, click Environment Variables, find GEMINI_API_KEY under User variables, select it, and click Delete.
- On macOS/Linux, remove the export GEMINI_API_KEY=... line from your ~/.bashrc or ~/.zshrc file.
- Delete your Gemini API key from Google AI Studio. Go to aistudio.google.com, open the Dashboard from the left panel, select API Keys, find the key you created for this project, and delete it.
Nice Work!
Nice Work!
You just built a fully functional multi-agent AI system that produces professional corporate legal analysis on demand. That is agentic AI in action.
You've learned how to:
- Build a multi-agent AI system with 3 specialized CrewAI agents that collaborate autonomously through sequential orchestration.
- Create a custom tool that agents use to perform legal research, demonstrating how the agentic AI loop works (receive a goal, decide actions, call tools, evaluate results, produce output).
- Configure CrewAI to use Google Gemini (free tier) as the underlying LLM via LiteLLM integration.
- Secret Mission: Extended the system with a contract clause extraction agent, demonstrating how to scale multi-agent architectures by adding new agents to a sequential pipeline.
Ready to quiz yourself?