# 1-3 RAG、微调、续训与智能体选型

当单靠提示词工程无法满足需求时，就要开始考虑更进一步的工程手段。本篇围绕五大模块中的后四项展开：**RAG、微调、续训、智能体开发**。它们表面上都在“增强模型能力”，实际解决的问题并不一样。

---

**本章课程目标：**

- 建立一张清晰的选型地图：知道 **RAG、微调、续训、智能体** 分别在解决什么问题。
- 理解 RAG 的核心价值是**补知识**，理解微调的核心价值是**改行为**，理解续训的核心价值是**补领域分布**。
- 理解智能体并不是“更强的大模型”，而是**大模型 + 工具 + 状态 + 执行流程**的系统。
- 能结合真实项目判断：什么时候继续优化 Prompt，什么时候上 RAG，什么时候考虑微调，什么时候再引入工作流（Workflow）或 Agent。

**学习建议：** 学这章时，建议始终围绕三条线来判断方案：**知识够不够、行为稳不稳、流程会不会动。**如果缺的是知识，先看 RAG；如果缺的是输出风格、格式、指令遵循，先看微调；如果缺的是更底层的领域语言能力，才考虑续训；如果缺的是多步决策、外部工具调用和执行能力，再看智能体。这样你就不会把几种方案混成一团。

