引言
最近 OpenClaw、Skill、MCP、RAG、Function Calling 这些词同时出现的频率很高。读多了之后反而容易有一种熟悉的眩晕感:每个词都好像懂一点,真正要解释「它们差在哪一层」时,又经常卡住。
本博文想做的事情比较朴素:把这些概念按「问题是怎么一步步长出来的」重新串一遍。重点不是背名词,而是弄清三件事:
- 每个词当初是为了补哪块短板;
- 它落在人、宿主程序、模型、外部能力之间的哪一段接口上;
- 哪些对比本身就不在同一维度。
写完以后会发现,很多新词并没有发明全新智能,而更像是在同一条工程链路上不断打补丁、起名字、做封装。
参考:概念脉络参考了飞天闪客的视频《一口气拆穿 Skill/MCP/RAG/Agent/OpenClaw 底层逻辑》。下文为本人整理与改写,仅供学习记录。
相关前文:
什么是智能体 / Agent?
一句话版:
所谓智能体,往往由大量「不需要智能」的部分构成。
再展开一点:
模型负责在不确定处做判断与生成;
宿主程序负责循环调度、执行工具、拼装上下文;
Agent ≈「模型 + 外围 harness」一起转起来的系统。
后面所有名词,大体都围着这句话长出来。
LLM 只能单轮对话?
混乱的起点仍然是语言模型。参数较小时,它更像勉强续写的机器;参数大到某个临界点后,涌现出更强的指令跟随与推理表现——这就是人们常说的「智能」。为了和更早的小模型区分,前面加了个「大」字,于是有了 LLM(Large Language Model)。
但 LLM 的基本机制没变:它在给定上下文中做自回归生成,不断预测下一个 token。如果只拿它做裸续写,体验仍然很差。工程上真正让它「看起来会聊天」的第一步,是人为切出角色边界——把交互组织成一问一答。
这里有个后面会反复用到的约束:
模型调用本身通常仍是「一次请求、一次回复」。
它并不能天然一边聊一边主动追问;
所谓多轮,往往是宿主在下一次请求前,把历史重新塞回上下文。
可以把模型想象成能力很强、但服务方式很奇怪的员工:只会接一次任务单,办完就交卷——不能追问。接下来的工程,就是想办法压榨这个「只会一问一答」的员工。
首先,给每次输入起名,叫 Prompt。拆开后通常至少有两类东西:
- 背景信息、约束、资料;
- 最终要模型完成的指示。
前者常单独称作 Context(上下文)。
模型一次能吞下的总量,则受 Context Window 限制——历史、检索结果、工具返回、说明文档,最终都要挤进这个窗口。
多轮是怎样做出来的?Memory
既然模型不能真正「记住」上轮对话,要追问怎么办?常见做法很直接:
- 把此前的对话历史整理好;
- 放进下一次请求的 Context;
- 再追加当前问题。
表面上是连续对话,底层仍是单次生成。人们把这种「靠回填历史维持连续性」的机制叫作 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,其实都可以归进一个更大的筐:获取模型参数以外的信息。它们解决的都是「只靠参数记忆不够」。
补两句边界:
- RAG 的目标是让生成建立在外部证据上,而不是只靠训练知识;
- 向量数据库是常见实现,但不是唯一实现;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/list、tools/call;通信多基于 JSON-RPC。
一张更清楚的位置关系:
拼装上下文 · 执行工具 · 控制循环"] 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 主要回收结论和必要产物。
本质先看做 任务拆分 + 上下文隔离,不必先上升成「多智能体社会」。
总结
先把名词生长路径收成一张图:
大语言模型 / 自回归生成"] --> 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 往上叠出来的概念层
再看多阶段任务的固化谱系:
代码/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。
越靠左,越稳、越死;
越靠右,越活、越飘。
选型关键不是谁更新,而是任务有多稳定、能允许多少不确定性。
如果再往下抽象一层,这些技术大多没有离开两件事:
- 自动往提示词里增加上下文(Search、RAG、Memory、Skill 文档常如此);
- 用程序代理,减少人与模型的无效往返(能脚本化的就别每次重新问模型)。
这也是为什么可以说:
一个流程里,所有能用固定程序解决、不必询问大模型的地方,
往往正是 Agent / Harness 最该发挥作用的地方:
模糊分流交给模型,确定逻辑交给程序。
最终目标也很朴素:节省人类时间,降低使用门槛。
运行时闭环可以画成:
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 / 确定性编排 | 用预定流程固化稳定多步任务 |