Skip to content

Commit

Permalink
ADDED: Job Posting Agent
Browse files Browse the repository at this point in the history
  • Loading branch information
AquibPy committed Jun 28, 2024
1 parent a79e18b commit 588c797
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 1 deletion.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,17 @@ percentage, missing keywords, and profile summary.
- **File Upload:** Users can upload audio or video files in various formats.
- **Transcription:** The API uses the OpenAI Whisper model to transcribe the uploaded file into text.

### 28. Job Posting Agent

- **Route:** `/job_posting_agent`
- **Description:** This API endpoint coordinates a team of AI agents to generate a detailed and engaging job posting tailored to the company's culture and values.
- **Feature:**
- **Input Data:** Users can provide input data including company description, company domain, hiring needs, and specific benefits.
- **Company Culture and Values Analysis:** The research analyst agent analyzes the company's website and provided description to extract insights on culture, values, and specific needs.
- **Role Requirements Identification:** The research analyst agent identifies the key skills, experiences, and qualities the ideal candidate should possess based on the company's needs, projects, competitive landscape, and industry trends.
- **Job Posting Drafting:** The job description writer agent uses the insights to create a detailed, engaging, and enticing job posting that aligns with the company's culture and values.
- **Review and Editing:** The review and editing specialist agent reviews the job posting for clarity, engagement, grammatical accuracy, and alignment with company values, refining it to ensure perfection.

## Usage

