深入浅出 GenAI 关键概念—— 从 RAG、Function Calling、MCP 到 AI Agent
简介
随着大语言模型飞速演进,其在知识时效、生成准确性以及与外部系统交互方面的局限也愈发显现。
为此,检索增强生成(RAG)、函数调用(Function Calling)、模型上下文协议(MCP)与 AI 智能体(AI Agent)等一系列技术相继涌现,为模型补足“知识新鲜度”与“操作执行力”。
近期 CloudCanal 也推出了 RagApi 功能,并引入了 MCP 协议。本文将聚焦 RAG、Function Calling、MCP、AI Agent 等核心概念,并介绍 CloudCanal 在 RAG 架构上的具体实现。
RAG:检索增强生成
RAG(Retrieval-Augmented Generation) 是一种将“检索”与“生成”结合的 AI 架构。与传统大模型直接回答问题不同,RAG 会先从外部知识库(如文档库、数据库、向量数据库)中找到与用户问题相关的上下文信息,再将这些内容作为提示输入给大语言模型,从而生成更加准确的回答。
RAG 的优势
- 模型不再完全依赖预训练知识,可结合实时或特定领域的信息;
- 对私有数据支持更强,安全性与定制性更高;
- 减少模型“胡编乱造”的情况,提高回答可靠性。
RAG 的工作流程
- 构建知识库:准备大量文本资料,并将其向量化,存储到向量数据库中(如 PGVector)。
- 相似度检索:用户提问时,问题也会被向量化,然后通过相似度计算检索出最相关的文本段落。
- 生成回答:将这些相关内容作为上下文,提供给生成模型,用于回答用户问题。
什么是向量?
在 RAG 的工作流程中,数据向量化是第一步。那么,什么是向量呢?
为了方便理解,让我们来举个例子。对于“苹果”这个概念,人类靠经验理解,但计算机不懂“苹果”,它需要一种可以量化的方式来表示这个词。
于是,AI 会用一种叫做嵌入的方式,把“苹果”变成一个高维度的向量(Embedding),比如:
[0.12, 0.85, -0.33, ..., 0.07](假设有 768 维)
你可以理解为:计算机试图用很多个“语义维度”来描述“苹果”这件事。例如:
- 第 12 维可能代表“是不是水果”
- 第 47 维可能代表“是不是食物”
- 第 202 维可能代表“是不是公司名字”
- 第 588 维可能代表“颜色偏红”
每一维都像是在回答一个隐形的问题,而这个维度上的数值就是模型给出的“打分”,越高表示这个特征越明显。
不同的词在这些语义维度上的“打分”不同,最终就构成了不一样的向量。
相似度如何计算?
虽然“苹果”和“香蕉”的词面不同, 但它们在语义向量空间中的表示非常相近——因为在很多语义维度上,它们的“打分”都很接近,这就是语义相似性。
我们可以用向量来描述这些词的语义特征。例如,每个词用 [类别, 可食性, 颜色] 三个维度表示如下:
词语 | [类别, 食用属性, 颜色] | 向量 | 说明 |
---|---|---|---|
苹果 | 食物 + 可食 + 红色 | [1.0, 1.0, 0.8] | 是食物,能吃,颜色偏红 |
香蕉 | 食物 + 可食 + 黄色 | [1.0, 1.0, 0.3] | 是食物,能吃,颜色偏黄 |
飞机 | 交通工具 + 不可食 + 银色 | [0.1, 0.1, 0.9] | 是交通工具,不能吃,金属色居多 |
在语义向量中,我们判断两个词是否相似,看的不是它们的数值大小,而是它们“指向的方向”是否一致。为此,我们通常使用 余弦相似度。
cos(θ) = (A · B) / (||A|| × ||B||)
它的核心思想是:比较两个向量之间的夹角。
- 夹角越小 → 方向越一致 → 语义越相似(cos θ 接近 1)
- 夹角越大 → 方向越偏离 → 语义差异越大(cos θ 接近 0,甚至为负)
Function Calling:让模型具备调用工具的能力
在日常对话中,大模型通常只需返回文字答案。但当用户提出诸如“帮我查一下明天北京的天气”这类超出模型内置知识范围的问题时,就需要借助 Function Calling,即让 AI 调用外部工具来完成任务。
Function Calling 的核心作用在于让模型具备以下能力:
- 判断当前问题是否需要使用工具
- 自动提取参数,并以结构化 JSON 形式生成调用指令
- 将调用交由程序执行,并接收返回结果,用于后续生成回复。
Function Calling 操作示例
举个例子:用户说
“我明天要去北京旅游,请帮我查天气”
AI 会这样处理:
- 提取参数:城市 “北京”,时间 “明天”
- 制定计划:调用 get_weather 工具获取天气信息
- 生成调用指令:输出包含一次对 get_weather 的 tool_call,并传入所需参数