随手把百炼 CLI 的审计命令挨个敲了一遍,结果比自己搭监控知道得多
最近在改一个跑在百炼上的 Agent,改到一半突然想知道一件事:它昨天被调了多少次,有没有被安全策略拦下来。
答不上来。应用是我自己部署的,Key 在我手里,但一整天发生了啥我完全没数。我一开始的想法是搭个监控,看了几个方案,都要先接 SDK、起服务、往调用链里塞埋点,看着麻烦就放着了。前天晚上闲着没事,我想先试试用命令行问平台本身,结果一晚上敲了十几条命令,出来的东西比预期多不少。
顺手记一下,命令和数字都是本机实测(macOS,CLI 版本 2.0.1)。
第一屏就把我问住了
bl agents security overview
Scanned: 4412 Risks: 13
Protection
on Flow Agent (1536)
on Managed Agents (387)
on RAG (154)
on Memory (44)
on store (586)
off BYOA hosting
Detections
Content safety hit 0 / scanned 3466
File scan hit 3 / scanned 474
Skill scan hit 10 / scanned 472
过去 24 小时被扫 4,412 次,判出 13 条风险。内容安全 3,466 次零命中,文件扫描 474 次中 3,Skill 扫描 472 次中 10。我更喜欢看后面那个分母,它说明扫描真的在跑。
这条命令我第一次跑是 403:HTTP 403 Endpoint.AccessDenied。带上 --workspace-id 复测还是 403,CLI 参考文档明明把 agents security 标成 API Key 鉴权,可我机器上 API Key 是登录着的。缺的是控制台会话,走一次浏览器登录才通:
bl auth login --console
bl auth status
bl auth status 会把 API Key 和 Console 两套凭证分开列,两个都在位才算准备好。文档和现实不一致,这种地方只能自己踩。
告警那一条我也没贴全
bl agents security alerts --risk-level high --page-size 20 --order-by check_time --order desc
Total: 57 high: 7 medium: 50 low: 0,类型几乎全是命令/代码注入和服务端请求伪造。状态那一列 57 行都是 unhandled,一条都没人处理过。
应用名我不往这里贴,这个工作空间不是我一个人用,有两三个名字一看就知道是谁家的。能说的只有形态:一个偏支付的应用连续五条注入告警,检查时间挤在三分钟里,两两之间隔了 16 秒到 92 秒不等。像有人在反复试,也可能只是正常流量撞上某个解析分支,我在博客里没法判断。但在这之前,我连"有没有人在反复试"都不知道。
想验证一次调用有没有进日志,得先确认账本开着
bl log status
三个状态都得绿:服务关联角色已授权、审计服务就绪、投递开关 On。少一项,后面的 bl log audit * 全是空表。这条链的授权比我想的长,所以我现在建议先跑 status 再跑 list。
发一次最便宜的探针,输出压到 16 token:
bl text chat --model qwen3.8-flash --message "只回复四个字:审计探针" --max-tokens 16 --output json
返回体的 id 形如 chatcmpl-fce8aec9-…,把 chatcmpl- 前缀剥掉,剩下的 UUID 就是审计日志里的 request_id。拿它去服务端过滤:
bl log audit list --hours 1 --request-id <你的uuid> --output json
bl log audit get --hours 1 --request-id <你的uuid> --output json
get 给我一条完整记录:状态码 200、duration 987 毫秒、输入 67 token、输出 29 token、模型名、地域 cn-beijing、调用渠道、request_id。
顺便一个容易误会的设计:审计日志只记元数据,不记你问了什么、它答了什么,文档原话 "call metadata; request/response content is not recorded"。想找回内容得走 bl log inference list,那是另一条要单独开投递的链。
我在这一步翻了一次车
探针发完立刻查:
bl log audit list --hours 1 --model qwen3.8-flash
# No logs found in this range.
我当时的判断是 --model 过滤器有 bug,还挺自信。后来换了一个已知有大量调用的模型,把窗口放宽:
bl log audit count --hours 6 --model qwen3.6-plus --output json
194 条,逐条 model 都是 qwen3.6-plus。过滤器好得很,是我查得太快,那条还没投递进来。同一天下午再用一模一样的命令查,正常返回 4 条,正好是我那天下午发的四次探针。
同一个窗口里一共 108 条,只有 4 条是我发的。这个工作空间确实是共享的,以前我没概念。
终端输出骗了我两次
第一次是 bl log audit list,不报错,给你十七行长这样:
Time │ Request ID │ Model │ Status │ Duration │ First Token │ Tokens
NaN-NaN-NaN NaN:NaN:NaN │ - │ - │ - │ - │ - │ -
第二次是 bl log audit count,普通输出直接打:
Audit logs: [object Object]
我一度以为自己漏传参数。加 --output json 之后一切正常:totalCount 108,每条字段齐全。而且隔壁 bl log inference list 的普通输出时间、时长、状态码全好。同一时刻、同一条命令族,只有审计这条链的 text 层坏了。

