先约定一个最朴素的说法:本文中的 Agent,是“模型加上外层程序和工具”组成的工作系统。模型负责判断下一步,外层程序负责准备材料、执行真实动作并保存结果,工具则让它能够读文件、改代码和运行测试。

读完这篇,你应该能回答:模型需要知道什么?谁真正执行动作?为什么要重复多轮?一次运行结束后谁接手?谁确认工作已经完成?改动某一层后,又怎样证明系统真的变好?

资料说明:本文结合 OpenAI 与 Anthropic 的官方材料,以及 Codex 的固定源码快照。六类工程职责是学习和设计用的划分,并非每个产品都有六个独立模块。图与教学 JSON 表示建议设计;具体源码行为另行注明。运行结束、检查通过与任务交付是三个不同判断。

一、先沿一项任务建立完整直觉

1.1 跟着 Agent 完成一次任务

假设支付模块有一个测试失败了。我们给 Agent 的任务是:“找出原因,做最小修改,运行支付测试,并留下可审查的结果。”一条带有独立验收的目标路径是:

  1. 系统先把任务要求交给模型。
  2. 系统再准备失败日志、相关代码和项目规则,让模型看到当前事实。
  3. 模型判断应该先读取哪个文件,或者提出运行哪条测试命令。
  4. 外层程序检查这个动作是否存在、参数是否有效、权限是否允许,然后才真正执行。
  5. 文件内容或测试结果返回给模型,成为它判断下一步的新依据。
  6. 模型继续读取、修改和验证,直到完成,或者明确说明为什么不能继续。
  7. 最后由测试、静态检查或 reviewer 独立确认结果,而不是只相信模型说“修好了”。
工具结果返回模型继续判断,运行结束后的候选结果另行接受独立检查
建议设计:工具结果回到模型,形成循环;运行结束只交出候选结果,交付流程还需独立验收。检查失败可以带着新证据重新开始,并非每个运行时都内置这一步。

1.2 给沿途的六类问题命名

AI Engineering 不是先背一组英文名词,而是反复解决六个普通问题。每个问题都来自刚才那条任务路径。

1.2.1 怎样把要求说清楚?

目标是什么、不能改什么、什么结果才算完成、最后怎样报告——把这些默认期待写成清楚的工作说明,就是本系列所说的 Prompt engineering。

1.2.2 这一步应该让模型看到什么?

调查时需要失败日志,修改时需要相关代码,验证时需要当前 diff 和最新测试输出。为模型的下一次判断挑选材料,就是 Context engineering。

1.2.3 模型提出的动作怎样真正发生?

模型说“运行测试”只是一项建议。负责检查参数和权限、隔离执行环境、运行工具、保存日志的外层软件,就是 runtime harness。

1.2.4 为什么 Agent 能做一步再看一步?

外层程序不断让模型判断、执行动作、接收结果,再决定继续或停止。一次运行里的这段反复过程叫 Agent Loop。

1.2.5 一次运行结束后,任务怎样继续?

任务可能因为时间、预算或等待人工而中断。负责保存进度、安排下一次运行、控制重试并防止重复工作的外层流程叫 Outer Loop。

1.2.6 谁来证明系统真的做对了?

测试、规则、模型评审或人工评审组成可重复的“考试”,用外部证据判断结果。这类机制统称 Evals。

如果只想建立入门地图,到这里已经掌握主线。后半篇把同一条故事换成工程设计语言,供需要评审系统边界、API 和故障归因的读者继续深入。

二、再把故事压缩成工程地图

2.1 把六类工作放回各自的时间尺度

把刚才的故事拉远看,会发现这些工作持续的时间并不相同:模型每次只判断一个下一步;读取、修改和测试会在一次运行里往返多轮;同一张任务卡可能经历多次运行;Evals 还要比较多个任务和不同系统版本。

工程上常给这些尺度起名字:一次模型调用叫 inference;一次“模型判断—工具执行—结果返回”叫 tool cycle;从 Agent 启动到完成或中止叫一次 run;跨多个 run 仍然存在的任务卡叫 work item。下面的表只是把已经讲过的六类工作压缩到这些尺度里。

AI Engineering 时间尺度图,从一次推理、一次运行、跨运行到系统生命周期
同一套 agent 系统同时存在四个时间尺度。后出现的工程层不会让前一层消失。
系统部分它具体负责什么主要时间尺度典型失败
Prompt写明模型的角色、目标、限制、指令优先级、输出格式和工具用法。影响一次 inference 的行为意图含糊、约束冲突、输出漂移
Context某次模型调用实际可见、可依据的工作集。每次 inference 重新装配缺失、噪声、过期、位置失衡
Runtime harness在模型之外准备请求、检查并执行工具、记录一次运行。一次 run副作用失控、状态断裂、不可恢复
Agent loop在一次运行内重复“推理—行动—观察”,直到满足退出条件。一次 run(可含多次 inference)过早停止、空转、预算耗尽
Outer loop跨运行执行触发、选工、验证、持久化、重试与升级。多次 run重复劳动、丢状态、重试风暴
Evals把结果质量变成可重复测量的真值与反馈机制。系统生命周期把“说完成了”误当成完成

