# Unit economics 101: what does a useful result cost?

A client asks, “The model call is cheap. Why does this service cost so much to run?” Start with the work the client needs finished. A request can produce several model calls, require human correction and still fail to produce a useful result.

This original 45-minute lesson turns that conversation into a small, inspectable calculation. Follow the visual, predict six cases, then run an offline Python calculator. Every request count, acceptance label, effort estimate and rate is fictional. These are teaching inputs, not vendor prices or measured customer outcomes.

## 1. Start with a finished repair

A repair shop buys parts, spends time diagnosing a fault, repeats some work and checks the repair. Dividing only the parts bill by the number of workshop visits will not tell you the cost of a completed repair.

For an AI service, **unit economics** relates the costs and, where relevant, revenue associated with a defined unit of work. This lesson concentrates on cost. A **requested task** is the work submitted by a user. A **model attempt** is one call made while handling it. An **accepted task** is a distinct completed task that meets agreed criteria. A retry is another attempt at the same task.

The analogy has a limit: acceptance is not automatic or necessarily a single physical inspection. A software team must define the evidence, decision owner, observation period and quality conditions. Here a fictional reviewer accepts a draft only if it answers the request using an approved source and needs no correction. The calculator consumes supplied labels; it does not judge drafts or prove their quality.

An FDE needs this distinction to compare a model-assisted workflow with a simpler alternative. Lower token spend can be useful, but it is only one input to the delivery decision.

## 2. Read one complete cost ledger

All six cases concern the same 100 fictional administrative requests over the same observation window. The manual case supplies a comparison, rather than assuming an AI implementation is necessary.

| Input | Supplied value | Meaning |
| --- | --- | --- |
| Input / output per model attempt | 1,000 / 400 tokens | Used for every attempt, including retries |
| Input / output rate | 40 / 200 units per million tokens | Deliberately invented rates, not a provider quote |
| Human effort rate | 0.25 units per minute | Illustrative allocation, not a salary claim |
| Infrastructure / support | 2 / 6 units per window | Allocated costs retained in every case |
| Minimum accepted tasks | 80 of 100 | A supplied comparison rule, not production approval |

In the baseline, one model attempt costs `(1,000 / 1,000,000 × 40) + (400 / 1,000,000 × 200) = 0.12` units. Across 100 attempts, that is 12 units. Reviewing all requests takes 80 minutes, costing 20 units. Infrastructure and support add 8. The total is 40 units; 80 distinct tasks are accepted.

**Cost per requested task** is `40 / 100 = 0.40`. **Cost per accepted task** is `40 / 80 = 0.50`. Both are useful when clearly named. Neither number is a selling price, profit, observed saving or return on investment.

Count costs for rejected work as well as accepted work. Keep failed attempts in the numerator and count each accepted task once in the denominator. The program uses decimal arithmetic and rounds only the displayed result.

## 3. Predict, run and compare six cases

Download `fde-outcome-cost-lab.py` into a practice folder. Use Python 3.11 or newer. It uses the standard library, writes only to the terminal and requires no account, package installation, network connection or model.

Before running it, predict which change raises total cost, which changes the accepted denominator, and whether half-priced model calls guarantee a cheaper useful result.

```sh
python3 --version
python3 fde-outcome-cost-lab.py compare
python3 fde-outcome-cost-lab.py retries
python3 fde-outcome-cost-lab.py cheaper
python3 fde-outcome-cost-lab.py none-accepted
```

On a small screen, scroll the comparison table sideways to see the complete cost and accepted-task columns.

| Case | Model attempts | Accepted tasks | Model cost | Human cost | Total cost | Cost per accepted task |
| --- | --- | --- | --- | --- | --- | --- |
| Manual | 0 | 90 | 0.00 | 64.00 | 72.00 | 0.8000 |
| Baseline | 100 | 80 | 12.00 | 20.00 | 40.00 | 0.5000 |
| Retries | 120 | 80 | 14.40 | 25.00 | 47.40 | 0.5925 |
| Cheaper calls | 140 | 60 | 8.40 | 40.00 | 56.40 | 0.9400 |
| More review | 100 | 80 | 12.00 | 40.00 | 60.00 | 0.7500 |
| None accepted | 100 | 0 | 12.00 | 20.00 | 40.00 | Undefined |

Every total includes the same 8 units of infrastructure and support. The retries case gives 20 tasks one extra attempt and one extra review minute each. It still has only 100 requested tasks and 80 accepted tasks. The cheaper case halves the token rates, but supplies 40 retried tasks, 160 review minutes and only 60 accepted tasks. Those are assumptions to investigate, not a claim that inexpensive models behave this way.

The manual and baseline cases do not deliver identical coverage: 90 versus 80 requests are accepted. Compare the remaining manual work and the consequences of the gap before choosing either. Passing the exercise's minimum acceptance count does not establish safety, latency, adoption or a release decision.

When no task is accepted, the result is `null` for cost per accepted task. It is not zero or free. Forty units were spent without an accepted denominator.

## 4. Follow the calculation in the code

`task_ledger` creates one row per requested task. Each row has a task ID, attempt count, token counts, total review effort and a final acceptance label. Open the function and locate the two separate decisions: whether another attempt occurs and whether the final task is accepted.

`summarize` counts all attempts and all review minutes, then adds the allocated infrastructure and support costs. It separately sums the distinct accepted-task labels. A task that takes two calls can contribute twice to model usage while contributing at most once to accepted work.

In a real service, connect provider usage, tool charges and human-work records to stable task IDs. Reconcile the selected time window and cost scope before comparing options. A provider's usage report cannot by itself establish whether the receiving team accepted the outcome. The [FinOps Foundation's unit-economics guidance](https://www.finops.org/framework/capabilities/unit-economics/) distinguishes technical unit metrics from business outcomes.

For Claude, consult the [current API pricing documentation](https://platform.claude.com/docs/en/about-claude/pricing) for the exact model and purchasing route. Token categories and chargeable tools can differ. The lab intentionally avoids a current price table; replace its rates with dated, applicable evidence before using the method in an actual proposal.

## 5. Change one assumption at a time

Make two separate copies of the original Python file. Keep the unchanged file as your reference.

**Experiment A: free model calls.** In `RATE_MULTIPLIER`, change the cheaper case from `D("0.5")` to `D("0")`. Predict the result, then run `cheaper`. Total cost becomes 48 units and cost per accepted task becomes 0.8000. Human effort and allocated costs remain. The case still misses the 80-task floor.

**Experiment B: longer review.** In `REVIEW_MINUTES`, change the baseline from `D("0.8")` to `D("1.6")`. Run `baseline`. Total cost becomes 60 units and cost per accepted task becomes 0.7500, while the token bill remains 12. The supplied acceptance labels remain 80; changing review effort does not automatically change them.

This is **sensitivity analysis**: asking how a conclusion changes when an assumption changes. Editing a fixture does not create a new observation. Label changed-copy results as scenarios until measured work supplies the inputs.

## 6. Turn the result into a delivery decision

Write a one-page comparison with the task definition, quality conditions, window, request count, distinct accepted count, all included costs and each input's origin. Preserve rejected work and the manual alternative. State the operating consequence of the 20 or 40 unaccepted requests; do not make that work disappear from the proposal.

Record costs missing from this exercise: implementation, integration, licensing, security work, storage growth, monitoring, incident response, taxes or commercial commitments where applicable. Decide which belong to a one-time investment and which recur. Allocate shared costs consistently and avoid charging the same review minute twice. A complete proposal needs more than this small operating estimate.

Do not multiply a synthetic “saving per task” by a sales forecast and present the result as proven benefit. Observed time released is not automatically reduced expenditure, and a lower cost does not establish willingness to pay. Ask the receiving team which outcome is valuable, who owns acceptance and what a small matched pilot would need to demonstrate.

## 7. Keep the evidence and continue

Keep six predictions, the original output, the two changed-copy outputs and a cost ledger that someone else can recalculate. Explain why 120 attempts are not 120 accepted tasks, why zero accepted tasks produces an undefined ratio, and which missing measurement could reverse your recommendation.

Continue in the protected **Forward-deployed engineering: client delivery** course, **Deliver the client packet and defend the next decision**. Bring the cost comparison into the same packet as scope, quality, access and recovery evidence. The cost calculation informs that conversation; it does not authorize rollout.

Primary references checked on 21 October 2026: FinOps Foundation unit economics and Anthropic Claude API pricing, linked above. This is original instruction with fictional inputs. No vendor affiliation, certification or commercial outcome is implied.