bl log trace stats 更隐蔽,普通输出是一张四行、Calls 全 0 的表,看着像"你这天没有链路数据"。json 里才看到后端返回的是 Telemetry.InvalidParams,写着 "Not support resourceType model"。它把一次报错渲染成了一张空表。--resource-type app 才有正常结构。
还有一个直接崩的:bl monitor errors --days 7 回 Error: e is not iterable 然后退出,bl monitor overview --days 7 正常,errors 加 --output json 也能出数。
分页参数有个不太讲武德的上界
--hours 1 明明 108 条,list 只给 20 行(默认每页 20)。我想一次多拿点:
bl log audit list --hours 1 --max-results 50 --output json # 50 行
bl log audit list --hours 1 --max-results 51 --output json # totalCount: 0, list: []
bl log audit list --hours 1 --max-results 100 --output json # totalCount: 0, list: []
从 51 开始,它不说参数超限,不说报错,直接告诉你这个窗口 0 条调用。要是拿它做每日巡检,看到的就是"我的应用今天一次都没跑",然后你会去查代码,不会怀疑这个数。我在 50 和 51 之间卡了界,又往上试了 60、80、90、95、99,全是 0 条,上界就停在 50。
顺带纠正了另一件事:默认那 20 行不按时间倒序,首页第一条 14:36:28、最后一条 14:19:16,中间不单调。所以我一开始"在默认那一页 grep 我刚发的调用"这个思路本身就不对,没命中不代表没入库,得让服务端过滤。
我以为是平台延迟,查完发现是我电脑快了 169 秒
这是那天最有意思的一段。前两次翻车之后我学乖了,写脚本自测投递延迟:记录发出时刻,剥出 request_id,隔一阵查一次直到命中。第一版跑出来 30 秒,回去看脚本,request_id 被解析成了空字符串,grep -c "" 于是匹配了全部 777 行。第二版用 UUID 精确匹配,得到 25 秒,我差点就信了。
卡住我的是对不上的一处:脚本说调用 14:26:32 发出,bl log audit get 说平台时间 14:23:44。平台把我一分钟前发的调用记成了三分钟前。
于是我去核自己的钟:
date -u
curl -sI https://www.aliyun.com | grep -i '^date:'
阿里云和百度回的是 06:35:22,Cloudflare 回的是 06:35:23,我机器上 06:38:12。拿最近那次比,这台机器快了 169 秒。

