Prompts and guidance

Prompts and guidance#

Langworks employs templatable prompts and guidance when interfacing with LLMs. These templates are implemented using the Jinja template language, extended specifically for the challenges presented by prompting. Langworks differentiates between ‘static’ and ‘dynamic’ templates, respectively used by prompts and guidance.

Static templates#

Prompts rely on static templates. These templates largely work the same as Jinja templates. A notable difference is that Langworks’ templates are nestable. Consider the following example:

q = Query(

    query = (
        """
        The following {{language}} document, delimited by triple backticks, contains \\
        information about {{topic}}. Your task is to {{task}}. Base your work on the document \\
        provided.

        ```\n
        {{doc}}
        ```
        """
    )

)

for task in [
    "explain what {{topic}} are",
    "explain how {{topic}} relate to humans",
    "give a taxonomy of {{topic}}"
]:

    q.exec(context = dict(
        language = "English",
        topic    = "dogs",
        task     = task,
        doc      = "..." # Contents of Wikipedia page about dogs.
    ))

Regular Jinja templates would fail to expand the tags embedded in the task variable. This would require the use of custom filters. Instead, Langworks renders recursively, allowing to use templates as variables. This allows these templates to be nested in Langworks, making it possible to take a modular approach to prompt design.

Dynamic templates#

Guidance is specified using dynamic templates. These templates enjoy the same features as static templates, being based on Jinja templates, and allowing for nesting of templates. However, dynamic templates have some additional features to put constraints on LLM generation.

Constraints#

By default Langworks applies no constraints on guidance. LLMs are simply requested to generate a response to the query prompted. However, when guidance is specified, constraints need to be specified too. Consider the following example:

query = Query(

    query = (
        "Your task is to solve the following equation: 1 + 1 ="
    ),

    guidance = (
        "1 + 1 ="
    )
)

Langworks cannot deduce the desired output. Perhaps a digit would suffice, but perhaps a further explanation is also desired. To help guide the generation of the desired output, constraints are required:

guidance = (
    "1 + 1 = {% regex = '\d' %}"
)

In this example, only a single digit is accepted, after which generation is stopped. If this was not desidered, guidance may have been specified as follows:

guidance = (
    "1 + 1 = {% regex = '\d' %}. This can be explained as follows: {% gen %}"
)

Accordingly, constraints serve as a powerful tool in guiding LLM generation. Langworks provides a number of constraints by default.

See Constraints for an overview of all constraints Langworks ships with.