agentfin — Agent FinOps: cost attribution & ROI
Which agent, which task, which team spent what — and was it worth it?
agentfin ingests token usage from your agent stack into an append-only
SQLite ledger, attributes every event to a task/agent/team via rules,
prices it from a YAML price book, and answers the Monday-morning question:
did the $4K spike come from a runaway agent or real work? Then it goes
one step further than every competitor: cost-per-outcome and ROI.
Install
pip install agentfin # (when published)
# or from source:
pip install -e ".[dev]"
60-second start
agentfin init # scaffolds .agentfin/
agentfin ingest --adapter provider usage.jsonl # Anthropic/OpenAI-style records
agentfin ingest --adapter gateway gateway.jsonl # calas-gateway ledger lines
agentfin ingest --adapter jsonl custom.jsonl # your own shape
agentfin report --by team
agentfin anomalies # spikes + probable cause
agentfin budgets # month-end forecast vs caps
agentfin budgets set team:platform 500 # create/update a monthly cap
agentfin outcomes tag refactor --kind hours_saved --value 4
agentfin outcomes roi # cost-per-outcome per task
agentfin dashboard --out report.html # static HTML, no server
How it works
- Ingest — adapters normalize provider usage records into one canonical
event:
{ts_utc, provider, model, tokens in/cache/out, task, agent, team}. Redaction runs before storage (prompts, keys,sk-…strings scrubbed). - Attribute —
rules.yamlmaps model/provider/metadata regexes to task/agent/team tags. Adapter-supplied tags win; defaults catch the rest. - Price —
pricing.yamlholds exact-SKU rates (USD per 1M tokens). Cost is computed at ingest and stored as integer micro-USD (no float drift). SKUs with no price land in the UNPRICED bucket — loud in every report, never silently zero.agentfin repricebackfills once you add rates. - Ledger — SQLite, append-only. Every event carries an idempotency key, so re-ingesting the same file is a no-op (no double-counting). Corrections are new events, never edits.
- Analyze — reports by agent/task/team/model, daily trends, robust anomaly detection (median/MAD, 14-day baseline minimum, 24h cooldown, probable-cause attached), budget burn-rate forecasts that alert before overrun, and ROI from tagged outcomes.
- Trust —
agentfin reconcile invoice.csvdiffs ledger totals against your actual provider invoice, per SKU.
Config files (in .agentfin/)
| file | purpose |
|---|---|
pricing.yaml |
exact-SKU USD/1M-token rates. Paste from the provider pricing page. |
rules.yaml |
attribution rules, first match wins. |
budgets.yaml |
monthly caps per team/agent with forecast-alert thresholds. |
config.yaml |
display currency + FX (marked * as estimates), extra redact keys. |
Adapters
jsonl— generic JSONL, flat or nestedusageblocks, flexible key names.provider— raw Anthropic (msg_…) / OpenAI (chatcmpl-…) API responses; cache tokens mapped correctly. Optionalagentfinsidecar for tags.gateway— calas-gateway ledger lines (route: provider/model); gateway-computedcost_usdis preserved verbatim, never re-priced.
Commands
init [--force] · ingest · report · trends · anomalies (detect) · alerts · budgets [check|set] · outcomes [tag|roi] · reconcile · reprice · dashboard · doctor
doctor surfaces unpriced SKUs and unattributed events — the two things
that silently ruin FinOps data. init refuses to overwrite existing config
files unless --force is given. outcome/roi remain as hidden aliases
for outcomes tag / outcomes roi.
Development
python -m pytest # 37 tests
ruff check agentfin/ tests/
Limitations (read before trusting the numbers)
- Prices are yours to maintain. Model prices change;
pricing.yamlis a snapshot. Totals are only as right as your price book — reconcile monthly. - File-based ingest only. v1 does not poll provider APIs; bring your own export or cron the API pull into JSONL.
- Attribution is heuristic. Rules are regexes over metadata. Garbage tags
in → garbage attribution out.
doctorshows the unattributed share. - Ledger is USD-only. Multi-currency display is a report-time FX estimate
(marked
*), not accounting truth. - Anomalies need history. 14 days of baseline minimum; new teams/agents get no anomaly coverage until then.
- One source per call. Idempotency keys stop same-file re-ingest, but the
same API calls ingested via two adapters (e.g. gateway file + provider
export) have different keys and will double-count.
doctorwarns on suspicious groups; ingest each source exactly once. - Anomalies evaluate the latest day in the data, not necessarily today. Backfilled history gets a spike verdict on its last day.
- Single-user SQLite. No auth, no concurrency story beyond one writer. Fine for a team cron job; not a multi-tenant SaaS backend.
- Outcome values are estimates.
hours_saved × rateis a model, not a bank deposit. ROI ranks tasks; don't put it in a 10-K.
Metadata
Release files for agentfin 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| agentfin-0.2.0.tar.gz | 32.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agentfin-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.2 kB
Release files / agentfin-0.2.0.tar.gz
| Download URL | agentfin-0.2.0.tar.gz |
|---|---|
| Size | 32.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
72862faf3c9abf844b2d7451d16818e91b39234caa665eef0d52c509d08d09a5
|
|
BLAKE2b-256 checksum How to use checksums |
cbd0ecbcf3c1e15cb1d79749ef5310e9e061c6783f604d859d314de20ac7018b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|
Release files / agentfin-0.2.0-py3-none-any.whl
| Download URL | agentfin-0.2.0-py3-none-any.whl |
|---|---|
| Size | 29.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a7d3921658093c9c6cf4519cdbac2d67f6160b7978bba792ea9f3c161e0d7666
|
|
BLAKE2b-256 checksum How to use checksums |
386ae29ecfefa582442d02db8b3cccb22222d7a916a306a11e2bec3bdc216542
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|
Security for agentfin 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.