Introducing Prompt Coding Helpers¶
To better utilize the power of LMs, a lot of effort has been put into designing prompts, and the complexity of prompts has been increasing as observed in recent researches like ToolEmu, Swe-agent, etc.
APPL provides two types of prompt coding helpers, Compositor
and Definition
, to facilitate coding prompts in a structured and maintainable way. These helpers were originally designed in PromptCoder and have been used to develop prompts in the ToolEmu project with more than 20k tokens in total. By leveraging Python's idiomatic features, we have enhanced the usability and flexibility of these helpers.
Prompt Compositors¶
It is common to write prompts in Markdown or XML format to interact with LMs, where the prompts are structured with different elements like headers, lists, tags, etc.
To facilitate the creation of structured prompts in a programmatic way, we provide a set of compositors that compose the text within their context into a structured prompt with the corresponding format. For example, the NumberedList
is a context manager composes a list of text within its scope into a numbered list:
with NumberedList():
f"First item"
f"Second item"
>>> composed into >>>
1. First item
2. Second item
You can also nest the compositors to create more complex structures, like:
- The default indentation inside the tag is 4 spaces, can be changed by setting the
indent_inside
parameter. - Explicitly set the indentation for the content inside the list.
- Fits different number of items.
The composed prompt is:
Check the list of available compositors in the API Reference.
Prompt Definitions¶
To make the prompt more structured and clear, it is often helpful to define concepts in prompts and refer to them in different parts of the prompt.
APPL provides the Definition
class for defining concepts by subclassing it. For example:
class InputReq(Definition):
name = "Input Requirement"
fstr = "[{}]" # defines the format when referring to the concept
To include the concept in the prompt, you can instantiate the class with the description as an argument, for example:
Referring to the concept
You can use the class name in the prompt (without instantiation), which will be replaced by a certain format containg the concept's name. For example,
In some cases you may need the raw name of the concept without formatting, you can use the!r
flag:
With the help of modern IDEs like VSCode, you can easily navigate to the definition and references of the concept. The IDEs can also provide highlights to class names, which makes it easier to distinguish between concepts defined in the prompt and other variables in the code. These features are especially useful when the prompt is large and complex.
Example¶
We use the example in PromptCoder to illustrate the usage of these prompt coding helpers:
- Declare the input and output requirements classes for reference.
Alternatively, but not recommended, you can define classes as follows:
InputReq = define("Input Requirement")
andOutputReq = define("Output Requirement")
. But then VSCode cannot recognize it as a class. - Complete the input requirement with a description.
- Complete the output requirement with a description.
- The naming can be used to distinguish:
- variable naming (e.g. language): the dynamic input.
- class naming (e.g. InputReq): the reference to the concept.
- The returned prompt will be formatted using the compositor.
- Create an empty line regardless of other compositors.
The result of get_prompt("sum", "Python")
will be:
## Requirements
1. Input Requirement: The input should be two numbers.
2. Output Requirement: The output should be the sum of the two numbers.
## Instruction
Write a function in Python that satisfies the [Input Requirement] and [Output Requirement].
Overall, these helpers provide a more structured and maintainable way to write dynamic prompts.