Skip to content

Commit ee71226

Browse files
authored
Refactor AgentScope ReAct Agent workflow example (agentscope-ai#303)
1 parent 7e01668 commit ee71226

File tree

20 files changed

+621
-180
lines changed

20 files changed

+621
-180
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ This project is built upon many excellent open-source projects, including:
358358
+ [verl](https://github.com/volcengine/verl) and [PyTorch's FSDP](https://pytorch.org/docs/stable/fsdp.html) for LLM training;
359359
+ [vLLM](https://github.com/vllm-project/vllm) for LLM inference;
360360
+ [Data-Juicer](https://github.com/modelscope/data-juicer?tab=readme-ov-file) for data processing pipelines;
361-
+ [AgentScope](https://github.com/modelscope/agentscope) for agentic workflow;
361+
+ [AgentScope](https://github.com/agentscope-ai/agentscope) for agentic workflow;
362362
+ [Ray](https://github.com/ray-project/ray) for distributed systems;
363363
+ we have also drawn inspirations from RL frameworks like [OpenRLHF](https://github.com/OpenRLHF/OpenRLHF), [TRL](https://github.com/huggingface/trl) and [ChatLearn](https://github.com/alibaba/ChatLearn);
364364
+ ......

README_zh.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ trinity run --config examples/grpo_gsm8k/gsm8k.yaml
358358
+ [verl](https://github.com/volcengine/verl)[PyTorch's FSDP](https://pytorch.org/docs/stable/fsdp.html) 用于大模型训练;
359359
+ [vLLM](https://github.com/vllm-project/vllm) 用于大模型推理;
360360
+ [Data-Juicer](https://github.com/modelscope/data-juicer?tab=readme-ov-file) 用于数据处理管道;
361-
+ [AgentScope](https://github.com/modelscope/agentscope) 用于智能体工作流;
361+
+ [AgentScope](https://github.com/agentscope-ai/agentscope) 用于智能体工作流;
362362
+ [Ray](https://github.com/ray-project/ray) 用于分布式系统;
363363
+ 我们也从 [OpenRLHF](https://github.com/OpenRLHF/OpenRLHF)[TRL](https://github.com/huggingface/trl)[ChatLearn](https://github.com/alibaba/ChatLearn) 等框架中汲取了灵感;
364364
+ ......
-23.1 KB
Loading
60 KB
Loading

docs/sphinx_doc/source/main.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ This project is built upon many excellent open-source projects, including:
4545
+ [verl](https://github.com/volcengine/verl) and [PyTorch's FSDP](https://pytorch.org/docs/stable/fsdp.html) for LLM training;
4646
+ [vLLM](https://github.com/vllm-project/vllm) for LLM inference;
4747
+ [Data-Juicer](https://github.com/modelscope/data-juicer?tab=readme-ov-file) for data processing pipelines;
48-
+ [AgentScope](https://github.com/modelscope/agentscope) for agentic workflow;
48+
+ [AgentScope](https://github.com/agentscope-ai/agentscope) for agentic workflow;
4949
+ [Ray](https://github.com/ray-project/ray) for distributed systems;
5050
+ we have also drawn inspirations from RL frameworks like [OpenRLHF](https://github.com/OpenRLHF/OpenRLHF), [TRL](https://github.com/huggingface/trl) and [ChatLearn](https://github.com/alibaba/ChatLearn);
5151
+ ......

docs/sphinx_doc/source/tutorial/example_react.md

Lines changed: 140 additions & 90 deletions
Large diffs are not rendered by default.

docs/sphinx_doc/source_zh/main.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Trinity-RFT 是一个灵活、通用的大语言模型(LLM)强化微调(RF
4444
+ [verl](https://github.com/volcengine/verl)[PyTorch's FSDP](https://pytorch.org/docs/stable/fsdp.html) 用于大模型训练;
4545
+ [vLLM](https://github.com/vllm-project/vllm) 用于大模型推理;
4646
+ [Data-Juicer](https://github.com/modelscope/data-juicer?tab=readme-ov-file) 用于数据处理管道;
47-
+ [AgentScope](https://github.com/modelscope/agentscope) 用于智能体工作流;
47+
+ [AgentScope](https://github.com/agentscope-ai/agentscope) 用于智能体工作流;
4848
+ [Ray](https://github.com/ray-project/ray) 用于分布式系统;
4949
+ 我们也从 [OpenRLHF](https://github.com/OpenRLHF/OpenRLHF)[TRL](https://github.com/huggingface/trl)[ChatLearn](https://github.com/alibaba/ChatLearn) 等框架中汲取了灵感;
5050
+ ......
Lines changed: 145 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,202 @@
1-
# ReAct 例子
1+
# ReAct Agent 训练
22

3-
本示例用于演示如何通过我们兼容 OpenAI 接口的 `ModelWrapper` 类,将 Trinity-RFT 训练工作流适配到你自己的智能体项目中
3+
本节将会展示如何借助 Trinity-RFT 训练一个基于智能体框架实现的 ReAct Agent。这里我们以 [AgentScope](https://github.com/agentscope-ai/agentscope) 框架为例,并使用其内置的 ReAct 智能体来解决 GSM8K 数学问题。开发者可以参考此示例,将 Trinity-RFT 的训练工作流适配到自己的智能体项目中
44

5-
这里我们以 [AgentScope](https://github.com/modelscope/agentscope) 框架为例,但你完全可以使用其他任何框架,因为 Trinity 提供了极大的灵活性。该示例利用一个采用 ReAct 风格推理并支持原生工具调用的智能体(Agent),在 GSM8K 数学数据集上对模型进行微调。
65

76
## 关键特性
87

9-
此示例突出了 Trinity-RFT 框架的几项高级特性:
8+
在介绍案例之前,我们先来看看 Trinity-RFT 在训练智能体应用方面的几个重要特性。
109

11-
### 与外部智能体框架的无缝集成
12-
Trinity-RFT 被设计为高度模块化,因此你可以轻松地将来自外部框架(如 AgentScope)的复杂、现成的智能体逻辑直接嵌入到 Trinity 的 `Workflow` 中。
10+
### 兼容各种智能体框架
1311

14-
- **无需重写智能体**:你不必在 Trinity 内重新实现智能体的复杂逻辑(例如 ReAct 循环、内存管理或工具调用)。
15-
- **关注高层编排**:正如我们在 `AgentScopeReactV2MathWorkflow` 中所展示的那样,Trinity 工作流只需初始化并调用外部智能体的 `reply` 方法。Trinity 对底层复杂性负责,使你能专注于高层任务编排和奖励设计。
12+
当前智能体开发框架众多,对模型的封装和调用方式也各不相同。为了最大限度地兼容各种框架,Trinity-RFT 对 `openai.OpenAI` 以及 `openai.AsyncOpenAI` 接口进行了封装,只要你的智能体框架支持使用 openai 接口调用模型,就可以通过 Trinity-RFT 提供的 `OpenAI` 或是 `AsyncOpenAI` 实例对智能体进行训练。当然,你也可以不使用任何智能体框架,直接借助 Trinity-RFT 提供的 openai 接口实现自己的智能体。
1613

17-
### 通用多步训练
18-
现代智能体任务通常涉及多步推理、工具使用和观察。Trinity-RFT 原生支持跨这些多步交互的训练。
1914

20-
- **逐步步经验生成**:Trinity 不仅从最终结果进行学习,还能将智能体推理轨迹中的每一步视为独立的学习经验(experience)。
21-
- **奖励分配**:解决任务的奖励(reward)会传播至成功轨迹内的所有 experience,使模型能够学习整个推理链,而不仅仅是最终响应。这由配置中的 `advantage_fn` 控制。
15+
### 无需修改智能体代码
2216

23-
### 原生工具调用支持
24-
Trinity-RFT 的推理引擎和训练流水线专为支持原生 OpenAI `tool_calls` 格式而构建。
17+
智能体的训练需要收集智能体运行中产生的对话历史以及其他相关信息(例如 `token_id``logprobs`),这往往需要对智能体应用代码进行一定的修改。Trinity-RFT 通过封装 `openai.OpenAI``openai.AsyncOpenAI` 实例的方式,在模型调用时自动收集训练所需的各种信息,从而避免了对智能体自身代码的修改。
2518

26-
- **学习使用工具**:该框架允许模型学习*何时*调用工具、*调用哪个*工具以及*使用什么*参数,全部采用标准 `tool_calls` 格式。
27-
- **易操作性**:这种原生支持确保了与任何消费 OpenAI API 格式的服务或环境无缝集成,例如 `MCP_server`(多智能体协作平台)或其他工具使用评估器。
2819

29-
## 工作原理
20+
### 支持多轮次交互
3021

31-
下面我们逐步介绍如何执行此流程
22+
智能体任务通常涉及多步推理、工具使用和观察。为了支持训练智能体应用,Trinity-RFT 原生支持包含多轮交互的训练任务,且不限制交互轮次(只需确保每次模型调用的序列长度不超过模型所支持的上限),这意味着你可以根据任务的复杂度,设计动态长度的交互过程。Trinity-RFT 通过动态同步机制,能够在收集到足够的训练样本后立即启动训练任务,从而提升训练效率
3223

33-
### 工作流 (`workflow.py`)
3424

35-
核心逻辑封装在 `AgentScopeReactV2MathWorkflow` 类中。
25+
## 实现流程
3626

37-
1. **初始化 (`__init__`)**
38-
- 首先初始化 AgentScope 环境和所需的 Agent(`ReActAgentV2`)。
39-
- 最关键的集成步骤是将 Trinity 的模型客户端注入到 Agent 中:
40-
```python
41-
self.openai_client = model.get_openai_client()
42-
# self.openai_client = get_openai_async_client() # or async client depend on whether you are using async openai client
43-
# ...
44-
self.agent.model.client = self.openai_client
45-
```
46-
这确保了 Agent 发出的所有 API 请求都通过 Trinity 的 `ModelWrapper` 进行路由,后者会记录完整的对话历史。
27+
我们将逐步介绍如何使用 Trinity-RFT 训练一个基于 AgentScope 实现的 ReAct 智能体。
4728

48-
2. **执行 (`run`)**
49-
- `run` 方法非常简洁,它只是将任务描述传递给 Agent。
50-
```python
51-
content = self.agent.reply(msg).content # your agent logic
52-
```
53-
- 在 Agent 完成其多步推理并产生最终答案后,Trinity 从模型历史中提取所有中间轮次:
54-
```python
55-
experiences = self.model.extract_experience_from_history(clear_history=True)
56-
```
57-
- 基于最终答案计算奖励,并将其应用于从该轨迹生成的所有 `Experience` 对象。然后这些 experiences 被发送到 Buffer 中用于训练。
5829

59-
### 配置说明
30+
### 1. 更换智能体的 OpenAI 客户端
6031

61-
配置文件用于微调整个系统的行为。以下是本示例的关键参数:
32+
{class}`AgentScopeReActAgent <trinity.common.workflows.agentscope.react.react_agent.AgentScopeReActAgent>` 封装了 AgentScope 的 ReAct 智能体,并在初始化时注入 Trinity-RFT 提供的 `openai.AsyncOpenAI` 实例,而后续的执行过程均由 AgentScope 智能体自行处理,无需任何修改。
6233

63-
#### 原生工具调用设置
6434

65-
`explorer.rollout_model` 部分的这些设置用于配置基于 vLLM 的引擎,以生成和解析兼容 OpenAI 的工具调用。
66-
我们使用 `Qwen3` 模型并通过 vLLM 托管模型。不同模型的配置可参考 [vLLM Toolcalls](https://docs.vllm.ai/en/stable/features/tool_calling.html#qwen-models)
35+
```python
36+
# A simplified version of trinity.common.workflows.agentscope.react.react_agent.AgentScopeReActAgent
37+
class AgentScopeReActAgent:
38+
def __init__(
39+
self,
40+
openai_client: openai.AsyncOpenAI, # provided by Trinity-RFT
41+
# some other params
42+
):
43+
"""Initialize the AgentScope ReAct agent with specified tools and model.
44+
45+
Args:
46+
openai_client (openai.AsyncOpenAI): An instance of AsyncOpenAI client.
47+
"""
48+
self.agent_model = OpenAIChatModel(
49+
api_key="EMPTY",
50+
model_name=model_name,
51+
generate_kwargs=generate_kwargs,
52+
stream=False,
53+
)
54+
# patch the OpenAIChatModel to use the openai_client provided by Trinity-RFT
55+
self.agent_model.client = openai_client
56+
self.agent = ReActAgent(
57+
name="react_agent",
58+
model=self.agent_model,
59+
)
60+
61+
async def reply(self, query):
62+
"""Generate a response based on the query."""
63+
# no need to modify your agent logic
64+
return await self.agent.reply(
65+
Msg("user", query, role="user")
66+
)
67+
```
68+
69+
```{note}
70+
这里用一个新类封装 AgentScope 的 ReAct 智能体主要是为了清晰地展示更换 OpenAI 客户端的过程。
71+
在实践中,你可以直接修改现有智能体的 OpenAI 客户端,而无需创建一个新的类。
72+
```
73+
74+
75+
### 2. 实现训练工作流
76+
77+
{class}`AgentScopeReActWorkflow <trinity.common.workflows.agentscope.react.react_workflow.AgentScopeReActWorkflow>` 展示了智能体的训练流程,其核心 `run_async` 方法包含三个步骤:
78+
79+
1. 调用智能体完成指定任务并获取任务结果。
80+
2. 对任务结果进行评估,计算奖励。
81+
3. 收集任务执行中产生的可训练数据并集合奖励生成训练样本(`Experience`)。
82+
83+
```python
84+
# A simplified version of trinity.common.workflows.agentscope.react.react_workflow.AgentScopeReActWorkflow
85+
class AgentScopeReActWorkflow(Workflow):
86+
def __init__(
87+
self,
88+
*,
89+
task: Task,
90+
model: ModelWrapper,
91+
auxiliary_models: Optional[List[openai.OpenAI]] = None,
92+
):
93+
# initialize the agent
94+
self.agent = AgentScopeReActAgent(
95+
openai_client=model.get_openai_async_client(),
96+
# some other params
97+
)
98+
# get query from the task
99+
self.query = task.raw_task.get(task.format_args.prompt_key) # type: ignore [index]
100+
101+
async def run_async(self):
102+
"""Run the workflow asynchronously."""
103+
# Step 1: call the ReAct agent to solve the task
104+
response = await self.agent.reply(self.query)
105+
# Step 2: calculate the reward based on the response
106+
reward = await self.calculate_reward(response)
107+
# Step 3: construct experiences from the interaction history and return them
108+
return self.construct_experiences(reward)
109+
110+
async def calculate_reward(self, response) -> float:
111+
"""Calculate the reward based on the response."""
112+
# your reward logic
113+
114+
def construct_experiences(self, reward: float) -> List[Experience]:
115+
"""Construct experiences from the agent's interaction history.
116+
117+
Returns:
118+
List: A list of Experience objects.
119+
"""
120+
# Extract all interaction history generated by this task
121+
exps = self.model.extract_experience_from_history()
122+
# update the reward for each experience
123+
for exp in exps:
124+
exp.reward = reward
125+
return exps
126+
127+
```
128+
129+
### 3.训练配置
130+
131+
Trinity-RFT 借助配置文件来控制整个训练流程,下面是本示例的关键配置参数说明。
132+
133+
#### 推理模型配置
134+
135+
`explorer.rollout_model` 部分负责配置智能体应用所使用的模型,其中的关键参数如下:
67136

68137

69138
```yaml
70139
explorer:
71140
rollout_model:
72141
# ...
73-
enable_auto_tool_choice: true # 允许模型生成 `tool_calls`
142+
enable_openai_client: true # 启用 OpenAI Client
143+
enable_history: true # 启用调用历史自动记录
144+
enable_auto_tool_choice: true # 允许模型生成 `tool_calls`
74145
tool_call_parser: hermes # 指定格式化解析工具调用输出的解析器
75146
reasoning_parser: deepseek_r1 # 有助于解析模型的思维过程
76-
enable_thinking: true # 允许模型生成中间“思考”内容
147+
enable_thinking: true # 是否启用模型深度思考能力(主要针对 Qwen3 系列模型)
77148
```
78149
79-
#### 多步训练策略
150+
#### 多步训练算法
80151
81-
`algorithm` 部分的此设置定义了如何处理多步 rollout 产生的 experience。
152+
`algorithm` 部分负责配置智能体应用所使用的训练算法,其中的关键参数如下:
82153

83154
```yaml
84155
algorithm:
85156
algorithm_type: grpo
86-
advantage_fn: step_wise_grpo # 多步训练的关键
157+
advantage_fn: step_wise_grpo # 多步训练的关键,该策略告诉 Trinity 为智能体执行路径中的每一步创建独立的训练样本。`grpo` 算法随后使用这些样本来更新模型。
87158
```
88-
- `step_wise_grpo`:该策略告诉 Trinity 为智能体执行路径中的每一步创建独立的训练样本。`grpo` 算法随后使用这些样本来更新模型。
89159

90-
#### 异步同步提升效率
160+
#### 动态同步配置
91161

92-
由于多步 rollout 会产生数量不固定的 experience,等待固定数量的 *rollout* 是低效的。我们采用动态同步策略。
162+
由于智能体应用在完成不同任务时,交互轮次往往不固定,导致生成的训练样本数量也不固定;为此需要开启 Trinity-RFT 的动态同步功能,以便在收集到足够的训练样本后立即启动训练任务,从而提升训练效率。相关配置如下:
93163

94164
```yaml
95165
synchronizer:
96-
sync_style: dynamic_by_explorer # 当积累足够 experience 时即开始训练
97-
sync_interval: 2
166+
sync_style: dynamic_by_explorer # 当产生足够训练数据时,trainer 立即启动训练任务,而不是将生成的数据补齐到一个固定规模,能够有效提升训练效率
167+
sync_interval: 2 # 每执行两个批次的任务后检查是否需要同步更新模型参数
98168
```
99-
- `sync_style: dynamic_by_explorer`:当缓冲区收集到足够的 *experience*(即单个对话轮次)时,trainer 即启动一次训练任务,而不是等待固定数量的完整智能体轨迹。这显著提高了 GPU 利用率和训练吞吐量。
100-
101-
## 如何运行示例
102-
103-
1. **前置条件**:确保已安装 Trinity 及本示例所需依赖(如 `AgentScope`)。请参考 [Agentscope Github link](https://github.com/agentscope-ai/agentscope/tree/v0)
104-
105-
> **注意**:本示例需要以下来源之一的 AgentScope:
106-
> - Commit: `ad13ed5dacecb79d20abf626769f8c7d7a7d2afb`
107-
> - 分支: [`v0`](https://github.com/agentscope-ai/agentscope/tree/v0)
108-
109-
2. 下载你想使用的模型,并填写 `examples/agentscope_tool_react/agentscopev0_tool_react_gsm8k.yaml``examples/agentscope_tool_react/agentscopev0_tool_react_dapo.yaml` 中的配置文件
110-
111-
3. **启动训练任务**:从仓库根目录运行以下命令。
112169
113-
```bash
114-
trinity run --config examples/agentscope_tool_react/agentscopev0_tool_react_gsm8k.yaml
115-
```
116170
117-
171+
## 运行示例
118172
119-
```bash
120-
trinity run --config examples/agentscope_tool_react/agentscopev0_tool_react_dapo.yaml
121-
```
173+
1. 安装依赖库:按照 [安装指南](/tutorial/installation.md) 成功安装 Trinity-RFT,并且安装了 AgentScope 的 v1.0 及以上版本。
122174
175+
```bash
176+
pip install agentscope>=1.0.4
177+
```
123178

124-
GSM8K 数据集的示例非常简单,在 8 块 H20 GPU 上几分钟内即可收敛。
125-
126-
![](../../assets/agentscope_gsm8k_reward.png)
179+
2. 下载模型和数据集:
127180

128-
DAPO 数据集的示例耗时稍长,但也能够收敛。
181+
```bash
182+
huggingface-cli download Qwen/Qwen3-8B
183+
huggingface-cli download openai/gsm8k --repo-type dataset
184+
```
129185

130-
![](../../assets/agentscope_dapo_reward.png)
186+
3. 启动训练任务:
131187

132-
我们还可以看到,模型总体上开始更多地使用工具调用来解决问题。
188+
```bash
189+
# Navigate to the Trinity-RFT root directory
190+
cd /path/to/Trinity-RFT
133191

134-
![](../../assets/agentscope_dapo_turns.png)
192+
# Run the training for GSM8k dataset:
193+
trinity run --config examples/agentscope_react/gsm8k.yaml
194+
```
135195

136-
我们也可以把使用 v1 版本的 AgentScope 仓库,然后对 Qwen3-4b-instrcut-2507 进行训练:
137196

138-
![](../../assets/agentscope_dapo_qwen3-4B_reward.png)
197+
## 结果展示
139198

140199

141-
## 总结
200+
reward 变化曲线:
142201

143-
这个示例虽然简单,但展示了 Trinity 在训练使用工具的复杂多步智能体方面的强大功能和灵活性。通过无缝集成外部智能体逻辑,并提供对多步训练和工具调用的原生支持,Trinity-RFT 使你能够高效地在复杂且真实的任务上微调模型。
202+
![](../../assets/agentscope_gsm8k_reward.png)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# AgentScope ReAct Agent Training Example
2+
3+
This example demonstrates how to train the [AgentScope](https://github.com/agentscope-ai/agentscope) built-in ReAct Agent using Trinity-RFT. We use the GSM8K dataset as an example. Developers can refer to this example to adapt Trinity-RFT's training to their own agent projects.
4+
5+
Full documentation is available at: https://modelscope.github.io/Trinity-RFT/en/main/tutorial/example_react.html

0 commit comments

Comments
 (0)