Promuet
A simple yet powerful prompt templating engine
Promuet is a simple Python library for designing complex chains of prompts using basic prompt templates:
from promuet import PromptFlow, Prompt, UserMessage, AssistantMessage, AppFlow
HAIKU_GENERATION_FLOW = PromptFlow(
Prompt(
description="Brainstorm haiku themes",
messages=[
UserMessage(
"""
I want to write a haiku. Let's brainstorm themes inspired by {{season}}.
List a few poetic and evocative themes that capture the mood and essence of the season.
"""
)
],
response_format="{{haiku_themes}}"
),
Prompt(
description="Generate haiku",
is_continuation=True,
messages=[
AssistantMessage("{{haiku_themes}}"),
UserMessage(
"""
Based on the following themes inspired by {{season}}:
{{haiku_themes}}
Please write a simple, elegant haiku for each theme.
"""
)
],
response_format="{{haikus}}"
)
)
app_flow = AppFlow()
app_flow.run_prompt(HAIKU_GENERATION_FLOW, dict(season="autumn"))
print(app_flow['haikus'])
It supports a variety of parsing methods designed to make parsing LLMs natural and intuitive. See below for more details.
Detailed Usage
Parsing
At the core, Promuet is just a simple parsing engine:
from promuet import TemplateMatchItem
template = TemplateMatchItem(
"""
Name: {{name}}
Age: {{age:int}}
"""
)
input_string = """
Name: John Doe
Age: 30
"""
data = template.parse(input_string)
assert data['name'] == 'John Doe'
assert data['age'] == 30
A variable like {{foo}} can currently be one of the following types (default is str):
str: A multi-line wildcard (essentially.*?)int: A numberlist: A bulleted or numbered list of items
In addition to basic variables, Promuet also supports parsing lists of repeated items with a template like this:
[[:myitems:]]
Item name: {{name}}
Item attribute: {{attribute}}
[[:myitems:]]
Which will produce a parsed result like:
{"myitems": [{"name": "Item 1", "attribute": "Attribute 1"}, ...]}
Prompts
A prompt is just a convenient wrapper around a series of chat message templates:
from promuet import Prompt, SystemMessage, UserMessage
GENERATE_USERS_PROMPT = Prompt(
description="Generate sample users",
messages=[
SystemMessage(
"""
You are a synthetic data generator generating sample people. Format your response like so:
```
=== Person 1 ===
Name: John Doe
Age: 23
=== Person 2 ===
...
```
"""
),
UserMessage(
"""Generate me {{count}} sample people from the country of {{country}} around the age of {{age_range}}."""
),
],
response_format="""
[[:people:]]
=== Person {{index:int}} ===
Name: {{name}}
Age: {{age:int}}
[[:people:]]
"""
)
You can execute a prompt as follows:
from promuet import AppFlow, OpenAiChatClient
# Set OPENAI_API_KEY environment variable
app_flow = AppFlow()
app_flow.run_prompt(GENERATE_USERS_PROMPT, dict(country='Nigeria', count=5, age_range='50-60'))
for person in app_flow['people']:
print(f"Generated person: {person['name']} (age {person['age']})")
Prompt Flows
Finally, sometimes you may want to piece together multiple prompts to produce more complex reasoning chains:
from promuet import PromptFlow, AppFlow, Prompt, UserMessage, AssistantMessage
STARTUP_IDEA_FLOW = PromptFlow(
Prompt(
description="Decide problem area",
messages=[
UserMessage(
"""
Think about various problem areas in everyday life and then at the bottom propose a specific area that has high potential for innovation.
For now, let's focus on problems related to {{problem_area}}.
Place the final proposed problem area at the bottom like <problem_area>problem area</problem_area>.
"""
),
],
response_format="""
{{problem_area_thoughts}}
<problem_area>{{problem_area}}</problem_area>
"""
),
Prompt(
description="Generate startup idea",
messages=[
UserMessage("What is a problem area that we can explore innovative solutions for? Provide a direct answer."),
AssistantMessage("{{problem_area}}"),
UserMessage(
"""
Based on this problem area, generate a complete startup idea that addresses the problem.
"""
),
],
response_format="{{startup_idea_description}}"
),
Prompt(
description="Generate startup plan",
is_continuation=True,
messages=[
AssistantMessage("{{startup_idea_description}}"),
UserMessage("Now develop a complete end to end business proposal and plan for this startup including how we go from MVP/POC to launch to scale."),
],
response_format="{{startup_idea_proposal}}"
)
)
app_flow = AppFlow()
app_flow.run_prompt(STARTUP_IDEA_FLOW, dict(problem_area="construction"))
print('Startup idea proposal:')
print(app_flow['startup_idea_proposal'])
Installation
pip install promuet
License
promuet is distributed under the terms of the MIT license.
Metadata
Release files for promuet 0.3.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| promuet-0.3.3.tar.gz | 11.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| promuet-0.3.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.1 kB
Release files / promuet-0.3.3.tar.gz
| Download URL | promuet-0.3.3.tar.gz |
|---|---|
| Size | 11.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
75cba606f027e86cd6b08b3c0499170f355d46bf4f8d99aa69f9f73603a3ea57
|
|
BLAKE2b-256 checksum How to use checksums |
960e35860ac84a42dab985b812e7c772fa96383ebd88b74e40ea05abcb76ffb5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.0.1 CPython/3.13.2
|
Release files / promuet-0.3.3-py3-none-any.whl
| Download URL | promuet-0.3.3-py3-none-any.whl |
|---|---|
| Size | 10.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
35ba247355f5558cb77f55ad1d73c79e5525a1cde559e9759b64836420917b3f
|
|
BLAKE2b-256 checksum How to use checksums |
afa6a5f6d733b5636d070e31040c19983a4bd48ff99fa094f15b8c7c3fff3586
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.0.1 CPython/3.13.2
|