Skip to content

⚡ Claude Token Optimization2026-04-03 — Security Guard #1647

Description

@github-actions

Target Workflow: security-guard

Source report: #1646
Estimated cost per run: $0.87
Total tokens per run: ~985K
Cache read rate: 99.1% (858.8K cache_read / 985K total)
Cache write rate: 10.7% (103.4K cache_write / 985K total)
LLM turns: 21 Sonnet + 10 Haiku (detection job) = 31 total


Current Configuration

Setting Value
GitHub tools loaded 52 (full context,repos,issues,pull_requests toolsets)
GitHub tools actually used 7 unique tools
Local built-in tools loaded 15 (Bash, Edit, Write, MultiEdit, Glob, Grep, Read, Task, …)
Network groups Default (includes playwright, PyPI, npm — unused)
Pre-agent steps No
Post-agent steps No
Prompt size ~4,441 bytes (workflow .md body)

GitHub Tools Loaded vs Actually Used (run §23957630036)

Tool Used Calls
pull_request_read 13
get_file_contents 6
get_commit 1
list_commits 1
list_pull_requests 1
search_code 1
search_issues 1
45 other tools (discussions, alerts, notifications, releases, workflows, …) 0

86% of loaded GitHub tools were never used.


Cache Analysis (Anthropic-Specific)

Turn Input Output Cache Read Cache Write Notes
1 ~3K ~800 ~0 ~37K System + all tool schemas written to cache
2 ~1 ~800 ~37K ~3.3K Reads T1 cache; adds conversation turn
3 ~1 ~800 ~40K ~3.3K Cache growing
~1 ~800 growing ~3.3K Each turn appends ~3.3K to cache
21 ~1 ~800 ~82K ~3.3K Max cache context reached
Total ~8.2K ~15.2K ~858.8K ~103.4K

Cache write amortization: Turn 1's 37K cache write is reused across all 20 subsequent turns — excellent amortization within a single session. The cache write cost IS justified by read savings.

Cache cost vs benefit: The Turn 1 write of 37K tokens at $3.75/M = $0.14. Those same 37K tokens are read by 20 subsequent turns × $0.30/M = $0.22 in reads. Net benefit from caching the initial prompt context: $0.08 saved. However, if the tool schemas are reduced by ~29K tokens, Turn 1's cache write drops to ~8K, dramatically lowering subsequent read costs too.

Key insight: ~35K of the 37K Turn 1 cache write is tool schemas (52 GitHub tools × ~600 tokens each + 15 local tools). Reducing the tool surface is the single highest-leverage optimization.


Recommendations

1. Restrict GitHub Toolset from [default] to [pull_requests, repos]

Estimated savings: ~$0.28/run (~32%)

The workflow uses toolsets: [default] which expands to context,repos,issues,pull_requests — 52 GitHub MCP tools. Only 7 were used in the analyzed run. Changing to [pull_requests, repos] reduces this to ~12 tools.

In security-guard.md, change:

tools:
  github:
    toolsets: [default]

to:

tools:
  github:
    toolsets: [pull_requests, repos]

Token math:

  • Removed tools: 45 × ~650 tokens each ≈ 29,250 tokens cut from Turn 1 cache write
  • Cache write savings: 29,250 × $3.75/M = $0.11
  • Cache read savings (20 turns × 29,250): 585,000 × $0.30/M = $0.18
  • Total: ~$0.28 savings per run

Note: search_issues was used once. If repos toolset doesn't include it, add toolsets: [pull_requests, repos, issues] and verify coverage. The search_code tool is in the repos toolset.


2. Remove Write-Capable Local Tools

Estimated savings: ~$0.02/run (~2%)

The security review is read-only — it inspects PR diffs and files, then calls add-comment via safe-outputs. The following local tools loaded in --allowed-tools are never needed for a read-only reviewer:

Tool Reason to remove
Edit, Write, MultiEdit Write to local filesystem — not needed
NotebookEdit, NotebookRead Jupyter notebooks — irrelevant for PR review
Task Sub-agent spawning — over-powered for a reviewer
KillBash Only needed for interactive sessions

