跳到主要内容

6 saasai工具

saasai 是 saastool 的 AI 友好衍生版本,与 saastool 并存(同一套后端 API,同一份 cfg.toml 配置),专为 AI Agent、CI 流水线与自动化脚本设计:

  • stdout 只输出结构化 JSON(或 table);失败时 stdout 严格为空,便于 cmd > ok.json 不被污染。
  • stderr 承载结构化错误 JSON(以及进度、日志),失败时 JSON 格式与成功输出同构。
  • 精细化退出码(usage/config/auth/not-found/invalid/network/server/timeout 等),AI Agent 可据此决定是否重试。
  • 破坏性命令全部支持 --dry-run(delete / resetds / columnclear / create / bind / grant 等)。
  • --hash-file ---lua - 等参数支持从 stdin 读入。
提示
  • saasai 与 saastool 完全独立,原 saastool 的命令、参数、输出字节级保持不变,现有脚本无需修改。
  • 建议:人工操作继续用 saastoolAgent / 流水线 / 新脚本用 saasai

源码:saasai

6.1 基础约定

6.1.1 输出格式

saasai 默认 --output json,成功时写入 stdout 的统一结构(envelope):

{
"schema_version": "v1",
"status": "success",
"code": 0,
"command": "task list",
"data": { /* ... 业务数据 ... */ }
}

失败时写入 stderr(stdout 为空):

