Skip to content
RED SAGSkills

AI Engineer (LLM & Generative AI) interview questions and answers

30 questions interviewers really ask, with what a strong answer covers. Read them, then test yourself in a timed mock interview.

Start a AI Engineer (LLM & Generative AI) mock interview

Easy questions easy

1. Explain retrieval-augmented generation (RAG) to a new team member. Why do we use it?

A strong answer covers:

  • Retrieve relevant documents for the question
  • Add them to the prompt as context
  • Model answers grounded in the context, can cite sources
  • Works for private and fresh data without retraining
Show model answer

RAG means we look things up before the model answers. When a user asks a question, we search our own knowledge base, usually by turning the question into an embedding and finding similar document chunks in a vector database, sometimes combined with keyword search. We take the best few chunks and put them into the prompt with instructions like "answer only using these sources and cite them". The model then writes an answer grounded in that context. We use it because the base model does not know our private documents and its knowledge has a cutoff date. RAG lets us use fresh and private data without retraining the model, reduces hallucinations, and lets users check citations. The quality of the answer depends heavily on the quality of retrieval, so we measure that separately.

2. What are embeddings, and what can you build with them besides RAG?

A strong answer covers:

  • Vectors that capture meaning; similar items are close
  • Semantic search and recommendations
  • Clustering, deduplication, classification
  • Similarity measured with cosine or dot product
Show model answer

Embeddings are lists of numbers that represent the meaning of text, images or other data. An embedding model is trained so that similar items end up close in vector space, and we compare them with cosine similarity or dot product. Besides RAG, I can use them for semantic search, where a query like "laptop will not charge" finds articles about "battery not charging". I can recommend similar products or articles. I can cluster support tickets to find common themes, and detect near-duplicate documents. Embeddings also make good features for simple classifiers: for example, a logistic regression on embeddings can route tickets to the right team cheaply. They are fast and cheap compared to calling a large model for every item, which makes them useful at scale.

3. Why do LLMs hallucinate, and what simple steps reduce it in an application?

A strong answer covers:

  • Models predict likely text, not verified facts
  • Ground answers with retrieved sources
  • Instruct to say "I do not know" and to cite
  • Lower temperature for factual tasks; validate outputs
Show model answer

LLMs are trained to predict the next likely token, so they produce fluent text even when they do not have the facts. If the answer is not in their training data or context, they may fill the gap with something that sounds right. In an application, the biggest fix is grounding: give the model the relevant facts through retrieval or tool calls, and tell it to answer only from those sources and cite them. I also explicitly allow "I do not know" so the model does not feel forced to guess. For factual tasks I use low temperature. Then I check outputs: for example verifying that cited passages actually contain the claim, validating numbers against the database, and using structured output so fields can be checked. Finally I measure hallucination rate on an eval set.

4. How do tokens affect the cost and speed of an LLM application?

A strong answer covers:

  • Pricing is usually per input and output token
  • Output tokens are slower and usually cost more
  • Long prompts and history increase cost and latency
  • Trim context, cache, and choose the right model size
Show model answer

Most providers charge per token, with separate prices for input and output tokens, and output is usually more expensive. Speed also depends on tokens: the model processes the input first, which affects time to first token, then generates output one token at a time, so long answers take longer. In a chat app, history grows every turn, so cost per message grows unless I trim or summarise old messages. RAG adds retrieved chunks, so sending ten chunks when three are enough wastes money. To control this, I keep system prompts tight, retrieve fewer but better chunks, ask for concise answers or set max tokens, use prompt caching for repeated prefixes, and send simple tasks to smaller, cheaper models. I log token usage per feature so I can see where money goes.

5. What do temperature and top-p control, and how would you set them for different tasks?

A strong answer covers:

  • Both control randomness of token sampling
  • Temperature reshapes the probability distribution
  • Top-p samples from the smallest set covering probability p
  • Low for extraction and code; higher for creative writing
Show model answer

