Agent 面试题

生产化与系统设计:可靠性、安全、评估与成本

生产化与系统设计:可靠性、安全、评估与成本

前面十一期讲的是「怎么把 Agent 做出来」,这一篇讲**「怎么让它敢在生产上跑」**。生产化的核心不是加功能,而是给一个本质上不可靠的东西装上边界。


一、导语:生产化的第一原则是「假设它会出错」

把一个 Agent 做 demo,和把同一个 Agent 上线,是完全不同的两个工程。Demo 关心「能不能跑通一次」,生产关心**「跑不通的时候会怎样」**。

生产化的第一原则:

不要假设 Agent 会成功,要假设它一定会失败——然后设计好失败发生时系统会做什么。

这句原则会推导出本篇所有内容:为什么要幂等、为什么要风险分级、为什么要人工兜底、为什么要分层指标、为什么要成本归因。下面逐层展开。


二、问题来源:Agent 不可靠是四重叠加

面试官问「Agent 为什么难做到可靠」,很多人的答案是「因为 LLM 会幻觉」。这只说对了四分之一。真实的不可靠来自四重风险的叠加:

层级风险来源特征
概率模型LLM 本身是采样输出同一输入可能不同输出(非确定性)
非确定性决策模型用它来决定「下一步做什么」决策路径不固定,无法穷举测试
外部工具网络、第三方 API、数据库超时、限流、部分失败、幂等性未知
分布式执行跨服务、跨机器、有状态网络分区、消息重复、状态不一致

单看每一层,都在可接受范围;叠起来,失败概率是相乘的。假设每层成功率 99%:0.99⁴ ≈ 96%,也就是约 4% 的请求最终会失败。而且失败的方式千奇百怪——第 1 层的失败(模型输出格式坏)和第 4 层的失败(消息重复导致动作做两次)需要完全不同的处理。

这就解释了为什么「加一个更强的模型」解决不了可靠性问题:更强的模型只降低了第 1 层的失败率,第 2–4 层的失败率纹丝不动。生产可靠性必须逐层处理。


三、讲透 Q1:超时 ≠ 失败,所以不能盲目重试

这是生产化篇最经典、也最能区分层次的面试题。

3.1 一个致命的误判

假设 Agent 调了一个「扣款 100 元」的工具,超时了。超时的含义是什么?

超时意味着「我不知道它成功没成功」。请求发出去了,可能是:① 服务端处理完了但响应在回来的路上丢了;② 服务端压根没收到;③ 服务端正在处理中。

如果你把它当成「失败」然后重试,那么情况 ① 就会导致扣款两次。这就是盲目重试的代价。

3.2 正确姿势:幂等键 + 结果查询

超时后的正确做法有两件,缺一不可:

  1. 重试必须携带幂等键(idempotency key)。服务端收到相同的幂等键,就知道「这是同一次请求的重放」,不会重复执行副作用,而是返回第一次的结果。
  2. 优先「查询」而非「重试」。如果工具支持状态查询(「这笔扣款成功了吗」),超时后应该先查,查到已成功就直接用结果,查到未处理才重试。

幂等键的三要素(面试高频):

要素要求反例
调用方生成由发起方生成,而非服务端服务端生成 → 重试时又生成了新的 key,去不了重
业务语义绑定业务含义(如 task_id + step_id)随机 UUID 每次不同 → 永远去不了重
跨重试稳定同一次业务操作的所有重试共用一个 key每次重试都新生成 → 等于没有

3.3 为什么说 exactly-once 是应用层实现的

分布式系统里,传输层只能保证 at-least-once 或 at-most-once,无法保证 exactly-once(消息可能丢、可能重复)。所谓「恰好一次」的效果,是应用层用「at-least-once 投递 + 幂等消费」模拟出来的。

这就是为什么幂等性不是「可选的优化」,而是生产 Agent 的基础设施。任何会产生副作用的工具(扣款、发消息、下单、改状态),都必须幂等。


四、讲透 Q2:风险分级与 Human-in-the-Loop

4.1 不是所有动作都需要人确认

「高风险动作要人工确认」这个原则人人会说,但工程难点在于:怎么定义「高风险」? 如果全都要确认,Agent 就退化成了一台「什么都问你」的机器,没有价值;如果都不确认,一次误删就是事故。

所以需要一个可量化的风险分级, 参考用四个维度打分:

维度含义权重逻辑
不可逆性做了能不能撤销不可逆 +5(最重)
金额涉及的资金规模每 500 元 +1,封顶 3
敏感度是否触及敏感数据/权限敏感 +2
范围影响多少对象每扩展一档 +1,封顶 3

分数决定处理方式 decide_gate:

分数处置例子
< 3自动执行查询订单(1)、退款 299(1)
3 – 8自动执行但记录审计退款 5000(4)
≥ 8强制人工确认删除用户账号(8)、批量重置密码(10)

这个设计的要点是:不可逆动作几乎必然落到强制人工档,因为可见的金额损失能赔,不可逆的数据损失赔不了。

4.2 HITL 异步化

「人工确认」在生产里的最大坑是同步阻塞:Agent 停下等人点确认,会话挂起几分钟,用户体验极差,还占用连接资源。

正确做法是异步化:Agent 发起确认请求后,把任务挂起(checkpoint 落盘)并释放资源,人工确认后通过回调唤醒任务继续。这和第 08 期的「状态外置 + 断点续跑」是同一套机制——HITL 是 checkpoint 的一种应用场景。

HITL 的所有决策都必须可审计:谁在什么时候批准了什么动作、依据是什么。这既是合规要求,也是事后复盘的数据来源。


五、讲透 Q3:分层指标与归因

5.1 为什么不能只看「准确率」

面试官问「你怎么评估生产 Agent」,答「看准确率」会被继续追问:单点指标无法指导排障。一个人看到「成功率 67%」,知道该修哪里吗?不知道。必须把它拆开。

一个端到端请求要穿过好几层,每层有自己的通过率。把各层通过率列出来,算每层的下降(drop),找出下降最大的那一层,那才是瓶颈。

端到端通过率 674/1000 = 67.4%,而各层里下降最大的是「检索命中率」,掉了 10.0%——也就是说,这个系统最大的问题不在生成、不在工具,而在检索没召回。这个结论直接指向了修复方向(见第 10 期:先看召回再看生成)。

面试加分点:分层指标的价值在于「定位」,不在于「打分」。 单点指标告诉你「好不好」,分层指标告诉你「哪里不好」。

5.2 归因顺序

排障的标准顺序:

  1. 看变更:最近有没有上线、改 prompt、换模型、改配置?故障 80% 和变更相关。
  2. 看哪层掉:用分层指标定位是召回、生成、工具还是状态层掉。
  3. 看 trace:定位到层之后,回放具体请求的 trace,看那一步的输入输出。

这三步的前提是你留下了 trace。所以生产 Agent 的 trace 必须记录:输入摘要、模型决策、工具调用(参数 + 结果)、状态变化、延迟、token、成本、最终结果。没有 trace,生产问题基本无解。

5.3 LLM-as-judge 的边界

评估开放式输出(如「回答是否忠实」)很难用规则判定,常用 LLM 当裁判。但有一个铁律:

裁判模型不能和被测模型是同一个。

同模型自我评判会有系统性偏好(它会偏向自己风格的输出、也看不出自己的盲区)。至少要用不同的模型,或者搭配人工抽检验证裁判的可靠性。而且 LLM-as-judge 本身也有成本,要控制抽样比例。


六、深入讨论:成本归因与安全

6.1 成本归因:大头在哪

很多团队觉得「Agent 很贵」但说不清贵在哪。

结论通常反直觉:成本大头是 LLM 的输入 token,而不是输出、也不是工具。因为每一轮循环都要把整个上下文重新喂进去,输入 token 是累加式的。这直接对应第 05 期的「四重成本模型」——输入成本是随轮数平方级增长的。

省钱七招(结合前面各期):

  1. 裁剪上下文(第 05 期):只喂必要的,别把 Top-20 全塞。
  2. 缓存前缀(Prompt Caching):固定前缀命中缓存可大幅降本。
  3. 模型分级:简单步骤用小模型,难判断才上大模型。
  4. 早停:信息收敛就停(第 11 期 Agentic RAG 的软判据)。
  5. 结构化输出:减少往返次数和重试。
  6. 子 Agent 隔离:把冗长中间过程挡在主上下文外(第 11 期)。
  7. 批处理:非实时任务攒批处理。

6.2 三类 Prompt Injection

安全是生产化的另一条腿。Prompt Injection 分三类,防御手段完全不同:

类型攻击面防御
直接注入用户直接在输入里写「忽略前面的指令」输入过滤 + 指令优先级声明
间接注入恶意内容藏在 Agent 读到的文档/网页/邮件里来源隔离 + 数据与指令分离(第 09 期根本论证)
工具注入恶意内容藏在工具返回结果里工具输出按「不可信数据」处理,不提升为指令

