论文:https://arxiv.org/abs/2503.06580
代码:https://github.com/ADaM-BJTU/AutoCoA
时间线:2025/03/09(submitted)
简介
这篇论文提出了一个自动行动链生成(AutoCoA)框架,目的是为了增强推理模型的多轮工具使用能力,尤其是那些需要长期推理和多步骤操作的任务,效果会非常好。
通篇看下来,工作还是非常扎实的,所以篇幅有点长,可以耐心看完,一起交流学习经验。
CoT vs CoA
在正式介绍论文开始,先说明下CoT和CoA的区别,有助于理解论文的内容,CoT大家应该都很熟悉了,就是你用DeepSeek这种模型的时候,模型的思考过程,但CoA对大部分人应该就很陌生了,主要是在Agent应用中用到,因为有动作(Action),涉及到使用具体的工具(Tool)。论文里面的图2,也展示了 CoT(Level 2)和 CoA(Level 3)的区别。
列一张表格说明下区别:
维度 | Chain-of-Thought (CoT) | Chain-of-Action (CoA) |
---|---|---|
定义 | 思维链,强调模型通过分步推理生成中间逻辑步骤,逐步推导答案。 | 行动链,动态交织思维(Thought)与行动(Action),生成包含工具调用、环境交互的序列化动作序列。 |
核心目标 | 增强模型的逻辑推理透明度,解决复杂推理问题(如数学、逻辑问答)。 | 赋予模型自主决策何时及如何使用工具/环境的能力,实现推理与行动的无缝衔接,解决需要多步工具交互的任务。 |
交互方式 | 纯文本推理,依赖内部知识,无需外部工具或环境交互。 | 结合内部推理与外部工具调用(如API查询、计算器、知识库检索等),需与真实/数字环境互动。 |
决策自主性 | 仅决定“如何思考”,不涉及工具使用的触发或执行。 | 主动判断“是否需要行动”、“使用什么工具”、“如何执行动作”,具备工具使用的自主决策能力。 |
典型输出 | 推理过程文本(如“首先计算A,然后比较B和C,最后得出结论…”)。 | 包含动作指令的序列(如“调用天气API获取某地温度→根据温度推荐衣物→生成建议文本”)。 |
应用场景 | 数学题解答、逻辑推理、常识问答等纯文本推理任务。 | 开放域问答(需外部知识)、任务型对话(需调用工具)、机器人控制(需物理环境交互)等。 |
Agent Model
作者定义了Agent Model,它的推理过程可以想象成一个 AI助手帮你解决问题的过程,它需要 边想边做,中间可能还要用工具(比如查资料、调用 APP)。这个过程可以用 POMDP(部分可观察马尔可夫决策过程)来描述,核心是说:AI助手每次做决策时,既要想下一步该 “思考” 还是该 “行动”,又要根据环境反馈(比如工具返回的结果)调整策略。
POMDP
状态(State)
有个状态(State)的概念,可以理解成当前已知的所有信息,论文里的状态公式可以拆解为三个:
-
s 0 s_{0} s0(初始环境状态):问题开始时的“初始条件”,比如你想订外卖时的时间(晚上8点)、位置(公司地址)。
-
t c tc tc(任务上下文):用户的具体问题,比如“我想吃辣的,推荐附近的餐厅”。
-
x 1 : n x_{1: n} x1:n(历史生成序列):之前已经做过的事和得到的结果,比如“思考了‘附近有哪些川菜馆’→调用外卖APP搜索‘川菜 辣’→收到APP返回的餐厅列表”。
类比:就像你打开外卖APP时,APP知道你在哪、你说了“想吃辣”,还记录了你之前搜过什么、看过哪些餐厅的评价。
三种操作模式
每次决策时,AI助手可以选以下三种操作模式:
-
⟨think⟩
(思考):纯内部推理,比如分析“用户要吃辣,可能需要排除不辣的菜”、“这家餐厅评分高但距离远,是否值得选”。 -
⟨action⟩
(行动):调用外部工具,比如“打开地图查餐厅位置”、“调用计算器算配送时间和价格”、“搜索用户评价”。 -
⟨answer⟩
(回答):给出最终结果,比如“推荐XX川菜馆,预计30分钟送达”。
关键:
-
选
⟨action⟩
时,需要明确“用什么工具”(比如选外卖APP的“搜索”功能)和“怎么用”(比如搜索参数“川菜 辣 3公里内”),然后工具会返回结果(比如餐厅列表),这个结果会作为后续决策的依据。 -
整个过程是“思考→行动→观察结果→再思考→再行动……”的循环,直到能回答问题。
策略(Policy)
策略
π
θ
\pi_{\theta}
πθ 就是AI助手的“决策规则”,它根据当前状态(已知信息)决定下一步该选⟨think⟩
、⟨action⟩
还是⟨answer⟩
。
比如:
-
如果发现缺少关键信息(比如不知道餐厅地址),就选
⟨action⟩
调用地图工具; -
如果信息足够,就选
⟨answer⟩
结束流程。
实际案例说明
-
用户问题:“我在朝阳区望京SOHO,晚上8点想吃辣,推荐附近的餐厅”
-
初始状态:
-
s 0 s_{0} s0 = 位置(望京SOHO)、时间(20:00)
-
t c tc tc= “想吃辣,推荐附近餐厅”
-
x 1 : n x_{1: n} x1:n = 空(刚开始,没有历史记录)
-
-
第一步决策:
-
策略判断:需要先确定“附近有哪些辣的餐厅”,但内部知识可能不全,选
⟨action⟩
。 -
行动细节:
-
工具类型:外卖APP的“搜索”功能(τ=“搜索”)
-
参数:“朝阳区 望京SOHO 辣 餐厅 3公里内”(p=具体搜索条件)
-
环境响应:外卖APP返回10家辣餐厅的列表(o=餐厅列表)
-
-
-
第二步决策:
-
状态更新: x 1 : n x_{1: n} x1:n = [
⟨action⟩
, 搜索参数, 餐厅列表] -
策略判断:需要分析哪家餐厅“评分高+配送快”,选
⟨think⟩
-
思考内容: “A餐厅评分4.8,但配送时间40分钟;B餐厅评分4.5,配送时间25分钟” 、“用户晚上8点下单,可能希望尽快送达,优先选配送时间短的”
-
-
第三步决策:
-
策略判断:信息足够,可以给出推荐,选
⟨answer⟩
-
回答:“推荐B餐厅(评分4.5,配送25分钟),主打川味辣菜,符合你的需求。”
-
模型训练 - SFT Stage
这个阶段目的是让模型先学会人类的“规矩”,也就是说:“什么时候该用工具”、“怎么用工具”,同时保留纯推理的能力(比如算满减)。
可以看到,SFT、RL 两个阶段都混合了CoT数据,理由是确保模型不会忘记推理能力,并且可以自适应的决定是否在不同难度的任务上使用行动。同时,在SFT的开始阶段,作者添加了一个额外的子阶段,称为CoT+A。
子阶段 1:CoT+A
给模型看“正反对比”的案例,强制它学会,对于某些问题,需要用工具才能答对。
-
正面案例(该用工具):用户问“望京 SOHO 附近营业中的湘菜餐厅有哪些?”✅ 正确动作:调用外卖 APP 搜索“望京 湘菜 营业中”,成功得到餐厅列表。
-
反面案例(不该用工具/没工具导致失败):同样的问题,❌ 模型没调用工具,用旧数据回答“ABC 餐厅”,但 ABC 实际上已关门(失败)。
-
训练方法:用对比损失函数让模型记住:“当问题涉及实时信息(如营业中),必须用工具,否则会出错!”
子阶段 2:CoT+CoA(w/ observation mask)
训练模型怎么用对工具,但暂时不关心工具返回的真实结果。
-
比如用户问“推荐望京评分最高的川菜馆”,模型需要:
-
决定用什么工具:选外卖 APP 的“搜索”功能(τ=搜索)。
-
设定搜索参数:“望京 川菜馆 评分降序 3 公里内”(p=参数)。
-
-
重点:只关注“动作本身是否正确”(比如参数是否合理),不考虑搜索后返回的餐厅列表(损失计算的时候,mask掉结果,即排除了环境的响应)。
子阶段 3:CoT+CoA(w/o observation mask)
让模型能够预判工具的结果是怎样的,像是在点餐时,看到“西红柿炒鸡蛋”,就大概知道是什么样子了。
-
比如模型规划“调用外卖 APP 搜索望京川菜馆”后,会“脑补”可能的结果:
-
A 餐厅(评分 4.8,营业中,配送 30 分钟)
-
B 餐厅(评分 4.5,休息中,配送 25 分钟)
-
-
目标:让模型学会“提前预判工具返回的格式和内容”,这个时候就不能mask掉工具的结果了,一定要把环境的响应给到模型。
模型训练 - RL Stage
让模型自主规划最佳行动链,减少真实工具调用成本,适应动态环境(比如餐厅营业时间变化)。
子阶段 1:CoT+CoA(simulated environment)
-
模型用 SFT 阶段微调后的模型,可以假装调用工具,因为生成的是模拟结果。
-
基于这些模拟结果,让模型疯狂探索各种行动链(比如“先按评分排序→再过滤营业中→选配送最快” vs “先按距离排序→再选评分≥4.5”)。
-
用Reward模型打分:哪种行动链能更快、更准地推荐餐厅,就给高分,让模型记住“这种规划方式更好”。
子阶段 2:CoT+CoA(real environment)
-
等模型在模拟工具调用的环境中能够规划最佳行动链后,模型只进行少量真实工具调用来校正模型。
-
对比真实结果和模拟结果:
-
如果一致(比如模型脑补 A 餐厅评分 4.8,真实查也是 4.8),说明“脑补”准确,奖励+10 分;
-
如果不一致(真实评分 4.5),则继续调整模型。
-
-
目标:让模型适应真实环境的动态变化(比如餐厅临时歇业)。
训练数据构造
训练集
取自 HotpotQA,是一个多跳问答数据集,包含多步推理的问题和答案。作者随机选取2万个样本构成数据集D,每个数据的样式为QA对:
-
问题(question):一个需要多步推理的自然语言问题
-
答案(answer):问题的正确答案
构造工具
-
数据生成模型:DeepSeek-R1-Distill-Qwen-32B
-
工具调用环境:基于 FlashRAG 构建的本地 wiki 搜索引擎
CoT数据构造
从数据集D中随机选取1万个样本作为基础数据,使用 DeepSeek-R1-Distill-Qwen-32B ,通过一个CoT Prompt,让模型生成了纯思维链过程,但不允许使用外部工具。
这些CoT数据包括问题拆解、已知信息分析和最终答案,能够保持模型的基本推理能力,确保它能够处理不需要外部知识补充的问题。
CoA数据构造
从数据集中选择剩下的1万个样本进行构造,同样使用一个引导模型在遇到知识差距时调用搜索工具的CoA prompt。这些CoA数据包括问题、推理过程和最终答案,能够让模型学习何时以及如何触发动作,以及如何根据返回的观察结果继续推理。
CoT+A数据构造
筛选 “双错样本”:首先从构造的CoT和CoA样本中,找出两种方法单独使用都会导致错误的样本。
生成对比对:对于同一个问题,生成两个版本的推理路径:
-
正例:插入动作触发标识
⟨action⟩
,允许调用工具(正确路径) -
反例:移除动作触发标识,强制纯推理(错误路径)
SFT 数据训练
数据配比
-
Stage-1:1500个CoT+A
-
Stage-2 & 3:5000个CoA + 1000个CoT
Stage-1:CoT+A
作者用 x c h o s e n = [ x 1 , x 2 , ⋯ , x n ] x_{chosen} = [x_1, x_2, \cdots , x_n] xchosen=[x1,x2,⋯,xn] 表示在策略模型下提高其概率的序列,用 x r e j e c t e d x_{rejected} xrejected表示想降低概率的序列。
对于大多数的样本,将包含⟨action⟩
标记的序列视为
x
r
e
j
e
c
t
e
d
x_{rejected}
xrejected,剩下的都是一些仅包含⟨think⟩
标记并最终得出正确答案的序列。
对于给定的上下文 c c c,计算每个目标输出序列的对数概率,归一化后,结果为:
其中 ∣ x ∣ |x| ∣x∣ 表示序列的长度, π θ ( ⋅ ) \pi_{\theta} (\cdot) πθ(⋅) 表示当前模型针对给定序列输出的概率。所以,最终的对比损失函数为:
其中
σ
\sigma
σ 是sigmoid
函数,这个损失会激励模型为选定的序列分配比被拒绝的序列更高的概率。
但在实际的训练过程中,作者观察到一种现象:被选择的和被拒绝的序列概率往往会同时降低,这可能会导致模型崩溃。为了防止这种情况,引入了一个辅助的有监督微调损失。
这种辅助损失会让模型为选定的序列保持高概率,同时将它们与被拒绝的序列区分开来。那么最终损失函数为:
其中 α \alpha α 是控制辅助损失的权重系数。
Stage-2:CoT+CoA(w/ observation mask)
这一阶段与下一阶段最大的区别是,有无mask掉工具返回的结果,这一阶段mask掉了,因为重点是让模型先学会怎么使用工具,所以不要让模型受到工具返回结果的干扰。
给定上下文 c c c,以及完整的决策轨迹 x = [ x 1 , x 2 , . . . , x n ] x=[x_{1}, x_{2}, ..., x_{n}] x=[x1,x2,...,xn],其中 x i ∈ { ⟨ think ⟩ , ⟨ action ⟩ , ⟨ answer ⟩ } x_{i} \in \{ \langle \text{think} \rangle, \langle \text{action} \rangle, \langle \text{answer} \rangle \} xi∈{⟨think⟩,⟨action⟩,⟨answer⟩},因此该阶段的损失函数定义为:
其中 I x i ≠ o I_{x_i \neq o} Ixi=o表示与外部反馈不对应的标记,并且在损失计算中,只考虑与这些标记相关的数值项。
Stage-3:CoT+CoA(w/o observation mask)
这个阶段就不做mask的操作了,因为训练目标是要让模型优化其内部推理和动作输出,学会准确预测外部反馈结果,原文是没给出损失函数的定义,但也很好推出来,将 I x i ≠ o I_{x_i \neq o} Ixi=o去掉就行:
L = 1 ∣ x ∣ ∑ i = 1 ∣ x ∣ [ log π θ ( x i ∣ tc , x < i ) ] L = \frac{1}{|x|} \sum_{i = 1}^{|x|} \left[ \log \pi_{\theta}(x_i | \text{tc}, x_{<i}) \right] L=∣x∣1i=1∑∣x∣[logπθ(xi∣tc,x<i)]
RL 数据训练
Reward Function
分两个,内容与格式上的约束:
-
Exact matching reward:仅当最终输出与真实结果完全匹配时才给予正奖励。
-
Format penalty:如果模型的输出不遵循所需格式,例如缺少像
⟨think⟩
这样的关键标签,则会施加惩罚。
优化方法
采用近期大热的GRPO方法,具体原理不多说了,放一张图。
实验结果
评测方式
-
Exact Match(EM):完全精确匹配,只有当模型的预测结果与真实值完全相等时,才算正确。
-
LLM-based :即LLM-as-Judge,使用 Qwen2.5-14B-instruct 来确定模型预测结果的语义正确性。
模型与框架选型
-
模型: R1-Distill-Qwen-7B
-
SFT框架:LLaMA-Factory
-
RL框架:verl
关键结论
-
Agent model 在AutoCoA的加持下,任务完成率明显好于React方法。
-
直接做RL提升有限,还是需要依赖SFT掌握基础能力。
-
双阶段的RL可行性非常高,尤其是第一阶段的模拟工具调用训练,能在显著降低真实交互成本的同时,还能做到可观的性能提升。
作者还通过图3说明了CoA 的作用,能让模型从 “只能做简单几步操作” 升级为 “能连贯处理多步复杂任务”,尤其是需要长期推理和多次工具交互时优势明显。