Each endpoint accepts specific parameters as described in the respective endpoint documentation. Users can make POST requests to these endpoints with the required parameters to perform the desired tasks.
Expand Down
61 changes: 60 additions & 1 deletion api.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from tech_news_agent.crew import run_crew
from investment_risk_analyst_agent.crew import run_investment_crew
from agent_doc.crew import run_doc_crew
from job_posting_agent.crew import run_job_crew
from langchain.agents import AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
from langchain_cohere.react_multi_hop.agent import create_cohere_react_agent
Expand Down Expand Up @@ -870,7 +871,7 @@ async def run_doc_agent(request:Request,gender: str = Form("Male"),

try:
input_data = {"gender": gender,
"risk_tolerance": age,
"age": age,
"symptoms": symptoms,
"medical_history": medical_history
}
Expand Down Expand Up @@ -934,6 +935,64 @@ async def transcribe_audio_video(request: Request, file: UploadFile = File(...))
return JSONResponse(content={"transcription": transcription.text})
except Exception as e:
return JSONResponse(content={"error": str(e)}, status_code=500)

@app.post("/job_posting_agent",description="""
This endpoint generates a job posting by analyzing the company's website and description.
Multiple agents work together to produce a detailed, engaging, and well-aligned job posting.
NOTE : Output will take some time as multiple agents are working together.
""")
@limiter.limit("2/30minute")
async def run_job_agent(request:Request,
company_description: str = Form("""Microsoft is a global technology company that develops, manufactures, licenses, supports,
and sells a wide range of software products, services, and devices, including the Windows operating system,
Office suite, Azure cloud services, and Surface devices."""),
company_domain : str = Form("https://www.microsoft.com/"),
hiring_needs: str = Form("Data Scientist"),
specific_benefits : str = Form("work from home, medical insurance, generous parental leave, on-site fitness centers, and stock purchase plan"),
token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, os.getenv("TOKEN_SECRET_KEY"), algorithms=[settings.ALGORITHM])
email = payload.get("sub")
if email is None:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
user = users_collection.find_one({"email": email})
if user is None:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found")
except JWTError:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")

try:
input_data = {"company_description": company_description,
"company_domain": company_domain,
"hiring_needs": hiring_needs,
"specific_benefits": specific_benefits
}
print(input_data)
cache_key = f"job_posting_agent:{input_data}"
cached_response = redis.get(cache_key)
if cached_response:
print("Retrieving response from Redis cache")
return ResponseText(response=cached_response.decode("utf-8"))

jd = run_job_crew(input_data)
redis.set(cache_key, jd, ex=10)
db = MongoDB()
payload = {
"endpoint": "/job_posting_agent",
"Company Description" : company_description,
"Company Domain" : company_domain,
"Hiring Needs" : hiring_needs,
"Specific Benefits" : specific_benefits,
"Job Description": jd
}
mongo_data = {"Document": payload}
result = db.insert_data(mongo_data)
print(result)
return ResponseText(response=jd)
except Exception as e:
return {"error": str(e)}


if __name__ == '__main__':
import uvicorn
Expand Down
45 changes: 45 additions & 0 deletions job_posting_agent/agents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from crewai import Agent
from .tools import web_search_tool, serper_search_tool
import os
import settings
from langchain_google_genai import ChatGoogleGenerativeAI

llm=ChatGoogleGenerativeAI(model=settings.GEMINI_FLASH,
verbose=True,
temperature=0.7,
google_api_key=os.getenv("GOOGLE_API_KEY"))


class JobAgents():
def research_agent(self):
return Agent(
role = "Research Analyst",
goal = "Analyze the company website and provided description to extract insights on culture, values, and specific needs.",
tools = [web_search_tool,serper_search_tool],
backstory = "Expert in analyzing company cultures and identifying key values and needs from various sources, including websites and brief descriptions.",
llm = llm,
verbose = True,
allow_delegation=False
)

def writer_agent(self):
return Agent(
role='Job Description Writer',
goal='Use insights from the Research Analyst to create a detailed, engaging, and enticing job posting.',
tools= [web_search_tool,serper_search_tool],
backstory='Skilled in crafting compelling job descriptions that resonate with the company\'s values and attract the right candidates.',
llm = llm,
verbose=True,
allow_delegation=False
)

def review_agent(self):
return Agent(
role='Review and Editing Specialist',
goal='Review the job posting for clarity, engagement, grammatical accuracy, and alignment with company values and refine it to ensure perfection.',
tools= [web_search_tool,serper_search_tool],
backstory='A meticulous editor with an eye for detail, ensuring every piece of content is clear, engaging, and grammatically perfect.',
llm = llm,
verbose=True,
allow_delegation=False
)
45 changes: 45 additions & 0 deletions job_posting_agent/crew.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from crewai import Crew
from dotenv import load_dotenv
load_dotenv()
from .tasks import Tasks
from .agents import JobAgents

tasks = Tasks()
agents = JobAgents()

researcher_agent = agents.research_agent()
writer_agent = agents.writer_agent()
review_agent = agents.review_agent()

research_company_culture_task = tasks.research_company_culture_task(researcher_agent)
industry_analysis_task = tasks.industry_analysis_task(researcher_agent)
research_role_requirements_task = tasks.research_role_requirements_task(researcher_agent)
draft_job_posting_task = tasks.draft_job_posting_task(writer_agent)
review_and_edit_job_posting_task = tasks.review_and_edit_job_posting_task(review_agent)

job_crew = Crew(
agents=[researcher_agent, writer_agent, review_agent],
tasks=[
research_company_culture_task,
industry_analysis_task,
research_role_requirements_task,
draft_job_posting_task,
review_and_edit_job_posting_task
],
verbose=True
)


def run_job_crew(input_data):
result = job_crew.kickoff(input_data)
return result

if __name__=='__main__':
job_agent_input = {
'company_description': 'Microsoft is a global technology company that develops, manufactures, licenses, supports, and sells a wide range of software products, services, and devices, including the Windows operating system, Office suite, Azure cloud services, and Surface devices.',
'company_domain': 'https://www.microsoft.com/',
'hiring_needs': 'Data Scientist',
'specific_benefits': 'work from home, medical insurance, generous parental leave, on-site fitness centers, and stock purchase plan'
}

print(run_job_crew(job_agent_input))
67 changes: 67 additions & 0 deletions job_posting_agent/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from textwrap import dedent
from crewai import Task

class Tasks():
def research_company_culture_task(self, agent):
return Task(
description=dedent("""\
Analyze the provided company website and the hiring manager's company's domain ({company_domain}), description: "{company_description}".
Focus on understanding the company's culture, values, and mission. Identify unique selling points and specific projects or achievements highlighted on the site.
Compile a report summarizing these insights, specifically how they can be leveraged in a job posting to attract the right candidates."""),
expected_output=dedent("""\
A comprehensive report detailing the company's culture, values, and mission, along with specific selling points relevant to the job role.
Suggestions on incorporating these insights into the job posting should be included."""),
agent=agent
)

def research_role_requirements_task(self, agent):
return Task(
description=dedent("""\
Based on the hiring manager's needs: "({hiring_needs})", identify the key skills, experiences, and qualities the ideal candidate should possess for the role.
Consider the company's current projects, its competitive landscape, and industry trends.
Prepare a list of recommended job requirements and qualifications that align with the company's needs and values."""),
expected_output=dedent("""\
A list of recommended skills, experiences, and qualities for the ideal candidate, aligned with the company's culture,
ongoing projects, and the specific role's requirements."""),
agent=agent
)

def draft_job_posting_task(self, agent):
return Task(
description=dedent("""\
Draft a job posting for the role described by the hiring manager: "({hiring_needs})".
Use the insights on "({company_description})" to start with a compelling introduction, followed by a detailed role description, responsibilities,
and required skills and qualifications. Ensure the tone aligns with the company's culture and incorporate any unique benefits or opportunities offered by the company.
Specfic benefits: "({specific_benefits})"""),
expected_output=dedent("""\
A detailed, engaging job posting that includes an introduction, role description, responsibilities, requirements, and unique company benefits.
The tone should resonate with the company's culture and values, aimed at attracting the right candidates."""),
agent=agent
)

def review_and_edit_job_posting_task(self, agent):
return Task(
description=dedent("""\
Review the draft job posting for the role: "({hiring_needs})".
Check for clarity, engagement, grammatical accuracy, and alignment with the company's culture and values.
Edit and refine the content, ensuring it speaks directly to the desired candidates and accurately reflects the role's unique benefits and opportunities.
Provide feedback for any necessary revisions."""),
expected_output=dedent("""\
A polished, error-free job posting that is clear, engaging, and perfectly aligned with the company's culture and values.
Feedback on potential improvements and final approval for publishing. Formated in markdown."""),
agent=agent
)

def industry_analysis_task(self, agent):
return Task(
description=dedent("""\
Conduct an in-depth analysis of the industry related to the company's domain: "({company_domain})".
Investigate current trends, challenges, and opportunities within the industry, utilizing market reports, recent developments, and expert opinions.
Assess how these factors could impact the role being hired for and the overall attractiveness of the position to potential candidates.
Consider how the company's position within this industry and its response to these trends could be leveraged to attract top talent.
Include in your report how the role contributes to addressing industry challenges or seizing opportunities."""),
expected_output=dedent("""\
A detailed analysis report that identifies major industry trends, challenges, and opportunities relevant to the company's domain and the specific job role.
This report should provide strategic insights on positioning the job role and the company as an attractive choice for potential candidates."""),
agent=agent
)
29 changes: 29 additions & 0 deletions job_posting_agent/tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from crewai_tools import SerperDevTool, WebsiteSearchTool
import os
from dotenv import load_dotenv
load_dotenv()

os.environ['SERPER_API_KEY'] = os.getenv('SERPER_API_KEY')

serper_search_tool = SerperDevTool()
web_search_tool = WebsiteSearchTool(
config=dict(
llm=dict(
provider="google", # or google, openai, anthropic, llama2, ...
config=dict(
model="gemini-1.5-flash-latest",
# temperature=0.5,
# top_p=1,
# stream=true,
),
),
embedder=dict(
provider="google", # or openai, ollama, ...
config=dict(
model="models/embedding-001",
task_type="retrieval_document",
# title="Embeddings",
),
),
)
)

0 comments on commit 588c797

Please sign in to comment.