{
"schema_version": "v1",
"status": "error",
"code": 30,
"command": "task info",
"error": {
"type": "NOT_FOUND",
"message": "任务不存在",
"retriable": false,
"details": { "sha256": "abc..." }
}
}
字段说明
schema_versionenvelope 版本,当前 v1
statussuccess / error
code与进程退出码一致
command子命令路径(如 task list
data成功时的业务数据
error.type错误类型枚举
error.retriable是否可自动重试
error.details额外诊断信息(如入参 sha256)

6.1.2 退出码与错误类型

codetype含义retriable
0SUCCESS成功
1GENERAL_ERROR兜底错误
2USAGE_ERROR参数错误
10CONFIG_ERROR配置文件错误
20AUTH_ERROR认证失败(账号/签名错误)
21PERMISSION_ERROR权限不足(账号被禁用)
30NOT_FOUND资源不存在(任务/数据空间等)
40INVALID_INPUT输入非法(文件解析失败、参数越界等)
50NETWORK_ERROR网络错误
51SERVER_ERROR服务端 5xx / 未分类服务端错误
60TIMEOUT超时
Agent 使用约定
  • code ∈ {50, 51, 60} 可退避后自动重试。
  • code ∈ {2, 10, 20, 21, 40} 不可盲目重试,必须先修正输入或配置。
  • code = 30 按业务语义处理(例如可视作"已不存在")。

6.1.3 全局参数

参数默认含义
-o / --outputjson输出格式:json(默认)或 table
-c / --configcfg.toml配置文件路径(与 saastool 完全兼容)
-q / --quietfalse抑制 stderr 的进度与 info 日志(错误仍保留)
-v / --verbose0计数:-v info,-vv debug(写入 stderr)
--dry-runfalse破坏性命令仅打印"将要执行"的内容,不实际调用后端
-h / --help任意层级均可附加
注意

--output json(默认)下,进度条与 info/debug 日志会自动抑制,确保 stderr 也是纯净 JSON。需要看进度请用 -o table 或显式加 -v

6.1.4 cfg.toml 配置文件

与 saastool 完全兼容。默认名称 cfg.toml,置于 saasai 同目录;也可用 -c--config 指定。

[auth]
account = "2000"
token = "test"

[apiurls]
baseurl = "https://api.rta.qq.com" # 正式环境
#baseurl = "https://srta.algo.com.cn" # 演示环境

6.1.5 参数命名对照(与 saastool)

saasai 采用 GNU 风格(双横线 kebab-case);saastool 沿用 Go flag 风格。差异表:

saastoolsaasai语义
-config--config / -c配置文件
-hashfile--hash-file任务哈希文件,saasai 额外支持 - 表示 stdin
-userids--user-ids用户 ID 列表
-beginday / -endday--begin-day / --end-day日期区间
-bucketids--bucket-ids桶 ID
-accountid--account-id账户 ID
-hashtype / -idtype--hash-type / --id-type哈希/ID 类型
-blocksize--block-size块大小
-batchsize--batch-size批大小
-extfields--ext-fields扩展字段
-groupby--group-by分组
-b(target list)--list-binds是否列出绑定

6.2 命令总览

saasai --help
Available Commands:
admincode Manage admin codes
bind Manage target binds
columnclear Clear columns for a data space (destructive!)
convert Convert data to write format (local, no network)
exp Manage experiments and exp grants
grant Manage data grants
info Get SaaS server info
read Read users' bytes / uint32s / flags
resetds Reset data space (destructive!)
script Manage lua scripts
target Manage targets
task Manage tasks
write Write users' bytes / uint32s / flags from files
信息

saasai 不提供 daemon / web 子命令,这两类长驻服务仍由 saastool 承担。

6.3 info

读取 sRTA 服务的基础信息(数据空间、策略 ID 等)。

参数必填含义样例
--config / -c配置文件路径cfg.toml(默认)
saasai info

输出示例

{
"schema_version": "v1",
"status": "success",
"code": 0,
"command": "info",
"data": {
"dataspace": { "did": ["did", "20010101"], "wuid": ["wuid", "20010201"] },
"targetId": ["test44"]
}
}

6.4 read(读取用户数据)

读取指定用户在数据空间中的数据(bytes / uint32s / flags)。

参数必填含义样例
--ds数据空间 IDdidwuidgeogeoipgeofac
--user-ids用户 ID 列表(逗号分隔,最多 100 个)cfcd208495d565ef66e7dff9f98764da
--appid小程序 appidwx1111111111111111
--account-id账户 ID,--ds=wuid--appid 非空时必填123
--id-type哈希类型:0=DEFAULT、1=PHONE_MD5、2=PHONE_SHA2561
--config / -c配置文件路径cfg.toml(默认)
wuid 数据空间的参数约束
  • --ds=wuid--appid 为空:--id-type 必须为 12
  • --ds=wuid--appid 非空:必须指定 --account-id

使用示例

# did 单用户
saasai read --ds did --user-ids cfcd208495d565ef66e7dff9f98764da

# did 多用户
saasai read --ds did --user-ids cfcd208495d565ef66e7dff9f98764da,a87ff679a2f3e71d9181a67b7542122c

# wuid + openid
saasai read --ds wuid --user-ids o_e3j4ggVPO2CP8iCPBLunzKL79n --appid wx1111111111111111 --account-id 123

# wuid + 手机号 MD5
saasai read --ds wuid --id-type 1 --user-ids 6b23320fcfc29304d73ce8090bce8e96

6.5 write(写入用户数据)

向指定数据空间批量写入,source 可以是单文件或目录(递归处理)。

参数必填含义样例
--source本地文件或目录(JSONL 格式)./users.jsonl./data_dir/
--ds数据空间 IDdidwuidgeo
--appid小程序 appidwx1111111111111111
--account-id--ds=wuid + --appid 非空时必填123
--id-type哈希类型:0/1/21
--batch-size批处理大小10000(默认)
--clear写入前清空所有数据(破坏性)
--dry-run仅预览
--config / -c配置文件路径cfg.toml(默认)

数据格式(JSONL,每行一个 WriteItem 的 protojson)

{"userid":"cfcd208495d565ef66e7dff9f98764da","bytesKv":{"1":1,"2":100},"uint32sKv":{"1":1000000}}
{"userid":"a87ff679a2f3e71d9181a67b7542122c","bytesKv":{"1":2},"flagsWithExpireKv":{"1":{"flag":true}}}

使用示例

# 单文件
saasai write --ds did --source ./users.jsonl

# 整个目录(递归),batch=5000
saasai write --ds did --source ./data_dir/ --batch-size 5000

# 先清空再写入
saasai write --ds did --source ./users.jsonl --clear

# wuid + 手机号 MD5
saasai write --ds wuid --id-type 1 --source ./phone_write.jsonl --batch-size 2000

# 预览
saasai --dry-run write --ds did --source ./users.jsonl --clear

输出示例

{
"status": "success",
"code": 0,
"command": "write",
"data": { "processed_items": 10000, "failed_items": 0 }
}

6.6 resetds(重置数据空间)

清除指定数据空间中的全部数据。

注意

破坏性操作,请先用 --dry-run 预览。

参数必填含义样例
--ds数据空间 IDdidgeogeofac
--dry-run仅预览
--config / -c配置文件路径cfg.toml(默认)
saasai --dry-run resetds --ds geo
saasai resetds --ds geo

6.7 convert(数据转换)

根据映射配置把原始数据(userid\t[tag1 tag2 ...] 格式)转换成 write 可消费的 JSONL。纯本地操作,不访问后端

参数必填含义样例
--map映射配置文件(JSON)./map.json
--source源数据文件或目录./raw_data/
--dest输出目录./converted_data/

映射文件样例

{
"targets": {
"news_1": { "write_byte": 1, "write_byte_pos": 0 },
"music_2": { "write_byte": 2, "write_byte_pos": 1 }
}
}
saasai convert --map ./map.json --source ./raw_data/ --dest ./converted_data/

6.8 columnclear(列清零)

对数据空间的列(byte/uint32/flag)清零。

注意

破坏性操作,建议先 --dry-run

参数必填含义样例
--ds数据空间 IDdidwuid
--all清零所有列
--u8uint8 列索引(1–64),逗号分隔1,2,3
--u32uint32 列索引(1–8),逗号分隔1,2
--flagflag 列索引(1–4),逗号分隔1,2
--dry-run仅预览
--config / -c配置文件路径cfg.toml(默认)
提示

必须指定 --all--u8 / --u32 / --flag 之一。

saasai --dry-run columnclear --ds did --u8 1,2,3
saasai columnclear --ds did --all
saasai columnclear --ds wuid --u32 1,2 --flag 1

6.9 task(任务管理)

文件上传任务的全生命周期管理。

Available Commands:
create Create a task on server
delete Delete a task on server
download Download task's file blocks to local
info Get a task info
list List tasks on server
make Make file hash for upload task (local, no network)
run Run a task on server
upload Upload task's file blocks to server

6.9.1 task list

参数必填含义样例
--statusall/waiting/running/success/failrunning
--config / -c配置文件路径cfg.toml(默认)
saasai task list
saasai task list --status running

6.9.2 task make

本地计算文件 / 目录的分块 SHA256,输出 hash 文件。不联网

参数必填含义样例
--source本地文件或目录./data.jsonl
--hash-file输出 hash 文件路径./task.json
--ds数据空间 IDdidwuid
--block-size块大小,支持 K/M/G/T(50M–200M)100M(默认 50M
--appid小程序 appidwx1111111111111111
--account-id--ds=wuid + --appid 非空时必填123
--hash-type0/1/21
--desc任务描述"批量导入"
saasai task make --source ./users.jsonl --hash-file ./task.json --ds did
saasai task make --source ./data_dir/ --hash-file ./task.json --ds did --block-size 100M
saasai task make --source ./users.jsonl --hash-file ./task.json \
--ds wuid --appid wx1111111111111111 --account-id 123 \
--desc "openid 用户导入"

输出示例

{
"status": "success",
"command": "task make",
"data": {
"hash_file": "./task.json",
"task_sha256": "abc123...",
"task_size": 1048576,
"file_count": 1
}
}

6.9.3 task create

上传 hash 文件到服务端,创建任务。支持 --hash-file - 从 stdin 读取

参数必填含义样例
--hash-filehash 文件路径,或 - 表示 stdin./task.json
--dry-run仅预览
saasai task create --hash-file ./task.json
cat task.json | saasai task create --hash-file -
saasai --dry-run task create --hash-file ./task.json

6.9.4 task upload

参数必填含义样例
--sha256任务 SHA256abc123...
saasai task upload --sha256 abc123...

输出示例

{
"status": "success",
"command": "task upload",
"data": {
"sha256": "abc123...",
"uploaded_blocks": 12,
"skipped_blocks": 0,
"total_files": 1
}
}

6.9.5 task download

参数必填含义样例
--sha256任务 SHA256abc123...
--dest本地目标目录./output/
saasai task download --sha256 abc123... --dest ./output/

6.9.6 task run

saasai task run --sha256 abc123...
saasai --dry-run task run --sha256 abc123...

6.9.7 task delete

saasai task delete --sha256 abc123...
saasai --dry-run task delete --sha256 abc123...

6.9.8 task info

saasai task info --sha256 abc123...

任务不存在时的错误输出(stderr,exit=30):

{
"status": "error",
"code": 30,
"command": "task info",
"error": {
"type": "NOT_FOUND",
"message": "任务不存在",
"retriable": false,
"details": { "sha256": "abc123..." }
}
}

6.10 target(策略管理)

Available Commands:
create Create a target
delete Delete a target
list List targets

6.10.1 target list

参数必填含义样例
--targets策略 ID 列表,逗号分隔(空=全部)target1,target2
--list-binds同时列出绑定
saasai target list
saasai target list --targets target1,target2 --list-binds

6.10.2 target create

参数必填含义样例
--target策略 ID(3–20 字符)my_target
--desc策略描述"核心策略"
--dry-run仅预览
saasai target create --target my_target --desc "核心用户策略"
saasai --dry-run target create --target my_target

6.10.3 target delete

参数必填含义样例
--target策略 IDmy_target
--dry-run仅预览
saasai target delete --target my_target
saasai --dry-run target delete --target my_target

6.11 bind(策略绑定)

Available Commands:
delete Delete binds
setaccount Set Account binds
setad Set AdGroup binds

6.11.1 bind setaccount

参数必填含义样例
--target策略 IDmy_target
--accounts广告主 ID 列表(逗号分隔)123,456,789
--dry-run仅预览
saasai bind setaccount --target my_target --accounts 123,456

6.11.2 bind setad

参数必填含义样例
--target策略 IDmy_target
--account广告主 ID123
--ads广告组 ID 列表(逗号分隔)1001,1002
--dry-run仅预览
saasai bind setad --target my_target --account 123 --ads 1001,1002,1003

6.11.3 bind delete

参数必填含义样例
--target策略 IDmy_target
--ids要删除的 ID 列表(逗号分隔)1001,1002
--id-type0=自动匹配、1=广告组、3=账户1
--dry-run仅预览
saasai bind delete --target my_target --ids 1001,1002
saasai bind delete --target my_target --id-type 1 --ids 1001
saasai bind delete --target my_target --id-type 3 --ids 123

6.12 grant(授权管理)

Available Commands:
add Add data grant
delete Delete data grant
list List data grants

6.12.1 grant list

saasai grant list

6.12.2 grant add

参数必填含义样例
--account被授权的 sRTA 账号 ID2001
--dsRaw 数据空间 ID20010101
--index授权位索引,支持单个或范围"1,2,4,55-64"
--dry-run仅预览
saasai grant add --account 2001 --ds 20010101 --index "1,2,4,10-20"

6.12.3 grant delete

参数同 grant add

saasai grant delete --account 2001 --ds 20010101 --index "1,2"

6.13 script(脚本管理)

Available Commands:
create Create lua script on server
debug Debug lua script on server
delete Delete a script from server
get Get script content from server
list List all scripts on server
use Use a script as default

6.13.1 script list

saasai script list

6.13.2 script debug(别名:run

在服务端运行本地 Lua 脚本进行调试。

参数必填含义样例
--luaLua 文件路径,或 - 表示 stdin./script.lua
--userid测试用户 IDabc123...
--ds数据空间 IDdid
--os1=iOS、2=Android、7=Harmony2(默认)
saasai script debug --lua ./script.lua --userid abc123 --os 2
saasai script run --lua ./script.lua --userid abc123 --os 1
cat script.lua | saasai script debug --lua - --userid abc123 --ds did

JSON 模式下的结构化输出

{
"status": "success",
"command": "script debug",
"data": {
"error_output": "...",
"print_output": "...",
"dataspace_output": "...",
"targets_output": "..."
}
}

6.13.3 script create

参数必填含义样例
--luaLua 文件路径,或 -./script.lua
--name脚本名(3–20 字符)my-script
--dry-run仅预览
saasai script create --lua ./script.lua --name my-script
cat script.lua | saasai script create --lua - --name my-script

6.13.4 script delete / get / use

参数必填含义
--name脚本名
--dry-run否(仅 delete)仅预览
saasai script delete --name my-script
saasai script get --name my-script
saasai script use --name my-script

6.14 exp(实验管理)

Available Commands:
get Get exp report
grant Manage experiment authorizations
list List experiments

6.14.1 exp list

saasai exp list

6.14.2 exp get

参数必填含义样例
--begin-day开始日期(YYYYMMDD,范围 20250101–21001231)20250101
--end-day结束日期20250131
--target策略 IDmy_target
--bucket-ids桶 ID 列表(逗号分隔,值范围 1–10;空=全部)1,2,3
--uid广告主 ID 列表(逗号分隔)123,456
--group-by分组字段(逗号分隔;允许:advertiser_iduser_weight_factoradvertiser_id
--ext-fields扩展字段(逗号分隔;* 表示全部)*
--total返回总计数据
saasai exp get --begin-day 20250101 --end-day 20250131 --target my_target
saasai exp get --begin-day 20250101 --end-day 20250131 --target my_target --bucket-ids 1,2,3
saasai exp get --begin-day 20250101 --end-day 20250131 --target my_target \
--uid 123,456 --group-by advertiser_id
saasai exp get --begin-day 20250101 --end-day 20250131 --target my_target --total --ext-fields "*"

6.14.3 exp grant list / add / delete

saasai exp grant list
saasai exp grant add --account 12345
saasai exp grant delete --account 12345
saasai --dry-run exp grant add --account 12345
参数必填含义样例
--account是(add/delete)sRTA 账户 ID12345
--dry-run否(仅 add/delete)仅预览

6.15 admincode(行政区划代码)

查询中国行政区划代码。

saasai admincode list
saasai -o table admincode list # 人类可读

返回数据示例

{
"status": "success",
"command": "admincode list",
"data": {
"adminCodes": [
{ "code": "110000", "province": "北京市", "city": "北京市" },
{ "code": "120000", "province": "天津市", "city": "天津市" },
{ "code": "310000", "province": "上海市", "city": "上海市" }
]
}
}

6.16 AI Agent / 脚本集成范式

6.16.1 Bash

if saasai task info --sha256 "$H" > ok.json 2> err.json; then
jq '.data' ok.json
else
code=$?
TYPE=$(jq -r '.error.type' err.json)
RETRIABLE=$(jq -r '.error.retriable' err.json)
case "$code" in
50|51|60) echo "retriable (type=$TYPE), backoff..." ;;
30) echo "not found, skip" ;;
2|10|20|21|40) echo "fix input first (type=$TYPE)"; exit 1 ;;
*) echo "unknown (type=$TYPE)"; exit 1 ;;
esac
fi

