Dayward AI
Week 4 · D26About 6 hours

System Design Deep Dive: Agent Platforms / Customer-Support Agents / Multi-Tenancy / Cost Control

Prepare an interview-ready answer template for each of four frequently asked system-design topics: agent platforms, customer-support agents, multi-tenancy, and cost control.

Today's goals 0/3

Sign in to tick these off and save your progress.

Today's Goals

  1. Give a system-design answer template for an agent platform (architecture, scalability, cost)
  2. Give a system-design answer template for a customer-support agent (multi-turn conversation, escalation to a human, knowledge base)
  3. Give a checklist of design points for both the multi-tenancy and cost-control topics

From today this course has no new technology: yesterday connected the backend to a browser and four weeks of technical content ended there — the next five days practice expression, how these same parts become an answer that makes an interviewer nod within 40 minutes. So you will see many familiar terms today, and the point is not what each is but "how many minutes this section gets, where the interviewer will interject, and which sentence loses points on the spot."

Plain-Language Walkthrough

The client gives you one sentence, and you cannot pull out construction drawings

An architecture bid presentation. The client opens with one sentence: "We want an office building."

The firm that lost unrolled a set of construction drawings on the spot, with beam reinforcement and pipe routing all drawn. Beautiful drawings, and by the third minute the client was looking at their phone — they had not yet said whether the budget was twenty million or two hundred.

The firm that won spent five minutes asking first: budget range, stories, fire rating, timeline. Then they produced a site plan of nothing but boxes and arrows, went deep on structural selection and fire egress, and said "standard practice" for everything else. The last five minutes were dedicated to trade-offs: why no second basement level, and at what budget the scheme should be overturned.

Whoever opens with construction drawings loses. A system-design interview is that same presentation: a one-sentence brief, 35 to 40 minutes, and one client scoring silently. The answer's shape is five fixed steps, each with a time box:

StepTimeWhat this step must deliver
1 Clarify requirements5 mindaily actives and concurrent sessions, per-turn latency budget, cost budget, multi-tenant or not, failure tolerance
2 Capacity and cost estimate3 mina number with arithmetic behind it, not a number reported by feel
3 Architecture sketch8 minfour blocks: intake, execution, storage, observability
4 Go deep on 2 to 3 points15 minpicked live from three pre-prepared deep-dive packs
5 Trade-offs5 minwhat you gave up, and at what scale this design gets overturned

Below, step by step, where the interviewer will interject.

Step one, clarifying, 5 minutes. None of the five questions is optional, because each substantially changes the architecture: daily actives decide whether to split, the latency budget decides synchronous versus asynchronous, the cost budget decides model tiering, multi-tenancy decides the table structure, and failure tolerance decides the shape of retries and degradation. The interviewer will most likely interject "just assume something" — that is not "stop asking," it is "give a number yourself and state your basis": "then I will work from 10,000 daily actives at 5 turns each, and if it is actually six figures I will say in step five what changes." Whoever starts drawing without asking discovers twenty minutes later that they solved a different problem.

Step two, estimating, 3 minutes. Reporting only the result and not the arithmetic is this step's most common death. The interviewer's interjection will certainly be "where did that number come from."

Step three, the sketch, 8 minutes. Four boxes and arrows suffice. The interviewer will point at an arrow and ask "is this synchronous or asynchronous" — drawing every arrow as a synchronous call is this step's only fatal flaw.

Step four, going deep, 15 minutes. This cannot be improvised, and three deep-dive packs must be prepared so whichever the interviewer picks you have it: state and ordering, cost and rate limiting, failure and retry, corresponding to what you already wrote on D11, D13, and D9 plus D10.

Step five, trade-offs, 5 minutes. Almost nobody does this step, and doing it earns points — it is the shortest dividing line between having designed something and having read a design.

Reciting the structure is not the same as delivering it. Each of the four frequent topics has one through-line, and with the wrong line the five steps are a hollow frame however correctly walked. Each of the four templates below pins a line first and hangs the parts off it.

Template one: an agent platform, whose line is "stateless execution plus stateful orchestration"

The line in one sentence: the gateway is stateless and scales horizontally; a run's state lands in Postgres; long tasks are decoupled by a message bus; orchestration is in the worker. Say it in the first second of the architecture sketch, because it is what every later detail hangs from.

This topic's own clarifying questions are three: how long is one execution (three hundred milliseconds, do not split; thirty seconds, you must), is streaming needed (yes means one endpoint becomes two), and do the tools have side effects (yes means a human-confirmation tier and argument caps).

For estimating's 3 minutes, write this out live. It is six lines, and changing any input changes all six outputs — which is precisely the "changes with it" the interviewer wants.

estimate.js
// Write these lines on the whiteboard. Prices: 0.15 dollars per million input tokens,
// 0.60 per million output
const PRICE_IN = 0.15 / 1_000_000
const PRICE_OUT = 0.6 / 1_000_000
 
function estimate({ dau, turnsPerUser, promptTokens, completionTokens, peakFactor, avgLatencySec }) {
  const runsPerDay = dau * turnsPerUser
  const peakQps = (runsPerDay / 86400) * peakFactor
  // Little's law: requests in flight = arrival rate times average residence time
  const concurrency = Math.ceil(peakQps * avgLatencySec)
  const costPerRun = promptTokens * PRICE_IN + completionTokens * PRICE_OUT
  return {
    runsPerDay,
    peakQps: peakQps.toFixed(2),
    concurrency,
    workers: Math.ceil(concurrency / 4), // one worker runs 4 executions at a time
    costPerDay: (costPerRun * runsPerDay).toFixed(2),
    costPerMonth: (costPerRun * runsPerDay * 30).toFixed(2),
  }
}
 