Both settings control how random the output is. At each step the model gives a probability for every possible next token. Temperature rescales these probabilities: low temperature makes the top token much more likely, so output is focused and repeatable; high temperature flattens the distribution, so rarer tokens get picked and output is more varied. Top-p, or nucleus sampling, only samples from the smallest set of tokens whose probabilities add up to p, cutting off the unlikely tail. I usually change one, not both. For extraction, classification, SQL or code, I use low temperature for consistency. For brainstorming, marketing copy or story writing, I use a higher value for variety. Even at zero temperature, outputs may not be perfectly identical, so I still design evals and validation instead of relying on determinism.

6. What is an LLM agent, and how is it different from a single LLM call?

A strong answer covers:

  • An agent runs the model in a loop and lets it choose actions
  • The model requests tool calls; application code executes them
  • Tool results are fed back so the model can decide the next step
  • The loop ends on a final answer or a step limit
  • Agents add flexibility but also cost, latency and failure modes
Show model answer

A single LLM call takes a prompt and returns text once. An agent wraps the model in a loop and gives it tools, such as search, a database query or sending an email. On each turn the model either answers or asks for a tool call with arguments. My code runs the tool, appends the result to the conversation, and calls the model again, so it can plan, observe what happened and adjust. The loop stops when the model gives a final answer or when we hit a step or cost limit. Agents are powerful for open-ended tasks, but they are slower, more expensive and harder to test than a fixed workflow, so I only use one when the steps cannot be known in advance, and I trace every step.

7. How does vector search work, and why is it useful for an AI application?

A strong answer covers:

  • Text is turned into embeddings that capture meaning
  • Documents are embedded once and stored in an index
  • The query is embedded with the same model and compared by similarity
  • Approximate nearest-neighbour indexes make search fast at scale
  • It finds matches by meaning, but can miss exact terms like codes
Show model answer

Vector search finds text by meaning rather than exact words. First I split documents into chunks and run each through an embedding model, which turns it into a list of numbers where similar meanings end up close together. These vectors go into an index, often a vector database. At query time I embed the question with the same model and ask the index for the nearest vectors, usually by cosine similarity or dot product. Approximate nearest-neighbour structures such as HNSW make this fast even with millions of chunks. It is useful because a question like "how do I get my money back" can match a section titled "refund policy". Its weakness is exact terms like error codes or names, so I often combine it with keyword search.

8. Your app starts getting rate-limit errors from the LLM API. How do you handle them?

A strong answer covers:

  • Recognise 429 responses and honour Retry-After
  • Retry with exponential backoff and jitter, with a cap
  • Control concurrency with a queue or token budget
  • Reduce tokens per request to fit tokens-per-minute limits
  • Monitor usage and request higher limits or add fallbacks
Show model answer

Rate-limit errors usually come back as HTTP 429. First I make the client handle them properly: read the Retry-After header if present, otherwise retry with exponential backoff plus random jitter, and stop after a few attempts so users are not left waiting forever. Then I look at why we are hitting the limit. Limits are often on both requests and tokens per minute, so trimming long prompts or capping output length can help as much as slowing down. I put a queue or semaphore in front of the API to control concurrency, and move non-urgent work to batch jobs. Finally I add monitoring on usage against limits, ask the provider for a higher tier if needed, and consider a fallback model for peak times.

9. What is the difference between zero-shot and few-shot prompting, and when would you use each?

A strong answer covers:

  • Zero-shot gives only instructions; few-shot adds worked examples
  • Examples show format, tone and edge cases better than rules
  • Few-shot costs more tokens on every request
  • Examples should be diverse and representative to avoid copying bias
  • Measure both on an eval set rather than guessing
Show model answer

Zero-shot prompting gives the model only instructions, like "classify this ticket as billing, technical or other". Few-shot prompting adds a handful of worked examples of input and correct output. I start zero-shot because strong models follow clear instructions well and it keeps prompts short and cheap. I add examples when the output format is unusual, when the boundary between categories is subtle, or when I need a specific tone, because examples often show these better than rules. The examples must be varied and representative; if they all have the same label or length, the model copies that pattern. Since examples add tokens to every call, I compare both versions on a small eval set and keep the cheaper one if quality is equal.

10. How do you protect personal data when building a feature on a hosted LLM API?

A strong answer covers:

  • Send only the data the task needs (data minimisation)
  • Redact or mask sensitive fields before sending
  • Check provider data retention and training terms
  • Control what gets stored in logs and traces
  • Apply access controls so retrieval only returns permitted data
Show model answer

I start with data minimisation: only send the fields the task actually needs. If the summary does not need card numbers or phone numbers, I redact or mask them before the call, often with a PII detection step. I check the provider terms for retention and whether data is used for training, and pick settings or regions that match our privacy rules and contracts. Logs and traces are an easy place to leak data, so I mask or limit what is stored and set retention periods. In RAG features I enforce access controls in retrieval, so a user can never get another person record into the prompt. Prompt instructions like "do not reveal" are not protection; real controls must sit in code.

Medium questions medium

1. How do you decide between better prompting, RAG and fine-tuning for a new use case?

A strong answer covers:

  • Start with prompting and an eval set as a baseline
  • RAG for knowledge: private, large or changing data
  • Fine-tuning for behaviour, format, style, or a smaller cheaper model
  • Consider data availability, cost, latency and maintenance
  • Often combined
Show model answer

I start with prompting and build an eval set first, so I can measure every option. Good instructions and a few examples solve many problems cheaply and quickly. If the gap is missing knowledge, such as company documents, product data or anything that changes often, I add RAG or tool calls, because fine-tuning is a poor way to store facts and is hard to update. If the gap is behaviour, like a strict output format, a domain writing style, or a classification task the model keeps getting wrong despite good prompts, fine-tuning helps, especially when I have hundreds or thousands of good examples. Fine-tuning a smaller model can also cut cost and latency once a large model has proven the task. These approaches combine: a fine-tuned model can still use RAG. I always compare against the prompted baseline.

2. How do you evaluate an LLM-powered feature before and after launch?

A strong answer covers:

  • Build a test set from real queries and edge cases with expected outcomes
  • Mix code-based checks, LLM-as-judge with rubric, and human review
  • Evaluate components separately (retrieval, generation)
  • Run evals on every change like regression tests
  • Online: user feedback, task success, cost and latency monitoring
Show model answer

Before launch I build an eval set of real or realistic inputs, including common cases, edge cases and adversarial ones, with expected outcomes or grading criteria. I use the cheapest reliable grader for each check: code checks for format, exact values and JSON validity; an LLM judge with a clear rubric for qualities like helpfulness and faithfulness to sources; and human review on a sample, which I also use to calibrate the judge. For RAG I evaluate retrieval separately with recall at k, then generation for correctness and citation support. I run the suite on every prompt, model or pipeline change and compare per category to catch regressions. After launch I track thumbs up and down, task completion, escalation rate, latency and cost, and regularly add failed production cases back into the eval set.

3. Your RAG bot often answers "I could not find this" even though the answer is in the documents. How do you improve retrieval?

A strong answer covers:

  • Measure retrieval recall with labelled queries first
  • Fix parsing and chunking (structure, overlap, metadata)
  • Hybrid search with keywords plus vectors
  • Query rewriting or expansion; reranking
  • Try a better or domain-suited embedding model
Show model answer

First I measure. I collect queries where the answer is known to be in the corpus, label the correct chunks, and compute recall at k. Then I look at failures. Often the problem is parsing: tables, PDFs or scanned pages extracted badly. Next is chunking: I split along headings, add overlap, and prepend document and section titles so chunks have context. If users search for codes, names or exact terms, I add keyword search like BM25 and fuse it with vector results. Query rewriting helps when user questions are short or conversational, for example turning "what about refunds?" into a full question using chat history. Retrieving more candidates and using a cross-encoder reranker improves precision. Finally, I test a different embedding model on my labelled set. I change one thing at a time and track recall.

4. You need an LLM to extract fields from invoices into your database. How do you make this reliable?

A strong answer covers:

  • Define a strict schema with types and enums
  • Use structured output or tool calling
  • Validate with code; business rule checks
  • Retry or route to human review on failure or low confidence
  • Evaluate field-level accuracy on labelled invoices
Show model answer

I define a clear schema: field names, types, enums for things like currency, and nullable fields so the model can say a value is missing instead of inventing it. I use the provider structured output or tool calling so responses follow the schema. Then I validate in code with something like Pydantic or Zod, and add business checks: line items should add up to the total, dates should be valid, the tax ID should match a pattern. If validation fails, I retry with the error message included, and if it still fails or values look suspicious, I send the invoice to a human review queue. Low temperature helps consistency. Before launch I build a labelled set of real invoices and measure accuracy per field, and I keep monitoring correction rates from reviewers after launch.

5. How do you design good tools (functions) for an LLM to call?

A strong answer covers:

  • Clear names, descriptions and typed parameters
  • Few focused tools rather than many overlapping ones
  • Return concise, useful results and helpful error messages
  • Validate arguments and enforce permissions in code
  • Make actions idempotent and confirm risky ones
Show model answer

The model only knows what the tool name, description and schema tell it, so I write them like documentation for a new developer: what the tool does, when to use it, and what each parameter means, with types and enums. I prefer a small set of focused tools over many overlapping ones, because overlap confuses the model. Tool results should be concise and relevant, not huge raw dumps that waste context, and errors should explain what went wrong so the model can fix its call. On the application side I validate every argument, enforce the user permissions in code rather than trusting the model, and follow least privilege. For actions with side effects, like refunds or sending emails, I make them idempotent and require confirmation. I test tool selection with evals that check the right tool and arguments are chosen.

6. How do you measure the retrieval part of a RAG system separately from the generation part?

A strong answer covers:

  • Build a labelled set of queries with known relevant chunks
  • Use recall@k to check the right chunks are retrieved
  • Use MRR or nDCG to check ranking quality
  • Evaluate generation separately for faithfulness and correctness
  • Track metrics per change: chunking, embeddings, hybrid, reranking
Show model answer

I split the evaluation in two. For retrieval I build a labelled set of real queries, each mapped to the chunks or documents that contain the answer, often with help from domain experts or by generating questions from known passages and reviewing them. Then I compute recall@k, because the model cannot use a chunk that was never retrieved, and MRR or nDCG to see whether good chunks rank near the top. Precision@k tells me how much noise goes into the prompt. For generation I separately check faithfulness to the retrieved context and answer correctness, using rubric-based judges calibrated on human labels. Keeping them apart tells me where to fix things: if recall is low I work on chunking, embeddings, hybrid search or reranking; if recall is fine I work on the prompt or model.

7. How would you implement streaming LLM responses in a web app, and what problems do you need to handle?

A strong answer covers:

  • Use server-sent events or a streaming HTTP response from the backend
  • Keep the API key on the server and proxy the stream
  • Handle partial tool-call arguments by buffering until complete
  • Handle client disconnects and cancel upstream work
  • Validate or moderate content that is shown before it is complete
Show model answer

The browser calls my backend, never the provider directly, so the key stays secret. The backend opens a streaming request to the model and forwards text deltas to the client, usually as server-sent events, and the UI appends them as they arrive. This mainly cuts time to first token, which is what users feel. There are several details to handle. Tool-call arguments stream as JSON fragments, so I buffer them per call and parse only when complete. If the user closes the tab, I cancel the upstream request to stop paying for tokens. Errors can happen mid-stream, so the UI needs a clear failure state and retry. Since text is shown before it is finished, any structured output must be validated at the end, and for sensitive apps I run moderation in chunks.

8. What kinds of caching can you use in an LLM application, and what are the risks of each?

A strong answer covers:

  • Provider prompt caching for repeated prefixes needs stable prompt order
  • Exact-match response caching is safe but hits rarely
  • Semantic caching raises hit rate but risks false hits
  • Cache keys must include user, permissions, model and prompt version
  • Use expiry and invalidation when source data changes
Show model answer

I think in three layers. First, provider prompt caching: if long system prompts, tool definitions or documents are a stable prefix, the provider reuses that work, cutting cost and latency, so I put static content first and changing content last. Second, exact-match caching of full responses keyed by normalised input, model and prompt version. It is safe but only hits for repeated questions. Third, semantic caching, which returns a stored answer for a similar question. It raises hit rates but can return wrong answers when phrasing is close but meaning differs, so I use a strict threshold, measure false hits on labelled pairs, and skip it for actions. For all of them, the cache key must include user or tenant and permissions so nobody gets someone else data, and entries need expiry when sources change.

9. What would you put in place to observe and monitor an LLM application in production?

A strong answer covers:

  • Traces with spans for each model call, retrieval and tool call
  • Record prompt version, model, tokens, cost and latency per span
  • Collect user feedback and run online evals on sampled traffic
  • Alert on error rates, latency, cost and quality signals
  • Handle PII in logs with masking and retention rules
Show model answer

I instrument every request as a trace, with spans for each model call, retrieval step and tool call, often using OpenTelemetry-style conventions so it works with existing tooling. Each span records inputs and outputs, prompt version, model, token counts, cost, latency and errors. That lets me debug a single bad answer and also see trends. On top I add product signals such as thumbs up or down, edits and retries, and run automated online evals, like groundedness or format checks, on a sample of traffic. Dashboards and alerts cover error rates, time to first token, p95 latency, cost per request and drops in quality scores, broken down by prompt version so I can tie regressions to deploys. Because traces hold user text, I mask PII and set strict retention and access.

10. How would you build and maintain a golden evaluation set for an LLM feature?

A strong answer covers:

  • Start from real user inputs covering common and edge cases
  • Define expected outputs or rubrics with domain experts
  • Include known failures and adversarial cases
  • Version the set and run it on every prompt or model change
  • Refresh it from production as traffic changes
Show model answer

I start from real inputs, sampled from logs or pilot users, so the set reflects actual traffic rather than what I imagine. I make sure it covers the main intents plus edge cases: empty input, long input, other languages, and questions we should refuse. For each case I write an expected answer or a grading rubric together with domain experts, since some tasks have many valid answers. Every bug report becomes a new case, so past failures never quietly return. The set is versioned in the repo and runs in CI on every prompt, model or retrieval change, with results compared per category. I keep it large enough to detect the size of change we care about, and refresh it regularly from production so it follows shifts in what users ask.

Hard questions hard

1. Design a RAG assistant over 2 million internal documents with different access permissions per team.

A strong answer covers:

  • Ingestion pipeline: parsing, chunking, metadata, incremental updates
  • Hybrid retrieval with reranking
  • Permission filtering at retrieval time (document-level ACLs)
  • Citations, refusal when unsupported
  • Evaluation, monitoring, cost and latency budgets
Show model answer

I would start with ingestion: connectors pull documents from each source, parse them carefully (including PDFs and tables), split them along structure, and store chunks with metadata such as source, date, owner and access control list. Updates are incremental using change events, and deletions remove vectors quickly. Retrieval uses hybrid search, vector plus BM25, and always applies a permission filter based on the user identity at query time, so the model never sees chunks the user cannot access; filtering after generation is too late. A reranker narrows to the top few chunks. The generator is instructed to answer only from sources, cite them, and say when it cannot find an answer. I build an eval set per department, measure retrieval recall and answer faithfulness, and monitor latency, cost per query, feedback and stale content.

2. How would you protect an LLM application that reads emails and can take actions, against prompt injection and data leaks?

A strong answer covers:

  • Treat all external content as untrusted data
  • Least privilege tools and scoped credentials
  • Human confirmation or policy checks for sensitive actions
  • Input and output filtering, PII and secret detection
  • Logging, monitoring, red teaming
Show model answer

I assume prompt injection will happen, because any email can contain instructions written for the model. So the design must stay safe even if the model is fooled. First, untrusted content is clearly separated from instructions and treated as data. Second, least privilege: the agent only gets tools it needs, with scoped credentials, for example read-only access by default and sending only to allowlisted domains. Third, sensitive actions such as sending email, deleting data or making payments go through code-level policy checks and user confirmation that shows exactly what will happen. Fourth, I block common exfiltration routes, like rendering external image links containing data, and scan outputs for secrets and personal data. Finally I log every tool call, monitor for unusual patterns, and run regular red-team tests with known injection attacks in my eval suite.

3. An agent that completes multi-step tasks works in demos but fails often in production. How do you make it reliable?

A strong answer covers:

  • Prefer simple workflows; use agents only where needed
  • Tracing to find failure steps
  • Better tools, clearer instructions, structured state
  • Budgets, retries, checkpoints, human-in-the-loop
  • Task-level evals with realistic scenarios
Show model answer

First I add tracing so I can see each step: the prompt, the tool calls, the results and where it went wrong. Usually failures cluster: wrong tool choice, bad arguments, confusing tool output, or losing track of the goal. Then I simplify. Many tasks do not need a free-form agent; a fixed workflow with LLM steps at specific points is more predictable, so I only keep autonomy where it adds value. I improve tool descriptions and errors, keep explicit state like a task plan or checklist, and validate each step output. I add hard limits on steps, tokens and time, retries for transient tool errors, and checkpoints so long tasks can resume. Risky actions get human approval. Finally I build task-level evals from real production failures and measure success rate, cost and steps per task on every change.

4. Your LLM feature costs too much and p95 latency is 9 seconds. Walk through how you would reduce both without hurting quality.

A strong answer covers:

  • Measure: tokens, calls per request, time breakdown
  • Shorter prompts and context; fewer chained calls
  • Model routing: smaller models for easy requests
  • Prompt caching, response caching, batching
  • Streaming for perceived latency; evals to protect quality
Show model answer

I start by measuring where time and money go: input and output tokens per request, number of model calls, retrieval time and time to first token. Often there are quick wins: a bloated system prompt, too many retrieved chunks, or several sequential calls that could run in parallel or be merged. I reduce output length with clear instructions and max tokens, since output tokens are slow and costly. I add model routing, where a small fast model handles simple requests and only hard ones go to the large model; sometimes a fine-tuned small model replaces the large one for a narrow task. Prompt caching cuts cost for repeated prefixes, and caching full responses helps for repeated questions. Streaming improves perceived latency. For offline jobs I use batch APIs. Every change is checked against the eval set so quality does not slip.

5. When would you fine-tune a smaller open-weight model instead of using a large hosted model, and how would you do it?

A strong answer covers:

  • Narrow, high-volume task with clear success criteria
  • Cost, latency, privacy or on-premise requirements
  • Generate or collect high-quality training data, possibly distil from a large model
  • Parameter-efficient methods like LoRA
  • Compare on held-out evals; plan serving and maintenance
Show model answer

I consider it when the task is narrow and high volume, such as classifying tickets or extracting fields, and a large model already does it well but is too expensive or slow at scale. Data privacy or on-premise rules are another strong reason. The steps: define the task and an eval set first. Collect training data from labelled history or by having the large model produce outputs that humans spot-check, which is a form of distillation; check the provider terms allow that. Clean the data carefully, since quality matters more than size. Fine-tune with a parameter-efficient method like LoRA, which is cheap and keeps the base model frozen. Compare the fine-tuned model against the large model on held-out data, including edge cases. Finally plan serving with something like vLLM, monitoring, and a process to retrain when data drifts.

6. You must self-host an open-weights LLM for a high-traffic product. How do you plan memory, throughput and latency?

A strong answer covers:

  • Size weights by parameter count and precision, and choose quantization carefully
  • Budget KV cache memory from layers, KV heads, context and concurrency
  • Use an inference server with continuous batching and paged KV cache
  • Balance throughput against time to first token and per-token latency
  • Load test with realistic prompt and output lengths, then autoscale
Show model answer

I start with memory. Weights need parameters times bytes per parameter, so a model in 16-bit needs about 2 bytes per parameter, and 8-bit or 4-bit quantization cuts that but must be checked on our evals. Then the KV cache: per token it is 2 × layers × KV heads × head size × bytes, multiplied by context length and concurrent sequences, and it often dominates at long contexts. I would use a serving engine with continuous batching and paged KV cache, which raises throughput a lot. The key trade-off is throughput versus latency: bigger batches lower cost per token but raise time per token, so I set limits from our latency targets. Prefix caching and speculative decoding can help further. Finally I load test with realistic prompt and output lengths, and autoscale on queue depth.

