Skip to content

Commit

Permalink
Add deprecation warning for the prompt decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
rlouf committed Feb 24, 2025
1 parent 6042da7 commit eac26dc
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 156 deletions.
47 changes: 13 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,40 +379,12 @@ print(result)
## Prompting

Building prompts can get messy. **Outlines** makes it easier to write and manage
prompts by encapsulating templates inside "template functions".
prompts by encapsulating templates inside "template functions". Template
functions use the Jinja2 templating engine to help build complex prompts in a
concise manner.

These functions make it possible to neatly separate the prompt logic from the
general program logic; they can be imported from other modules and libraries.

Template functions require no superfluous abstraction, they use the Jinja2
templating engine to help build complex prompts in a concise manner:

``` python
import outlines

examples = [
("The food was disgusting", "Negative"),
("We had a fantastic night", "Positive"),
("Recommended", "Positive"),
("The waiter was rude", "Negative")
]

@outlines.prompt
def labelling(to_label, examples):
"""You are a sentiment-labelling assistant.
{% for example in examples %}
{{ example[0] }} // {{ example[1] }}
{% endfor %}
{{ to_label }} //
"""

model = outlines.models.transformers("microsoft/Phi-3-mini-4k-instruct")
prompt = labelling("Just awesome", examples)
answer = outlines.generate.text(model)(prompt, max_tokens=100)
```

You can also load a template from a text file. Assume you have the following prompt template defined in `prompt.txt`:
Template functions are created by loading a Jinja2 template from a text file.
Assume you have the following prompt template defined in `prompt.txt`:

``` text
You are a sentiment-labelling assistant.
Expand All @@ -423,7 +395,7 @@ You are a sentiment-labelling assistant.
{{ to_label }} //
```

You can load it with:
You can then load it and call it with:

``` python
import outlines
Expand All @@ -433,6 +405,13 @@ prompt = labelling("Just awesome", examples)

```

This helps:

- Keep content separate from the code
- Design "white space perfect" prompts

It is more maintainable and means prompts can be versioned separately from the code.

## Join us

- 💡 **Have an idea?** Come chat with us on [Discord][discord]
Expand Down
11 changes: 11 additions & 0 deletions outlines/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Callable, Dict, Optional, Type, cast
import warnings

import jinja2
import pydantic
Expand Down Expand Up @@ -165,6 +166,16 @@ def prompt(
A `Template` callable class which will render the template when called.
"""
warnings.warn(
"The @prompt decorator is deprecated and will be removed in outlines 1.1.0. "
"Instead of using docstring templates, please use Template.from_file() to "
"load your prompts from separate template files, or a simple Python function "
"that returns text. This helps keep prompt content separate from code and is "
"more maintainable.",
DeprecationWarning,
stacklevel=2,
)

if fn is None:
return lambda fn: prompt(fn, cast(Dict[str, Callable], filters))

Expand Down
21 changes: 12 additions & 9 deletions tests/test_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@


def test_function_basic():
@outlines.prompt
def test_template(text: str):
"""{{ text }}"""
with pytest.deprecated_call(match="The @prompt decorator"):
@outlines.prompt
def test_template(text: str):
"""{{ text }}"""

class Foo(BaseModel):
id: int
Expand Down Expand Up @@ -102,10 +103,11 @@ class User(BaseModel):
)
"""

fn = extract_function_from_file(content, "function")
assert (
str(type(fn)) == "<class 'outlines.function.Function'>"
) # because imported via `exec`
with pytest.deprecated_call(match="The @prompt decorator"):
fn = extract_function_from_file(content, "function")
assert (
str(type(fn)) == "<class 'outlines.function.Function'>"
) # because imported via `exec`


def test_extract_function_from_file_no_function():
Expand All @@ -129,5 +131,6 @@ class User(BaseModel):
)
"""

with pytest.raises(AttributeError, match="Could not find"):
extract_function_from_file(content, "function")
with pytest.deprecated_call(match="The @prompt decorator"):
with pytest.raises(AttributeError, match="Could not find"):
extract_function_from_file(content, "function")
Loading

0 comments on commit eac26dc

Please sign in to comment.