CrewAI Agent: A Financial Use Case
Thanks for dataset provided in this repo
pip install -U "crewai[tools]==0.102.0" python-dotenv==1.0.1
.env file (change to your own Azure OpenAI endpoint and API key)
OPENAI_API_TYPE=azure
AZURE_OPENAI_ENDPOINT=
AZURE_OPENAI_API_VERSION=2024-08-01-preview
AZURE_OPENAI_API_KEY=
AZURE_OPENAI_GPT4O_MODEL_NAME=gpt-4o-mini
AZURE_OPENAI_GPT4O_DEPLOYMENT_NAME=gpt-4o-mini
AZURE_OPENAI_EMBEDDING_API_VERSION=2023-05-15
AZURE_OPENAI_EMBEDDING_MODEL_NAME=text-embedding-3-small
AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME=text-embedding-3-small
Define LLM and embedding for CrewAI agent
import os
from crewai import LLM
from dotenv import load_dotenv
load_dotenv(".env")
# from langchain_logger.callback import ChainOfThoughtCallbackHandler
import logging
load_dotenv(".env")
api_key = os.getenv("AZURE_OPENAI_API_KEY")
azure_openai_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
api_version=os.getenv("AZURE_OPENAI_API_VERSION", "2024-08-01-preview")
import openai
openai.api_key = api_key
model_name = os.getenv("AZURE_OPENAI_GPT4O_MODEL_NAME", "gpt-4o-mini")
azure_deployment_name = os.getenv("AZURE_OPENAI_GPT4O_DEPLOYMENT_NAME", "gpt-4o-mini")
crewai_llm = LLM(model=f"azure/{model_name}", temperature=0.0, api_key=api_key, api_version=api_version)
crewai_embedder_config=dict(
# provider="azure_openai", # or openai, ollama, ...
provider="azure",
config=dict(
model=os.getenv("AZURE_OPENAI_EMBEDDING_MODEL_NAME"),
deployment_name=os.getenv("AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
api_base=os.getenv("AZURE_OPENAI_ENDPOINT"),
api_version=os.getenv("AZURE_OPENAI_EMBEDDING_API_VERSION"),
openai_api_version=os.getenv("AZURE_OPENAI_EMBEDDING_API_VERSION"),
openai_api_type="azure"
)
)
Define agent with LLM and embedding
from crewai import LLM, Agent, Crew, Process, Task
from crewai.knowledge.source.crew_docling_source import CrewDoclingSource
import os
def loan_assistant(file_path: str, customer_question: str) -> str:
# Create a knowledge source
content_source = CrewDoclingSource(
file_paths=[
file_path
],
)
llm = crewai_llm
loan_assistant_agent = Agent(
role="Loan Officer Assistant",
goal="Analyze bank statement and provide accurate insights about its contents",
allow_delegation=False,
verbose=True,
backstory=(
"""
You are a helpful bank loan officer. You are going to be given a bank statement
to analyse and you must provide accurate insights about its contents.
If a question doesn't make any sense, or is not factually coherent, explain what is wrong with the question instead of answering something incorrect. If you don't know the answer, don't share inaccurate information.
Your goal is to provide insightful answers about the financial background of an individual.
"""
),
llm=llm,
tools=[],
embedder=crewai_embedder_config
)
# --- Tasks ---
loan_assistant_task = Task(
description=("""
{customer_question}
"""),
expected_output="""
Answer the customer's question.
""",
tools=[],
agent=loan_assistant_agent,
)
# --- Crew ---
crew = Crew(
agents=[loan_assistant_agent],
tasks=[loan_assistant_task],
process=Process.sequential,
knowledge_sources=[
content_source
],
embedder=crewai_embedder_config
)
result = crew.kickoff(
inputs={"customer_question": customer_question}
)
return result.raw
Test 1
customer_question = """
I want to analyze the financial health of the individual based solely on the given statement. Here are some details I want information on:
1. Total monthly deposits (with months and amounts)
2. Total monthly withdrawals (with months and amounts)
3. Any recurring payments (such as rent, utilities, loan repayments - with descriptions, dates, and amounts)
4. Any other noticeable spending habits (with amounts)
Make sure your output is well formatted and is plain-text.
I want to determine if this individual should be awarded a business loan based on the above.
Give me a potential yes, potential no or cannot say answer and evidence your response from details from above. Be sure to highlight any noticeable red-flags or positive signs.
"""
file_path = "loan_officer_assistant/statement4.pdf"
result = loan_assistant(file_path, customer_question)
Result
# Agent: Loan Officer Assistant
## Task:
I want to analyze the financial health of the individual based solely on the given statement. Here are some details I want information on:
1. Total monthly deposits (with months and amounts)
2. Total monthly withdrawals (with months and amounts)
3. Any recurring payments (such as rent, utilities, loan repayments - with descriptions, dates, and amounts)
4. Any other noticeable spending habits (with amounts)
Make sure your output is well formatted and is plain-text.
I want to determine if this individual should be awarded a business loan based on the above.
Give me a potential yes, potential no or cannot say answer and evidence your response from details from above. Be sure to highlight any noticeable red-flags or positive signs.
# Agent: Loan Officer Assistant
## Final Answer:
**Financial Analysis of the Individual's Bank Statement**
1. **Total Monthly Deposits:**
- **December 2022:**
- 01 Dec: $40.00 (Direct Credit from Jessica Laing)
- 01 Dec: $1,000.00 (Transfer from xx8727 NetBank)
- 06 Dec: $700.00 (Transfer from xx8727 NetBank)
- 27 Dec: $20.00 (Direct Credit from Cameron Browning)
- **Total for December: $1,760.00**
- **January 2023:**
- 02 Jan: $40.00 (Direct Credit from Jessica Laing)
- 04 Jan: $800.00 (Transfer from xx8727 CommBank app)
- **Total for January: $840.00**
2. **Total Monthly Withdrawals:**
- **December 2022:**
- 01 Dec: $4.00 (Account Fee)
- 01 Dec: $70.00 (Transfer to xx6832 NetBank)
- 01 Dec: $122.25 (Direct Debit to HBF Health)
- 05 Dec: $700.00 (Transfer to other Bank)
- 06 Dec: $850.75 (Tax Office Payment)
- 07 Dec: $115.00 (Direct Debit to Telstra)
- 07 Dec: $27.90 (Direct Debit to Jetts Kingsway)
- 21 Dec: $56.42 (Direct Debit to SGIO)
- 21 Dec: $27.90 (Direct Debit to Jetts Kingsway)
- **Total for December: $1,974.17**
- **January 2023:**
- 01 Jan: $4.00 (Account Fee)
- 02 Jan: $122.25 (Direct Debit to HBF Health)
- 04 Jan: $70.00 (Transfer to xx6832 CommBank app)
- 04 Jan: $27.90 (Direct Debit to Jetts Kingsway)
- 05 Jan: $700.00 (Transfer to other Bank)
- 07 Jan: $115.00 (Direct Debit to Telstra)
- **Total for January: $1,039.15**
3. **Recurring Payments:**
- **HBF Health:** $122.25 (Direct Debit on 01 Dec, 02 Jan)
- **Telstra Corp Ltd:** $115.00 (Direct Debit on 07 Dec, 07 Jan)
- **Jetts Kingsway:** $27.90 (Direct Debit on 07 Dec, 04 Jan, 21 Dec)
- **SGIO:** $56.42 (Direct Debit on 21 Dec, 21 Nov)
- **Total Recurring Payments: $399.77**
4. **Other Noticeable Spending Habits:**
- **Tax Office Payment:** $850.75 (on 06 Dec)
- **Transfer to Other Bank:** $700.00 (on 05 Dec, 05 Jan)
- **Account Fees:** $4.00 (monthly)
- **Total Other Spending: $1,554.75**
**Conclusion:**
- **Total Deposits (Dec + Jan):** $2,600.00
- **Total Withdrawals (Dec + Jan):** $3,013.32
- **Net Cash Flow:** -$413.32 (indicating a negative cash flow)
**Potential Loan Decision:**
- **Potential No:** The individual has a negative cash flow over the analyzed period, which raises concerns about their ability to manage additional debt. The high amount of withdrawals, particularly the tax payment and transfers to other banks, could indicate financial strain. Additionally, the recurring payments are significant compared to the income, which may not support a business loan application.
**Red Flags:**
- Negative cash flow.
- High recurring payments relative to income.
- Significant tax payment indicating possible financial obligations.
**Positive Signs:**
- Regular income deposits, though not sufficient to cover expenses.
- No overdrafts or missed payments noted in the statement.
Overall, the financial health of this individual appears to be concerning, and it may not be advisable to award a business loan at this time.
Test 2
customer_question = """
What 5 questions you would ask the individual to determine whether they can get bank loan?
"""
file_path = "loan_officer_assistant/statement4.pdf"
result = loan_assistant(file_path, customer_question)
Result
# Agent: Loan Officer Assistant
## Task:
What 5 questions you would ask the individual to determine whether they can get bank loan?
# Agent: Loan Officer Assistant
## Final Answer:
To determine whether an individual can get a bank loan, I would ask the following five questions:
1. **What is your current employment status and income level?** Understanding the individual's job stability and income is crucial for assessing their ability to repay the loan.
2. **Do you have any existing debts or financial obligations?** This includes credit card debt, personal loans, or any other liabilities that could affect their debt-to-income ratio.
3. **What is your credit score?** A credit score provides insight into the individual's creditworthiness and their history of managing debt.
4. **How much do you intend to borrow, and what will the loan be used for?** Knowing the loan amount and its purpose helps in evaluating the risk and the individual's financial planning.
5. **Do you have any assets or savings that could be used as collateral?** This can provide additional security for the loan and may influence the bank's decision.
These questions will help in assessing the individual's financial background and their eligibility for a bank loan.
Structured output
CrewAI can return structured output like Pydantic. We need to specify output pydantic model in crewai task
Define pydantice model (a list of transactions)
from pydantic import BaseModel, Field
from typing import List, Dict
from crewai import Agent, Crew, Process, Task, LLM
from crewai.knowledge.source.crew_docling_source import CrewDoclingSource
import os
# Create a knowledge source
content_source = CrewDoclingSource(
file_paths=[
"loan_officer_assistant/statement4.pdf"
],
)
llm = crewai_llm
class BankStatementTransaction(BaseModel):
date: str = Field(description="date")
transaction: str = Field(description="transaction description")
debit: str = Field(description="debit amount")
credit: str = Field(description="credit amount")
balance: List[str] = Field(description="running balance")
class BankStatementTransactions(BaseModel):
transaction: List[BankStatementTransaction] = Field(description="list of transactions")
Define agent and task (notice “output_pydantic=BankStatementTransactions,” in task definition)
TransactionsAgent= Agent(
role="Transactions extraction",
goal=("Extract transactions from bank statement"
),
backstory=( "Extract transactions from bank statement"
),
allow_delegation=False,
llm=llm,
verbose=True,
embedder=crewai_embedder_config,
)
transactions_task = Task(
name="Transactions extraction Task",
description=(""" Read the provided document and extract transactions from the document."), """
),
agent=TransactionsAgent,
expected_output="A structured list of transactions.",
output_pydantic=BankStatementTransactions,
context= [],
sync_mode=True
)
crew = Crew(
agents=[TransactionsAgent],
tasks=[transactions_task],
process=Process.sequential,
knowledge_sources=[
content_source
],
embedder=crewai_embedder_config,
verbose=True,
)
result = crew.kickoff()
result.pydantic
BankStatementTransactions(transaction=[BankStatementTransaction(date='01 Dec', transaction='Account Fee', debit='4.00', credit='', balance=['$804.80 CR']), BankStatementTransaction(date='01 Dec', transaction='Direct Credit 421520 JESSICA LAING JL - Internet', debit='', credit='40.00', balance=['$844.80 CR']), BankStatementTransaction(date='01 Dec', transaction='Transfer from xx8727 NetBank', debit='', credit='1,000.00', balance=['$1,844.80 CR']), BankStatementTransaction(date='01 Dec', transaction='Transfer to xx6832 NetBank', debit='70.00', credit='', balance=['$1,774.80 CR']), BankStatementTransaction(date='01 Dec', transaction='Direct Debit 000702 HBF - HEALTH 1439123504', debit='122.25', credit='', balance=['$1,652.55 CR']), BankStatementTransaction(date='05 Dec', transaction='Transfer to other Bank NetBank Oronsay', debit='700.00', credit='', balance=['$952.55 CR']), BankStatementTransaction(date='06 Dec', transaction='TAX OFFICE PAYMENTS NetBank BPAY 75556 551004045508468221 ATO tax 2016 to 20', debit='850.75', credit='', balance=['$101.80 CR']), BankStatementTransaction(date='06 Dec', transaction='Transfer from xx8727 NetBank', debit='', credit='700.00', balance=['$801.80 CR']), BankStatementTransaction(date='07 Dec', transaction='TELSTRA CORP LTD NetBank BPAY 23796 2000353972134', debit='115.00', credit='', balance=['$686.80 CR']), BankStatementTransaction(date='07 Dec', transaction='Direct Debit 165969 JETTS KINGSWAY 201727539277', debit='27.90', credit='', balance=['$658.90 CR']), BankStatementTransaction(date='21 Dec', transaction='Direct Debit 180247 SGIO MOT563142623171221', debit='56.42', credit='', balance=['$602.48 CR']), BankStatementTransaction(date='21 Dec', transaction='Direct Debit 165969 JETTS KINGSWAY 201728541361', debit='', credit='', balance=['$574.58 CR']), BankStatementTransaction(date='27 Dec', transaction='Direct Credit 106600 CAMERON BROWNING Ool party thanks x', debit='', credit='20.00', balance=['$594.58 CR']), BankStatementTransaction(date='01 Jan', transaction='Account Fee', debit='4.00', credit='', balance=['$590.58 CR']), BankStatementTransaction(date='02 Jan', transaction='Direct Credit 421520 JESSICA LAING JL - Internet', debit='', credit='40.00', balance=['$630.58 CR']), BankStatementTransaction(date='02 Jan', transaction='Direct Debit 000702 HBF - HEALTH 1439123504', debit='122.25', credit='', balance=['$508.33 CR']), BankStatementTransaction(date='04 Jan', transaction='Transfer from xx8727 CommBank app', debit='', credit='800.00', balance=['$1,308.33 CR']), BankStatementTransaction(date='04 Jan', transaction='Transfer to xx6832 CommBank app', debit='70.00', credit='', balance=['$1,238.33 CR']), BankStatementTransaction(date='04 Jan', transaction='Direct Debit 165969 JETTS KINGSWAY 2018270979', debit='27.90', credit='', balance=['$1,210.43 CR']), BankStatementTransaction(date='05 Jan', transaction='Transfer to other Bank NetBank Oronsay', debit='700.00', credit='', balance=['$510.43 CR']), BankStatementTransaction(date='07 Jan', transaction='TELSTRA CORP LTD NetBank BPAY 23796', debit='115.00', credit='', balance=['$395.43 CR']), BankStatementTransaction(date='13 Jan 2018', transaction='CLOSING BALANCE', debit='', credit='', balance=['$395.43 CR'])])