6.16.2 Python

import json, subprocess

res = subprocess.run(
["saasai", "-c", "cfg.toml", "task", "list"],
capture_output=True, text=True,
)
if res.returncode == 0:
data = json.loads(res.stdout)["data"]
else:
err = json.loads(res.stderr)["error"]
if err["retriable"]:
... # schedule retry with backoff
else:
raise RuntimeError(f"{err['type']}: {err['message']}")

6.16.3 关键约定

  • 永远先看 exit code,再解析 stderr(error)或 stdout(data)。
  • 失败时 stdout 一定为空,可放心 cmd > out.json| jq
  • JSON 模式下 stderr 也是纯净 JSON(或完全为空),方便 2> err.json 后直接解析。
  • 需要人工可读时加 -o table;需要诊断时加 -v-vv

6.17 与 saastool 的关系

维度saastoolsaasai
目标用户人类(运维、开发)AI Agent / CI / 自动化脚本
参数风格Go flag-config-hashfileGNU:--config--hash-file
默认输出table(task res: {...} 等带前缀文本)JSON envelope
失败 stdout可能有 Command failed. 前缀文本严格为空
退出码0(成功)/ 1(失败)0 / 2 / 10 / 20 / 21 / 30 / 40 / 50 / 51 / 60
--dry-run不支持覆盖所有破坏性命令
stdin 输入不支持--hash-file ---lua -
守护进程/HTTP支持(daemon / web不提供(仍由 saastool 承担)
配置文件cfg.tomlcfg.toml完全共用
账号/签名同一套 [auth] 机制同一套 [auth] 机制
提示

两个二进制 共用同一份 cfg.toml,账号 / Token / baseurl 完全兼容,可并存使用。