InterviewKata
System design · Worked design D32 of 46 · Data and infrastructure · Long form

Design an AI code assistant

Two products share one name. Inline completion suggests the rest of a line as a developer types, and is useless if it arrives after they've typed it themselves. The chat and agent mode reads the codebase, edits several files and runs the tests, and is dangerous if it runs the wrong command. Both depend on picking the right few thousand tokens of context out of millions of lines of code.

1. The prompt

"Design an AI coding assistant that works inside the editor: inline completions as you type, and a chat that can answer questions about the codebase, edit files and run tests. It's a product used by many companies."

What makes it hard:

2. Frame the problem

How many users?

1 M daily active developers across ~20 K companies; editors on every desktop OS.

Completion traffic is enormous; chat is smaller but each request is much larger.

How fast must a completion appear?

Ideally under ~300 ms from the moment the developer pauses.

Response-time research puts "feels instant" around 100 ms and "flow is kept" up to about a second; a suggestion that arrives after the next keystroke is wasted.

What can the agent do?

Read and search files, propose multi-file edits, run tests and commands in the developer's environment, with approval.

A tool loop with permissions, not free shell access.

Where does the code live?

On the developer's machine and in their company's repositories; we never store it beyond the request unless the company opts in to indexing.

Privacy and retention rules shape caching and indexing.

Which models?

We host our own small completion model and use large hosted models for chat and agents.

Two serving paths with very different latency and cost profiles.

How do we know it's good?

Acceptance of suggestions, code that survives in the file, and agent tasks that pass tests.

Plan the telemetry and evaluation from the start.

3. What it must do

  1. Suggest completions at the cursor while typing, using the surrounding code and relevant code elsewhere in the project.
  2. Answer questions and make edits through chat, grounded in the codebase, shown as diffs the developer accepts.
  3. Run an agent loop: plan, read, edit, run tests, repeat, with the developer approving risky steps.

Not now: code review bots on pull requests, autonomous agents in the cloud working on tickets, training custom models per company.

4. How well it must do it

TargetWhy this number
Completions: p50 under 200 ms, p95 under 500 ms after the pause speedSlower suggestions arrive after the developer has moved on.
Useful: suggestions accepted often enough to be worth showing, and accepted code mostly kept data qualityBad suggestions distract more than no suggestions.
Safe agent: no file write or command without the configured approval; no secrets leave the machine securityOne destructive command or leaked key outweighs all the saved time.
Private: customer code isn't retained or used for training without consent; tenants isolated securityThe precondition for any company to adopt it.
Degrades quietly: if the service is slow or down, the editor works normally surviving failuresIt's an assistant, never a blocker.

5. Numbers that change the design

QuantityWorking→ so we…
Completion requests1 M developers × ~4 h typing × a request every few seconds ≈ 3 B a day ≈ 35 K a second, ~100 K at peak→ so a small, fast model on our own GPUs, close to users, with cancellation and caching
Completion prompt~2 K tokens in (code around the cursor and snippets), ~20–50 outPrefill dominates → so reuse cached prefixes and keep prompts tight
Wasted requestsMany requests are overtaken by the next keystroke→ so debounce, cancel in flight, and stop generating when the client disconnects
Chat and agent~20 M turns a day, often 20–100 K tokens of context eachHundreds of billions of input tokens a day → so prompt caching and careful context selection decide the bill

6. The nouns

completion_req   req_id, user_id, org_id, lang, path, prefix (tail), suffix (head), snippets[], created_at   (not stored by default)
suggestion_event req_id, shown_ms, accepted (none | partial | full), chars_kept_after_5min                   (telemetry, no code)
index_chunk      org_id, repo_id, commit, path, symbol, kind (function | class | …), embedding, text        (opt-in, encrypted)
agent_step       session_id, n, tool (read | search | edit | run), args, approval (auto | user | denied), result_summary
org_policy       org_id, retention, indexing_enabled, allowed_models[], auto_run_commands[]

7. The contract

POST /v1/completions        {lang, path, prefix, suffix, snippets[]}         → stream of tokens; client may cancel any time
POST /v1/completions/events {req_id, outcome, kept_chars}                    → 204      (telemetry, batched)
POST /v1/chat               {messages, context: {files, selection, index_hits}} → stream: text · tool_call · diff
Tools run in the editor (client side), never on our servers:
read_file(path) · search(query) · edit(path, diff) · run(command)           each checked against the org policy

