The Problem: IELTS Candidates Can't Afford Daily Feedback
Over 3.5 million people take the IELTS exam every year. Most of them need to practise writing — a lot. The official recommendation is 10–15 full essays before the exam. But professional IELTS tutors charge $30–80 per essay evaluation, making daily practice financially out of reach for the majority of candidates who are, by definition, trying to move countries and already managing significant costs.
The alternative — self-evaluation — is almost useless. You can't spot your own coherence problems. You don't know when your vocabulary is too repetitive. And you certainly can't predict whether an examiner would give you a 6.5 or a 7.0 on Task Response. Students were practising in the dark.
Why I Built Writiq
I'd been building software for over a decade when large language models became genuinely capable of nuanced writing assessment. I knew immediately what the application was. The IELTS marking rubric is public. The four criteria — Task Response, Coherence and Cohesion, Lexical Resource, and Grammatical Range and Accuracy — are well-defined. If you could reliably operationalise those criteria into a prompt, you could produce evaluations that were meaningful, consistent, and fast.
The goal was clear: a student should be able to submit an essay, get band-score predictions for each criterion, sentence-level annotations showing exactly what hurt their score, and specific rewrite suggestions — all in under 30 seconds, for a fraction of tutor cost.
Technical Architecture
The stack was deliberate. Laravel on the backend for the API, queue management, and user/billing logic. Vue.js on the frontend for the essay submission interface and results display. An AI API for the evaluation itself.
The most important architectural decision was treating evaluations as asynchronous jobs, not synchronous API calls. When a student submits an essay, the backend creates an evaluation job, dispatches it to the queue, and immediately returns a job ID. The frontend polls for completion. This means the web server is never blocked waiting on OpenAI — the queue workers handle that independently, and they can scale separately from the web tier.
The Prompt Engineering Challenge
The prompt is the product. Early versions returned wildly inconsistent scores — the same essay would get a 6.0 one run and a 7.5 the next. The fix was structural: instead of asking the LLM to "evaluate this IELTS essay", I restructured the prompt to work through each criterion independently, in a defined order, with explicit scoring anchors drawn from the official IELTS public band descriptors.
The output format matters just as much. Asking for free-form feedback produces varied, hard-to-parse responses. Asking for structured JSON with defined fields — criterion, band score, justification, flagged sentences, rewrite suggestion — produces consistent, machine-readable output that the frontend can render reliably.
| IELTS Criterion | What the LLM Evaluates | Output |
|---|---|---|
| Task Response / Achievement | Does the essay fully address all parts of the prompt? | Band 1–9 + flagged gaps |
| Coherence & Cohesion | Is the argument logically sequenced? Are linking devices used correctly? | Band 1–9 + sentence-level flags |
| Lexical Resource | Vocabulary range, precision, spelling, and word form accuracy | Band 1–9 + word-level flags |
| Grammatical Range & Accuracy | Sentence structure variety and grammatical correctness | Band 1–9 + annotated errors |
Sentence-Level Annotation: The Hardest Problem
Telling a student "your Coherence and Cohesion is 5.5" is marginally useful. Showing them which specific sentences weakened their score, and offering a rewrite, is genuinely useful. This required solving a harder problem: mapping the LLM's feedback back to specific positions in the original essay text.
The approach: the essay is tokenised into sentences server-side before the prompt is built. Each sentence is given a numeric ID. The prompt instructs the LLM to reference sentences by their ID when flagging issues. The response then maps IDs back to the original text for display in the editor. This sounds straightforward — and it mostly is — but edge cases around multi-sentence constructions, semicolons, and quotations required several iterations to handle cleanly.
Cost Control at Scale
GPT-4 calls are not cheap, and a 350-word IELTS essay evaluation uses a substantial number of tokens. Three optimisations reduced OpenAI costs significantly without impacting quality:
- Response caching: Identical essays (detected by hash) return cached results. Surprisingly common — students resubmit the same essay after minor edits.
- Prompt compression: The system prompt was trimmed from ~2,000 tokens to ~800 tokens by removing redundant explanation and tightening the band descriptor extracts.
- Model routing: Task 1 essays (shorter, more structured) are evaluated with GPT-4o-mini at comparable accuracy for that task type. Task 2 essays (longer, more complex arguments) use GPT-4.
Results and What I Learned
Writiq evaluates essays in 20–35 seconds. The four-criterion scoring framework aligns with the official IELTS public band descriptors — the same rubric human examiners use — which is the foundation that makes the feedback actionable rather than generic. Task 1 Academic essays with unusual data sets remain the most challenging to evaluate precisely; this is true for human examiners as well.
The product insight that surprised me most: students don't primarily want a score. They want to know which sentence to rewrite. The feature that drove the most positive feedback was the sentence-level annotation view, not the band score summary. This shifted the UI priority significantly from the original design, where the score was the hero element.
The lesson that applies beyond this specific product: LLM application development is mostly prompt engineering and output structuring, not model selection. The same underlying model produces wildly different quality results depending on how you structure the task. Get the prompt right first, then worry about everything else.