chewme-audit 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chewme_audit-0.1.0/LICENSE +21 -0
- chewme_audit-0.1.0/PKG-INFO +270 -0
- chewme_audit-0.1.0/README.md +257 -0
- chewme_audit-0.1.0/chewme_audit/__init__.py +12 -0
- chewme_audit-0.1.0/chewme_audit/adapters/__init__.py +1 -0
- chewme_audit-0.1.0/chewme_audit/adapters/claude_code.py +138 -0
- chewme_audit-0.1.0/chewme_audit/adapters/jsonl.py +62 -0
- chewme_audit-0.1.0/chewme_audit/adapters/langfuse.py +59 -0
- chewme_audit-0.1.0/chewme_audit/adapters/langsmith.py +68 -0
- chewme_audit-0.1.0/chewme_audit/api_log.py +82 -0
- chewme_audit-0.1.0/chewme_audit/cli.py +200 -0
- chewme_audit-0.1.0/chewme_audit/counting.py +82 -0
- chewme_audit-0.1.0/chewme_audit/cross_trace.py +115 -0
- chewme_audit-0.1.0/chewme_audit/detectors/__init__.py +21 -0
- chewme_audit-0.1.0/chewme_audit/detectors/base.py +26 -0
- chewme_audit-0.1.0/chewme_audit/detectors/near_duplicates.py +57 -0
- chewme_audit-0.1.0/chewme_audit/detectors/oversized_outputs.py +57 -0
- chewme_audit-0.1.0/chewme_audit/detectors/pretty_print.py +84 -0
- chewme_audit-0.1.0/chewme_audit/detectors/repeated_calls.py +67 -0
- chewme_audit-0.1.0/chewme_audit/detectors/unmeasurable.py +53 -0
- chewme_audit-0.1.0/chewme_audit/diff.py +344 -0
- chewme_audit-0.1.0/chewme_audit/fixes/__init__.py +192 -0
- chewme_audit-0.1.0/chewme_audit/model.py +22 -0
- chewme_audit-0.1.0/chewme_audit/pricing.py +146 -0
- chewme_audit-0.1.0/chewme_audit/receipt.py +62 -0
- chewme_audit-0.1.0/chewme_audit/report.py +281 -0
- chewme_audit-0.1.0/chewme_audit.egg-info/PKG-INFO +270 -0
- chewme_audit-0.1.0/chewme_audit.egg-info/SOURCES.txt +39 -0
- chewme_audit-0.1.0/chewme_audit.egg-info/dependency_links.txt +1 -0
- chewme_audit-0.1.0/chewme_audit.egg-info/entry_points.txt +2 -0
- chewme_audit-0.1.0/chewme_audit.egg-info/requires.txt +4 -0
- chewme_audit-0.1.0/chewme_audit.egg-info/top_level.txt +1 -0
- chewme_audit-0.1.0/pyproject.toml +21 -0
- chewme_audit-0.1.0/setup.cfg +4 -0
- chewme_audit-0.1.0/tests/test_api_log.py +72 -0
- chewme_audit-0.1.0/tests/test_claude_code.py +93 -0
- chewme_audit-0.1.0/tests/test_cli.py +63 -0
- chewme_audit-0.1.0/tests/test_cross_trace.py +50 -0
- chewme_audit-0.1.0/tests/test_detectors.py +110 -0
- chewme_audit-0.1.0/tests/test_diff.py +176 -0
- chewme_audit-0.1.0/tests/test_pricing.py +63 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 chewme-audit contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chewme-audit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Cost-audit reports for AI agent traces: find fixable waste, price it, fix it.
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Provides-Extra: fast-count
|
|
10
|
+
Requires-Dist: tiktoken; extra == "fast-count"
|
|
11
|
+
Requires-Dist: tokenizers; extra == "fast-count"
|
|
12
|
+
Dynamic: license-file
|
|
13
|
+
|
|
14
|
+
# chewme-audit
|
|
15
|
+
|
|
16
|
+
A CLI that reads your agent traces and tells you where the money went —
|
|
17
|
+
every fixable waste pattern, its measured dollar cost, and a concrete
|
|
18
|
+
copy-paste fix. MIT licensed. Not a money play; a working tool.
|
|
19
|
+
|
|
20
|
+
## Worked example: the 283-repeat loop
|
|
21
|
+
|
|
22
|
+
A public SWE-agent trajectory (`iterative__dvc-7734`, nebius set —
|
|
23
|
+
chosen as the clearest loop case in the 73-trajectory set, not claimed
|
|
24
|
+
representative) fell into an error loop: a malformed `edit` command,
|
|
25
|
+
repeated **283 times** until the step limit. The audit flagged it; the
|
|
26
|
+
recommended fix (error-loop dedup) was applied; the agent was re-run
|
|
27
|
+
from the fixed context with a real model call (deepseek-chat,
|
|
28
|
+
2026-10-17, $0.0015).
|
|
29
|
+
|
|
30
|
+
**Before → after** (`--diff`, deepseek):
|
|
31
|
+
|
|
32
|
+
- Waste: **13,193 tokens ($0.0020)** → **3,041 tokens ($0.0005)** —
|
|
33
|
+
**−10,152 tokens (−$0.0015)**
|
|
34
|
+
- The loop is gone: the 283 identical repeats tripped both the
|
|
35
|
+
exact-repeat and near-duplicate detectors, but the total counts each
|
|
36
|
+
step once (cross-detector dedupe — overlapping findings are not
|
|
37
|
+
double-counted)
|
|
38
|
+
- Per million wasted tokens, by provider (miss rate — what waste
|
|
39
|
+
actually costs): DeepSeek **$0.15**, Claude Sonnet 5.5 **$2.00**,
|
|
40
|
+
GPT-5/6 class **$4.00**, Grok **$1.25**, Gemini Flash **$0.75**.
|
|
41
|
+
Same waste, even playing field. (Recorded sheets; `--pricing`
|
|
42
|
+
overrides.)
|
|
43
|
+
- The agent broke the loop on the very next call: instead of a 284th
|
|
44
|
+
malformed edit, it reasoned about the actual bug (pickle protocol 5
|
|
45
|
+
on Python 3.7) and issued `bash grep -rn "pickle" dvc/ | head -50`
|
|
46
|
+
- What this proves: the fix lets the agent **progress**. It does NOT
|
|
47
|
+
prove the agent solves the underlying issue — the re-run was one
|
|
48
|
+
step. (See `traces/worked_example/PROVENANCE.md`.)
|
|
49
|
+
- Residual waste ($0.0005, oversized outputs the fix didn't touch) is
|
|
50
|
+
listed, not hidden — the report's "fixes not fully applied" section
|
|
51
|
+
re-surfaces those snippets
|
|
52
|
+
|
|
53
|
+
**Stress test, not a waste claim (2026-10-17):** the same real loop
|
|
54
|
+
bytes assembled to exactly 1,000,000 input tokens — 99.5% loop by
|
|
55
|
+
construction, so the 998,009-token (99.8%, $0.1497) reading is the
|
|
56
|
+
*expected* result, not a discovery about real agents. What the test
|
|
57
|
+
actually proves: the tool audits 1M tokens in ~8s, the dedupe holds at
|
|
58
|
+
scale (naive per-detector sum: 1,992,977 vs correct 998,009), and
|
|
59
|
+
`--diff` works end to end (→ 3,041 tokens, −$0.1492). A live
|
|
60
|
+
deepseek-chat replay with the fix broke a 1000-deep loop for ≈$0.0014
|
|
61
|
+
(5,074 prompt / 41 completion tokens, real billed traffic). For what
|
|
62
|
+
waste looks like in real trajectories, see the worked example above
|
|
63
|
+
and the honest-scope section below. (`traces/calibration_1M/` —
|
|
64
|
+
assembled calibration data, not observed traffic; traces generated by
|
|
65
|
+
`generate.py`, deterministic, ~3s)
|
|
66
|
+
|
|
67
|
+
The headline finding carries a tamper-evident receipt
|
|
68
|
+
(`--receipt`): `error_loop_dedup`, 10,152 tokens, $0.0015,
|
|
69
|
+
SHA-256 `6269f6eb…e816`.
|
|
70
|
+
|
|
71
|
+
Reproduce it:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
python -m chewme_audit.cli traces/worked_example/before.jsonl \
|
|
75
|
+
traces/worked_example/after.jsonl --diff --provider deepseek
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Full report, traces, and provenance: `traces/worked_example/`.
|
|
79
|
+
|
|
80
|
+
## The honest scope, first
|
|
81
|
+
|
|
82
|
+
- **What it finds:** repeated identical tool calls (usually agents stuck
|
|
83
|
+
in error loops), near-duplicate re-sends (full file re-views after
|
|
84
|
+
one-line edits), oversized tool outputs nothing later references, and
|
|
85
|
+
pretty-printed JSON. Each finding names the exact call.
|
|
86
|
+
- **What it can't see from trace exports:** real cache hit/miss behavior
|
|
87
|
+
and reasoning-token overspend need your provider API logs. The report
|
|
88
|
+
says so explicitly instead of guessing.
|
|
89
|
+
- **Estimates out of the box from trace exports; hand it your API logs
|
|
90
|
+
if you want exacts.** Without `--api-log`, every dollar figure is
|
|
91
|
+
labeled **estimated**. With it, cache accounting is **exact** and the
|
|
92
|
+
report says **measured**.
|
|
93
|
+
- **Not bound to API billing — works on subscription (flat-plan) usage
|
|
94
|
+
too.** The audit reads trace exports; it never calls a provider API,
|
|
95
|
+
so how you were billed doesn't matter. On a flat plan the meaningful
|
|
96
|
+
numbers are waste tokens and waste share ("35% of session I/O was pure
|
|
97
|
+
re-verification"); per-token dollar figures are illustrative there,
|
|
98
|
+
and the report labels them as such.
|
|
99
|
+
- **The numbers behind it:** on public benchmark trajectories, 74%
|
|
100
|
+
carried measurable waste ≥10% of input spend, ~6–16% of the total bill
|
|
101
|
+
after honest shrinking. Those figures are labeled "measured on public
|
|
102
|
+
benchmark trajectories" everywhere — benchmark agents loop more than
|
|
103
|
+
production agents, so treat your own traces as the true test.
|
|
104
|
+
- **Fix safety:** the two headline fixes (error-loop dedup, diff-reads)
|
|
105
|
+
were replay-tested on 13 trajectory pairs — 13/13 preserve or improve
|
|
106
|
+
agent comprehension, no breakage. An audit that recommends fixes which
|
|
107
|
+
break agents loses trust fast; these don't.
|
|
108
|
+
|
|
109
|
+
## Why this gets more useful over time
|
|
110
|
+
|
|
111
|
+
Two trends both point the same way:
|
|
112
|
+
|
|
113
|
+
- **Cache discounts keep getting steeper on newer models.** DeepSeek
|
|
114
|
+
discounts cache hits 50×, Claude's newest models 20–40×, OpenAI's
|
|
115
|
+
GPT-5/6 class 10×. A cache break on a 40×-discount model costs four
|
|
116
|
+
times what the same break costs at 10× — and providers are competing
|
|
117
|
+
on these discounts, so the gap widens.
|
|
118
|
+
- **Agents keep getting more ambitious.** Bigger contexts, longer
|
|
119
|
+
trajectories, more tool calls per task. Every step of that multiplies
|
|
120
|
+
the raw material: more re-reads, more retries, more repeated calls.
|
|
121
|
+
|
|
122
|
+
The more your agents do, and the newer the models they run on, the more
|
|
123
|
+
each unit of waste costs you. This tool measures that waste — so its
|
|
124
|
+
value grows with the market, not against it.
|
|
125
|
+
|
|
126
|
+
## Quickstart
|
|
127
|
+
|
|
128
|
+
No API keys needed — token counting is local.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Estimates out of the box:
|
|
132
|
+
python -m chewme_audit.cli traces/sample.jsonl --provider deepseek
|
|
133
|
+
|
|
134
|
+
# Exact cache accounting from your API logs:
|
|
135
|
+
python -m chewme_audit.cli my_traces.jsonl --provider deepseek \
|
|
136
|
+
--api-log my_api_log.jsonl
|
|
137
|
+
|
|
138
|
+
# JSON output, framework-specific fixes, tamper-evident receipts:
|
|
139
|
+
python -m chewme_audit.cli my_traces.jsonl --provider grok \
|
|
140
|
+
--output json --framework langchain --receipt --out audit.json
|
|
141
|
+
|
|
142
|
+
# Override pricing (file or inline JSON, merged over recorded sheets):
|
|
143
|
+
python -m chewme_audit.cli my_traces.jsonl --provider deepseek \
|
|
144
|
+
--pricing '{"deepseek": {"miss_per_mtok": 0.20}}'
|
|
145
|
+
|
|
146
|
+
# OPT-IN: illustrative total-bill share (assumes outputs ~50% of bill).
|
|
147
|
+
# Off by default so nobody quotes it without the label:
|
|
148
|
+
python -m chewme_audit.cli my_traces.jsonl --provider deepseek --total-bill
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Diff mode: prove the delta
|
|
152
|
+
|
|
153
|
+
The complete loop — find → recommend fix → apply → prove it:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
python -m chewme_audit.cli before.jsonl after.jsonl --diff --provider deepseek
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
All flags (`--provider`, `--format`, `--framework`, `--pricing`,
|
|
160
|
+
`--api-log`, `--output`, `--out`) apply to both sides; `--api-log`
|
|
161
|
+
applies the same log to both. Traces are matched by `trace_id` when
|
|
162
|
+
both sides carry them, otherwise by order — unmatched traces are listed,
|
|
163
|
+
never silently dropped.
|
|
164
|
+
|
|
165
|
+
The Diff section answers three questions:
|
|
166
|
+
|
|
167
|
+
1. **Net change** — waste and input spend, before → after, in tokens
|
|
168
|
+
and dollars, plus residual waste left.
|
|
169
|
+
2. **What disappeared / shrank** — resolved and reduced classes with
|
|
170
|
+
the original detector and fix key.
|
|
171
|
+
3. **What remains or got worse** — new and unchanged findings, so a
|
|
172
|
+
partial win never gets shipped as done.
|
|
173
|
+
|
|
174
|
+
Fix keys surviving on both sides are re-surfaced with their snippet and
|
|
175
|
+
a note that the fix wasn't fully applied (or the agent found a new way
|
|
176
|
+
to loop).
|
|
177
|
+
|
|
178
|
+
### Token counting
|
|
179
|
+
|
|
180
|
+
Token counts come from the first available backend, and the basis is
|
|
181
|
+
labeled on every figure:
|
|
182
|
+
|
|
183
|
+
1. **`tiktoken` (`o200k_base`), if installed** (`pip install tiktoken`) —
|
|
184
|
+
counts labeled `o200k-local`. This is the only public basis whose
|
|
185
|
+
counts may back dollar figures.
|
|
186
|
+
2. **chars/4 estimate** — labeled `chars4-estimate`. Used when tiktoken
|
|
187
|
+
isn't installed. Never priced; the report says so.
|
|
188
|
+
|
|
189
|
+
A third backend (a local provider-tokenizer via `CHEWME_LAB`) exists for
|
|
190
|
+
the author's own lab runs; it isn't needed to use the tool.
|
|
191
|
+
|
|
192
|
+
## Inputs
|
|
193
|
+
|
|
194
|
+
| Flag | Format |
|
|
195
|
+
|---|---|
|
|
196
|
+
| (default) | JSONL, one observation per line — schema auto-detected (generic, nebius/SWE-agent style, or bare observations) |
|
|
197
|
+
| `--format langfuse` | Langfuse trace export (JSON array or JSONL) |
|
|
198
|
+
| `--format langsmith` | LangSmith run export (JSON array or JSONL) |
|
|
199
|
+
| `--format claude-code` | Claude Code CLI session transcript (`~/.claude/projects/*/*.jsonl`) — works on subscription usage too, no API key needed |
|
|
200
|
+
| `--api-log FILE` | Provider API log: JSONL, one record per request with `prompt_tokens`, `cached_tokens`, `completion_tokens` (OpenAI-style `usage` objects accepted). Joined to steps by `(trace_id, step)`. |
|
|
201
|
+
|
|
202
|
+
## What the report contains
|
|
203
|
+
|
|
204
|
+
- **Headline:** measurable waste in tokens and dollars, share of input
|
|
205
|
+
spend — each labeled estimated or measured. The total-bill share is
|
|
206
|
+
**opt-in only** (`--total-bill`): it's illustrative (assumes outputs
|
|
207
|
+
~50% of bill), so it's off by default rather than quoted without its
|
|
208
|
+
label.
|
|
209
|
+
- **Prioritized findings:** every waste instance by dollar impact, with
|
|
210
|
+
the evidence (repetition counts, similarity scores, diff hints).
|
|
211
|
+
- **Recommended fixes:** copy-paste snippets for your framework
|
|
212
|
+
(`--framework generic|langchain|llamaindex|openai_agents`), each with
|
|
213
|
+
its safety evidence.
|
|
214
|
+
- **Needs your API logs:** the classes trace exports can't measure,
|
|
215
|
+
stated plainly, never priced.
|
|
216
|
+
- **`--receipt`:** tamper-evident per-finding receipts (SHA-256 over
|
|
217
|
+
canonical fields; hashes of text, never the text — no PII).
|
|
218
|
+
- **Data handling:** findings may include up to 200 characters of the
|
|
219
|
+
repeated observation as evidence (in the JSON report's `detail`
|
|
220
|
+
field). Receipts are hash-only. The tool runs locally and never
|
|
221
|
+
sends your traces anywhere.
|
|
222
|
+
|
|
223
|
+
## Pricing
|
|
224
|
+
|
|
225
|
+
Recorded sheets (re-verify before quoting): `deepseek-flash` —
|
|
226
|
+
miss $0.15/M, hit $0.003/M, out $0.60/M (peak windows 01:00–04:00 and
|
|
227
|
+
06:00–10:00 UTC Mon–Fri ×2); `grok-4.20-0309` — in $1.25/M, cached
|
|
228
|
+
$0.20/M, out $2.50/M; `claude-sonnet-5-5` — miss $2.00/M, hit $0.10/M
|
|
229
|
+
(20×), out $10.00/M; `gpt-5.6-sol` — miss $4.00/M, hit $0.40/M, out $20.00/M
|
|
230
|
+
(promo through 2026-11-21); `gemini-3.8-flash` — miss $0.75/M,
|
|
231
|
+
hit $0.075/M, out $3.75/M. Waste is priced at the cache-**miss** rate:
|
|
232
|
+
measured on benchmark trajectories, waste spans are 100% cache misses
|
|
233
|
+
(duplicates at new positions can't hit under prefix caching).
|
|
234
|
+
|
|
235
|
+
Sheets are hardcoded and will drift — override any rate with
|
|
236
|
+
`--pricing` (JSON file or inline), which merges over the recorded
|
|
237
|
+
sheets without touching the repo.
|
|
238
|
+
|
|
239
|
+
## Tests
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
cd tests && python3 run_tests.py
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The regression suite runs the detectors against real excerpts from the
|
|
246
|
+
public SWE-agent trajectories behind the premise measurements — a
|
|
247
|
+
detector that stops firing on them is a regression.
|
|
248
|
+
|
|
249
|
+
## Sample data
|
|
250
|
+
|
|
251
|
+
`traces/sample.jsonl` — 5 trajectories (683 steps) from the public
|
|
252
|
+
nebius SWE-agent set, deliberately the heaviest-waste tail (that's why
|
|
253
|
+
the sample report shows a high waste share; it is not representative).
|
|
254
|
+
`traces/sample_api_log.jsonl` — synthetic demo API log for the sample
|
|
255
|
+
traces (labeled `_synthetic` per record).
|
|
256
|
+
|
|
257
|
+
`traces/sample_typical.jsonl` — 5 trajectories from the **middle
|
|
258
|
+
quintile** of the same set (median waste share), for calibrating
|
|
259
|
+
expectations: 27,947 waste tokens, 39.6% of input on deepseek. Still
|
|
260
|
+
benchmark-trajectory waste — production agents loop less — but a fairer
|
|
261
|
+
picture of what "a normal run" looks like than the heavy tail.
|
|
262
|
+
|
|
263
|
+
## The `rust/` folder
|
|
264
|
+
|
|
265
|
+
The deterministic Rust core from the earlier wrapper work, kept as a
|
|
266
|
+
library: fidelity gate, collision handling, lexical rules. The CLI is
|
|
267
|
+
pure Python and doesn't need it — it's the future performance path
|
|
268
|
+
(byte-exact minify with real guarantees) and the home of the
|
|
269
|
+
`pretty_printing` detector's "here's what minify would save you" line.
|
|
270
|
+
See `rust/README.md`.
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# chewme-audit
|
|
2
|
+
|
|
3
|
+
A CLI that reads your agent traces and tells you where the money went —
|
|
4
|
+
every fixable waste pattern, its measured dollar cost, and a concrete
|
|
5
|
+
copy-paste fix. MIT licensed. Not a money play; a working tool.
|
|
6
|
+
|
|
7
|
+
## Worked example: the 283-repeat loop
|
|
8
|
+
|
|
9
|
+
A public SWE-agent trajectory (`iterative__dvc-7734`, nebius set —
|
|
10
|
+
chosen as the clearest loop case in the 73-trajectory set, not claimed
|
|
11
|
+
representative) fell into an error loop: a malformed `edit` command,
|
|
12
|
+
repeated **283 times** until the step limit. The audit flagged it; the
|
|
13
|
+
recommended fix (error-loop dedup) was applied; the agent was re-run
|
|
14
|
+
from the fixed context with a real model call (deepseek-chat,
|
|
15
|
+
2026-10-17, $0.0015).
|
|
16
|
+
|
|
17
|
+
**Before → after** (`--diff`, deepseek):
|
|
18
|
+
|
|
19
|
+
- Waste: **13,193 tokens ($0.0020)** → **3,041 tokens ($0.0005)** —
|
|
20
|
+
**−10,152 tokens (−$0.0015)**
|
|
21
|
+
- The loop is gone: the 283 identical repeats tripped both the
|
|
22
|
+
exact-repeat and near-duplicate detectors, but the total counts each
|
|
23
|
+
step once (cross-detector dedupe — overlapping findings are not
|
|
24
|
+
double-counted)
|
|
25
|
+
- Per million wasted tokens, by provider (miss rate — what waste
|
|
26
|
+
actually costs): DeepSeek **$0.15**, Claude Sonnet 5.5 **$2.00**,
|
|
27
|
+
GPT-5/6 class **$4.00**, Grok **$1.25**, Gemini Flash **$0.75**.
|
|
28
|
+
Same waste, even playing field. (Recorded sheets; `--pricing`
|
|
29
|
+
overrides.)
|
|
30
|
+
- The agent broke the loop on the very next call: instead of a 284th
|
|
31
|
+
malformed edit, it reasoned about the actual bug (pickle protocol 5
|
|
32
|
+
on Python 3.7) and issued `bash grep -rn "pickle" dvc/ | head -50`
|
|
33
|
+
- What this proves: the fix lets the agent **progress**. It does NOT
|
|
34
|
+
prove the agent solves the underlying issue — the re-run was one
|
|
35
|
+
step. (See `traces/worked_example/PROVENANCE.md`.)
|
|
36
|
+
- Residual waste ($0.0005, oversized outputs the fix didn't touch) is
|
|
37
|
+
listed, not hidden — the report's "fixes not fully applied" section
|
|
38
|
+
re-surfaces those snippets
|
|
39
|
+
|
|
40
|
+
**Stress test, not a waste claim (2026-10-17):** the same real loop
|
|
41
|
+
bytes assembled to exactly 1,000,000 input tokens — 99.5% loop by
|
|
42
|
+
construction, so the 998,009-token (99.8%, $0.1497) reading is the
|
|
43
|
+
*expected* result, not a discovery about real agents. What the test
|
|
44
|
+
actually proves: the tool audits 1M tokens in ~8s, the dedupe holds at
|
|
45
|
+
scale (naive per-detector sum: 1,992,977 vs correct 998,009), and
|
|
46
|
+
`--diff` works end to end (→ 3,041 tokens, −$0.1492). A live
|
|
47
|
+
deepseek-chat replay with the fix broke a 1000-deep loop for ≈$0.0014
|
|
48
|
+
(5,074 prompt / 41 completion tokens, real billed traffic). For what
|
|
49
|
+
waste looks like in real trajectories, see the worked example above
|
|
50
|
+
and the honest-scope section below. (`traces/calibration_1M/` —
|
|
51
|
+
assembled calibration data, not observed traffic; traces generated by
|
|
52
|
+
`generate.py`, deterministic, ~3s)
|
|
53
|
+
|
|
54
|
+
The headline finding carries a tamper-evident receipt
|
|
55
|
+
(`--receipt`): `error_loop_dedup`, 10,152 tokens, $0.0015,
|
|
56
|
+
SHA-256 `6269f6eb…e816`.
|
|
57
|
+
|
|
58
|
+
Reproduce it:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
python -m chewme_audit.cli traces/worked_example/before.jsonl \
|
|
62
|
+
traces/worked_example/after.jsonl --diff --provider deepseek
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Full report, traces, and provenance: `traces/worked_example/`.
|
|
66
|
+
|
|
67
|
+
## The honest scope, first
|
|
68
|
+
|
|
69
|
+
- **What it finds:** repeated identical tool calls (usually agents stuck
|
|
70
|
+
in error loops), near-duplicate re-sends (full file re-views after
|
|
71
|
+
one-line edits), oversized tool outputs nothing later references, and
|
|
72
|
+
pretty-printed JSON. Each finding names the exact call.
|
|
73
|
+
- **What it can't see from trace exports:** real cache hit/miss behavior
|
|
74
|
+
and reasoning-token overspend need your provider API logs. The report
|
|
75
|
+
says so explicitly instead of guessing.
|
|
76
|
+
- **Estimates out of the box from trace exports; hand it your API logs
|
|
77
|
+
if you want exacts.** Without `--api-log`, every dollar figure is
|
|
78
|
+
labeled **estimated**. With it, cache accounting is **exact** and the
|
|
79
|
+
report says **measured**.
|
|
80
|
+
- **Not bound to API billing — works on subscription (flat-plan) usage
|
|
81
|
+
too.** The audit reads trace exports; it never calls a provider API,
|
|
82
|
+
so how you were billed doesn't matter. On a flat plan the meaningful
|
|
83
|
+
numbers are waste tokens and waste share ("35% of session I/O was pure
|
|
84
|
+
re-verification"); per-token dollar figures are illustrative there,
|
|
85
|
+
and the report labels them as such.
|
|
86
|
+
- **The numbers behind it:** on public benchmark trajectories, 74%
|
|
87
|
+
carried measurable waste ≥10% of input spend, ~6–16% of the total bill
|
|
88
|
+
after honest shrinking. Those figures are labeled "measured on public
|
|
89
|
+
benchmark trajectories" everywhere — benchmark agents loop more than
|
|
90
|
+
production agents, so treat your own traces as the true test.
|
|
91
|
+
- **Fix safety:** the two headline fixes (error-loop dedup, diff-reads)
|
|
92
|
+
were replay-tested on 13 trajectory pairs — 13/13 preserve or improve
|
|
93
|
+
agent comprehension, no breakage. An audit that recommends fixes which
|
|
94
|
+
break agents loses trust fast; these don't.
|
|
95
|
+
|
|
96
|
+
## Why this gets more useful over time
|
|
97
|
+
|
|
98
|
+
Two trends both point the same way:
|
|
99
|
+
|
|
100
|
+
- **Cache discounts keep getting steeper on newer models.** DeepSeek
|
|
101
|
+
discounts cache hits 50×, Claude's newest models 20–40×, OpenAI's
|
|
102
|
+
GPT-5/6 class 10×. A cache break on a 40×-discount model costs four
|
|
103
|
+
times what the same break costs at 10× — and providers are competing
|
|
104
|
+
on these discounts, so the gap widens.
|
|
105
|
+
- **Agents keep getting more ambitious.** Bigger contexts, longer
|
|
106
|
+
trajectories, more tool calls per task. Every step of that multiplies
|
|
107
|
+
the raw material: more re-reads, more retries, more repeated calls.
|
|
108
|
+
|
|
109
|
+
The more your agents do, and the newer the models they run on, the more
|
|
110
|
+
each unit of waste costs you. This tool measures that waste — so its
|
|
111
|
+
value grows with the market, not against it.
|
|
112
|
+
|
|
113
|
+
## Quickstart
|
|
114
|
+
|
|
115
|
+
No API keys needed — token counting is local.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Estimates out of the box:
|
|
119
|
+
python -m chewme_audit.cli traces/sample.jsonl --provider deepseek
|
|
120
|
+
|
|
121
|
+
# Exact cache accounting from your API logs:
|
|
122
|
+
python -m chewme_audit.cli my_traces.jsonl --provider deepseek \
|
|
123
|
+
--api-log my_api_log.jsonl
|
|
124
|
+
|
|
125
|
+
# JSON output, framework-specific fixes, tamper-evident receipts:
|
|
126
|
+
python -m chewme_audit.cli my_traces.jsonl --provider grok \
|
|
127
|
+
--output json --framework langchain --receipt --out audit.json
|
|
128
|
+
|
|
129
|
+
# Override pricing (file or inline JSON, merged over recorded sheets):
|
|
130
|
+
python -m chewme_audit.cli my_traces.jsonl --provider deepseek \
|
|
131
|
+
--pricing '{"deepseek": {"miss_per_mtok": 0.20}}'
|
|
132
|
+
|
|
133
|
+
# OPT-IN: illustrative total-bill share (assumes outputs ~50% of bill).
|
|
134
|
+
# Off by default so nobody quotes it without the label:
|
|
135
|
+
python -m chewme_audit.cli my_traces.jsonl --provider deepseek --total-bill
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Diff mode: prove the delta
|
|
139
|
+
|
|
140
|
+
The complete loop — find → recommend fix → apply → prove it:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
python -m chewme_audit.cli before.jsonl after.jsonl --diff --provider deepseek
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
All flags (`--provider`, `--format`, `--framework`, `--pricing`,
|
|
147
|
+
`--api-log`, `--output`, `--out`) apply to both sides; `--api-log`
|
|
148
|
+
applies the same log to both. Traces are matched by `trace_id` when
|
|
149
|
+
both sides carry them, otherwise by order — unmatched traces are listed,
|
|
150
|
+
never silently dropped.
|
|
151
|
+
|
|
152
|
+
The Diff section answers three questions:
|
|
153
|
+
|
|
154
|
+
1. **Net change** — waste and input spend, before → after, in tokens
|
|
155
|
+
and dollars, plus residual waste left.
|
|
156
|
+
2. **What disappeared / shrank** — resolved and reduced classes with
|
|
157
|
+
the original detector and fix key.
|
|
158
|
+
3. **What remains or got worse** — new and unchanged findings, so a
|
|
159
|
+
partial win never gets shipped as done.
|
|
160
|
+
|
|
161
|
+
Fix keys surviving on both sides are re-surfaced with their snippet and
|
|
162
|
+
a note that the fix wasn't fully applied (or the agent found a new way
|
|
163
|
+
to loop).
|
|
164
|
+
|
|
165
|
+
### Token counting
|
|
166
|
+
|
|
167
|
+
Token counts come from the first available backend, and the basis is
|
|
168
|
+
labeled on every figure:
|
|
169
|
+
|
|
170
|
+
1. **`tiktoken` (`o200k_base`), if installed** (`pip install tiktoken`) —
|
|
171
|
+
counts labeled `o200k-local`. This is the only public basis whose
|
|
172
|
+
counts may back dollar figures.
|
|
173
|
+
2. **chars/4 estimate** — labeled `chars4-estimate`. Used when tiktoken
|
|
174
|
+
isn't installed. Never priced; the report says so.
|
|
175
|
+
|
|
176
|
+
A third backend (a local provider-tokenizer via `CHEWME_LAB`) exists for
|
|
177
|
+
the author's own lab runs; it isn't needed to use the tool.
|
|
178
|
+
|
|
179
|
+
## Inputs
|
|
180
|
+
|
|
181
|
+
| Flag | Format |
|
|
182
|
+
|---|---|
|
|
183
|
+
| (default) | JSONL, one observation per line — schema auto-detected (generic, nebius/SWE-agent style, or bare observations) |
|
|
184
|
+
| `--format langfuse` | Langfuse trace export (JSON array or JSONL) |
|
|
185
|
+
| `--format langsmith` | LangSmith run export (JSON array or JSONL) |
|
|
186
|
+
| `--format claude-code` | Claude Code CLI session transcript (`~/.claude/projects/*/*.jsonl`) — works on subscription usage too, no API key needed |
|
|
187
|
+
| `--api-log FILE` | Provider API log: JSONL, one record per request with `prompt_tokens`, `cached_tokens`, `completion_tokens` (OpenAI-style `usage` objects accepted). Joined to steps by `(trace_id, step)`. |
|
|
188
|
+
|
|
189
|
+
## What the report contains
|
|
190
|
+
|
|
191
|
+
- **Headline:** measurable waste in tokens and dollars, share of input
|
|
192
|
+
spend — each labeled estimated or measured. The total-bill share is
|
|
193
|
+
**opt-in only** (`--total-bill`): it's illustrative (assumes outputs
|
|
194
|
+
~50% of bill), so it's off by default rather than quoted without its
|
|
195
|
+
label.
|
|
196
|
+
- **Prioritized findings:** every waste instance by dollar impact, with
|
|
197
|
+
the evidence (repetition counts, similarity scores, diff hints).
|
|
198
|
+
- **Recommended fixes:** copy-paste snippets for your framework
|
|
199
|
+
(`--framework generic|langchain|llamaindex|openai_agents`), each with
|
|
200
|
+
its safety evidence.
|
|
201
|
+
- **Needs your API logs:** the classes trace exports can't measure,
|
|
202
|
+
stated plainly, never priced.
|
|
203
|
+
- **`--receipt`:** tamper-evident per-finding receipts (SHA-256 over
|
|
204
|
+
canonical fields; hashes of text, never the text — no PII).
|
|
205
|
+
- **Data handling:** findings may include up to 200 characters of the
|
|
206
|
+
repeated observation as evidence (in the JSON report's `detail`
|
|
207
|
+
field). Receipts are hash-only. The tool runs locally and never
|
|
208
|
+
sends your traces anywhere.
|
|
209
|
+
|
|
210
|
+
## Pricing
|
|
211
|
+
|
|
212
|
+
Recorded sheets (re-verify before quoting): `deepseek-flash` —
|
|
213
|
+
miss $0.15/M, hit $0.003/M, out $0.60/M (peak windows 01:00–04:00 and
|
|
214
|
+
06:00–10:00 UTC Mon–Fri ×2); `grok-4.20-0309` — in $1.25/M, cached
|
|
215
|
+
$0.20/M, out $2.50/M; `claude-sonnet-5-5` — miss $2.00/M, hit $0.10/M
|
|
216
|
+
(20×), out $10.00/M; `gpt-5.6-sol` — miss $4.00/M, hit $0.40/M, out $20.00/M
|
|
217
|
+
(promo through 2026-11-21); `gemini-3.8-flash` — miss $0.75/M,
|
|
218
|
+
hit $0.075/M, out $3.75/M. Waste is priced at the cache-**miss** rate:
|
|
219
|
+
measured on benchmark trajectories, waste spans are 100% cache misses
|
|
220
|
+
(duplicates at new positions can't hit under prefix caching).
|
|
221
|
+
|
|
222
|
+
Sheets are hardcoded and will drift — override any rate with
|
|
223
|
+
`--pricing` (JSON file or inline), which merges over the recorded
|
|
224
|
+
sheets without touching the repo.
|
|
225
|
+
|
|
226
|
+
## Tests
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
cd tests && python3 run_tests.py
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The regression suite runs the detectors against real excerpts from the
|
|
233
|
+
public SWE-agent trajectories behind the premise measurements — a
|
|
234
|
+
detector that stops firing on them is a regression.
|
|
235
|
+
|
|
236
|
+
## Sample data
|
|
237
|
+
|
|
238
|
+
`traces/sample.jsonl` — 5 trajectories (683 steps) from the public
|
|
239
|
+
nebius SWE-agent set, deliberately the heaviest-waste tail (that's why
|
|
240
|
+
the sample report shows a high waste share; it is not representative).
|
|
241
|
+
`traces/sample_api_log.jsonl` — synthetic demo API log for the sample
|
|
242
|
+
traces (labeled `_synthetic` per record).
|
|
243
|
+
|
|
244
|
+
`traces/sample_typical.jsonl` — 5 trajectories from the **middle
|
|
245
|
+
quintile** of the same set (median waste share), for calibrating
|
|
246
|
+
expectations: 27,947 waste tokens, 39.6% of input on deepseek. Still
|
|
247
|
+
benchmark-trajectory waste — production agents loop less — but a fairer
|
|
248
|
+
picture of what "a normal run" looks like than the heavy tail.
|
|
249
|
+
|
|
250
|
+
## The `rust/` folder
|
|
251
|
+
|
|
252
|
+
The deterministic Rust core from the earlier wrapper work, kept as a
|
|
253
|
+
library: fidelity gate, collision handling, lexical rules. The CLI is
|
|
254
|
+
pure Python and doesn't need it — it's the future performance path
|
|
255
|
+
(byte-exact minify with real guarantees) and the home of the
|
|
256
|
+
`pretty_printing` detector's "here's what minify would save you" line.
|
|
257
|
+
See `rust/README.md`.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""chewme-audit: cost-audit reports for AI agent traces.
|
|
2
|
+
|
|
3
|
+
Reads a team's agent traces and reports every fixable waste pattern,
|
|
4
|
+
its measured dollar cost, and a concrete copy-paste fix.
|
|
5
|
+
|
|
6
|
+
Honest scope (standing): benchmark-trajectory numbers stay labeled as
|
|
7
|
+
such; no claim beyond what was measured. Token counting labels its
|
|
8
|
+
basis on every figure; where no provider tokenizer exists, figures are
|
|
9
|
+
labeled as estimates, never priced.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Trace adapters: normalize vendor exports into Trace objects."""
|