console.log(
  estimate({
    dau: 10000,
    turnsPerUser: 5,
    promptTokens: 2000,
    completionTokens: 500,
    peakFactor: 3,
    avgLatencySec: 6,
  }),
)
// runsPerDay 50000, peakQps 1.74, concurrency 11, workers 3,
// costPerDay 30.00, costPerMonth 900.00

Spoken, it goes like this: one turn is 2,000 input plus 500 output, so input is 2000 over a million times 0.15 which is 0.0003 dollars and output is 500 over a million times 0.60 which is also 0.0003, so one turn is about 0.0006 dollars; 10,000 daily actives at 5 turns each is 50,000 turns, so about 30 dollars a day and about 900 a month, which is model spend excluding machines. On concurrency, at a peak factor of 3 and 6 seconds per turn, the peak has about 11 executions in flight, so 4 concurrent per worker means 3 replicas — exactly the number you actually ran on D14.

The sketch's 8 minutes draw four blocks with a sentence each: the intake layer does auth, rate limiting, persistence, and delivery, and returns 202 immediately (D8); the execution layer takes work off the bus, runs the agent loop, and returns fragments with sequence numbers (D9, D11); storage is the sessions, runs, and messages tables, with idempotency on the runs unique constraint rather than check-then-insert (D8); observability is tracing plus the cost ledger (D13, D21).

Depth's 15 minutes go wherever the interviewer picks. Picked on state and ordering, you say "a consumer group's unit of assignment is one message and the business's serial unit is one user, so userId hashes onto 256 shards and each shard is held by one worker at a time via a lease" (D10), adding "seq starts at 0, contiguous and skipping nothing, so resumption can continue from the last received plus one" (D11). What getting it wrong looks like: casually saying "Kafka would be more professional" without being able to state the retention and second-consumer criteria pins you there on the next follow-up.

Trade-offs' 5 minutes say three things: global ordering across users was given up (ordering and parallelism are inversely related); a 300-millisecond-per-turn scenario should not be split, and splitting is asking for trouble; and at six-figure daily actives the first wall is not CPU but database connections.

Template two: a customer-support agent, whose line is "three exits"

The line in one sentence: any conversation ends at exactly one of three exits — self-served, escalated to a human, or a ticket filed. What an interviewer wants to hear is never "I wired in a knowledge base" but how you guarantee not trapping a user inside a bot. Take that sentence as the skeleton and both the knowledge base and multi-turn conversation are only parts hung off the exits.

