AI Auto-Generation of Job Descriptions
HR departments spend 30 to 90 minutes drafting a single job description. An AI system generates a structured job description in 15–30 seconds based on job title, tech stack, and key requirements — while maintaining company tone of voice, gender-neutral phrasing, and SEO optimization for job aggregators.
Job Description Generator
from openai import AsyncOpenAI
from dataclasses import dataclass, field
client = AsyncOpenAI()
@dataclass
class JobBrief:
title: str
department: str
employment_type: str # full-time, part-time, contract, freelance
experience_years: tuple # (min, max)
tech_stack: list[str]
responsibilities: list[str]
company_description: str
tone: str = "professional" # professional, startup, corporate, creative
language: str = "en"
include_salary_range: bool = False
salary_range: tuple = None
async def generate_job_description(brief: JobBrief) -> dict:
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "system",
"content": f"""You are an HR copywriter, employer branding specialist.
Create a job description for job aggregators (LinkedIn, Indeed, GitHub Jobs).
REQUIREMENTS:
- Title: position + key technologies (for SEO in search)
- About company: 2–3 sentences, specific facts, no "industry leader"
- Duties: 5–7 points with action verbs, concrete
- Requirements: hard skills separate from soft skills, must-have vs nice-to-have
- Conditions: no fluff, facts only
- Gender-neutral phrasing (inclusive language)
- Tone of voice: {brief.tone}
Return JSON: {{title_seo, about_company, responsibilities, requirements_hard, requirements_soft, nice_to_have, conditions, cta}}"""
}, {
"role": "user",
"content": f"""
Position: {brief.title}
Department: {brief.department}
Employment type: {brief.employment_type}
Experience: {brief.experience_years[0]}–{brief.experience_years[1]} years
Tech stack: {', '.join(brief.tech_stack)}
Key tasks: {', '.join(brief.responsibilities)}
About company: {brief.company_description}
{"Salary: " + f"{brief.salary_range[0]}–{brief.salary_range[1]} USD" if brief.include_salary_range and brief.salary_range else ""}
"""
}],
response_format={"type": "json_object"}
)
import json
return json.loads(response.choices[0].message.content)
Multi-Language Generation and Platform Adaptation
JOB_PLATFORM_FORMATS = {
"linkedin": {
"max_title": 120,
"sections": ["about_company", "responsibilities", "requirements_hard", "requirements_soft", "nice_to_have"],
"style": "professional, with keywords for LinkedIn Search"
},
"indeed": {
"max_title": 100,
"sections": ["about_company", "responsibilities", "requirements_hard", "conditions"],
"style": "structured, no marketing"
},
"github_jobs": {
"max_title": 100,
"sections": ["responsibilities", "requirements_hard", "nice_to_have", "conditions"],
"style": "technical, for engineering audience, specific metrics"
}
}
async def adapt_for_platform(job_data: dict, platform: str) -> str:
fmt = JOB_PLATFORM_FORMATS.get(platform, JOB_PLATFORM_FORMATS["linkedin"])
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "system",
"content": f"Adapt job description for platform {platform}. Style: {fmt['style']}. Use sections: {fmt['sections']}."
}, {
"role": "user",
"content": str(job_data)
}]
)
return response.choices[0].message.content
Batch Generation for Hiring
When filling multiple positions simultaneously, the system accepts a CSV with titles and stacks, generates descriptions in batches of 10–15 positions in parallel via asyncio.gather, saves in formats for each platform. For companies hiring 50+ positions annually, this reduces HR team workload by 200–300 hours yearly.
Description Effectiveness Analysis
async def score_job_description(text: str) -> dict:
"""Score description on factors attracting candidates"""
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "system",
"content": """Score job description by criteria (1–10):
- clarity: clarity of requirements
- appeal: attractiveness to candidates
- seo_score: SEO for job aggregators
- gender_neutrality: gender neutrality
- specificity: specificity (vs abstract requirements)
Return JSON with scores and recommendations."""
}, {
"role": "user",
"content": text
}],
response_format={"type": "json_object"}
)
import json
return json.loads(response.choices[0].message.content)
Job description generator with adaptation for 3 platforms ready in 1–2 weeks. Integration with ATS (Huntflow, Talantix, Greenhouse) and auto-posting — another 2–3 weeks.







