agent-runtime · git:20260920.a4843f5 · 2026-09-20 · sha256 7bf220de77edfccd

agent-runtime git:20260920.a4843f5A

Immutable. This exact content is served forever at /api/v1/blob/7bf220de77edfccd.

---
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 类工具的替代(当回合拒绝、下回合再问);有首字延迟与整回合延迟两个数