Choice Prompt Template#

If you want to ask the LLM to pick from a series of choices, you can use ChoicePromptTemplate to help you do so.

[1]:
from langchain_contrib.prompts import ChoicePromptTemplate

template = ChoicePromptTemplate.from_template(
    "This {product} is available in {choices}. Which color should I pick?",
)
template.format(product="dress", choices=["red", "green", "blue"])
[1]:
'This dress is available in red, green, or blue. Which color should I pick?'

This works with Chat messages as well:

[2]:
from langchain.prompts.chat import (
    HumanMessagePromptTemplate,
    SystemMessagePromptTemplate,
)

chat_template = ChoicePromptTemplate.from_messages(
    messages=[
        SystemMessagePromptTemplate.from_template(
            "You are helping the user pick a {product}."
        ),
        HumanMessagePromptTemplate.from_template(
            "This {product} is available in {choices}. Which color should I pick?"
        ),
    ],
)
chat_template.format_prompt(product="dress", choices=["red", "green", "blue"]).to_messages()
[2]:
[SystemMessage(content='You are helping the user pick a dress.', additional_kwargs={}),
 HumanMessage(content='This dress is available in red, green, or blue. Which color should I pick?', additional_kwargs={})]

And supports partials (though you have to use permissive_partial from ZBasePromptTemplate for the array to be accepted as input by mypy).

[3]:
chat_template.permissive_partial(
    choices=["red", "green", "blue"],
).format_prompt(
    product="dress",
).to_messages()
[3]:
[SystemMessage(content='You are helping the user pick a dress.', additional_kwargs={}),
 HumanMessage(content='This dress is available in red, green, or blue. Which color should I pick?', additional_kwargs={})]

Serializing the choices#

You can pick a different way of serializing the list of choices if you’d like.

The default one is the Oxford comma formatter, with which you can also customize the conjunction used:

[4]:
from langchain_contrib.prompts.choice import get_oxford_comma_formatter

template = ChoicePromptTemplate.from_template(
    "This {product} is available in {choices}. Which color should I pick?",
    choices_formatter = get_oxford_comma_formatter(conjunction="and")
)
template.format(product="car", choices=["red", "green"])
[4]:
'This car is available in red and green. Which color should I pick?'

Or, you could simply go with a regular Python join as well:

[5]:
from langchain_contrib.prompts.choice import get_simple_joiner

template.choices_formatter = get_simple_joiner()
template.format(product="car", choices=["red", "green"])
[5]:
'This car is available in red, green. Which color should I pick?'

Or, you could even go with a list:

[6]:
from langchain_contrib.prompts.choice import list_of_choices

template = ChoicePromptTemplate.from_template(
    """Your available actions are

{choices}

Which will you pick?""",
    choices_formatter = list_of_choices,
)
print(template.format(choices=["Page a human", "Retry", "Proceed"]))
Your available actions are

1. Page a human
2. Retry
3. Proceed

Which will you pick?

You can also serialize the choices themselves if they’re not presented in string form to the formatter:

[7]:
from langchain.tools.python.tool import PythonREPLTool
from langchain_contrib.tools import TerminalTool

template = ChoicePromptTemplate.from_template(
    "Your task is to {task}. You have access to {choices}. Begin.",
    choices_formatter=get_oxford_comma_formatter("and"),
    choice_serializer=lambda tool: tool.name,
)
template.format(task="take over the world", choices=[PythonREPLTool(), TerminalTool()])
[7]:
'Your task is to take over the world. You have access to Python REPL and Terminal. Begin.'

Customizing the choice variable#

If you want to use a different key than choice in your template, you can also specify that as well. For example, to use tool_names instead of choice in the template:

[8]:
template = ChoicePromptTemplate.from_template(
    "Your task is to {task}. You have access to {tools}. Begin.",
    choices_formatter=get_oxford_comma_formatter("and"),
    choice_serializer=lambda tool: tool.name,
    choice_format_key="tools",
)
template.format(task="take over the world", tools=[PythonREPLTool(), TerminalTool()])
[8]:
'Your task is to take over the world. You have access to Python REPL and Terminal. Begin.'

Chain and LLM interop#

The ChoicePromptTemplate is designed to be compatible with the ChoiceChain, which actually executes a subsequent chain based on the decision made.

It also generates a Choice PromptValue that retains information about which choices were used to generate the prompt. This is used, for example, by the Human “LLM” to show a terminal menu to the user when presented with such a prompt.