JJoeven

Curriculum/Prompting

Stop Rules

Call finish when the world matches the goal. Max steps, max tokens, and handoff live in the prompt and in code.

intermediate20 min23 / 24

A model that says “done” while the test suite is still red has not stopped. It has lied. Speech is not the world. finish is a request. Code checks the goal.

Write stop rules in both places:

  • Prompt: “Call finish when the goal predicate is met. If you cannot, call handoff with a reason. Never invent success. Ask at most one clarifying question, then stop.”
  • Code: max_steps, token/dollar caps, and a real goal_satisfied check on the world, not on the model’s speech

The loop should not treat finish as success until the predicate passes. If the model emits finish and get_job never ran and status is unknown, reject finish. Continue, or handoff, or budget-stop. Do not trust the poem.

This is still a prompting lesson: the OS must say when to stop, or the model will loop, narrate, and emit finish to escape. The predicate itself is a few lines of Python you write on day one. Caps from the LLM spend lesson belong on the same loop. How tools mutate the world is a later track. Here, the world is a dict the prompt is not allowed to override.

Finish is a request
Finish?World checkSuccessReject

Speech is not the world. Code checks the goal.

Finish is a request

What to write in the OS

Be concrete:

  • Call finish only after you have quoted status from get_job
  • Call handoff if job_id is missing after one ask
  • Call handoff if the user wants a refund (not a tool you have)
  • Never call finish with “all good” when the observation was an error
  • If you already asked once, do not ask again

Clarify once, then stop. Infinite “what is the job id?” is not politeness. It is a leaked budget.

Handoff is a success of the system (a human got the bag). It is not a model failure if the world was impossible.

Budget stops are stop rules too

Step 4 of 4 should stop even if the model wants another tool. Token caps should stop even if the thought is “almost done.” Put the numbers in the prompt (“you have at most 4 steps”) and in the loop. Models ignore numbers under load. Loops do not.

Live PythonOpen full playgroundpython
Output
Run to execute this in your browser. Nothing is sent to a server.

What printed: first finish rejects (world unknown). Second finish succeeds (failed + error present). Step 4 budget-stops even if the model wants another tool. Handoff returns a reason. The first finish is the lie. The loop did not take it.

goal_satisfied is a unit test from the start track. Wire it here. Prompt text that says “stop when done” without a predicate is a vibe.

Walkthrough: finish while status is unknown

The model emits finish with “all good” after zero get_job calls. If the loop trusts speech, you shipped a lie. If the loop checks goal_satisfied, finish is rejected. Step 4 of 4 budget-stops even if the model wants another tool. Handoff after one missing job_id ask is a system success: a human got the bag. Infinite clarifying questions are a leaked budget.

Write the same English in the OS so the model asks for the stop you will honor. Caps still live in code. Models ignore numbers under load.

What goes wrong if you skip this

Loops narrate forever. Finish means nothing. Token bills become the stop rule by accident. Users are asked the same question ten times. Handoff looks like failure, so the model would rather invent success.

Speech is not the world. finish is a request. goal_satisfied is a check on state you can freeze in a test. Max steps and spend caps live in the loop even if the prompt also names the number. Models ignore numbers under load. Clarify once, then handoff. Infinite “what is the job id?” is a leaked budget.

Write the same English in the OS: when to finish, when to handoff, when not to invent success. Handoff is a system success when the world was impossible. A human got the bag. That is not a model failure.

If finish arrives and the required tool never ran, reject it. Continue, handoff, or budget-stop. Do not trust “all good.”

Common mistakes

MistakeLooks likeRepair
Trust finish“all good”World predicate
Numbers only in the poem“at most 4 steps”Loop cap
Clarify foreverPoliteOne ask, then handoff
Handoff as shameModel avoids itSystem success
No English in OSCode-only stopsModel never asks to stop

Put the same three stops in the OS, the parser, and the world predicate: finish only when the goal is true, handoff when it cannot be true, budget when the loop is out of steps. If only code stops, the model will narrate to the cap. If only the poem stops, the model will emit finish as a lie. Three places is a system. One place is a suggestion.

How agents use this

Reject finish until the world predicate passes (or handoff). Caps on the same loop. Clarify once. Handoff is a system success when the world was impossible. Put the same English in the OS so the model asks for the stop you will actually honor. If get_job never ran, finish is a lie even when the sentence is calm. Budget-stop is also a stop rule: step N of N ends the loop whether the poem is “almost done” or not. Numbers in the prompt are hints. Numbers in the loop are law.

Tip:Handoff is a success of the system (a human got the bag). It is not a model failure if the world was impossible.

Check your understanding

The model emits finish but get_job never ran and status is unknown. What should the loop do?