简介:围绕Skill、MCP、RAG、Agent等常见AI应用架构概念,本文从对话包装、工具调用、知识检索和上下文协议四个层面梳理它们的本质差异、演进关系与适用场景,帮助开发者理解不同技术组件的边界,避免概念混用和选型偏差。
在大语言模型应用快速落地的过程中,Skill、MCP、RAG、Agent 这几个词频繁出现。它们有时被并列讨论,有时被混用,甚至同一个系统里会同时涉及其中多个概念。对开发者来说,如果不把这些概念的边界、职责和依赖关系理清,很容易在设计系统时出现两种偏差:一是把简单需求过度设计,引入不必要的抽象层;二是把复杂需求简单化,把一段提示词或一个工具调用就称为“智能体”,导致实际能力与预期不符。
因此,本文尝试从“模型能力如何被逐步包装、扩展和工程化”的视角,把这组概念放在同一条演进链路上进行对比。需要提前说明的是,这些概念并非彼此互斥,也不是同一层级上的四个并列模块。它们分别回答了不同阶段的问题:模型如何从文字接龙变成对话、如何获得记忆、如何调用工具、如何检索外部知识、如何定义工具与模型的接口规范。
理解这些差异,比记住定义本身更有价值。
大语言模型的核心行为可以理解为文字接龙:给定一段文本,预测下一个最可能的字或词,再不断重复这个过程。这个能力本身并不等于“对话”,也不等于“员工”。它只是一个统计上很强的文本生成器。
为了让这个文本生成器变成可用的系统,需要在其外围增加很多工程能力。通常的演进路径是:
下面沿着这条路径逐一拆解。
最初,人们发现同一个模型,输入不同的问题或指令,输出质量差异很大。于是,精心设计输入内容成为一种常见做法。这种输入内容被称为 Prompt。Prompt 的本质就是模型的输入文本,它既可以是简单问题,也可以包含角色设定、任务说明、输出格式要求等。
Prompt 并不神秘,它只是对“如何更好地触发模型能力”的一种工程化约定。随着模型能力增强,Prompt 的设计复杂度和重要性也在发生变化,但它始终是模型输入的总称。
在实际使用中,Prompt 内部往往混杂着不同类型的文本。比如一段客服对话里,可能既有系统规则、历史聊天记录,也有用户当前的问题。如果把这些内容不加区分地塞给模型,模型虽然也能处理,但开发者在维护和调试时会比较混乱。
于是,人们把 Prompt 中的“背景信息”和“当前指令”做了区分。背景信息通常被称为 Context,也就是上下文。上下文可以包括系统设定、对话历史、外部检索结果、用户画像等。当前指令则是这一次真正希望模型完成的任务。
这种划分不是模型要求的,而是工程组织上的需要。清晰的上下文管理,能让提示词更易维护,也能减少无关信息对模型输出的干扰。
单轮问答有一个明显限制:模型每次调用都是无状态的。用户问“帮我查一下北京的天气”,模型回答了;用户接着问“那明天呢”,模型并不知道“那”指代什么。
为了解决这个问题,常见的做法是:在每次新的提问中,把之前的对话历史作为上下文的一部分重新传给模型。这样,模型看到的是完整的对话记录,而不是孤立的一句话。这些被重新传回的历史信息,称为 Memory。
Memory 的实现方式有很多种:
Memory 的目标不是让模型“真的记住”,而是通过外部工程手段,让模型在每次调用时都能获得必要的背景信息。
大语言模型只能生成文本。它不能直接上网搜索,不能查询数据库,不能调用某个业务接口,也不能执行本地命令。当业务需要这些能力时,单靠模型本身无法完成。
一种直观的解决思路是:把模型的输出交给一段外部程序,由这段程序去判断模型想做什么,然后执行相应操作,再把操作结果反馈给模型。这样,模型负责“思考”和“生成回复”,外部程序负责“执行动作”。
这层外部代理程序被称为 Agent,也就是智能体。Agent 的核心职责是:
从架构上看,系统变成:用户 → Agent → 模型。Agent 位于用户和模型之间,承担协调者的角色。
需要注意的是,早期很多被称为 Agent 的实现,实际上只是在 Prompt 中增加了一段“你可以使用以下工具”的描述。模型并没有真正的工具调用能力,只是被要求输出类似“调用搜索工具”的文字。严格来说,这更接近提示词工程,而不是真正意义上的智能体。随着模型能力演进和 Function Calling 机制的普及,Agent 的实现方式才逐渐规范化。
当模型需要获取实时信息时,可以让 Agent 调用搜索引擎接口,把搜索结果作为上下文传给模型。这种方式能解决一部分“模型不知道最新信息”的问题。
但对于企业场景,很多关键知识不在公网搜索引擎中,而在内部文档、知识库、工单系统、设计文档里。这些内容无法通过普通搜索接口获取,也不适合全部塞进上下文。
RAG,即检索增强生成,解决的问题是:如何从大量本地或私有文档中,找到与当前问题最相关的内容,并把它们作为上下文提供给模型。
传统的关键词搜索在这种场景下有两个主要问题:
因此,RAG 通常采用向量化检索的方式:把文档切分成块,通过嵌入模型将每个块转换为向量,存入向量数据库。用户提问时,同样将问题转为向量,在向量空间中查找语义最接近的文档块,再把这些块作为上下文拼接给模型。
RAG 不是模型的一部分,而是一套外部的检索与上下文构建机制。它的效果取决于文档切分策略、嵌入模型质量、向量检索精度、重排序策略以及上下文拼接的合理性。
在 Agent 调用工具的过程中,有一个关键问题:模型输出是自然语言,程序很难稳定解析。
比如,模型可能回复“我想帮你查一下天气,请调用天气查询工具,城市是北京”。这段文字对人类友好,但对程序来说,需要额外编写解析逻辑,而且模型每次的措辞可能不同,解析容易失败。
Function Calling 的解决思路是:不再让模型输出自然语言来描述工具调用,而是要求模型按照预定义的格式输出,通常是 JSON 结构。比如:
{"tool": "weather_query","parameters": {"city": "北京"}}
这样,Agent 可以直接解析 JSON,提取工具名和参数,执行调用。模型的回复分成了两部分:一部分是给用户的自然语言,另一部分是给程序的结构化指令。
Function Calling 本质上是前后端之间的接口约定。它把模型输出从“自由文本”变成“受限但可解析的结构”,从而让工具调用变得可靠。
在早期实现中,Agent 里的工具调用逻辑和具体业务代码耦合较深。每增加一个工具,都需要在 Agent 代码中注册、编写调用逻辑、处理返回结果、维护参数格式。随着工具数量增多,维护成本快速上升。
如果一个企业内部有多个 Agent 应用,每个应用都需要调用同一组工具,那么每个应用都要重复实现一遍工具接入逻辑。工具的升级、参数变更、权限调整,也会牵涉到所有使用方。
MCP,即模型上下文协议,是一套用于规范模型与外部工具、数据源之间交互的协议。它的目标是定义:
MCP 的核心价值是解耦。工具提供方按照协议暴露工具服务,Agent 按照协议发现和调用工具,双方不再需要理解各自内部的实现细节。
从架构上看,MCP 让工具调用从“代码内嵌”变成“协议交互”。工具可以独立部署、独立升级、独立授权,Agent 侧只需实现协议客户端即可。
Function Calling 解决的是“模型输出如何被程序可靠解析”的问题,它定义的是模型与 Agent 之间的输出格式约定。MCP 解决的是“Agent 如何以标准化方式发现和调用外部工具”的问题,它定义的是 Agent 与工具服务之间的接口规范。
两者处于不同层级:Function Calling 更靠近模型侧,MCP 更靠近工具侧。它们可以配合使用,也可以独立存在。
Skill 这个词在不同语境下有不同含义。在 AI 应用架构中,Skill 通常指一个封装好的能力单元。它可以包含:
一个 Skill 可能依赖 Function Calling 来解析参数,也可能通过 MCP 来调用外部服务,还可能使用 RAG 来获取知识。换句话说,Skill 是比上述概念更高一层的封装,它面向业务能力,而不是面向基础设施。
如果用一个比喻来区分:
下表从多个维度对这组概念进行对比:
| 维度 | Prompt | Memory | RAG | Agent | Function Calling | MCP | Skill |
|---|---|---|---|---|---|---|---|
| 主要解决的问题 | 如何触发模型能力 | 如何保持多轮对话状态 | 如何获取外部私有知识 | 如何代理模型完成操作 | 如何可靠解析模型参数 | 如何标准化工具接入 | 如何封装业务能力 |
| 所在层级 | 模型输入层 | 上下文构建层 | 知识检索层 | 应用编排层 | 模型输出约定层 | 工具协议层 | 业务封装层 |
| 是否依赖模型 | 是 | 否 | 部分依赖嵌入模型 | 是 | 是 | 否 | 组合使用 |
| 核心产物 | 文本输入 | 历史信息管理 | 文档检索结果 | 任务执行流程 | 结构化参数 | 工具接口定义 | 可复用能力单元 |
| 与模型的交互方式 | 直接输入 | 拼接进上下文 | 作为上下文注入 | 双向交互 | 结构化输出 | 间接通过工具结果 | 视内部实现而定 |
| 典型工程复杂度 | 低 | 中 | 中高 | 高 | 中 | 中高 | 视封装范围而定 |
如果你的应用场景中,用户会进行多轮追问,或者需要模型记住对话中的事实和偏好,那么 Memory 是必需的。实现时可以从简单的历史拼接开始,当上下文长度成为瓶颈时,再引入摘要压缩或向量化检索记忆。
如果模型需要频繁访问企业内部知识,或者知识更新频繁、不适合训练进模型参数,那么 RAG 是更合适的方案。RAG 特别适合文档问答、规章制度查询、技术支持知识库等场景。需要注意的是,RAG 的效果高度依赖文档质量和检索精度,不能解决所有知识获取问题。
如果应用需要执行实际操作,比如创建工单、查询订单、发送通知、调用业务接口,那么就需要 Agent 来协调。只有当模型需要在多个工具之间做选择、并传递参数时,Function Calling 才成为必要。如果只是简单的单工具调用,直接在业务代码中解析模型输出也未尝不可。
当你的工具数量较多,或者多个 Agent 应用需要复用同一组工具,或者工具由不同团队独立提供时,MCP 的价值就体现出来了。它能减少重复接入成本,规范工具治理。如果只有一个简单工具、只有一个调用方,引入 MCP 反而可能增加不必要的复杂度。
当一组能力需要在多个场景中复用,并且希望以统一方式对外提供时,可以考虑封装为 Skill。例如,“生成周报”“竞品分析”“合同条款比对”等,都可以设计为 Skill。Skill 的边界在于:如果能力过于通用,封装意义不大;如果能力过于场景化,复用价值有限。
误区一:把任何加了 Prompt 的流程都称为 Agent。 如果只是让模型按某个提示词输出,没有实际的工具调用与执行循环,称为 Agent 是不准确的。
误区二:认为 RAG 是模型的一部分。 RAG 是外部检索与上下文构建机制,模型本身并不知道自己在使用 RAG。它只是接收了包含检索结果的上下文。
误区三:把 MCP 等同于 Function Calling。 两者解决不同层级的问题,不能互相替代。Function Calling 不需要 MCP 也能工作,MCP 也不强制要求模型支持 Function Calling。
误区四:引入 Memory 就一定需要向量数据库。 对于低并发、短会话场景,简单的历史拼接和摘要压缩足够满足需求。向量化记忆适合长周期、大规模的用户记忆管理。
误区五:Skill 越多越好。 Skill 的价值在于复用和封装,而不是数量。大量低质量和不加维护的 Skill 反而会带来管理负担。
如果现有系统需要从简单提示词方案演进到 Agent 架构,或者从内嵌工具调用迁移到 MCP 协议,有几点需要提前关注:
模型能力评估:并非所有模型都稳定支持 Function Calling。在选型时需要确认模型对结构化输出的支持程度,尤其是参数提取的准确性和稳定性。
接口兼容性:从内嵌工具到标准化协议,会涉及工具注册方式、参数格式、错误处理机制的变化。建议先做小范围试点,验证工具发现和调用的可靠性。
上下文预算管理:引入 RAG 和 Memory 后,上下文长度会快速膨胀。需要建立截断、摘要、重排序等机制,避免超长上下文导致成本上升和输出质量下降。
权限与安全:当 Agent 能调用外部工具时,工具侧需要做独立的权限控制。模型输出不应直接作为敏感操作的授权依据,需要在执行层做校验。
可观测性:Agent 的执行链路比单次模型调用复杂得多。日志中应记录模型输入、工具调用、检索结果、最终输出等关键信息,方便排查“模型为什么没调用工具”“检索结果为什么没被使用”等问题。
Skill、MCP、RAG、Agent 这些概念并不是并列的四个模块,而是在大语言模型应用演进过程中,为解决不同问题而提出的工程方案。理解它们的关键,不是记住定义,而是搞清楚每个概念处于哪一层、解决什么问题、与其他概念如何衔接。
从最基础的 Prompt 开始,到通过 Context 和 Memory 构建多轮对话,再到通过 Agent 和 Function Calling 实现工具调用,再到通过 RAG 接入外部知识,最后通过 MCP 标准化工具服务,这条链路构成了当前大语言模型应用架构的常见骨架。Skill 则是在这条链路之上,面向业务的封装单元。
在实际选型时,应当从需求出发,判断当前需要解决的是哪一层的问题。如果只需要多轮对话,就先做好 Context 和 Memory;如果需要调用工具,再引入 Agent 和 Function Calling;如果工具生态复杂,再考虑标准化协议。避免为了概念完整而引入不必要的复杂度,才是更务实的工程思路。