ARTICLE / AI Agent · Context Engineering

Agent 的真正核心:Context Engineering

同一个模型放进不同的 Agent 系统,实际表现可能相差很大——差异往往来自 Model 之外的 Harness。本文用 Agent = Model + Harness 的视角解释模型 API 的无状态本质,说明为什么 build_context() 才是 Agent Loop 里最难的部分,以及 Context Engineering 与 Prompt Engineering 的边界。

发布
阅读
约 5 分钟
作者
Nicolas Leigh
READS1次阅读

过去一年,AI Agent 成为了大模型应用中最热门的方向之一。

很多人在讨论 Agent 时,第一反应往往是:

Agent 强不强,主要取决于底层模型够不够强。

比如换成能力更强的 GPT、Claude 或 Gemini,再给模型接上搜索、文件系统、Shell、数据库等工具,似乎就能得到一个强大的 Agent。

但真正开始开发 Agent 之后,会很快发现一个现象:

同一个模型,放在不同 Agent 系统里,实际表现可能相差非常大。

有的 Agent 能连续执行几十步任务,始终知道自己正在做什么;有的 Agent 几轮之后就开始遗忘约束、重复调用工具,甚至陷入循环。

造成这种差异的关键,往往已经不只是 Model,而是 Model 外面的那一整套运行系统——Agent Harness

重新理解 Agent

可以用一个非常简洁的公式理解现代 AI Agent:

Agent = Model + Harness

Model 负责"思考",包含 Reasoning(推理)、Planning(规划)和 Decision Making(决策)三个核心能力。

Harness 负责把模型的思考真正变成一个可以持续运行的系统。它要处理 Context Management、Tool Interface、Agent Loop、State Management、Memory、Permission、Validation、Error Recovery 这一连串问题。

以一个 Coding Agent 为例。模型本身可以判断:

我需要先查看 login_service.go

但真正读取文件的不是模型,是 Harness:

  1. 接收模型输出的 Tool Call;
  2. 调用 read_file
  3. 获取文件内容;
  4. 把结果加入下一轮 Context;
  5. 再次调用模型。

Model 提供的是智能,而 Harness 负责如何组织、约束和释放这种智能

而 Context Engineering,就是 Harness Engineering 中最重要的问题之一。

模型其实是"无状态"的

理解 Context Engineering,首先要认识一个事实:大模型 API 本身基本是无状态的。

假设第一次请求是:

帮我分析这个项目的架构。

模型完成分析之后,下一次如果只发送:

那数据库这一层有什么问题?

模型并不会天然知道"这个项目"指什么。

所谓模型"记住了之前的对话",通常只是 Harness 把历史重新发送给模型:

System: You are a coding assistant.
User: 帮我分析这个项目的架构。
Assistant: 这个项目主要分为 API、Service、Repository...
User: 那数据库这一层有什么问题?

也就是说,每一次模型调用,本质上都是一次重新推理:

System Prompt
+ Conversation History
+ Tool Results
+ Current State
+ User Request
        ↓
      Model

模型并不是一直"在线"维护状态。它更像是每一轮都会重新醒来的智能系统

Harness 的任务,就是在它重新醒来时,把正确的信息重新交给它。

一个不断"失忆"的聪明员工

可以把模型想象成一个能力很强的新员工:阅读速度很快,推理能力很强,能理解代码和文档,能制定下一步行动。

但有一个问题:每完成一步工作,他都会失去之前的工作记忆。

下一次开始工作前,你必须重新告诉他:项目背景、用户要求、已经完成什么、刚刚发生了什么、现在还剩什么、有哪些工具可以使用。

于是 Agent 开发中的核心问题就出现了——下一轮应该给模型看什么?

给得太少,模型缺乏信息。给得太多,大量无关内容会干扰模型。关键约束被删掉,Agent 就可能跑偏。之前的失败原因没有保留,它就可能重新走一次错误路线。

