什么是Agent?:从 LLM 到 Skill / MCP / RAG

2026-08-01

引言

最近 OpenClaw、Skill、MCP、RAG、Function Calling 这些词同时出现的频率很高。读多了之后反而容易有一种熟悉的眩晕感:每个词都好像懂一点,真正要解释「它们差在哪一层」时,又经常卡住。

本博文想做的事情比较朴素:把这些概念按「问题是怎么一步步长出来的」重新串一遍。重点不是背名词,而是弄清三件事:

  1. 每个词当初是为了补哪块短板;
  2. 它落在人、宿主程序、模型、外部能力之间的哪一段接口上;
  3. 哪些对比本身就不在同一维度。

写完以后会发现,很多新词并没有发明全新智能,而更像是在同一条工程链路上不断打补丁、起名字、做封装。

参考:概念脉络参考了飞天闪客的视频《一口气拆穿 Skill/MCP/RAG/Agent/OpenClaw 底层逻辑》。下文为本人整理与改写,仅供学习记录。

相关前文:

什么是智能体 / Agent?

一句话版:

所谓智能体,往往由大量「不需要智能」的部分构成。

再展开一点:

模型负责在不确定处做判断与生成;
宿主程序负责循环调度、执行工具、拼装上下文;
Agent ≈「模型 + 外围 harness」一起转起来的系统。

后面所有名词,大体都围着这句话长出来。

LLM 只能单轮对话?

混乱的起点仍然是语言模型。参数较小时,它更像勉强续写的机器;参数大到某个临界点后,涌现出更强的指令跟随与推理表现——这就是人们常说的「智能」。为了和更早的小模型区分,前面加了个「大」字,于是有了 LLM(Large Language Model)

但 LLM 的基本机制没变:它在给定上下文中做自回归生成,不断预测下一个 token。如果只拿它做裸续写,体验仍然很差。工程上真正让它「看起来会聊天」的第一步,是人为切出角色边界——把交互组织成一问一答。

这里有个后面会反复用到的约束:

模型调用本身通常仍是「一次请求、一次回复」。
它并不能天然一边聊一边主动追问;
所谓多轮,往往是宿主在下一次请求前,把历史重新塞回上下文。

可以把模型想象成能力很强、但服务方式很奇怪的员工:只会接一次任务单,办完就交卷——不能追问。接下来的工程,就是想办法压榨这个「只会一问一答」的员工。

首先,给每次输入起名,叫 Prompt。拆开后通常至少有两类东西:

  • 背景信息、约束、资料;
  • 最终要模型完成的指示。

前者常单独称作 Context(上下文)
模型一次能吞下的总量,则受 Context Window 限制——历史、检索结果、工具返回、说明文档,最终都要挤进这个窗口。

多轮是怎样做出来的?Memory

既然模型不能真正「记住」上轮对话,要追问怎么办?常见做法很直接:

  1. 把此前的对话历史整理好;
  2. 放进下一次请求的 Context;
  3. 再追加当前问题。

表面上是连续对话,底层仍是单次生成。人们把这种「靠回填历史维持连续性」的机制叫作 Memory

Memory 还可以继续演化:

  • 完整回放太占窗口时,做摘要压缩;
  • 跨会话要长期保留时,把关键事实外置存储,需要时再检索回来。

所以产品里的 Memory,通常不是「模型参数里突然长出了记忆」,而是一套上下文管理策略

NOTE:
后面几乎所有花活——搜索结果、RAG 片段、Skill 文档——工程上常常落成同一类动作:在合适时机,自动往 Prompt / Context 里补信息

模型不会上网,怎么办?Agent 出场

有了多轮对话后,下一个缺口很快出现:模型没有实时查阅资料的能力,要么不知道,要么一本正经胡说,要么只能复述过时知识。

NOTE:
关于「过时知识」,私有化部署或早期模型时,问一句「今天是几号?」看输出,往往就能直接感受到。

最天真的想法是「给模型一台电脑」。但模型本身只会生成文本,不会独立完成外部动作。于是折中方案变成:

  • 让模型在需要查资料时提出请求;
  • 由一段程序去真正搜索;
  • 再把结果回填给模型继续生成。

对外看,用户仍像在「一问一答」;对内看,中间已经多了一层代理程序。当这层程序不仅能搜网页,还能读写文件、调 API、跑脚本时,它看起来就像拥有了「能操作工具的更高智能」。人们给它起名叫 Agent(智能体)

一个比较干净的工程定义是:

Agent ≈ 模型在循环中调用工具,直到任务完成;
Harness ≈ 围在模型周围的那一层:提示词、工具列表、中间件、状态与终止条件。

也就是说,Agent 不是另一个更神秘的大脑,而更接近 Model + Harness

  • 模型负责理解目标、选择下一步、提出工具调用或给出最终回答;
  • 宿主程序负责组织上下文、真正执行工具、把结果喂回模型、控制循环何时结束。

早期一些所谓 Agent,实现上可能只是多包了一层 Prompt,外加几段「上网搜资料」的代码。名词很新,底层未必复杂——这也是后来大家对概念通胀格外警惕的原因。

所以,Agent 更像人和 LLM 之间的一套程序:减少人与大模型的无效往返,并处理 LLM 无法直接操作的事情——搜索只是其中之一;放到具身智能里,也可能是导航、抓取这类工具调用。

本地知识怎么接进来?Search 与 RAG

既然 Agent 已经能代理外部动作,下一步很自然:除了上网,能不能搜本地文档和数据库?

当然可以。私有知识检索常常不是传统关键词查询,而是先把文本做成向量,再按语义相似度召回相关片段;把「检索到的证据」与用户问题一起交给模型生成,就是 RAG(Retrieval-Augmented Generation)

Web Search 与 RAG,其实都可以归进一个更大的筐:获取模型参数以外的信息。它们解决的都是「只靠参数记忆不够」。

补两句边界:

  1. RAG 的目标是让生成建立在外部证据上,而不是只靠训练知识;
  2. 向量数据库是常见实现,但不是唯一实现;BM25、混合检索、知识图谱等也可以做 Retriever。

检索质量仍然决定上限。RAG 能降低胡编概率,不会自动保证正确。

模型和程序怎么说话?Function Calling

当 Agent 需要稳定调用工具时,如果模型和宿主之间一直用自然语言沟通,程序会很难解析。于是需要一套约定:让模型在需要外部能力时,输出可解析的结构化请求(工具名 + 参数),而不是只吐一段自由发挥的话。

这就是 Function Calling,现在也常叫 Tool Calling

关键事实只有一句:

模型不负责真正执行函数;
它只提出调用请求;
宿主程序执行完后,再把结果作为后续上下文喂回模型。

没有这类机制,宿主就得靠脆弱的文本解析去猜意图,工程上很难做稳。它很像前后端约定好接口字段:约定清楚,系统才能自动流转。

工具如何外置成服务?MCP

一开始,工具实现常常直接写在 Agent 主程序里。这样简单,但难复用、难解耦。一旦希望把工具拆成独立服务,让不同 AI 应用都能发现和调用,就又需要一套标准协议。

这就是 MCP(Model Context Protocol,模型上下文协议)。说白了,也是一套约定:

  • 架构上常见 Host(宿主应用)— Client(连接层)— Server(能力提供方)
  • Server 可暴露:
    • Tools:可执行动作;
    • Resources:可读的上下文数据;
    • Prompts:可复用提示模板;
  • 工具侧最常提到的动作是 tools/listtools/call;通信多基于 JSON-RPC。

一张更清楚的位置关系:

flowchart TB classDef user fill:#FFF3E0,stroke:#E65100,color:#222 classDef host fill:#E3F2FD,stroke:#1565C0,color:#222 classDef model fill:#F3E5F5,stroke:#6A1B9A,color:#222 classDef tool fill:#E8F5E9,stroke:#2E7D32,color:#222 classDef mem fill:#FFF8E1,stroke:#F9A825,color:#222 U["你 / 自然语言任务"] <-->|"CLI / IDE / 桌面助手"| H["Host / Harness
拼装上下文 · 执行工具 · 控制循环"] H --- MEM["Memory"] H --- SK["Skill
SKILL.md + 资源/脚本"] H --- SUB["SubAgent"] H <-->|"Function / Tool Calling"| L["LLM
决策与生成"] H <-->|"MCP Client"| S["MCP Server
Tools / Resources / Prompts"] H --- RAG["RAG / Web Search
检索后回填上下文"] class U user class H,MEM,SK,SUB host class L model class S tool class RAG mem

图 1:人、Host/Harness、LLM、MCP 与检索能力的相对位置

可以很粗地记:

  • 大模型像个「会说话、不会直接动手」的智者;
  • MCP Server 提供各种可调用能力;
  • 中间的 Host / Agent 更像传话筒与调度器——把模型意图翻译成工具调用,再把结果原路送回。

