Deterministic prompt builder on pydantic-stack-core (every prompt = a MetaStack of RenderablePieces) + cognition chains + optional grammar gate — the shared base of the chaincompiler ecosystem.
Project description
name: prompt-engineering description: The Prompt Engineering System (APE) — a deterministic prompt builder on pydantic-stack-core. A prompt is a MetaStack of RenderablePiece "blocks" (typed, self-rendering pydantic models); the same blocks render the SAME prompt every time. Compose blocks into stored "prompt templates". Use it to make system prompts, personas, rule blocks, few-shot blocks, cognition chains, or any prompt. No model call, no randomness. when_to_use: Building or reusing prompts/personas/templates programmatically; you want the same spec to render the same prompt every time; making a new prompt template (folder of block specs).
Prompt Engineering System (APE)
A skill (this SKILL.md + the code beside it) that turns data → a prompt, deterministically, on the
pydantic-stack-core foundation. The model decides what blocks to write; this engine guarantees
how they render — same inputs, same output, every time. That reliability is the point: an agent reads
this skill and uses it to make prompts/personas the same way each time.
The foundation rule: every prompt is a MetaStack of RenderablePieces. A block is a real, typed,
self-rendering pydantic model (RenderablePiece subclass) — not an exec'd code string. (This supersedes
the old {values, methods:[code-string]} mechanism; see META-APE-ARCHITECTURE.md §1.)
Vocabulary
- block — a
RenderablePiece: typed fields + a purerender()→ a chunk of prompt. Concrete blocks ship inblocks.py(Text,Heading,Section,Role,BulletList,KeyValue,Fenced,Template,Group). Declarative form:{"type": <BlockName>, **fields}. - prompt — a
MetaStackof blocks, built withprompt(...)/render_prompt(...). - prompt template — a stored, ordered set of block files (a folder under
templates/) → one prompt.
There is no baked-in structure and no "levels." You bring your own via blocks and templates.
Use it (the package prompt_engineering)
# pip install -e . (deps: pydantic-stack-core, rulecatcher, agent-skilltree)
from prompt_engineering import Role, BulletList, render_prompt, render, render_template, list_templates
# 1) compose blocks (RenderablePieces) into one prompt — a MetaStack
render_prompt(
Role(role="a senior Python code reviewer", mission="find correctness bugs"),
BulletList(title="Rules", items=["Cite file:line.", "Never invent an API."]),
) # → "You are a senior Python code reviewer. Your mission is to find correctness bugs.\n\n## Rules\n- ..."
# 2) render a single block from a declarative spec (data → prompt, no exec)
render({"type": "Template",
"template": "# {role}\n\nYou are the {role} of {domain}.",
"values": {"role": "Worldsmith", "domain": "otters"}}) # same spec → same prompt, always
# 3) render a stored prompt template (its blocks composed in order)
list_templates() # ['five_level', 'persona', 'simple_agent']
render_template("five_level") # → one prompt with WORLD/EGREGORE/DEITY/PROGENITOR/AGENT sections
Define your own block by subclassing RenderablePiece and (optionally) registering it for declarative use:
from prompt_engineering import RenderablePiece, register_block
@register_block
class Callout(RenderablePiece):
emoji: str
text: str
def render(self) -> str:
return f"> {self.emoji} {self.text}"
# now usable directly or as {"type": "Callout", "emoji": "⚠️", "text": "..."}
Add a prompt template — DROP A FOLDER
templates/
{template_name}/
template.json # {name, description, blocks: ["block1.json", "block2.json", ...]}
{block}.json # a declarative block spec: {"type": <BlockName>, **fields}
Create the folder, write template.json, drop in the block specs. Nothing in the engine changes.
list_templates() / render_template(name) pick it up by convention.
Resource files (referenced by relative path)
prompt_engineering/blocks.py— the block library (RenderablePiece subclasses on pydantic-stack-core)prompt()/render_prompt()+ declarativeblock_from_dict()/register_block()/REGISTRY
prompt_engineering/prompt_engine.py—render,render_file,list_templates,load_template,render_template,render_template_blocks(single block + stored templates)examples/— single-block specs for different block types (system/role, persona, rules, few-shot, constraints, output-format) and full personas — read these to learn the declarative block formattemplates/five_level/,templates/simple_agent/,templates/persona/— worked prompt templatesprompt_engineering/cognition.py— the cognition-chain blocks (AttentionChain/ChainOfReasoning/SkillChain, all RenderablePieces; a CoR nests an AC) +validate_chain(a no-dep broken-detector)prompt_engineering/gate.py— the REAL gate:gate(text, exemplars)LEARNS the grammar from exemplar chains → violations + fixes + theorthogonal/syntax_break(steerable/fatal) verdictprompt_engineering/grammar.py— the persistent rulecatcher seam (learn/gate/render on aConnection)prompt_engineering/skillpack.py—write_skill/cohere_skills: a markdown body → a publishable<name>/SKILL.md(skilltree-aware)pydantic-stack-core— THE foundation (RenderablePiece + MetaStack);rulecatcher— the grammar engine the gate runs on;agent-skilltree— coordinate-addressed skill placementprompt_engineering/persona.py—make_persona(spec)/make_persona_file(path): a full persona prompt (block types + a cognition DSL block) from a small specscripts/—make_prompt.py,make_persona.py,new_template_skill.py(scaffold a skill for a template)test_*.py— run to verify (all NO-API): prompt engine · cognition · persona · gate · skillpack
Cognition chains & personas
cognition.py gives the three chain primitives as RenderablePiece blocks: an attention chain, a
chain-of-reasoning (which nests an AC = block-nesting), and a skill chain. Rendering never
touches a grammar engine or a DB. The gate is a separate, optional layer (gate.py, on
rulecatcher): gate(text, exemplars) LEARNS the grammar from exemplar chains (next_kind = shape,
next_token = vocabulary), then lints a candidate → violations + fixes + the orthogonal (in the
language, wrong slot → steerable) vs syntax_break (foreign → fatal) verdict.
from prompt_engineering import render_cor, gate, make_persona
render_cor("Debugger", ["Symptom", "Repro", "Hypothesis"], "Localize", "the root cause") # a CoR persona
gate("[Goal] ⇒ [Repro] ⇒ |Localize|", # learn, then lint:
exemplars=["[Symptom] ⇒ [Repro] ⇒ |Localize|", "[Symptom] ⇒ [Bisect] ⇒ |RootCause|"])
# → {ok: False, verdict: 'orthogonal', violations: [{found:'Goal', candidates:['Symptom'], ...}]}
make_persona({ # a whole persona with a complex reasoning DSL, in one call
"name": "Ada", "role": "a senior debugger",
"reasoning": {"foci": ["Symptom", "Repro", "Bisect"], "held": "RootCause", "decision": "the minimal fix"},
"rules": ["Reproduce before theorizing."], "output": "A markdown report.",
})
Why deterministic matters
Each block's render() is a pure function of its typed fields; a MetaStack joins the rendered pieces in
order with a separator — pure composition, no model call. That's what lets an agent rely on it to produce
prompts consistently across runs. This is the base layer of the chaincompiler ecosystem (CC → ACCC →
CORCC → SCCC all import DOWN to here; see META-APE-ARCHITECTURE.md).
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
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_prompt_engineering-0.2.0.tar.gz.
File metadata
- Download URL: agent_prompt_engineering-0.2.0.tar.gz
- Upload date:
- Size: 22.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b3decd9f110646f28058ca911339dc840475a76e3a8a7d67edfaf28c25bff5e
|
|
| MD5 |
1b57e9f223b6217e837c3c15a29e2a23
|
|
| BLAKE2b-256 |
515822f871df0d63831536e5b1fa69ff132ab7ca84a3e4077e893ef78930753d
|
File details
Details for the file agent_prompt_engineering-0.2.0-py3-none-any.whl.
File metadata
- Download URL: agent_prompt_engineering-0.2.0-py3-none-any.whl
- Upload date:
- Size: 30.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b151553d3b5645fc252c5f1b9ef87bd00be5ca1dc4e67cfed568b47003920b5
|
|
| MD5 |
a71a85adbf43b920461360ea0c07c12a
|
|
| BLAKE2b-256 |
9148a2dd62f2e1ee3c6dad4441726113c8a8be754b4752c4ecd82bcb56e7e932
|