---
name: agent-runtime
description: Agent 运行时深挖：循环与事件、工具协议与沙箱、子 agent、预算终止、恢复、输出契约。
keywords: [agent runtime, harness, agent loop, 事件溯源, 工具权限, 沙箱, 子 agent, durable execution, checkpoint, structured output, tool_choice, trace]
layer: detail
domains: [ai-agent, ai-infra]
---

## 面试官在意什么

这本是 ai-agent 的运行时那一层：模型外面那圈代码怎么写。面试官要的不是框架名，而是候选人自己写过或改过循环之后留下的判断：状态存哪、预算超了怎么办、工具报错怎么回给模型、跑一半停了怎么续、换个服务商结构化输出为什么就坏。追问的方式是给一个故障现象让候选人定位到层：死循环是终止条件还是工具结果的问题，上下文爆是历史没裁还是工具结果太长，重放不一致是状态存了两份还是事件缺字段。能把 Claude Code、Codex、Manus 这类公开资料里的做法和自己的取舍对上的，算实。

## 项目 / 实习怎么深挖

简历上出现下面这类经历时从哪里切、追什么。追到候选人能说出机制、数字的来源与一次真实的故障或取舍才算实；只有框架名与结论、说不出自己那一段的，记为危险信号。通用的追问方法见 project-deep-dive。

- 简历出现自研 agent 循环 / 运行时 → 追一步的定义、状态存在哪、预算超了发生什么、能不能从某一步续跑、最长一次跑了多少步、每步的 token 与缓存命中
- 简历出现工具权限 / 沙箱 → 追分了几档、谁批准、误调过什么、执行类工具隔离了什么边界、超时怎么处理
- 简历出现多 agent / 子 agent → 追为什么拆、子 agent 的上下文与预算、产出怎么回主流程、协作失败怎么定位
- 简历出现 checkpoint / 断点续跑 → 追存了什么、哪些不能重跑、写操作的幂等键、一次真实的恢复
- 简历出现 trace / 回放 / 调试工具 → 追记了哪些事件、按步回放怎么做、靠它定位过什么故障
- 简历出现多服务商 / 结构化输出 → 追哪个服务商坏过、修在哪一层、收敛与抢救的顺序

## 常见失守与危险信号

- 运行时循环与状态：循环全交给框架的 maxIterations，说不出超限后发生了什么；状态既存消息列表又存事件，两边对不上
- 工具协议、权限分级与沙箱：工具越多越强；敏感工具没有确认或 dry-run；工具报错把栈信息原样喂回模型；沙箱只说"用 Docker"
- 子 agent 与编排：为了"多"而多 agent；子 agent 与主 agent 共享同一份无限增长的上下文；说不出协作失败时看哪个 agent 的轨迹
- 中断恢复与持久化：说"重跑一遍就行"；把重试和续跑混为一谈；不知道写操作要幂等键
- 事件日志与轨迹可观测：只记最终输出不记步；trace 里没有每步的 token、缓存、耗时；定位故障靠重跑
- 预算与终止条件：只有步数上限；预算超了直接抛错给用户；没想过给模型一步"不许调工具直接结论"
- 结构化输出契约与多服务商：只会"加一句请输出 JSON"；不知道 schema 是否随请求下发；把服务商差异修在每个 agent 里
- 流式输出与多步循环：把流式和多步混在一起说不清哪一步的文本给了用户；流式时确认类工具没法挂起也没有替代方案

## 常考主题清单

只列名字、阶梯与答实的标志，作"问到哪一层算实"的参考；问哪些、问几道由这份 JD 与这份简历定，不是配额。

### 运行时循环与状态
- 阶梯：一次 agent 执行由哪几段组成（收上下文 → 调模型 → 执行工具 → 观察 → 再调） → 循环状态存在哪、为什么"事件日志是唯一事实源、其余都是投影"比直接存消息列表好 → 预算（步数、token、时长、费用）超了该抛错还是给模型一步结论，各自对用户体验的影响 → 流式输出与自己掌握循环的冲突：第一步要往外吐字时循环还能不能自己控
- 答实的标志：能说出事件 → 消息的投影关系；预算超了先写事件再给一步"不许调工具直接结论"；知道 SDK 的 stopWhen 和自己写循环各能控什么；讲得出一次"重放即恢复"的实际用法