这张表还有一个更重要的工程结论:它们不是互斥的岗位。一个人可以同时修改 prompt、context policy 和 harness;但评审改动时必须说清楚改的是哪一层,否则“效果变好”无法归因,回归也无法定位。

2.2 每一步由谁决定,结果保存在哪里

再沿七步故事问一次“谁说了算”:用户决定目标;运行时准备材料并检查工具请求;仓库和测试进程保存真实结果;持久化组件保存跨运行的进度;评估器判断检查结果是否通过。一项工作会经过多个负责方,所以模型很重要,却不能单独决定整个任务的状态。

2.2.1 用户目标先变成可验证的 done

“修一下测试”只给了方向,没有说清允许做什么。可以改生产代码还是只能改测试?必须跑哪些命令?网络是否可用?要把哪些结果交给 reviewer?Prompt 把这些要求写进工作说明;eval 再把其中可验证的要求变成机器或人工检查。两者围绕同一个目标,但承担不同工作。

2.2.2 运行时为下一次模型调用挑选材料

OpenAI 的官方 prompt engineering 指南把高层 instructions、消息角色、工具和输入都放在请求设计中讨论;Anthropic 的 context engineering 文章则强调,agent 每一步都会根据当前 context 决定下一次推理要带什么。一个便于思考的请求形状是:

{
  "instructions": "Fix the failing payment test; do not change public APIs.",
  "tools": ["read_file", "search", "apply_patch", "run_tests"],
  "input": [
    { "type": "task", "text": "..." },
    { "type": "repo_facts", "ref": "selected working set" }
  ]
}
形状级示例:Prompt 主要回答“怎样行动”,context 回答“这次调用能看到什么”;真实 API 字段依产品而异。

仓库里可能保存了一万条事实,但只有被选择、序列化并放进当前请求的部分才属于本次 model-visible context。反过来,系统指令本身也占 context window;所以 prompt 是按职责切出的语义层,context 是按可见性切出的物理工作集,它们会重叠,却不能互换。

2.2.3 工具调用只是提案,Harness 才执行副作用

模型输出“运行测试”或一个 tool call,并没有让进程自动发生。Harness 根据具体工具校验参数与权限,选择执行环境,处理超时与取消、限制结果长度、记录事件,再把 observation 送回模型。审批与隔离是分别配置的控制:允许执行不代表没有沙箱,而没有审批提示也不能证明动作始终处于沙箱内。工具和配置决定实际经过哪些检查,第四篇会沿源码展开。

官方用法确实有宽窄差异。OpenAI 在 Harness engineering 一文里把 Codex harness 描述为核心 agent loop 和围绕它的工具/指令环境;Anthropic 在 Building and evaluating trustworthy agents 中更强调 instructions 与 guardrails 组成的 harness,在 Managed agents 又把 session、harness 和 sandbox 分开讨论。本系列采用较窄、方便设计评审的定义:runtime harness 是模型之外、单次运行之内的执行与控制面;loop 是其中驱动状态前进的控制流。

2.3 一次运行与长期任务处在不同层次

OpenAI 对 Codex agent loop 的公开拆解展示了一条单次运行主线:准备输入、调用模型、接收事件、执行工具、回填结果,直到模型完成或运行被中止。Anthropic 的 Building effective agents 也把 agent 概括为模型动态指导自己的过程和工具使用。这里说的是 inner loop。

在 Codex app-server 中,这个边界可以直接看到:turn/start 的成功响应带有 status: "inProgress",表示运行已经受理;它不是测试通过的收据。随后 run_turn 根据模型是否还需继续以及是否有待处理输入决定后续循环;没有这些工作时,还会经过可配置的 Stop hooks。这些条件控制一次 turn 的退出,并不自动证明支付测试和回归已经通过。

turn/start 成功 → inProgress:请求已受理
工具结果返回 → 模型继续判断:还在运行
turn/completed → 读取最终 status / error:本次运行结束
测试、回归、diff 范围检查通过 → 交付流程接受任务结果
前三步对应 Codex 的请求与事件边界;最后一步是支付任务应配置的验收规则。完成通知携带运行状态与错误,并没有通用的“业务目标已验证”字段。

但生产系统还要回答另一组问题:谁触发下一次运行?从队列里选哪项工作?上次执行留下了什么可恢复状态?验证失败后是重试、换策略还是交给人?这组跨运行控制就是本系列所说的 outer loop。

问题Inner / Agent loopOuter loop
输入从哪里来当前任务与 observation事件、计划、队列或人工触发
状态存多久运行中的消息与工具结果;会话记录也可持久化跨 run 的 work item、调度决策及可恢复进度
何时停止完成、错误、预算或人工中止目标达成、重试上限、时间窗或升级
主要风险无限工具循环、错误 observation、过早 final重复触发、状态漂移、无人负责的失败

