0基础学会Agent Harness工程(前置知识一):从AI、大模型到Agent
0基础学会Agent Harness工程(前置知识一):从AI、大模型到Agent
本篇对应的官方文档
- Anthropic:Building effective agents:用于区分由代码预定路径的 Workflow 与由模型动态决定过程的 Agent,并说明何时不必增加 Agent 复杂度。
- OpenAI Agents SDK:Agents:用于观察一个具体 SDK 如何把 Agent 落成 LLM、instructions、tools 与运行行为的组合。
- Google Cloud:What are AI agents?:用于补充 Agent 与工具、自治、任务自动化的关系,以及当前应用仍然存在的限制。
- Learn Claude Code:用于确定本系列的教学主线——模型负责判断,Harness 为模型提供工具、观察、行动接口和权限边界。
本篇主要内容
这是整个 Agent Harness 系列的第一块地基。我们先把 AI、Machine Learning、Deep Learning、Generative AI 和 LLM 放回各自的位置,再沿一次模型调用观察它能生成什么、不能直接改变什么。随后用同一个“整理本地 Python 项目”任务,对照聊天助手、固定 Workflow 和模型驱动 Agent 的控制权、状态来源与执行责任。最后给出本课程采用的 Agent 工程口径,并说明后续为什么不从框架 API 开始,而要从最小 Harness 逐层搭建。下篇预告
下一篇承接“模型只能产生下一步输出”这个边界,解释 ReAct 为什么需要 Action 和 Observation,并把单次调用扩展成能够持续获得环境反馈的 Agent Loop。
一、先分清 AI 大模型与 Agent
如果你是第一次系统学习智能体,很可能已经听过一串相互挤在一起的词:人工智能、机器学习、深度学习、生成式 AI、大模型、聊天机器人、Agent、Agentic System。它们经常出现在同一场发布会、同一个产品页面,甚至同一句宣传语里,于是很容易形成一个模糊印象:这些词说的似乎都是“会聊天、会写代码的那个东西”。
问题恰恰从这里开始。后面20篇正式博文的中会出现模型、工具、消息、循环、权限、记忆和多智能体。如果一开始把“大模型”和“Agent”看成同一个对象,你就会不断遇到无法解释的问题:既然模型已经是 Agent,为什么还要写 Loop?既然模型会生成命令,为什么还要实现 Bash handler?既然模型学过大量知识,为什么还要读取当前目录?这些问题不是代码细节,而是对象边界没有分清。
我们先建立一张适合入门的坐标图,刚开始时我们可以先用下面这组关系定位:
AI 是更大的目标领域;
Machine Learning 和 Deep Learning 描述重要的方法路线;
Generative AI 描述“生成新内容”的能力类别;
LLM 是面向语言与符号序列的一类生成模型;
Agent 则是围绕目标、状态、行动和反馈组织起来的系统。
这些对象不能只按“谁更大”排列,还要看它们分别描述目标领域、实现方法、生成能力还是完整系统。下面的关系地图把 LLM 放在方法与能力的交汇处,再用虚线表示它只是 Agent 系统的组成部分。
更专业的解释:
Artificial Intelligence(AI) 是最宽的目标领域。只要系统表现出某种通常需要人类智能的能力,例如识别图像、理解语言、规划路线、进行预测,都可以落在 AI 这个大范围里。AI 不等于聊天,也不等于大模型。早期专家系统、搜索算法、规则引擎同样属于 AI 的历史与方法谱系。
Machine Learning(机器学习) 是一类让系统从数据中学习规律的方法,而不是由开发者把每条规则都手工写死。垃圾邮件分类、商品推荐和价格预测都可以使用机器学习,但这些系统未必生成新内容,也未必使用神经网络。
Deep Learning(深度学习) 是机器学习中的一类方法,核心工具是多层神经网络。图像识别、语音识别和现代语言模型的发展都与深度学习密切相关。对本系列来说,不需要先学习反向传播或网络结构;只需知道大语言模型建立在深度学习路线之上,但“深度学习系统”远不止大语言模型。
Generative AI(生成式 AI) 从能力表现上描述能够生成新内容的系统。它可以生成文本、图片、音频、视频或代码。这里换了一个观察维度:Machine Learning、Deep Learning 更偏向实现方法,Generative AI 更偏向系统能产出什么。因此,把所有词画成一条完全严格的包含链会造成误导。
Large Language Model(LLM,大语言模型) 则是面向语言序列训练的大规模模型。它接收上下文,预测并生成后续内容。现代 LLM 不只会写自然语言,还能生成代码、JSON、工具调用参数和多模态相关输出。但无论输出形式怎样变化,它首先仍是一个模型:根据输入上下文计算输出,而不是天然拥有你的文件系统、终端和业务数据库。

