An intelligent agentic AI system built with LangGraph and LangChain to automate LinkedIn job searching and application processes.
Get up and running in 3 minutes:
# 1. Install dependencies
pip install -r requirements.txt
# 2. Set your API key
export ANTHROPIC_API_KEY=your_key_here
# 3. Start the agent
langgraph dev- Click the "Chat" tab in LangGraph Studio
- Start chatting:
"Find me ML engineer jobs in Seattle"
- β Intelligent job search based on user criteria
- β Detailed job information retrieval
- β AI-powered cover letter generation
- β Conversational interface for job hunting
- β Tool-calling agent architecture with LangGraph
- π Automated job applications via LinkedIn Easy Apply
- π Resume optimization for specific jobs
- π Application tracking and status monitoring
- π Referral network analysis
- π Interview preparation assistance
- π Salary research and negotiation tips
- π Browser automation with Playwright
- π Persistent storage with MongoDB/PostgreSQL
- Python 3.10 or higher
- Anthropic API key (for Claude)
- LangSmith account (optional, for monitoring)
# Create project directory
mkdir linkedin-job-agent
cd linkedin-job-agent
# Create virtual environment
python -m venv .venv
# Activate virtual environment
# On macOS/Linux:
source .venv/bin/activate
# On Windows:
source .venv/Scripts/activate
# Install LangGraph CLI
pip install langgraph-cliCreate the following structure:
linkedin-job-agent/
βββ linkedin_agent/
β βββ __init__.py
β βββ agent.py # Main agent code
β βββ advanced_agent.py # Multi-agent system
β βββ tools.py # Extended tools
β βββ real_linkedin_scraper.py # LinkedIn job scraper
β βββ utils.py # Utility functions
βββ .env # Environment variables
βββ .env.example # Example environment file
βββ requirements.txt # Python dependencies
βββ langgraph.json # LangGraph configuration
βββ .gitignore # Git ignore rules
βββ README.md # Main documentation
βββ DEPLOYMENT.md # Production deployment
pip install -r requirements.txt# Copy example environment file
cp .env.example .env
# Edit .env and add your API keys
nano .env # or use your preferred editorRequired variables:
ANTHROPIC_API_KEY=your_anthropic_api_key_hereOptional but recommended:
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=your_langsmith_key_here
LANGCHAIN_PROJECT=linkedin-job-agentStart the development server with hot reloading:
langgraph devThis will:
- Start the LangGraph server on
http://127.0.0.1:2024 - Open LangGraph Studio in your browser
- Enable hot-reloading for development
LangGraph Studio URL:
https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024
LangGraph Studio provides two interfaces:
Chat Mode - Simple conversational interface:
- Click the "Chat" tab at the top
- Clean chat interface for testing
- Real-time streaming responses
- Perfect for demos and quick testing
Graph Mode - Technical debugging view:
- Visual execution graph
- Node-by-node tracking
- State inspection
- Time travel debugging
- LangSmith integration
from langgraph_sdk import get_sync_client
client = get_sync_client(url="http://localhost:2024")
# Stream responses
for chunk in client.runs.stream(
None,
"linkedin_job_agent",
input={
"messages": [{
"role": "human",
"content": "Find me AI engineer jobs in San Francisco"
}]
},
stream_mode="values"
):
print(chunk)python linkedin_agent/agent.pyUser: Find me machine learning engineer jobs in New York
Agent: I'll search for machine learning engineer positions in New York for you.
[Searches LinkedIn and fetches REAL jobs...]
Found 15 LIVE jobs from LinkedIn:
1. Senior ML Engineer at OpenAI
Location: New York, NY (Hybrid)
Salary: $180k-$250k
Posted: 2 days ago
URL: https://www.linkedin.com/jobs/view/3789456123
2. Machine Learning Engineer at Google
Location: New York, NY
Posted: 1 week ago
URL: https://www.linkedin.com/jobs/view/3789456124
Would you like more details on any of these positions?
User: Apply to the TechCorp position and generate a cover letter
Agent: I'll generate a personalized cover letter for the Senior ML Engineer
position at TechCorp. Let me analyze the job requirements first...
[Generates cover letter based on job description and your profile]
Here's your cover letter:
[Shows generated cover letter]
Would you like me to proceed with the application?
User: Show me only remote positions that mention Python and deep learning
Agent: Filtering jobs for remote positions with Python and deep learning...
[Applies filters...]
Found 8 matching positions. Here are the top 3:
[Shows filtered results with match scores]
graph TD
A[User Input] --> B[Agent Node]
B --> C{Tool Call?}
C -->|Yes| D[Tools Node]
C -->|No| E[End]
D --> F[Execute Tool]
F --> B
- StateGraph: Manages conversation state and job search context
- Agent Node: Main reasoning node using LLM with tool binding
- Tools Node: Executes tools (search, apply, generate cover letter)
- Conditional Edges: Routes between agent and tools based on LLM decision
| Tool | Description | Status |
|---|---|---|
search_linkedin_jobs |
Search LinkedIn for real jobs | β Live |
get_job_details |
Get detailed job information | β Live |
generate_cover_letter |
Create personalized cover letter | β Implemented |
apply_to_job |
Apply to a job posting | βοΈ Stub (Ready to extend) |
update_user_preferences |
Save job search preferences | π Available in tools.py |
analyze_job_match |
Match score for job fit | π Available in tools.py |
find_referrals |
Find connections at companies | π Available in tools.py |
{
"dependencies": ["."],
"graphs": {
"linkedin_job_agent": "./linkedin_agent/agent.py:graph"
},
"env": ".env"
}Change the LLM model:
# Use Claude Sonnet 4 (default)
llm = ChatAnthropic(model="claude-sonnet-4-20250514", temperature=0)
# Or use Claude Opus 4.1 for more complex reasoning
llm = ChatAnthropic(model="claude-opus-4-20250514", temperature=0)
# Or switch to OpenAI (requires OPENAI_API_KEY)
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o", temperature=0)Change scraping method:
# Default: Public scraper (no auth)
from linkedin_agent.real_linkedin_scraper import LinkedInJobScraper
scraper = LinkedInJobScraper()
# Or use library method (more features)
# pip install linkedin-jobs-scraper
from linkedin_agent.real_linkedin_scraper import LinkedInJobsLibraryScraper
scraper = LinkedInJobsLibraryScraper()
# Or use API method (requires credentials)
# pip install linkedin-api
from linkedin_agent.real_linkedin_scraper import LinkedInAPIClient
scraper = LinkedInAPIClient()Add custom tools:
@tool
def my_custom_tool(param: str) -> dict:
"""Your tool description"""
# Implementation
return {"result": "success"}
# Add to tools list
tools = [search_linkedin_jobs, my_custom_tool]Modify system prompt:
Edit the SystemMessage content in agent_node() function.
Enable tracing to monitor agent performance:
export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY=your_api_key
export LANGCHAIN_PROJECT=linkedin-job-agent
export ANTHROPIC_API_KEY=your_anthropic_keyView traces at: https://smith.langchain.com
- Never commit
.envfile - Add to.gitignore - LinkedIn credentials - Use environment variables only
- Rate limiting - Implement to avoid account restrictions
- API quotas - Monitor Anthropic/LLM usage
- User data - Encrypt stored resumes and applications
The foundation is complete! Here are ideas for extending the agent:
Currently stubbed - ready to implement with:
- Browser automation (Playwright/Selenium)
- Form filling and submission
- LinkedIn Easy Apply integration
- Application confirmation and tracking
Use LLM to:
- Parse existing resumes
- Optimize for specific job descriptions
- Highlight relevant experience
- Format for ATS systems
Implement with database (MongoDB/PostgreSQL):
- Application history
- Status updates
- Interview scheduling
- Follow-up reminders
- Connection analysis
- Referral requests
- Message drafting
- Network visualization
See the extended tools in linkedin_agent/tools.py for ready-to-use functions!
The agent includes built-in test functionality:
# Test the scraper directly
python linkedin_agent/real_linkedin_scraper.py
# Test the main agent
python linkedin_agent/agent.py
# Run with LangGraph Studio (recommended)
langgraph devAll core features are working and ready to use!
Ideas for extending the agent beyond current functionality:
- Browser automation for Easy Apply
- Automated form filling
- Application status tracking
- Follow-up scheduling
- Multi-agent system with specialized roles
- RAG for job description analysis
- Resume parsing and optimization
- Interview scheduling assistant
- Salary negotiation advisor
- Network analysis for referrals
- Email integration
- Mobile app interface
- Voice interface
- Analytics dashboard
All foundational features are complete - these are optional enhancements!
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit changes (
git commit -m 'Add AmazingFeature') - Push to branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Start with the mock implementation to understand the flow
- Test thoroughly before connecting to real LinkedIn
- Use LangSmith for debugging agent behavior
- Implement rate limiting to avoid API restrictions
- Store user data securely with encryption
- β
Already configured in
langgraph.json - Check that file is in project root
- Verify the graph path matches:
./linkedin_agent/agent.py:graph
- Activate virtual environment
- Run
pip install -r requirements.txt - Check Python version (3.10+)
- Ensure port 2024 is not in use
- Try
langgraph dev --port 8080 - Check firewall settings
- β Real scraping is working
- LinkedIn may be rate-limiting
- Try broader search terms
- Add delay between searches
For issues and questions:
- Open an issue on GitHub
- Check LangChain Discord
- Review LangGraph documentation
Built with β€οΈ using LangGraph and LangChain