把两者揉成一个“loop”,常见后果是:inner loop 已经生成漂亮的完成报告,outer loop 却没有独立验证;或者 outer loop 不断把同一失败重新喂给 agent,却没有改变证据、策略或权限。重试只是重复,不等于学习。

三、用这张地图诊断真实系统

3.1 同一个失败,应该改哪一层

一个失败现象可能经过多个组件,但修复应该尽量落在最接近根因的地方。模型一直忽略固定约束,先查 prompt precedence;它不知道刚更新的接口,先查 context selection;它执行了越权命令,先查 harness 的权限检查;它找到正确修复却没有跑测试,查 loop termination;它声称测试通过而实际没有,查 evaluator 读取了什么结果。

失败证据的六类检查位置:规则到 Prompt、事实到 Context、越权到 Harness、提前停止到 Agent Loop、跨运行丢失到 Outer Loop、判分到 Evals
路由图不是说失败只属于一层,而是要求先把修复放在拥有控制权的层。

3.1.1 只修改真正能控制问题的组件

  • 若规则对所有任务都成立,把它放进稳定 instruction,而不是每次检索出来。
  • 若事实会变化,让 context policy 选择最新事实,而不是把快照永久写进 prompt。
  • 若动作可能造成副作用,用权限、沙箱和确定性校验控制,而不是请求模型“千万小心”。
  • 若完成条件可执行,让 loop 或 evaluator 真的执行检查,而不是让模型自我报告。
  • 若失败跨运行累积,把 checkpoint、重试预算和升级责任交给 outer loop。

3.2 回到真实 Coding Agent

这套地图不是悬在具体产品之上。本系列第二至五篇用 Codex 分别检查指令、上下文、工具控制与循环,第六篇用 Symphony 检查跨运行调度,第七篇用开源 Evals 检查样本、判分和记录。它们是不同项目的实现切片,不应拼成一个现成产品。本站其他源码文章还提供更深入的阅读入口:

工程问题可以继续看的本站材料观察重点
一次任务怎样进入模型—工具循环Codex 运行主线、Claude Code 运行主线请求装配、事件流、tool result 回填
模型每轮实际看到什么Codex 上下文、Claude Code 上下文history、投影、压缩与持久化的区别
谁在执行前检查副作用Codex 权限与沙箱、Claude Code 权限提案、校验、审批、执行、observation
长任务怎样恢复Transcript 与恢复、Hermes 运行过程持久化事实与下一轮可见工作集

源码能让抽象概念落地,但不能替代系统级定义。接下来的文章采用同一套资料规则:官方文档说明产品公开承诺的行为;涉及具体实现时,再用开源或公开镜像代码展示程序怎样做到;我们自己的图只解释两者之间的机制。

3.3 修改以后,用同一个任务和同一组检查重跑

定位根因只是开始。假设支付任务因为“测试结果没有进入下一轮 Context”而失败,团队修改了 Context selection。此时不能用一句“召回率更高”宣布完成;要在相同起点重跑任务,确认新测试结果确实进入模型请求、Agent 因此选择了正确下一步,并且其他任务没有退化。

  1. 先执行:固定任务起点、模型、工具、权限和预算,记录旧版结果与 trace。
  2. 再定位:根据日志、工具结果和评估结果判断是哪一部分导致失败,而不是凭直觉改 Prompt。
  3. 只改一个主要组件:例如 Context 选择策略,并写下预期会改变的可观察结果。
  4. 在可比较条件下重跑:检查目标失败是否消失、相邻能力是否回归、成本和延迟是否仍可接受。
  5. 最后才采用:验证通过说明候选可发布;灰度、回滚条件和采用权限仍由交付流程决定。

因此,AI Engineering 的完整动作不是“发现问题 → 加一条规则”,而是执行 → 观察 → 找到负责组件 → 修改 → 重跑 → 只保留通过检查的改进。最后一篇会把这套过程做成可重复的 Evals。

四、复盘:用六个问题重画完整系统

如果你正在决定……先问……主要修改位置
怎样让模型稳定遵循要求目标、限制、指令优先级和输出格式是否明确?Prompt
这一轮该带哪些事实哪些信息相关、最新、可信且值得占预算?Context
动作能不能安全发生谁校验、谁授权、在哪里执行、如何恢复?Harness
一次运行怎样收敛observation 是否可靠,停止与预算条件是什么?Agent loop
多次运行怎样接力触发、checkpoint、验证、重试与人工升级归谁?Outer loop
我们凭什么说系统变好了结果真值、失败分类与回归集在哪里?Evals

所以,这个系列不是宣布 prompt engineering 已经过时,而是把它放回正确位置。下一篇从最靠近模型行为的表面开始:怎样把 Prompt 从一次性话术变成版本化的行为接口。

官方资料