地图中的实线表达学习上的来源关系,虚线则提醒我们:从 LLM 到 Agent 还缺少运行环境。只要保留“维度不同”这个判断,后面遇到新术语时就不会被一条僵硬的包含链困住。
这不是一条可以用圆圈大小证明的数学集合定理,而是一张“遇到术语时先问它在描述什么”的学习地图。一个词可能描述研究领域,一个词描述训练方法,一个词描述输出能力,另一个词描述完整系统的控制方式。维度不同,不能只靠名字判断上下级。
还要特别区分 Model 和 Application。你在网页里看到的聊天界面通常是应用。应用内部可能调用一个或多个模型,还会增加 system instructions、检索、文件上传、内容安全、会话存储和用户权限。用户感觉自己在“和模型聊天”,但真正提供体验的是模型与外部软件共同组成的系统。
同理,Agent 也通常不是模型的另一个名字。模型为系统提供理解、生成和决策能力,Agent 系统还需要某种运行环境,使模型能接触当前状态、提出动作、获得结果并继续工作。这个外部运行环境正是本系列后面反复出现的 Harness。
为了避免后文越学越乱,可以先记住三个问题。看到一个新术语时,先问:
- 它描述的是模型本身、训练方法,还是完整应用?
- 它产生的是内容,还是会对外部环境产生真实动作?
- 下一步由预先写好的代码决定,还是由模型根据新状态动态决定?
这三个问题比背诵二十个定义更有用。第一问把 LLM 和 Agent 分开,第二问把“生成命令”和“执行命令”分开,第三问会在后面帮助我们区分 Workflow 与 Agent。
二、大模型能生成什么,为什么还不能独立完成任务
现在暂时放下所有 Agent 术语,只看一次最普通的大模型调用。
你把问题、历史消息或资料作为上下文交给模型。模型根据这些输入生成下一段输出,然后这次调用结束。输出可以是一段解释,也可以是一段 Python 代码、一个 JSON 对象,甚至是“建议调用某个工具”的结构化意图。形式不同,但基本边界没有变化:
当前上下文进入模型
→ 模型进行计算
→ 文本或结构化意图返回给调用方
假设你问:
请帮我找出当前项目里所有超过 500 行的 Python 文件,并说明它们各自负责什么。
模型擅长理解这个目标。它知道可以先枚举 .py 文件、统计行数、挑出目标文件,再阅读内容并总结职责。它甚至可能给出一条可用命令:
Get-ChildItem -Recurse -Filter *.py |
Where-Object { (Get-Content $_.FullName).Count -gt 500 }
但这条命令出现在回复里时,真实任务仍未完成。模型没有因为输出了 Get-ChildItem 就自动进入你的电脑,也没有看到命令运行后的文件列表。它生成的是符号,不是副作用。
这里的“副作用”不是贬义词,而是工程里的准确说法:读取当前目录、写入文件、发送网络请求、修改数据库、创建工单,都会让程序接触或改变模型之外的世界。模型输出可以描述这些动作,却不等于动作已经发生。
如果你复制命令到终端执行,再把输出粘贴回聊天窗口,任务就能继续。可这时形成闭环的人是你:
模型建议动作
→ 你判断是否允许
→ 你执行
→ 你复制结果
→ 模型根据结果继续回答
这是一条“人肉 Harness”。它非常适合低频、高风险任务,因为每一步都有人工检查;但如果目标是让程序自主完成大量可控任务,就需要把其中可自动化的连接工作交给外部代码。
第二个边界是:模型训练时学到的知识,不等于任务发生此刻的环境状态。
模型可能知道 Python 项目的常见结构,知道 README.md 往往介绍项目,知道 main.py 可能是入口。但你的当前目录里可能根本没有这两个文件,也可能入口叫 app.py,项目说明放在 docs/index.md。如果模型没有读取当前目录,却直接依据常见模式回答,它给出的只是合理猜测,不是观察结果。
“知道一般规律”和“看到当前事实”必须分开:
- 训练知识帮助模型理解什么是 Python 文件、怎样判断职责;
- 用户提供的上下文告诉模型本次任务的目标与已知信息;
- 工具或环境接口提供此刻真实存在的目录、文件内容和运行结果;
- Harness 负责把这些对象接入同一条执行链。
第三个边界是:一次调用没有天然的持续任务状态。
在普通请求里,模型只处理调用方这次提交的上下文。如果第一次调用返回“请先列出目录”,外部程序却没有执行,也没有把结果加入下一次上下文,模型不会凭空知道目录发生了什么。即使应用保存了聊天记录,也只是保存文本;是否保存结构化动作、是否执行动作、怎样把结果与原动作配对,仍由应用负责。
这解释了为什么“模型很聪明”不能替代系统工程。模型能力提高后,它可以更准确地选择动作、更好地阅读结果、更少走弯路;但文件访问权、网络连接、权限审批和状态持久化不会自动从模型参数里长出来。
可以用一个简单的责任表来判断:
| 对象 | 擅长或负责的内容 | 本身不保证的内容 |
|---|---|---|
| LLM | 理解目标、生成内容、提出下一步、根据上下文调整判断 | 真实执行命令、访问未提供的实时状态、保证动作获准 |
| Tool | 封装一种外部能力,例如读文件、执行 Shell、查询 API | 决定整个任务下一步、维护完整会话 |
| Harness | 组织消息、暴露工具、执行或拒绝动作、回填结果、控制循环 | 替代模型完成开放式语义判断 |
| Environment | 返回当前文件、进程、网页、数据库等真实状态 | 自动把结果解释成任务结论 |
这张表也给出一个关键认识:大模型并不是“缺少一条神奇提示词”才不能独立完成任务。限制来自系统边界。提示词可以告诉模型应当怎样做,却不能授予操作系统权限;模型可以生成严谨的调用参数,却仍需要外部程序解析和执行。
一次调用的边界可以直接画在“调用意图”和“真实环境”之间。模型一侧负责生成,文件、终端和数据库一侧才承载现实状态与副作用。