它未必生产智能,但负责搬运上下文、执行确定动作、组织整条链路。

NOTE:
Function Calling 和 MCP 常被拿来互比,其实不在同一层:前者约定「模型如何提出工具请求」,后者约定「宿主如何发现并接入外部能力」。二者通常协作,而不是互相取代。

交互形态:从 CLI 到 OpenClaw

同样一套 Agent 能力,交互外壳可以完全不同:

  • CLI 命令行;
  • 编程 IDE 里的编码助手;
  • 更通用的桌面助手,例如 CloudBot / OpenClaw 一类产品。

OpenClaw 之类产品引起关注,往往不只是因为又发明了新协议,而更因为:

  • 降低了配置门槛;
  • 能接入社交软件、配置定时任务;
  • 有页面可以看到并管理 Skill;
  • 第一次让普通人觉得「这像一个助手」,而不只是电脑里的后台服务。

这也回到一个更朴素的判断:便利性常常比概念纯度更决定扩散速度。

固定流程还要 Agent 每次自由发挥吗?Skill 来了

开放 Agent 很强,但对相对稳定的多阶段任务,每次都让它重新规划,既不稳定,也浪费 Token。

典型例子:

1. 从英文 PDF 提取文本;
2. 翻译成中文;
3. 保存为 Markdown。

其中「提取 PDF」「保存文件」完全可以固化成脚本;只有中间翻译更适合交给模型。整条链路未必需要每一步都由智能体重新发明。

于是出现了不同固化方式。

** 1. 确定性编排(代码 / Chain)**

用代码把步骤写死,或用链式编排把流程固定下来。优点是稳定、可测、可复现;缺点是输入输出一组合爆炸,维护成本会很快上升。

NOTE:
LangChain 早期的确以 Chain 著称;今天它已不只是硬编码链条,也提供 Agent 等能力。和 LangGraph 的分工,更接近「组件/harness」与「复杂状态图编排」。谱系最左端,准确说法应是确定性编排

** 2. Workflow / 工作流 **

把编程换成低代码拖拽。对非程序员更友好,改流程也直观,但本质仍偏「程序预先规定走向」。分支一多,画布一样会复杂。

** 3. 为什么会逼出 Skill **

如果输入可能是 PDF / Word / TXT / PPT,输出可能是 Markdown / HTML / 图片,难道每一种排列组合都画一套工作流?可以堆很多 if-else,但若仍希望用户用自然语言触发,分支判断又会重新变得困难。

更折中的做法是:

1. 准备一个目录,放好可能用到的转换脚本;
2. 写一份统一说明,把流程和选择规则讲清楚;
3. 让 Agent 先读说明,再按文件类型灵活选脚本执行。

为了避免每次都人工追加「请先读那份说明」,宿主程序可以约定:接到任务时自动去指定位置读取 SKILL.md。于是就有了今天常说的 Skill

** 4. Skill 到底是什么 **

更贴近当前常见实现的理解是:

  • Skill 通常是一个目录,核心是 SKILL.md,并可附带参考文档、脚本等资源;
  • 关键设计是 progressive disclosure(渐进式披露):先只暴露名称/描述,相关时再加载全文,需要时再读附加文件或执行脚本;
  • 触发方式通常是模型自主判断是否调用,而不是每次由人整份粘贴进 Prompt。

所以,把 Skill 仅仅说成「换地方存的提示词」偏简化了;它更像「可被发现、按需加载的专项能力包」。相对纯硬编码,多了灵活;相对完全放养的 Agent,又多了边界。

NOTE:
Skill 和 MCP 也不是同一维度。Skill 是给 Agent 用的程序性知识包;MCP 是宿主与外部能力服务之间的协议。Skill 更适合拿去和「确定性编排 / Workflow / 开放 Agent」比较。

超级复杂的任务怎么办?SubAgent

复杂任务里,主会话很容易被中间过程撑爆。于是又出现 SubAgent

  • 把相对独立的子任务丢给子代理;
  • 子过程细节不全部回流主会话;
  • 主 Agent 主要回收结论和必要产物。

本质先看做 任务拆分 + 上下文隔离,不必先上升成「多智能体社会」。

总结

先把名词生长路径收成一张图:

