Building CareerAgent: An AI-Powered Job Search Assistant with LangChain and Gemini

Have you ever wished for an AI assistant that could analyze your resume, find matching jobs, and even write cover letters for you? That's exactly what I built with CareerAgent, my submission for Quira Quest 25! The Problem Job searching is a tedious, time-consuming process that involves: Figuring out which job titles match your skills Searching through numerous job boards Customizing cover letters for each application Tracking applications and responses It's a perfect candidate for automation with AI, especially with the capabilities of modern LLMs and agent frameworks. Enter CareerAgent CareerAgent is a practical AI assistant that streamlines the entire job application process, built with LangChain and Google's Gemini 2.0 Flash LLM. It demonstrates how we can use AI agents to create coherent workflows for real-world problems. Here's what it does: Resume Analysis: Extracts and analyzes PDF resumes Job Title Suggestions: Recommends suitable job titles based on your experience Keyword Extraction: Identifies relevant keywords for job searching Job Search: Integrates with the Jooble API to find actual job listings Cover Letter Generation: Creates tailored cover letters for specific jobs Document Export: Saves cover letters as PDF or DOCX files The Technology Stack LangChain: For agent structure, tool definitions, and workflows Google Gemini 2.0 Flash: The LLM powering the intelligence Streamlit: For the user interface PyMuPDF: For PDF text extraction Jooble API: For retrieving real job listings python-docx & pdfkit: For document generation Building the Agent The core of the application is the LangChain agent structure. Here's how I approached it: 1. Tool Definitions First, I defined a set of tools to handle each job search task: tools = [ Tool( name="analyze_resume", description="Analyze a resume and extract key information", func=lambda query: CareerTools.analyze_resume(resume_text, query), ), Tool( name="suggest_job_titles", description="Suggest job titles based on resume content", func=lambda _: CareerTools.suggest_job_titles(resume_text), ), # More tools... ] 2. Agent Initialization Then, I initialized the LangChain agent with these tools: agent = initialize_agent( tools=tools, llm=llm, agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION, verbose=True, handle_parsing_errors=True, max_iterations=3, memory=ConversationBufferMemory(memory_key="chat_history", return_messages=True) ) 3. Workflow Implementation The application follows this step-by-step workflow: Upload Resume: User uploads their PDF resume Resume Analysis: System processes and extracts text from the PDF User Action Choice: User can choose to search jobs or get recommendations Keyword Extraction: For job search, the system extracts relevant keywords API Request: System queries Jooble API with extracted keywords Display Results: Job listings are displayed in the UI Job Selection: User selects a specific job listing Cover Letter Generation: System creates a customized cover letter Export Options: User can save the cover letter as PDF or DOCX This workflow combines several AI-powered steps with user decisions to create a seamless job application process. Key Insights From Building This Project 1. Prompt Engineering is Crucial For resume analysis and cover letter generation, prompt design makes a huge difference: prompt = PromptTemplate( template=""" You are a professional career advisor. Write a tailored cover letter for a job application. RESUME: {resume_text} JOB DETAILS: Title: {job_title} Company: {job_company} Description: {job_description} Write a professional cover letter that highlights the candidate's relevant experience and skills for this specific job. Format it as a proper business letter. """, input_variables=["resume_text", "job_title", "job_company", "job_description"] ) 2. Agent Structure Matters I initially built a simpler version but refactored to use LangChain's proper agent structure with: Defined tools with clear responsibilities Sequential chains for multi-step tasks Proper memory management for contextual awareness 3. Error Handling is Essential When dealing with external APIs and document processing, robust error handling is critical: try: jobs = fetch_job_listings(query) if not jobs: return {"status": "error", "message": "No jobs found matching your query."} # Process jobs... except ToolException as e: return {"status": "error", "message": f"Error searching for jobs: {str(e)}"} The User Experience The app interface is built with Streamlit and provides an intuitive workflow: Upload resume: Start by uploading a PDF resume Search for jobs: U

Apr 13, 2025 - 19:56
 0
Building CareerAgent: An AI-Powered Job Search Assistant with LangChain and Gemini

CareerAgent Demo Video

Have you ever wished for an AI assistant that could analyze your resume, find matching jobs, and even write cover letters for you? That's exactly what I built with CareerAgent, my submission for Quira Quest 25!

The Problem

Job searching is a tedious, time-consuming process that involves:

  • Figuring out which job titles match your skills
  • Searching through numerous job boards
  • Customizing cover letters for each application
  • Tracking applications and responses

It's a perfect candidate for automation with AI, especially with the capabilities of modern LLMs and agent frameworks.

Enter CareerAgent

CareerAgent is a practical AI assistant that streamlines the entire job application process, built with LangChain and Google's Gemini 2.0 Flash LLM. It demonstrates how we can use AI agents to create coherent workflows for real-world problems.

Here's what it does:

  1. Resume Analysis: Extracts and analyzes PDF resumes
  2. Job Title Suggestions: Recommends suitable job titles based on your experience
  3. Keyword Extraction: Identifies relevant keywords for job searching
  4. Job Search: Integrates with the Jooble API to find actual job listings
  5. Cover Letter Generation: Creates tailored cover letters for specific jobs
  6. Document Export: Saves cover letters as PDF or DOCX files

The Technology Stack

  • LangChain: For agent structure, tool definitions, and workflows
  • Google Gemini 2.0 Flash: The LLM powering the intelligence
  • Streamlit: For the user interface
  • PyMuPDF: For PDF text extraction
  • Jooble API: For retrieving real job listings
  • python-docx & pdfkit: For document generation

Building the Agent

The core of the application is the LangChain agent structure. Here's how I approached it:

1. Tool Definitions

First, I defined a set of tools to handle each job search task:

tools = [
    Tool(
        name="analyze_resume",
        description="Analyze a resume and extract key information",
        func=lambda query: CareerTools.analyze_resume(resume_text, query),
    ),
    Tool(
        name="suggest_job_titles",
        description="Suggest job titles based on resume content",
        func=lambda _: CareerTools.suggest_job_titles(resume_text),
    ),
    # More tools...
]

2. Agent Initialization

Then, I initialized the LangChain agent with these tools:

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,
    verbose=True,
    handle_parsing_errors=True,
    max_iterations=3,
    memory=ConversationBufferMemory(memory_key="chat_history", return_messages=True)
)

3. Workflow Implementation

The application follows this step-by-step workflow:

  1. Upload Resume: User uploads their PDF resume
  2. Resume Analysis: System processes and extracts text from the PDF
  3. User Action Choice: User can choose to search jobs or get recommendations
  4. Keyword Extraction: For job search, the system extracts relevant keywords
  5. API Request: System queries Jooble API with extracted keywords
  6. Display Results: Job listings are displayed in the UI
  7. Job Selection: User selects a specific job listing
  8. Cover Letter Generation: System creates a customized cover letter
  9. Export Options: User can save the cover letter as PDF or DOCX

This workflow combines several AI-powered steps with user decisions to create a seamless job application process.

Key Insights From Building This Project

1. Prompt Engineering is Crucial

For resume analysis and cover letter generation, prompt design makes a huge difference:

prompt = PromptTemplate(
    template="""
    You are a professional career advisor. Write a tailored cover letter for a job application.

    RESUME:
    {resume_text}

    JOB DETAILS:
    Title: {job_title}
    Company: {job_company}
    Description: {job_description}

    Write a professional cover letter that highlights the candidate's relevant experience and skills
    for this specific job. Format it as a proper business letter.
    """,
    input_variables=["resume_text", "job_title", "job_company", "job_description"]
)

2. Agent Structure Matters

I initially built a simpler version but refactored to use LangChain's proper agent structure with:

  • Defined tools with clear responsibilities
  • Sequential chains for multi-step tasks
  • Proper memory management for contextual awareness

3. Error Handling is Essential

When dealing with external APIs and document processing, robust error handling is critical:

try:
    jobs = fetch_job_listings(query)

    if not jobs:
        return {"status": "error", "message": "No jobs found matching your query."}

    # Process jobs...

except ToolException as e:
    return {"status": "error", "message": f"Error searching for jobs: {str(e)}"}

The User Experience

The app interface is built with Streamlit and provides an intuitive workflow:

  1. Upload resume: Start by uploading a PDF resume
  2. Search for jobs: Use the form to search by keywords/title
  3. Browse results: View matching job listings
  4. Generate cover letters: Create tailored cover letters for specific positions
  5. Export documents: Save as PDF or DOCX files

Demo

Check out the full demo video to see it in action:

CareerAgent Demo

What Makes This an Agent?

CareerAgent isn't just an application with LLM integration. It's a true AI agent because it:

  1. Makes decisions: Determines appropriate job matches and cover letter content
  2. Uses tools: Leverages different tools for specific tasks
  3. Follows workflows: Executes multi-step processes to achieve goals
  4. Maintains context: Uses memory to provide coherent assistance
  5. Takes actions: Performs concrete steps toward the user's job search goals

Try It Yourself

Want to try CareerAgent or build on it? The code is available on GitHub:

CareerAgent Repository

Installation

# Clone the repository
git clone https://github.com/sharmachaitanya945/CareerAgent-AI-Powered-Job-Assistant.git

# Install dependencies
pip install langchain langchain_google_genai streamlit pymupdf requests python-docx pdfkit

# Set environment variables
export GOOGLE_API_KEY="your_google_api_key"  
export JOOBLE_API_KEY="your_jooble_api_key"

# Run the application
streamlit run main.py

Future Enhancements

I'm planning several enhancements:

  • Integration with more job search APIs
  • Resume improvement suggestions
  • Interview preparation assistance
  • Application tracking features

Conclusion

Building CareerAgent has shown me how powerful the combination of LLMs and agent frameworks can be for creating practical applications. The key insight is that structuring agents properly with well-defined tools and workflows allows them to tackle complex real-world problems effectively.

What do you think? Would you use an AI agent like this for your job search? What other features would you like to see?

Share your thoughts in the comments!

This project was created for Quira Quest 25, April 2025.