断开的箭头是本章最重要的边界:调用意图穿过这条线之前仍然只是数据。后续所有 Tool Calling 和 handler 代码,本质上都在为这次受控交接服务。
因此,后面课程里经常出现的 messages、Tool Schema、handler、observation,都不是为了给模型增加更多知识,而是为了建立可靠的交接:
模型能看见什么?
模型能请求什么?
谁真正执行?
执行结果怎样进入下一轮?
前置知识一暂时不展开这些协议字段。现在只需要形成一个稳定判断:大模型提供智能决策能力,但从输出到行动之间仍有一道软件边界。
三、下一步由谁控制
很多产品都有对话框,所以人们容易按界面判断系统类型:能聊天的是助手,会自动跑几步的是 Agent。这个判断不可靠。聊天只是一种交互方式,后台自动运行也只是一种触发方式。真正影响架构的,是任务路径由谁控制、运行中怎样获得新状态,以及谁负责产生副作用。
我们用同一个目标做静态对照:
整理一个陌生的本地 Python 项目:找出入口文件、测试目录和主要模块,最后生成一份结构说明。
先看单次聊天助手。你只把任务描述交给模型,没有提供文件,也没有工具。模型可以告诉你常见检查方法,或者根据你粘贴的目录树进行分析。如果它不知道真实目录,就只能给建议;如果你把全部文件都塞进上下文,它可以一次性总结,但输入规模、信息新鲜度和隐私边界都由你人工处理。
单次聊天的主链是:
用户准备上下文
→ 模型生成回答
→ 用户决定是否执行
它的优点是简单、便宜、容易审查。对“解释一段已提供代码”这类任务,单次调用可能就是最正确的方案。使用 Agent 不是目标,完成任务才是目标。
再看固定 Workflow。开发者预先写好步骤:
- 枚举所有文件;
- 查找
pyproject.toml、requirements.txt或setup.py; - 搜索包含
if __name__ == "__main__"的文件; - 读取测试目录;
- 把收集结果交给模型生成说明。
这里可以调用 LLM,也可以包含多个工具,但主要路径由代码预定。无论目录是什么,程序都按相同顺序执行,最多在代码写好的分支里选择。Anthropic 的工程文章将这类系统称为 Workflow:模型和工具通过预定义代码路径被组织起来。
固定 Workflow 并不比 Agent “落后”。恰恰相反,当步骤稳定、合规要求明确、错误代价高时,Workflow 往往更容易测试和预测。批量生成日报、按固定字段审核合同、把表单同步到数据库,都可能更适合 Workflow。系统不需要为了显得智能而把确定流程交给模型。
最后看模型驱动 Agent。Harness 先让模型看到目标和有限工具,例如列目录、读文件、搜索文本。模型可能先列目录;看到没有 main.py 后,转而读取 pyproject.toml;根据包入口再去找 src/app/cli.py;发现测试使用特殊目录后,再调整下一步。任务路径不是开发者在运行前完整列出的,而是模型依据 observation 动态形成。
Agent 的主链更接近:
用户给出目标
→ 模型选择下一步动作
→ Harness 执行并返回新状态
→ 模型依据新状态再次选择
→ 达成目标或触发停止条件
三种系统可能使用同一个模型、同一组工具、同一个聊天界面。它们的关键差别不在“用了几个 API”,而在控制权:
| 判断问题 | 单次聊天助手 | 固定 Workflow | 模型驱动 Agent |
|---|---|---|---|
| 谁决定下一步 | 用户 | 预定义代码 | 模型依据当前状态动态决定 |
| 谁取得环境新状态 | 用户提供 | 工作流按固定步骤读取 | Harness 按模型请求读取 |
| 谁执行副作用 | 用户或外部应用 | 预定义处理器 | Harness 在权限边界内执行 |
| 路径是否预先确定 | 通常只有一次调用 | 大部分确定 | 运行前无法完全确定 |
| 主要优势 | 简单、透明 | 稳定、可预测 | 灵活、能处理开放路径 |
| 主要代价 | 需要人工搬运 | 难应对未知分支 | 成本、延迟和错误会累积 |
这里要观察三列的箭头方向,它比界面外观更容易判断系统类型:聊天助手的反馈主要由用户搬运,Workflow 沿代码写好的直线前进,Agent 则让 observation 回到模型形成动态回环。

