Build a CSV-to-JSON Classification Service
Company: Scale AI
Role: Backend Engineer
Category: Software Engineering Fundamentals
Difficulty: easy
Interview Round: Onsite
## Build a CSV-to-JSON Classification Service
Build a backend service in stages. First, an HTTP request supplies a server-visible CSV path and the service writes the rows as JSON to the filesystem. Then add a `category` field to each row by calling a provided LLM API. Finally, explain and implement the concurrency changes needed to process much larger inputs. Do not include a real API key in code, prompts, logs, or examples.
Assume configuration supplies a finite set of allowed category strings and the LLM credential through secret storage. State any CSV dialect, output naming, and row-failure policy you choose.
### Part 1 — Convert CSV to JSON Safely
Define the endpoint, validate the path, parse the CSV, and produce a JSON file whose objects use the header fields.
#### What This Part Should Cover
- A request and response contract plus deterministic output-path selection.
- Restriction to an approved input root rather than arbitrary filesystem access.
- Correct handling of headers, quoted fields, empty fields, malformed rows, and encoding.
- A temporary output followed by atomic rename so readers never see a partial final file.
```hint Use a CSV parser, not a line split
A quoted field can contain a delimiter or newline, so physical lines are not always logical rows.
```
### Part 2 — Add LLM-Generated Categories
For each parsed row, call the LLM API with a prompt you write, validate its response against the configured categories, and add the accepted category to the JSON object.
#### What This Part Should Cover
- A compact prompt containing the task, allowed labels, row data, and strict output schema.
- Credential isolation, request timeout, bounded retry, and rate-limit handling.
- Validation of structured output and a defined fallback or row-level error.
- Model and prompt version recorded so the file can be explained or reproduced.
```hint Treat model output as untrusted input
Even a strong instruction does not replace parsing and validating the returned category.
```
### Part 3 — Scale with Sharding and Bounded Parallel Calls
Move long conversions to an asynchronous job, split work safely, call the LLM concurrently within provider and resource limits, and assemble one deterministic result.
#### What This Part Should Cover
- Durable job and row identifiers with checkpointed per-row state.
- Sharding at parsed-record boundaries rather than arbitrary byte offsets.
- Bounded worker pools, a shared rate limiter, backpressure, and fair scheduling.
- Idempotent retry, preservation of original row order, atomic finalization, and resumability.
```hint Concurrency needs a budget
Launching one request per row at once moves the bottleneck to rate limits, sockets, memory, or cost without providing controlled throughput.
```
### What a Strong Answer Covers
- A working and secure CSV-path-to-JSON flow with explicit error semantics.
- A concrete classification prompt plus strict response validation.
- Safe secret handling, retry, idempotency, and partial-failure decisions.
- Sharding and bounded parallel LLM calls that preserve row identity and order.
- Operational signals for throughput, provider failures, invalid labels, and stuck jobs.
### Follow-up Questions
1. How would the design change if the CSV is uploaded rather than already on the server?
2. What cache key could safely reuse a prior classification?
3. How would you resume after half the rows are classified and the process crashes?
4. How would you keep a malformed or adversarial row from corrupting the prompt contract?
Quick Answer: Build a service that converts server-visible CSV data to JSON, adds an allowed category through a provided LLM API, and scales to larger inputs. Address safe paths and output writes, secret handling, structured model validation, row failures, bounded concurrency, retries, ordering, and resumability.