The escalation criteria must be quantified, and any one of four hits escalates, said just like this: two consecutive unresolved turns, an explicit user request (matching phrases like asking for a person), an amount above a threshold (reusing the tools tier's automatic-execution cap of 50), and an emotional-language match. Saying only "escalate when we detect dissatisfaction" is empty and the interviewer will immediately ask how dissatisfaction is judged.

The knowledge base needs one back-reference: hybrid search plus reranking, with citation numbers in the answer (D24). What genuinely needs explaining is what happens when it cannot answer — if the retrieved citations are empty, the correct behavior takes exit two or three rather than letting the model improvise an answer. That sentence is this topic's likeliest place to be pressed: volunteering "I treat empty citations as an explicit branch" is worth more than any amount of detail about the retrieval flow.

Multi-turn conversation likewise needs one back-reference: compression triggers past seven tenths of the budget with the cut aligned to a round's start (D6), and a user correcting themselves mid-reply is merged into the same execution within 30 seconds rather than opening two concurrently (D11).

The interviewer will certainly interject here: "when you escalate, how does the context reach the human?" The answer is not "send them the transcript" — 40 turns of raw text takes an agent two minutes to read before they dare speak. The correct shape is a structured summary: one sentence of what the user wants, a few verified facts (order number, amount, shipping status), what the agent already did, and why it failed, plus a link to the raw conversation for reference.

Exit three, filing a ticket, is the backstop when no human is available either (overnight, queue timeout). The ticket must carry this execution's trace id, or whoever picks it up tomorrow has nowhere to start (D21).

Trade-offs need one sentence, said precisely: escalation criteria should err loose. A wrong escalation costs one human conversation, and trapping a user in a bot costs a churned customer plus a bad review — those two costs are not the same order of magnitude, so the threshold leans towards escalating easily.

Template three: multi-tenancy, whose line is "three layers of isolation"

The line in one sentence: data, resources, and billing isolated in three layers, and missing any one maps to a class of incident. Answer in that order and do not mix the three.

Data isolation: add a tenant_id column to every business table and enable the database's row-level security. The upgrade path has three tiers — a shared table with tenant_id (the vast majority), schema-level isolation (a few large customers with custom fields), and database-level isolation (compliance requiring physical separation). The criterion is not tenant count, it is whether a single tenant can drag the others down and whether there is a hard compliance requirement.

What getting it wrong looks like: answering only "every query carries tenant_id" invites "and if one place misses it." The correct answer hands the final ruling to the database: row-level security is the gate and the application's where clause is only an optimization. That is the second appearance of D8's "the final arbiter of idempotency must be the database's unique constraint" — whatever can be enforced at the data layer must not depend on everybody remembering while writing code.

Resource isolation: one rate-limit bucket per tenant, with workers sharded by hashing tenantId. That is D10's sharding plus leases with the hash's input changed from userId to tenantIdthe purpose shifts from preserving one user's ordering to stopping one tenant's surge exhausting everybody else's throughput, with the mechanism unchanged. The noisy-neighbor problem is especially acute in agent settings, because one execution may run thirty seconds and one tenant dumping in a thousand items leaves everybody else queued behind.

Billing isolation: add a tenant_id column to D13's cost ledger and tag it on every token-usage write. Bills, quotas, and over-budget degradation all rest on that column.

Mention the idempotency key specifically here, because multi-tenancy quietly breaks it. D8's persistence, D13's scheduling, D19's cross-service calls, and D25's frontend retry all use the same move; in multi-tenancy the key itself need not change, and its scope must include the tenantId. Without it, two tenants' clients each generate the same string (both using order number order-1024, say) and the later one is blocked by the unique constraint as a duplicate — one tenant's write swallowed by another tenant's historical request, which is multi-tenancy's hardest bug to find, because both sides' logs look entirely normal.

Trade-offs, two sentences: row-level security adds a policy evaluation per query and has a performance cost; database-level isolation looks cleanest and multiplies migration scripts, backups, monitoring, and connection pools by the tenant count, so operational cost grows steeply rather than linearly.

Template four: cost control, five layers from cheap to expensive

The line in one sentence: five layers ordered by the cost to you, smallest first — the first three change your own code, the fourth changes behavioural boundaries, and the fifth touches product commitments. Asked what to do when cost runs away, answering in that order incidentally tells the interviewer your implementation order.

Put the baseline on the table first: 0.0006 dollars a turn, 10,000 daily actives at 5 turns each, 30 dollars a day, 900 a month. A cost discussion with no baseline is all waste — you cannot state how much any layer saves.

Layer one, caching and prompt cache. A high-frequency question hitting cache costs nothing that turn; the fixed prefix of the system prompt plus tool definitions (10 tools is about 1,000 to 1,500 tokens, D6's figure) is billed against cache on repeat requests. Estimating a fifteen-percent hit rate, 900 dollars becomes about 765. The only cost is cache-invalidation consistency.

Layer two, tiered model routing. Simple intents (classification, routing, chat) take a small model and only complex reasoning takes a strong one (D4). This layer requires honesty about one premise: it is the only one of the five that can change an order of magnitude, provided your baseline uses a flagship model. This course's 900-dollar baseline already uses the cheapest tier, so there is little left to squeeze — volunteering that sentence is far more persuasive than inventing a savings percentage.

Layer three, context compression. Of that turn's 2,000 input tokens, over half is the system prompt plus the tool list, and it gets worse as history grows. The approach summarizes past seven tenths of the budget (D6) and switches low-frequency tools to per-scenario loading. Input compressed from 2,000 to 1,200 makes a turn 1200 over a million times 0.15 plus 500 over a million times 0.60, which is 0.00048 dollars, so 24 dollars a day and 720 a month, a twenty-percent reduction. The cost is one extra model call for the compression, and irreversible information loss.

Layer four, step and tool-budget ceilings. At most 5 tool calls per subtask and at most 2 bounces (D17). What this layer buys is not savings, it is predictability. Maxing out 5 tool calls with 800 tokens of result each pushes input to 6,000 and a turn to 0.0012 dollars — exactly twice the baseline, and without a ceiling that number has no upper bound. The cost is degrading to existing results on exhaustion rather than throwing.

Layer five, rate limiting and degradation. A daily budget per user or tenant, downgrading past it and refusing only past that (D13). Nine hundred dollars across 10,000 daily actives is 0.09 dollars per person per month, so a hard ceiling of 1 dollar per user is never reached by a normal user and stops the extreme case of somebody scripting the endpoint. It is the only layer users can feel, so its cost is highest — hence last.

Source Reading

Hands-On Lab

🧪 D26 lab: 3 answer templates

Code location: labs/agent-30days/day-26-system-design-templates

Acceptance criteria:

  1. After reading solution/'s four templates once, deliver agent-platform.md aloud and record it, finishing within 15 minutes with no notes throughout.
  2. Replay the recording and check the five time boxes one by one: clarification no less than 3 minutes, the estimate stating both 0.0006 and 900 with the arithmetic, and all four sketch blocks present.
  3. Delivering customer-support-agent.md, state the three exits and the four quantified escalation criteria within 60 seconds without notes.
  4. Every TODO block in starter/'s four templates is replaced with your own project's content, with zero hits for TODO in a full-text search.
  5. Have somebody (or self-assess by recording) pick any one of the three deep-dive packs at random and deliver it for a full 5 minutes without notes.

Today's output is documents rather than a program, so this lab has no pnpm install, no MOCK=1, and no self-check script. solution/ is a worked example filled in with this course's three repositories (agent-service, mini-koda, mini-multi-agent) — it is a reference, not an answer, and you must adapt it to your own project's details or the first follow-up gives you away. A phone recording is enough; what matters is timing yourself on replay.

  1. Open starter/agent-platform.md and fill the five-step skeleton section by section in your own words, writing the arithmetic and not just the result in the estimate step.
  2. Fill in starter/customer-support-agent.md, with all three exits and all four quantified criteria present, especially the empty-citations branch.
  3. Fill in starter/multi-tenant.md with three to five points per isolation layer, noting why the idempotency key's scope must include the tenant identifier.
  4. Fill in starter/cost-control.md with a number derived from the baseline for each of the five layers, stating each one's cost.
  5. Record yourself delivering agent-platform.md, timed at 15 minutes, then replay against acceptance criterion 2 item by item and practice the section that stumbled three more times.

Interview Questions

Today's four questions are in the bank below: one on the answering process itself, one a complete system-design question (a customer-support agent), and two on multi-tenancy and cost control. Expand a question and read the analysis before the key points — question 2's analysis is not a list of points, it is a 35-minute speaking skeleton, so do not skim it as an ordinary question. Each is tagged for the China-domestic or overseas market so you can prioritize by where you are applying.

Checklist and Tomorrow

  • Give a system-design answer template for an agent platform (architecture, scalability, cost)
  • Give a system-design answer template for a customer-support agent (multi-turn conversation, escalation to a human, knowledge base)
  • Give a checklist of design points for both the multi-tenancy and cost-control topics
  • Recite the five time boxes, and say where the interviewer interjects at each step
  • Compute, without notes, 0.0006 dollars a turn and 900 dollars a month, and state the arithmetic
  • Deliver any one of the three deep-dive packs for a full 5 minutes
  • All 5 acceptance criteria of the lab pass, with agent-platform.md recorded and timed once
  • Answer at least 3 of the 4 interview questions without looking at the key points

Tomorrow (D27) moves one step earlier: a system-design question tests whether you can design, and before an interviewer will spend 40 minutes on it they have to believe from your resume that this person really built something. So tomorrow packages the three repositories agent-service, mini-koda, and mini-multi-agent into resume highlights: the STAR one-sentence formula, a seven-section README, Mermaid architecture diagrams, a demo video, and an English resume. The order is deliberate: know today what an interviewer wants to hear, and tomorrow you know which numbers to put on the page.

Interview questions

  • You get 35 to 40 minutes for a system design round. How do you budget that time, and why is drawing the architecture not step one?系统设计环节只有 35 到 40 分钟,你会怎么分配时间?为什么第一步不是画架构图?
    Common in ChinaCommon overseasBasic#system-design#interview-process

    How to reason about it · think before answering

    1. This question tests pacing, not knowledge. Interviewers ask it because the previous candidate spent 25 minutes on the architecture diagram and left five each for deep dives and trade-offs — which is exactly where the rubric puts most of the weight.
    2. Give the structure with explicit time boxes: 5 minutes clarifying requirements, 3 minutes on capacity and cost estimation, 8 minutes sketching the architecture, 15 minutes going deep on two or three areas, 5 minutes on trade-offs. Naming actual minute counts is itself worth points, because it shows you have rehearsed against a clock.
    3. Then answer the 'why not draw first' half head on: a one-line prompt leaves five things unknown — daily actives, latency budget, cost budget, multi-tenancy, and failure tolerance — and every one of them changes the architecture materially. Drawing first means at best you guessed right, at worst the interviewer realizes twenty minutes in that you solved a different problem. An analogy lands it: the client said 'we need an office building' and you unrolled construction drawings before hearing whether the budget is twenty million or two hundred million.
    4. Add the situation that comes up almost every time: you start asking and the interviewer says 'just assume something'. That is not permission to skip clarification, it is an invitation to state a number and its justification. The right reply is 'then I will assume 10k daily actives at five turns each, and I will flag in the final step what changes at 100k'. You keep the pacing and turn the assumption into a traceable premise.
    5. Close by explaining how step four is prepared: those 15 minutes cannot be improvised. Have three deep-dive packages ready — state and ordering, cost and rate limiting, failure and retry — so any pick is covered. Saying you prepared three directions signals rehearsal better than winging one.
    6. Expect the follow-up: what if you run out of time? Cut step three, never step five. An unfinished sketch can be closed with 'the rest follows the standard pattern, happy to come back to it', but dropping the trade-off section makes you indistinguishable from someone who memorized an architecture.

    分析过程 · 先想清楚再作答

    1. 这题考的不是知识,是节奏感。面试官问它,通常是因为上一位候选人在架构图上讲了 25 分钟,深入和权衡各剩五分钟——而评分表上分数最重的恰恰是后两步。
    2. 先给结构,五步加时间盒:需求澄清 5 分钟、容量与成本估算 3 分钟、架构草图 8 分钟、深入 2 到 3 个点 15 分钟、权衡与取舍 5 分钟。给得出具体分钟数本身就是分数,因为它说明你掐过表。
    3. 然后正面回答「为什么不先画图」:一句话的题干里,日活、延迟预算、成本预算、是否多租户、失败可容忍度这五件事全是未知的,而它们每一个都会实质改变架构。不问就画,最好的结果是运气好蒙对,最坏的结果是二十分钟后面试官发现你解的是另一道题。用一个类比说清:甲方只说「我要一栋办公楼」,你就展开施工图,而他连预算是两千万还是两个亿都没讲。
    4. 补一条几乎每次都会遇到的现场情况:你开始问,面试官说「你先自己假设一个」。这不是让你别问了,是让你自己给一个数并说出依据。正确接法是「那我按日活 1 万、人均 5 轮算,如果实际是十万级我会在最后一步说明哪里要改」——既守住了节奏,又把假设变成了可追溯的前提。
    5. 最后主动交代第四步的准备方式:深入的 15 分钟不能临场想,要提前备好三个「深入包」(状态与保序、成本与限流、失败与重试),面试官挑哪个都有货。说得出「我提前准备了三个方向」,比现场硬讲一个更能体现你练过。
    6. 可以预期的追问:如果时间不够怎么办?答案是砍第三步而不是砍第五步——草图讲不完可以说「其余按常规做,需要的话我们回头补」,但权衡那 5 分钟一旦砍掉,你就和一个只会背架构的人没有区别。

    Key points

    • Five steps with time boxes: clarify 5, estimate 3, sketch 8, deep dive 15, trade-offs 5
    • Do not sketch first because DAU, latency budget, cost budget, multi-tenancy and failure tolerance all change the architecture
    • When told to 'just assume something', state a number with its justification instead of skipping clarification
    • Fill the 15-minute deep dive from three pre-prepared packages: state and ordering, cost and rate limiting, failure and retry
    • If time runs short, cut the sketch, never the trade-offs — almost nobody does that section, so doing it stands out

    答题要点

    • 五步加时间盒:澄清 5 分钟、估算 3 分钟、草图 8 分钟、深入 15 分钟、权衡 5 分钟
    • 不先画图,是因为日活、延迟预算、成本预算、是否多租户、失败可容忍度这五件事都会实质改变架构
    • 面试官说「你先假设一个」时,要自己给数并说出依据,而不是跳过澄清
    • 深入的 15 分钟要靠提前备好的三个「深入包」:状态与保序、成本与限流、失败与重试
    • 时间不够时砍草图不砍权衡——权衡那 5 分钟几乎没人做,做了就是加分
  • System design: design an e-commerce customer support agent. It looks up orders and shipments, drafts refunds by policy, answers product and policy questions, and escalates to a human when it cannot resolve the issue.系统设计:请设计一个电商客服 Agent。它要能查订单和物流、按规则拟退款方案、回答商品与政策问题,并在搞不定时转人工。
    Common in ChinaCommon overseasDeep dive#system-design#customer-support#escalation

    How to reason about it · think before answering

    1. Start by separating this from 'design an agent platform', or you will answer an infrastructure question. The platform question is about running execution reliably; this one is about not trapping users inside a bot. The rubric lives in the business exits, not the message bus. So pin the thesis in your first sentence: every conversation must end in exactly one of three exits — self-served, handed to a human, or filed as a ticket.
    2. Clarify for 5 minutes, asking four things: daily actives and concurrent sessions (does execution need to be split out), whether human agents work nights (does exit three exist), whether the agent executes refunds or only drafts them (do you need an approval tier), and how large the knowledge base is and how often it changes (is retrieval the center of this problem). The third question matters most: it decides whether this system has irreversible side effects.
    3. Estimate for 3 minutes, out loud: 2000 input plus 500 output per turn, input is 2000 over a million times $0.15 which is $0.0003, output is 500 over a million times $0.60 which is also $0.0003, so about $0.0006 per turn. 10k daily actives at five turns is 50k turns, roughly $30 a day and $900 a month in model spend, machines excluded. For concurrency, a peak factor of 3 and 6 seconds per turn gives about 11 in-flight executions at peak, which is 3 worker replicas at 4 concurrent each. State the arithmetic before the result — the interviewer's next line is always 'where did that number come from'.
    4. Sketch for 8 minutes, four blocks: ingress does auth, rate limiting, persistence and publish, then returns immediately; execution pulls from the bus, runs the agent loop, and streams sequenced fragments back; storage is sessions, runs and messages plus a chunk table for the knowledge base; observability is tracing plus a cost ledger. Then mark on the diagram which node decides between the three exits — that single annotation tells the interviewer you are answering the support question rather than the generic platform one.
    5. Go deep for 15 minutes, starting with escalation because that is the crux. The criteria must be quantified, any one of four triggering a handoff: two consecutive unresolved turns, an explicit user request, an amount above the auto-execution ceiling (50 CNY in our setup), or a sentiment keyword hit. Then describe the handoff payload: not forty turns of raw transcript, but a structured summary — the user's ask in one line, verified facts, actions already taken, and the failure reason, with a link to the full transcript. Cover the knowledge base in one line (hybrid search, rerank, inline citations) and spend the weight on 'when the citation set comes back empty, take exit two or three rather than letting the model invent an answer' — that is the sentence they will push on. Cover multi-turn in one line too: compress once history passes 70% of budget, cut on a turn boundary, and merge a change of mind within 30 seconds into the same execution.
    6. Trade-offs for 5 minutes, three points: bias the escalation threshold toward escalating, because a false handoff costs one human conversation while trapping a user costs a churned customer and a bad review — different orders of magnitude. Drafting refunds instead of executing them trades one human approval for an entire class of irreversible incidents. And name what breaks the design: once the agent team is large enough to need skill-based routing and queueing, escalation stops being a boolean and becomes its own scheduling system.
    7. Expect, in rough order: does 'I want to file a complaint' count as a sentiment hit (yes, and track that class separately — it is a product signal); should the agent keep listening after handoff (yes, to summarize and prompt the human, but not to speak); how do you stop users being bounced repeatedly (allow one handoff per conversation, then file a ticket); and what happens to old answers when the knowledge base changes (cite chunk ids and versions so you can trace which revision was wrong).

    分析过程 · 先想清楚再作答

    1. 先说这题和「设计一个 Agent 平台」的区别,否则你会把它答成一道基础设施题。平台题考的是怎么把执行跑稳,这题考的是**怎么保证不把用户困在机器人里**——面试官心里的评分点在业务出口上,不在消息总线上。所以主线要一开口就钉死:任何一通会话最后只能落到三条出口之一,自助解决、转人工、留工单。
    2. 第一步澄清 5 分钟,问四件事:日活与并发会话数(决定要不要拆执行层)、人工坐席有没有夜班(决定出口三存不存在)、退款是 Agent 直接执行还是只拟方案(决定要不要人工确认档)、知识库有多大且多久更新一次(决定检索是不是本题的重点)。第三个问题尤其关键,它直接决定这道题是不是带副作用。
    3. 第二步估算 3 分钟,现场算:单轮 2000 输入加 500 输出,输入 2000 除以一百万乘 0.15 等于 0.0003 美元,输出 500 除以一百万乘 0.60 也等于 0.0003 美元,一轮约 0.0006 美元;日活 1 万、人均 5 轮就是 5 万轮,一天约 30 美元、一个月约 900 美元,模型费不含机器。并发按峰谷比 3、单轮 6 秒算,峰值在途约 11 次执行,每个 worker 并发 4 就是 3 个副本。报数字之前先报算式,面试官插的那句一定是「这个数怎么来的」。
    4. 第三步草图 8 分钟,四块:接入层只做鉴权、限流、落库、投递并立刻返回;执行层从消息总线取活跑 Agent 循环、片段带序号回传;存储是会话、执行、消息三张表加一张知识库切块表;可观测是 tracing 加成本台账。在这张图上额外标出三条出口的分叉点在哪一个节点上——这是本题独有的一笔,画上去面试官立刻知道你答的是客服而不是通用平台。
    5. 第四步深入 15 分钟,优先讲转人工这一支,因为它是本题的题眼。判据必须量化,四条任一命中就转:连续 2 轮未解决、用户明确要求、涉及金额超过自动执行上限(本课口径 50 元)、情绪词命中。接着讲交接形状——不是把 40 轮原文丢给客服,而是一段结构化摘要:用户诉求一句、已核实事实几条、Agent 已做过的动作、失败原因,附原始对话链接。知识库那一支一句话带过混合检索加重排加引用,重点落在「引用为空时走出口二或三,而不是让模型编一个答案」,这是最容易被追的一句。多轮那一支同样一句话:历史超七成预算触发压缩且切口对齐到一轮开头,用户中途改口则 30 秒内合并进同一次执行。
    6. 第五步权衡 5 分钟,说三件事:转人工的判据宁可偏松,因为误转的代价是一次人工会话,把用户困住的代价是一个流失客户加一条差评,两者不在一个量级;退款只拟方案不直接执行,是拿一次人工点头换掉一整类不可逆事故;以及什么规模会推翻这个设计——坐席团队大到需要技能路由和排队策略时,转人工就不再是一个布尔判断,而是另一套调度系统。
    7. 可以预期的追问,按频率排:用户说「我要投诉」算不算情绪词命中(算,且这一类要单独统计,它是产品问题的信号);转人工之后 Agent 还要不要继续在旁边听(要,用来生成小结和给坐席提示,但不允许再发言);怎么防止用户被反复转来转去(同一通会话只允许转一次,第二次直接留工单);以及知识库更新后旧答案怎么办(回答里带引用编号和版本,出问题能倒查是哪一版说错的)。

    Key points

    • Thesis: every conversation ends in exactly one of three exits — self-served, escalated to a human, or filed as a ticket
    • Clarify four things: concurrent sessions, whether humans cover nights, whether refunds are executed or only drafted, and knowledge base size and churn
    • Estimate with arithmetic: about $0.0006 per turn, so 10k DAU at five turns is roughly $30/day and $900/month; peak concurrency about 11, meaning 3 worker replicas
    • Quantify escalation: two consecutive unresolved turns, an explicit request, an amount over the auto-execution ceiling, or a sentiment keyword
    • Hand over a structured summary — ask, verified facts, actions taken, failure reason — plus a transcript link, not forty raw turns
    • When retrieval returns no citations, take exit two or three instead of letting the model improvise; answers carry citation ids
    • Reuse compression and 30-second merge for multi-turn; draft refunds rather than executing them, trading one approval for a class of irreversible incidents
    • Trade-off: bias toward escalating, because a false handoff and a trapped user cost different orders of magnitude

    答题要点

    • 主线一句话:任何一通会话只能落到三条出口之一——自助解决、转人工、留工单
    • 澄清必问四件事:并发会话数、人工有没有夜班、退款是执行还是只拟方案、知识库规模与更新频率
    • 估算带算式:单轮约 0.0006 美元,日活 1 万人均 5 轮约 30 美元一天、900 美元一月;峰值并发约 11、3 个 worker 副本
    • 转人工判据必须量化,四条任一命中:连续 2 轮未解决、用户明确要求、金额超自动执行上限、情绪词命中
    • 交接给人工的是结构化摘要(诉求、已核实事实、已做动作、失败原因)加原始对话链接,不是 40 轮原文
    • 知识库检索不到时走出口二或三,绝不让模型自由发挥编答案;回答带引用编号
    • 多轮沿用压缩与 30 秒打断合并,退款只拟方案不直接执行,用一次人工点头换掉一类不可逆事故
    • 权衡:判据宁可偏松,因为误转和困住用户的代价不在一个量级
  • For a multi-tenant agent service, how do you design data isolation and billing isolation, and when do you move from a shared table to a dedicated database per tenant?一个多租户的 Agent 服务,数据隔离和计费隔离要怎么设计?什么时候该从共享表升级到独立库?
    Common in ChinaCommon overseasIntermediate#system-design#multi-tenancy#isolation

    How to reason about it · think before answering

    1. The hinge is that 'isolation' is plural. Plenty of candidates answer only data isolation, but the layer that actually breaks in production is resources: one tenant's spike starves everyone else, no rows leak, and users still complain. Open with all three — data, resources, billing — and note that each missing layer maps to its own class of incident.
    2. On data, one sentence separates people who shipped this from people who read about it: 'every query carries tenant_id' versus 'row-level security is the backstop'. The first eventually misses a query, and the one it misses is always the newest, least-tested feature. The correct framing is that RLS is the gate and the application-level where clause is just an optimization — the same reasoning as idempotency being adjudicated by a database unique constraint. Whatever the data layer can enforce should not depend on everyone remembering.
    3. On resources, give two concrete things: a rate-limit bucket per tenant, and workers sharded by a hash of the tenant id. That is the same sharding mechanism used to preserve per-user ordering, with a different hash input and a different purpose — containing spikes rather than serializing. Noisy neighbors hurt more in agent workloads because a single execution can run thirty seconds, so a thousand queued items from one tenant leaves everyone else waiting.
    4. Billing is the simplest and the most often forgotten: add a tenant column to the token usage ledger and tag every write. Invoicing, quotas and over-budget degradation all hang off it. Bring the cost figures too — roughly $0.0006 per turn at 2000 in and 500 out, about $900 a month at 10k daily actives and five turns each — because quoting per-tenant economics shows you actually ran the numbers.
    5. Then the escalation criteria, the second discriminator. Three tiers: shared table with a tenant column, schema per tenant, database per tenant. The trigger is not tenant count, it is whether a single tenant can starve the rest and whether there is a hard compliance requirement. 'Split the database past a hundred tenants' is guesswork: a hundred small tenants share a table happily, while one regulated enterprise customer may require physical separation on its own. State the cost too — a database per tenant looks clean, but migrations, backups, monitoring and connection pools all multiply by tenant count, so operational cost jumps rather than scaling linearly.
    6. Expect the sharpest follow-up: does the idempotency key change under multi-tenancy? The algorithm does not, but its scope must include the tenant id. Without it, two tenants whose clients independently produce the same string — both using order id order-1024 — collide, and the later request is rejected by the unique constraint as a duplicate. One tenant's write is swallowed by another tenant's history, both logs look perfectly normal, and it is the hardest class of multi-tenant bug to find.

    分析过程 · 先想清楚再作答

    1. 这题的题眼在「隔离」是复数。只答数据隔离的候选人非常多,而多租户翻车最多的其实是资源那一层——一个租户的洪峰打穿别人的处理能力,数据一条都没串,用户照样投诉。所以第一句先把三层摆出来:数据、资源、计费,缺哪一层对应一类事故。
    2. 数据这一层,判断一个人有没有真做过就看一句话:他说「每条查询都带 tenant_id」还是「靠数据库的行级安全兜底」。前者迟早会漏一处,而漏掉的那处通常是最新加、最没被测过的功能。正确说法是行级安全是闸门,应用层那句 where 只是优化——这和幂等的最终裁判必须是数据库唯一约束,是同一种思路:能在数据层强制的,不要指望每个人写代码时都记得。
    3. 资源这一层给两件具体的东西:每个租户一个独立限流桶,以及 worker 按租户标识哈希分片。分片这一招和「按用户哈希保住同一用户顺序」是同一套机制,只是哈希的输入换了,目的从保序变成隔离洪峰。Agent 场景里噪声邻居格外突出,因为单次执行可能跑三十秒,一个租户灌一千条进来,别人就得排队。
    4. 计费这一层最简单也最容易漏:token 用量台账加一列租户标识,写入时打标。账单、配额、超支降级三件事全靠它。顺带说一句成本口径——单轮 2000 输入加 500 输出约 0.0006 美元,日活 1 万人均 5 轮约每月 900 美元,能报出这个量级说明你真的算过每租户成本。
    5. 然后回答升级判据,这是本题的第二个区分点。三档是共享表加租户列、schema 级、库级;**判据不是租户数量,是「有没有单个租户能把别人拖垮」和「有没有合规硬要求」**。答「超过一百个租户就该分库」是典型的凭感觉,因为一百个小租户共享一张表毫无问题,而一个受监管的大客户哪怕只有一个也可能必须物理隔离。代价要一起说:库级隔离看着干净,但迁移脚本、备份、监控、连接池全部乘以租户数,运维成本是陡增不是线性。
    6. 可以预期的追问,也是最见功力的一问:幂等键在多租户下要不要变?答案是键的算法不用变,但**作用域必须带上租户标识**。不带的话两个租户的客户端各自生成了同一个字符串(都用订单号 order-1024),后来那个会被唯一约束当成重复请求挡掉——一个租户的写入被另一个租户的历史请求吞掉,两边日志都完全正常,是多租户里最难查的一类 bug。

    Key points

    • Three parallel layers, each missing one causing its own class of incident: data, resources, billing
    • Data isolation is backstopped by row-level security; the application where clause is only an optimization
    • Resource isolation is a per-tenant rate-limit bucket plus sharding workers by tenant hash, aimed at noisy neighbors
    • Billing isolation is a tenant column on the usage ledger, powering invoices, quotas and degradation
    • Escalate to schema or database isolation based on starvation risk and compliance mandates, not tenant count
    • Per-tenant databases multiply migrations, backups, monitoring and connection pools — operational cost jumps
    • The idempotency key algorithm stays, but its scope must include the tenant id or identical keys across tenants collide

    答题要点

    • 三层隔离并列,缺一层对应一类事故:数据、资源、计费
    • 数据靠行级安全兜底,应用层的 where 只是优化——能在数据层强制的不要靠人记得
    • 资源是每租户独立限流桶加按租户标识哈希分片,防的是噪声邻居而不是数据串
    • 计费是台账加一列租户标识,账单、配额、超支降级全靠它
    • 升级到 schema 级或库级的判据是「单租户能否拖垮别人」与「有没有合规硬要求」,不是租户数量
    • 库级隔离的代价是迁移、备份、监控、连接池全部乘以租户数,运维成本陡增
    • 幂等键算法不变,但作用域必须带租户标识,否则两个租户的同名键会互相挡掉请求
  • An agent system's model spend is out of control. Which levers do you pull, in what order, and roughly how much does each save?一个 Agent 系统的模型成本失控了,你会从哪几个层面着手控制?每一层大概能省多少?
    Common in ChinaCommon overseasIntermediate#system-design#cost#capacity-planning

    How to reason about it · think before answering

    1. The reflex answer is 'switch to a cheaper model', and it is also the easiest one to get killed on: the follow-up is 'how do you know quality did not drop', and without an offline eval set and a comparison run you are exposed. The right opening is 'look at the ledger first' — slice by user, by day and by model to find which dimension is growing. Locate before you act.
    2. Second, put the baseline on the table, because cost talk without a baseline is noise. At 2000 input and 500 output tokens per turn, input is 2000 over a million times $0.15 which is $0.0003, output is 500 over a million times $0.60 which is also $0.0003, so about $0.0006 per turn. 10k daily actives at five turns is 50k turns, roughly $30 a day and $900 a month.
    3. Then give five layers ordered by the cost you pay, not by the savings: caching and prompt caching, tiered model routing, context compression, step and tool budget caps, rate limiting and degradation. The ordering is part of the answer, because it also communicates your rollout sequence.
    4. Attach a number derived from the baseline to each layer. Caching at a 15% hit rate takes $900 to roughly $765. For tiered routing, state the precondition honestly: it is the only layer that can change the order of magnitude, but only if your baseline runs a flagship model — if you already run the cheapest tier there is nothing left to squeeze. Saying that out loud is far more credible than inventing a savings percentage. Compression takes input from 2000 to 1200 tokens, so $0.00048 per turn, about $720 a month, a 20% cut.
    5. Layer four is usually mis-sold as savings; what it actually buys is predictability. With a cap of five tool calls per subtask, per-turn cost finally has a ceiling: five calls each feeding back 800 tokens pushes input to 6000, so $0.0012 per turn, exactly double the baseline — and with no cap there is no ceiling at all. The right phrasing is 'this does not save money, it makes the bill predictable'.
    6. Layer five is rate limiting and degradation, last because it costs the most: $900 across 10k daily actives is about $0.09 per user per month, so a $1 monthly hard cap is invisible to real users and only stops scripted abuse. The nuance is degrade before refusing — this is the only layer users can feel.
    7. Expect the follow-up: which layer first? Say layers one and three, because they only touch your own code, change no product promise, and need no quality re-validation, whereas tiered routing needs an eval set and rate limiting needs product buy-in.

    分析过程 · 先想清楚再作答

    1. 这题最容易脱口而出的答案是「换个便宜模型」,也是最容易被追死的答案——面试官紧跟着就问「你怎么知道换了质量不掉」,答不出离线评估集和对比实验就露馅了。正确的第一句是「先看台账」:按用户、按天、按模型各切一刀,找出是哪一维在涨。先定位再动手,这是工程习惯。
    2. 第二步是把基准摆到桌上,没有基准的成本讨论全是废话。单轮 2000 输入加 500 输出,输入 2000 除以一百万乘 0.15 等于 0.0003 美元,输出 500 除以一百万乘 0.60 也等于 0.0003 美元,一轮约 0.0006 美元;日活 1 万、人均 5 轮就是 5 万轮,一天约 30 美元、一个月约 900 美元。
    3. 然后给五层,排序的依据是**你要付出的代价从小到大**,不是省钱多少:缓存与 prompt cache、模型分级路由、上下文压缩、步数与工具预算上限、限流与降级。这个顺序本身就是答案的一部分,因为它同时说明了你的落地顺序。
    4. 每层配一个从基准推出来的数字。缓存按一成半命中估,900 降到 765 左右。分级路由要诚实说清前提:它是唯一能改数量级的一层,但前提是你的基准用的是旗舰模型;基准已经是最便宜那档时这一层榨不出东西——主动说破这一条,比硬编一个省钱比例可信得多。上下文压缩把输入从 2000 压到 1200,单轮变成 0.00048 美元,一个月 720 美元,降两成。
    5. 第四层最容易被讲成「省钱」,其实它买的是**可预测**:给每个子任务设 5 次工具调用上限之后,单轮成本才有上界——调满 5 次、每次结果回灌 800 token,输入涨到 6000,单轮 0.0012 美元,正好是基准的两倍;没有上限时这个数字没有上界。这一层的正确说法是「我不是靠它省钱,我是靠它让账单可以被预测」。
    6. 第五层是限流与降级,代价最大所以放最后:900 美元摊到 1 万日活是每人每月 0.09 美元,给单用户设 1 美元硬顶,正常用户碰不到,挡的是脚本刷接口那种极端户。要点是超预算先降档再拒绝,而不是直接拒绝——它是五层里唯一用户能感觉到的一层。
    7. 可以预期的追问:这五层里哪一层最先做?答「第一层和第三层」,因为它们只改自己的代码、不动产品承诺、也不需要重新验证质量;而分级路由要配离线评估集,限流要配产品沟通,都不是当天能上的。

    Key points

    • Open with 'look at the ledger', not 'use a cheaper model': slice by user, by day and by model to locate the growth
    • Set a baseline: about $0.0006 per turn, roughly $30/day and $900/month at 10k DAU and five turns
    • Five layers ordered by cost to you: caching and prompt cache, tiered routing, context compression, step and tool budget caps, rate limiting and degradation
    • Tiered routing is the only order-of-magnitude lever, but only if the baseline is a flagship model — say so when it is not
    • Compression from 2000 to 1200 input tokens gives $0.00048 per turn, about $720/month, a 20% cut
    • Tool budget caps buy predictability: with a cap the per-turn ceiling is $0.0012, without one there is no ceiling
    • Rate limiting comes last because users feel it; degrade before refusing

    答题要点

    • 第一句不是「换便宜模型」,是「先看台账」:按用户、按天、按模型各切一刀定位是哪一维在涨
    • 先立基准:单轮约 0.0006 美元,日活 1 万人均 5 轮约每天 30 美元、每月 900 美元
    • 五层按代价从小到大:缓存与 prompt cache、模型分级路由、上下文压缩、步数与工具预算上限、限流与降级
    • 分级路由是唯一能改数量级的一层,但前提是基准用的是旗舰模型;基准已经最便宜时要诚实说没得省
    • 上下文压缩把输入从 2000 压到 1200,单轮 0.00048 美元、每月 720 美元,降两成
    • 工具预算上限买的是可预测:有上限时单轮上界是 0.0012 美元,没上限时没有上界
    • 限流降级放最后,因为它是唯一用户能感觉到的一层;超预算先降档再拒绝

Comments