The editor extension does most of the work that touches code: it gathers context, runs tools, and shows diffs. The server sees only what each request needs.

8. First working version

An editor extension, a completion service with a small model on GPUs in a few regions, and a chat service that calls a large hosted model, with tools executed by the extension.

8.1 A completion

After a short pause in typing, the extension sends the code before and after the cursor (the model is trained for "fill in the middle") plus a few snippets from open files. The model streams a suggestion; the editor shows it as grey "ghost text". Any keystroke cancels the request.

8.2 An agent task

The chat sends the goal and context to a large model. The model asks for tools; the extension runs them locally, subject to policy and approvals, and sends results back, until the tests pass or a step budget is reached. Edits appear as diffs to accept.

Parked for laterthe completion latency budget (9.1) · choosing context (9.2) · indexing the repository (9.3) · a safe agent (9.4) · privacy and tenants (9.5) · serving and cost (9.6) · measuring quality (9.7).

9. Make it hold up

9.1 The completion latency budget completions under 200 ms at p50

ApproachWhy
✗ BadA large model in one region, a request on every keystrokeSeconds per suggestion, and most requests are obsolete before they finish.
~ GoodA small model, a debounce of ~100–200 ms, cancel on the next keystrokeFar fewer requests, but users far from the region still wait on the round trip.
✓ GreatPlus GPUs in several regions, a persistent connection (no TLS handshake per request), prefix caching of the attention state for the unchanged part of the file, streaming the first line early, speculative decoding, and stopping generation when the client cancelsEach piece removes a slice of the budget. Try them in section 13.

Also show cached suggestions instantly: if the developer types exactly what the previous suggestion predicted, keep showing the rest of it without a new request.

9.2 Choosing the context useful

For chat, retrieval reaches further: search the repository index (9.3) and let the model ask for more with tools.

9.3 Indexing a repository useful · private

ApproachWhy
✗ BadPut whole files in the promptRuns out of context after a few files and costs a fortune.
~ GoodFixed-size chunks with embeddingsChunks cut functions in half; exact symbol names are missed by vector search.
✓ GreatChunk by syntax (whole functions and classes), index symbols and keywords as well as embeddings, update incrementally from file changes and commits, and filter by the user's repository permissions at query timeResults are whole, findable by name or meaning, current, and never from code the user can't see.

Indexing can run locally (small repos, maximum privacy) or on our servers for large monorepos, encrypted per company, only when the company opts in.

9.4 A safe agent loop safe agent

9.5 Privacy and tenants private

By default prompts and suggestions are processed in memory and not stored; telemetry records outcomes, not code. Companies can choose retention, regions and which models may see their code. Indexes and caches are keyed by company and encrypted with per-company keys; prefix caches never cross company boundaries. A filter blocks suggestions that match public code verbatim if the company requires it, and a secret scanner strips keys from prompts before they leave the machine.

9.6 Serving and cost completions at 100 K a second

ApproachWhy
✗ BadOne GPU pool for completions and chatLong chat prompts block short completions, and completion latency spikes.
~ GoodSeparate pools: small model for completions, hosted large models for chatLatency is protected, but completion GPUs idle at night and overflow at peak.
✓ GreatContinuous batching with paged KV memory (as in vLLM), prefix caching per file, autoscaling per region by queue time, routing to the nearest healthy region, per-user rate limits, and turning completions off gracefully under overloadHigh GPU utilisation without letting a batch hurt latency; overload degrades to fewer suggestions, not slower editors (Module 08).

9.7 Measuring quality useful

9.8 The whole design after the deep dives

10. Interviewer follow-ups

A company with a 50-million-line monorepo complains chat doesn't find the right code.

Server-side indexing (opt-in) with syntax-aware chunks, a symbol index, and a code-graph of imports and calls; retrieval combines all three, filtered by permissions. Let the agent search iteratively rather than relying on one retrieval.

Completions get slow in Asia.

Measure the breakdown (network vs queue vs prefill vs decode). Add a region, or route to the nearest region with capacity; check prefix-cache hit rate there.

The agent ran a command that deleted files.

Commands outside the allowlist must be approved; run agents in containers; keep edits as diffs that can be reverted; log every step. Then add the command pattern to the deny list and an eval case.

A customer forbids sending code to third-party model providers.

Per-company policy routes their chat to models we host (or their own deployment), and the client refuses to send anywhere else.

