深度拆解 Agent 引擎:从 Prompt 到 Harness Engineering,揭秘 AI 操作系统的工程本质
AI 时代技术名词层出不穷?本文带你从零构建 Agent,深度拆解 Prompt、Context 到 Harness 的工程演进逻辑,看透智能体时代的“操作系统”雏形。
原文链接:AI 小老六
在 AI 领域,每隔一段时间总会涌现出一些新名词:Prompt Engineering、ReAct、Memory、Function Calling、MCP、Skill、Harness Engineering 等等。很多开发者面对层出不穷的概念,难免会产生技术焦虑:“旧的还没学完,新的又来了,它们到底是在取代还是在补充?”
其实,如果我们抛开这些光鲜的词汇,从零开始亲手构建一个 **Agent(智能体)**,就会发现它们的出现有着极强的内在逻辑和必然性。整个 Agent 工程的演进,本质上是在回答三个递进的问题:怎么和 LLM(大语言模型) 说话?让 LLM 看到什么?以及如何保障 LLM 稳定完成任务?
第一层:怎么和 LLM 说话(Prompt Engineering)

图:通过角色设定与指令设计,为 LLM 赋予特定能力
要利用大模型的能力,最基础的方式就是调用 API 发起一次网络请求。但在实际业务场景中(比如构建一个视频创作助手),单纯的闲聊毫无意义。我们需要为模型设定身份边界和能力范围,这正是 System Prompt 的用武之地。
通过在对话上下文中注入特定的角色设定,模型就能从一个“通用知识库”变成一个“专业助手”。这其实就是 Prompt Engineering 的核心工作——它解决的是“如何用自然语言为 LLM 编程”的问题。从角色设定、指令设计到输出格式约束,高质量的 Prompt 是 Agent 能否胜任特定场景的基石。
第二层:让 LLM 看到什么(Context Engineering)
仅仅能听懂话的 Agent 是没有记忆和行动能力的。为了让 Agent 能够持续产出并与外部世界交互,我们需要管理并扩展它的上下文,这就是 Context Engineering。
赋予长期与短期记忆(Memory)
大模型的 API 接口是无状态的。要实现多轮对话,必须在工程层面对历史消息进行缓存和管理,并在每次请求时将相关上下文打包发给模型。
在工程实现中,这不仅是简单地将所有历史对话塞进请求里。随着对话的深入,我们需要考虑上下文窗口的限制,这就衍生出了短期记忆与长期记忆的划分,以及更复杂的上下文检索策略。
为 LLM 安装手脚(Tool)

