How Drafter-Reviewer Separation Improves AI Job Application Drafts
The drafter-reviewer separation improves application drafts by splitting content generation and critique between two distinct Claude Code agents, enabling ATS-optimized keyword coverage, company-specific tailoring, and reduced token costs while ensuring error-free PDF output.
The MadsLorentzen/ai-job-search repository implements a sophisticated multi-agent architecture that elevates automated job application generation beyond simple template filling. This drafter-reviewer separation pattern orchestrates two specialized Claude Code agents—one to create initial drafts and another to critique them with fresh context—resulting in higher-quality, tailored CVs and cover letters that outperform single-pass generation approaches.
The Two-Agent Architecture
The core pattern divides responsibilities between distinct cognitive roles to prevent the compromises typical of monolithic AI systems.
The Drafter Agent
The drafter generates initial LaTeX drafts for both CV and cover letter documents. It consumes the candidate profile defined in CLAUDE.md and follows the template rules specified in 05-cv-templates.md and 06-cover-letter-templates.md. This agent handles the initial transformation of raw profile data into structured application documents based on the target job posting.
The Reviewer Agent
The reviewer is spawned by the /apply workflow with a fresh context that contains no prior conversation history. According to the orchestration logic in .claude/commands/apply.md, the reviewer receives the drafts inline within its prompt rather than reading them from disk. It conducts external research on the target company, identifies missing keywords, critiques weak framing, and flags generic language that could trigger applicant tracking system (ATS) filters.
Quality Improvements Through Separation
This architectural split delivers four measurable improvements to final application quality.
Enhanced Keyword Coverage for ATS Optimization
The reviewer spots critical keywords the drafter initially missed. Because the reviewer focuses exclusively on critique rather than generation, it detects subtle terminology gaps that would otherwise cause rejection by automated ATS filters. The drafter then incorporates these terms during the revision phase, ensuring keyword-dense content without sacrificing readability.
Company-Specific Tailoring
While the drafter works from static templates, the reviewer actively researches the target organization. This allows the drafter to rewrite opening paragraphs with concrete references to company values, recent projects, or industry position during the second pass. The separation ensures research-informed customization without contaminating the initial drafting context.
Token Efficiency and Context Management
Only the reviewer receives the full drafts inline; it does not re-read the template files. This design reduces token consumption significantly compared to a monolithic agent that would need to maintain the entire template library, conversation history, and draft content simultaneously. The pattern minimizes API costs while maintaining high output quality.
PDF Verification and Error Handling
The reviewer's critique triggers a second LaTeX compile pass that catches layout problems before final PDF generation. The tools/verify_pdf.py script executes a verification loop that confirms contact details appear as literal text in the PDF layer, preventing rendering errors that could disqualify otherwise qualified candidates.
Implementing the Drafter-Reviewer Workflow
The complete pipeline executes through the /apply command documented in the repository's README.md. Trigger the workflow by passing a job posting URL:
# Apply to a Danish Jobindex posting
/apply https://jobindex.dk/job/1234567
Internally, apply.md orchestrates the handoff using the Agent tool to spawn a general-purpose reviewer. The reviewer receives structured drafts inline:
Use the **Agent tool** to spawn a `general-purpose` reviewer agent.
Pass the drafts inline in the prompt (no file reads needed):
After critique, the drafter applies changes using JSON-encoded edits without re-reading source files:
[
{
"file": "cv/main_example.tex",
"old_string": "Experienced data scientist",
"new_string": "Senior data scientist with 5 years of experience"
},
{
"file": "cover_letters/cover_example.tex",
"old_string": "I am excited about the role",
"new_string": "I am excited about the role at {{CompanyName}} because ..."
}
]
Finally, the drafter executes PDF verification to ensure text renders correctly:
pdftotext output_cv.pdf - | grep -i "email@example.com"
# Ensures contact details appear as literal text in the PDF layer
Summary
- Drafter-reviewer separation splits generation and critique between two Claude Code agents with isolated contexts.
- The drafter creates initial LaTeX drafts using
CLAUDE.mdand template files (05-cv-templates.md,06-cover-letter-templates.md). - The reviewer receives drafts inline with fresh context, researches companies, and provides structured feedback without token-heavy file re-reads.
- This pattern improves ATS keyword coverage, enables company-specific tailoring, reduces token costs, and ensures error-free PDF output through verification loops in
tools/verify_pdf.py. - The workflow is language-agnostic and executes via the
/applycommand defined in.claude/commands/apply.md.
Frequently Asked Questions
How does the drafter-reviewer separation reduce API costs?
The separation eliminates redundant context loading. Only the reviewer receives the draft content inline, while the drafter maintains template context separately. This prevents a single monolithic agent from holding the entire template library, conversation history, and draft content simultaneously, significantly reducing token consumption during the critique and revision phases.
Why does the reviewer need a fresh context instead of sharing history with the drafter?
A fresh context prevents cognitive contamination. According to the implementation in .claude/commands/apply.md, spawning the reviewer without prior conversation history enables objective critique unburdened by the drafter's initial assumptions or template constraints. This isolation ensures the reviewer evaluates the drafts as a hiring manager would, spotting gaps that the original author might overlook due to confirmation bias.
What files does the reviewer read compared to the drafter?
The drafter actively reads CLAUDE.md for candidate profiles and both 05-cv-templates.md and 06-cover-letter-templates.md for LaTeX formatting rules. The reviewer receives drafts inline in its prompt and does not re-read these template files. It focuses instead on external company research and critique, making the workflow more efficient by avoiding redundant file I/O operations.
How does the workflow ensure PDFs render correctly?
The reviewer's feedback triggers a second LaTeX compilation pass before final output. Additionally, tools/verify_pdf.py executes verification commands like pdftotext to confirm that contact details and critical text appear as literal strings in the PDF text layer rather than as images or corrupted encodings, preventing ATS parsing failures.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →