$ mkdir upwork-agent
cd upwork-agent
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Mac/Linux
mkdir upwork-agent
cd upwork-agent
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Mac/Linux
mkdir upwork-agent
cd upwork-agent
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Mac/Linux
-weight: 500;">pip -weight: 500;">install google-adk
-weight: 500;">pip -weight: 500;">install google-adk
-weight: 500;">pip -weight: 500;">install google-adk
upwork-agent/ upwork_agent/ ← folder named after your agent agent.py ← your agent lives here .env ← your API key lives here
upwork-agent/ upwork_agent/ ← folder named after your agent agent.py ← your agent lives here .env ← your API key lives here
upwork-agent/ upwork_agent/ ← folder named after your agent agent.py ← your agent lives here .env ← your API key lives here
mkdir upwork_agent
mkdir upwork_agent
mkdir upwork_agent
GOOGLE_GENAI_USE_VERTEXAI=FALSE
GOOGLE_API_KEY=your_key_here
GOOGLE_GENAI_USE_VERTEXAI=FALSE
GOOGLE_API_KEY=your_key_here
GOOGLE_GENAI_USE_VERTEXAI=FALSE
GOOGLE_API_KEY=your_key_here
from google.adk.agents import Agent
from dotenv import load_dotenv load_dotenv() def analyze_job(job_description: str) -> dict: """Analyzes a job description and returns key details.""" return { "-weight: 500;">status": "success", "job_text": job_description } root_agent = Agent( name="upwork_proposal_agent", model="gemini-2.5-flash", description="An agent that reads job descriptions and writes winning proposals.", instruction=""" You are an expert proposal writer for a Full-Stack MERN and AI/ML developer. When given a job description: 1. Identify the top 3 skills the client needs 2. Identify the tone of the client (formal, casual, urgent) 3. Write a short personalized proposal (150 words max) that: - Opens with something specific from the job post, not a generic greeting - Shows you understand their exact problem - Mentions 1 relevant past project naturally - Ends with a simple low pressure call to action Be conversational, confident and human. Never -weight: 500;">start with "I am writing to apply". """, tools=[analyze_job],
)
from google.adk.agents import Agent
from dotenv import load_dotenv load_dotenv() def analyze_job(job_description: str) -> dict: """Analyzes a job description and returns key details.""" return { "-weight: 500;">status": "success", "job_text": job_description } root_agent = Agent( name="upwork_proposal_agent", model="gemini-2.5-flash", description="An agent that reads job descriptions and writes winning proposals.", instruction=""" You are an expert proposal writer for a Full-Stack MERN and AI/ML developer. When given a job description: 1. Identify the top 3 skills the client needs 2. Identify the tone of the client (formal, casual, urgent) 3. Write a short personalized proposal (150 words max) that: - Opens with something specific from the job post, not a generic greeting - Shows you understand their exact problem - Mentions 1 relevant past project naturally - Ends with a simple low pressure call to action Be conversational, confident and human. Never -weight: 500;">start with "I am writing to apply". """, tools=[analyze_job],
)
from google.adk.agents import Agent
from dotenv import load_dotenv load_dotenv() def analyze_job(job_description: str) -> dict: """Analyzes a job description and returns key details.""" return { "-weight: 500;">status": "success", "job_text": job_description } root_agent = Agent( name="upwork_proposal_agent", model="gemini-2.5-flash", description="An agent that reads job descriptions and writes winning proposals.", instruction=""" You are an expert proposal writer for a Full-Stack MERN and AI/ML developer. When given a job description: 1. Identify the top 3 skills the client needs 2. Identify the tone of the client (formal, casual, urgent) 3. Write a short personalized proposal (150 words max) that: - Opens with something specific from the job post, not a generic greeting - Shows you understand their exact problem - Mentions 1 relevant past project naturally - Ends with a simple low pressure call to action Be conversational, confident and human. Never -weight: 500;">start with "I am writing to apply". """, tools=[analyze_job],
) - Your agent needs to read a database? Write a custom connector.
- Call an external API? Write a custom connector.
- Send a notification? Pull data from a spreadsheet? Custom connector. Custom connector.
- Something breaks at 2am? Debug the connector you wrote at midnight. - Python 3.10 or higher (check with python --version)
- A free Gemini API key from Google AI Studio, no credit card needed
- Any terminal or VS Code - Setting up your own agent runtime from scratch
- Writing tool connectors manually for every -weight: 500;">service
- Figuring out memory and session management yourself
- Deploying and monitoring everything on your own - Support agent that reads emails, checks your DB and drafts replies
- Daily standup bot that pulls GitHub commits and summarizes them
- Onboarding agent that remembers where each new user left off
- Code review agent that checks PRs against your team standards - Google ADK Docs
- Google AI Studio, free API key
- GitHub repo