Use an LLM Completion Generation Framework
Take a look at Completion Generation Frameworks such as Guidance (created by Microsoft).
@guidance
def character_maker(lm, id, description, valid_weapons):
lm += f"""\
The following is a character profile for an RPG game in JSON format.
```json
{{
"id": "{id}",
"description": "{description}",
"name": "{gen('name', stop='"')}",
"age": {gen('age', regex='[0-9]+', stop=',')},
"armor": "{select(options=['leather', 'chainmail', 'plate'], name='armor')}",
"weapon": "{select(options=valid_weapons, name='weapon')}",
"class": "{gen('class', stop='"')}",
"mantra": "{gen('mantra', stop='"')}",
"strength": {gen('strength', regex='[0-9]+', stop=',')},
"items": ["{gen('item', list_append=True, stop='"')}", "{gen('item', list_append=True, stop='"')}", "{gen('item', list_append=True, stop='"')}"]
}}```"""
return lm
a = time.time()
lm = llama2 + character_maker(1, 'A nimble fighter', ['axe', 'sword', 'bow'])
time.time() - a
A side bonus is that the framework will not ask LLM to generate the tokens related to JSON structure itself, this guarantees a valid JSON output every time. Note that generated tokens are marked in green.
![enter image description here](https://cdn.statically.io/img/i.sstatic.net/cOZrE.png)
Frameworks available
I'll give a list of what I consider to be the top three LLM Completion Generation Frameworks as of today. Note that they have different strengths and tradeoffs.
All of these should support both fixed and open-ended ontologies.
There are some frameworks as well, but they may or may not be suited to this use case and have variable levels of community support: