☰
syzkaller Aflow 数据抽取工具:从 syzbot Dashboard 导出 Agentic Workflow 运行数据
2026/10/10 13:44:03 网站建设 项目流程
  • 网络安全
  • 开发工具
  • 质量保障

【免费下载链接】syzkaller

syzkaller is an unsupervised coverage-guided kernel fuzzer

项目地址:https://gitcode.com/gh_mirrors/sy/syzkaller
点击查看免费下载

导读

本文讲解 syzkaller 仓库中专门用于导出 AI/Agentic 工作流(workflow)运行数据的工具:Aflow Data Extraction Tool。该工具从 syzbot 仪表盘(Dashboard)暴露的 JSON API 拉取 AI 任务列表与完整执行轨迹(trajectory),并将结果以结构化目录形式落盘,供离线分析与优化使用。读完本文,你将掌握:Dashboard 侧json=1接口的设计与实现位置、tools/extract_workflows.sh脚本的完整参数与执行流程、输出目录结构,以及如何基于源码证据扩展这套抽取能力。

背景:为什么要抽取 Workflow 数据

syzkaller 在 pkg/aflow 中实现了一套 Agentic 工作流执行引擎,支持流程(flow)、动作(action)、Agent、工具(tool)等多层执行语义,并依赖 LLM 完成诸如崩溃复现(repro)、代码审查等任务。这些工作流运行在 syzbot 云端仪表盘上,每次运行都会产生一条完整的执行轨迹:调用了哪些工具、各阶段输入输出、耗时与错误信息等。

这些数据对离线分析和优化极具价值:可以统计各工作流的成功率、定位 LLM 调用失败环节、对比不同代码版本(commit)下工作流行为的变化。而 Aflow Data Extraction Tool 正是为此设计——它不依赖数据库直连,而是通过 Dashboard 对外暴露的 JSON 接口获取数据,天然与仪表盘页面上看到的内容保持一致。

Dashboard 集成:json=1查询参数

要支持数据抽取,syzbot 仪表盘在 AI 任务相关页面上增加了json=1查询参数支持,共两个端点:

  1. AI 任务列表:/{ns}/ai?json=1返回该命名空间(namespace)下所有 AI 任务的 JSON 列表,包含工作流类型、状态、代码修订版本(code revision)等元数据;
  2. AI 任务详情:/ai_job?id=<id>&json=1返回指定任务的详细信息,包括完整执行轨迹(由 flow、action、agent、tool 执行的 span 组成)。

这两个端点复用现有的writeJSONVersionOf辅助函数,把内部页面数据结构直接序列化为 JSON。

源码实现位置

