Observed since 20 Oct, 22:37 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Lightweight AgentLoop offline experiment SDK
AgentLoop 离线实验 SDK,用于从 AgentLoop 实验计划加载数据集,在本地串行或并行执行 Agent,并将实验输入、原始输出、运行状态及可选的 Pipeline 处理结果写入 SLS experiment_detail。
本仓库是纯 Python SDK,适合 HTTP Agent、本地 CLI 和自定义 Python Agent。
traceparent 与 AgentLoop baggageexperiment_detaildataset.<column>pipeline.<field>agentloop-experiment-sdk/
├── agentloop_experiment_sdk/ # Python SDK 源码
├── examples/ # HTTP、CLI 和自定义 Solution 示例
├── pyproject.toml # PEP 621 打包配置
├── .gitignore
└── README.md
缓存、测试代码、构建产物、wheel、egg-info、虚拟环境和本地实验结果不会纳入发布分支。
offline 的 AgentLoop 实验计划从仓库安装:
pip install .
# 或使用 uv
uv pip install .
本地开发可使用 editable 模式:
pip install -e .
# 或使用 uv
uv pip install -e .
安装时会自动安装:
alibabacloud_agentloop20260520>=2.3.7,<3.0.0aliyun-log-python-sdk>=0.9.0Python SDK 没有内置 OpenAPI 生成源码,也不依赖 requests、OpenTelemetry、Web 框架或数据库 ORM。
仓库内的 examples 会在导入 SDK 前设置 sys.dont_write_bytecode = True,直接运行时不会生成 __pycache__ 和 .pyc。执行其他 Python 命令时建议使用:
python3 -B your_script.py
# 或在当前终端统一设置
export PYTHONDONTWRITEBYTECODE=1
.gitignore 同时忽略 Python 缓存、构建产物、egg-info 和本地实验结果,避免误提交。
推荐使用环境变量:
export AGENTLOOP_AK="your-access-key-id"
export AGENTLOOP_SK="your-access-key-secret"
同时兼容阿里云通用环境变量:
export ALIBABA_CLOUD_ACCESS_KEY_ID="your-access-key-id"
export ALIBABA_CLOUD_ACCESS_KEY_SECRET="your-access-key-secret"
如果以上变量均未设置,SDK 会读取 ~/.aliyun/config.json 中的 default profile。可通过 ALIBABA_CLOUD_PROFILE 或 ALIYUN_PROFILE 选择其他 profile,也可用 ALIBABA_CLOUD_CREDENTIALS_FILE 指定配置文件路径。
也可以显式传入:
from agentloop_experiment_sdk import AgentLoopConfig
config = AgentLoopConfig(
agent_space="your-agent-space",
experiment_plan_id="your-offline-plan-id",
region_id="cn-hangzhou",
access_key_id="your-access-key-id",
access_key_secret="your-access-key-secret",
)
不要将 AccessKey、Token 或其他凭证提交到 Git。
config = AgentLoopConfig(
agent_space="your-agent-space",
experiment_plan_id="your-offline-plan-id",
region_id="cn-hangzhou",
project=None,
max_rows=1000,
ground_truth_field=None,
experiment_name=None,
agentloop_endpoint=None,
sls_endpoint=None,
)
主要参数:
| 参数 | 必填 | 说明 |
|---|---|---|
agent_space | 是 | AgentSpace 名称 |
experiment_plan_id | 是 | 离线实验计划 ID |
region_id | 是 | 地域 ID |
project | 否 | SLS Project;未填写时从 AgentSpace 自动解析 |
max_rows | 否 | 最多加载的数据量,默认 1000 |
ground_truth_field | 否 | 数据集中的标准答案字段 |
experiment_name | 否 | 本地实验分组名称 |
access_key_id | 否 | AccessKey ID,优先级高于环境变量 |
access_key_secret | 否 | AccessKey Secret,优先级高于环境变量 |
agentloop_endpoint | 否 | 自定义 AgentLoop Endpoint |
sls_endpoint | 否 | 自定义 SLS Endpoint |
调用 resolve_experiment_plan() 后,以下字段会从实验计划自动解析:
datasetplan_namepipeline_nameplan_evaluatorsselected_item_idsquery_sqlimport logging
import os
logging.basicConfig(level=logging.INFO)
from agentloop_experiment_sdk import AgentLoopConfig, http_solution_with, run_experiment_parallel
config = AgentLoopConfig(
agent_space="your-agent-space",
experiment_plan_id="your-offline-plan-id",
region_id="cn-hangzhou",
max_rows=100,
)
solution = http_solution_with(
"https://your-agent-endpoint.example.com/invoke",
headers={"Authorization": "Bearer {}".format(os.environ["AGENT_TOKEN"])},
body_builder=lambda task: {
"input": task.input.get("input", ""),
},
timeout=300,
)
record_id = run_experiment_parallel(
config=config,
solution=solution,
result_dir="./results",
n_repeat=1,
n_workers=4,
)
logging.getLogger(__name__).info("实验记录 ID:%s", record_id)
完整示例:examples/http_offline_experiment.py。
http_solution / http_solution_with 支持:
授权、Token、Cookie 等敏感 Header 在本地结果摘要中会被脱敏。
command_solution_with 可以根据每条数据动态生成命令:
import logging
logging.basicConfig(level=logging.INFO)
from agentloop_experiment_sdk import AgentLoopConfig, command_solution_with, run_experiment_parallel
config = AgentLoopConfig(
agent_space="your-agent-space",
experiment_plan_id="your-offline-plan-id",
region_id="cn-hangzhou",
)
solution = command_solution_with(
lambda task: [
"your-agent-cli",
"--prompt",
str(task.input.get("input", "")),
"--output-format",
"text",
],
default_timeout=120,
)
record_id = run_experiment_parallel(
config=config,
solution=solution,
n_workers=4,
)
logging.getLogger(__name__).info("实验记录 ID:%s", record_id)
完整示例:examples/command_offline_experiment.py。
命令执行结果会保存为:
{
"stdout": "...",
"stderr": "...",
"returncode": 0,
}
命令超时或非零退出码会转换为失败的 SolutionOutput,不会导致其他并行任务停止。
Solution 支持普通函数和异步函数:
import logging
logging.basicConfig(level=logging.INFO)
from agentloop_experiment_sdk import AgentLoopConfig, SolutionOutput, Task, run_experiment_parallel
config = AgentLoopConfig(
agent_space="your-agent-space",
experiment_plan_id="your-offline-plan-id",
region_id="cn-hangzhou",
)
async def custom_solution(task: Task, pre_hook) -> SolutionOutput:
question = task.input.get("input", "")
pre_hook()
# 在这里调用你的 Agent、模型或任意异步逻辑。
result = "answer to: {}".format(question)
return SolutionOutput.success(
result,
meta={"experiment_input": question},
)
record_id = run_experiment_parallel(
config=config,
solution=custom_solution,
n_workers=4,
)
logging.getLogger(__name__).info("实验记录 ID:%s", record_id)
完整示例:examples/custom_solution_experiment.py。
run_experiment 和 run_experiment_parallel 是同步入口,不需要 asyncio.run。执行器会自动识别并等待异步 Solution。
Solution 也可以直接返回普通 Python 对象,SDK 会自动包装为成功结果:
def solution(task):
return {"answer": task.input.get("input", "")}
串行运行:
from agentloop_experiment_sdk import run_experiment
record_id = run_experiment(config, solution)
并行运行:
from agentloop_experiment_sdk import run_experiment_parallel
record_id = run_experiment_parallel(
config,
solution,
n_repeat=1,
n_workers=4,
)
n_repeat:每条数据重复执行次数,默认 1n_workers:并行线程数量,并行入口默认 4recordId是否使用 Pipeline 完全由实验计划决定。SDK 不要求调用方手工传入 Pipeline 名称。
每条任务只写入原始字段,包括:
experiment_inputexperiment_outputdataset.<column>SDK 会执行以下流程:
GetExperimentPlan 响应解析 pipeline_name。traceId 调用 GetPipeline 获取 Pipeline 定义。PreviewPipeline 处理本次 Agent 轨迹。pipeline.<field>。pipeline_name 和全部 pipeline.<field> 写入同一条 experiment_detail 日志。例如同一条 SLS 日志可能包含:
experiment_output={"answer":"raw answer"}
pipeline_name=your-pipeline
pipeline.question=normalized question
pipeline.answer=processed answer
pipeline.score=0.95
Pipeline 不会替换 experiment_output,原始响应始终保留。
除普通离线实验权限外,还需要:
agentloop:GetPipelineagentloop:PreviewPipelineAgent 轨迹通常异步上报到 SLS。PreviewPipeline 返回空数据时:
pipeline_name,但可能没有 pipeline.<field>HTTP Solution 会自动:
traceparent Header。traffic.agentloop.experiment.id。traffic.agentloop.dataset.data_item_id。eagleeye-traceId 或 traceId。如果被测服务通过其他响应头返回 trace ID:
export AGENTLOOP_TRACE_ID_RESPONSE_HEADER="X-Trace-Id"
自定义 Solution 可通过 meta 显式返回:
return SolutionOutput.success(
output={"answer": "ok"},
meta={
"experiment_input": task.input,
"traceId": "0123456789abcdef0123456789abcdef",
},
)
experiment_detail 字段每个任务的每次重复执行对应一条日志,主要字段如下:
| 字段 | 说明 |
|---|---|
experiment_id | 实验记录 ID |
experiment_name | 实验分组名称 |
experiment_start_time | 实验启动毫秒时间戳 |
experiment_type | 当前为 agent |
experiment_metadata | 记录与计划元数据 |
experiment_config | 实验配置 JSON |
task_id | SDK 生成的任务 ID |
repeat_id | 重复执行序号 |
data_config | 数据集及数据项配置 |
experiment_input | Agent 实际输入 |
experiment_output | Agent 原始输出或错误摘要 |
status | success 或 failed |
traceId | 本次调用的 trace ID |
experiment_metrics | 当前包含延迟信息 |
dataset.<column> | 原始数据集列 |
pipeline_name | 实验计划关联的 Pipeline |
pipeline.<field> | Pipeline 处理结果 |
experiment_metadata 中的计划字段使用 snake_case:
{
"run_env": "local_run",
"record_id": "...",
"record_name": "...",
"experiment_group_name": "...",
"plan_id": "...",
"plan_name": "..."
}
默认结果目录是 ./results。目录包含:
evaluation_meta.json<task_id>/task_meta.json<task_id>/<repeat_id>/solution.jsonstats.jsonevaluation_result.json如果 solution.json 已存在,SDK 会跳过对应任务和重复序号,从而支持基础断点续跑。
SDK 自动维护 AgentLoop 实验记录:
CreateExperimentRun 创建离线实验记录。running 并写入总任务数和执行时间。completed。failed。单条任务的业务异常会转换为失败结果并继续执行其他任务。SLS 或 Pipeline 写入失败会记录日志,本地任务结果仍会保留。
预发、联调或私有环境可覆盖 Endpoint:
config = AgentLoopConfig(
agent_space="your-agent-space",
experiment_plan_id="your-offline-plan-id",
region_id="cn-hangzhou",
agentloop_endpoint="agentloop.example.com",
sls_endpoint="cn-hangzhou.log.aliyuncs.com",
)
python -m pip wheel --no-deps -w dist .
生成文件位于 dist/。该目录已被 .gitignore 忽略。
Python SDK 只运行 offline 类型实验计划。请确认 experiment_plan_id 指向离线实验计划。
确认实验计划已关联数据集,并检查计划中的 selected_item_ids、query_sql 和 max_rows。
确认:
experiment_detail 写权限sls_endpoint 与 Region 匹配pipeline_name 但没有 pipeline.<field>常见原因:
GetPipeline 或 PreviewPipeline 权限直接将 async def 函数传给 run_experiment 或 run_experiment_parallel。不要对实验入口使用 asyncio.run,SDK 会在任务执行阶段等待协程。
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 15 Oct 2026 | 2 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 22:37 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:e964908f3827c8c207f4736527f18493d3dd5b8c7b346d6f68012bd33c8b988a