Skip to content

Commit 0e5a56c

Browse files
committed
Update the documentation
1 parent 677ff2e commit 0e5a56c

File tree

5 files changed

+337
-4
lines changed

5 files changed

+337
-4
lines changed

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
## Prompt functions
44

5-
The `prompt` decorator takes a function as an argument whose docstring is a Jinja template, and return a `Prompt` object:
5+
The `template` decorator takes a function as an argument whose docstring is a Jinja template, and return a `Template` object:
66

77
```python
8-
from prompts import prompt
8+
from prompts import template
99

10-
@prompt
10+
@template
1111
def few_shots(instructions, examples, question):
1212
"""{{ instructions }}
1313
@@ -21,7 +21,7 @@ def few_shots(instructions, examples, question):
2121
A: """
2222
```
2323

24-
Caling the `Prompt` object renders the Jinja template:
24+
Caling the `Template` object renders the Jinja template:
2525

2626
```python
2727
instructions = "Please answer the following question following the examples" examples = [

docs/reference/dispatch.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Model-based prompt dispatching

docs/reference/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Reference

docs/reference/template.md

+306
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
# Prompt templating
2+
3+
Prompts provides a powerful domain-specific language to write and manage
4+
prompts, via what we call *prompt functions*. Prompt functions are Python
5+
functions that contain a template for the prompt in their docstring, and their
6+
arguments correspond to the variables used in the prompt. When called, a prompt
7+
function returns the template rendered with the values of the arguments.
8+
9+
The aim of prompt functions is to solve several recurrent problems with prompting:
10+
11+
1. **Building complex prompts quickly leads to messy code.** This problem has
12+
already been solved in the web development community by using templating, so
13+
why not use it here?
14+
2. **Composing prompts is difficult.** Why not just compose functions?
15+
3. **Separating prompts from code.** Encapsulation in functions allows a clean
16+
separation between prompts and code. Moreover, like any function, prompt
17+
functions can be imported from other modules.
18+
19+
Prompts uses the [Jinja templating
20+
engine](https://jinja.palletsprojects.com/en/3.1.x/) to render prompts, which
21+
allows to easily compose complex prompts.
22+
23+
!!! warning "Prompt rendering"
24+
25+
Prompt functions are opinionated when it comes to prompt rendering. These opinions are meant to avoid common prompting errors, but can have unintended consequences if you are doing something unusual. We advise to always print the prompt before using it. You can also [read the
26+
reference](#formatting-conventions) section if you want to know more.
27+
28+
## Your first prompt
29+
30+
The following snippet showcases a very simple prompt. The variables between
31+
curly brackets `{{ }}` are placeholders for the values of the arguments you
32+
will pass to the prompt function.
33+
34+
=== "Code"
35+
36+
```python
37+
import prompts
38+
39+
@prompts.template
40+
def greetings(name, question):
41+
"""Hello, {{ name }}!
42+
{{ question }}
43+
"""
44+
45+
prompt = greetings("user", "How are you?")
46+
print(prompt)
47+
```
48+
49+
=== "Output"
50+
51+
```text
52+
Hello, user!
53+
How are you?
54+
```
55+
56+
If a variable is missing in the function's arguments, Jinja2 will throw an `UndefinedError` exception:
57+
58+
=== "Code"
59+
60+
```python
61+
import prompts
62+
63+
@prompts.template
64+
def greetings(name):
65+
"""Hello, {{ surname }}!"""
66+
67+
prompt = greetings("user")
68+
```
69+
70+
=== "Output"
71+
72+
```text
73+
Traceback (most recent call last):
74+
File "<stdin>", line 9, in <module>
75+
File "/home/remi/projects/normal/prompts/prompts.templates.py", line 38, in __call__
76+
return render(self.template, **bound_arguments.arguments)
77+
File "/home/remi/projects/normal/prompts/prompts.templates.py", line 213, in render
78+
return jinja_template.render(**values)
79+
File "/home/remi/micromamba/envs/prompts/lib/python3.9/site-packages/jinja2/environment.py", line 1301, in render
80+
self.environment.handle_exception()
81+
File "/home/remi/micromamba/envs/prompts/lib/python3.9/site-packages/jinja2/environment.py", line 936, in handle_exception
82+
raise rewrite_traceback_stack(source=source)
83+
File "<template>", line 1, in top-level template code
84+
jinja2.exceptions.UndefinedError: 'surname' is undefined
85+
```
86+
87+
## Importing prompt functions
88+
89+
Prompt functions are functions, and thus can be imported from other modules:
90+
91+
=== "prompts.py"
92+
```python
93+
import prompts
94+
95+
@prompts.template
96+
def greetings(name, question):
97+
"""Hello, {{ name }}!
98+
{{ question }}
99+
"""
100+
```
101+
102+
=== "generate.py"
103+
104+
```python
105+
from .prompts import greetings
106+
107+
prompt = greetings("John Doe", "How are you today?")
108+
```
109+
110+
=== "Output"
111+
112+
```text
113+
Hello, John Doe!
114+
How are you today?
115+
```
116+
117+
## Few-shot prompting
118+
119+
Few-shot prompting can lead to messy code. Prompt functions allow you to loop
120+
over lists or dictionaries from the template. In the following example we
121+
demonstrate how we can generate a prompt by passing a list of dictionaries with
122+
keys `question` and `answer` to the prompt function:
123+
124+
=== "Code"
125+
126+
```python
127+
import prompts
128+
129+
@prompts.template
130+
def few_shots(instructions, examples, question):
131+
"""{{ instructions }}
132+
133+
Examples
134+
--------
135+
136+
{% for example in examples %}
137+
Q: {{ example.question }}
138+
A: {{ example.answer }}
139+
140+
{% endfor %}
141+
Question
142+
--------
143+
144+
Q: {{ question }}
145+
A:
146+
"""
147+
148+
instructions = "Please answer the following question following the examples"
149+
examples = [
150+
{"question": "2+2=?", "answer":4},
151+
{"question": "3+3=?", "answer":6}
152+
]
153+
question = "4+4 = ?"
154+
155+
prompt = few_shots(instructions, examples, question)
156+
print(prompt)
157+
```
158+
159+
=== "Output"
160+
161+
```text
162+
Please answer the following question following the examples
163+
164+
Examples
165+
--------
166+
167+
Q: 2+2=?
168+
A: 4
169+
170+
Q: 3+3=?
171+
A: 6
172+
173+
Question
174+
--------
175+
176+
Q: 4+4 = ?
177+
A:
178+
```
179+
180+
## Conditionals, filters, etc.
181+
182+
Jinja2 has many features beyond looping that are not described here:
183+
conditionals, filtering, formatting, etc. Please refer to the [Jinja
184+
documentation](https://jinja.palletsprojects.com/en/3.1.x/>) for more
185+
information about the syntax of the templating language. The Jinja syntax is
186+
powerful, and we recommend you take some time to read their documentation if you
187+
are building complex prompts.
188+
189+
## Formatting conventions
190+
191+
Prompt functions are opinionated when it comes to rendering, and these opinions
192+
are meant to avoid prompting mistakes and help with formatting.
193+
194+
### Whitespaces
195+
196+
If you have experience working with strings between triple quotes you know that
197+
indenting has an influence on the string's formatting. Prompt functions adopt
198+
a few conventions so you don't have to think about indents when writing prompt.
199+
200+
First, whether you start the prompt right after the triple quotes or on the line
201+
below does not matter for formatting:
202+
203+
=== "Code"
204+
205+
```python
206+
import prompts
207+
208+
@prompts.template
209+
def prompt1():
210+
"""My prompt
211+
"""
212+
213+
@prompts.template
214+
def prompt2():
215+
"""
216+
My prompt
217+
"""
218+
219+
print(prompt1())
220+
print(prompt2())
221+
```
222+
223+
=== "Output"
224+
225+
```text
226+
My prompt
227+
My prompt
228+
```
229+
230+
Indentation is relative to the second line of the docstring, and leading spaces are removed:
231+
232+
=== "Code"
233+
234+
```python
235+
import prompts
236+
237+
@prompts.template
238+
def example1():
239+
"""First line
240+
Second line
241+
"""
242+
243+
@prompts.template
244+
def example2():
245+
"""
246+
Second line
247+
Third line
248+
"""
249+
250+
@prompts.template
251+
def example3():
252+
"""
253+
Second line
254+
Third line
255+
"""
256+
257+
print(example1())
258+
print(example2())
259+
print(example3())
260+
```
261+
262+
=== "Output"
263+
264+
```text
265+
First line
266+
Second line
267+
268+
Second line
269+
Third line
270+
271+
Second line
272+
Third line
273+
```
274+
275+
Trailing whitespaces are not removed, unless they follow a linebreak symbol `\` (see [linebreaks](#linebreaks)).
276+
277+
### Linebreaks
278+
279+
You can use the backslash `\` to break a long line of text. It will render as a single line:
280+
281+
=== "Code"
282+
283+
```python
284+
import prompts
285+
286+
@prompts.template
287+
def example():
288+
"""
289+
Break in \
290+
several lines \
291+
But respect the indentation
292+
on line breaks.
293+
And after everything \
294+
Goes back to normal
295+
"""
296+
297+
print(example())
298+
```
299+
300+
=== "Output"
301+
302+
```text
303+
Break in several lines But respect the indentation
304+
on line breaks.
305+
And after everything Goes back to normal
306+
```

mkdocs.yml

+25
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,27 @@ extra:
3838
link: https://twitter.com/OutlinesOSS
3939
generator: false
4040

41+
42+
markdown_extensions:
43+
- admonition
44+
- def_list
45+
- attr_list
46+
- md_in_html
47+
- pymdownx.highlight:
48+
anchor_linenums: true
49+
line_spans: __span
50+
pygments_lang_class: true
51+
noclasses: True
52+
pygments_style: gruvbox-light
53+
- pymdownx.superfences
54+
- pymdownx.tabbed:
55+
alternate_style: true
56+
- pymdownx.inlinehilite
57+
- pymdownx.details
58+
- pymdownx.emoji:
59+
emoji_index: !!python/name:material.extensions.emoji.twemoji
60+
emoji_generator: !!python/name:material.extensions.emoji.to_svg
61+
4162
plugins:
4263
- search
4364
- section-index
@@ -50,3 +71,7 @@ plugins:
5071

5172
nav:
5273
- Home: index.md
74+
- Docs:
75+
- reference/index.md
76+
- Prompt template: reference/template.md
77+
- Dispatch: reference/dispatch.md

0 commit comments

Comments
 (0)