AgentLoop SDK(agentloop-sdk)提供离线实验能力,用于批量评估 LLM Agent 应用的表现。离线实验从已有数据集逐条读取输入,调用 Agent 获取结果,并将实验数据上报至 AgentLoop 平台,支持实验完成后自动触发平台侧评估。
前提条件
步骤一:安装 SDK
通过 pip 安装 agentloop-sdk:
pip install agentloop-sdk步骤二:配置凭证
SDK 使用阿里云 AccessKey 认证身份,支持以下两种方式。
方式一:环境变量(推荐)
设置以下环境变量后,SDK 自动读取,无需通过代码传入凭证信息:
export AGENTLOOP_AK="your-access-key-id"
export AGENTLOOP_SK="your-access-key-secret"也支持标准阿里云环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
方式二:代码传参
创建 AgentLoopConfig 时直接传入 AccessKey:
config = AgentLoopConfig(
agent_space="my-agent-space",
experiment_plan_id="my_plan_id",
region_id="cn-hangzhou",
access_key_id="your-ak",
access_key_secret="your-sk",
)步骤三:配置实验参数
使用 AgentLoopConfig 类配置实验的核心参数。
from agentloop_sdk import AgentLoopConfig
config = AgentLoopConfig(
agent_space="my-agent-space",
experiment_plan_id="my_plan_id",
region_id="cn-hangzhou",
)AgentLoopConfig 支持以下参数:
参数 | 类型 | 必填 | 默认值 | 说明 |
| str | 是 | - | 智能体空间名称。 |
| str | 是 | - | 实验计划 ID,需为离线类型( |
| str | 是 | - | 阿里云地域 ID,例如 |
| str | 否 |
| 实验名称,用于标识本次实验。平台上显示的实验记录名称由计划名称加时间戳自动生成。 |
| int | 否 | 1000 | 自动分页加载的最大行数。 |
| str | 否 | - | 阿里云 AccessKey ID,未设置环境变量时使用。 |
| str | 否 | - | 阿里云 AccessKey Secret,未设置环境变量时使用。 |
步骤四:定义 Solution 函数
Solution 函数定义了如何调用 Agent 并获取结果。SDK 提供 HTTP 调用和命令行调用两种方式:HTTP 调用适用于通过 API 接口访问的远程 Agent,命令行调用适用于本地部署的 Agent。
Solution 函数的 task.input 是一个 dict,对应数据集中的一条记录,key 为数据集的列名。
通过 HTTP 调用 Agent
使用 http_solution_with 通过 HTTP 接口调用 Agent,支持普通 JSON 响应和 SSE 流式响应。
普通 JSON 响应
from agentloop_sdk import http_solution_with
solution = http_solution_with(
url="https://your-agent-endpoint.com/invoke",
headers={"key": "your-api-key"},
body_builder=lambda task: {
"input": task.input.get("input", ""),
"stream": False,
},
timeout=60.0,
)SSE 流式响应
当 Agent 端点返回 text/event-stream 格式时,SDK 自动检测并解析 SSE,提取所有 data: 行内容拼接为最终结果:
solution = http_solution_with(
url="https://your-agent-endpoint.com/invoke",
headers={"key": "your-api-key"},
body_builder=lambda task: {
"input": task.input.get("input", ""),
"stream": True,
},
timeout=120.0,
)如果 SSE 的每个 chunk 是 JSON 格式,可以通过 chunk_extractor 提取指定字段:
solution = http_solution_with(
url="https://your-agent-endpoint.com/invoke",
headers={"key": "your-api-key"},
body_builder=lambda task: {
"input": task.input.get("input", ""),
"stream": True,
},
timeout=120.0,
chunk_extractor=lambda chunk: chunk.get("output", ""),
)http_solution_with 支持以下参数:
参数 | 类型 | 必填 | 默认值 | 说明 |
| str | 是 | - | Agent 服务的请求 URL。 |
| str | 否 |
| HTTP 请求方法。 |
| dict | 否 |
| 请求头。 |
| Callable[[Task], Any] | 否 | - | 根据 Task 动态构造请求体的函数。 |
| Any | 否 | - | 静态 JSON 请求体,与 |
| float | 否 | 60 | 请求超时时间,单位为秒。 |
| Callable[[Any], str] | 否 | - | SSE 流式响应中,从每个 JSON chunk 提取指定字段的函数。 |
底层 API:http_solution
如果需要完全控制请求构造逻辑,可以使用底层 API http_solution:
from agentloop_sdk import http_solution, HttpRequestSpec
def build_request(task):
return HttpRequestSpec(
url="https://your-agent-endpoint.com/invoke",
headers={"key": "your-api-key"},
json={"input": task.input.get("input", "")},
)
solution = http_solution(build_request, default_timeout=60.0)通过命令行调用 Agent
使用 command_solution_with 通过命令行调用本地部署的 Agent:
from agentloop_sdk import command_solution_with
# 静态命令
solution = command_solution_with(["python", "agent.py", "--input", "hello"])
# 根据 Task 动态构造命令
solution = command_solution_with(
lambda task: ["python", "agent.py", "--input", task.input.get("input", "")],
default_timeout=120.0,
)command_solution_with 支持以下参数:
参数 | 类型 | 必填 | 默认值 | 说明 |
| list 或 Callable[[Task], list] | 是 | - | 静态命令列表或根据 Task 动态构造命令的函数。 |
| float | 否 | - | 命令执行超时时间,单位为秒。 |
底层 API:command_solution
如果需要更多控制,可以使用底层 API command_solution:
from agentloop_sdk import command_solution
def build_command(task):
return ["python", "agent.py", "--input", task.input.get("input", "")]
solution = command_solution(build_command, default_timeout=120.0, cwd="/path/to/agent")command_solution 支持以下参数:
参数 | 类型 | 必填 | 默认值 | 说明 |
| Callable[[Task], list] | 是 | - | 根据 Task 构造命令列表的函数。 |
| float | 否 | - | 命令执行超时时间,单位为秒。 |
| str | 否 | - | 命令执行的工作目录。 |
步骤五:运行实验
配置完成后,调用 SDK 提供的运行函数执行实验。SDK 支持串行和并行两种执行方式。
串行执行
逐条执行数据集中的任务:
import asyncio
from agentloop_sdk import run_experiment
asyncio.run(run_experiment(
config=config,
solution_fn=solution,
result_dir="./results",
n_repeat=1,
))并行执行(推荐)
通过多个 worker 并发执行任务,适合数据集较大的场景:
import asyncio
from agentloop_sdk import run_experiment_parallel
asyncio.run(run_experiment_parallel(
config=config,
solution_fn=solution,
result_dir="./results",
n_repeat=1,
n_workers=4,
))运行函数支持以下参数:
参数 | 类型 | 必填 | 默认值 | 说明 |
| AgentLoopConfig | 是 | - | 实验配置。 |
| Callable | 是 | - | Solution 函数。 |
| str | 否 |
| 本地结果保存目录。 |
| int | 否 | 1 | 每条数据的重复执行次数。 |
| int | 否 | 串行为 1,并行为 4 | 并发 worker 数量。 |
实验运行完成后,结果自动保存至 result_dir 指定的本地目录。如果配置了评估器,实验完成后将自动触发平台侧评估。
链路追踪
http_solution 和 http_solution_with 发送 HTTP 请求时,自动向请求头注入符合 W3C Trace Context 规范的 traceparent 头,并从响应头提取 eagleeye-traceId 或 traceId,用于将实验请求与平台侧链路追踪关联。无需手动处理追踪头信息。
完整示例
以下示例展示了一个完整的离线实验流程:配置实验参数、定义评估器、通过 HTTP 调用 Agent,并以 4 个 worker 并行执行。
import asyncio
from agentloop_sdk import (
AgentLoopConfig,
EvaluatorConfig,
http_solution_with,
run_experiment_parallel,
)
async def main():
config = AgentLoopConfig(
agent_space="default-cn-hangzhou",
experiment_plan_id="cc_plan_id",
region_id="cn-hangzhou",
experiment_name="Offline-Experiment-LocalAgent",
experiment_config={"agent_name": "LocalAgent"},
evaluators=[
EvaluatorConfig(
evaluator_ref="Builtin.agent_correctness",
result_type="score",
variable_mapping={
"input": "experiment_input",
"output": "experiment_output",
"expected_output": "dataset.expected_output",
},
),
],
)
solution = http_solution_with(
url="https://your-agent-endpoint.com/invoke",
headers={"key": "your-api-key"},
body_builder=lambda task: {
"input": task.input.get("input", ""),
"stream": True,
},
timeout=120.0,
chunk_extractor=lambda chunk: chunk.get("output", ""),
)
await run_experiment_parallel(
config=config,
solution_fn=solution,
n_workers=4,
)
if __name__ == "__main__":
asyncio.run(main())