1# review_crew.py
2
3from crewai import Agent, Crew, Process, Task
4from crewai_tools import FileReadTool
5from dotenv import load_dotenv
6
7load_dotenv()
8
9read_file = FileReadTool()
10
11# agents
12
13reader = Agent(
14 role="Contract analyst",
15 goal="Pull every commercially important term out of a contract, with its section number",
16 backstory=(
17 "You read contracts line by line for a procurement team. You quote "
18 "the contract rather than paraphrase it, and you always note the "
19 "section a term comes from."
20 ),
21 tools=[read_file],
22 verbose=True,
23)
24
25risk_analyst = Agent(
26 role="Commercial risk analyst",
27 goal="Spot the deadlines, costs, and one-sided terms that could hurt {customer}",
28 backstory=(
29 "You have reviewed hundreds of software agreements from the buyer's "
30 "side. You know which clauses cost customers money: automatic "
31 "renewals, price increases, short claim windows, and terms the "
32 "vendor can change on its own."
33 ),
34 verbose=True,
35)
36
37fact_checker = Agent(
38 role="Contract fact-checker",
39 goal="Make sure every claim in a contract memo matches the contract word for word",
40 backstory=(
41 "You are the last reviewer before a memo goes to the finance team. "
42 "You check every number, date, and section reference against the "
43 "source document and fix anything that does not match."
44 ),
45 tools=[read_file],
46 verbose=True,
47)
48
49# tasks
50
51extract_terms = Task(
52 description=(
53 "Read the contract at {contract_path}. List its key terms: parties, "
54 "dates, term and renewal, fees and payment, service levels, data "
55 "handling, termination, liability, and any clause that lets one "
56 "party change the deal on its own."
57 ),
58 expected_output="A bulleted list of key terms. Each bullet quotes the contract and ends with its section number.",
59 agent=reader,
60)
61
62assess_risks = Task(
63 description=(
64 "Using the key terms, write a risk memo for {customer}. Pick the five "
65 "terms most likely to cost them money or catch them out, and say what "
66 "they should do about each one."
67 ),
68 expected_output=(
69 "A Markdown memo of no more than 350 words: a two-sentence summary, then "
70 "a numbered list of five risks. Each risk has a section number, why it "
71 "matters, and a recommended action."
72 ),
73 agent=risk_analyst,
74)
75
76fact_check = Task(
77 description=(
78 "Check every claim in the risk memo against the contract at {contract_path}. "
79 "Fix any number, date, or section reference that does not match the "
80 "contract, and remove anything the contract does not say."
81 ),
82 expected_output="The corrected memo in Markdown, followed by a 'Corrections' section that lists each change you made, or says 'None'.",
83 agent=fact_checker,
84)
85
86crew = Crew(
87 agents=[reader, risk_analyst, fact_checker],
88 tasks=[extract_terms, assess_risks, fact_check],
89 process=Process.sequential,
90 verbose=True,
91)
92
93if __name__ == "__main__":
94 result = crew.kickoff(
95 inputs={
96 "contract_path": "contracts/acme-saas-agreement.md",
97 "customer": "Northwind Traders",
98 }
99 )
100 print(result.raw)