Feature request: generic ARM JSON pruner — used by az rest, reusable as fallback for all az wrappers
#1,590 建立於 2026年4月29日
倉庫指標
- Star
- (48,085 star)
- PR 合併指標
- (平均合併 11天 1小時) (30 天內合併 45 個 PR)
描述
Context
rtk discover and a deeper analysis of 30 days of Claude Code transcripts (686 sessions scanned, paired Bash tool_use → tool_result by tool_use_id) shows az rest averages 283 tokens per call — the highest of any az subcommand:
| Subcommand | Calls | Est. tokens | Avg/call |
|---|---|---|---|
| az rest | 67 | 19,023 | 283 |
This is below the absolute volume of az monitor (138K) and az aks (38K), but the per-call cost is the highest because az rest returns raw, untrimmed ARM API responses. Worth wrapping for two reasons:
- Direct savings on az rest itself — 19K tokens / 30 days for power users.
- Reusability: a generic ARM JSON pruner can be invoked as a final pass by every other az wrapper (az monitor, az aks, etc.), and serves as a fallback for the long tail of
az foo barsubcommands that aren't big enough to justify their own dedicated rule.
Verified bloat patterns (from real transcripts)
Three actual outputs in my transcripts (24K-char alert query, 10K-char activity log, 8K-char billing list):
Pattern A — Repeated long ARM resource path prefixes
A query returning an array of N alerts repeats the full subscription resource ID path on every row:
{ "alertRule": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myapp-prod-monitoring-rg/providers/Microsoft.Insights/metricAlerts/MyApp - App Insights - Exceptions",
"targetResource": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/myapp-prod-monitoring-rg/providers/microsoft.insights/components/myapp-prod-ai01" }
Half of every entry is path repetition. With 50+ alerts in a window, that's ~5K tokens of redundant prefix.
Suggested: detect common ARM path prefixes per response, hoist to a top-level _basePath once, replace with a sigil (e.g., ${base}/...) in nested values. Lossless and reversible.
Pattern B — properties.* boilerplate
Billing/Defender/AAD responses follow {id, name, type, properties: {...}}. The id always restates the subscription/resourceGroup/name combo, and name is the trailing segment of id.
Suggested: drop id when it is exactly <known-prefix>/<name>. Drop name when it is the last segment of id. Lossless.
Pattern C — Standard ARM metadata fields
When present (Front Door, Storage, KV control-plane responses): etag, systemData, provisioningState: "Succeeded", empty tags: {}, kind (when matches the parent type).
Suggested: drop unconditionally by default; emit --rtk-keep-metadata opt-out.
Pattern D — Empty/null fields
ARM responds with every nullable field even when null. Activity log entries have ~30 fields per event but typically only 5–8 are populated.
Suggested: strip null + empty-array + empty-string values by default.
Proposed wrapper interface
rtk az rest [...passthrough az rest args...] # auto-applies pruner
rtk az rest --rtk-raw [...] # disables pruner
Plus an internal API that other wrappers (rtk az monitor, rtk az aks, etc.) can call as a final-pass step on JSON responses.
Lossy vs lossless
The patterns above (A, B, C, D) are all lossless — anyone can recover the original by reversing the path-hoist and adding back the dropped boilerplate. That should be the default.
A separate --rtk-summary flag could enable lossy rules (drop nested arrays when only counts matter, truncate long strings, etc.), but that's a phase-2 concern.
Why this beats per-subcommand wrappers for the long tail
The az subcommand surface area is massive (~700 commands). Dedicated wrappers for az aks and az monitor are worth it — but for the rare az postgres flexible-server replica list-by-server call (or any of the dozens of long-tail subcommands), a generic ARM JSON pruner would catch them all without per-command engineering.
Related issues filed alongside
- #1591 —
az monitor(would benefit from this pruner as a final pass) - #1592 —
az aks(same) - #1593 —
az network(same) - #1594 —
az afd(~70% of per-call savings would come from this pruner alone)
Happy to share annotated input/output samples privately if useful.
Methodology note: numbers come from scanning ~/.claude/projects/**/*.jsonl transcripts, pairing Bash tool_use blocks with their tool_result by tool_use_id, stripping any rtk prefix to count like-for-like, and estimating tokens at 4 chars/token.