Agent面试详解(上):从模型接口到可恢复的运行时
《Agent面试详解》系列:上篇:运行时与上下文 · 中篇:记忆、工具与并发(待发布) · 下篇:评测、安全与落地(待发布)
最近刷到几段讨论 DeepSeek Agent 岗位和面试的视频。里面反复出现的问题很有代表性:上下文窗口怎么选,多用户并发怎么处理,长期记忆会不会无限膨胀,一个 Agent 跑几十步以后为什么越来越不稳定。
这些问题表面上像面试题,实际已经越过 Prompt 和框架用法,进入运行时、分布式系统、数据治理和工程架构的范围。
DeepSeek 的公开招聘也能印证这个变化。当前职位列表中已经出现 Agent Harness、Agent Infra、Agent 后端和 Code Agent 数据等不同方向。它需要的不是一个“会调模型 API 的人”,而是一支能把模型能力变成稳定产品的完整团队。DeepSeek 官方招聘
这个系列不整理“面试题标准答案”,而是从零设计一套企业级 Agent。假设它支持多租户,可以连续执行 100 步,能访问内部与外部工具,进程崩溃后可以恢复,高风险操作必须审批,所有行为可以审计和评测。
上篇先处理底座:模型、Harness 和环境是什么关系,运行时如何保存状态,长任务为什么会失控,上下文窗口应该怎样管理。
DeepSeek 最近在招什么人
Agent 这个词过去太宽泛。一个聊天框接上搜索 API,也有人叫它 Agent;一个可以操作代码仓库、跑几小时、修改外部状态的系统,也叫 Agent。两者显然不是同一种工程问题。
DeepSeek 当前公开岗位把边界划得更清楚:Agent Harness 团队、Agent Infra、Agent 后端、Code Agent 数据、搜索算法与架构分别承担不同工作。可以用一个简化公式表达这种分工:
Model + Harness = Agent
如果把真实工作环境也纳入系统,公式还要再补一项:
Model + Harness + Environment = Agent System

模型负责理解、推理和生成决策;Harness 决定模型能看到什么、能调用什么、怎样保存状态、失败后如何恢复;Environment 则提供代码仓库、浏览器、数据库、业务 API 和权限边界。离开后两层,模型再强也只能在对话框里给建议。
近期的 Harness Engineering 研究把这层运行时拆成任务定义、上下文选择、工具访问、项目记忆、任务状态、可观测性、失败归因、验证、权限和人工干预等职责。它强调的不是“模型能否生成一个 patch”,而是整个系统能否交付一个可验证、可归因、可维护的修改。AI Harness Engineering
这也是 Agent 面试变硬的原因:考察对象从某个框架的 API,变成了一个完整软件系统。
先把企业级架构画出来
先不要急着讨论 LangGraph、AutoGen 或某个 SDK。框架选型之前,应该先确定系统边界。

一套可以长期运行的企业 Agent,至少需要下面这些模块。
| 模块 | 主要职责 | 不应该负责什么 |
|---|---|---|
| API Gateway | 认证、租户解析、限流、请求入口 | 不编排 Agent 步骤 |
| Run Manager | 创建、去重、取消、恢复和查询 run | 不直接执行工具 |
| State Machine | 驱动 Agent Loop,约束状态迁移 | 不保存全部业务数据 |
| Planner | 拆任务、维护依赖、触发重规划 | 不绕过权限调用工具 |
| Context Builder | 组装每一轮模型输入 | 不把数据库当成聊天记录倾倒 |
| Model Router | 按难度、风险、延迟和成本选模型 | 不决定业务权限 |
| Scheduler | 排队、并发、租约、重试和背压 | 不持有长期数据库事务 |
| Tool Gateway | 发现、校验、授权和执行工具 | 不暴露 Secret 给模型 |
| Sandbox | 隔离 Shell、浏览器和代码执行 | 不承担全局调度 |
| Memory Service | 记忆写入、合并、检索和遗忘 | 不控制 Agent Loop |
| Approval Center | 审核高风险和不可逆操作 | 不替模型补参数 |
| Trace / Eval | 记录轨迹、证据、指标和评测结果 | 不反向污染运行状态 |
模块之间怎么通信
短查询可以走 HTTP 或 gRPC,例如 Run Manager 查询一个 run 的状态;长操作应该进入消息队列,例如一个需要运行十分钟的浏览器任务。状态变化最好发布版本化事件,而不是让所有模块直接读写同一批表。
有三条边界尤其重要:
- Tool Gateway 不应依赖 Planner 的内部对象,只接受稳定的 Tool Call Contract。
- Memory Service 不应知道某个框架的 message class,只存储有版本的领域对象。
- 数据库事务不能跨模型调用、工具调用、文件 I/O 或网络 I/O。