所以很多时候,Agent 开发真正困难的并不是 How to call LLM?,而是 How to build the right context for the next LLM call?

这就是 Context Engineering。

一个 Agent Loop 的核心

一个极简 Agent 可以写成:

while True:
    context = build_context()

    response = model(context)

    if response.has_tool_calls():
        results = execute_tools(response.tool_calls)
        update_state(results)
    else:
        return response

代码并不复杂。真正困难的地方其实是 build_context()

它需要决定:

  • System Prompt 放什么?
  • 历史消息保留多少?
  • 哪些 Tool Result 仍然有价值?
  • 哪些内容应该删除?
  • 哪些内容应该压缩?
  • 当前还有哪些 TODO?
  • 哪些知识应该按需加载?
  • 哪些状态必须显式告诉模型?

这也是为什么一个成熟 Agent 的 Harness,往往会有大量代码围绕 Context Management 展开。

Context 为什么会决定 Agent 的能力?

假设一个 Coding Agent 接到任务:

修复登录接口的并发问题。

要求:

  • 不要修改数据库 Schema
  • 修改完成后运行测试

经过十几轮操作以后,如果模型仍然可以看到:

Goal:
修复登录接口并发问题

Constraints:
- 不修改数据库 Schema

Progress:
- 已定位问题
- 已修改 login_service.go
- 尚未运行测试

它通常可以继续稳定完成任务。

但如果上下文被粗暴截断,只剩一句:

刚刚修改了 login_service.go

模型可能已经不知道:为什么修改这个文件、数据库不能改、最后还要运行测试。

模型本身没有发生任何变化,但 Agent 的实际能力已经明显下降。

所以很多看起来像"模型变笨了"的问题,其实可能是Context 丢失了

Prompt 和 Context 不是一回事

Prompt Engineering 更关注应该怎样向模型表达一个指令,比如:

你是一名高级 Go 工程师,请分析下面代码中的并发问题。

Context Engineering 关注的范围更大:这一轮模型到底应该看到哪些信息?

这些信息包括 System Prompt、Tool Definitions、User Messages、Assistant Messages、Tool Results、Memory、Skills、Environment State、Current Task Status 等。

因此:Prompt 是 Context 的一部分,但 Context 不等于 Prompt。

当任务从"一问一答"变成几十步甚至几百步的 Agent Workflow 后,Context Engineering 的重要性就会迅速上升。

真正应该优化的是什么?

成熟的 Agent 并不会简单地把所有已知信息全部塞给模型。因为 Context Window 再大也是有限的,而且信息越多,不代表效果越好。

真正应该优化的是单位 Token 中有效信息的密度

模型这一轮需要什么,就给它什么。不需要的内容就删除、压缩、延迟加载,或者隔离到 Sub-Agent 去处理。

这也自然引出了后面一系列 Agent Engineering 问题:

  • 历史对话太长怎么办?
  • Tool Result 是否应该完整保留?
  • System Prompt 为什么最好保持稳定?
  • 如何让 Agent 始终知道当前 TODO?
  • Skill 应该什么时候加载?
  • 什么时候压缩 Context?
  • 什么时候应该让 Sub-Agent 执行任务?

这些问题看似分别属于 Memory、Prompt、Tool、Skill、Sub-Agent,但从更高的层面来看,它们其实都在解决一个共同问题:如何控制哪些信息进入模型的上下文

结语

如果只把 AI Agent 理解成 Model + Tools,很容易低估 Agent Engineering 真正的复杂度。

更合适的理解是 Agent = Model + Harness

Model 提供智能。Harness 负责工具、状态、执行循环、安全、验证,以及最重要的 Context Management。

因此,在开发 Agent 时,一个值得反复思考的问题并不只是"要不要换一个更强的模型",还应该问:

下一轮调用模型时,它到底应该看到什么?

这就是 Context Engineering 的起点。

参考资料