Stand-in model
A stand-in model is a plain Python function that answers the way a language model does, so a program can be built and tested with no API key.
Last updated: 30 Sep, 2026 · Python 3.14
A real model needs an API key and charges for every call. For learning, a function that answers in the same shape is free, instant and easy to read. It uses Functions and JSON.
Writing ask_model
A model asked to sort a ticket as JSON sends back a string. Usually it is the JSON you asked for. Sometimes it is a polite sentence instead. The stand-in does both:
def ask_model(ticket_text):
text = ticket_text.lower()
if "charged" in text or "refund" in text:
return '{"category": "billing", "priority": 4}'
if "parcel" in text or "arrived" in text:
return '{"category": "shipping", "priority": 3}'
return "I am not sure how to sort this one."
print(ask_model("I was charged twice for one order"))
print(ask_model("How do I change my password?")){"category": "billing", "priority": 4}
I am not sure how to sort this one.It returns strings, not dictionaries, because that is what arrives from a real model: text, which your program then has to read. It decides from the words in the ticket, so a different ticket gets a different answer.
View the code here
[
{
"id": 1,
"customer": "Asha",
"text": "I was charged twice for one order"
},
{
"id": 2,
"customer": "Ben",
"text": "My parcel has not arrived"
},
{
"id": 3,
"customer": "Chen",
"text": "Can I get a refund for the blue mug?"
},
{
"id": 4,
"customer": "Dara",
"text": "How do I change my password?"
},
{
"id": 5,
"customer": "Eli",
"text": "The parcel arrived but the box was crushed"
}
]
Asking about every ticket
This reads tickets.json from JSON; keep that file in the same folder as your code.
import json
with open("tickets.json") as f:
tickets = json.load(f)
for ticket in tickets:
answer = ask_model(ticket["text"])
print(ticket["id"], answer)1 {"category": "billing", "priority": 4}
2 {"category": "shipping", "priority": 3}
3 {"category": "billing", "priority": 4}
4 I am not sure how to sort this one.
5 {"category": "shipping", "priority": 3}Four answers are JSON and ticket 4's is not. Real models do this too, which is why a program that trusts every answer eventually breaks.
Parsing every answer, and where it breaks
for ticket in tickets:
data = json.loads(ask_model(ticket["text"]))
print(ticket["id"], data["category"])1 billing
2 shipping
3 billing
Traceback (most recent call last):
File "main.py", line 2, in <module>
data = json.loads(ask_model(ticket["text"]))
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)Tickets 1 to 3 print, then ticket 4's sentence reaches json.loads and the whole program stops. On your computer the error also lists lines from inside the json module; the last line is the one to read. Ticket 5 is never sorted. try and except keeps the program running.
Stand-in vs a real model
Stand-in ask_model | A real model | |
|---|---|---|
| Needs | Nothing | An API key and a network |
| Answer | The same every run | Can change between runs |
| Cost and speed | Free, instant | Paid per token, a second or more |
| Returns | A string | A string |
Where stand-ins show up in AI code
- Tests that must run the same way every time, with no key.
- Building the rest of a program before a model account exists.
- The stand-in models the agent framework courses write, which follow the same idea.
Related
- Previous: JSON
- Next: try and except
- Add a branch for
"password"that returns{"category": "other", "priority": 2}as JSON text, and run the loop that broke. - Make it return
'{"category": "billing", "priority": "high"}'for refunds. It parses; is it still right? Pydantic models comes back to this. - Print
type(ask_model("refund")).
Slow is fine. Stopping is the only problem.