This is controlled by the compiled lock file's --allowed-tools list. In security-guard.md, add an explicit tools restriction section:

tools:
  github:
    toolsets: [pull_requests, repos]
  allowed-local-tools: [Bash, BashOutput, ExitPlanMode, Glob, Grep, LS, Read, TodoWrite]

If the gh-aw framework doesn't support allowed-local-tools directly in .md files, this must be set via a tools: key at compile time — check the framework docs for the correct syntax.

Token math: 7 tools removed × ~350 tokens each = 2,450 tokens × (Turn 1 write + 20 reads) ≈ $0.02 savings


3. Pre-Compute PR Diff in a Pre-Agent Step

Estimated savings: ~1–2 LLM turns, ~5K tokens (~1%)

The agent's first 1–2 turns are spent fetching the PR diff via pull_request_read and get_pull_request_diff. This is deterministic work that can be done before the LLM starts, reducing the number of tool-call round-trips.

Add to security-guard.md:

steps:
  - name: Fetch PR diff
    run: |
      gh api repos/$\{\{ github.repository }}/pulls/$\{\{ github.event.pull_request.number }}/files \
        --paginate --jq '.[] | {filename: .filename, additions: .additions, deletions: .deletions, patch: .patch}' \
        > /tmp/pr-files.json
      echo "PR_FILES_JSON=$(cat /tmp/pr-files.json | head -c 8000)" >> $GITHUB_OUTPUT
    id: pr_files

Then inject via template variable in the prompt body:

## Changed Files (pre-fetched)

```json
$\{\{ steps.pr_files.outputs.PR_FILES_JSON }}

Focus your security analysis on these files. Use get_file_contents only if you need full context beyond this diff.


This eliminates the initial "what changed?" exploration turns and lets the LLM start analysis immediately on Turn 1.

---

### 4. Restrict Allowed Domains in Lock File

**Estimated savings: Security posture improvement (no token impact)**

The `--allow-domains` list includes packages/tools never needed by a PR security reviewer:

| Domain(s) | Used for | Needed? |
|-----------|----------|---------|
| `cdn.playwright.dev`, `playwright.download.prss.microsoft.com` | Playwright | ❌ |
| `pypi.org`, `files.pythonhosted.org` | Python packages | ❌ |
| `registry.npmjs.org` | npm packages | ❌ |
| `ppa.launchpad.net`, `packagecloud.io` | Ubuntu PPAs | ❌ |
| `archive.ubuntu.com`, `azure.archive.ubuntu.com`, `security.ubuntu.com` | Apt packages | ❌ |
| `packages.cloud.google.com`, `packages.microsoft.com` | Cloud packages | ❌ |

The lock file (`.github/workflows/security-guard.lock.yml`) is compiled from `security-guard.md`. If the AWF framework allows domain restriction via the `.md` file, add:

```yaml
network:
  allowed: [github, anthropic, pki]

Otherwise, open a separate issue to trim the default domain list for PR-review-only workflows.


Expected Impact

Metric Current Projected Savings
Total tokens/run 985K ~670K -32%
Cache write tokens 103.4K ~74K -28%
Cache read tokens 858.8K ~580K -32%
Cost/run $0.87 ~$0.59 -32%
LLM turns (Sonnet) 21 ~19 -2
Tool schemas loaded 52 GitHub + 15 local ~12 GitHub + 8 local -64%

Implementation Checklist

  • Change toolsets: [default]toolsets: [pull_requests, repos] in security-guard.md
  • Verify search_issues availability; add issues toolset if needed
  • Remove write/notebook/task tools from local tool allowlist
  • Add steps: block to pre-fetch PR files diff
  • Add template injection of pre-fetched diff into prompt body
  • Recompile: gh aw compile .github/workflows/security-guard.md
  • Post-process: npx tsx scripts/ci/postprocess-smoke-workflows.ts
  • Trigger a PR review run and compare token-usage.jsonl vs baseline
  • Verify no regression in security issue detection quality

Generated by Daily Claude Token Optimization Advisor · Source report: #1646

Generated by Daily Claude Token Optimization Advisor ·

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions