← Back to all posts

9 min readUpdated 12 Aug 2026
AI AgentCodexAgent EngineeringHarnessRuntime+2 more

真正的 AI Agent,不只是调用 LLM:从 OpenAI Codex Harness 看 Agent Engineering

Yap Wei JunSoftware Engineer · Singapore

很多人第一次听到 Build Your Own Agent,会自然想到:

是不是要自己训练一个模型?

其实不是。

当 Agent 真正开始修改代码、操作浏览器、调用 MCP、执行 Shell、管理文件,甚至连续工作几个小时以后,真正困难的问题已经从:

“LLM 聪不聪明?”

变成:

怎样把一个概率性的 LLM,放进一个可控制、可恢复、可验证的工程系统里面?

这就是我越来越关注的 Agent Engineering。


Model 只是 Agent 的其中一层

一个现代 Agent 更接近:

Model
+
Harness
+
Runtime
+
Tools
+
Memory
+
Skills
+
State
+
Security
+
Verification

Model 提供 intelligence。

但真正决定 Agent 能不能长期、可靠工作的是它周围的系统。

OpenAI 对 Codex App Server 的公开介绍也说明,Codex 的 Web、CLI、IDE 等不同体验可以复用同一套 Codex harness;App Server 则提供一个双向协议,让不同客户端驱动相同的 agent loop 和 thread lifecycle。

所以第一个很重要的架构原则是:

UI 不应该等于 Agent。


Harness 到底是什么?

我会把 Agent Harness 理解成:

负责组织 Agent 怎样使用模型能力的控制层。

它通常需要解决:

  • Goal framing
  • Context construction
  • Tool discovery
  • Tool selection
  • Planning / reasoning loop
  • Verification strategy
  • Continue / stop decision
  • Compaction

简单来说:

Model   = Intelligence
Harness = Direction
Runtime = Control + Execution

Harness 可以提出:

“我想读取这个文件。”

或者:

“我想执行这个命令。”

但真正决定有没有权限、怎样执行、失败后怎样恢复,不应该只靠模型。

那是 Runtime 的责任。

我很喜欢用一句话总结这条边界:

Harness proposes. Runtime governs and executes.


Context 越大,不代表 Agent 越聪明

现在很多模型都有很大的 context window。

所以一个很容易出现的误区是:

既然放得下,就全部塞进去。

但 Context 太多会带来新的问题:

  • Token cost 增加
  • Latency 增加
  • Irrelevant information 增加
  • Stale information 增加
  • Conflicting instructions 增加
  • Tool selection 更混乱

所以好的 Context Engineering 不是问:

“最多可以放多少?”

而是问:

“完成当前任务所需的最小充分上下文是什么?”

我把它叫做:

Smallest Sufficient Context

也就是:够用,但不要把 Context Window 当垃圾桶。


Deferred Tools:MCP 时代会越来越重要

假设未来一个 Agent 同时连接:

GitHub MCP
ERP MCP
KB-MCP
Gmail
Calendar
Browser
Finance
Other MCPs

加起来可能有几百个 Tools。

最直接但最差的方法是:

System Prompt
+
400 Tool Schemas
+
Skills
+
Memory
+
Conversation

全部发给模型。

更合理的设计应该是:

Tool Registry
      ↓
Tool Search
      ↓
Relevant Tool Schemas
      ↓
Current Context

例如当前任务只是:

查询 Sales Invoice。

Agent 就不需要同时看到 Gmail、Calendar 或 Finance 的全部 schema。

它先发现自己需要 ERP invoice capability,再按需加载几个相关 Tools。

这个设计真正减少的不只是 Token。

它还减少了:

Agent 当下需要做的选择数量。

Tools 越多,选错 Tool 的概率也会增加。


Skills 也应该有 Context Budget

同样的原则适用于 Skills、Memory 和 Project Rules。

成熟 Agent 未来可能拥有:

Hundreds of skills
Hundreds of tools
Thousands of memories
Many project-specific rules