### 工具协议、权限分级与沙箱
- 阶梯：工具的描述与入参 schema 怎么写才让模型少选错 → 读 / 写 / 需确认三档各怎么执行、审计记什么 → 执行类工具（跑代码、改文件、发请求）为什么要隔离，隔离的三条边界（进程、文件系统、网络）与超时 → 确认机制在流式对话里怎么做：挂起等确认与"这一回合不能等"的取舍
- 答实的标志：按任务动态挂载工具子集；写操作强制确认或 dry-run 并有调用日志可回放；知道未知工具、执行抛错、hook 拒绝都应变成"失败的工具结果"而不是让循环崩掉

### 子 agent 与编排
- 阶梯：什么时候需要拆子 agent（独立上下文、独立预算、独立权限），什么时候只是一个带工具的 agent 就够 → 子 agent 的产出怎么回到主流程（只写事件 / 回传摘要 / 共享文件）→ 多 agent 协作失败时怎么定位是哪一个出错 → 编排的三种控制哲学：模型驱动、代码驱动、显式交接，各自适合什么任务
- 答实的标志：拆分理由落在上下文与预算上；子 agent 只有只读工具、只写事件；有每场 / 每任务的步数上限；能举例说明"评论员的意见为什么不进主 agent 的输入"

### 中断恢复与持久化
- 阶梯：长任务为什么要能停能续（超时、部署、人工确认）→ checkpoint 存什么：消息列表 vs 事件日志 vs 外置快照 → 续跑时哪些东西不能重跑（已执行的写操作）、哪些要补跑（没结果的工具调用）→ 幂等：同一条用户消息重复提交、同一回合序号只落一次
- 答实的标志：从事件重放出状态；只补跑没结果的调用；写操作带幂等键或先记"要做"再记"做了"；能说出客户端 id 去重的实际做法

### 事件日志与轨迹可观测
- 阶梯：一次执行要记哪些事件（模型调用、工具调用与结果、退回、预算、挂起）→ 事件到消息、状态、指标三种投影各怎么算 → 一个故障从 trace 里怎么定位到步：哪一步的输入让模型选错了工具、哪一步上下文突然变长 → 轨迹数据的保留、脱敏与成本；每步记多少才够回放又不至于存爆
- 答实的标志：能画出事件 → 投影的关系；每步有 token、缓存命中、耗时、成本四个数；讲得出一次靠 trace 定位到根因的故障；知道记录原文与记录摘要的取舍

### 预算与终止条件
- 阶梯：为什么每个循环都要有步数、token、时长、费用四类预算 → 预算超了的三种处理（抛错、给模型一步结论、降级到更便宜的路径）各对用户体验的影响 → 死循环怎么防：重复调用检测、同参数去重、工具结果的"没有新信息"信号 → 预算怎么按任务类型与用户等级配，超预算率怎么当指标看
- 答实的标志：四类预算都能说出默认值与依据；有重复调用检测；超预算先写事件再收尾；能说出预算触顶率与任务成功率的关系

### 结构化输出契约与多服务商
- 阶梯：为什么换一个服务商结构化输出就坏（有的按 schema 约束、有的只保证是 JSON、有的不支持指定工具）→ 收敛、修补、抢救三层各做什么，顺序为什么这样 → 推理型模型的思考 token 算在输出上限里怎么统一处理；JSON 模式下不调工具或只吐空白怎么定位 → 契约放在工具入参上（模型必须调某个工具）与放在最终对象上的差别，各适合什么
- 答实的标志：能说出按 JSON Schema 收敛类型 → 带校验错误让模型改一次 → 抢救的顺序；输出上限加推理余量；用探针脚本隔离服务商差异；修在统一的调用入口而不是每个 agent 里

### 流式输出与多步循环
- 阶梯：用户要边看边出字，循环要多步调工具，两者为什么冲突 → 第一步就往外吐文本时，循环还能不能决定再调一次工具；流式时需要确认的工具怎么办 → 非流式一回合 + 前端打字机、只流最后一步、流事件而不是流文本，三种方案的取舍 → 流式对结构化输出与缓存的影响
- 答实的标志：能说出自己产品选了哪种方案与原因；知道流式时 confirm 类工具的替代（当回合拒绝、下回合再问）；有首字延迟与整回合延迟两个数