flowchart BT classDef base fill:#ECEFF1,stroke:#455A64,color:#222 classDef agent fill:#E3F2FD,stroke:#1565C0,color:#222 classDef product fill:#FFF3E0,stroke:#EF6C00,color:#222 P1["① LLM
大语言模型 / 自回归生成"] --> P2["② Prompt
送入模型的输入"] P2 --> P3["③ Context Window
有限上下文窗口"] P3 --> P4["④ Memory
靠回填历史维持连续性"] P4 --> P5["⑤ Agent
模型 + harness 循环调工具"] P5 --> P6["⑥ RAG / Web Search
获取参数外信息"] P5 --> P7["⑦ Function Calling
模型提出结构化工具请求"] P5 --> P8["⑧ MCP
宿主与外部能力的标准协议"] P5 --> P9["⑨ 确定性编排 / Workflow / Skill
多步任务如何固化"] P5 --> P10["⑩ SubAgent
子任务与上下文隔离"] P5 --> P11["⑪ 产品形态
CLI / IDE / OpenClaw"] class P1,P2,P3,P4 base class P5,P6,P7,P8,P9,P10 agent class P11 product

图 2:从 LLM 往上叠出来的概念层

再看多阶段任务的固化谱系:

flowchart LR classDef rigid fill:#FFCDD2,stroke:#C62828,color:#222 classDef mid fill:#FFE0B2,stroke:#EF6C00,color:#222 classDef soft fill:#C8E6C9,stroke:#2E7D32,color:#222 classDef flex fill:#BBDEFB,stroke:#1565C0,color:#222 LC["确定性编排
代码/Chain 写死步骤
最稳定 / 难包容变化"] -->|"更柔性"| WF["Workflow
低代码拖拽
好改一点 / 仍偏程序控"] WF -->|"更柔性"| SK["Skill
SKILL.md + 资源/脚本
模型按需加载 / 有约束"] SK -->|"更柔性"| PA["开放 Agent 循环
动态拆解与自写脚本
最灵活 / 易失控"] class LC rigid class WF mid class SK soft class PA flex

图 3:确定性编排 → Workflow → Skill → 开放 Agent

  • 确定性编排:全程硬编码,稳,但难包容变化。
  • Workflow:把程序控制换成拖拽,改起来容易些,仍偏预定路径。
  • Skill:流程走向更多由模型根据说明与脚本自行选择,既保留灵活性,又不会完全失控。
  • 开放 Agent:最柔,可随时改计划甚至自写脚本;也最容易把简单任务做复杂,并烧掉大量 Token。
越靠左,越稳、越死;
越靠右,越活、越飘。
选型关键不是谁更新,而是任务有多稳定、能允许多少不确定性。

如果再往下抽象一层,这些技术大多没有离开两件事:

  1. 自动往提示词里增加上下文(Search、RAG、Memory、Skill 文档常如此);
  2. 用程序代理,减少人与模型的无效往返(能脚本化的就别每次重新问模型)。

这也是为什么可以说:

一个流程里,所有能用固定程序解决、不必询问大模型的地方,
往往正是 Agent / Harness 最该发挥作用的地方:
模糊分流交给模型,确定逻辑交给程序。

最终目标也很朴素:节省人类时间,降低使用门槛。

运行时闭环可以画成:

flowchart LR classDef user fill:#FFF3E0,stroke:#E65100,color:#222 classDef host fill:#E3F2FD,stroke:#1565C0,color:#222 classDef model fill:#F3E5F5,stroke:#6A1B9A,color:#222 classDef tool fill:#FFF8E1,stroke:#F9A825,color:#222 U["人"] -->|"自然语言"| H["Host / Harness"] H -->|"组装 Prompt
Memory / RAG / Skill"| L["LLM"] L -->|"Tool Calling
结构化工具请求"| H H -->|"本地工具或 MCP call"| T["Tools / Servers"] T -->|"结果回填上下文"| H H -->|"最终答复"| U class U user class H host class L model class T tool

图 4:人 → Host → LLM / Tools → 回填上下文 → 最终答复

最后用一张极简对照表收束:

名词 一句话
LLM 自回归生成引擎;单次调用通常一问一答
Prompt / Context 送进模型的输入,及其背景信息部分
Memory 靠回填/摘要/外置存储维持连续性的上下文管理
Agent 模型 + harness:循环调工具,直到任务完成
RAG / Web Search 获取参数外信息,再回填给模型
Function Calling 模型提出结构化工具请求,由程序执行
MCP 宿主发现并接入外部能力的标准协议
Skill 按需加载的说明 + 脚本能力包
SubAgent 子任务拆分与上下文隔离
Workflow / 确定性编排 用预定流程固化稳定多步任务