图:为 Agent 配备工具,使其能够与外部世界交互
为了让 Agent 执行实际任务(如读写文件、执行脚本),我们需要为其配备“工具”。目前主流的做法是遵循 Function Calling 范式。
首先,在系统中定义好可用工具的 Schema:
```json
[
{
"name": "file_write",
"description": "向指定路径写入文件内容",
"parameters": {
"type": "object",
"properties": {
"file": { "type": "string", "description": "目标文件路径" },
"content": { "type": "string", "description": "要写入的内容" }
},
"required": ["file", "content"]
}
}
]
在调用大模型时,我们将这些工具定义一并传入。LLM 会自主判断是否需要调用某个工具,并返回标准的工具调用指令。随后,我们在工程代码中解析这些指令,执行对应的本地逻辑,再将执行结果反馈给 LLM。
自主循环思考(ReAct)
当 Agent 拥有了工具后,完成复杂任务往往需要多次试错和交互。这种“思考(Reason)- 行动(Act)- 观察 - 再思考”的交替循环,被称为 ReAct 模式。

在代码层面,这表现为一个不断与 LLM 交互的循环结构,直到 LLM 判断任务已完成不再输出 Tool Call 为止:
```go
// 伪代码:ReAct 核心执行循环
for continueThinking {
respMessage := CallLLM(messages, tools)
toolCalls := respMessage.ToolCalls
if len(toolCalls) > 0 {
for _, call := range toolCalls {
// 执行本地工具逻辑
result := executeTool(call)
// 将结果拼接入上下文,继续下一轮思考
messages = append(messages, result)
}
} else {
// 无需调用工具,任务完成
continueThinking = false
}
}
应对 Prompt 膨胀(Skill)
随着可用工具的增多,如果我们把所有工具的调用逻辑和使用规范都写在 System Prompt 里,会导致上下文严重膨胀,模型也极易出现“幻觉”或意图冲突。
为了解决这个问题,Skill 机制应运而生。它类似于分布式的 System Prompt:每个 Skill 都是一个独立的单元,包含特定场景的详细指令甚至工作流。
在执行时,业界通常有三种做法:
- 共享上下文:直接将 Skill 内容塞入主上下文,容易导致污染。
- 隔离推理,部分共享:拉起新实例独立推理 Skill,只将结果返回给主 Agent。
- 完全隔离推理:环境完全干净,Skill 无法访问主对话背景。
在多数复杂场景中,我们倾向于第二种方案。主 Agent 决定调用某个 Skill 时,系统会拉起一个独立的推理环境,仅加载该 Skill 的专属 Prompt 和必要的历史上下文,执行完毕后再将最终结果返回给主 Agent。
```go
// 伪代码:Skill 隔离执行逻辑
func ExecuteSkill(skillName string, history []Message) string {
// 仅加载当前 Skill 的专属配置
skillPrompt := loadSkillConfig(skillName)
messages := append(history, skillPrompt)
// 在独立沙箱中进行 ReAct 推理
return runReActLoop(messages)
}
这大大降低了主 Agent 的心智负担,也让复杂任务的编排变得更加模块化。
第三层:保障稳定执行(Harness Engineering)
当我们把 Agent 投入到真实的生产环境中时,新的问题出现了:如何防止它执行高危命令(比如 rm -rf /)?如何保证在遇到网络抖动或工具报错时能够自动重试和恢复?
这就引出了 Harness Engineering。它不是某项单一技术,而是指在 LLM 之外,所有为了保障 Agent 能够稳定、安全完成任务的系统性工程工作。
比如,针对执行环境的安全性,我们需要引入 Sandbox(沙箱) 机制,通过目录隔离或容器化技术,限制 Agent 对文件系统、网络和底层调用的访问权限。
图:通过沙箱隔离等机制保障 Agent 的安全与稳定执行
```go
// 伪代码:简单的路径沙箱隔离
func executeInSandbox(cmd string, rootPath string) Result {
// 校验命令执行路径是否在允许的工作区内
if !isPathAllowed(cmd.TargetDir, rootPath) {
return Error("Permission Denied: 越权访问")
}
return runCommand(cmd)
}
工程定义的演进脉络
我们可以用一个生活化的例子来串联这几个阶段:
| 遇到的问题 | 解决方案示例 | 对应的工程阶段 |
|---|---|---|
| 如何与一个脾气古怪的老教授有效对话? | 设定角色:让他扮演一位大厨,分享煮泡面的步骤。 | Prompt Engineering |
| 教授给的步骤需要煤气灶,但我家只有电磁炉。 | 提供上下文:递上一份“我家厨房物资清单”,让他因地制宜出方案。 | Context Engineering |
| 方案没问题,但我操作时忘了按电磁炉开关。 | 保障执行:提供一份防呆的 To-Do List,打勾确认每一步,并确保电磁炉不会漏电。 | Harness Engineering |
这些名词的演进,绝不是单纯的新技术替代旧技术,而是随着应用场景的深入,我们对 Agent 工程边界的不断扩展和重新定义。
结语:寻找 Agent 时代的“操作系统”
如果我们将眼光放得更长远一些,当前的 Agent 发展历程与计算机操作系统的演进惊人地相似。

图:Agent 工程向着类似操作系统的架构演进
| 计算机体系 | Agent 体系 |
|---|---|
| 硬件资源 (CPU, 内存等) | LLM 算力资源 |
| 操作系统 (OS) | Agent 工程 |
| 应用软件 (Application) | 工具 (Tool) / 技能 (Skill) / 工作流 (Workflow) |
将 Agent 的现状与成熟的操作系统进行对比,从而发现当前 Agent 工程尚存的差距,也许 Agent 工程的下一步就在其中。
| 操作系统核心模块 | Agent 工程现状 |
|---|---|
| 底层资源调度 (CPU 调度) | 对 LLM 的调用缺乏标准的调度方案 |
| 内存管理 | Memory 管理 (上下文管理) |
| 进程模型 | 多任务、多会话之间缺乏标准的隔离与协作方案 |
| 系统调用 (Syscall) | 工具调用 (Tool Call) |
| 权限系统 | 仅有局部的权限管理 (Sandbox) |
| 文件系统 | 文件系统访问 |
| 中断机制 | 缺乏系统性的中断、重试与恢复机制 |
| 可观测性 | 缺乏系统性的日志、追踪与调试方案 |
LLM 提供了底层的“算力”,而 Agent 工程正是为了将这种“概率性智能”转化为“确定性的程序交付”。未来的 Agent 工程,必然会向着包含标准资源调度、进程隔离、系统中断与恢复机制的完整 Agent Runtime 演进。
在这个将智能落地为生产力的过程中,我们还会听到更多既熟悉又陌生的“概念词”,但这正是技术浪潮向前推进的真实回响。只要把握住工程保障的本质,就能在纷繁的概念中看清未来的方向。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)