Formatting¶
The format
Method¶
Functions created using magentic decorators expose a format
method that accepts the same parameters as the function itself but returns the completed prompt that will be sent to the model. For @prompt
this method returns a string, and for @chatprompt
it returns a list of Message
objects. The format
method can be used to test that the final prompt created by a magentic function is formatted as expected.
from magentic import prompt
@prompt("Write a short poem about {topic}.")
def create_poem(topic: str) -> str: ...
create_poem.format("fruit")
# 'Write a short poem about fruit.'
Classes for Formatting¶
By default, when a list is used in a prompt template string it is formatted using its Python representation.
from magentic import prompt
from magentic.formatting import BulletedList
@prompt("Continue the list:\n{items}")
def get_next_items(items: list[str]) -> list[str]: ...
items = ["apple", "banana", "cherry"]
print(get_next_items.format(items=items))
# Continue the list:
# ['apple', 'banana', 'cherry']
However, the LLM might respond better to a prompt in which the list is formatted more clearly or the items are numbered. The BulletedList
, NumberedList
, BulletedDict
and NumberedDict
classes are provided to enable this.
For example, to modify the above prompt to contain a numbered list of the items, the NumberedList
class can be used. This behaves exactly like a regular Python list
except for how it appears when inserted into a formatted string. This class can also be used as the type annotation for items
parameter to ensure that this prompt always contains a numbered list.
from magentic import prompt
from magentic.formatting import NumberedList
@prompt("Continue the list:\n{items}")
def get_next_items(items: NumberedList[str]) -> list[str]: ...
items = NumberedList(["apple", "banana", "cherry"])
print(get_next_items.format(items=items))
# Continue the list:
# 1. apple
# 2. banana
# 3. cherry
Custom Formatting¶
When objects are inserted into formatted strings in Python, the __format__
method is called. By defining or modifying this method you can control how an object is converted to a string in the prompt. If you own the class you can modify the __format__
method directly. Otherwise for third-party classes you will need to create a subcless.
Here's an example of how to represent a dictionary as a bulleted list.
from typing import TypeVar
from magentic import prompt
K = TypeVar("K")
V = TypeVar("V")
class BulletedDict(dict[K, V]):
def __format__(self, format_spec: str) -> str:
# Here, you could use 'format_spec' to customize the formatting further if needed
return "\n".join(f"- {key}: {value}" for key, value in self.items())
@prompt("Identify the odd one out:\n{items}")
def find_odd_one_out(items: BulletedDict[str, str]) -> str: ...
items = BulletedDict({"sky": "blue", "grass": "green", "sun": "purple"})
print(find_odd_one_out.format(items))
# Identify the odd one out:
# - sky: blue
# - grass: green
# - sun: purple