控制权不同不代表三者必须互相取代。任务越确定,直线路径越有价值;只有新状态确实会改变下一步时,模型驱动的回环才值得增加。
还可以加入一个中间词:Agentic System。不同资料对 Agent 的定义并不一致,有些把遵循固定步骤但包含模型和工具的系统也称作 Agent,有些只把模型动态掌控过程的系统称为 Agent。Anthropic 用 agentic systems 覆盖 Workflow 与 Agent,再在内部按控制权区分两者。这个口径的价值是避免争论名称,直接讨论架构。
OpenAI Agents SDK 的文档则从具体实现对象出发:一个 Agent 是配置了 instructions、tools 和可选运行行为的 LLM,Runner 管理轮次和工具等运行责任。它告诉我们在某个 SDK 中对象怎样组合,但不意味着所有论文、框架和公司都必须使用相同定义。
Google Cloud 的页面采用更宽的能力视角,强调工具交互、自治、适应变化、后台运行和多 Agent。这适合观察当前产品层如何使用“Agent”这个词,同时也提醒我们:高伦理风险、不可预测物理环境和资源成本仍是明确限制。
因此,遇到“这到底算不算 Agent”时,不要先争名字。先把系统画出来:
- 目标从哪里来?
- 可用动作有哪些?
- 下一步由谁决定?
- 新状态由谁读取?
- 动作由谁批准和执行?
- 何时结束,失败后怎样处理?
把这些问题回答清楚,术语差异就不会阻碍工程判断。反过来,如果系统只写着“AI Agent”却说不清控制权和反馈来源,这个名称对理解架构几乎没有帮助。
四、本课程所说的 Agent 到底是什么
现在可以给本系列建立一个稳定口径。
本课程中的 Agent,是一个由大模型承担动态判断、由 Harness 提供状态、工具、执行和边界控制,并能围绕目标持续获得反馈的系统。
为了方便记忆,我们会使用:
Agent 产品 = Model + Harness
这里的加号是一条工程分工,不是唯一行业定义。
Model 负责理解目标、阅读当前上下文、选择动作、解释 observation,并判断下一步。它提供的是不容易用大量 if/else 写出的语义决策能力。
Harness 负责把这种能力安放进真实环境。它至少会逐步包含:
- 消息与状态:保存用户目标、模型输出、工具调用和环境结果;
- 工具接口:告诉模型可用能力及参数结构;
- 执行器:把结构化调用路由到真实函数、Shell、文件系统或 API;
- 循环与停止:决定何时再次调用模型,何时正常结束或强制停止;
- 权限与沙箱:限制模型可以触达的路径、命令和外部系统;
- 上下文管理:在信息增长时选择保留、压缩或按需加载;
- 可观察性:记录每次判断、动作、结果、错误和成本;
- 协作机制:让子智能体、任务系统、消息箱和外部协议参与更复杂任务。
Model 与 Harness 之间交换的不是模糊的“智能”,而是可观察的 action 和 observation。前者从模型流向执行层,后者把真实结果送回模型。