这些东西不应该每次全部进入 Prompt。

所以 Context 本身应该被当作一种有限资源。

例如可以概念性地分成:

Instructions
User Goal
Relevant Memory
Retrieved Evidence
Relevant Skills
Relevant Tools
Working Context

重点不是每一类固定占多少百分比。

重点是:

每一个进入 Context 的 Token,都应该有理由。


Sub-agent 本质上可以是一种 Async Task

Codex Harness 的另一个有趣设计,是 Sub-agent 可以被创建,然后继续接收 input、等待结果或结束。

如果继续往下抽象,会发现:

  • Sub-agent
  • Background terminal
  • Browser job
  • Research job
  • Long-running MCP call

其实都有类似的生命周期:

queued
running
waiting
completed
failed
cancelled

所以 Runtime 可以统一成一种:

Async Task Handle

而不是每一种能力都重新发明一个 Manager 和状态机。

这会让长期运行的 Agent 系统简单很多。


Browser Agent 不应该每一步都重新开始

如果一个 Agent:

  1. 打开网站
  2. Login
  3. 进入 Dashboard
  4. 找到 Table
  5. 提取资料

最浪费的方法是每一步重新建立 Browser Context。

更好的方式是:

Persistent Execution Session

也就是让:

  • tabs
  • browser state
  • variables
  • execution environment

尽可能在 turns 之间继续存在。

这样模型可以先理解页面结构,再用代码批量操作,而不是每一步都重新截图、重新猜。

这也是我认为 Computer Use 会继续发展的方向:

先理解环境,再编程控制环境。


Sandbox 不是整个 Agent,但它是重要边界

当 Agent 可以:

  • 删除文件
  • 执行 Shell
  • 修改 Git
  • Access Network
  • 上传文件
  • 发 Email

安全就不能靠一句:

“请小心。”

最简单的方法是每一步问用户:

Allow?
Allow?
Allow?
Allow?

很快就会出现 Approval Fatigue。

然后用户反而可能直接打开 Full Access。

比较成熟的设计应该有多层治理:

Tool Call
   ↓
Deterministic Policy
   ↓
Allow / Review / Deny
          ↓
      Risk Evaluation
          ↓
Execute / Human Approval

LLM 可以协助 Risk Review。

但是:

最终 Security Authority 不应该完全属于 LLM。

Runtime 才应该拥有最终权限边界。


“Model 说完成”不等于“任务完成”

这是我认为真正 Agent 和普通 Chatbot 最明显的区别之一。

普通 Chat:

User
 ↓
Model
 ↓
Answer
 ↓
Stop

Agent 应该是:

Goal
 ↓
Context
 ↓
Reason
 ↓
Act
 ↓
Observe
 ↓
Verify
 ↓
Recover or Complete

例如 Goal 是:

Fix the login bug.

真正完成不应该只是:

“我已经修改 login.js。”

而应该有 Evidence:

Implementation changed      ✓
Unit tests passed           ✓
Integration test passed     ✓
Browser verification        ✓
Expected behavior observed  ✓
No critical regression      ✓

最后才进入:

VERIFIED_COMPLETE

所以我的一个核心原则是:

Completion must be evidence-backed.

完成必须有证据。


Compaction 决定 Agent 能不能真正跑很久

如果 Agent 只有五个 turns,context 不是大问题。

但如果它工作:

Turn 1
Turn 2
...
Turn 300

就不能永远把所有旧 transcript 重新发送给模型。

Long-running Agent 必须有 Compaction。

但 Compaction 最好不要只写:

“我们之前修改了一些代码,目前工作正在进行。”

更有价值的是 compact 成:

{
  "goal": "...",
  "completed": [],
  "openTasks": [],
  "decisions": [],
  "constraints": [],
  "artifacts": [],
  "failures": [],
  "approvals": [],
  "currentState": {},
  "nextAction": "...",
  "evidenceRefs": []
}

也就是说:

不只是总结 Conversation。

