Guardrails for an AI Feature: Rate Limits, Budgets and Logs

How to put an AI model behind safe limits: why most of the protection is ordinary code around the model, how rate limits, a monthly budget ceiling and anonymous logs work, and the real bugs found before launch.

Free preview · 2 of 3 free left
Topic: Operations Guide intermediate 9 min read

Why this matters

Adding an AI model to a website takes an afternoon. Making it safe to leave running when nobody is watching takes much longer. A model can be asked things you did not plan for, it costs money on every call, and it can state something false in a confident voice. If the only protection is a polite instruction in the prompt, the first unusual visitor finds the gap.

This chapter uses a real example: the design of a private AI tutor for law students that is still being tested and is not open to the public. The decisions below come from its design log. They apply to any AI feature, whatever the subject.

What you'll learn

Why most of the protection should be plain code around the model, the order in which a message is checked, how limits and a monthly budget work, what an anonymous log can and cannot hold, and three real bugs found before launch.

Put the protection in code, not only in the prompt

A prompt is a request. Code is a rule. The tutor's main protections are all code that runs before or after the model:

This also decides where you test. The team tested in a private lab on the site, not in a model playground, because a playground sees only the prompt. A pass there proves little about the checks that sit around the model.

The order matters

Every message goes through the same steps, in this order:

  1. Limits. Is this visitor over their rate limit, over the conversation cap, or has the month's budget run out?
  2. Inbound checks. Is this advice, or off-topic?
  3. Prompt. Build the instructions for this subject and mode.
  4. Model. Make the call.
  5. Outbound check. Remove any case that is not on the verified list.
  6. Anonymous log. Save the turn.
  7. Reply.

The point of the order is that a blocked message never reaches the model. A refused request costs nothing, and a trick in the wording of the question cannot change the answer, because the refusal is written in code, not generated.

Diagram of one message passing through the tutor: the learner's message goes through the API, then the limits check and the inbound check, then the prompt, the model, the citation filter, and an anonymous log, before the reply. Two dashed paths show messages stopped before any model call.
One message through the tutor. Solid lines are the normal path; dashed lines are messages stopped before any model call.

Limits that protect people and the budget

The design sets these values, all adjustable through environment variables, so changing a limit does not mean editing code:

The last one is the most important. A warning email can be missed over a weekend. A ceiling that switches the feature off cannot be missed, and the worst case is a known number you chose in advance.

Be wrong in the safe direction

The citation filter shows a design principle worth copying. The tutor may only cite cases on a verified list. If the filter wrongly removes a real case, the student loses a little. If it lets a made-up case through, the student may rely on something false and stop trusting the tool. When a check must sometimes be wrong, choose the mistake that costs less.

The log records one known limit: a real case name with a lower-case word to the left of "v." (for example "Hammersmith and City Railway Co. v. Brand") can be removed by mistake. The team chose to accept this and watch whether it matters in testing.

Three real bugs, found before launch

Logs: keep what you need, and say so

The tutor keeps conversation logs so mistakes can be found and fixed. The privacy rules around them are part of the design:

A "Flag this answer" button feeds the site's existing feedback queue, which closes the loop: a visitor who spots a wrong answer can tell you.

Try it yourself

Pick any feature you could put behind a limit, such as a contact form. Write down: (1) the most one visitor should be able to do in 15 minutes, (2) the most the whole feature should be able to cost in a month, (3) what happens when each is reached, and (4) what you would store in a log and what you would deliberately leave out.

What's next

Limits and logs are only useful if you can see them. Read Monitoring: Metrics, Logs and Traces. For keeping the model's key out of your code, read Secrets Management: Don't Commit Passwords. The scripts that installed these checks follow the habits in Writing Idempotent Deployment Scripts.

Continue learning

Guide

Secrets Management: Don't Commit That Password

Practical credential hygiene for real projects — why secrets don't belong in source control, how .gitignore and environment variables actually protect you (and where they don't), and what to do if a secret is committed by mistake.

Guide

Monitoring 101: Metrics, Logs, and Traces

The three pillars of observability explained plainly — what metrics, logs, and traces each tell you, and which one to reach for first depending on the question you're actually asking.

Guide

Writing Idempotent Deployment Scripts

What idempotent actually means for a deployment or automation script, why it matters when a script might be run twice by accident, and concrete patterns for writing scripts that are safe to re-run.

← Back to Guides

Next → How Computers Store Numbers: Binary, Hex and Why 0.1 + 0.2 Isn't 0.3 Bits, bytes, binary and hexadecimal explained simply, why integers have limits, and why decimal fractions like 0.1 are stored approximately, with a practical rule for money.