从源码看,这两处实现位于 dashboard/app/ai.go:

  • 任务列表页处理函数handleAIJobsPage在r.FormValue("json") == "1"时,将组装好的uiAIJobsPage页面结构通过writeJSONVersionOf(w, page)以 JSON 形式写出(ai.go#L406-L409);
  • 任务详情页则通过handleAIJobPageJSON处理json=1与export=1两个参数:json=1时返回uiAIJobDetails{Job, Trajectory, Args}结构(ai.go#L838-L861)。

writeJSONVersionOf定义在 dashboard/app/main.go#L1689-L1696:

func writeJSONVersionOf(writer http.ResponseWriter, page any) error { data, err := GetJSONDescrFor(page) if err != nil { return err } _, err = writer.Write(data) return err }

它调用GetJSONDescrFor将任意页面结构转换为 JSON 描述,再写入响应。列表页返回的核心结构uiAIJobsPage定义于 dashboard/app/ai.go#L37-L51,包含Jobs(任务切片)、Workflows(可用工作流名称)、Managers(可用 manager 列表)以及分页游标字段;任务详情结构uiAIJobDetails则定义于 ai.go#L223-L227,包含任务本体、轨迹 span 列表与参数列表。

任务 JSON 字段说明

uiAIJob结构(dashboard/app/ai.go#L255-L275)定义了单个任务序列化后的字段,抽取脚本直接依赖其中几个:

JSON 字段类型含义
IDstring任务唯一 ID,也是详情接口的入参
Workflowstring工作流类型名称(如repro、repro-c)
Createdtime任务创建时间(RFC3339 字符串)
Finishedtime任务完成时间;零值(0001-01-01T00:00:00Z)表示尚未结束
CodeRevisionstring任务运行的 syzkaller 代码修订(commit)
AgentNamestring执行的 Agent 名称
Error/ErrorSummarystring任务错误信息与摘要
Correctstring正确性标记(用于 review 流程)
Results[]*uiAIResult结构化执行结果

详情接口返回的Trajectory是[]*aflowhtml.UIAITrajectorySpan切片,其中的每个 span 对应一次 flow/action/agent/tool 执行记录,是离线分析的核心数据。

抽取脚本:tools/extract_workflows.sh

抽取过程由 bash 脚本自动化完成,脚本位于 tools/extract_workflows.sh。脚本使用set -e,任何一步失败都会立即退出,便于在 CI 或批处理任务中安全使用。

用法

./tools/extract_workflows.sh <dashboard_url> <commit> [output_dir]

参数说明:

  • dashboard_url:AI 任务列表页 URL,例如http://localhost:8080/linux/ai;
  • commit:一个 syzkaller commit 哈希。脚本只抽取在该 commit当天或之后(按日期比较)运行的工作流,除非任务的CodeRevision与该 commit 完全一致(这种情况即使更早也会被纳入);
  • output_dir:可选,抽取数据的存储目录,默认extracted_workflows。

脚本对参数的校验逻辑(extract_workflows.sh#L11-L18):URL与COMMIT缺失时打印用法并exit 1;OUTPUT_DIR为空时回退为extracted_workflows。

认证支持

脚本支持通过环境变量ACCESS_TOKEN携带 Bearer Token:

CURL_OPTS=(-s -A "") if [ -n "$ACCESS_TOKEN" ]; then CURL_OPTS+=(-H "Authorization: Bearer $ACCESS_TOKEN") fi

也就是说,curl统一使用静默模式(-s)并携带空 User-Agent(-A "");当访问需要登录的仪表盘时,先导出ACCESS_TOKEN环境变量,脚本会自动附加Authorization: Bearer $ACCESS_TOKEN请求头。

执行流程

脚本共分五步:

  1. 获取 commit 日期:通过git log -1 --format=%ct "$COMMIT"取得指定 commit 的时间戳(Unix 秒);
  2. 拉取任务列表:调用列表端点并附加json=1。脚本会智能处理 URL 是否已含查询参数——已含?时追加&json=1,否则追加?json=1(extract_workflows.sh#L28-L35);
  3. 过滤:用jq将列表解析为 TSV(ID、Workflow、Created、CodeRevision 四列),先剔除Finished为零值(即未完成任务)的行,再逐行判断:任务创建时间早于 commit 时间且CodeRevision与目标 commit 不一致的任务被跳过;
  4. 拉取详情:从原始 URL 中提取协议与主机(grep -oE '^https?://[^/]+')得到BASE_URL,对每个命中任务调用/ai_job?id=${ID}&json=1获取完整轨迹;
  5. 存储:按工作流类型创建子目录,将详情 JSON 保存为<job_id>.json。

过滤与下载的核心循环(extract_workflows.sh#L43-L66)如下:

printf "%s\n" "$DATA" | jq -r '.Jobs[] | select(.Finished != "0001-01-01T00:00:00Z") | "\(.ID)\t\(.Workflow)\t\(.Created)\t\(.CodeRevision)"' | while IFS=$'\t' read -r ID WORKFLOW CREATED REVISION; do if [ -z "$ID" ] || [ "$ID" == "null" ]; then continue fi # Convert created time to timestamp JOB_DATE=$(date -d "$CREATED" +%s) # Filter by date or exact commit match if [ "$JOB_DATE" -lt "$COMMIT_DATE" ] && [ "$REVISION" != "$COMMIT" ]; then continue fi echo "Fetching details for job $ID..." DETAIL_URL="${BASE_URL}/ai_job?id=${ID}&json=1" TARGET_DIR="${OUTPUT_DIR}/${WORKFLOW}" mkdir -p "$TARGET_DIR" FILE_PATH="${TARGET_DIR}/${ID}.json" curl "${CURL_OPTS[@]}" "$DETAIL_URL" > "$FILE_PATH" done

几点实现细节值得注意:

  • Finished零值判断"0001-01-01T00:00:00Z"与 Go 中time.Time的零值序列化格式一致——未完成任务在 JSON 中就是该字符串,这保证了脚本只抽取已结束的工作流;
  • 日期比较使用date -d "$CREATED" +%s,要求运行环境支持 GNU date 语义;
  • 任务 ID 为空或为字面量"null"时跳过,防御异常数据;
  • 每个命中任务独立请求详情接口,天然支持断点式增量抽取(已下载的任务可通过目录内文件判断跳过)。

输出结构

抽取结果按工作流类型分目录组织:

output_dir/ ├── repro/ │ ├── 12345678-1234-5678-1234-567812345678.json │ └── ... ├── repro-c/ │ ├── ... └── ...

每个 JSON 文件是一次工作流运行的完整快照,包含任务元数据(Job)、完整执行轨迹(Trajectory)与任务参数(Args),可供其他分析工具直接消费。

数据的可消费性:与轨迹渲染层的对应

抽取出的Trajectory与仪表盘详情页实际渲染的轨迹是同一份数据。Dashboard 使用 pkg/aflow/trajectory 下的aflowhtml.RenderTrajectory将 span 渲染为 HTML(dashboard/app/ai.go#L810),而 JSON 模式输出的uiAIJobDetails.Trajectory字段同样是[]*aflowhtml.UIAITrajectorySpan。这意味着离线 JSON 与线上页面看到的信息完全一致,分析脚本可以直接解析 JSON 而不需要 HTML 解析。

测试验证:接口行为已被用例锁定

Dashboard 对这两个 JSON 端点有完整的端到端测试覆盖,见 dashboard/app/ai_test.go:

  • 创建任务后,通过c.GET(fmt.Sprintf("/ai_job?id=%v&json=1", resp.ID))验证响应包含"Trajectory"字段(ai_test.go#L443-L445);
  • 同时验证export=1端点返回dashapi.AIJobPollResp结构(ai_test.go#L448-L453);
  • 在管理员与普通用户两种权限下均验证了/ai_job?id=...&json=1的可用性(ai_test.go#L1543-L1548);
  • 任务列表页的?json=1输出也在测试中被调用验证(ai_test.go#L539)。

这些用例保证了 JSON 接口的字段结构稳定,抽取脚本所依赖的.Jobs[]、.Finished、.Created、.CodeRevision等字段不会在 Dashboard 演进中无声变化。

实操指南:完整跑通一次抽取

假设你有一个本地运行的 syzbot Dashboard(或线上实例),并按以下步骤操作:

  1. 确认端点可用:先用浏览器或 curl 验证http://localhost:8080/linux/ai?json=1返回 JSON 数组;再挑一个任务 ID 验证http://localhost:8080/ai_job?id=<id>&json=1;
  2. 确定基线 commit:进入仓库执行git log,选定一个你关心的 commit 哈希作为抽取基线;
  3. (可选)配置认证:若 Dashboard 需要登录,先export ACCESS_TOKEN=<your-token>;
  4. 运行脚本:
./tools/extract_workflows.sh http://localhost:8080/linux/ai <commit_hash> ./wf_data

脚本运行过程中会打印Fetching job list from $URL...、Processing jobs...、Fetching details for job <ID>...与最终的Extraction complete.提示;

  1. 检查结果:wf_data/下应出现按工作流类型命名的子目录,每个子目录内是<job_id>.json文件。

进阶用法

  • 按工作流类型定向抽取:Dashboard 列表页支持workflow查询参数(对应handleAIJobsPage中的r.FormValue("workflow"),见 dashboard/app/ai.go#L295),可在dashboard_url后追加&workflow=repro只拉取某类工作流,减少数据量;
  • 增量更新:重复运行脚本并指定同一output_dir,已存在的 JSON 文件会被覆盖更新,可配合更严格的日期过滤实现增量同步;
  • 离线分析:对每个 JSON 文件中的Trajectoryspan 做统计(如按 span 类型、时长、错误率聚合),或结合Args字段还原任务的输入参数。

局限与注意事项

  • 脚本依赖jq、curl、GNUdate,运行环境需预装这些工具;
  • 日期过滤是"创建时间 >= commit 时间 或 CodeRevision 完全匹配",并非精确的提交祖先关系判断;若任务代码版本恰好早于基线但已包含目标改动,可能会被过滤掉,需要自行权衡;
  • 抽取的是 Dashboard 页面视图的数据快照,不包含数据库中的全部原始字段(如内部评论、补丁版本历史等);
  • CodeRevision匹配是精确字符串比较,commit 缩写形式不会命中,建议使用完整 40 位哈希。

总结

Aflow Data Extraction Tool 通过仪表盘的json=1接口与 tools/extract_workflows.sh 脚本,为 syzkaller 的 Agentic 工作流提供了轻量、可脚本化的离线数据管道。它复用了页面渲染同源的数据结构(uiAIJobsPage/uiAIJobDetails),由writeJSONVersionOf统一序列化,配合 dashboard/app/ai_test.go 的端到端测试保证接口稳定。对于想要分析工作流成功率、定位 LLM 调用失败、对比不同代码版本行为差异的开发者来说,这是一条开箱即用的数据通道。

  • 网络安全
  • 开发工具
  • 质量保障

【免费下载链接】syzkaller

syzkaller is an unsupervised coverage-guided kernel fuzzer

项目地址:https://gitcode.com/gh_mirrors/sy/syzkaller
点击查看免费下载
上一篇:2024最新版libcuckoo入门教程:从安装到实战的完整指南
下一篇:探索 BSPWM Themes:打造个性化的桌面环境

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询