**官方文档与资源**：详见 [工具导航与参考资料索引 - 微调与模型对齐](工具导航与参考资料索引.md#微调与模型对齐)、[工具导航与参考资料索引 - RAG与向量检索](工具导航与参考资料索引.md#rag与向量检索)、[工具导航与参考资料索引 - 工具调用、MCP与智能体](工具导航与参考资料索引.md#工具调用、MCP与智能体)。

---

## 1、问题诊断

真实项目里，AI 应用回答不好时，最容易犯的错误是：还没判断问题根因，就直接说“要不要微调”“要不要上 Agent”。

先问四个问题会稳很多：

| 诊断问题                           | 常见现象                                             | 优先考虑                |
| ---------------------------------- | ---------------------------------------------------- | ----------------------- |
| 模型是不是没看到资料？             | 不知道公司制度、产品手册、最新公告，回答没有引用依据 | RAG                     |
| 模型是不是行为不稳定？             | 格式飘、话术不统一、分类标签不稳、JSON 经常错        | Prompt 优化，必要时微调 |
| 模型是不是不懂这个领域的语言分布？ | 拿到资料也读不懂，专业术语和行业逻辑经常错           | 续训，通常再配合 RAG    |
| 任务是不是需要多步执行？           | 需要查资料、调接口、校验、重试、写入系统             | 工作流或 Agent          |

![从提示词、RAG、微调、续训到智能体的方案诊断关系图](images/1-3/1-3-1-1-1.png)

1. **先 Prompt**：如果只是需求表达不清，先把输入、输出、约束写清楚。
2. **再 RAG**：如果缺的是资料、依据、最新信息或私有知识，优先建知识库。
3. **再微调**：如果长期行为不稳，并且有高质量样本和评测标准，再考虑微调。
4. **慎用续训**：只有当模型对领域语言和知识分布系统性陌生时，才考虑续训。
5. **流程固定先工作流**：步骤明确、需要稳定可审计时，优先 Workflow。
6. **流程开放再 Agent**：步骤会变化、需要动态选工具和根据中间结果调整路线时，再上 Agent。

后面的方案不是“不高级”，只是成本、风险和维护压力更高。能用轻方案稳定解决的问题，就不要过早引入重方案。

## 2、RAG

### 2.1 什么是 RAG

**1）定义**

RAG（Retrieval-Augmented Generation，检索增强生成）是一种把**信息检索**与**大模型生成**结合起来的应用架构。

基本流程并不复杂：

1. 用户先提问。
2. 系统先去外部知识库里找相关资料。
3. 再把“问题 + 检索结果”一起发给大模型。
4. 由模型基于这些资料生成答案。

RAG 的重点不是“修改模型参数”，而是**在运行时给模型补充它当前需要的上下文**。

先记住这个最短定义：**RAG = 先查资料，再回答问题。**

这和 [1-2 提示词工程基础](1-2-提示词工程基础.md) 的区别也很重要：

- **提示词工程**主要依赖你提前写好的 Prompt。
- **RAG**主要依赖系统在提问时实时检索到的外部资料。

![RAG 的基本流程：先检索外部资料，再把结果与问题一起交给大模型生成答案](images/1-3/1-3-2-1-1.png)

### 2.2 为什么 RAG 往往是项目里的第一选择

从工程角度看，RAG 之所以常常先于微调和续训，不是因为它“最先进”，而是因为它**最符合大量知识类业务问题的真实成因**。

真实项目里，大模型答不好，常见原因通常有三类：

- **知识过时**：例如最新政策、最新产品说明、最新公告。
- **知识私有**：例如企业制度、内部接口文档、项目手册、客户资料。
- **证据不足**：模型有通用知识，但没有你当前要它参考的那份资料，因此容易幻觉。

这三类问题，本质上都更像“模型没看到材料”，而不是“模型不会说话”。这时最先应该验证的，往往不是训练模型，而是**能不能把资料喂对**。RAG 正是解决这个问题的。

它的现实优势主要有：

- **更新快**：知识库更新后可以重新建索引，不必重新训练模型。
- **成本低**：相比微调和续训，实施门槛和试错成本通常更低。
- **可追溯**：检索结果可以保留来源、页码、文件名，方便核验。
- **更贴近业务系统**：文档、数据库、FAQ、接口说明等都可以成为外部知识源。

在本仓库里，RAG 不是一个孤立概念，而是后续很多章节的主线能力：

- [2-RAG-搭建企业私有&个人知识库](2-RAG-搭建企业私有&个人知识库.md) 会从平台角度带你搭建知识库。
- [19-RAG检索增强生成](19-RAG检索增强生成.md) 会从 LangChain 代码角度带你拆开 RAG 的技术链路。
- `电商问数` 项目里，系统也不是“直接把问题交给模型”，而是先通过 **MySQL + Qdrant + Elasticsearch** 组成的元数据知识库做多路召回，再生成 SQL。这属于面向结构化问数场景的 RAG 思路。

### 2.3 RAG 的工作流程

虽然 RAG 常被一句话概括成“先检索，再生成”，但在工程上，它通常分成两个阶段：

**阶段一：知识库构建（离线）**

- 读取原始文档
- 做清洗和切分
- 用嵌入模型把文本块转成向量
- 把文本块、向量和元数据写入向量数据库

**阶段二：检索与生成（在线）**

- 用户发起问题
- 将问题向量化
- 从知识库中召回相关片段
- 把片段与问题一起组装进 Prompt
- 交给大模型生成最终回答

这条链可以拆成：

- **索引阶段**解决“资料怎么准备好”
- **问答阶段**解决“资料怎么在提问时被找出来并用上”

因此，RAG 从来不只是“向量库 + 大模型”这么简单。文档质量、分块策略、召回方式、重排策略、Prompt 组织方式，都会影响最终效果。

### 2.4 何时需要 RAG

当你遇到下面这些场景时，优先验证 RAG 通常是比较稳妥的：

- 需要接入**企业内部资料**、产品文档、FAQ、制度手册、接口说明等私有知识
- 需要回答**最新信息**、时效性很强的问题
- 希望回答结果能附带**依据和来源**
- 希望在不改模型参数的情况下，快速迭代知识内容

典型场景包括：

- 企业知识库问答
- 智能客服与售后助手
- 研发文档问答
- 运维排障助手
- 合同、制度、政策、课程讲义等文档问答

### 2.5 实现方式

RAG 的实现方式大致可以分为三类：

**（1）在线平台**

例如 Cherry Studio、ima、Dify、FastGPT、RAGFlow 等。优点是上手快、可视化、验证快，适合入门或快速搭原型。

**（2）离线客户端**

例如本地知识库客户端、桌面 AI 工具，适合个人知识管理和轻量实验。

**（3）借助框架或纯代码实现**

例如基于 LangChain、LangGraph 或纯 Python 自己搭建完整的文档加载、切分、向量化、检索和生成流程。这种方式灵活度最高，也最接近真实项目开发。

### 2.6 RAG 的几个常见误区

**误区 1：有知识库就一定不会幻觉**

不是。RAG 只能显著降低幻觉，不能保证 100% 正确。检索错了、召回噪声太多、Prompt 没约束好，模型仍然可能答错。

**误区 2：文档全塞进去就行**

不是。RAG 的关键不是“文档数量多”，而是“**能不能把相关的那几段稳稳找出来**”。

**误区 3：RAG = 向量检索**

也不完全对。向量检索只是常用手段，真实项目里经常会结合关键词检索、过滤、重排、元数据约束一起使用。

**误区 4：RAG 能替代一切训练**

不能。RAG 解决的是“模型没看到知识”的问题，不擅长解决“模型不会按固定风格/格式输出”的问题。

### 2.7 RAG 效果不好时，先看哪里

RAG 上线后效果不理想，不要马上得出“RAG 不行”或“必须微调”的结论。先沿着链路拆问题：

| 问题位置    | 典型表现                              | 优先排查                                      |
| ----------- | ------------------------------------- | --------------------------------------------- |
| 文档质量    | 原文过期、冲突、缺页、扫描件 OCR 错误 | 更新资料、清洗文档、保留版本和来源            |
| 文档解析    | 表格、标题、层级、图片说明被解析乱    | 更换解析器，必要时引入人工校验                |
| 文本切分    | 检索片段太碎或太长，答案上下文不完整  | 调整 chunk size、overlap、按标题层级切分      |
| 召回策略    | 找不到正确片段，或者召回一堆无关内容  | 调整 Embedding、Top-K、关键词检索、元数据过滤 |
| 重排序      | 正确片段被排到后面                    | 引入 Reranker 或调整重排模型                  |
| Prompt 增强 | 检索到了资料，但模型没按资料答        | 明确要求引用资料、缺依据时说明“不确定”        |
| 生成模型    | 资料正确但推理仍错                    | 更换模型、加强约束，必要时再看微调或续训      |

这张表背后的原则是：

> **RAG 失败先修检索链路，再看生成模型；不要把所有问题都归因于“模型不够强”。**

---

## 3、微调（Fine-tuning）

### 3.1 什么是微调

微调（Fine-tuning）是指在已经训练好的基础模型上，继续用特定数据做训练，使模型在某类任务、某种风格或某种输出形式上表现更稳定。

在工程语境里，可以记住这句话：**微调主要是在改模型的“行为方式”，而不是在给模型外挂一套知识库。**

它最常见的目标包括：

- 让模型更稳定地遵循指令
- 让模型输出固定格式，例如 JSON、SQL、标签、分类结果
- 让模型更符合某种业务风格、品牌口吻或术语习惯
- 让模型在某类任务上更稳，例如分类、抽取、代码补全、客服回复

需要特别提醒的是，微调虽然也可能让模型“记住一些样例”，但它**并不适合承载高频变化的知识**。如果知识经常变，仍然应该优先考虑 RAG 或外部知识源。

> **你可能会问：** 微调是不是把企业资料“灌进模型里”？
> 更贴切的说法是：微调更擅长让模型“按你想要的方式做事”，而不是“记住所有最新资料”。知识经常变化的场景，优先考虑 RAG；风格、格式、任务习惯长期不稳的场景，再考虑微调。

### 3.2 何时需要微调

当你遇到下面这些问题时，微调才更可能是对路的方案：

**（1）模型行为不稳定**

比如：

- 明明已经写了输出格式，还是经常不按格式来
- JSON、SQL、分类标签这类输出经常飘
- 多轮提示后仍然经常漏字段、漏步骤

**（2）风格和话术需要长期固化**

例如：

- 客服回复要长期保持统一口吻
- 某行业报告要始终遵循同一种写作规范
- 品牌文案需要稳定体现品牌语气

**（3）提示词已经很重，但效果还是不稳**

如果你已经反复优化 Prompt、增加示例、做结构化约束，效果仍然不理想，说明问题可能不只是“提示没写好”，而是模型对这类任务的行为模式还不够稳定。

### 3.3 何时可以微调

不是所有团队都适合上来就微调。一般至少要满足下面两个前提：

**（1）数据足够**

微调依赖的是**高质量、任务相关、标注明确**的数据。没有好数据，微调很容易沦为“把噪声训练进模型”。

**（2）评测标准清楚**

如果你连“什么叫变好了”都说不清，就很难知道微调到底有没有价值。真实项目里，先做清楚评测集和验收标准，往往比先开始训练更重要。

**（3）算力与预算可接受**

虽然微调远比续训便宜，但依然需要训练资源、数据清洗和评测成本。

### 3.4 微调的技术方法

随着模型越来越大，全参数微调并不是大多数团队的首选。工程上更常见的是参数高效微调。

**（1）全参数微调（Full Fine-tuning）**

更新模型全部参数，理论上上限更高，但训练资源和显存开销都很大，适合资源充足、目标明确的场景。

**（2）参数高效微调（PEFT, Parameter-Efficient Fine-Tuning）**

这类方法的核心思路是：**尽量少改参数，用更低成本获得可接受的效果。**

最常见的两种是：

- **LoRA**：冻结原模型大部分参数，只训练新增的低秩适配参数。
- **QLoRA**：在 LoRA 基础上结合低比特量化，进一步降低显存占用。

**（3）其他高效方法**

- `Adapter Tuning`：在模型层间插入小型适配器模块
- `Prefix Tuning`：在输入前添加可学习的虚拟前缀
- `P-Tuning v2`：在模型每一层添加可训练的提示向量

这些方法你在入门阶段不必死记公式，但要建立一个工程认知：
**今天大多数团队如果自己做微调，优先考虑的通常不是全参，而是 LoRA / QLoRA 这类 PEFT 路线。**

### 3.5 主要风险

微调并不是“只要训一下就更强”，它的常见风险包括：

- **过拟合**：训练集表现很好，真实场景一塌糊涂
- **灾难性遗忘**：模型学了新任务，原有能力被冲掉
- **样本偏差**：把团队自己的偏见、噪声、错误格式一起学进模型
- **评测幻觉**：只看少量样例感觉“效果不错”，但没有系统评测

所以微调前后都要问自己：
**我到底是在解决一个长期、稳定、可评测的行为问题，还是只是暂时觉得 Prompt 写得不够顺手？**

### 3.6 RAG vs 微调

RAG 和微调常被混在一起。工程上先看这条分工：

- **RAG 更偏补知识**
- **微调更偏改行为**

![RAG、微调等方案在“补知识”和“改行为”上的分工对比示意图](images/1-3/1-3-3-6-1.png)

先用下面这张工程对照表来建立判断：

| 维度           | RAG                        | 微调（Fine-tuning）        |
| -------------- | -------------------------- | -------------------------- |
| 核心目标       | 给模型补充外部知识         | 让模型更稳定地按目标做事   |
| 是否修改参数   | 否                         | 是                         |
| 更适合解决什么 | 私有知识、最新知识、可追溯 | 风格、格式、指令遵循、分类 |
| 更新速度       | 快，改知识库即可           | 慢，需要重新训练           |
| 成本结构       | 系统开发成本为主           | 数据、训练、评测成本为主   |
| 典型场景       | 文档问答、知识库、客服知识 | 结构化输出、统一话术       |

最常见的判断口诀是：

- **缺知识**：先看 RAG
- **缺行为**：再看微调

---

## 4、续训（Continued Training）

### 4.1 什么是续训

续训通常对应的是 **Continued Pretraining**，也就是在模型已经完成通用预训练后，再用某一领域的大规模原始语料继续训练，让模型更熟悉该领域的语言分布、术语体系和知识结构。

简要概括：**续训是让模型“更懂某个世界”，微调是让模型“更会按要求做事”。**

和微调相比，续训更接近预训练逻辑，通常使用的是**海量无标注文本**，而不是精心整理的“指令 - 答案”样本。

### 4.2 何时需要续训

只有在下面这类场景里，续训才比较值得考虑：

- 模型对某个领域语言分布存在明显系统性缺失
- 不是只差几个术语，而是整套领域表达都“不像这个行业的人”
- RAG 和微调都无法很好弥补这种底层缺口

例如：

- 大规模法律、医疗、金融、代码语料的领域适配
- 新语言、冷门编程语言、专业文献体系的长期能力增强
- 需要让模型在某个垂直领域具有更自然的基础表达和理解能力

### 4.3 何时可以续训

续训对资源要求比微调高得多，通常需要同时满足：

**（1）数据充足**

需要的是大量高质量原始文本，而不是少量指令样本。规模往往是 GB 到 TB 级。

**（2）硬件充足**

续训通常需要更长训练时间、更高显存、更强的数据处理能力。

**（3）业务收益足够大**

多数企业项目用不到续训。因为它成本高、风险高、迭代慢，很多问题用 `RAG + Prompt` 或 `RAG + 微调` 已经能解决。

### 4.4 工程实践中的常见误区

**误区 1：把 SFT 样本拿去做续训**

续训更接近语言建模，不是拿“问答对”硬灌进去。

**误区 2：把领域知识缺失问题全都交给微调**

如果模型连该领域“说话方式”都不熟，单靠微调往往不够稳。

**误区 3：企业项目动不动就想续训**

这是最常见的误区。绝大多数业务问题，没必要一上来就碰续训。

### 4.5 微调 vs 续训

很多团队之所以“做了训练但效果一般”，往往就是把本该续训的问题拿去微调，或者反过来。

**1）先做区分**

微调：让模型“按你想要的方式做事”。具体的：行为对齐／风格对齐／任务对齐。

续训：让模型“知道它原来不知道的世界”。具体的：知识扩充／语言分布补全／能力下沉。

**2）核心对比总览**

| 维度         | 微调（Fine-tuning）      | 续训（Continued Pre-training） |
| ------------ | ------------------------ | ------------------------------ |
| 训练目标     | 改行为方式               | 改知识分布 / 语言分布          |
| 数据形式     | 指令数据、对话数据、标签 | 大规模原始文本                 |
| 是否依赖标注 | 强依赖                   | 通常不依赖                     |
| 数据规模     | 千级、万级、十万级       | 十万级、百万级、海量语料       |
| 算力成本     | 低到中                   | 高                             |
| 常见方法     | LoRA / QLoRA / PEFT      | 更接近预训练流程               |
| 典型问题     | 格式、风格、指令遵循     | 领域语言理解和分布偏差         |

**3）典型应用场景对照**

| 场景                         | 正确选择                                   |
| :--------------------------- | :----------------------------------------- |
| 客服机器人更像「某公司风格」 | 微调                                       |
| 模型学会某行业黑话           | 续训                                       |
| 提高 SQL 生成稳定性          | 微调                                       |
| 让模型理解行业文档           | 通常先 RAG；模型读不懂领域语言时再评估续训 |
| 新语言/新编程语言            | 续训                                       |
| 工具调用意图和参数格式更稳定 | 微调或更强工具调用模型                     |

**4）工程上的组合拳**

实际项目中，很少“二选一”，而是：

一条常见训练路线可以理解为：通用基座模型 → 领域续训（补领域分布）→ 指令微调（对齐行为）→ RLHF / RLAIF（优化偏好）

这不是每个企业项目都要完整走一遍的固定流程，而是理解训练层次的参考路线。大多数应用团队更常见的路径是：先选合适基座模型，再用 `Prompt + RAG + 工作流 / Agent` 做应用层增强；只有当行为稳定性、领域语言分布或工具调用数据确实成为瓶颈时，才进入微调或续训。

如果确实要组合训练，顺序通常不能随意反过来。因为如果你先微调，再做大规模续训，前面学到的行为模式可能会被冲掉。

> **记法：** **续训** = 让模型更熟悉某个领域的语言和分布；**微调** = 让模型更稳定地按你想要的方式做事；**RAG** = 在运行时把资料和证据补给模型。工程上多数知识类场景先用「RAG + 提示词」验证，行为类问题再评估微调，续训放在更重、更后的位置。

---

## 5、智能体开发

### 5.1 什么是智能体？

在经典 AI 语境里，智能体（Agent）指能够感知环境、做出决策并执行动作，以实现目标的系统。

放到大模型应用开发里，更工程化的定义是：

> **智能体 = 大模型 + 工具 + 状态 + 执行流程**

智能体并不只是“会聊天的模型”，而是一个能够：

- 理解用户目标
- 决定下一步做什么
- 选择是否调用工具
- 接收工具结果
- 基于结果继续决策
- 直到完成任务的系统

五大核心要素通常包括：

- 大语言模型（LLM）
- 记忆系统（Memory）
- 工具调用（Tools）
- 规划决策（Planning）
- 行动执行（Action）

OpenAI 前安全系统团队负责人`翁丽莲`于 2023 年 6 月在个人博客系统化总结了当时流行的 LLM Agent 典型架构。

![典型 LLM Agent 架构：模型、记忆、工具、规划和行动执行协同工作](images/1-3/1-3-5-1-1.jpg)

**与单纯大模型的本质区别：**

- 大模型主要负责“生成回答”
- 智能体负责“围绕目标持续决策并执行动作”

例如：

- 单纯大模型会告诉你“可以查天气 API”
- 智能体会真的去调天气 API，再把结果组织成回答

### 5.2 何时需要智能体

当任务开始呈现下面这些特征时，就要认真考虑智能体：

- 任务是**多步骤**的，而不是一句话能答完
- 需要**调用外部工具**，例如天气、搜索、数据库、浏览器、发消息
- 中间结果会影响后续动作，流程不是完全固定的
- 需要一定的状态管理、规划、失败重试或反思机制

例如：

- “先查知识库，再查数据库，再生成一份报告”
- “先查库存，再查价格，再决定推荐哪一款商品”
- “先检索用户资料，再调外部系统完成操作，再返回结果”

在本仓库里，智能体这条主线后续会继续展开：[3-基于 Coze&Dify 平台的智能体开发](3-基于Coze&Dify平台的智能体开发.md)、[20-MCP模型上下文协议](20-MCP模型上下文协议.md)、[21-Agent智能体](21-Agent智能体.md)、[22-LangGraph概述与快速入门](22-LangGraph概述与快速入门.md)

`电商问数` 项目里，虽然主体是面向 SQL 生成的工作流（Workflow），但它本质上也体现了“检索、筛选、生成、校验、执行”的多步智能体 / 工作流思路。

> **粗略区分：** Prompt 更像“把问题问清楚”，RAG 更像“先给模型补资料”，Agent 更像“把一件事做完”。

### 5.3 工具调用的实现方式

#### 5.3.1 Tool Calls / Function Calling

**1、定义**

Tool Calls / Function Calling（函数调用，也常写作 Function Call、Tool Calling、工具调用）是模型和外部工具交互的一种标准能力。模型不会自己真的调用天气接口、数据库或发邮件接口，而是会根据工具描述，先输出“应该调用哪个工具、传什么参数”，然后由你的代码真正执行。

这里的分工是：

- **模型负责决定**
- **程序负责执行**

这就是 Function Calling 的本质。

**2、流程**

![Function Calling 的基本流程：模型决定工具和参数，程序负责真正执行](images/1-3/1-3-5-3-1.jpg)

![Function Calling 在实际接口调用中的工具声明与参数返回示意图](images/1-3/1-3-5-3-2.jpg)

**3、演示**

以 DeepSeek 官方 API 为例演示 Tool Calls / Function Calling。整体流程共五步：

① 告诉模型「有哪些工具、用户说了什么」；

② 模型决定「要调哪个工具、传什么参数」并返回；

③ 我们的代码真正执行工具拿到结果；

④ 把工具结果塞回对话发给模型；

⑤ 模型根据结果生成最终回复。

（1）步骤一：**定义工具 + 发用户消息**

**作用：**把「用户问了什么」和「你现在允许模型用哪些工具」一次性交给模型。模型没有内置天气接口，只有你通过 `tools` 传了 `get_weather` 的 name、description 和 parameters，它才知道可以调用这个工具。

```bash
curl https://api.deepseek.com/chat/completions \
 -H "Content-Type: application/json" \
 -H "Authorization: Bearer ${API_KEY}" \
 -d '{
 "model": "deepseek-v4-flash",
 "messages": [
    {
     "role": "system",
     "content": "你是个智能天气查询助手，根据用户的提问自主调用工具"
    },
    {
     "role": "user",
     "content": "北京市天气如何？"
    }
  ],
   "tools": [
    {
     "type": "function",
     "function": {
      "name": "get_weather",
      "description": "根据用户输入的城市信息，获取该城市的天气",
      "parameters": {
       "type": "object",
       "properties": {
        "city": {
         "type": "string",
         "description": "城市名称，只保留最细粒度的地区名称"
        }
       },
       "required": ["city"]
      }
     }
    }
   ]
  }'
```

（2）步骤二：**模型返回“要调哪个工具、参数是什么”**

**作用：**模型根据上下文判断需要查天气，于是返回 `tool_calls`。注意这里它只是“提出调用请求”，并没有真的去执行天气接口。

```json
{
  "id": "7cccd00d-f0a5-4b2e-872c-a54bdb767796",
  "object": "chat.completion",
  "created": 1767176438,
  "model": "deepseek-v4-flash",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "我来帮您查询北京市的天气情况。",
        "tool_calls": [
          {
            "index": 0,
            "id": "call_00_Kpq3g6mPl9BYlZIe1NSNm3Cs",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\": \"北京\"}"
            }
          }
        ]
      },
      "logprobs": null,
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 336,
    "completion_tokens": 52,
    "total_tokens": 388,
    "prompt_tokens_details": {
      "cached_tokens": 0
    },
    "prompt_cache_hit_tokens": 0,
    "prompt_cache_miss_tokens": 336
  },
  "system_fingerprint": "fp_eaab8d114b_prod0820_fp8_kvcache"
}
```

（3）步骤三：**在本地/服务端真正执行工具**

**作用：**你的程序根据步骤二里的 `name` 和 `arguments` 去真正执行天气函数或第三方 API 请求，并得到真实结果。这里为了教学，直接给出假设返回值。

```json
{
  "temp": "2℃",
  "text": "晴",
  "wind": "西北风3级"
}
```

（4）步骤四：**把工具结果塞回对话，再请求模型**

**作用：**模型必须“看到”工具执行结果，才能生成最终面向用户的自然语言回答。

```bash
curl https://api.deepseek.com/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${API_KEY}" \
  -d '{
  "model": "deepseek-v4-flash",
  "messages": [
        {
          "role": "system",
          "content": "你是个智能天气查询助手，根据用户的提问自主调用工具"
        },
        {
          "role": "user",
          "content": "北京市天气如何？"
        },
        {
            "role": "assistant",
            "content": "我来帮您查询北京市的天气情况。",
            "tool_calls": [
                {
                    "index": 0,
                    "id": "call_00_Kpq3g6mPl9BYlZIe1NSNm3Cs",
                    "type": "function",
                    "function": {
                        "name": "get_weather",
                        "arguments": "{\"city\": \"北京\"}"
                    }
                }
            ]
        },
        {
          "role": "tool",
          "tool_call_id": "call_00_Kpq3g6mPl9BYlZIe1NSNm3Cs",
          "content": "{\"temp\":\"2℃\",\"text\":\"晴\",\"wind\":\"西北风3级\"}"
        }
      ],
      "tools": [
        {
          "type": "function",
          "function": {
            "name": "get_weather",
            "description": "根据用户输入的城市信息，获取该城市的天气",
            "parameters": {
              "type": "object",
              "properties": {
                "city": {
                  "type": "string",
                  "description": "城市名称，只保留最细粒度的地区名称"
                }
              },
              "required": ["city"]
            }
          }
        }
      ]
    }'
```

（5）步骤五：**模型根据工具结果生成最终回复**

**作用：**这一步模型不再返回 `tool_calls`，而是直接给用户最终答案。

```json
{
  "id": "4f5f2133-6519-497e-aecc-2bd25a37c747",
  "object": "chat.completion",
  "created": 1767177264,
  "model": "deepseek-v4-flash",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "根据查询结果，北京市当前的天气情况如下：\n\n- **温度**：2℃\n- **天气状况**：晴\n- **风力**：西北风3级\n\n今天北京天气晴朗，温度在2℃左右，风力不大，是个不错的天气。建议您外出时适当保暖，虽然天气晴朗但温度还是偏低的。"
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 422,
    "completion_tokens": 70,
    "total_tokens": 492,
    "prompt_tokens_details": {
      "cached_tokens": 384
    },
    "prompt_cache_hit_tokens": 384,
    "prompt_cache_miss_tokens": 38
  },
  "system_fingerprint": "fp_eaab8d114b_prod0820_fp8_kvcache"
}
```

**4）Function Calling 的不足**

**（1）工具实现与复用成本高**

很多工具是某个项目自己定义的，和业务环境耦合较重，不容易跨团队、跨客户端复用。

**（2）规范碎片化**

不同模型厂商的工具调用格式、字段命名、细节行为并不完全一致，维护成本会逐渐上升。

**（3）可靠性依赖工具描述质量**

工具描述不清、参数 schema 不完整时，模型就更容易调错工具或传错参数。

#### 5.3.2 MCP

**1、定义**

MCP（Model Context Protocol，模型上下文协议）是一套面向 AI 应用与外部能力连接的开放协议。它的核心含义是：

> **MCP 是把“工具、资源、提示模板”等能力按统一方式暴露出来的一层标准接口。**

MCP 更关注的是“**怎么统一接入和复用外部能力**”，而不仅仅是“模型会不会调某个函数”。

MCP 就像 AI 世界的 USB-C 接口。只要某个能力按 MCP 标准暴露出来，支持 MCP 的不同 AI 应用就可以更容易地发现和使用它。

![MCP 像 AI 世界的 USB-C 接口，用统一协议暴露工具、资源和提示模板](images/1-3/1-3-5-3-3.jpg)

**Function Calling 与 MCP 的关系与区别**

Function Calling 和 MCP 不是同一个东西，但经常会一起出现。

|            | **Function Calling**         | **MCP**                            |
| ---------- | ---------------------------- | ---------------------------------- |
| **是什么** | 模型调用工具的能力           | 一套标准化通讯协议                 |
| **关注点** | 模型怎么表达“我要调哪个工具” | 工具和资源怎么统一暴露、发现和复用 |
| **作用**   | 让模型能调用外部能力         | 让外部能力能被不同 AI 应用统一接入 |
| **适用层** | 更偏模型调用层               | 更偏应用接入层 / 工具生态层        |

更容易记的方式是：

- **Function Calling**：模型侧的调用能力
- **MCP**：工具侧的标准化暴露方式

**2、流程**

![MCP 的调用流程：主机、客户端和服务器之间如何完成能力发现与调用](images/1-3/1-3-5-3-4.jpg)

MCP 本质上是对“工具接入”做了进一步标准化。除了 Tools，它还支持 Resources 和 Prompts。

最常用的是 **Tools**，但它的设计范围比传统 Function Calling 更大。

**MCP 使用理解（以 Cherry Studio + 天气为例）**

可以按这个关系理解：

- **MCP 是协议**
- **天气 MCP Server 是实现了该协议的服务**
- **Cherry Studio 是支持该协议的客户端**
- **DeepSeek / 其他模型仍然在负责理解用户意图并决定是否调用工具**

所以当你在 Cherry Studio 里连接了天气 MCP Server，再问“北京天气怎么样”时，背后不是模型自己突然学会了天气接口，而是：

1. 客户端把可用工具列表告诉模型
2. 模型决定调用 `get_weather`
3. 客户端通过 MCP 调用对应 Server
4. Server 返回天气结果
5. 模型再把结果组织成自然语言

**大模型如何知道“什么时候调”“调哪一个”？**

- **什么时候调？**
  因为客户端会把当前所有可用工具及其描述发给模型，模型根据用户问题和工具描述，判断是否需要调用。

- **调哪一个？**
  因为每个工具都有 `name`、`description`、`parameters`，模型会根据用户问题和工具描述进行匹配。

所以模型并不是“认识 MCP”本身，而是认识“这次请求里有哪些可用工具”。

**3、相较于 Function Calling 的优势**

MCP 一定程度上弥补了 Function Calling 在生态层面的不足：

- **复用更强**：一个 MCP Server 可以被多个客户端复用
- **适配更统一**：不同 AI 应用按同一协议接能力
- **更利于形成工具生态**：工具不再只服务某个单一应用

### 5.4 智能体开发方式

当前常见的智能体开发方式主要有两类：

**（1）在线平台开发**

例如 Dify、Coze。这类方式上手快，适合做可视化编排和快速原型。

**（2）基于框架开发**

例如 LangChain、LangGraph。这类方式自由度更高，更适合真实项目开发和复杂业务逻辑落地。

### 5.5 工作流（Workflow）

**1、什么是工作流**

工作流（Workflow）是一种更强调**固定步骤和可控执行**的设计模式。它通常用于把复杂任务拆成一系列明确步骤，并按预设顺序执行。

![工作流更强调固定步骤、可控执行和明确顺序的流程编排方式](images/1-3/1-3-5-5-1.jpg)

例如：先分类、再检索、再生成、再校验、再输出。

这类场景不一定需要 Agent 临场自由决策，更适合工作流。

比如：讯飞星辰 Agent 平台：https://agent.xfyun.cn/home

**2、工作流（Workflow）和 Agent 怎么区分**

这是实际项目里的常见判断。

| 场景特征                             | 更适合什么         |
| ------------------------------------ | ------------------ |
| 步骤固定、顺序明确、强调可控和稳定   | 工作流（Workflow） |
| 步骤不固定、需要动态选工具和持续决策 | Agent              |

所以很多真实系统并不是“只做 Agent”或者“只做工作流（Workflow）”，而是：

**固定部分用工作流（Workflow），动态部分再交给 Agent。**

`电商问数` 就很适合拿来理解这件事。它不是放任模型完全自由发挥，而是先做召回、再做生成、再做校验和执行，整体更接近 **工作流（Workflow）主导 + 大模型参与关键节点决策** 的工程思路。

**3、工作流开发方式**

（1）Dify、Coze 等在线平台开发工作流

（2）基于 LangChain / LangGraph 等框架开发工作流

---

**章节思考题：**

1. 当一个 AI 应用回答不好时，你如何判断问题是“缺知识”“行为不稳”，还是“流程没设计好”？

   **参考思路：** 先看错误类型：不知道公司资料、引用过时信息，多半缺知识，优先 RAG；格式、语气、分类口径反复飘，多半行为不稳，可先优化 Prompt，再评估微调；需要多步查找、校验、执行，则是流程问题，优先工作流或 Agent。

2. 为什么内部知识库问答通常不应该一上来就做微调？

   **参考思路：** 内部资料经常变化，微调把知识写进模型参数，更新成本高且可追溯性弱。RAG 可以保留资料来源，更新文档即可生效，更适合私有知识、制度、FAQ、产品手册这类场景。

3. 续训、微调和 RAG 都能让模型“更懂业务”，但代价和风险有什么不同？

   **参考思路：** RAG 代价最低，主要风险在检索质量；微调代价中等，风险在数据质量和行为泛化；续训最重，涉及大规模语料、算力、稳定性和评测。项目选型时应先用轻方案验证，再考虑重方案。

4. 什么时候固定工作流比 Agent 更合适？

   **参考思路：** 当步骤稳定、责任清晰、需要审计和可解释时，工作流更合适，比如先召回、再过滤、再生成、再校验。Agent 更适合步骤不固定、需要临场选工具和根据中间结果调整路线的任务。

**本章小结：**

- **RAG** 解决的是“模型没看到知识”的问题，尤其适合私有知识、最新知识、可追溯问答。它不改模型参数，而是在运行时补上下文。
- **微调** 解决的是“模型行为不稳定”的问题，更适合风格、格式、指令遵循、结构化输出等长期一致性要求高的场景。
- **续训** 解决的是“模型底层领域分布不熟”的问题，成本高、门槛高，不应成为大多数项目的第一选择。
- **智能体** 解决的是“怎么围绕目标做多步决策并调用外部能力”的问题；Function Calling 偏模型调用能力，MCP 偏统一接入协议，工作流（Workflow）偏固定流程编排。
- 从选型顺序看，比较稳的思路通常是：**先 Prompt，再看 RAG，再看微调，续训放到更后面；流程固定先工作流（Workflow），流程开放再上 Agent。**

**建议下一步：** 建议按你最关心的能力线继续往下走：想把 RAG 落到代码里，就看 [第 19 章 RAG 检索增强生成](19-RAG检索增强生成.md)；想理解工具接入和协议层，就看 [第 20 章 MCP 模型上下文协议](20-MCP模型上下文协议.md)；想理解多步决策与执行，就看 [第 21 章 Agent 智能体](21-Agent智能体.md)。
