Skip to main content

A prompt template engine for LLM apps: validated variables, reusable few-shot blocks, and clean chat/message construction.

Project description

promptkit

PyPI Python versions License: MIT

promptkit

A prompt template engine for LLM apps: validated variables, reusable few-shot blocks, and clean chat/message construction.

Part of the ragkit suite. Install with pip install ragkit-promptkit, then import promptkit.

promptkit replaces scattered f-strings that silently break when a variable is missing. You define templates once, get up-front validation of required variables, compose few-shot prompts, and build OpenAI-style message lists without hand-assembling dicts. Zero third-party dependencies -- standard library only, Python 3.8+.

Install

pip install ragkit-promptkit

Local development (from promptkit/):

pip install -e .

Quick Start

Define a template, inspect its variables, and render it:

from promptkit import PromptTemplate

tmpl = PromptTemplate("Summarize the following {kind} in {n} sentences:\n\n{text}")

print(tmpl.variables)   # {'kind', 'n', 'text'}

print(tmpl.render(kind="article", n=3, text="..."))

render() also accepts a single dict:

tmpl.render({"kind": "article", "n": 3, "text": "..."})

Missing variables are reported all at once

If a referenced variable has no value (and no default), you get a MissingVariableError listing every missing name -- not just the first:

from promptkit import PromptTemplate, MissingVariableError

tmpl = PromptTemplate("{greeting}, {name}! Welcome to {place}.")

try:
    tmpl.render(greeting="Hello")
except MissingVariableError as exc:
    print(exc)          # Missing required variable(s): 'name', 'place'
    print(exc.missing)  # ['name', 'place']

Extra/unknown keyword arguments are ignored, so you can safely pass a shared context dict to many templates.

Literal braces

Use {{ and }} for literal braces (same rules as str.format):

PromptTemplate('Return JSON like {{"score": {n}}}').render(n=5)
# Return JSON like {"score": 5}

Defaults and partial()

Provide defaults for optional variables, and use partial() to bake in some values while leaving the rest open:

from promptkit import PromptTemplate

tmpl = PromptTemplate(
    "You are a {tone} assistant. Answer: {question}",
    defaults={"tone": "friendly"},
)

tmpl.render(question="What is Python?")
# "You are a friendly assistant. Answer: What is Python?"

# Bake in the tone, get a new reusable template:
sarcastic = tmpl.partial(tone="sarcastic")
sarcastic.render(question="What is Python?")
# "You are a sarcastic assistant. Answer: What is Python?"

An explicit value always overrides a default. partial() returns a new template and never mutates the original.

Few-shot prompts

FewShotTemplate stitches a prefix, a list of rendered examples, and a suffix (which usually holds the final user query):

from promptkit import FewShotTemplate

few = FewShotTemplate(
    example_template="Q: {q}\nA: {a}",
    examples=[
        {"q": "2 + 2", "a": "4"},
        {"q": "3 * 3", "a": "9"},
    ],
    prefix="Solve the math problems.",
    suffix="Q: {question}\nA:",
    example_separator="\n\n",
)

# Add more examples dynamically:
few.add_example(q="10 - 4", a="6")

print(few.render(question="7 + 5"))

Output:

Solve the math problems.

Q: 2 + 2
A: 4

Q: 3 * 3
A: 9

Q: 10 - 4
A: 6

Q: 7 + 5
A:

Missing-variable validation applies across the prefix, examples, and suffix.

Chat prompts -> message dicts

ChatPromptTemplate builds OpenAI-style list[dict] message payloads. Each message content is rendered with the same PromptTemplate rules, and missing variables are aggregated across all messages:

from promptkit import ChatPromptTemplate, system, user, assistant

chat = ChatPromptTemplate.from_messages([
    system("You are a helpful {role}."),
    user("Explain {topic} to a {level} audience."),
])

messages = chat.render(role="tutor", topic="recursion", level="beginner")
# [
#   {"role": "system", "content": "You are a helpful tutor."},
#   {"role": "user", "content": "Explain recursion to a beginner audience."},
# ]

Pass messages straight to your LLM client. The system, user, and assistant helpers just return (role, template) tuples. If you prefer typed objects, chat.render_messages(...) returns Message(role, content) dataclass instances (each has .to_dict()).

Prompt registry and versioning

PromptRegistry is a tiny in-memory store for named, versioned prompts. get() returns the latest version by default:

from promptkit import PromptRegistry, PromptTemplate

registry = PromptRegistry()

registry.register(PromptTemplate("Summarize: {text}", name="summarize", version="1.0"))
registry.register(PromptTemplate("TL;DR the following:\n{text}", name="summarize", version="2.0"))

registry.list()                       # ['summarize']
registry.get("summarize")             # v2.0 (latest)
registry.get("summarize", version="1.0")  # the v1.0 template

latest = registry.get("summarize")
latest.render(text="...")

Versions are compared numerically when they look like dotted numbers ("1.0", "2.3"), falling back to string comparison otherwise.

API summary

Object Purpose
PromptTemplate Single-string template with {var} placeholders, defaults, partial(), and .variables.
FewShotTemplate Prefix + examples + suffix composition with add_example().
ChatPromptTemplate Renders (role, template) pairs to message dicts.
Message dataclass(role, content) with .to_dict().
system / user / assistant Helpers returning (role, template) tuples.
PromptRegistry In-memory register / get / list with versioning.
MissingVariableError Raised with .missing listing every unresolved variable.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ragkit_promptkit-0.1.0.tar.gz (12.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ragkit_promptkit-0.1.0-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file ragkit_promptkit-0.1.0.tar.gz.

File metadata

  • Download URL: ragkit_promptkit-0.1.0.tar.gz
  • Upload date:
  • Size: 12.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for ragkit_promptkit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4e3fd22f4fb1eed2e16452d2dbb94b595080dd3c87b72126376fe18a172153e6
MD5 e55ce6076b9e59951a47a16f45c31db6
BLAKE2b-256 354a33263999854c5398b782080fe1bdedb12e90851599916e1cbe65dfb772d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for ragkit_promptkit-0.1.0.tar.gz:

Publisher: publish.yml on Meet2147/pythonLibraries

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ragkit_promptkit-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for ragkit_promptkit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d1929bc280eaf17eb275aeecc53d6b6be51f302b7e8186fc6579370e72de344e
MD5 3885350e1852a85d6348386f1af66daf
BLAKE2b-256 3867338f08f2e67526463d417cbc634775a47269bd720ec762a1f101270b2d60

See more details on using hashes here.

Provenance

The following attestation bundles were made for ragkit_promptkit-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Meet2147/pythonLibraries

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page