如果多个模块共享 ORM 对象、共享进程内全局状态、共享一条长事务,系统在单机 Demo 里很方便,到了多 Worker、重试和滚动升级时就会迅速失控。
Agent Loop 怎样从 Demo 变成运行时
最小 Agent Loop 通常写成这样:
while not done:
response = model(messages, tools=tools)
if response.tool_call:
result = execute(response.tool_call)
messages.append(result)
else:
done = True
它适合教学,不适合企业运行。至少缺少状态持久化、预算、取消、错误分类、并发控制、审批和完成证据。
更接近真实系统的循环是:
读取 run 与 checkpoint
→ 构造本轮上下文
→ 模型规划下一动作
→ 策略与权限检查
→ 执行工具或等待审批
→ 持久化 observation
→ 更新任务状态
→ 验证完成条件
→ 继续、重试、重规划、暂停或结束
每一步都要能够回答三个问题:
- 这一步的输入来自哪个版本的状态?
- 这一步是否已经产生外部副作用?
- 进程现在崩溃,下一台 Worker 从哪里继续?
“完成”不是模型说了算
模型输出 done,只能表示它认为自己完成了。系统还要运行验证器。例如代码 Agent 必须检查目标测试、相关回归测试和工作区 diff;数据 Agent 必须核对查询范围、行数和口径;客服 Agent 必须确认工单状态确实改变。
完成条件应该是机器可观察的状态:
completion:
required:
- target_tests_passed
- regression_tests_passed
- no_unapproved_side_effects
- final_evidence_attached
max_steps: 100
max_duration_seconds: 7200
这里的 max_steps 是安全上限,不是让 Agent 必须跑满 100 步。真正的结束条件来自证据,预算只负责在异常时切断循环。
跑到五十步为什么容易崩
长任务最先碰到的通常不是模型智力,而是上下文管理。
如果每次工具调用都把原始结果追加到 messages,上下文会持续膨胀。更麻烦的是,Token 变多不只意味着成本变高,还意味着关键约束被大量 observation 淹没、旧错误继续传播、模型开始重复已经做过的工作。
不要只按“最近 N 轮”截断
固定保留最近 10 轮很简单,但不可靠:一次浏览器 DOM 或日志输出可能比十轮普通对话还长,而第 11 轮恰好可能保存了不可丢失的架构决策。
更稳妥的是按 Token 预算组装混合窗口:
固定区:system policy、目标、权限和不可变约束
任务区:当前 plan、未完成步骤、最近 checkpoint、关键决策
动态区:最近交互、本步工具摘要、按需检索的记忆
预留区:模型输出、Tool Schema、下一轮 observation

阈值怎样设
不能等模型 API 返回“context too long”才处理。一个可落地的初始方案是:
| 上下文水位 | 动作 |
|---|---|
| 60%–70% | 开始监控重复内容,工具大结果只保存摘要 |
| 75%–80% | 生成 checkpoint,压缩旧轨迹 |
| 85% | 大型原始结果全部外置,只保留引用和关键事实 |
| 90% | 停止扩展任务,不再接收不可预测的大结果 |
| 接近硬限制 | 从 checkpoint 启动新线程,或交还人工 |
真正的输入预算不是模型标称上下文上限:
可用输入预算 =
上下文上限
- 最大输出预算
- Tool Schema
- 安全预留
- 序列化与格式化开销
建议至少留出 10%–20% 给输出和不可预测增长。对于会返回大结果的浏览器、日志和数据库工具,预留还要更高。阈值不是行业标准,应根据真实轨迹、模型输出长度和工具分布持续校准。
溢出前的兜底顺序
- 删除可以重新获取的原始工具结果。
- 合并重复 observation。
- 把旧步骤压缩成带证据引用的 checkpoint。
- 只加载当前阶段需要的工具定义。
- 将独立工作拆给 Subagent,隔离上下文。
- 冻结旧线程,用结构化状态启动新线程。
- 仍无法压缩时暂停,而不是静默丢掉约束。
DeepSeek 的上下文缓存可以降低相同前缀的延迟和成本,但缓存并不能解决上下文语义污染。它优化的是重复计算,不是信息选择。DeepSeek Context Caching
上篇留下的接口
到这里,Agent 已经有了运行时骨架:每一步受状态机约束,慢调用不占用数据库事务,完成依赖证据,上下文按预算组装,进程可以从 checkpoint 恢复。
但状态能够恢复,不代表长期记忆可信;工具能够调用,也不代表它不会越权或重复产生副作用。中篇继续处理最容易把 Demo 拖垮的三件事:记忆、工具和多用户并发。
**接下来:**中篇将继续讨论记忆、工具与多用户并发,暂未发布。
《Agent面试详解》系列:上篇:运行时与上下文 · 中篇:记忆、工具与并发(待发布) · 下篇:评测、安全与落地(待发布)
微信公众号
欢迎关注「字与码」
如果这篇文章对你有用,也欢迎在微信里继续关注后续更新。
X / Twitter
关注 @ax2_zicode
更即时的技术观察、新文章提醒和一些短想法会发在 X 上。