ZBasePromptTemplate#
The ZBasePromptTemplate extends BasePromptTemplate in multiple ways:
Partial variables now support arbitrary types (used by ChoicePromptTemplate to accept arrays as partials)
Partial variables now support using defaults from other keys
Only
_prompt_typeandformat_promptneed to be overridden during subclassing, asformatis rather redundant now.ZChatPromptTemplatesupports partials, unlikeChatPromptTemplate(as of langchain v0.0.125)
There also exists ZStringPromptTemplate, ZPromptTemplate, and ZChatPromptTemplate, which should be plug-and-play replacements for their regular Langchain counterparts.
Usage#
It can be used directly:
[1]:
from langchain_contrib.prompts import ZPromptTemplate
template = ZPromptTemplate.from_template("a={a} b={b} c={c}").partial(a="one")
template.format(b=2, c=[3])
[1]:
'a=one b=2 c=[3]'
Or wrapped around an existing BasePromptTemplate:
[2]:
from langchain_contrib.prompts import ZBasePromptTemplate
from langchain.prompts.prompt import PromptTemplate
base = PromptTemplate.from_template("a={a} b={b} c={c}").partial(a="one")
z_base = ZBasePromptTemplate.from_base_template(base).permissive_partial(b=2)
z_base.format(c=[3])
[2]:
'a=one b=2 c=[3]'
Or it can be subclassed. Note that you no longer need to also override format here.
[3]:
from typing import List, Any
from langchain.prompts.base import StringPromptValue
from langchain.schema import PromptValue
class DemoPromptTemplate(ZBasePromptTemplate):
"""Demonstration of subclassing a ZBasePromptTemplate."""
input_variables: List[str] = ["a", "b", "c"]
@property
def _prompt_type(self) -> str:
return "demo"
def _format_prompt(self, **kwargs: Any) -> PromptValue:
"""Return a demonstration of a partial prompt."""
return StringPromptValue(text="a={a} b={b} c={c}".format(**kwargs))
z_base = DemoPromptTemplate().permissive_partial(a="one", b=2)
z_base.format(c=[3])
[3]:
'a=one b=2 c=[3]'
Partials support#
Arbitrary types can be passed into the permissive_partial function. (After all, the BasePromptTemplate.format_prompt function supports arbitrary types, so why shouldn’t partials?)
[4]:
class MyCustomClass:
def __str__(self):
return "a car"
template = ZPromptTemplate.from_template(
"This is {thing}"
).permissive_partial(thing=MyCustomClass())
template.format()
[4]:
'This is a car'
The permissive partials also call any functions you pass in, just as the regular kinds do. To reproduce an example from the Langchain docs:
[5]:
from datetime import datetime
from langchain_contrib.prompts import ZPromptTemplate
def _get_datetime():
now = datetime.now()
return now.strftime("%m/%d/%Y, %H:%M:%S")
prompt = ZPromptTemplate.from_template(
"Tell me a {adjective} joke about the day {date}"
)
partial_prompt = prompt.permissive_partial(date=_get_datetime)
print(partial_prompt.format(adjective="funny"))
Tell me a funny joke about the day 03/31/2023, 14:16:24
Defaulting to other keys#
Partials can also refer to other keys, which can be useful when chaining together formerly unrelated prompts:
[6]:
from langchain_contrib.prompts import ChainedPromptTemplate, DefaultsTo
product = ZPromptTemplate.from_template("I went to buy a {product}.")
fruit = ZPromptTemplate.from_template("I ate the {fruit}.")
chained = ChainedPromptTemplate(subprompts=[product, fruit], joiner=" ")
partial = chained.permissive_partial(product=DefaultsTo("fruit"))
partial.format(fruit="apple")
[6]:
'I went to buy a apple. I ate the apple.'
You can of course still override the partial at prompt formatting time:
[7]:
partial.format(product="banana", fruit="apple")
[7]:
'I went to buy a banana. I ate the apple.'
Chat Prompt Template partials#
ZChatPromptTemplate in also supports partials now, unlike the regular ChatPromptTemplate:
[8]:
from langchain_contrib.prompts import ZChatPromptTemplate
from langchain.prompts.chat import SystemMessagePromptTemplate
template = ZChatPromptTemplate.from_messages(
[SystemMessagePromptTemplate.from_template("a={a} b={b} c={c}")]
)
partial = template.partial(a="one").permissive_partial(b=2)
partial.format_prompt(c=[3])
[8]:
ChatPromptValue(messages=[SystemMessage(content='a=one b=2 c=[3]', additional_kwargs={})])