而是:

Compact Agent State。

原始 Event Log 仍然保留为 Source of Truth。


WebSocket 真正重要的是 Incremental State

随着 inference 越来越快,Agent 的 bottleneck 不一定还在模型。

大量 Tool Calls 会让:

  • API processing
  • network round trips
  • client-side execution

变得越来越明显。

WebSocket 的一个关键价值,是允许长期连接和更增量的状态传输。

但真正值得学习的原则不是:

“所有 Agent 都必须用 WebSocket。”

而是:

不要重复发送系统已经知道的状态。

Transport 可以因环境而不同:

HTTP
SSE
WebSocket
MessageChannel
postMessage

Architecture 不应该被某一种 transport 绑死。


这对 AGRUN 意味着什么?

我自己正在研究的 AGRUN,目标是:

Browser-first、BYOK、Provider-neutral 的 JavaScript Agent Runtime + Harness。

这次研究 Codex Harness 后,我更确定一个边界:

               Intelligence
                    ↓
                 Harness
                    ↓
                  proposes
                    ↓
                 Runtime
                    ↓
              governs + executes
                    ↓
           Browser / MCP / Tools
                    ↓
                  Reality

然后:

Memory  → Harness
Skills  → Harness
Provider→ Harness

Policy  → Runtime
Budget  → Runtime
State   → Runtime
Sandbox → Runtime
Audit   → Runtime

Browser-first 也不等于 Browser-only。

比较合理的原则是:

Browser is the primary environment. Node/server is an optional capability extension.

例如 Browser 本身可以处理:

  • UI
  • IndexedDB
  • Web Worker
  • HTTP MCP
  • Web APIs
  • Local state

只有真正需要:

  • Shell
  • Full filesystem
  • stdio MCP
  • Local processes
  • Playwright

才连接 optional Node Companion。


我现在怎样理解 Harness Engineering?

最简单的 Agent Loop 可能只是:

while (true) {
  const response = await llm();
  await executeTool(response.tool);
}

但真正成熟的 Harness 应该管理:

Goal
 ↓
Frame
 ↓
Context
 ↓
Reason
 ↓
Plan
 ↓
Action
 ↓
Observe
 ↓
Verify
 ↓
Recover
 ↓
Continue / Complete

我会把它进一步理解成:

Controlled Causal Loop Engineering

中文可以叫:

可控因果闭环工程。

对于每一个 Action X,系统都应该尽可能知道:

Action X
   ↓
Expected Result Y

然后继续判断:

  • Y 有没有真的发生?
  • Evidence 是什么?
  • 没发生的原因是什么?
  • 应该 Retry、Recover、Rollback,还是 Stop?

这才开始接近一个真正值得长期信任的 Agent。


最后的思考

这次研究 Codex Harness 后,我最大的 takeaway 不是:

“Codex 有很多厉害功能。”

而是:

随着 Model 越来越强,Agent Engineering 的竞争正在从单纯的 Model Capability,移动到 Model 周围的 System Capability。

未来优秀 Agent 的能力,很大一部分会来自:

  • Context Engineering
  • Tool Discovery
  • Skills
  • Memory
  • Runtime
  • Sandbox
  • State Management
  • Long-running Execution
  • Verification
  • Recovery
  • Observability

所以如果今天有人问我:

“Develop your own Agent,是不是自己训练一个 LLM?”

我的答案是:

不是。

你完全可以使用别人训练好的 Model。

真正需要自己建立的是:

一个能够把 Model Intelligence 转化成 Reliable Action 的系统。

Model 给 Intelligence。

Harness 给 Direction。

Runtime 给 Control。

Tools 连接 Reality。

Verification 告诉 Agent:

事情到底有没有真的完成。

这才是我认为真正值得研究的 Agent Engineering。


Sources & Further Reading

Note: Codex and Responses API capabilities evolve quickly. This article reflects publicly available information reviewed on 12 August 2026, together with my own architectural interpretation.

← Back to all posts