这个分工同时说明了能力与责任:模型选择动作不等于动作必然获准,Harness 掌握执行权也不应代替模型做开放式语义判断。二者通过明确接口协作,才能分别测试和演进。
Learn Claude Code 把这种学习方向概括为“模型决定,Harness 执行”。这句话很有力量,但也需要补上工程边界:Harness 不是模型命令的无条件执行器。它必须能够拒绝危险动作、校验参数、限制资源、记录过程,并在不确定时把控制权还给人。
换句话说,模型提供 agency,即根据目标和状态选择行动的能力;Harness 提供 operational environment,即行动能够被描述、执行、观察和约束的环境。模型越强,越可能做出合理的动态决策;Harness 越清晰,模型越容易正确使用能力,错误也越容易被控制和定位。
从当前一手工程资料可以看到,Agent 开发已经不再只谈“给模型一个提示词”。常见系统会显式处理 tools、state、runner/loop、guardrails、handoffs、sessions、memory、sandbox 和 tracing。与此同时,一手资料也反复强调简单性:能用一次模型调用解决,就不必上 Agent;能用固定 Workflow 稳定解决,就不必把所有路径交给模型。Agent 的价值来自开放任务中的灵活决策,不来自“自治”这个标签本身。
把当前工程能力按层排列,可以看到“模型”只是地基。工具让系统接触环境,状态与循环形成反馈,权限、可观察性、协作和记忆再逐层把最小闭环变成可维护系统。

能力栈向上增长并不表示每个项目都必须拥有全部层次。选择哪一层,取决于任务风险、持续时间和协作复杂度;简单任务停在更低层反而更清楚。
这段现状只是一张带日期的快照。具体 SDK 名称、模型能力和产品功能会继续变化,但几条工程关系相对稳定:
- 模型输出与外部执行是两个对象;
- 环境状态必须通过接口进入上下文;
- 动态任务需要反馈,而不是只需要更长提示词;
- 自主性越高,越需要权限、停止条件和可观察性;
- 简单可组合的结构更适合学习、调试和逐层扩展。
这也是本系列为什么从“零”开始。我们不会一上来使用大型框架,把工具注册、消息协议、结果回填和循环控制全部藏在抽象层下面。框架当然有价值,但如果不知道底层发生了什么,遇到工具没有执行、结果没有回填、上下文断裂或循环无法停止时,就只能靠猜。
后续 22 篇的学习路线会沿同一条主链生长:
前置知识一:分清 Model、Agent 与 Harness;
前置知识二:理解 Action、Observation 与 Agent Loop;
第 01 篇:用一个 Bash handler 写出最小闭环;
第 02 篇以后:逐步增加原子工具、任务计划、子智能体、记忆、并发、团队协议、权限、Hook 与外部能力路由;
第 20 篇:把前面分散学习的机制装配成完整 Harness。
这条路线只有一个骨架:先建立对象边界,再形成反馈循环,随后让真实代码围绕最小 Loop 增长。每个站点解决上一站暴露的新问题。

因此,我们在当前前置篇所了解到的内容是后续读代码时持续复用的坐标,等到完整学完第 20 篇,我们会发现新增能力很多,但是Model/Harness 分工和 action/observation 主链仍然不会消失。
在正式的20篇中,每一篇都不只是展示新增代码。首先我们会先回顾上一版能做什么,再指出它无法解决的问题;接着解释本篇引入的机制;最后回到真实代码,观察机制怎样改变状态和执行链。这样我们就可以从最简单的智能体入手,一点一点去学习一个系统为什么必须一步步长成现在的样子。
读完前置知识一,你应该能够用自己的话回答四个问题:
- LLM 为什么不是 Agent 的同义词?
- 模型生成命令为什么不等于命令已经执行?
- Workflow 与 Agent 最重要的区别为什么是下一步控制权?
- Harness 为什么既要给模型能力,也要约束能力?
如果这四个问题已经清楚,下一处断点就非常具体了:即使 Harness 能执行一个动作,模型怎样看到动作后的新状态?例如模型先请求列出目录,程序执行后得到真实文件列表,这份结果怎样重新进入模型上下文,让它继续选择要读的文件?
这就是前置知识二要解决的问题。我们会从 ReAct 的 reasoning、action、observation 关系出发,分清方法范式、工具调用协议和运行循环,再把抽象反馈链交给第 01 篇的 Python 程序。
更多推荐




所有评论(0)