A lightweight, no-nonsense library for managing your LLM prompts.
Project description
🤌 wtprompt: What the Prompt?
wtprompt is a lightweight, no-nonsense library designed to help you manage your LLM prompts efficiently.
Tired of cluttering your code with blocks of text? wtprompt lets you keep your code clean by loading prompts from text files. Say goodbye to length issues and linting headaches.
Why wtprompt?
- ✅ Lightweight, zero bloat: need to just work with prompts? Use this as an alternative to a full MLOps library.
- ✅ Jinja syntax: Leverage the powerful Jinja syntax, already used by haystack and other libraries.
- ✅ Markdown-friendly: OpenAI is popularizing Markdown as a prompt language; wtprompt is ready for that!
- ✅ Easy PromptManagement: Instantly load prompts from a directory (and its subdirectories) or a JSON file.
- ✅ Dynamic Prompts: Seamlessly insert text into your prompts at runtime.
- ✅ Built-in Preprocessing Access straightforward, ready-to-use preprocessing for your text.
Folder-Based Prompt Loading
Gather all your prompts into a folder, e.g. folder_path
, saving them as .txt
or .md
files. You can organize them
into subfolders, and they will be loaded according to the original folder structure.
Then, simply run the following code:
from wtprompt.core import FolderPrompts
my_prompts = FolderPrompts(prompt_folder='folder_path')
# The following commands will retrieve your prompt as a string variable:
prompt = my_prompts.prompt_name
# Note, nested calls like `my_prompts.subfolder.prompt_name` won't work!
prompt = my_prompts('prompt_name')
prompt = my_prompts('subfolder/prompt_name')
Where the prompt name is given by the file name, e.g., hello.txt
can be loaded as hello
.
Remark:
Folder-based loading is lazy: call the .load()
method to load the whole folder structure.
JSON-Based Prompt Loading
Another option is to store your prompts in a .json file:
{
'prompt name' : 'prompt content',
...
}
This can be used in a similar fashion:
from wtprompt.core import JsonPrompts
my_prompts = JsonPrompts(prompt_file='path_to_json.json')
my_prompts.prompt_name
my_prompts('prompt_name')
Remark:
- To speed up the loading times, the JSON is not validated: pass the flag
validate=True
or use the functionvalidate_json
to check your json file. - Currently lazy loading is not supported for JSON files.
Prompts in-Code
It is possible to initialize an empty PromptLoader
class:
my_prompts = PromptLoader()
And then add prompts as follows:
my_prompts.add_prompt(prompt_name, prompt_text)
where prompt_name and prompt_text are string variables.
Fill in Values
One of the primary reasons for embedding prompts directly within the code is to streamline the process of populating values.
This situation is typical, for example, of a Retrieval-Augmented Generation (RAG) system, where the prompt often follows a structure of this kind:
Basing your answer only on the following context
# Context
--- variable context ---
Answer the following question
# Question:
--- variable question ---
wtprompt allows to easily handle this use case. There are two main approaches:
fill_list
: a function which will substitute some values in order, quicker to use for simple substitutions: not necessarily compatible with jinja syntax!PromptGenerator
: a class which, through the methodfill_prompt
,- allows you to use the Jinja templates.
For example by writing the previous prompt as follows:
Basing your answer only on the following context
# Context
{{context}}
Answer the following question
# Question:
{{question}}
it is possible to make the proper substitutions in one of the following ways:
p_gen = PromptGenerator()
# Using a dictionary to make the substitutions
filled_in_prompt = p_gen.fill_prompt(wtprompt.prompt_name, {'question': '...question here...',
'context': '...context here...'})
# Using a list to make the substitutions
# In this case, the order of the variables and placeholders must match.
filled_in_prompt = fill_list(wtprompt.prompt_name, ['...context here...', '...question here...'])
Remarks:
- Jinja can be flexible and powerful, which is why it is used by many projects (for instance Haystack). See Jinja's documentation for more details.
- To minimize the likelihood of errors, it is recommended to use
fill_list
when there are only a few substitutions. - For
fill_list
, nested substitutions are not allowed.
Text Preprocessing
The text that is added, especially if automatically selected or typed by a user, is potentially messy.
For this reason, wtprompt offers a basic tool TextPreprocessor
, that does some basic preprocessing.
The preprocessor
method returns a bool
and a str
; if the bool
is False
the preprocessing stopped half-way because of some property not being satisfied, if it is
True
then the str
is the processed string.
The following variables control the default behavior of the class:
- do_strip (bool): If True removes leading and trailing whitespace.
- check_empty (bool): Verifies if the text is non-empty.
- check_letters (bool): If True compares the number of letters to the total number of characters.
- percentage_letters (float): If check_letters is True this is the minimum percentage of accepted letters.
- spaces_only (bool): If true, replaces all whitespace characters with spaces.
- max_consecutive_spaces (int): Limits consecutive spaces to a specified maximum.
- text_truncate (bool): If True text can be truncated to a specified maximum length.
- max_length (int): Max length of the processed text (to be used if text_truncate = True)
- ascii_only (bool): If True removes non-ASCII characters.
- text_normalize (str): Normalizes the text using a specified Unicode normalization form.
- has_min_length (bool): Verifies if the text meets a minimum length requirement.
- min_length (int): Min length of the processed text (to be used if has_min_length = True)
To continue the previous example, it is possible to perform a basic preprocessing in the following way:
preprocessor = TextPreprocessor()
def build_prompt(my_prompts, preprocessor, context, question):
is_okay, context = preprocessor.preprocess(context)
assert is_okay, "ERROR: Invalid context"
return my_prompts.fill_list("prompt_name", [context, question])
Note 💡 The preprocessing class performs basic steps by default. In a production environment, you may want to customize the pipeline or add specific steps to meet your requirements.
TL;DR
- Organize your prompts by storing them in a folder or within a JSON file.
- Use a dictionary or list to dynamically modify prompts at runtime.
- Apply the preprocessor to perform basic processing on the filler values before using the prompts.
License
This software is distributed under the MIT License (see LICENSE for details).
Contributions are welcome!
You are free to use, modify, and distribute it as you wish, though attribution is appreciated.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file wtprompt-0.1.1.tar.gz
.
File metadata
- Download URL: wtprompt-0.1.1.tar.gz
- Upload date:
- Size: 15.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.10.14
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | aef8f96dc6bf9764dcfc5a17b1885eb496314d1d64508ff67bddce9b40eb95b2 |
|
MD5 | 6bd26f79fdfe1de2a5a4f7a54bdd131e |
|
BLAKE2b-256 | 497935a9b62ce46d1544c49f2adfaa4c987fa0ca00403e6b4562bf5897ee9022 |
File details
Details for the file wtprompt-0.1.1-py3-none-any.whl
.
File metadata
- Download URL: wtprompt-0.1.1-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.10.14
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | aec808e94b4f8e177e1708ec2342348437398ba1e6809d4368cd2c2dd6ca9974 |
|
MD5 | 777d0f902425e5be29ace290d6629e95 |
|
BLAKE2b-256 | 2dc1bf0aadd013c35c8f48df6bbbc9e532cfea077d3fe7300dc492fe82b0a4e9 |