How do you ship a new completion model safely?

Offline benchmark, then shadow traffic for latency, then an A/B test on acceptance and kept code, then a gradual rollout per region with automatic rollback on latency or acceptance drops.

Offline mode on a plane.

Optionally ship a tiny local model for completions; chat and agents wait for the network.

11. When things break

FailureWhat users seeHow we detect itWhat limits the damage
Completion region overloadedFewer or later suggestionsQueue time, p95 latencyRoute to another region; shed load by raising the debounce
Hosted chat model downChat errorsError rateFallback model; completions unaffected (separate path)
Bad model releaseWorse suggestionsAcceptance and kept-code dropGradual rollout, automatic rollback
Index staleChat misses new codeIndex lag per repoIncremental updates; agent can read files directly
Prompt injection in a repo fileAgent proposes odd stepsDenied approvals, filter hitsApprovals in code, sandbox, no secrets in context
Our service unreachableNo suggestionsClient error rateEditor works normally; extension backs off quietly

12. Wrap-up and the clock

Trade-offs we made:

What we'd watch: completion p50/p95 by region · acceptance and kept code · cancelled-request share · GPU utilisation · prefix-cache hit rate · agent task success and denied approvals · cost per active developer.

At 10×: more regions, smaller or distilled models, more aggressive caching, and per-company dedicated capacity for the largest customers.

A 60-minute interview

0–5Frame: two products, latency, privacy, agent powers
5–10Must do, how well, numbers
10–15Nouns, contract (tools run client side)
15–25First version: completion and agent
25–50Deep dives: latency (9.1), context (9.2), safe agent (9.4)
50–60Serving or quality, follow-ups, wrap-up

A 90-minute interview

0–8Frame, including enterprise policies
8–15Must do, how well, numbers
15–22Nouns, contract
22–35First working version
35–75Deep dives 9.1–9.7 and the final picture
75–85Follow-ups: monorepo, model rollout, no third parties
85–90Trade-offs, metrics, 10×
LevelWhat a strong answer shows
Mid-levelAn editor extension, a completion API with a model behind it, chat with retrieval, debouncing.
SeniorA latency budget broken into parts, cancellation and prefix caching, syntax-aware indexing, tools run client side with approvals, separate serving pools.
Staff+Privacy and tenancy as architecture (what leaves the machine, per-company keys and policies), quality measured by kept code and controlled experiments, agent safety against injection, cost per developer as a design input.

Common mistakes:

13. Try it, check yourself, read more

Completion-latency lab. A developer pauses typing. How long until the grey suggestion appears, and how many requests does it cost? Change the model, the context size, the debounce and the distance to the GPUs. The target is under 300 ms from the pause.

2,000
100
debouncenetworkprefill (read the context)first line

Illustrative model: prefill at 50 K / 15 K / 5 K tokens a second and decode at 200 / 80 / 40 tokens a second for small / medium / large; a first line is ~15 tokens; a prefix-cache hit skips 80% of prefill. Requests a minute assume steady typing with pauses. GPU baseline = small model, 2,000 tokens, cache on, 200 ms debounce.

What should happen to a completion request when the developer types another character?

Its suggestion no longer matches the text; finishing it only wastes GPU time.

Where do agent tools such as run(command) execute?

Code stays local, permissions are the developer's own, and approvals are enforced in code.

How should code be chunked for retrieval?

Whole units of code are meaningful on their own and easy to cite.

Which metric best shows completions are useful?

Showing many suggestions is easy; useful ones are accepted and kept.
ResourceWhy
Response times: the 3 important limits (Nielsen Norman Group)0.1 s feels instant, 1 s keeps the flow of thought: the budget behind completions.
Productivity Assessment of Neural Code Completion (Ziegler et al., 2022)Which completion metrics track how productive developers feel.
Efficient Training of Language Models to Fill in the Middle (Bavarian et al., 2022)How models learn to complete code between a prefix and a suffix.
Fast Inference from Transformers via Speculative Decoding (Leviathan et al., 2022)A small model drafts tokens, the large one checks them.
Efficient Memory Management for LLM Serving with PagedAttention (Kwon et al., 2023)The vLLM paper: continuous batching and paged KV memory.
SWE-benchReal GitHub issues as agent tasks, checked by the repository's tests.
tree-sitter and the Language Server ProtocolParsing code into functions and finding definitions, for chunking and context.