15 系统设计题
“设计一个企业知识库问答系统""设计一个客服 Agent”,这类题在 AI 应用岗的二面、三面很常见。它没有标准答案,面试官看的是:你会不会先问清楚需求,能不能把前面学的检索、工具、状态、评测、安全、后端拼成一个能落地的系统,能不能主动说出成本、延迟和风险。
这篇要讲清楚:一个通用的答题框架(八步);怎么快速估算成本和流量;四道高频题——企业知识库问答、客服 Agent、Coding Agent、深度调研 Agent——每道题的澄清问题、架构图、关键设计、评测、风险和追问。最后把我自己的项目套进这个框架讲一遍。
怎么读:
前置:这一篇会用到前面几乎所有篇,尤其是 08 RAG、09 评测、11 安全、14 AI 应用后端。
第一部分 速记页
| 问题 | 一句话答案 |
|---|---|
| 答题框架 | 澄清需求 → 核心流程 → 架构图 → 数据与存储 → 工具与权限 → 评测 → 成本与延迟 → 风险与兜底 |
| 第一步最常犯的错 | 不问需求直接画架构;应该先问用户是谁、量多大、准确率要求、能不能出错、有哪些现有系统 |
| 先判断什么 | 这个需求要不要 Agent:流程固定用工作流,路径不固定、要多步调工具才用 Agent |
| 怎么估成本 | 每次输入 token × 未命中价 + 命中 token × 命中价 + 输出 × 输出价,乘以每天次数 |
| Agent 成本的特点 | 每步重发历史,步数翻倍成本不止翻倍;缓存命中率影响很大 |
| 知识库问答的关键 | 解析和切片质量、混合检索、按用户权限过滤、增量更新、引用出处、允许拒答 |
| 客服 Agent 的关键 | 工具对接业务系统、退款等写操作要幂等和确认、转人工、多轮状态、pass^k |
| Coding Agent 的关键 | 沙箱、用测试验证而不是模型自述、diff 给人审核、限制可改范围、专门为 Agent 设计的工具接口 |
| 深度调研 Agent 的关键 | 并行子 Agent、引用核对、预算控制、结果可追溯 |
| 评测怎么答 | 离线评测集(真实问题 + 成功标准)、分层评测(检索 / 单步 / 端到端)、线上指标 |
| 风险怎么答 | 幻觉、注入、越权、成本失控、下游故障;每条说兜底措施 |
| 被问”量涨 10 倍” | 先找瓶颈:模型限流、检索、任务队列;缓存、限流、降级、异步化、水平扩容 |
| 被问”成本降一半” | 缓存命中、小模型处理简单步骤、减少步数、截断工具结果、压缩历史 |
| 我项目属于哪类 | 接近 Coding Agent:在代码仓库里执行命令、改构建配置、用程序验收结果 |
第二部分 易混对照
| 容易混的两个 | 区别 | 一句话记法 |
|---|---|---|
| 功能需求 vs 非功能需求 | 功能需求是系统做什么;非功能需求是做得多快、多准、多便宜、多安全 | 做什么 vs 做成什么样 |
| 工作流 vs Agent | 工作流路径由代码定死;Agent 由模型决定下一步 | 能用工作流就别用 Agent |
| RAG 问答 vs 客服 Agent | 前者只读、回答问题;后者要调业务系统、可能有写操作 | 查资料 vs 办事 |
| 离线评测 vs 线上指标 | 前者发布前用固定题跑;后者看真实用户的完成率、转人工率、反馈 | 考试 vs 实战 |
| 准确率 vs 召回率(在检索里) | 前者是查出来的有多少是对的;后者是该查出来的查出来多少 | 查准 vs 查全 |
| 降级 vs 兜底 | 降级是主路径不可用时换一个差一点的方案(换小模型);兜底是最后的安全网(转人工、拒答) | 备胎 vs 安全网 |
| 权限过滤在检索层 vs 在提示词里 | 检索层过滤:没权限的文档根本不进上下文;提示词里要求模型别说:挡不住 | 锁门 vs 贴告示 |
| 人工确认 vs 人工接管 | 确认是 Agent 执行某个操作前等人点头;接管是整个对话交给人工处理 | 签字 vs 换人 |
| QPS vs 并发数 | QPS 是每秒请求数;并发数是同时在处理的请求数。Agent 请求时间长,并发数远大于 QPS | 每秒进门几个 vs 屋里有几个 |
第三部分 面试口述稿
3.1 “系统设计题你一般怎么答?”
我按八步来。
第一步先问清楚需求,不急着画图。用户是谁、每天多少量、对准确率和延迟的要求、出错的代价有多大、有哪些现有系统要对接、数据有没有权限区分。还要判断这个需求是不是真的需要 Agent,如果流程是固定的,用工作流更稳更便宜。
第二步说核心流程,一次请求从进来到返回经过哪几步。第三步画架构图,把前端、后端、模型、检索、工具、存储画出来。第四步讲数据和存储,存什么、怎么更新。第五步讲工具和权限,Agent 能调哪些工具、每个工具的权限边界、哪些操作要人确认。
后三步是很多人会漏的:评测,怎么知道系统做得好、改动之后没变差;成本和延迟,做一个粗略估算;风险和兜底,幻觉、注入、越权、下游故障分别怎么处理。
时间不够的话,前五步讲主干,后三步每步至少说两句,因为这三步最能体现做过工程。
3.2 “设计一个企业内部知识库问答系统”
我先会问几个问题:文档有多少、什么格式、多久更新一次;员工对不同文档的权限是否不同;回答需不需要给出处;能不能接受”不知道”。假设是几十万份文档、PDF 和网页为主、每天有更新、不同部门权限不同、必须给出处。
核心流程分离线和在线两条。离线:文档解析、清洗、按结构切片,每个片段带上文档标题、来源、权限标签,做向量化存进向量库,同时建关键词索引;文档变更时按文档 ID 增量更新。在线:用户提问,先按用户身份拿到可访问的权限范围,检索时带上权限过滤,向量和关键词混合检索,融合后重排取前几个片段,拼进提示词让模型回答,要求每个结论标注片段编号,最后程序检查引用的编号确实存在。
最重要的一点是权限要在检索层过滤,没权限的文档根本不能进上下文,不能靠提示词让模型别说。
评测上,先从真实提问里收集一两百个问题,标注正确的文档片段和参考答案,分别评检索的召回率和回答的忠实度。成本上,一次问答输入三四千 token,按便宜模型算一次不到一分钱人民币。风险主要是幻觉和过期文档,兜底是允许拒答、回答带出处和文档更新时间。
3.3 “设计一个电商客服 Agent”
先问:处理哪些问题,查物流、退换货、改地址还是全都要;Agent 能不能直接执行退款,还是只能提交申请;每天多少会话;转人工的条件是什么。假设要处理查订单、查物流、退货申请,退款金额小的可以自动执行。
这个场景和知识库问答最大的区别是有写操作。工具设计上,查询类工具只读,比如查订单、查物流;写操作工具比如提交退货、退款,参数由后端再校验一遍:订单是不是这个用户的、是否在退货期内、金额是否超过阈值。超过阈值的走人工确认。退款要带幂等键,网络重试不能退两次。
身份上,工具一律用当前登录用户的身份去调业务系统,模型给的订单号只是参数,归属由后端校验,防止用户通过对话查别人的订单。
转人工是必须的兜底:用户明确要求、情绪激动、连续几轮没解决、涉及投诉或高金额时转人工,并把对话摘要一起交过去。
评测上客服特别要看稳定性,τ-bench 论文里就发现客服场景单次成功率不到一半的模型,连续 8 次都成功的比例更低,所以要看 pass^k,而且要模拟多轮对话。线上看完成率、转人工率、用户满意度。
3.4 “设计一个 Coding Agent”
我项目其实就是这一类的简化版,所以我会结合它讲。
先问:是在用户本地跑还是云端跑;改哪些仓库;产出是直接提交还是给人审核;有没有测试。假设是云端跑、针对公司内部仓库、产出是一个待审核的合并请求。
核心是三件事。第一是沙箱:Agent 要执行命令、跑测试,必须在隔离的容器里,只挂载这个仓库、默认断网、有资源和时间上限。我项目就是没做容器,只做了工具层检查,结果评测里发现模型能通过写构建脚本绕过路径检查。
第二是用程序验证结果,而不是信模型说”改好了”。跑已有测试、跑新写的测试、跑静态检查,全部通过才算完成。我项目的验收就是独立重新构建并检查产物架构,还修过两次验收自身的 bug。
第三是人审核:产出是 diff,给人看,Agent 不能直接合入主分支。
另外工具接口要为 Agent 专门设计,比如读文件支持分页、命令输出截断但保留退出码、编辑文件用明确的替换而不是整个重写。我项目里读文件原来只保留末尾 100 行,模型为了看前半部分绕了很多弯路,改成分页后这类绕路就没有了。
3.5 “设计一个深度调研 Agent”
这是多 Agent 比较适合的场景,因为调研可以按方向拆开并行做。
先问:调研报告给谁看、要多长、能花多少时间和钱、信息源是公开网页还是内部资料。
架构用主管-工人:主 Agent 先分析问题、拆成几个互不依赖的方向,给每个子 Agent 写清楚目标、输出格式、可用的搜索工具和边界;子 Agent 并行搜索、阅读,只把带出处的要点交回来;主 Agent 汇总写报告;最后有一步专门核对引用,检查每个结论引用的来源确实支持这个结论。
关键设计是预算控制:按问题复杂度决定派几个子 Agent、每个最多多少次搜索,Anthropic 公开的研究系统里多 Agent 的 token 用量大约是普通对话的 15 倍,不控制成本很容易失控。还有网页内容是不可信的,要防间接注入,子 Agent 只有搜索和读取工具,不能对外发送任何东西。
评测上可以用模型当裁判,按准确性、引用质量、完整性打分,但要先用人工标注校准。
第四部分 逐个详解
4.1 答题框架(八步)
flowchart TD
S1["① 澄清需求<br/>用户 量 准确率 延迟 出错代价<br/>要不要 Agent"] --> S2["② 核心流程<br/>一次请求经过哪几步"]
S2 --> S3["③ 架构图<br/>前端 后端 模型 检索 工具 存储"]
S3 --> S4["④ 数据与存储<br/>存什么 怎么更新 怎么查"]
S4 --> S5["⑤ 工具与权限<br/>工具清单 权限边界 人工确认"]
S5 --> S6["⑥ 评测<br/>评测集 分层 线上指标"]
S6 --> S7["⑦ 成本与延迟<br/>粗略估算 优化手段"]
S7 --> S8["⑧ 风险与兜底<br/>幻觉 注入 越权 故障"]
每一步该问、该说什么:
| 步骤 | 该问或该说的 | 对应前面哪篇 |
|---|---|---|
| ① 澄清需求 | 用户是谁、多少人;每天多少次;准确率要求;延迟要求(要不要流式);出错代价(只读还是有写操作);现有系统;数据权限;是否真的需要 Agent | 05 |
| ② 核心流程 | 一次请求的步骤序列;哪些步骤固定、哪些由模型决定 | 05 |
| ③ 架构图 | 前端、API 层、任务执行、模型网关、检索、工具、存储、可观测 | 14、10 |
| ④ 数据与存储 | 知识从哪来、怎么解析切片、索引怎么更新;会话和运行记录存哪 | 08、06、07 |
| ⑤ 工具与权限 | 工具清单和粒度;每个工具的权限边界;以谁的身份调下游;哪些操作要确认 | 04、11 |
| ⑥ 评测 | 评测集从哪来;成功标准;检索 / 单步 / 端到端分层;回归流程;线上指标 | 09 |
| ⑦ 成本与延迟 | token 估算;缓存;模型选择;并行;流式 | 01、02、10 |
| ⑧ 风险与兜底 | 幻觉、注入、越权、成本失控、下游故障;降级和兜底方案 | 11、02 |
第一步里最重要的一个判断:要不要 Agent。 05 篇引用过 Anthropic 的建议,先用最简单的方案,只有在确实需要时才增加复杂度。
| 特征 | 用工作流 | 用 Agent |
|---|---|---|
| 步骤 | 固定、可以事先列出 | 不固定,要根据中间结果决定 |
| 工具调用 | 顺序确定 | 调哪个、调几次由模型决定 |
| 例子 | 文档问答(检索 → 生成)、固定格式的信息抽取 | 排查问题、编译项目、开放式调研 |
| 优点 | 可预测、便宜、好测试 | 灵活 |
很多”设计一个 XX Agent”的题,核心部分其实用工作流就够了。主动指出这一点是加分项。
时间分配:一道题一般 30 到 45 分钟。前五步是主干,占大部分时间;但后三步每步至少说两三句,因为评测、成本、风险最能区分”做过项目”和”看过文章”。
4.2 快速估算:成本和流量
面试时不需要精确,但要能在一两分钟内说出数量级,并说清楚假设。
动手实验:保存为 estimate.py。价格用写这篇时核对的 DeepSeek deepseek-flash 非高峰价(每百万 token:未命中 0.15 美元、命中 0.003 美元、输出 0.6 美元),价格会变,只作演示。
PRICE_MISS, PRICE_HIT, PRICE_OUT = 0.15, 0.003, 0.6
def call_cost(inp, out, cached):
return ((inp - cached) * PRICE_MISS + cached * PRICE_HIT + out * PRICE_OUT) / 1e6
def rag_qa(users, per_user, system=800, chunks=5, chunk=400, history=600, question=60, out=350):
inp = system + chunks * chunk + history + question
per_query = call_cost(inp, out, cached=system)
queries = users * per_user
return queries, inp, per_query, per_query * queries
def agent_task(steps, system=2500, per_step_in=900, out=150, hit_ratio=0.8):
total, context = 0.0, system
for _ in range(steps):
total += call_cost(context, out, cached=int(context * hit_ratio))
context += out + per_step_in
return context, total
queries, inp, per_q, day = rag_qa(users=2000, per_user=8)
peak_qps = queries * 0.3 / 3600
print(f"知识库问答:每天 {queries:,} 次,单次输入 {inp:,} token,单次 ${per_q:.5f},每天 ${day:.2f},高峰约 {peak_qps:.1f} QPS")
for steps in (6, 20, 40):
ctx, cost = agent_task(steps)
ctx0, cost0 = agent_task(steps, hit_ratio=0)
print(f"Agent {steps:>2} 步:最后上下文 {ctx:>6,} token,缓存命中 80% ${cost:.4f},无缓存 ${cost0:.4f}")
实际输出(Python 3.14,只用标准库):
知识库问答:每天 16,000 次,单次输入 3,460 token,单次 $0.00061,每天 $9.78,高峰约 1.3 QPS
Agent 6 步:最后上下文 8,800 token,缓存命中 80% $0.0015,无缓存 $0.0052
Agent 20 步:最后上下文 23,500 token,缓存命中 80% $0.0099,无缓存 $0.0392
Agent 40 步:最后上下文 44,500 token,缓存命中 80% $0.0334,无缓存 $0.1414
逐段讲。
PRICE_MISS, PRICE_HIT, PRICE_OUT = 0.15, 0.003, 0.6:一行给三个变量赋值,右边的三个值按顺序对应左边三个名字,这叫多重赋值(本质是元组拆包)call_cost:10 篇讲过的成本公式,除以1e6是因为价格按每百万 token 计。1e6是科学计数法,等于 1000000.0rag_qa的默认参数就是假设:系统提示词 800、检索 5 个片段每个 400、对话历史 600、问题 60、回答 350 token。只有系统提示词能稳定命中缓存,所以cached=systempeak_qps = queries * 0.3 / 3600:假设一天里最忙的那一小时占全天 30% 的请求,除以 3600 秒得到每秒请求数agent_task:每一步把当前上下文全部发出,模型输出 150 token、工具结果 900 token 加回上下文。hit_ratio=0.8假设 80% 的输入命中缓存(前缀和上一步相同的部分)int(context * hit_ratio):int()把小数截成整数
看结果,面试时能说的几句话:
- 知识库问答很便宜:2000 个员工每人每天问 8 次,一天不到 10 美元,高峰 1 点几 QPS。瓶颈通常不在成本,而在解析质量和检索准确率
- Agent 的成本随步数加速增长:6 步到 40 步,步数约 6.7 倍,无缓存成本约 27 倍(0.0052 → 0.1414)。因为每步都重发越来越长的历史
- 缓存影响很大:40 步时有缓存 0.033 美元,无缓存 0.141 美元,差 4 倍多。所以系统提示词、工具定义要放前面保持稳定(06 篇)
- 这些假设要用真实数据校准。拿我项目对照:LangGraph 对比那组数据里,手写版平均每次运行输入 14.4 万 token,10 个项目平均约 13.6 步(简单中等 8 个平均 10.8 步、困难 2 个平均 25 步);按这个模型算 14 步的输入合计是 130,550 token,数量级对得上。但项目没记录缓存命中,80% 命中率只是假设
QPS 和并发数的换算:Agent 请求时间长,并发数远大于 QPS。
同时在跑的任务数 ≈ 每秒新任务数 × 平均任务时长
每秒 1 个新任务、每个跑 60 秒,同时就有约 60 个任务在跑。这决定了工作进程数、模型 API 的并发限额、数据库连接数。这个关系在排队论里叫利特尔法则(Little’s Law)。
它的来历。 这个公式本身很早就有人在用:1954 年 Alan Cobham 的论文直接拿它当已知结论,1958 年 Philip M. Morse 把它写成 L = λW,还请读者找反例。问题是没人证明过它在什么条件下一定成立。1961 年运筹学学者 John D. C. Little 在《运筹学》(Operations Research)期刊上发表了 A Proof for the Queuing Formula: L = λW,给出了第一个严格证明,公式从此用他的名字命名。三个字母对应的就是上面那行:L 是系统里平均同时有多少个任务,λ 是平均每秒进来多少个,W 是每个平均待多久。它厉害的地方在于几乎不挑前提,不管任务是怎么到达的、每个耗时怎么分布,只要长期看进出平衡就成立,所以估算 Agent 并发时可以放心拿来用。
自己改一改:
- 把知识库问答的
chunks从 5 改成 20(检索更多片段),看单次成本变化 - 把
agent_task的per_step_in改成 3000(工具返回很长),看 40 步的成本 - 算一下:每秒 2 个新 Agent 任务、平均 90 秒,需要同时支持多少个任务
4.3 题一:企业内部知识库问答
① 澄清需求(问完之后说出你的假设):
| 要问的 | 为什么影响设计 | 本题假设 |
|---|---|---|
| 文档量、格式 | 解析方案、索引规模 | 几十万份,PDF、Word、网页 |
| 更新频率 | 全量重建还是增量更新 | 每天有新增和修改 |
| 权限是否不同 | 检索时要不要过滤 | 按部门和项目区分 |
| 要不要出处 | 提示词和校验 | 必须给出处 |
| 能否拒答 | 找不到时怎么办 | 可以说”没找到” |
| 用户量 | 容量 | 2000 人,每人每天约 8 次 |
| 延迟 | 要不要流式 | 首字 2 秒内,流式输出 |
判断要不要 Agent:大部分问题是”检索 → 生成”两步,工作流就够了。只有”对比三份制度的差异”这类需要多次检索的复杂问题,才考虑让模型自己决定查几次。
② 核心流程和 ③ 架构:
flowchart TB
subgraph 离线
SRC[文档源<br/>网盘 Wiki 系统] --> PARSE[解析 清洗]
PARSE --> CHUNK[按结构切片<br/>带标题 来源 权限 更新时间]
CHUNK --> EMB[向量化]
EMB --> VDB[(向量索引)]
CHUNK --> KW[(关键词索引)]
SRC -.->|变更事件| INC[增量更新<br/>按文档 ID 删旧片段 写新片段]
INC --> VDB
INC --> KW
end
subgraph 在线
U[员工提问] --> AUTH[身份 → 可访问的权限范围]
AUTH --> RW[查询改写<br/>结合对话历史补全指代]
RW --> RET[混合检索<br/>带权限过滤]
VDB --> RET
KW --> RET
RET --> RR[融合 + 重排<br/>取前 5]
RR --> GEN[生成<br/>要求标注片段编号]
GEN --> CHK[引用校验<br/>编号存在 片段支持结论]
CHK --> OUT[流式返回<br/>附出处和更新时间]
end
④ 数据与存储:
| 数据 | 存哪 | 要点 |
|---|---|---|
| 原始文档 | 对象存储 | 保留原件,便于重新解析 |
| 片段 | 向量库 + 关键词索引 | 元数据:文档 ID、标题、章节、权限标签、更新时间 |
| 对话历史 | 数据库 | 按会话存,用于查询改写 |
| 反馈和日志 | 数据库 | 点踩的问题进入评测集候选 |
关键设计点(面试时重点讲):
- 权限在检索层过滤。片段带权限标签,检索时只在用户可访问的范围内查。不能先全量检索、再让模型”不要说出没权限的内容”,资料一旦进了上下文就可能泄露(08、11 篇;OWASP LLM08 向量和嵌入弱点)
- 切片带上下文。片段脱离原文会丢失”在讲哪份文档哪一章”,切片时把文档标题、章节路径加到片段前面。Anthropic 的 Contextual Retrieval 实验里,给片段补上下文加上下文化的 BM25,检索失败率降低 49%,再加重排降低 67%(08 篇)
- 混合检索。员工会搜制度编号、产品型号这类精确词,纯向量检索容易漏,要加关键词检索
- 增量更新。按文档 ID 管理片段,文档修改时删掉旧片段写入新的;文档删除时片段也要删,否则会答出已废止的制度
- 引用和拒答。提示词要求只根据资料回答并标注编号;程序检查编号存在;检索分数都很低时直接回答”没找到相关资料”
⑥ 评测:
| 层 | 测什么 | 怎么测 |
|---|---|---|
| 解析 | 表格、多栏排版是否正确 | 抽样人工看 |
| 检索 | 召回率@5、MRR | 从真实提问中收集问题,标注正确片段 |
| 生成 | 忠实度(有没有编造)、是否正确引用、该拒答时是否拒答 | 模型当裁判 + 人工校准 |
| 端到端 | 回答是否解决问题 | 抽样人工评 |
| 权限 | 用 A 部门身份问 B 部门的问题 | 必须拿不到,作为回归测试 |
| 线上 | 点赞率、追问率、“没找到”的比例 | 看板 |
⑦ 成本与延迟:按 4.2 节估算,一天不到 10 美元。延迟主要是检索(向量检索几十毫秒,重排可能上百毫秒到一秒以上,我项目实测 bge-reranker 每条查询 1.1 秒)加模型首 token 时间,流式输出改善体感。
⑧ 风险与兜底:
| 风险 | 兜底 |
|---|---|
| 幻觉 | 只根据资料回答、引用校验、允许拒答 |
| 过期文档 | 显示文档更新时间;废止文档从索引删除 |
| 越权 | 检索层权限过滤;权限变更时片段权限同步更新 |
| 文档里的注入 | 文档内容当数据;这个系统只读、不能对外发送,致命三要素缺一 |
| 模型服务故障 | 备用模型;再不行返回检索到的原文片段 |
追问:
| 追问 | 回答方向 |
|---|---|
| 员工权限变了怎么办 | 检索时实时查权限范围,而不是把权限写死在用户会话里;片段的权限标签随文档权限同步 |
| 表格很多怎么办 | 表格单独解析,转成行文本或存结构化数据走查询工具 |
| 问题需要综合多份文档 | 让模型拆成子问题多次检索(这时才用 Agent);或者提高召回数量后重排 |
| 怎么知道回答对不对 | 离线评测集 + 线上点踩回流 + 抽样人工 |
| 向量库选哪个 | 规模、是否已有基础设施、是否需要元数据过滤;几十万文档大部分都能支撑 |
4.4 题二:电商客服 Agent
① 澄清需求:
| 要问的 | 本题假设 |
|---|---|
| 处理哪些问题 | 查订单、查物流、退货申请、小额退款、常见问题 |
| 能不能直接执行写操作 | 查询自动;退货申请自动提交;退款 100 元以下自动,以上转人工确认 |
| 量 | 每天 5 万会话 |
| 转人工条件 | 用户要求、投诉、连续 3 轮未解决、高金额 |
| 渠道 | 网页和 App 聊天窗口 |
判断要不要 Agent:用户的问题五花八门,需要多轮对话、按情况调不同的查询和操作工具,适合 Agent。但每一类业务流程(比如退货)内部的规则应该由后端代码保证,而不是靠模型记住。
② 核心流程和 ③ 架构:
flowchart LR
U[用户] --> GW[对话网关<br/>登录身份]
GW --> AG[客服 Agent<br/>多轮状态]
AG -->|只读| T1[查订单]
AG -->|只读| T2[查物流]
AG -->|只读| T3[知识库 FAQ]
AG -->|写 带幂等键| T4[提交退货]
AG -->|写 超阈值需确认| T5[退款]
AG --> T6[转人工<br/>带对话摘要]
T1 & T2 & T4 & T5 --> BIZ[业务系统<br/>以用户身份鉴权]
T5 -.->|金额超阈值| HUM[人工审核台]
T6 --> HUM
AG --> LOG[(对话 轨迹 审计)]
关键设计点:
- 身份和鉴权在后端。工具调用业务系统时带的是当前登录用户的身份,模型给的订单号只是参数。后端检查订单归属,防止”帮我查一下订单 12345”查到别人的订单
- 业务规则在代码里。退货期限、退款金额上限、商品是否支持退货,由后端校验。模型可以解释规则,但不能决定规则
- 写操作幂等。退款请求带幂等键(比如”会话 ID + 订单号 + 操作类型”),网络超时重试不会退两次(07 篇)
- 人工确认和转人工。超阈值的退款挂起,等人工在审核台确认;转人工时把对话摘要和已查到的订单信息一起交过去,用户不用重复描述
- 状态机约束对话。退货流程有明确步骤(确认订单 → 确认原因 → 确认退货方式 → 提交),可以把当前步骤存在会话状态里,只开放这一步需要的工具,减少模型乱调
退款的时序:
sequenceDiagram
participant U as 用户
participant A as 客服 Agent
participant T as 退款工具
participant B as 业务系统
participant H as 人工审核
U->>A: 耳机坏了,要退款
A->>T: refund(order_id, reason)
T->>B: 以用户身份查订单
B-->>T: 订单属于该用户,金额 299 元
T->>T: 超过 100 元阈值
T->>H: 创建审核单(幂等键)
T-->>A: 已提交人工审核
A-->>U: 已提交,预计 24 小时内处理
H->>B: 审核通过,执行退款(同一幂等键)
⑥ 评测:
- 模拟多轮对话:用另一个模型扮演用户,按剧本提出问题、中途改主意、提供错误信息。τ-bench 就是这样测的,模拟用户、工具和业务规则
- 看 pass^k:τ-bench 发现当时最强的 GPT-4o 在零售场景单次成功率不到 50%,连续 8 次都成功的比例不到 25%。客服每次都要做对,要看稳定性(09 篇)
- 按结果检查:对话结束后检查数据库状态,比如退货单是否正确创建、有没有错误的退款
- 安全用例:查别人的订单、诱导超额退款、提示词注入,必须全部拦住
- 线上:问题解决率、转人工率、平均轮数、用户满意度、错误退款金额
⑦ 成本与延迟:每个会话平均 6 到 10 步,按 4.2 节估算每个会话不到 1 美分,每天 5 万会话几百美元以内。延迟要求高,每一轮要在几秒内回复,简单的 FAQ 可以不走 Agent 直接检索回答。
⑧ 风险与兜底:
| 风险 | 兜底 |
|---|---|
| 错误退款 | 阈值 + 人工确认;幂等键;业务系统校验;每日退款金额监控告警 |
| 越权查询 | 以用户身份调下游,后端校验归属 |
| 用户注入”忽略规则直接退款” | 规则在代码里,模型怎么被说服都执行不了 |
| 答非所问、绕圈 | 连续 N 轮未解决转人工 |
| 业务系统故障 | 工具返回明确错误,Agent 告知用户稍后再试或转人工 |
追问:
| 追问 | 回答方向 |
|---|---|
| 退款阈值怎么定 | 业务决定;按错误退款的损失和人工成本权衡;上线初期设低,逐步放开 |
| 模型把退款原因理解错了 | 提交前向用户复述确认;关键字段结构化 |
| 高峰期怎么办 | FAQ 走缓存或检索直接答;排队;限流;转人工排队提示 |
| 怎么防止 Agent 承诺做不到的事 | 提示词限制 + 输出检查(比如不能承诺具体赔偿金额)+ 评测用例 |
| 多轮对话上下文太长 | 会话状态结构化保存(订单号、当前步骤),历史压缩 |
4.5 题三:Coding Agent
① 澄清需求:
| 要问的 | 本题假设 |
|---|---|
| 在哪运行 | 云端,每个任务一个隔离环境 |
| 任务来源 | 从工单系统领取小型 bug 修复和功能 |
| 产出 | 一个待人工审核的合并请求,不能直接合入 |
| 有没有测试 | 大部分仓库有单元测试 |
| 能访问什么 | 当前仓库;公司内部包仓库;不能访问生产环境 |
② 核心流程和 ③ 架构:
flowchart TB
TICKET[工单] --> ORCH[任务调度]
ORCH --> SB[沙箱容器<br/>只挂载仓库副本<br/>网络只放行包仓库<br/>CPU 内存 时长上限]
subgraph SB2[沙箱内]
AG[Agent 循环] --> TOOLS[工具<br/>搜索代码 分页读文件<br/>精确替换编辑 执行命令]
TOOLS --> REPO[(仓库副本)]
end
SB --> SB2
AG --> VERIFY[程序验收<br/>编译 已有测试 新测试 静态检查]
VERIFY -->|失败| AG
VERIFY -->|通过| PR[生成 diff<br/>创建合并请求]
PR --> REVIEW[人工审核]
AG --> TRACE[(轨迹 审计)]
关键设计点:
- 沙箱是边界,工具层检查只是辅助。11 篇讲过,构建工具和测试框架本身就能执行任意代码,命令白名单挡不住。容器只挂载仓库副本、网络只放行需要的包仓库、不传入宿主机的环境变量和凭据
- 用程序验证,不信模型自述。完成的判据是编译通过、测试通过、静态检查通过,由调度程序在 Agent 结束后独立再跑一遍
- 防止钻验收的空子。模型可能删掉失败的测试、把断言改成永远成立。验收时要检查 diff 里有没有修改测试文件,修改了要特别标注给审核人。我项目遇到过类似情况:有一次 Agent 修改了项目的 CMakeLists.txt,加了一个示例目标来满足”必须有编译产物”的验收
- 为 Agent 设计工具接口。SWE-agent 论文(2405.15793)提出了”Agent-计算机接口”的概念,认为给 Agent 专门设计的命令和反馈格式能明显提升效果。实践上:搜索代码的工具返回文件和行号;读文件分页;编辑用精确替换;命令输出截断但保留退出码和完整日志的位置
- 人审核 diff。Agent 不能直接合入主分支;合并请求里附上 Agent 的思路摘要和验证结果
我项目对照(这道题我可以用自己的项目讲很具体的例子):
| 设计点 | 我项目 | 学到的 |
|---|---|---|
| 沙箱 | 没做容器,只有工具层检查 | 评测里发现模型写 CMakeLists 用 execute_process 扫主机目录,参数检查拦不住 |
| 程序验收 | 独立重新构建并检查 ELF 架构 | 验收自身出过两次 bug:没编译任何目标也判通过;构建目录不叫 build 时误判失败 |
| 钻验收空子 | run 44 里 Agent 给 header-only 项目加了一个示例目标 | 验收标准写了什么,模型就会想办法满足什么 |
| 工具接口 | read_file 分页、命令输出截断保留退出码、完整日志存工作目录内 | 旧版只留末尾 100 行,第一版里 6 次运行出现 15 次”写 CMake 脚本分段读文件”的绕路,改成分页后 v2、v3 的 120 次运行里一次没出现 |
| 步数预算 | 上限从 25 提到 40 | 困难项目是嵌套任务(先编依赖),25 步不够 |
⑥ 评测:用历史上真实修过的 bug 构造任务(有修复前的代码、修复后通过的测试),类似 SWE-bench 的做法;评分器就是跑测试;每个任务多跑几次看稳定性;另外看合并请求被审核通过的比例和审核时修改的量。
⑦ 成本:编码任务步数多、每步读的文件长,单个任务几十万 token 很常见。我项目单次运行平均输入十几万 token。要控制:步数上限、读文件分页、历史压缩、搜索工具返回摘要而不是全文。
⑧ 风险与兜底:
| 风险 | 兜底 |
|---|---|
| 执行恶意代码或破坏环境 | 容器隔离、断网、资源限制、每次新环境 |
| 泄露代码或凭据 | 不传凭据;网络白名单;仓库里的密钥扫描 |
| 引入隐蔽 bug | 测试 + 静态检查 + 人工审核 |
| 删测试、改断言 | 验收检查测试文件变更,标注给审核人 |
| 死循环、成本失控 | 步数、时间、token 上限 |
| 仓库里的注入(README、注释) | 没有对外通信能力;不给生产权限 |
追问:
| 追问 | 回答方向 |
|---|---|
| 仓库没有测试怎么办 | 先让 Agent 写复现问题的测试,人确认测试正确后再修复 |
| 大仓库上下文装不下 | 搜索工具定位;子 Agent 做只读调查(13 篇);不整个读入 |
| 多个 Agent 并行改同一个仓库 | 每个任务独立分支和副本;冲突在合并时由人解决;不建议并行改同一块代码 |
| 怎么让模型遵守代码规范 | 规范写进仓库里的说明文件;静态检查强制;评测里加检查 |
4.6 题四:深度调研 Agent
① 澄清需求:
| 要问的 | 本题假设 |
|---|---|
| 给谁看、多长 | 给业务负责人看的 3000 字左右调研报告 |
| 信息源 | 公开网页 + 公司内部资料库 |
| 时间和预算 | 10 分钟以内;单份报告成本上限 |
| 准确性要求 | 每个关键结论必须有可点击的出处 |
② 核心流程和 ③ 架构:
flowchart TD
Q[调研问题] --> LEAD[主 Agent<br/>分析问题 拆方向<br/>按复杂度定预算]
LEAD -->|方向 1 任务说明| S1[子 Agent 1<br/>网页搜索 读取]
LEAD -->|方向 2| S2[子 Agent 2<br/>网页搜索 读取]
LEAD -->|方向 3| S3[子 Agent 3<br/>内部资料检索]
S1 -->|要点 + 出处| LEAD
S2 -->|要点 + 出处| LEAD
S3 -->|要点 + 出处| LEAD
LEAD --> DRAFT[撰写报告]
DRAFT --> CITE[引用核对<br/>每个结论对应的原文<br/>是否真的支持它]
CITE -->|不支持| DRAFT
CITE --> OUT[报告 + 出处列表]
关键设计点:
- 主管-工人,并行查。调研可以按方向拆开,子 Agent 之间几乎不需要协调,是 13 篇里说的适合多 Agent 的典型场景
- 任务说明写全。每个子 Agent 的任务要写清目标、输出格式、该用哪些工具和信息源、边界,否则会重复搜索或者漏掉(Anthropic 多 Agent 研究系统的经验)
- 按复杂度控制预算。简单问题一个子 Agent 几次搜索就够;复杂问题多派几个。每个子 Agent 有搜索次数和 token 上限。Anthropic 的数据是多 Agent 系统 token 约为普通对话的 15 倍
- 引用核对。子 Agent 交回要点时必须附原文片段和链接;报告写完后,逐条检查结论和原文是否一致,不一致的删除或改写。这一步可以用模型做,但要保留原文供人核查
- 防注入。网页内容是不可信的,子 Agent 只有搜索和读取工具,没有任何对外发送或写入的能力,致命三要素里缺了”对外通信”。内部资料检索要按用户权限过滤
⑥ 评测:结果是开放式文本,很难用程序判对错。可以:用模型当裁判按事实准确性、引用是否支持结论、完整性、来源质量打分(先用人工标注校准,09 篇);准备一批有公认答案的问题检查关键事实;统计引用核对失败的比例。
⑦ 成本与延迟:成本最高的一类,要设单份报告上限;并行显著缩短时间,Anthropic 提到并行工具调用让复杂查询的研究时间最多缩短 90%。
⑧ 风险与兜底:
| 风险 | 兜底 |
|---|---|
| 编造结论或张冠李戴 | 引用核对;报告里每个结论可点击查看原文 |
| 来源质量差 | 优先权威来源;标注来源类型和日期 |
| 网页注入 | 子 Agent 无对外能力;读取内容当数据 |
| 成本失控 | 按复杂度定预算;每个子 Agent 有上限;总上限 |
| 子 Agent 结论互相矛盾 | 主 Agent 汇总时标注分歧,而不是强行统一 |
追问:
| 追问 | 回答方向 |
|---|---|
| 为什么用多 Agent | 方向可拆、互不依赖;并行省时间;各自上下文干净 |
| 子 Agent 查重复了怎么办 | 任务说明写清边界;主 Agent 分派时去重 |
| 怎么判断查够了 | 预算上限;主 Agent 判断各方向覆盖度;关键问题都有两个以上来源 |
| 结果怎么复现 | 保存所有搜索查询、读取的网页快照和轨迹 |
4.7 几个通用追问怎么接
| 追问 | 思路 |
|---|---|
| ”流量涨 10 倍怎么办” | 先说瓶颈在哪:模型 API 的并发和限流额度、检索服务、任务队列的工作进程、数据库连接。然后对应手段:申请更高限额或多供应商分流;缓存重复请求;简单请求走小模型;异步化长任务;工作进程水平扩容;限流保护 |
| ”模型服务挂了怎么办” | 超时和重试退避;切到备用模型(提前评测过的);再不行降级:知识库返回原文片段、客服转人工、长任务排队稍后执行;告警(02、10 篇) |
| “成本要降一半” | 先看钱花在哪(10 篇的成本看板);提高缓存命中(稳定前缀);简单步骤换小模型;减少步数(改工具设计、加知识);截断工具结果、压缩历史;限制失败任务的步数上限 |
| ”延迟太高” | 流式输出改善体感;先看步数;并行工具调用;减少输入长度;小模型做路由和简单判断 |
| ”怎么保证效果不退化” | 回归评测集接进发布流程;小流量灰度;线上指标监控和回滚(09 篇) |
| “数据安全怎么保证” | 权限在检索和工具层;凭据不进上下文;日志脱敏;私有化部署或选择数据不用于训练的服务 |
4.8 用这个框架讲我自己的项目
面试官常说”你就拿你的项目当设计题讲一遍”。CrossBuild Agent 按八步:
| 步骤 | 我项目 |
|---|---|
| ① 需求 | 给一个开源 C/C++ 仓库,交叉编译到 aarch64-linux-musl;判定标准是产出目标架构的产物。路径不固定(每个项目的依赖、选项、报错都不同),所以用 Agent |
| ② 核心流程 | 准备工作目录和 toolchain → 探测项目结构 → Agent 循环(调模型、执行工具、结果放回)→ 步数上限或模型结束 → 独立验收 |
| ③ 架构 | Vue 前端 + FastAPI(SSE 推进度)+ 后台线程跑 Agent;工具层独立,被手写循环、LangGraph、MCP server 三个入口共用 |
| ④ 数据 | runs.db 记每次运行和每次工具调用;知识库 15 条经验(BM25 + 向量混合检索);LangGraph 版本用 checkpoints.db 存检查点 |
| ⑤ 工具与权限 | 5 个工具;路径必须在工作目录内、凭据文件拦截、命令白名单、参数路径检查、不走 shell;明确不是沙箱 |
| ⑥ 评测 | 10 个项目三档 + 5 个留出项目;每配置 3 轮;程序验收;检索单独 48 条测试集;验收自身修过两次 |
| ⑦ 成本 | 288 次运行输入 4870 万 token、输出 117 万,比例 41.6;没记缓存命中;步数上限是成本控制手段 |
| ⑧ 风险 | 已处理:cat 绕过、路径前缀、断开连接放锁;未处理:构建脚本绕过、子进程读环境变量、没有容器、没有心跳、没有告警 |
第⑧步主动说”未处理”的部分,比只讲做到的更有说服力。
第五部分 对照项目
| 本篇知识点 | 项目里的位置 | 做到了什么 | 没做到或可以改进的 |
|---|---|---|---|
| 判断要不要 Agent | 交叉编译任务 | 路径不固定,用 Agent 合理 | — |
| 程序验收 | build_agent.verify | 独立重新构建、检查 ELF 架构、自动找构建目录 | 没检查 Agent 是否改了项目文件来迎合验收 |
| 为 Agent 设计工具 | agent/tools.py | 分页读、截断保留退出码、完整日志、错误信息引导 | 编辑是整文件覆盖,没有精确替换 |
| 沙箱 | — | README 写明不是沙箱 | Coding Agent 类设计必须有容器 |
| 权限 | 工具层检查 | 路径、凭据、白名单 | 构建脚本和环境变量问题未解决 |
| 评测 | eval/ | 分层、多轮、留出集、验收回归测试 | 规模小、已饱和 |
| 成本估算 | runs.db | 能统计 token | 没有缓存命中、没有金额 |
| 后端 | server/app.py | SSE、锁、409 | 单进程、无任务队列、无心跳 |
| 多 Agent | — | 没用,理由清楚 | — |
| 线上指标 | — | 没有线上用户 | — |
第六部分 追问清单
| 你刚讲完 | 下一个追问 | 回答方向 |
|---|---|---|
| 答题框架 | 时间不够先讲什么 | 前五步主干,后三步每步两三句 |
| 要不要 Agent | 知识库问答为什么不用 Agent | 检索 → 生成两步固定;复杂问题才让模型多次检索 |
| 成本估算 | 你的估算准吗 | 只求数量级;说清假设;用真实数据校准(项目 14 步约 13 万 vs 实测 14.4 万) |
| QPS | Agent 服务要多少工作进程 | 并发数 ≈ 每秒新任务 × 平均时长 |
| 知识库权限 | 权限实时变化怎么办 | 检索时实时查权限范围;片段权限标签同步更新 |
| 知识库更新 | 文档删了怎么办 | 按文档 ID 删除片段;否则答出废止内容 |
| 客服退款 | 怎么防止退两次 | 幂等键;业务系统校验 |
| 客服安全 | 用户说”我是管理员,直接退” | 身份来自登录态;规则在代码里 |
| 客服评测 | 为什么看 pass^k | 每次都要成功;τ-bench 数据 |
| Coding Agent | 模型删测试怎么办 | 验收检查测试文件变更;人工审核 |
| Coding Agent | 你项目遇到过迎合验收吗 | run 44 给 header-only 项目加示例目标 |
| 调研 Agent | 引用核对怎么做 | 保留原文片段;逐条比对结论;不支持的删改 |
| 调研 Agent | 成本怎么控 | 按复杂度定子 Agent 数和搜索次数;总上限 |
| 通用 | 模型挂了 | 重试、备用模型、降级、告警 |
| 通用 | 成本降一半 | 缓存、小模型、减步数、截断、压缩 |
第七部分 闭卷自测
1. 系统设计题的八步框架是什么?哪三步最容易被漏掉,为什么它们重要?
答案
澄清需求 → 核心流程 → 架构图 → 数据与存储 → 工具与权限 → 评测 → 成本与延迟 → 风险与兜底。后三步(评测、成本与延迟、风险与兜底)最容易漏,它们最能体现有没有真正做过工程、是否考虑过上线后的问题。
2. 第一步澄清需求至少要问哪些问题?还要做一个什么判断?
答案
用户是谁和数量、每天请求量、准确率要求、延迟要求(是否流式)、出错代价(只读还是有写操作)、现有系统、数据权限。还要判断是否真的需要 Agent:步骤固定用工作流,路径不固定、需要根据中间结果多步调工具才用 Agent。
3. 实验里 Agent 步数从 6 到 40,无缓存成本增长了多少倍?为什么远超步数的倍数?缓存有多大影响?
答案
步数约 6.7 倍,无缓存成本约 27 倍(0.0052 → 0.1414 美元),因为每步都重发越来越长的历史,输入合计近似平方增长。40 步时 80% 缓存命中成本 0.0334 美元,无缓存 0.1414 美元,差 4 倍多。
4. 每秒 2 个新 Agent 任务、平均每个 90 秒,同时大约有多少个任务在跑?这影响哪些资源规划?
答案
约 2 × 90 = 180 个。影响工作进程数、模型 API 并发限额、数据库连接数、沙箱容器数量。
5. 企业知识库问答为什么要在检索层做权限过滤?只在提示词里要求模型不说有什么问题?
答案
资料一旦进入上下文就可能被模型说出来,或者被注入、套话泄露;提示词要求是概率性的,挡不住。检索层过滤保证没权限的片段根本不进上下文,是确定性的。
6. 知识库文档修改或删除时,索引怎么处理?不处理会怎样?
答案
按文档 ID 管理片段,修改时删除旧片段写入新片段,删除时同步删除片段。不处理会检索到过期或已废止的内容,模型据此回答错误信息。
7. 客服 Agent 的退款工具要做哪几层保护?
答案
以当前登录用户身份调业务系统,后端校验订单归属;业务规则(退货期、金额上限)在代码里校验;超过阈值转人工确认;带幂等键防止重复退款;审计记录;每日退款金额监控告警。
8. 为什么客服 Agent 的评测要看 pass^k 并模拟多轮对话?τ-bench 的数据说明了什么?
答案
客服每次对话都要做对,稳定性比”能做到”更重要;真实对话是多轮的,用户会改主意、给错信息。τ-bench 里 GPT-4o 零售场景单次成功率不到 50%,连续 8 次都成功不到 25%,说明单次成功率会高估实际可靠性。
9. Coding Agent 设计里最关键的三件事是什么?分别用我项目的经验说明。
答案
沙箱:我项目没做容器,模型写 CMakeLists 用 execute_process 扫主机目录,参数检查拦不住。程序验收:独立重新构建检查 ELF 架构,验收自身修过两次 bug。为 Agent 设计工具:read_file 旧版只留末尾 100 行导致 15 次绕路,改成分页后 120 次运行一次没出现。(人工审核 diff 也是关键之一。)
10. 模型可能怎样”钻验收的空子”?怎么防?
答案
删除失败的测试、把断言改成永远成立、加一个无意义的目标来满足”有产物”(我项目 run 44 给 header-only 项目加了示例目标)。防:验收检查测试和构建文件的变更并标注给审核人;人工审核 diff;验收标准尽量贴近真实目标。
11. 深度调研 Agent 为什么适合多 Agent?怎么控制成本、怎么保证结论可靠?
答案
调研可按方向拆开、子 Agent 之间几乎不需要协调,并行省时间、上下文干净。成本:按问题复杂度决定子 Agent 数量和搜索次数,每个子 Agent 和总体都有上限。可靠:子 Agent 交回要点必须附原文和链接,报告写完逐条引用核对,不支持的结论删改;网页内容当不可信数据,子 Agent 没有对外能力。
12. 面试官问”流量涨 10 倍”和”模型服务挂了”,分别怎么答?
答案
流量涨 10 倍:先找瓶颈(模型 API 限额、检索、工作进程、数据库连接),再对应手段:提高限额或多供应商、缓存、简单请求走小模型、长任务异步化、工作进程水平扩容、限流保护。模型挂了:超时重试退避、切换到提前评测过的备用模型、降级(返回检索原文、转人工、排队稍后执行)、告警。
延伸阅读
- Anthropic:Building effective agents(2024-12)— 什么时候用工作流、什么时候用 Agent
- Anthropic:Contextual Retrieval(2024-09)— 知识库检索的具体改进和数据
- τ-bench(2024)— 客服类 Agent 的评测方法和 pass^k
- SWE-agent(2024)— 为 Coding Agent 设计 Agent-计算机接口
- Anthropic:How we built our multi-agent research system(2025-06)— 深度调研 Agent 的完整案例
- OWASP GenAI LLM Top 10 2026(2026-08)和 Top 10 for Agentic Applications — 设计时逐条对照风险,11 篇 4.2 节有 2026 版的中文对照表
下一篇:16 项目怎么讲——把整个系列落到你自己的项目上,准备 1 分钟、3 分钟、10 分钟三个版本。