I built an AI-powered Upwork cover letters generation system using Langgraph and Litellm. This project consists of two AI agents working together to achieve the following steps:
- Scrape job listings from Upwork for the user provided job title.
- Classify scraped jobs to identify the ones that match with user profile.
- Generate personalized cover letters based on user writing style and the matched job description.
- Save generated cover letters for review and submission.
This is the detailed flow of the system:
-
For building agentic workflows, there are multiple popular frameworks available, such as CrewAI, AutoGen, or Agency Swarm. However, most of them grant full autonomy to the agents while accomplishing tasks and do not provide control over the working process of the agents.
-
With Langgraph, you gain that control. You can decide when each agent or tool needs to be called, and you can add custom feedback based on the agent's output, which aids in self-improvement. Essentially, Langgraph is the best choice when you know exactly the process flow of your application, whereas other frameworks allow agents to choose the process.
-
Langgraph also enables you to use an LLM only when necessary. For example, in this application, we need to scrape jobs from Upwork, which does not require an LLM call; a simple node tool suffices. In other frameworks, you would need to create an agent that calls the scraping tool through function calling, which helps reduce the application's cost.
- LiteLLM is a framework that standardizes calls to 100+ LLMs. It allows interaction with different LLMs beyond OpenAI (GPT models) using the same input/output format, simplifying the process of switching models for the application to just changing the model name.
- Use LLAMA3 with GROQ:
from litellm import completion
response = completion(
model="groq/llama3-70b-8192",
messages=messages,
temperature=0.1
)
- Use Google Gemini:
response = completion(
model="gemini/gemini-1.5-flash",
messages=messages,
temperature=0.1
)
While the current app provides correct results, it requires further tuning to be used in real job applications.
-
Currently, only two example letters are provided to the writer agent (directly in its prompt) for crafting personalized letters. This is insufficient, and it would be better to create a file containing multiple cover letters written in the user's style, which will improve the model's output.
-
Enhanced Feedback Loop: Implement a mechanism for continuous feedback from user, allowing the model to adapt and learn from user writing style (similar to reinforcement learning from human feedback).
- Python 3.9+
- Tavily API key
- Groq API key (for Llama3)
- Google Gemini API key (for using Gemini model)
- Necessary Python libraries (listed in
requirements.txt
)
-
Clone the repository:
git clone https://github.com/kaymen99/upwork-jobs-langgraph.git cd upwork-jobs-langgraph
-
Create and activate a virtual environment:
python -m venv venv source venv/bin/activate # On Windows use `venv\Scripts\activate`
-
Install the required packages:
pip install -r requirements.txt
-
Set up environment variables:
Create a
.env
file in the root directory of the project and add your API keys:TAVILY_API_KEY=your_tavily_api_key GEMINI_API_KEY=your_gemini_api_key GROQ_API_KEY=your_groq_api_key
-
Start the workflow:
python main.py
The application will start scraping job listings, classifying them, generating cover letters, and saving the results.
By default at the end of the process, all the cover letters generated are saved under
files/cover_letter.txt
file. -
You can test the Upwork jobs scraping tool by running:
python scrape_upwork_jobs.py
-
To use this automation for you own profile, just add your profile into
files/profile.md
and remove the example profile. -
You can customize the behavior of each agent by modifying the corresponding agent prompt in the
prompts
script.
Contributions are welcome! Please open an issue or submit a pull request for any changes.
If you have any questions or suggestions, feel free to contact me at aymenMir10001@gmail.com
.