把这 169 秒减掉,那天下午三条留有发出时刻的探针,平台时间和发出时间就都对上了,剩下 1 秒出头的零头,正好是请求走到服务端要花的工夫。所以平台没写回三分钟前,是我的钟超前了三分钟。
那 25 秒得另算一笔:第二版脚本 25 秒才查一次,头一轮就命中,它给我的其实是"不超过 25 秒"这个上界,我把它当成测量值了。换成 5 秒一查重测,留下来的数字是 5 秒:14:36:46 返回,14:36:53 查到。同一只钟、同一个下午,两个数差五倍,差的就是我查得够不够勤。
钟不准的实际代价比那个数字值钱。--hours 1 这类窗口的起止按本地时间换算,钟不准你就会看到"未来"的日志,或者干脆查不到刚才那条。以后按时间排查之前先校时。
一周的账,两条命令盘完
bl monitor overview --days 7
Models Called 17
Total Calls 1,910
Successful Calls 1,832
Failed Calls 78
Failure Rate 4.08%
4xx Errors 78
5xx Errors 0
Avg Call Duration 15,460 ms
Avg First Token Duration 5,002 ms
4xx 和失败数完全相等,78 对 78,5xx 为 0,服务端一次没挂,全是我这侧的问题,参数、鉴权、额度,都是能改的东西。另一个是平均首 token 5,002 毫秒,也就是用户点完按钮要干等五秒才看见第一个字,这数字我在此之前从来没看见过,我一直以为"慢"是我错觉。
bl usage summary --days 7
这行我看了很久:Cache Read 103,132,400 tokens。这七天有一亿零三百万 token 是从缓存读回来的,我没为它们花钱,也不知道自己在省。
想知道额度什么时候见底:
bl usage free --expiring 30 --output json
我这边 30 天内到期 11 条,最早一批落在 2026-10-12,每条都带 autoStop,我这 11 条全是 False。这里得说准:到期是额度失效、不补发,跟扣不扣钱是两件事。autoStop 关着意味着额度用完后调用不会停,超出部分按控制台单价从余额扣。已完成实名认证的账号这开关默认就是关的,随时能开;没认证的强制开着,连开关都看不见。真在意成本就先去控制台看一眼这个开关。限流面 bl quota check 给 11 个模型的 RPM/TPM 现值和上限,全部 Normal、剩余 100%。
最后缺的那一环我愣是没想到
bl alert list --output json
bl alert history --output json
两条都回 {"list":[],"totalCount":0}。1,910 次调用、78 次失败、首 token 五秒,我一条告警规则都没配。不是平台没给,是我没配。
能配什么问它自己:bl alert metrics --output json 给 12 个指标,含 model_call_failed_percent、model_call_429_count、model_cache_hit_percent、model_first_token_duration;bl alert template list --output json 里官方模板直接有「模型调用失败次数1分钟总和大于10」「模型首包时长1分钟均值大于10秒」。
我不敢在共享空间里落真规则,通知会打到别人,所以只演练:
bl alert create --name <规则名> --template-id system_model_call_failed_count_sum --model qwen3.6-flash --dry-run
--dry-run 把要发出去的请求体原样吐回来:级别 INFO、检查间隔 60 秒、持续 60 秒、通知窗口 00:00-23:59、时区 +0800,连默认文案的模板变量都带着,但什么都没创建。真要建的时候留意 --contact 收的是云监控那边的告警联系人 ID,那批联系人得先去云监控控制台建,这段 CLI 帮不上忙。
每天想知道"有没有新的高危",其实一段 shell 就够,剩下的交给 cron:
bl agents security alerts --risk-level high --output json # 丢给 jq 数一数,非零就发通知
一点感受
这轮我改过的代码是零行。数据不是我送上去的,是调用本身就产生的,bl log audit list 只是把它取回来。想搭的那套 Langfuse 类方案解决的是另一个问题(这次回答好不好、trace 怎么对比),要埋点、要起服务、要长期运维,两者不冲突,我暂时也还用不上前者。
如果你也在百炼上跑了应用,两条命令就够今天试的:bl agents security overview 和 bl monitor overview --days 7。装的东西在这儿:CLI 安装页,API Key 页,新用户每个模型都有独立的一份免费额度,控制台里能看到同样的数。
三件事请记住:审计这一族里 --output json 不是可选是必需;--max-results 上界 50,超了静默返回 0;按时间排查之前先核钟。

浙公网安备 33010602011771号