Dotpromptz is a language-neutral executable prompt template file format for Generative AI.
Project description
dotpromptz
一个 Python 库,用于解析和渲染 .prompt 格式的模板文件。.prompt 文件基于 Jinja2 模板语法,结合 YAML 前置元数据(frontmatter),提供了一种声明式的方式来定义 LLM 提示词。
快速上手:
examples/目录包含多个可直接运行的.prompt示例文件。如果你想一次了解所有可用字段和模板语法,请参考完整字段参考模板all_fields.prompt.template(主要作为参考模板,建议复制为.prompt后按需裁剪)。
安装
# 作为 CLI 工具安装(推荐)
uv tool install dotpromptz-py
# 或作为项目依赖安装
uv add dotpromptz-py
要求 Python >= 3.12。
升级
# CLI 工具升级
uv tool upgrade dotpromptz-py
# 项目依赖升级
uv add --upgrade dotpromptz-py
也可以通过 CLI 命令直接升级:
prompt --upgrade
# 或
prompt -U
运行前凭据配置
prompt run 需要可用的 API 凭据。通过环境变量 API_CREDENTIALS 加载,支持以下形式:
- 内联 JSON 数组:
API_CREDENTIALS='[{"name":"default","adapter":"openai","api_key":"sk-..."}]' - 本地文件:
API_CREDENTIALS='@/path/to/credentials.yaml'(也支持.json) - 远程 URL:
API_CREDENTIALS='@https://example.com/credentials.yaml'
如果 API_CREDENTIALS 未设置,dotpromptz 会尝试从默认远程地址加载凭据。拉取私有地址时可设置 API_CREDENTIALS_TOKEN,未设置时会尝试使用 gh auth token 作为兜底。
快速开始
命令行使用
# 渲染并调用 LLM,输出结果到文件
prompt run my_prompt.prompt
# 若输出文件已存在,显式允许覆盖
prompt run my_prompt.prompt --force
# 仅渲染模板(不调用 LLM),将结果写入日志目录下的 YAML 文件
prompt build my_prompt.prompt
# 合并目录中的输入文件(json/yaml/txt)
prompt merge examples/data
# 通过 glob 过滤并注入文件名(FILENAME)
prompt merge examples/data --pattern "**/*.json" -W
merge 规则说明
- 默认只扫描目录第一层;需要递归时请显式传
--pattern "**/*.<ext>"。 - 一次合并要求文件格式一致(全部
.json、或全部.yaml/.yml、或全部.txt)。 - 输出文件位于输入目录同级:JSON/TXT 合并为
.jsonl,YAML 合并为.yaml。
.prompt 文件格式
一个 .prompt 文件由两部分组成:
- YAML Frontmatter — 配置元数据(用
---包裹) - 模板正文 — Jinja2 模板,定义发送给 LLM 的消息内容
---
# YAML 前置元数据
adapter: openai
config:
model: gpt-4o
output:
format: txt
file_name: "result"
---
这里是模板正文,支持 Jinja2 语法。
你好,{{ name }}!
Frontmatter 字段参考
严格校验说明:frontmatter 顶层字段仅允许以下白名单:
version、description、adapter、config、input、output、tools、toolDefs、runtime。其余字段(包括foo.bar这类带点的键)会直接报错。
version
| 属性 | 值 |
|---|---|
| 类型 | int |
| 是否必需 | 是 |
dotpromptz 的主版本号(major version),对应 dotpromptz 包的大版本。用于前向兼容性检查:当 .prompt 文件的 version 高于当前引擎版本时,会抛出错误。
当存在 frontmatter 时,version 必须显式提供。
version: 1
description
| 属性 | 值 |
|---|---|
| 类型 | str |
| 默认值 | null |
| 是否必需 | 否 |
对该 prompt 的人类可读描述。
description: "生成产品描述的提示词"
adapter
| 属性 | 值 |
|---|---|
| 类型 | str 或 object |
| 默认值 | null |
| 是否必需 | run 命令必需 |
指定使用的 LLM 适配器。支持的值:openai、anthropic、google。
简写形式:
adapter: openai
对象形式(支持凭据组):
adapter:
name: openai
group: my-group # 单个凭据组
# 或
groups: # 多个凭据组(轮询)
- group-a
- group-b
| 子字段 | 类型 | 是否必需 | 说明 |
|---|---|---|---|
name |
str |
是 | 适配器名称 |
group |
str |
否 | 单个凭据组名 |
groups |
list[str] |
否 | 凭据组列表,轮询使用 |
config
| 属性 | 值 |
|---|---|
| 类型 | dict |
| 默认值 | null |
| 是否必需 | 否 |
模型的具体配置参数。不同适配器支持的参数可能不同,以下是通用参数。在 .prompt 文件中统一使用 snake_case 命名,dotpromptz 会在内部自动映射为各 API 提供商要求的字段名。
注意:
config采用严格字段校验。未列出的字段(例如把model误写为models)会报错。
config:
model: gpt-4o
thinking: high
temperature: 1
max_tokens: 2048
top_p: 0.9
seed: 42
stop: ["\n\n"]
| 子字段 | 类型 | 说明 |
|---|---|---|
model |
str |
模型名称 |
thinking |
str |
思考强度档位,默认 high(可选:low/medium/high) |
temperature |
float |
采样温度 |
max_tokens |
int |
最大生成 token 数 |
top_p |
float |
核采样参数 |
seed |
int |
随机种子 |
stop |
list[str] |
停止序列 |
frequency_penalty |
float |
频率惩罚 |
presence_penalty |
float |
存在惩罚 |
input
| 属性 | 值 |
|---|---|
| 类型 | object |
| 默认值 | null |
| 是否必需 | 否 |
定义输入数据来源和默认值。当提供多条数据时,自动进入批量处理模式。
简写形式(直接作为数据):
input:
name: Alice
topic: Python
完整形式(支持 defaults 和 data):
input:
defaults:
language: Chinese
data:
- name: Alice
topic: Python
- name: Bob
topic: Rust
从文件加载(支持多个文件路径):
# 单个文件
input:
files: data/users.jsonl
# 多个文件
input:
files:
- data/batch_1.jsonl
- data/batch_2.json
- data/extra.yaml
文件路径解析规则:
files中的文件路径为相对于.prompt文件所在目录的相对路径。例如,若.prompt文件位于prompts/my_task.prompt,files: data/users.jsonl会解析为prompts/data/users.jsonl。也支持绝对路径。
| 子字段 | 类型 | 说明 |
|---|---|---|
defaults |
dict |
固定默认值,合并到每条记录(记录中的同名字段会覆盖默认值) |
data |
dict、list[dict] |
内联数据(单条或批量) |
files |
str、list[str] |
单个文件路径或多个文件路径列表 |
注意:
input.data与input.files互斥,不能同时设置。 仅设置defaults(不提供data/files)时,run会按单条记录执行,并将defaults作为输入上下文。
支持的数据文件格式:
| 格式 | 说明 |
|---|---|
.json |
单个对象或对象数组 |
.yaml / .yml |
单个对象或对象数组 |
.jsonl |
每行一个 JSON 对象(始终视为批量数据) |
output
| 属性 | 值 |
|---|---|
| 类型 | object |
| 默认值 | null |
| 是否必需 | run 命令必需 |
定义输出格式和存储路径。
output:
format: json
schema: |
name: string, The user's name
age: integer, The user's age
tags(array): string
output_dir: "output/{{ NAME }}"
file_name: "profile_{{ name }}"
| 子字段 | 类型 | 默认值 | 是否必需 | 说明 |
|---|---|---|---|---|
format |
str |
— | 是 | 输出格式:json、yaml、txt、image |
schema |
str |
null |
否 | 输出的 schema 定义(Picoschema 格式),仅 json/yaml 格式有效 |
output_dir |
str |
output/{{NAME}}_{{TIME}} |
否 | 输出目录模板;run 时支持 {{ NAME }}、{{ TIME }} |
file_name |
str |
— | run 命令必需 |
输出文件名模板(不含扩展名),支持自动变量和输入变量 |
注意:
run命令中,output_dir仅支持{{ NAME }}、{{ TIME }}。file_name还支持{{ INDEX }}(批量索引)和输入变量(如{{ name }}、{{ lang }})。批量处理时如果不同记录渲染出同名文件,默认会报错并停止,避免意外覆盖;可使用prompt run --force显式允许覆盖。
# 示例:使用自动变量和输入变量
output:
file_name: "profile_{{ name }}" # 输入变量
output:
file_name: "translation_{{ INDEX }}" # 批量索引
output:
file_name: "{{ NAME }}_{{ TIME }}" # prompt 文件名 + 时间戳
output:
file_name: "{{ NAME }}_{{ lang }}" # 自动变量 + 输入变量
tools
| 属性 | 值 |
|---|---|
| 类型 | list[str] |
| 默认值 | null |
| 是否必需 | 否 |
声明可供模型调用的工具名称列表。
tools:
- get_weather
- search_database
toolDefs
| 属性 | 值 |
|---|---|
| 类型 | list[object] |
| 默认值 | null |
| 是否必需 | 否 |
内联定义工具。每个工具包含名称、描述和参数 schema。
toolDefs:
- name: get_weather
description: "获取指定城市的天气"
inputSchema:
type: object
properties:
city:
type: string
description: "城市名称"
required: [city]
runtime
| 属性 | 值 |
|---|---|
| 类型 | object |
| 默认值 | null |
| 是否必需 | 否 |
执行时的运行参数,控制并发、超时和重试。
runtime:
max_workers: 5
timeout: 30.0
retry:
max_retries: 3
retry_delay: 1.0
| 子字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
max_workers |
int |
5 |
批量处理时的最大并发数 |
timeout |
float |
null |
单次请求的超时时间(秒) |
retry |
object |
null |
重试配置;默认不重试 |
retry.max_retries |
int |
3 |
最大重试次数(仅当设置 retry 时生效) |
retry.retry_delay |
float |
1.0 |
重试间隔基数(秒),实际延迟 = delay × (attempt + 1) |
约束:
max_workers >= 1,timeout > 0(若设置),retry.max_retries >= 0,retry.retry_delay >= 0。
模板语法
模板正文使用 Jinja2 语法。
变量插值
你好,{{ name }}!你对 {{ topic }} 感兴趣。
支持嵌套属性访问:
用户 {{ user.name }} 的邮箱是 {{ user.email }}。
条件判断
{% if premium %}
你是高级用户,享有优先服务。
{% else %}
欢迎注册成为高级用户。
{% endif %}
循环
你的兴趣爱好:
{% for hobby in hobbies %}
- {{ hobby }}
{% endfor %}
直接属性访问
姓名:{{ user.name }}
年龄:{{ user.age }}
自动变量(UPPERCASE 变量)
dotpromptz 自动注入以下大写变量,可在模板正文和 frontmatter 的部分字段中使用。大写变量为自动注入,小写变量为用户输入:
| 变量 | 说明 | 可用位置 | 示例值 |
|---|---|---|---|
{{ NAME }} |
当前 .prompt 文件的名称(不含扩展名) |
模板正文、frontmatter 字段、output_dir、file_name |
draw_cat |
{{ TIME }} |
当前时间戳 | 模板正文、frontmatter 字段、output_dir、file_name |
2025_01_15_14_30_00 / 20250115_143000 |
{{ INDEX }} |
批量处理中的项目索引(从 0 开始) | file_name |
0、1、2 |
{{ SCHEMA }} |
从 output.schema 生成的 JSON Schema 字符串 |
模板正文、frontmatter 字段 | {"type": "object", ...} |
时间格式差异:模板正文/frontmatter 渲染里的
{{ TIME }}为YYYY_MM_DD_HH_MM_SS;run命令解析output_dir/file_name时使用YYYYMMDD_HHMMSS。
{{ SCHEMA }} 的使用
当你定义了 output.schema 后,{{ SCHEMA }} 会自动包含对应的 JSON Schema。你可以在模板中引用它来指导模型输出结构化数据:
---
output:
format: json
schema: |
name: string, The user's name
age: integer
---
请按照以下 JSON Schema 输出:
{{ SCHEMA }}
为 {{ name }} 生成一份用户档案。
{{ NAME }}、{{ TIME }}、{{ INDEX }} 在 frontmatter 中的使用
output_dir 和 file_name 字段都支持 {{ NAME }}、{{ TIME }}:
output:
output_dir: "results/{{ NAME }}"
file_name: "{{ NAME }}_{{ INDEX }}"
file_name 还支持 {{ INDEX }} 和输入变量(如 {{ name }}、{{ lang }}),会根据每条输入记录动态解析:
output:
file_name: "profile_{{ name }}" # 每条记录生成不同的文件名
内置模板函数与过滤器
{{ role("...") }}
切换消息角色。有效角色:system、user、model、tool。
{{ role("system") }}
你是一个专业的翻译助手。
{{ role("user") }}
请翻译以下内容:{{ text }}
默认(不使用 {{ role() }} 时),整个模板正文作为 user 角色的消息。
{{ media(url="...", contentType="...") }}
嵌入媒体内容(如图片)。
{{ role("user") }}
请描述这张图片:
{{ media(url=imageUrl, contentType="image/png") }}
| 参数 | 类型 | 说明 |
|---|---|---|
url |
str |
媒体资源的 URL 或 base64 数据 |
contentType |
str |
MIME 类型(如 image/png、image/jpeg) |
contentType是兼容写法,也可以使用content_type。
{{ variable | tojson(indent=N) }}
将变量序列化为 JSON 字符串。使用 Jinja2 的 tojson 过滤器。
数据如下:
{{ userData | tojson(indent=2) }}
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| 变量 | 变量 | — | 要序列化的变量 |
indent |
int |
null |
JSON 缩进空格数 |
{% if a == b %}...{% endif %}
条件判断:当两个值相等时渲染内容。
{% if user_role == "admin" %}
你拥有管理员权限。
{% else %}
你是普通用户。
{% endif %}
{% if a != b %}...{% endif %}
条件判断:当两个值不相等时渲染内容。
{% if status != "active" %}
你的账号状态异常。
{% endif %}
Picoschema 格式
output.schema 使用 Picoschema — 一种简洁的 schema 定义语法,会自动转换为标准 JSON Schema。
基本类型
name: string
age: integer
score: number
active: boolean
data: any
支持的标量类型:string、number、integer、boolean、null、any。
可选字段
使用 ? 标记可选字段:
name: string
nickname?: string
字段描述
在类型后用逗号添加描述:
name: string, The user's display name
age: integer, User's age in years
数组类型
tags(array): string
scores(array): number
嵌套对象
address(object):
street: string
city: string
zip?: string
枚举类型
status(enum):
- PENDING
- APPROVED
- REJECTED
通配符
允许对象包含任意额外属性:
config(object):
name: string
(*): any
完整示例
output:
format: json
schema: |
name: string, The user's full name
age: integer, Age in years
email?: string, Email address
hobbies(array): string
address(object):
city: string
country: string
role(enum):
- ADMIN
- USER
- GUEST
Frontmatter 中的模板渲染
Frontmatter 中支持字符串模板渲染(input 部分除外),可在 config、description 等字段中引用变量:
---
adapter: openai
config:
model: "{{ model_name }}"
description: "当前模型:{{ model_name }}"
output:
format: txt
file_name: "report"
---
注意:仅字符串叶子节点会被渲染;列表中的字符串不会被 frontmatter 渲染器处理。
input部分不会进行模板渲染。run命令下的output.output_dir/output.file_name由 CLI 的专用模板解析逻辑处理(见上方output章节说明)。
批量处理
当 input.data(内联数组)或 input.files(指向 .jsonl/.json/.yaml 等文件)包含多条记录时,dotpromptz 自动进入批量处理模式:
- 每条记录独立渲染模板并调用 LLM
- 使用
runtime.max_workers控制并发数(默认 5) - 每条记录生成独立的输出文件
示例
完整的可运行示例请参考 examples/ 目录:
| 示例 | 文件 | 功能演示 |
|---|---|---|
| 完整字段参考 | all_fields.prompt.template |
所有 frontmatter 字段 + 模板语法一览(参考模板) |
| 基础文本生成 | basic_text.prompt |
单条输入、文本输出、多角色消息 |
| 批量处理 | batch_translate.prompt |
.jsonl 文件输入、批量并发 |
| 结构化 JSON 输出 | structured_output.prompt |
SCHEMA、Picoschema、JSON 输出 |
| 多轮对话 | chat_with_history.prompt |
{{ role() }}、多角色 |
| 媒体输入 | describe_image.prompt |
{{ media() }}、图片理解 |
| 聚合分析 | aggregate_reviews.prompt |
多文件输入、结构化总结输出 |
每个示例输出到不同的子目录下,运行方式:
prompt run examples/basic_text.prompt
# ...以此类推
许可证
参见 LICENSE 文件。
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 dotpromptz_py-1.19.0.tar.gz.
File metadata
- Download URL: dotpromptz_py-1.19.0.tar.gz
- Upload date:
- Size: 210.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7196360a36fe444e9bb7dc9406da864ebe31e137db194f7123a829c0457fec8c
|
|
| MD5 |
39cc7cb1cf28a911b844d1b9299651ea
|
|
| BLAKE2b-256 |
d9e1a179b59332c7ec646bad4d4e63aa13a9c5e0c09b9c33bec46f03c501c6cc
|
Provenance
The following attestation bundles were made for dotpromptz_py-1.19.0.tar.gz:
Publisher:
publish-pypi.yml on my-three-kingdoms/dotpromptz
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dotpromptz_py-1.19.0.tar.gz -
Subject digest:
7196360a36fe444e9bb7dc9406da864ebe31e137db194f7123a829c0457fec8c - Sigstore transparency entry: 1023903079
- Sigstore integration time:
-
Permalink:
my-three-kingdoms/dotpromptz@fb7a11284f24d26bdb906369ec19a84c72ea46f7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/my-three-kingdoms
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@fb7a11284f24d26bdb906369ec19a84c72ea46f7 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file dotpromptz_py-1.19.0-py3-none-any.whl.
File metadata
- Download URL: dotpromptz_py-1.19.0-py3-none-any.whl
- Upload date:
- Size: 76.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39fae4e67168df705d87f84a204abfc64c25df93f850683ffa9032f0f56c19b5
|
|
| MD5 |
594ca5df6541add1ebc1a65ab4e77fd9
|
|
| BLAKE2b-256 |
d90a1b3461c38837d9b0f5b405719bc663a61b343f4672b441ab630572392769
|
Provenance
The following attestation bundles were made for dotpromptz_py-1.19.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on my-three-kingdoms/dotpromptz
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dotpromptz_py-1.19.0-py3-none-any.whl -
Subject digest:
39fae4e67168df705d87f84a204abfc64c25df93f850683ffa9032f0f56c19b5 - Sigstore transparency entry: 1023903131
- Sigstore integration time:
-
Permalink:
my-three-kingdoms/dotpromptz@fb7a11284f24d26bdb906369ec19a84c72ea46f7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/my-three-kingdoms
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@fb7a11284f24d26bdb906369ec19a84c72ea46f7 -
Trigger Event:
workflow_dispatch
-
Statement type: