AI Engineering Interview Questions: Agents & Tool-Calling
Reviewed by Mark Dickie · Last updated
Tool-calling in AI agents is the mechanism by which a large language model requests execution of an external function, such as querying a database or calling an external API, rather than answering from its pretrained weights alone. For an AI engineering interview, you should know the end-to-end tool-call loop: how a tool's schema is defined in JSON, how the model decides whether to call a tool or respond directly, how an orchestrator executes the call and feeds the result back, and how to handle failures. Interviewers also test whether you understand multi-tool selection, parallel versus sequential execution, and the trade-offs of giving an agent access to tools that mutate state versus read-only tools. Here is how the core concepts map to what interviewers typically ask you to do or explain on the spot:
| Concept | What an interviewer asks |
|---|---|
| Tool schema definition | Write a JSON schema for a function with required and optional parameters |
| Model decision to call | Explain what signals make a model emit a tool_call vs a plain response |
| Orchestration loop | Walk through the full request, execute, observe, respond cycle |
| Error handling | Design retry logic for failed tool calls and malformed results |
| Multi-tool selection | Compare how models choose among several available tools |
| Parallel execution | Identify when tool calls can run concurrently vs when order matters |
How does an LLM decide to call a tool?
The model receives the conversation history along with a list of available tool definitions, each with a name, description, and parameter schema. Based on the user's input and the tool descriptions, the model either generates a natural-language response or emits a structured tool_call object containing the function name and arguments. The key factors:
- The model reads the tool description and judges whether the tool is relevant to the current request.
- It checks that the user's query maps to the tool's expected parameters.
- It emits a
tool_callwith structured arguments matching the JSON schema, or declines and responds directly. - The orchestrator parses the
tool_call, executes the function, and appends the result as atoolrole message. - The model reads the tool result and either calls another tool, responds to the user, or requests clarification.
What are the common failure modes in tool-calling agents?
Interviewers want to see that you can identify and handle the ways tool calls go wrong. The frequent ones: the model hallucinates parameters not in the schema, the external service times out or returns an error, the model loops calling the same tool repeatedly, or the tool succeeds but returns data the model misinterprets. A strong answer covers parameter validation before execution, timeout and retry policies, loop-detection in the orchestrator (e.g., a maximum tool-call count per turn), and clear error messages passed back to the model so it can recover rather than retry blindly.
What frameworks and APIs are used for tool-calling?
Most production tool-calling today uses the OpenAI function-calling API, Anthropic's tool-use feature, or open-source equivalents in LangChain and LlamaIndex. The core abstractions are similar: you define tools as functions with typed signatures, register them with the model or agent runtime, and the runtime handles the parse-execute-observe loop. The differences show up in how each framework handles multi-tool calls, streaming partial tool arguments, and structured error propagation back to the model.
Key facts
- Tarmac has 65 AI Engineering interview questions on this topic, 25 of them on this page, at difficulty 1–5 of 5.
- Tarmac tracked 4,175 job postings asking for AI Engineering in August 2026.
- Roles asking for AI Engineering advertise a median base salary of US$182,450, across 806 job postings as of August 2026.
- Tarmac last reviewed these AI Engineering interview questions on 31 August 2026.
At a glance
| Questions | 25 shown · 65 in the bank |
|---|---|
| Difficulty | 1–5 of 5 |
| Formats | True / false, Fill in the blank, Flashcard, Multiple choice, Find the bug, Short answer, Code output, Coding exercise, Multiple answer, Ordering |
| Interactive | 2 run your code against tests, in the app |
What you'll review
- tool calling
- agents
- agent loops
- agentic rag
- prompt injection
Practice questions
Try one before you open the answer. Pick an option and press Check; it's marked on the spot.
AI Engineering/agents/tool-calling
An AI agent that uses tool-calling can invoke multiple different tools in a single reasoning loop (i.e., call tool A, observe its result, then call tool B before producing a final answer).#
Options
Show answer
Yes, this is true. AI agents that support tool-calling can invoke multiple tools across successive steps in the same reasoning loop. After each tool returns its result, the result is appended to the conversation context and the model decides whether to call another tool or produce a final answer — a pattern central to frameworks like ReAct and OpenAI's function-calling API.
Modern agent frameworks (e.g., OpenAI function-calling, LangChain agents, ReAct-style loops) allow the model to iteratively call tools over multiple steps. After each tool response is appended to the conversation context, the model can decide to call another tool or produce a final answer. This multi-step tool-use is a core capability that separates agents from simple single-turn LLM calls.
AI Engineering/agents/tool-calling
Complete the following description of how tool-calling works in a typical LLM agent loop:#
Show answer
Complete the following description of how tool-calling works in a typical LLM agent loop:
- The developer registers one or more tools by providing their schema to the model.
- The model reads the user message and, if it decides a tool is needed, emits a structured tool call instead of a plain text reply.
- The orchestration layer executes the tool and appends the result to the conversation as a tool message.
- The model reads the tool result and produces the final answer.
The standard tool-calling loop has four stages: (1) the developer supplies tool schemas so the model knows what tools are available; (2) the model emits a structured tool call (not prose) when it decides a tool is needed; (3) the orchestration layer runs the tool and feeds the result back as a special 'tool' role message; (4) the model uses that result to craft its final answer. Understanding this loop is foundational to building LLM-powered agents.
AI Engineering/agents/tool-calling
Besides letting the model decide (auto) or forcing a tool call, what does a none tool-choice mode do, and when would you use it?#
Show answer
none disables tool calls for that turn entirely, even though the tool definitions are still attached to the request — the model can only respond with text. It's useful when you want the model to explain, summarize, or ask a clarifying question without the option of taking an action, such as a final confirmation turn after a sequence of tool calls has already completed ("here's what I found and did — anything else?"), or any turn where invoking a tool would be premature or unwanted even though tools remain available for later turns in the same conversation.
none is the mirror image of forcing a tool: instead of guaranteeing a call, it guarantees no call, which matters whenever you need the model to communicate rather than act on a specific turn without having to strip and re-add tool definitions for that one turn.
AI Engineering/agents/tool-calling
In an LLM-based agent framework, a tool (also called a "function" in some APIs) is best described as:#
Options
Show answer
A tool is an external capability—such as a web search, calculator, or API—that the model can invoke by emitting a structured call (typically JSON with a function name and arguments). The orchestrator executes the call and returns the result to the model's context, enabling the agent to take real-world actions and reason over live data beyond its training knowledge.
In agentic LLM systems, a tool (or function) is an external capability registered with the model. When the model decides to use it, it emits a structured call (e.g., JSON with a function name and arguments). The orchestrating framework executes that call and injects the result back into the conversation context, allowing the model to reason over the outcome. This is distinct from fine-tuning, system prompts alone, or RAG indexes.
AI Engineering/agents/tool-calling
When an LLM agent makes a tool call, the tool's return value is automatically incorporated into the model's weights so the agent "remembers" it in future sessions without needing to include it in the context window.#
Options
Show answer
False. Tool call results are not stored in the model's weights. LLMs are stateless between inference runs; the tool response is appended to the current conversation context (prompt) only. To persist information across sessions, an external memory store must be used and explicitly retrieved—the weights themselves are never updated during inference.
Tool call results are NOT written into the model's weights. LLMs are stateless between inference calls; the tool's response is simply appended to the conversation context (the prompt) for the current session. If the information needs to persist across sessions it must be stored externally (e.g., in a database or memory module) and explicitly retrieved later—it is never baked into the weights at inference time.
AI Engineering/agents/tool-calling
The following Python snippet registers a tool and calls the OpenAI Chat Completions API with tool-calling enabled. One line contains a bug that will prevent the API from recognizing the tool definition correctly. Identify the buggy line.#
import openai
tool_definition = {
"type": "function",
"function": {
"name": "get_weather",
"description": "Returns current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}
}
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "What is the weather in Paris?"}],
functions=[tool_definition],
tool_choice="auto"
)Options
Show answer
Line 20 — functions=[tool_definition] should be tools=[tool_definition].
The modern OpenAI tool-calling API (introduced mid-2023) uses the tools parameter to pass tool definitions, not the legacy functions parameter. Passing functions=[...] uses the deprecated interface and will be rejected or ignored depending on the model version. The correct call should use tools=[tool_definition] together with tool_choice="auto". Everything else in the snippet—the schema structure, required placement, and message format—is valid.
AI Engineering/agents/tool-calling
What are parallel tool calls, and what is the calling application responsible for once it receives them?#
Show answer
Parallel tool calls happen when a model returns several tool-call requests in a single response instead of one at a time — for example asking for the weather, a stock price, and an exchange rate all in one turn because none of them depend on each other. The API doesn't prescribe how you execute them; that's the application's decision. What the application must do regardless of execution strategy is return exactly one tool result per tool call, each correctly matched to its call's ID, before any other content in the next message — and if a call wasn't actually executed (e.g. an earlier one in the batch failed and you chose to skip the rest), it still needs a tool result marked as an error rather than being silently omitted.
Parallel tool calls are a latency win when the calls are genuinely independent, but the API's flexibility about execution order puts the correctness burden on the application: every emitted call needs a matching result, correctly IDed, or the conversation state becomes invalid.
AI Engineering/agents/tool-calling
Explain how LLM tool calling (function calling) works end to end. Who actually executes the tool?#
Show answer
You give the model a set of tool definitions with names, descriptions, and JSON-schema parameters. When the model decides a tool is needed it doesn't run anything — it returns a structured tool-call request with arguments matching the schema. Your application code executes the function, then sends the result back to the model as a tool-result message, and the model continues, optionally calling more tools, until it produces a final answer. The model only chooses and fills in arguments; your code is the one that actually executes the side effect.
Tool calling is a structured-output contract: the model emits a request (tool name plus schema-validated arguments) rather than running code itself. The host application executes the function, returns the result as a tool message, and the loop repeats. This separation is the whole security model — the model never has direct execution authority, so you can validate arguments, enforce permissions, and sandbox effects before acting. It is also the foundation of agent loops and MCP.
AI Engineering/agents/tool-calling
When an LLM needs to call an external function, the provider typically returns a special _____ message (not streamed text) containing the tool name and arguments, which the application executes before passing the result back to the model in a _____ message.#
Show answer
When an LLM needs to call an external function, the provider typically returns a special tool_call message (not streamed text) containing the tool name and arguments, which the application executes before passing the result back to the model in a tool message.
Tool/function calling works as a two-turn protocol: the model emits a structured tool_call (not prose), the host runs the function, and the result is injected back to the model. Providers name that result message differently — OpenAI uses a tool role message, while Anthropic returns a tool_result content block inside the user turn — but the protocol is identical. This separation keeps execution outside the model—the model only decides what to call and with what arguments, never running the code itself. Validating those arguments against a schema before execution is a key safety guard.
AI Engineering/agents/tool-calling
This executes a model's tool call and appends the result to the conversation, but a failing tool crashes the whole request instead of letting the model react to the failure. Which line is the bug?#
async function handleToolCall(call, tools, messages) {
const tool = tools[call.name];
const result = await tool.execute(call.arguments);
messages.push({
role: "tool",
tool_call_id: call.id,
content: JSON.stringify(result),
});
return messages;
}Show answer
The bug is on line 3.
Line 3 calls tool.execute with no try/catch, so when it throws — a network timeout, a downstream 500, a bug in the tool itself — the exception propagates straight up and kills the entire request instead of becoming a tool result the model can react to. The fix wraps the call in try/catch and, on failure, still pushes a tool message with an error flag and short description, so the model learns the call failed and can decide what to do next — retry, try something else, or tell the user — instead of the user seeing an unhandled server error with no explanation.
AI Engineering/agents/tool-calling
Most tool-calling APIs expose a few tool-choice modes — commonly something like auto, force-any-tool, force-a-specific-tool, and none. Explain what each does and give a concrete reason you'd reach for the forced-specific-tool mode instead of leaving it on auto.#
Show answer
Auto leaves the decision to the model: it can call any of the available tools, several in parallel, or just reply with text if no tool is needed — the normal default for an open-ended assistant. Forcing any tool (without naming one) tells the model it must call something, but leaves which one up to it. Forcing one specific tool removes both decisions: the model is constrained to return arguments matching that tool's schema, guaranteeing structured, schema-conformant output. None disables tool calls entirely for that turn even though the tool definitions are still attached, useful when you want a plain explanatory reply. You'd force a specific tool when you already know a call is required and just need the model to fill in the arguments reliably — the classic case is using a single tool purely as a structured-extraction mechanism (e.g. extracting {name, email, company} from a support ticket) where you never actually execute the 'tool' as a side effect, you just want guaranteed-shaped JSON back on the first turn instead of hoping a free-text JSON reply parses cleanly.
The tool-choice modes trade the model's autonomy for reliability along a spectrum: auto gives it full discretion (including replying with no call at all), forcing any tool removes the "no call" option but not which tool, and forcing a specific tool removes both, guaranteeing exactly one call with schema-conformant arguments. That last mode is the backbone of using tool calling purely as a structured-output mechanism — you never actually run side effects from the "tool", you just exploit the schema-constrained decoding to get reliable JSON instead of parsing prose. None is the escape hatch for turns where you want the model to talk without the option to act.
AI Engineering/agents
What's the practical difference between 'an LLM that can call tools' and 'an agent,' and why does the distinction matter when you're deciding how to architect a feature?#
Show answer
Tool-calling is a capability — the model can emit a structured request for your code to execute. An agent is an architecture built on top of that capability: the model runs an iterative loop where it plans a next step, observes the result of acting on it, and decides on its own what to do next, potentially many times, until it judges the task done. A single tool call followed by one response is much closer to a scripted workflow than an agent — the control flow is still effectively fixed. The distinction matters architecturally because agents trade predictability for flexibility: more LLM calls, more latency, non-deterministic behavior, and a need for guardrails (iteration caps, budgets, human checkpoints) a single call or fixed pipeline doesn't need. Reach for an agent only when the task's path genuinely can't be predetermined; otherwise a workflow of one or more scripted tool calls is simpler, cheaper, and more predictable.
The line between 'tool calling' and 'agent' is architectural, not a marketing label: the loop the model runs and the decisions it's allowed to make on its own is what separates them, and that difference is exactly what should drive the build-vs-simplify call on a new feature.
AI Engineering/agents/agent-loops
This models the standing cost of an agent's tool definitions, which are re-sent on every iteration. What does it print?#
tools = 40
tokens_per_schema = 120
iterations = 12
per_call = tools * tokens_per_schema
per_run = per_call * iterations
print(per_call, per_run)Options
Show answer
The program prints 4800 57600. Forty schemas at 120 tokens each is 4,800 tokens on every call, and twelve iterations makes 57,600 for the run — before any of the actual conversation. Tool definitions are not sent once at the start; they are part of every request the loop makes, so a large tool surface is a fixed tax multiplied by the iteration count. Narrowing the set per run cuts it directly and improves selection accuracy at the same time. Being stable and near the front, schemas also cache well — provided the list is built in a deterministic order.
40 schemas at 120 tokens is 4,800 tokens on every single call, and twelve iterations makes 57,600 tokens for the run — before a word of the actual conversation. That is the part teams miss: tool definitions are not sent once at the start, they are part of every request the loop makes, so a large tool surface is a fixed tax multiplied by the iteration count. It is also the cheapest thing to cut, because most runs need a handful of those forty. Narrowing the tool set per run reduces this directly and improves selection accuracy at the same time — one change, two wins. Note the interaction with caching: tool definitions sit near the front of the prompt and are stable, so they cache well when their order is deterministic; build the list from an unordered map and you lose both the cache and any hope of diagnosing why.
AI Engineering/agents/agent-loops
Implement build_tool_results(calls, outcomes). calls is the list of tool calls in one assistant turn, each a dict with id and tool. outcomes maps a call id to a dict with ok (bool) and value (string).#
Starter code
def build_tool_results(calls, outcomes):
# TODO: answer every call, including the failures
return [
{"tool_call_id": c["id"], "content": outcomes[c["id"]]["value"], "is_error": False}
for c in calls
if c["id"] in outcomes and outcomes[c["id"]]["ok"]
]Your solution must pass
- both succeed
- a failure is still answered
This one is written and run, not read. Solve it in the app and your code is executed against these tests and the hidden ones.
AI Engineering/agents/tool-calling
You are building an agent using the OpenAI Chat Completions API with tools defined. The model decides it needs to call get_weather(location="Paris"). Which sequence of events correctly describes what happens next?#
Options
Show answer
The API returns a finish_reason of "tool_calls" with a tool_calls array. Your application code must call the tool, then make a second API request appending a role: "tool" message with the result. The model does not execute tools itself — the caller owns the execution loop and feeds results back for the model to produce a final answer.
When an LLM is given a set of tools, it returns a structured 'tool_call' object (or equivalent) rather than a plain text answer when it decides a tool should be invoked. The caller is then responsible for executing the tool, collecting the result, and passing it back to the model as a 'tool' role message. The model does NOT execute the tool itself, and it does not simply embed the result inline — the conversation must include a follow-up turn with the tool's output before the model produces the final answer. This round-trip is fundamental to how OpenAI-style function/tool calling works.
AI Engineering/agents/tool-calling
A ReAct-style agent receives a single model response containing three parallel tool_calls. Which of the following statements are true about how the agent should handle this situation? Select all that apply.#
Options
Pick every one that applies.
Show answer
The true statements are: (a) parallel tools can be executed concurrently with one role: "tool" message per tool_call_id; (b) data dependencies between tools make parallel execution unsafe — they must be serialized; and (e) omitting any tool result from the follow-up request leaves the model with incomplete context. The API does not require sequential submission, and strict schema validation only enforces argument shape, not execution order.
Parallel tool calling allows a model to emit multiple tool_call entries in a single response, which the agent can execute concurrently before returning all results. The key subtlety is that each tool result must be returned as a separate role: "tool" message keyed by its tool_call_id. If any result is missing from the follow-up request the model has incomplete context. Additionally, if tools share side-effects or sequential data dependencies (e.g., tool B needs tool A's output), parallel execution is unsafe and the agent must serialize them. 'Strict' JSON schema validation prevents the model from generating malformed arguments, but does not force sequential execution.
AI Engineering/agents/tool-calling
The following Python agent loop uses the OpenAI SDK to run a single tool-calling round-trip. There is one logical bug that causes the model to never receive the tool result. Identify the buggy line.#
import json
import openai
client = openai.OpenAI()
def get_weather(location: str) -> str:
return f"Sunny, 22°C in {location}"
messages = [{"role": "user", "content": "What's the weather in Tokyo?"}]
tools = [{"type": "function", "function": {"name": "get_weather",
"parameters": {"type": "object", "properties": {"location": {"type": "string"}},
"required": ["location"]}}}]
response = client.chat.completions.create(model="gpt-4o", messages=messages, tools=tools)
assistant_msg = response.choices[0].message
conversation = messages + [assistant_msg]
if assistant_msg.finish_reason == "tool_calls":
for tc in assistant_msg.tool_calls:
args = json.loads(tc.function.arguments)
result = get_weather(**args)
conversation.append({
"role": "tool",
"tool_call_id": tc.id,
"content": result
})
final = client.chat.completions.create(model="gpt-4o", messages=messages)
print(final.choices[0].message.content)Show answer
The bug is on line 29.
The bug is on line 29. After appending the tool result message to conversation, the follow-up API call on line 29 re-passes the original messages list instead of the updated conversation list. This means the model never sees the assistant's tool_call message or the tool result, causing it to behave as if no tool was ever called. The fix is to pass conversation to the second client.chat.completions.create call so the full conversation history — including the assistant's tool invocation and the tool's response — is sent to the model.
AI Engineering/agents/tool-calling
When a model emits multiple tool calls in a single response, it is always safe to execute them in parallel without considering their dependencies.#
Options
Show answer
False. Models can emit parallel tool calls, but they have no reliable way to express or enforce data dependencies between them. If tool B depends on tool A's output, the model may still emit both at once, and executing them in parallel produces wrong results or a runtime error. As the orchestrator you must detect dependencies and sequence accordingly. A safe default is to run co-emitted calls in parallel only when their inputs are independent, and always validate before executing.
Models can and do emit parallel tool calls (supported natively in the Anthropic and OpenAI APIs), but they have no reliable way to express or enforce data dependencies between those calls. If tool B depends on the output of tool A, the model may still emit both in one response — and executing them in parallel produces incorrect results or a runtime error. As the orchestrator, you must detect dependencies (e.g. one tool's argument references another's output placeholder) and sequence or group calls accordingly. A safe default is to treat co-emitted calls as parallel only if their inputs are independent of each other, and always validate before executing.
AI Engineering/rag/agentic-rag
In an agentic RAG system with several knowledge sources (a docs index, a code index, and a live web search tool), how does the agent decide where to look, and why is exposing retrieval as tools better than always querying every source?#
Show answer
Each source is exposed to the agent as a separate tool with a clear name and description (search_docs, search_code, web_search), and the LLM routes the query by reading those descriptions and the user's intent — picking the relevant source, or several, and reformulating the query per source. This is query routing: the model decides which retriever fits the question rather than a fixed pipeline hitting one index. Exposing retrieval as tools beats fanning out to every source on every query because it cuts cost and latency (fewer unnecessary retrievals and tokens), avoids polluting the context with irrelevant passages that can distract the model and lower answer quality, and lets the agent iterate — retrieve from one source, judge sufficiency, then go to another only if needed. The tradeoff is that routing depends on good tool descriptions and adds a model decision that can be wrong.
Agentic RAG treats each retriever as a tool with a descriptive contract, and the model performs query routing: it reads the tool descriptions plus the user intent to choose the right source(s) and tailor the query to each. Querying every source unconditionally is wasteful and counter-productive — extra cost/latency, and irrelevant passages crowd the context and degrade the answer. Tool-mediated routing also enables iteration (retrieve, assess sufficiency, retrieve again from a different source only if needed). The cost is the dependence on well-written tool descriptions and a routing decision that the model can get wrong, which is why routing quality belongs in your eval set.
AI Engineering/agents/agent-loops
A tool-using agent answers a question that requires calling an external API. Order one iteration of its tool-call loop.#
Put these in order
Show answer
A tool-using agent runs one iteration of its loop in this order:
- Send the prompt plus available tool definitions to the model
- Model responds with a tool call (name + arguments)
- Application executes the tool and captures its result
- Feed the tool result back to the model as a tool message
- Model produces the final natural-language answer
The loop is: present the model with the tools it may call, the model decides to emit a tool call with structured arguments, your code executes that tool (the model never runs it), you return the result as a tool/function message appended to the conversation, and the model then synthesizes the final answer from it. For multi-step tasks the middle three steps repeat until the model stops requesting tools.
AI Engineering/agents/tool-calling
You're defining a set of tools for a customer-support agent to call. Which of these are genuine practices for reliable tool calling? Select all that apply.#
Options
Pick every one that applies.
Show answer
Genuine practices are writing a specific, unambiguous description for each tool stating what it does and when to use it, constraining arguments as tightly as the task allows with enums, explicit types, and required-versus-optional fields rather than free-text strings, keeping each tool's scope narrow so tools don't overlap in purpose, and adding clarifying detail to a description whenever a tool could plausibly be confused with a similar one. Defining many tools with overlapping purposes just in case is the opposite of good practice — it increases the odds the model picks the wrong one and makes every description's job harder.
Reliable tool calling comes from giving the model unambiguous signal at both selection time and argument-filling time. Specific descriptions (a) and tight argument typing (b) are exactly that signal, and a narrow, non-overlapping tool set (c) removes the ambiguity that causes wrong-tool selection in the first place — reinforced by disambiguating detail where two tools could plausibly be confused (e). Defining many overlapping tools "just in case" (d) is the opposite: it increases the chance the model picks the wrong one and makes every description's job harder, since it now has to differentiate itself from near-duplicates instead of just describing its own job.
AI Engineering/agents/tool-calling
Your agent has a tool that runs a database query built from arguments the model supplies. Which of these are genuine security considerations for executing that tool call? Select all that apply.#
Options
Pick every one that applies.
Show answer
Genuine considerations are validating and sanitizing the arguments before executing even though they came from a schema-constrained model response, enforcing least privilege on what the tool's underlying credentials can do, treating the arguments as untrusted input since the text that led the model to produce them may itself have come from an untrusted source, and logging tool calls and arguments so a suspicious call can be audited afterward. Skipping input validation because JSON-schema validation already guarantees safety is not a genuine safeguard — schema validation only checks shape and type, not whether a value is safe to interpolate into a query or command.
Schema validation only checks shape and type (this argument is a string, that one is an integer) — it says nothing about whether a string is safe to interpolate into a query or a shell command, so treating schema-passing as "safe to execute" (d) is a real vulnerability, not a genuine practice. The model's arguments can be influenced by untrusted content it read earlier in the conversation (c), so they deserve the same scrutiny as any other external input: validate/sanitize before executing (a), run with the least privilege the task needs so a bad or manipulated call can't do more damage than necessary (b), and keep an audit trail (e) so you can detect and investigate when something did go wrong.
AI Engineering/agents/agent-loops
Implement retry_decision(kind, status) for an agent loop's tool wrapper. kind is "read" or "mutating". status is an HTTP status code, or 0 for a connection timeout where no response was received.#
Starter code
def retry_decision(kind, status):
# TODO: 429 first, then 4xx, then 5xx/timeout by kind
if status >= 500 or status == 0:
return "retry"
return "surface"Your solution must pass
- read, 503
- mutating, 500
- read, 400
- mutating, 429
This one is written and run, not read. Solve it in the app and your code is executed against these tests and the hidden ones.
AI Engineering/agents/tool-calling
An AI agent built on the OpenAI Chat Completions API issues two parallel tool calls in a single assistant turn (the tool_calls array has two entries). Which message-history sequence is required before the model can produce a follow-up assistant reply?#
Options
Show answer
The required sequence is: the assistant message containing the tool_calls array, followed by one separate tool role message per tool call (each referencing its own tool_call_id), then the next assistant turn. The OpenAI API validates that every tool_call_id in the assistant message is resolved by a corresponding tool role message before it will accept another assistant generation; bundling results or using a user role both cause a 400 error.
When an LLM agent receives a tool call response, the message history must follow the provider's expected role sequence. For OpenAI's chat completions API with parallel tool calls, the assistant message containing the tool_calls array must come first, then one tool role message per tool call (each referencing the matching tool_call_id), before the model can generate a follow-up. Inserting a plain user message or omitting the assistant tool_calls message before the tool results causes a 400 validation error. Option C describes the only valid sequence.
AI Engineering/evaluation-safety/prompt-injection
Order the steps of the dual-LLM (privilege-separation) pattern for an agent that must check an untrusted webpage for a discount code and, if found, apply it to the user's cart.#
Put these in order
Show answer
The dual-LLM pattern for this task runs in this order:
- User asks the agent to check a webpage for a discount code and apply it
- A quarantined LLM with no tool access reads the raw webpage content and extracts only a narrow, typed value — the code string, or null
- The extracted value is passed to the privileged LLM as a plain variable, never as the raw page text
- The privileged LLM, which has tool access but never reads the untrusted page itself, decides whether to call the apply_discount tool with that variable
- The apply_discount tool call is checked against a hard rule (e.g. one use per order, valid code format) before it actually executes
The pattern only holds its trust boundary if the untrusted content is read exclusively by the tool-less component (b) after the task is issued (a), and only a narrow, typed extract crosses into the privileged side (c) — passing the raw page text across would recreate the exact vulnerability the split exists to avoid. The privileged LLM then makes the tool-call decision from that sanitized variable alone (d), and because even a correctly-designed extraction step or a flawed controller can still misfire, the resulting tool call is still checked against an independent hard rule before it takes effect (e) rather than being trusted purely because it came from the privileged side.
Related interview questions
Job market
See ai-engineering salaries and hiring demand from live job postings.
The other 40 questions
This page shows 25 and marks what you pick. That's as far as a page can go. A free account opens the other 40 and keeps every answer. What you miss comes back until it's right: after a day, then at longer gaps.
Free · the whole bank · 100 marked answers per 30 days · written feedback on the paid plan