7. Users say your AI assistant got worse this week, but nothing obvious changed. How do you investigate?

A strong answer covers:

  • Confirm with data: feedback, online eval scores, segments
  • Check every change: prompts, model or provider version, retrieval index, tools, data
  • Compare traces of bad cases to find which step fails
  • Check for input drift such as new topics or languages
  • Fix, add failing cases to the golden set, and add alerts
Show model answer

First I confirm and size the problem with data: feedback rates, retries, online eval scores and abstentions, split by intent, language and customer, to see whether it is broad or one segment. Then I list everything that can change silently: prompt versions, the provider model behind an alias, the embedding model, the index contents, tool APIs, and upstream data. I pull traces of bad examples and walk through each span to find the failing step, for example retrieval returning stale chunks or a tool now returning a new format. I also compare this week inputs with last week to spot drift, such as new topics after a launch. Once I find the cause, I fix it, rerun the golden set, add the failing cases to it, and add alerts or pinned versions so it is caught sooner next time.

8. How do you design an LLM-as-judge evaluation you can actually trust?

A strong answer covers:

  • Use specific rubrics or binary criteria rather than vague 1-10 scores
  • Calibrate against human labels and measure agreement per class
  • Mitigate position, verbosity and self-preference biases
  • Give the judge references or source context where possible
  • Re-check calibration when judge model or rubric changes
Show model answer

I make the judging task narrow. Instead of "rate quality 1 to 10", I ask specific yes or no questions, such as "is every claim supported by the context?" or "does it follow the refund policy?", each with a clear rubric and examples. I give the judge the reference answer or source documents when I have them. Then I calibrate: experts label a few hundred examples with enough failures in them, and I measure the judge recall on bad answers and a chance-corrected agreement like Cohen kappa, not raw accuracy, which looks good under class imbalance. I counter known biases by swapping order in pairwise tests, penalising padding, and avoiding the same model judging its own outputs. Whenever the judge model or rubric changes, I recalibrate, and I keep sampling cases for human review.

9. When would you choose a multi-agent architecture over a single agent or a fixed workflow?

A strong answer covers:

  • Prefer fixed workflows when steps are known in advance
  • A single agent with good tools covers most open-ended tasks
  • Multi-agent helps with parallel subtasks or context isolation
  • Multi-agent adds cost, latency, coordination errors and harder debugging
  • Decide with evals and traces, not by default
Show model answer

I start with the simplest option that works. If the steps are known, such as classify, retrieve, draft, check, a fixed workflow is cheaper, faster and easier to test. If the path depends on what the model finds, a single agent with a well-designed tool set handles most cases. I move to multiple agents only for a clear reason. One is parallelism: an orchestrator can send several subagents to research different parts at once. Another is context isolation: each subagent works in its own fresh context and returns a short summary, which keeps the main context clean on long tasks. The costs are real: many more tokens, more latency, lost information at handoffs, and harder debugging. So I compare designs on the same eval set and use tracing across agents before committing.

10. Your agent will connect to several MCP servers, some built by third parties. How do you make this secure?

A strong answer covers:

  • Treat servers, tool descriptions and tool results as untrusted input
  • Apply least privilege with scoped credentials per server
  • Require human approval for sensitive or irreversible actions
  • Avoid combining private data, untrusted content and exfiltration paths
  • Pin and review server versions, sandbox them, and log all tool calls
Show model answer

I treat every MCP server as untrusted code and its output as untrusted input. Tool descriptions and results go straight into the model context, so a malicious server can inject instructions. I review descriptions before enabling a server, pin versions so they cannot change silently, and run local servers in a sandbox with limited file and network access. Each server gets its own scoped credentials with least privilege, and OAuth tokens are never passed between servers. I watch for the dangerous mix of private data, untrusted content and a way to send data out, because together they allow exfiltration; I remove one leg or require human approval for actions like sending email, payments or deleting data. Finally I log every tool call with its arguments for audit, and red-team the setup with injected content.