关键认知回到第 09 期的根本论证:数据与指令同通道,所以 prompt 层面的防御没有强制力。真正的防御必须是系统级的:把外部内容始终当作「不可信数据」处理,绝不因为它出现在上下文里就赋予它指令权。间接注入是最危险的,因为用户自己都不知道自己「被注入了」——他只是让 Agent 读了一篇文档。

6.3 沙箱选型

如果 Agent 能执行代码(如数据分析 Agent),必须隔离。隔离强度与成本大致是:

进程隔离 < 容器 < 虚拟机 < MicroVM

  • 进程:最轻,但隔离最弱(共享内核),只适合「自己人写的、可信的」代码。
  • 容器:平衡之选,命名空间隔离,启动快,是最常用的默认。
  • 虚拟机:内核级隔离,安全,但重、启动慢。
  • MicroVM(如 Firecracker):兼顾 VM 级隔离和接近容器的启动速度,适合「不可信代码 + 高频启动」。

选型判据:代码的可信程度 × 启动频率。可信代码低频 → 进程;不可信代码高频 → MicroVM。


七、常见错误认识

  • 「超时了就当失败重试」 —— 超时 ≠ 失败。无幂等键的重试会造成重复副作用(示例里扣款两次)。
  • 「加个更强模型就更可靠」 —— 强模型只降第一层失败率,工具/网络/分布式三层照旧。可靠性要逐层解决。
  • 「幂等键服务端生成就行」 —— 必须调用方生成、绑定业务语义、跨重试稳定,否则去不了重。
  • 「高风险动作统统人工确认」 —— 全确认等于没价值;要用可量化的风险分级,只拦真正高危的。
  • 「人工确认同步等用户点」 —— 会话挂起几分钟,体验灾难。必须异步化 + checkpoint。
  • 「评估就看准确率」 —— 单点指标不能定位问题,必须分层 + 看 drop。
  • 「用同一个模型自己评自己」 —— 系统偏好 + 盲区,必须换模型或配人工抽检。
  • 「成本贵就是模型贵」 —— 大头通常是输入 token 的累加,要按阶段归因。
  • 「prompt 里写上『不要被注入』就够了」 —— 数据与指令同通道,prompt 无强制力,防御必须系统级。

八、概念速查

概念一句话
四重叠加概率模型 × 非确定性决策 × 外部工具 × 分布式执行
超时 ≠ 失败超时只说明「结果未知」,不代表操作未执行
幂等键调用方生成的、绑定业务语义的、跨重试稳定的去重标识
exactly-once传输层做不到,靠 at-least-once + 幂等消费在应用层模拟
风险分级按不可逆性/金额/敏感度/范围打分,决定自动/记录/人工
HITL人在环路,必须异步化 + 可审计
分层指标按层拆通过率并看 drop,用于定位而非打分
归因顺序先看变更 → 看哪层掉 → 看 trace
LLM-as-judge用 LLM 评估输出;裁判不能与被测同模型
三类注入直接 / 间接 / 工具注入,间接最危险
数据与指令分离外部内容一律按不可信数据处理,不提升为指令
沙箱选型进程 < 容器 < VM < MicroVM,按可信度 × 频率选
成本归因按阶段拆,通常大头是输入 token(累加式)

九、延伸阅读

站内:

  • 第 05 期《上下文工程》:四重成本模型与上下文裁剪——成本归因的源头。
  • 第 08 期《Planning 与状态》:状态外置、checkpoint、断点续跑——HITL 异步化的基础。
  • 第 09 期《Harness》:数据与指令同通道的根本论证——理解注入防御为何必须系统级。
  • 第 11 期《架构取舍》:跨 Agent 信任边界与结果校验。

站外:

  • 分布式系统经典:幂等性、at-least-once vs exactly-once 投递语义。
  • OWASP LLM Top 10:含 Prompt Injection 的官方分类与缓解建议。
  • AWS / Firecracker MicroVM 文档:沙箱隔离的工程权衡。

十、一句话总结

生产化就是承认 Agent 一定会失败:超时不等于失败所以重试要幂等,高危动作靠风险分级而非一刀切人工,评估靠分层指标定位而非单点打分,成本靠按阶段归因——把不可靠的东西装进可靠的边界里。

AI Agent面试系统设计可靠性

← 返回项目