Lesson ยท 16 min
Answers as JSON
Text for people, data for programs
A person can read the answer I think this comment is a complaint. It has the word "full". For a program, this text is hard to use. The program needs the parts of the answer: the label and the reason.
JSON gives each part a name. Lesson 11 of the course Python for data explains JSON. json.loads changes JSON text into a dictionary.
import json
text = '{"label": "complaint", "reason": "A full dock."}'
data = json.loads(text)
data["label"] # "complaint"
Loose instructions
Answer in JSON. is not enough. With these instructions, the simulated model answers this:
Here is the JSON:
{"category": "complaint", "explanation": "It has the word \"waited\"."}
The answer has two problems.
- A sentence comes before the JSON.
json.loadscannot read the text. It raises ajson.JSONDecodeError, which is a kind ofValueError. - The model chose the names of the keys. The next answer can have other names.
A real model makes the same two mistakes.
Strict instructions
Tell the model three things.
- The answer is JSON, and only JSON.
- The names of the keys.
- The values that you allow, such as the labels.
Classify the comment as one of: praise, complaint, question,
other. Answer with only JSON. Use the keys "label" and "reason".
In the code, these instructions are one text on one line. The text has quotation marks inside. So put single quotation marks around it in Python.
A model can still add text
Clear instructions make extra text rare. They do not make it impossible. Now and then, a model adds a sentence, or it puts the JSON in a code block:
```json
{"label": "complaint", "reason": "It has the word \"full\"."}
```
A program can find the JSON in such an answer. It takes the part from the first { to the last }.
text = 'Here is the JSON:\n{"label": "praise"}'
start = text.find("{") # 18
end = text.rfind("}") # 36
text[start:end + 1] # '{"label": "praise"}'
find and rfind give -1 when the text does not have the character. This method works for one JSON object in the answer. That is the usual case.
A setting that makes the service return JSON
Many real services have a setting for JSON answers. You give the service a description of the keys and of the type of each value. The service then makes sure that the answer is JSON in this form. Use this setting when your service has it.
The setting controls the form of the answer. It does not make the content correct. The label can still be wrong. Lesson 8 checks the content.
Your turn
main.py has a comment and the loose instructions. Do the tasks in order.
Tasks
5 to do
Task 1, not checked yet. Call the model with the system message
LOOSEand the user messagecomment. Store the text of the answer inraw. Print it.Task 2, not checked yet. Write a function
parses(text). It returnsTruewhenjson.loads(text)works, andFalsewhenjson.loadsraises aValueError. Then make a variableparsed_okwith the result forraw.Task 3, not checked yet. Make a variable
STRICTwith these instructions:Classify the comment as one of: praise, complaint, question, other. Answer with only JSON. Use the keys "label" and "reason".Call the model with the system messageSTRICTand the user messagecomment. Parse the answer withjson.loads, and store the dictionary indata.Task 4, not checked yet. Write a function
extract_json(text). It takes the part of the text from the first{to the last}, and it parses that part withjson.loads. It returns the result. It returnsNonewhen the text has no such part, or when the part is not valid JSON.Task 5, not checked yet. Write a function
classify(comment). It calls the model with the system messageSTRICTand the comment as the user message. It returns the result ofextract_jsonfor the text of the answer.
Task 1 of 5
Call the model with the system message LOOSE and the user message comment. Store the text of the answer in raw. Print it.