Skip to content

Chat Prompting

@chatprompt

The @chatprompt decorator works just like @prompt but allows you to pass chat messages as a template rather than a single text prompt. This can be used to provide a system message or for few-shot prompting where you provide example responses to guide the model's output. Format fields denoted by curly braces {example} will be filled in all messages (except FunctionResultMessage).

from magentic import chatprompt, AssistantMessage, SystemMessage, UserMessage
from pydantic import BaseModel


class Quote(BaseModel):
    quote: str
    character: str


@chatprompt(
    SystemMessage("You are a movie buff."),
    UserMessage("What is your favorite quote from Harry Potter?"),
    AssistantMessage(
        Quote(
            quote="It does not do to dwell on dreams and forget to live.",
            character="Albus Dumbledore",
        )
    ),
    UserMessage("What is your favorite quote from {movie}?"),
)
def get_movie_quote(movie: str) -> Quote: ...


get_movie_quote("Iron Man")
# Quote(quote='I am Iron Man.', character='Tony Stark')

escape_braces

To prevent curly braces from being interpreted as format fields, use the escape_braces function to escape them in strings.

from magentic.chatprompt import escape_braces

string_with_braces = "Curly braces like {example} will be filled in!"
escaped_string = escape_braces(string_with_braces)
# 'Curly braces {{example}} will be filled in!'
escaped_string.format(example="test")
# 'Curly braces {example} will be filled in!'

Placeholder

The Placeholder class enables templating of AssistantMessage content within the @chatprompt decorator. This allows dynamic changing of the messages used to prompt the model based on the arguments provided when the function is called.

from magentic import chatprompt, AssistantMessage, Placeholder, UserMessage
from pydantic import BaseModel


class Quote(BaseModel):
    quote: str
    character: str


@chatprompt(
    UserMessage("Tell me a quote from {movie}"),
    AssistantMessage(Placeholder(Quote, "quote")),
    UserMessage("What is a similar quote from the same movie?"),
)
def get_similar_quote(movie: str, quote: Quote) -> Quote: ...


get_similar_quote(
    movie="Star Wars",
    quote=Quote(quote="I am your father", character="Darth Vader"),
)
# Quote(quote='The Force will be with you, always.', character='Obi-Wan Kenobi')

Placeholder can also be utilized in the format method of custom Message subclasses to provide an explicit way of inserting values from the function arguments. For example, see UserImageMessage in (TODO: link to GPT-vision page).

FunctionCall

The content of an AssistantMessage can be a FunctionCall. This can be used to demonstrate to the LLM when/how it should call a function.

from magentic import (
    chatprompt,
    AssistantMessage,
    FunctionCall,
    UserMessage,
    SystemMessage,
)


def change_music_volume(increment: int) -> int:
    """Change music volume level. Min 1, max 10."""
    print(f"Music volume change: {increment}")


def order_food(food: str, amount: int):
    """Order food."""
    print(f"Ordered {amount} {food}")


@chatprompt(
    SystemMessage(
        "You are hosting a party and must keep the guests happy."
        "Call functions as needed. Do not respond directly."
    ),
    UserMessage("It's pretty loud in here!"),
    AssistantMessage(FunctionCall(change_music_volume, -2)),
    UserMessage("{request}"),
    functions=[change_music_volume, order_food],
)
def adjust_for_guest(request: str) -> FunctionCall[None]: ...


func = adjust_for_guest("Do you have any more food?")
func()
# Ordered 3 pizza

FunctionResultMessage

To include the result of calling the function in the messages use a FunctionResultMessage. This takes a FunctionCall instance as its second argument. The same FunctionCall instance must be passed to an AssistantMessage and the corresponding FunctionResultMessage so that the result can be correctly linked back to the function call that created it.

from magentic import (
    chatprompt,
    AssistantMessage,
    FunctionCall,
    FunctionResultMessage,
    UserMessage,
)


def plus(a: int, b: int) -> int:
    return a + b


plus_1_2 = FunctionCall(plus, 1, 2)


@chatprompt(
    UserMessage("Use the plus function to add 1 and 2."),
    AssistantMessage(plus_1_2),
    FunctionResultMessage(3, plus_1_2),
    UserMessage("Now add 4 to the result."),
    functions=[plus],
)
def do_math() -> FunctionCall[int]: ...


do_math()
# FunctionCall(<function plus at 0x10a0829e0>, 3, 4)