训练用沙箱¶
Note
本节介绍训练沙箱的用法,我们强烈建议在继续之前先完成上一节的基础教程(工具沙箱) 中的docker 安装和注意事项。
背景介绍¶
AgentScope Runtime的Training Sandbox主要用于训练评测的功能。训练沙箱的数据主要基于公开数据集(如Appworld、Webshop、BFCL等),提供用于Agent训练的数据供给、Agent使用数据集内供给的工具调用、实时的Reward验证。
训练用沙箱内主要通过Ray实现高并发的数据调用,在创建沙箱后,支持外部Agent高并发对不同样本的实例创建、执行、评测。
安装¶
安装依赖项¶
首先,安装带有沙箱支持的AgentScope Runtime:
pip install "agentscope-runtime[sandbox]"
Appworld 案例¶
拉取所需的镜像¶
请按照以下步骤从我们的仓库拉取并标记必要的训练用沙盒Docker镜像:
Note
镜像来源:阿里云容器镜像服务
所有Docker镜像都托管在阿里云容器镜像服务(ACR)上,以在全球范围内实现可获取和可靠性。镜像从ACR拉取后使用标准名称重命名,以与AgentScope Runtime无缝集成。
# 拉取并标记Appworld ARM64架构镜像
docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-appworld:latest-arm64 && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-appworld:latest-arm64 agentscope/runtime-sandbox-appworld:latest-arm64
# 拉取并标记 Appworld X86_64 架构镜像
docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-appworld:latest && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-appworld:latest agentscope/runtime-sandbox-appworld:latest
验证安装¶
您可以通过调用get_env_profile
来验证一切设置是否正确,如果正确将返回数据集ID:
from agentscope_runtime.sandbox.box.training_box.training_box import APPWorldSandbox
box = APPWorldSandbox()
profile_list = box.get_env_profile(env_type="appworld", split="train")
print(profile_list[0])
(可选)从头构建Docker镜像¶
如果您更倾向于在本地自己通过Dockerfile
构建镜像或需要自定义修改,可以从头构建它们。请参阅 工具沙箱高级用法 了解详细说明。
对于训练用沙箱,不同数据集使用不同的DockerFile,其路径在
src/agentscope_runtime/sandbox/box/training_box/environments/{dataset_name}
下
以appworld为例:
docker build -f src/agentscope_runtime/sandbox/box/training_box/environments/appworld/Dockerfile -t agentscope/runtime-sandbox-appworld:latest .
训练样本使用¶
您可以创建某一个具体的训练用沙箱(默认为Appworld
),随后可以并行创建多个不同的训练样本,并且分别执行、评测。
查看数据集样本¶
构建Docker镜像后,我们可以首先查看数据集样本。
例如,我们可以使用 get_env_profile 方法获取训练ID列表。
from agentscope_runtime.sandbox.box.training_box.training_box import APPWorldSandbox
box = APPWorldSandbox()
profile_list = box.get_env_profile(env_type="appworld", split="train")
print(profile_list[0])
创建训练样本¶
以取训练集中的第1个query为例,可以通过create_instance
创建1个训练实例(Instance),并分配了一个实例ID(Instance ID)。
一个Query可以创建多个实例,一个实例唯一对应一个训练样本(基于您创建时,指定的样本ID)
其中,训练集提供的prompt (system prompt
) 和 实际问题 (user prompt
) 均会以Message List
返回,具体位置于返回值的state
中
profile_list = box.get_env_profile(env_type="appworld", split="train")
init_response = box.create_instance(
env_type="appworld",
task_id=profile_list[0],
)
instance_id = init_response["info"]["instance_id"]
query = init_response["state"]
print(f"Created instance {instance_id} with query: {query}")
使用训练样本¶
使用step
方法,并指定具体的instance_id
和action
,可以得到环境内反馈结果。
该方法目前仅支持输入Message格式,建议以 "role": "assistant"
方式输入。
action = {
"role": "assistant",
"content": "```python\nprint('hello appworld!!')\n```",
}
result = box.step(
instance_id=instance_id,
action=action,
)
print(result)
评测训练样本¶
使用evaluate
方法,并评测某个实例的状态,并获取Reward
。不同的数据集可能含有额外的测评参数,通过params
传入。
score = box.evaluate(instance_id, messages={}, params={"sparse": True})
print(f"Evaluation score: {score}")
释放训练样本¶
为了减少内存开销,建议在使用完样本后使用release_instance
方法。
同时,在训练用沙箱运行期间,每5分钟亦会定期清除非活跃实例。
success = box.release_instance(instance_id)
print(f"Instance released: {success}")
BFCL案例¶
拉取所需的镜像¶
请按照以下步骤从我们的仓库拉取并标记必要的训练用沙盒Docker镜像:
Note
镜像来源:阿里云容器镜像服务
所有Docker镜像都托管在阿里云容器镜像服务(ACR)上,以在全球范围内实现可获取和可靠性。镜像从ACR拉取后使用标准名称重命名,以与AgentScope Runtime无缝集成。
# 拉取并标记BFCL ARM64架构镜像
docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-bfcl:latest-arm64 && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-bfcl:latest-arm64 agentscope/runtime-sandbox-bfcl:latest-arm64
# 拉取并标记 BFCL X86_64 架构镜像
docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-bfcl:latest && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-bfcl:latest agentscope/runtime-sandbox-bfcl:latest
(可选) 建立自己的Docker镜像
在根目录跑以下代码:docker build -f src/agentscope_runtime/sandbox/box/training_box/environments/bfcl/Dockerfile -t agentscope/runtime-sandbox-bfcl:latest .
初始化¶
BFCL 有多个子数据库 all, all_scoring, multi_turn, single_turn, live, non_live, non_python, python.在初始化沙盒前请选择一个数据库,然后填上自己的openai_api_key。
import os
os.environ["OPENAI_API_KEY"] = os.environ.get("OPENAI_API_KEY")
os.environ["DATASET_SUB_TYPE"] = "multi_turn"
# os.environ["DATASET_SUB_TYPE"] can be one of the following: "all","all_scoring","multi_turn","single_turn","live","non_live","non_python","python"
from agentscope_runtime.sandbox.box.training_box.training_box import BFCLSandbox
#initialize sandbox
box = BFCLSandbox()
profile_list = box.get_env_profile(env_type="bfcl")
init_response = box.create_instance(
env_type="bfcl",
task_id=profile_list[0],
)
inst_id = init_response["info"]["instance_id"]
query = init_response["state"]
使用训练样本¶
参考以下模拟的对话:
模拟对话
ASSISTANT_MESSAGES = [
# ── Turn-1 ──
{
"role": "assistant",
"content": '<tool_call>\n{"name": "cd", "arguments": {"folder": "document"}}\n</tool_call>\n<tool_call>\n{"name": "mkdir", "arguments": {"dir_name": "temp"}}\n</tool_call>\n<tool_call>\n{"name": "mv", "arguments": {"source": "final_report.pdf", "destination": "temp"}}\n</tool_call>'
},
{
"role": "assistant",
"content": 'ok.1'
},
# ── Turn-2 ──
{
"role": "assistant",
"content": '<tool_call>\n{"name": "cd", "arguments": {"folder": "temp"}}\n</tool_call>\n<tool_call>\n{"name": "grep", "arguments": {"file_name": "final_report.pdf", "pattern": "budget analysis"}}\n</tool_call>'
},
{
"role": "assistant",
"content": 'ok.2'
},
# ── Turn-3 ──
{
"role": "assistant",
"content": '<tool_call>\n{"name": "sort", "arguments": {"file_name": "final_report.pdf"}}\n</tool_call>'
},
{
"role": "assistant",
"content": 'ok.2'
},
# ── Turn-4 ──
{
"role": "assistant",
"content": '<tool_call>\n{"name": "cd", "arguments": {"folder": ".."}}\n</tool_call>\n<tool_call>\n{"name": "mv", "arguments": {"source": "previous_report.pdf", "destination": "temp"}}\n</tool_call>\n<tool_call>\n{"name": "cd", "arguments": {"folder": "temp"}}\n</tool_call>\n<tool_call>\n{"name": "diff", "arguments": {"file_name1": "final_report.pdf", "file_name2": "previous_report.pdf"}}\n</tool_call>'
},
{
"role": "assistant",
"content": 'ok.2'
},
]
for turn_no, msg in enumerate(ASSISTANT_MESSAGES, 1):
res = box.step(
inst_id,
msg
)
print(
f"\n[TURN {turn_no}] term={res['is_terminated']} "
f"reward={res['reward']}\n state: {res.get('state', {})}"
)
if res["is_terminated"]:
break
评估实例¶
score = box.evaluate(inst_id, params={"sparse": True})
print(f"\n[RESULT] sparse_score = {score}")
释放实例¶
box.release_instance(inst_id)