678 lines
19 KiB
Markdown
678 lines
19 KiB
Markdown
---
|
||
title: Tool Calling 与 Acting:让模型学会做事
|
||
draft: false
|
||
tags:
|
||
- Toolformer
|
||
- ReAct
|
||
- Tool-Calling
|
||
- Acting
|
||
- 大语言模型
|
||
---
|
||
|
||
# Tool Calling 与 Acting:让模型学会做事
|
||
|
||
---
|
||
|
||
## 一、从"说话"到"做事"
|
||
|
||
### 1.1 语言模型的本质限制
|
||
|
||
**语言模型的能力**:
|
||
|
||
给定输入 $x$,生成文本输出 $y$:
|
||
$$P_\theta(y|x) = \prod_{t=1}^T P_\theta(y_t | x, y_{<t}) \tag{1.1}$$
|
||
|
||
**限制**:
|
||
|
||
1. **无法访问实时信息**:不知道当前时间、天气、股价
|
||
2. **无法执行操作**:不能搜索网页、发送邮件、执行代码
|
||
3. **无法与环境交互**:只能处理文本,无法改变外部世界
|
||
|
||
### 1.2 工具调用的核心思想
|
||
|
||
**核心洞察**:
|
||
|
||
> 让语言模型不仅能"说话",还能"调用工具"——通过函数/API 调用执行操作,获取外部信息或改变外部状态。
|
||
|
||
**形式化**:
|
||
|
||
将语言模型扩展为:
|
||
$$P_\theta(y|x, \mathcal{T}) = \prod_{t=1}^T P_\theta(y_t | x, y_{<t}, \mathcal{T}) \tag{1.2}$$
|
||
|
||
其中 $\mathcal{T}$ 是可用工具的集合。
|
||
|
||
**工具调用示例**:
|
||
|
||
```
|
||
用户:今天北京天气如何?
|
||
|
||
模型决定调用工具:
|
||
[TOOL_CALL] get_weather(location="北京")
|
||
[TOOL_RESULT] 晴,25°C
|
||
|
||
模型基于结果生成回答:
|
||
"今天北京天气晴朗,气温25摄氏度。"
|
||
```
|
||
|
||
---
|
||
|
||
## 二、Toolformer:模型自主学习工具调用
|
||
|
||
### 2.1 核心思想
|
||
|
||
**Toolformer**(Schick et al., 2023)的核心是:让模型**自己决定**何时调用哪些工具,以及如何调用。
|
||
|
||
**关键创新**:
|
||
|
||
1. **工具选择**:模型自己决定是否需要调用工具
|
||
2. **工具调用**:模型生成符合 API 格式的调用
|
||
3. **结果融合**:将工具返回结果融入下一步生成
|
||
|
||
### 2.2 Toolformer 的工具定义
|
||
|
||
**定义(工具)**:
|
||
|
||
每个工具 $t \in \mathcal{T}$ 由以下部分组成:
|
||
$$t = (name, description, parameters, return\_type) \tag{2.1}$$
|
||
|
||
**示例:计算器工具**
|
||
|
||
```python
|
||
name: "calculator"
|
||
description: "计算数学表达式的值"
|
||
parameters: {
|
||
"expression": "str" # 要计算的表达式
|
||
}
|
||
return_type: "float" # 返回计算结果
|
||
```
|
||
|
||
### 2.3 Toolformer 的数据生成
|
||
|
||
**核心优势:自监督自动构建**
|
||
|
||
Toolformer 的关键创新在于**无标注自监督自动构造工具调用样本**——并非简单人工插入调用语句,而是让模型自行判断何地插入工具调用并验证结果,形成低成本大规模数据集。
|
||
|
||
**Algorithm: Toolformer Data Generation**
|
||
|
||
**输入**:语言模型 $\pi_0$,工具集 $\mathcal{T}$,工具调用数据集 $\mathcal{D}_{\text{tool}}$
|
||
|
||
**步骤 1:API 相关采样**
|
||
```
|
||
for each sample (x, y) in D:
|
||
# 判断是否适合插入工具调用
|
||
if should_insert_tool(x, y):
|
||
y' = insert_tool_calls(x, y, T) # 在适当位置插入工具调用
|
||
```
|
||
|
||
**步骤 2:工具调用格式**
|
||
|
||
在自然语言中插入特殊格式的调用:
|
||
```
|
||
这导致 45 + 23 = [TOOL_CALL] calculator("45 + 23") [TOOL_RESULT] 68 [TOOL_CALL_END]
|
||
所以结果是 68。
|
||
```
|
||
|
||
### 2.4 工具调用的训练目标
|
||
|
||
**Toolformer 的损失函数**:
|
||
|
||
在每个 token 位置 $t$,计算:
|
||
$$\mathcal{L}_t = -\log \pi_\theta(y_t | x, y_{<t}, \text{context}) \tag{2.2}$$
|
||
|
||
但只对以下 token 计算梯度:
|
||
- 自然语言 token
|
||
- 工具调用 token(API 名、参数)
|
||
- **不包含工具结果的 token**
|
||
|
||
**梯度阻断的三大 Token 类别**:
|
||
|
||
| Token 类型 | 示例 | 梯度计算 |
|
||
|-----------|------|---------|
|
||
| **自然语言 Token** | 普通文本生成 | ✅ 回传梯度 |
|
||
| **工具调用格式 Token** | `[TOOL_CALL]`, `calculator`, `"45+23"` | ✅ 回传梯度(模型自主生成) |
|
||
| **外部工具返回结果 Token** | `[TOOL_RESULT] 68` | ❌ **冻结梯度**(外部系统生成) |
|
||
|
||
**梯度阻断的核心原因**:工具返回结果由外部系统(如计算器、搜索API)生成,不属于模型自主生成内容,若对其回传梯度会导致模型学习外部系统的输出分布,破坏训练目标。
|
||
|
||
**原因**:工具结果是外部提供的,不应该从中学习。
|
||
|
||
### 2.5 工具选择的决策
|
||
|
||
**何时调用工具?**
|
||
|
||
模型通过 prompt 学习何时调用工具:
|
||
```
|
||
当你需要执行计算、查询信息或访问外部数据时,
|
||
使用以下格式调用工具:
|
||
|
||
[TOOL_CALL] tool_name("param1", "param2")
|
||
[TOOL_RESULT] result
|
||
[TOOL_CALL_END]
|
||
```
|
||
|
||
**工业主流 JSON Function Calling 格式**(OpenAI 生态标准):
|
||
|
||
```json
|
||
{
|
||
"name": "get_weather",
|
||
"arguments": {
|
||
"location": "北京",
|
||
"unit": "celsius"
|
||
}
|
||
}
|
||
```
|
||
|
||
**优势**:
|
||
- 结构化程度高,参数类型安全校验
|
||
- 企业级落地首选方案
|
||
- 规避自定义标签解析歧义
|
||
|
||
**零样本/少样本工具调用提示工程**:
|
||
|
||
无需 SFT 微调,仅靠 Prompt 即可实现工具调用:
|
||
|
||
```
|
||
可用工具:
|
||
{
|
||
"name": "calculator",
|
||
"description": "计算数学表达式",
|
||
"parameters": {
|
||
"expression": {"type": "string", "description": "要计算的表达式"}
|
||
}
|
||
}
|
||
|
||
示例调用:
|
||
{
|
||
"name": "calculator",
|
||
"arguments": {"expression": "45 + 23"}
|
||
}
|
||
|
||
请遵循上述格式调用工具。
|
||
```
|
||
|
||
**决策的数学表示**:
|
||
|
||
$$P(\text{call tool} | x) = \text{softmax}(W \cdot h_T) \tag{2.3}$$
|
||
|
||
其中 $h_T$ 是最后一层的隐藏状态。
|
||
|
||
---
|
||
|
||
## 三、ReAct:推理与行动的交织
|
||
|
||
### 3.1 核心思想
|
||
|
||
**ReAct**(Yao et al., 2023)的核心是:将**推理(Reasoning)**和**行动(Acting)**交错起来。
|
||
|
||
**ReAct 的核心洞察**:
|
||
|
||
> 人类智能是推理和行动的交织:边想边做,边做边想。
|
||
|
||
**与 Toolformer 的区别**:
|
||
|
||
| 方法 | 工具调用 | 推理方式 |
|
||
|------|---------|---------|
|
||
| **Toolformer** | 模型自主决定 | 工具调用穿插在生成中 |
|
||
| **ReAct** | 每个 step 都显式 | Thought → Action → Observation 循环 |
|
||
|
||
### 3.2 ReAct 的轨迹格式
|
||
|
||
**ReAct 的轨迹**由多个步骤组成:
|
||
|
||
```
|
||
输入:x
|
||
|
||
Step 1: Thought: 模型思考下一步该做什么
|
||
Action: 执行的操作(如 search, calculate)
|
||
Observation: 操作返回的结果
|
||
|
||
Step 2: Thought: 基于观察继续思考
|
||
Action: 继续操作
|
||
Observation: 继续观察
|
||
|
||
... (重复直到得到答案)
|
||
```
|
||
|
||
**关键特性:双向交互与动态纠错**
|
||
|
||
ReAct 支持环境反馈**反向修正推理逻辑**——可推翻之前错误思路重新规划,而非一条道走到黑。
|
||
|
||
```
|
||
Step 1: Thought: 我认为应该先搜索"北京天气"
|
||
Action: search("北京天气")
|
||
Observation: 结果显示"晴,25°C"
|
||
|
||
Step 2: Thought: 等等,用户问的是"明天"北京的天气,
|
||
而搜索结果显示的是"今天"的。
|
||
需要重新搜索"北京明天天气"
|
||
Action: search("北京明天天气")
|
||
Observation: 结果显示"多云,22°C"
|
||
```
|
||
|
||
**形式化表示**:
|
||
|
||
设 $s_t$ 是第 $t$ 步的状态,$a_t$ 是行动,$o_t$ 是观察。
|
||
|
||
$$\text{Traj} = (x, s_0) \xrightarrow{a_0} o_0 \xrightarrow{a_1} o_1 \xrightarrow{a_2} \cdots \tag{3.1}$$
|
||
|
||
### 3.3 ReAct 的数学框架
|
||
|
||
**定义(状态)**:
|
||
|
||
状态 $s_t$ 包含:
|
||
- 原始输入 $x$
|
||
- 之前的思考 $h_{<t} = (a_0, o_0, \ldots, a_{t-1}, o_{t-1})$
|
||
- 当前任务描述
|
||
|
||
**定义(行动空间)**:
|
||
|
||
$$\mathcal{A} = \mathcal{A}_{\text{search}} \cup \mathcal{A}_{\text{calc}} \cup \mathcal{A}_{\text{finish}} \cup \mathcal{A}_{\text{custom}}$$
|
||
|
||
其中:
|
||
- $\mathcal{A}_{\text{search}}$:检索类行动(如搜索网页、查询数据库)
|
||
- $\mathcal{A}_{\text{calc}}$:计算类行动(如执行数学运算、代码运行)
|
||
- $\mathcal{A}_{\text{finish}}$:终止行动(给出最终答案)
|
||
- $\mathcal{A}_{\text{custom}}$:自定义业务行动
|
||
|
||
**定义(策略)**:
|
||
|
||
$$\pi(a_t | s_t) = P_\theta(a_t | s_t) \tag{3.2}$$
|
||
|
||
### 3.4 ReAct 的推理循环
|
||
|
||
**Algorithm: ReAct**
|
||
|
||
```
|
||
输入:问题 x,可用工具集 T
|
||
输出:最终答案 y
|
||
|
||
初始化:s_0 = (x, empty_context)
|
||
|
||
for step t = 1 to MAX_STEPS:
|
||
# 1. 思考(Thought)
|
||
thought_t = pi_thought(s_{t-1})
|
||
# thought_t 是对当前状态的推理
|
||
|
||
# 2. 行动(Action)
|
||
action_t = pi_action(s_{t-1}, thought_t)
|
||
# action_t 可以是 search/calculate/finish
|
||
|
||
# 3. 执行并观察(Observation)
|
||
if action_t.type == "search":
|
||
obs_t = search(action_t.query)
|
||
elif action_t.type == "calculate":
|
||
obs_t = calculate(action_t.expression)
|
||
elif action_t.type == "finish":
|
||
return action_t.answer
|
||
|
||
# 4. 更新状态
|
||
s_t = \text{Concat}\big(s_{t-1},\; \text{Thought}_t,\; \text{Action}_t,\; \text{Observation}_t\big)
|
||
```
|
||
|
||
### 3.5 ReAct vs CoT vs Toolformer
|
||
|
||
**对比**:
|
||
|
||
| 方法 | 推理结构 | 工具调用 | 反馈利用 |
|
||
|------|---------|---------|---------|
|
||
| **CoT** | 线性推理链 | 无 | 无 | 纯内部推理,无外部交互 |
|
||
| **Toolformer** | 工具穿插在文本中 | 自动插入 | 通过工具结果 | 定向调用外部工具获取信息 |
|
||
| **ReAct** | Thought→Action→Obs 循环 | 显式决策 | 每步都有观察 | 推理+行动+环境观察闭环交互 |
|
||
|
||
**各自适用场景**:
|
||
|
||
- **CoT**:数学推理、逻辑推导(不需要外部信息)
|
||
- **Toolformer**:需要调用工具但不希望干扰生成流程
|
||
- **ReAct**:需要与环境交互、多步信息获取
|
||
|
||
---
|
||
|
||
## 四、工具调用的训练方法
|
||
|
||
### 4.1 监督微调方法
|
||
|
||
**步骤**:
|
||
|
||
1. **数据收集**:收集包含工具调用的轨迹数据
|
||
2. **格式化为对话**:将轨迹格式化为对话格式
|
||
3. **SFT 训练**:在格式化数据上做监督微调
|
||
|
||
**数据格式**:
|
||
|
||
```
|
||
[USER] x
|
||
[ASSISTANT] thought: ...
|
||
action: search("query")
|
||
[SYSTEM] observation: ...
|
||
[ASSISTANT] thought: ...
|
||
action: finish("answer")
|
||
```
|
||
|
||
### 4.2 工具选择的训练
|
||
|
||
**方法 1:分类头(判别式)**
|
||
|
||
在语言模型上添加一个二分类头,判断是否调用工具:
|
||
$$P(\text{call tool} | x) = \sigma(W \cdot h_T + b) \tag{4.1}$$
|
||
|
||
**方法 2:工具 embedding(生成式)**
|
||
|
||
为每个工具学习一个 embedding,在生成时通过 attention 选择工具。
|
||
|
||
**判别式 vs 生成式工具选择**:
|
||
|
||
| 方式 | 核心思想 | 适用场景 |
|
||
|------|---------|---------|
|
||
| **判别式(分类头)** | 二分类头判断是否调用工具 | 简单二选一场景 |
|
||
| **生成式(直接生成)** | 直接生成工具名与参数(主流) | 复杂多工具选择 |
|
||
|
||
### 4.3 API 调用的格式学习
|
||
|
||
**学习 API 调用格式**:
|
||
|
||
模型需要学会:
|
||
1. 生成正确的函数名
|
||
2. 生成正确的参数(JSON 格式)
|
||
3. 解析返回结果
|
||
|
||
**格式约束**:
|
||
|
||
使用特殊的 token 标记来约束格式:
|
||
```
|
||
[TOOL_CALL] calculator("45 + 23") [TOOL_RESULT] 68 [TOOL_CALL_END]
|
||
```
|
||
|
||
### 4.4 训练中的问题
|
||
|
||
**问题 1:工具描述的利用**
|
||
|
||
模型需要理解工具的 description 才能正确调用。
|
||
|
||
**解决方案**:
|
||
|
||
将工具描述作为输入的一部分:
|
||
```
|
||
可用工具:
|
||
- calculator: 计算数学表达式
|
||
- search: 搜索网页
|
||
|
||
请在需要时调用工具。
|
||
```
|
||
|
||
**问题 2:工具结果的幻觉**
|
||
|
||
模型可能伪造工具结果(没有调用工具但生成假结果)。
|
||
|
||
**解决方案**:
|
||
|
||
严格使用真实工具结果替换模型输出中的 [TOOL_RESULT] 部分。
|
||
|
||
**工具调用三类典型幻觉**:
|
||
|
||
| 幻觉类型 | 描述 | 治理方案 |
|
||
|---------|------|---------|
|
||
| **函数名幻觉** | 写错工具名称(如 `get_whether` 而非 `get_weather`) | Schema 校验 + 相似度匹配限制 |
|
||
| **参数幻觉** | 入参格式/内容错误(如字符串未加引号) | 严格 JSON Schema 验证 |
|
||
| **结果伪造幻觉** | 未调用工具,凭空编造返回结果 | 强制真实结果替换 + 调用日志审计 |
|
||
|
||
**高阶工具调用模式**:
|
||
|
||
1. **并行工具调用**:同时发起多个独立工具请求(如同时搜索多个关键词)
|
||
2. **嵌套工具调用**:一个工具的输出作为另一个工具的输入
|
||
3. **条件分支调用**:根据中间结果选择不同工具分支
|
||
|
||
**示例:并行调用**
|
||
```python
|
||
# 同时查询天气和股价
|
||
[TOOL_CALL] get_weather(location="北京")
|
||
[TOOL_CALL] get_stock(symbol="AAPL")
|
||
```
|
||
|
||
**示例:嵌套调用**
|
||
```python
|
||
# search 结果作为 calculate 输入
|
||
result = search("北京的人口")
|
||
calculate(f"population * 2 = {result}")
|
||
```
|
||
|
||
---
|
||
|
||
## 五、多工具协作与规划
|
||
|
||
### 5.1 多工具调用序列
|
||
|
||
**问题**:一个任务可能需要多个工具。
|
||
|
||
**示例**:
|
||
|
||
```
|
||
任务:查找今天北京演唱会票价
|
||
|
||
Step 1: search("北京演唱会今天")
|
||
→ 获取演出名称和场馆
|
||
|
||
Step 2: calculate("场馆到最近地铁站的距离")
|
||
→ 需要先 search 地铁站信息
|
||
|
||
Step 3: 整合信息给出回答
|
||
```
|
||
|
||
**多步依赖**:
|
||
|
||
后一步的工具可能依赖于前一步的结果。
|
||
|
||
### 5.2 工具调用图
|
||
|
||
**定义(工具依赖图)**:
|
||
|
||
$$\mathcal{G} = (V, E)$$
|
||
$$V = \{t_1, t_2, \ldots, t_n\} \quad \text{工具集合}$$
|
||
$$E = \{(t_i, t_j) | t_j \text{的输入依赖于 } t_i \text{的输出}\} \tag{5.1}$$
|
||
|
||
**有向无环图(DAG)**:工具调度使用 DAG 结构规避循环调用死锁。若存在环路,拓扑排序失效,需检测并终止。
|
||
|
||
**拓扑排序**:
|
||
|
||
按照依赖关系排序工具调用:
|
||
$$t_{\pi(1)}, t_{\pi(2)}, \ldots, t_{\pi(n)} \quad \text{满足依赖顺序} \tag{5.2}$$
|
||
|
||
### 5.3 规划与重规划
|
||
|
||
**静态规划**:事先规划好完整调用序列
|
||
|
||
**动态规划**:根据每步结果调整后续调用
|
||
|
||
**Algorithm: Dynamic Replanning**
|
||
|
||
```
|
||
if last_action.failed:
|
||
# 根据失败原因调整计划
|
||
new_plan = replan(current_state, failure_reason)
|
||
else if last_observation.is_satisfactory:
|
||
# 继续原计划
|
||
pass
|
||
```
|
||
|
||
---
|
||
|
||
## 六、实际应用中的挑战
|
||
|
||
### 6.1 工具调用的可靠性
|
||
|
||
**问题**:模型可能调用错误的工具或参数。
|
||
|
||
**解决方案**:
|
||
|
||
1. **参数验证**:对工具参数做 schema 验证
|
||
2. **错误处理**:工具调用失败时重新尝试或换工具
|
||
3. **置信度阈值**:低于置信度阈值时不调用
|
||
|
||
### 6.2 工具数量与选择
|
||
|
||
**问题**:当工具数量很大时(如 100+),如何选择?
|
||
|
||
**解决方案**:
|
||
|
||
1. **分层选择**:先选类别,再选具体工具
|
||
2. **语义匹配**:用文本相似度匹配工具描述
|
||
3. **工具 embedding**:学习工具的向量表示
|
||
|
||
### 6.3 循环与终止判断
|
||
|
||
**问题**:如何知道任务完成了?
|
||
|
||
**终止条件**:
|
||
|
||
1. **显式终止**:调用了 finish 类型的工具
|
||
2. **隐式终止**:连续几步没有新信息
|
||
3. **步数限制**:达到最大步数
|
||
4. **自反思终止**:模型自我判断当前信息已足够回答,主动停止交互
|
||
|
||
**自反思终止策略示例**:
|
||
```
|
||
Step t: Thought: 我已经获取了足够的信息来回答用户的问题。
|
||
北京今天天气晴朗,气温25°C,与用户询问相符。
|
||
不需要进一步搜索。
|
||
Action: finish("北京今天天气晴朗,气温25摄氏度。")
|
||
```
|
||
|
||
### 6.4 工具结果的处理
|
||
|
||
**长结果处理**:
|
||
|
||
工具可能返回很长的结果(如搜索返回 10 条结果)。
|
||
|
||
**解决方案**:
|
||
|
||
1. **截断**:限制结果长度
|
||
2. **摘要**:对结果做摘要
|
||
3. **选择性使用**:只使用最相关的部分
|
||
|
||
---
|
||
|
||
## 七、数学公式速查
|
||
|
||
### 7.1 工具调用公式
|
||
|
||
**扩展语言模型**:
|
||
$$P_\theta(y|x, \mathcal{T}) = \prod_t P_\theta(y_t | x, y_{<t}, \mathcal{T}) \tag{7.1}$$
|
||
|
||
**工具选择**:
|
||
$$P(\text{call tool} | x) = \sigma(W \cdot h_T + b) \tag{7.2}$$
|
||
|
||
### 7.2 ReAct 公式
|
||
|
||
**状态更新**:
|
||
$$s_t = \text{Concat}\big(s_{t-1},\; \text{Thought}_t,\; \text{Action}_t,\; \text{Observation}_t\big) \tag{7.3}$$
|
||
|
||
**策略**:
|
||
$$\pi(a_t | s_t) = P_\theta(a_t | s_t) \tag{7.4}$$
|
||
|
||
---
|
||
|
||
## 八、总结
|
||
|
||
**Toolformer vs ReAct**:
|
||
|
||
| 方面 | Toolformer | ReAct |
|
||
|------|-----------|-------|
|
||
| **工具调用方式** | 自动插入在文本中 | 显式 Thought→Action→Obs 循环 |
|
||
| **推理方式** | 工具调用穿插在生成 | 推理与行动交替 |
|
||
| **反馈利用** | 通过工具结果 | 每步都有观察 |
|
||
| **适用场景** | 需要工具辅助生成 | 需要交互探索 |
|
||
|
||
**核心洞察**:
|
||
|
||
> Tool Calling 将语言模型从"纯文本生成器"扩展为"能够操纵外部世界的智能体"。ReAct 则进一步将推理和行动交织,使得模型能够在与环境交互中不断调整策略。
|
||
|
||
**关键挑战**:
|
||
|
||
1. 工具选择的准确性
|
||
2. 工具调用的可靠性
|
||
3. 多步规划的效率
|
||
4. 循环检测与终止
|
||
|
||
### 8.1 主流智能体框架适配
|
||
|
||
**LangChain 工具调用封装**:
|
||
|
||
```python
|
||
from langchain.agents import AgentExecutor, Tool
|
||
from langchain.llms import OpenAI
|
||
|
||
tools = [
|
||
Tool(name="calculator", func=calculate, description="计算数学表达式"),
|
||
Tool(name="search", func=search_web, description="搜索网页")
|
||
]
|
||
|
||
agent = initialize_agent(tools, llm, agent_type="react")
|
||
agent.run("北京今天天气如何?")
|
||
```
|
||
|
||
**LlamaIndex 工具调用封装**:
|
||
|
||
```python
|
||
from llama_index import download_loader
|
||
from llama_index.agent import ReActAgent
|
||
|
||
agent = ReActAgent.from_tools(tools, verbose=True)
|
||
response = agent.query("计算 45 + 23 的结果")
|
||
```
|
||
|
||
**AgentScope 工具调用封装**:
|
||
|
||
```python
|
||
import agentscope
|
||
from agentscope.agents import ReActAgent
|
||
|
||
agent = ReActAgent(config={
|
||
"tools": [get_weather, calculator],
|
||
"model": "gpt-4"
|
||
})
|
||
```
|
||
|
||
### 8.2 工程实战落地方案
|
||
|
||
**调用异常处理**:
|
||
|
||
| 异常类型 | 处理策略 |
|
||
|---------|---------|
|
||
| **超时** | 重试3次,间隔2s/4s/8s指数退避 |
|
||
| **参数错误** | 自动纠错(如类型转换)+ 回退到自然语言回答 |
|
||
| **工具不可用** | 降级方案:直接基于已有信息回答,或提示用户 |
|
||
|
||
**多轮交互上下文优化**:
|
||
|
||
```
|
||
问题:用户进行20轮对话后,Context 溢出风险
|
||
|
||
解决方案:
|
||
1. 摘要压缩:每隔5轮用 small LLM 压缩历史
|
||
2. 滑动窗口:只保留最近 N 轮对话
|
||
3. 重要性筛选:删除与当前任务无关的历史
|
||
```
|
||
|
||
**微调实战配比**:
|
||
|
||
| 数据类型 | 推荐比例 | 作用 |
|
||
|---------|---------|------|
|
||
| **工具调用轨迹数据** | 30% | 专精工具调用能力 |
|
||
| **自然对话数据** | 70% | 保持通用对话能力 |
|
||
|
||
**冷热方案选型**:
|
||
|
||
| 场景 | 推荐方案 | 说明 |
|
||
|------|---------|------|
|
||
| **快速上线验证** | 少样本Prompt | 无需训练,快速迭代 |
|
||
| **深度业务适配** | SFT微调 | 专属工具调用范式,效果更优 |
|
||
| **复杂多工具场景** | ReAct + DAG规划 | 推理+行动+环境观察闭环 |
|
||
|
||
---
|
||
|
||
**延伸阅读**:
|
||
|
||
1. Schick et al., "Toolformer: Language Models Can Teach Themselves to Use Tools" (ICLR 2023)
|
||
2. Yao et al., "ReAct: Synergizing Reasoning and Acting in Language Models" (ICLR 2023)
|
||
3. Liu et al., "Tool Learning with Foundation Models" (2023)
|
||
4. Zhou et al., "InternLM: A Multilingual Language Model with Progressively Enhanced Capabilities" (2023)
|
||
5. Patil et al., "Gorilla: Large Language Models Connect with Tools" (2023) |