MyRelay

← Back to the notebook

I Set the Test Before Spending Tokens on Code

The most expensive coding prompt is often the vague one you send twice. A request like “build an expense summarizer” looks cheap until the answer assumes the wrong input format, adds unnecessary dependencies, and needs three repairs. I get more useful first attempts by defining a small, testable result before asking for implementation. Here is that process, using a simple expense-summary function.

Start with one result you can verify

Choose a task small enough that you can describe success without discussing an entire application. For this walkthrough, the function accepts expense records and returns a total for each category. It does not read spreadsheets, display charts, or connect to a bank.

Write the opening request as a complete instruction: “Write a Python function that accepts a list of expense records and returns the total spending for each category.” This gives the model a direction, but not yet enough information to make reliable implementation decisions.

State the environment before it becomes an assumption

Add the runtime, dependency limits, and integration boundary. For example: “The code must run on Python 3.12 using only the standard library. It will be called by another function, so do not add interactive input, network access, or a command-line interface.”

These constraints prevent a plausible answer that cannot run in your environment. For an existing project, include the relevant function signature and nearby behavior, not the whole repository. Extra context costs tokens and can bury the details that actually matter.

Define the data and the awkward cases

Now remove ambiguity from the records. Say that each record contains a category string and an amount string representing a decimal value. Require exact decimal arithmetic, rather than binary floating-point arithmetic, because the result represents money.

Specify the decisions the model should not make for you: “Trim surrounding whitespace from category names, but preserve their capitalization. Accept nonnegative amounts with at most two decimal places. Reject missing fields, blank categories, negative amounts, and malformed amounts with a ValueError. Return an empty mapping for empty input.”

If you do not know a rule yet, ask for a clarification before implementation. One short question is usually cheaper than replacing code built around an incorrect assumption.

Give examples that act as acceptance tests

Describe expected outcomes in plain English. Two records for Food with amounts of 12.50 and 7.25 must produce a Food total of 19.75. A separate Travel record of 3.00 must remain separate. An empty list must produce an empty mapping.

Include at least one rejection case, such as an amount written as “twelve.” Ask for automated tests covering these examples and the stated validation rules. Also specify that returned totals should be Decimal values. Otherwise, correct arithmetic could still arrive wrapped in an unexpected output type.

Request a compact, runnable delivery

Finish the prompt with a clear delivery request: “Provide the implementation and standard-library unit tests. Keep the function independent of external services. Explain any remaining assumptions briefly, and do not add features beyond the request.”

Your complete prompt now combines the task, environment, data contract, edge cases, examples, and delivery requirements. It is longer than the original sentence, but those extra tokens buy decisions you would otherwise pay to correct. Save this structure as a reusable checklist rather than copying unrelated project details into every request.

Run the tests before buying another answer

No prompt guarantees that generated code will run correctly on its first attempt. Execute the tests in the target environment, then inspect whether they genuinely check your requirements. Passing weak tests is not the same as meeting the contract.

If something fails, send the exact failure, the relevant implementation, and the expected behavior. Ask for the smallest correction that preserves passing tests. Avoid restarting with “try again,” which discards useful evidence and invites another round of guessing.

Track the cost of getting to a working result

Judge a coding request by its total repair cost, not just its first response. MyRelay shows each request’s tokens and cost, which helps you compare a carefully specified attempt with a string of vague retries. Keep tasks small and check the output before requesting more.

Create a MyRelay account if you want one key and one pay-as-you-go budget across supported models. Whatever model you choose, the spending habit stays the same: define success, generate once, test locally, and pay for a follow-up only when you have specific evidence to send.

More to read