开源工具让开发者在终端直接执行.prompt文件,简化提示工程工作流,便利频繁使用prompt的开发者。
从 Shell 运行 .prompt 文件,用单个 Python 脚本处理 LLM 提示。
.prompt 文件在一个文件中包含提示和元数据(模型、schema、配置)。你可以用它运行 LLM 提示,并直接在 shell 中获取结构化响应。可以用它自动化 AI 工作流或构建自己的工具框架。让提示成为一级制品。将它们签入你的仓库,从命令行运行,而不是向 AI 聊天机器人发送临时请求。
快速开始 | 示例 | 工具 | 模板语法 | 配置 | 供应商 | 缓存 | 规范兼容性
curl -O https://raw.githubusercontent.com/chr15m/runprompt/main/runprompt
chmod +x runprompt
或者可以直接用 uvx 运行,不需要安装:
uvx --from git+https://github.com/chr15m/runprompt runprompt hello.prompt
或通过 pip 或 uv 安装来作为库使用:
# 使用 uv(推荐)
uv pip install git+https://github.com/chr15m/runprompt
# 使用 pip
pip install "git+https://github.com/chr15m/runprompt.git"
---
model: anthropic/claude-sonnet-4-20250514
---
Say hello to {{name}}!
export ANTHROPIC_API_KEY="your-key"
./runprompt hello.prompt '{"name": "World"}'
# 或者通过 STDIN 传递数据。
echo '{"name": "World"}' | ./runprompt hello.prompt
(你可以从这里获取 Anthropic 密钥:https://console.anthropic.com/settings/keys 其他密钥见下文。)
除了以下内容外,还可以在 tests 目录中看到更多 .prompt 文件示例。
---
model: anthropic/claude-sonnet-4-20250514
---
Summarize this text: {{STDIN}}
cat article.txt | ./runprompt summarize.prompt
特殊变量 {{STDIN}} 始终包含原始 stdin 作为字符串。{{STDIN}} 和 {{ARGS}} 总是可用的;如果输入是 JSON,它也会被解析成单个变量。
不需要创建 .prompt 文件:
./runprompt -p "Say hello to {{name}}" --model openai/gpt-4o '{"name": "World"}'
直接在命令行上传递参数:
---
model: anthropic/claude-sonnet-4-20250514
---
Process this: {{ARGS}}
./runprompt process.prompt Hello world, please summarize this text.
特殊变量 {{ARGS}} 包含 prompt 文件之后的所有参数,用空格连接。{{INPUT}} 变量包含 STDIN(如果提供),否则包含 ARGS。
使用输出 schema 提取结构化数据:
---
model: anthropic/claude-sonnet-4-20250514
input:
schema:
text: string
output:
format: json
schema:
name?: string, the person's name
age?: number, the person's age
occupation?: string, the person's job
---
Extract info from: {{text}}
echo "John is a 30 year old teacher" | ./runprompt extract.prompt
# {"name": "John", "age": 30, "occupation": "teacher"}
Schema 使用 Picoschema 格式。以 ? 结尾的字段是可选的。格式为 field: type, description。
echo "John is 30" | ./runprompt extract.prompt | ./runprompt generate-bio.prompt
第一个提示的 JSON 输出成为第二个的模板变量。
执行 shell 命令来收集动态上下文,然后再将提示发送给 LLM:
---
model: anthropic/claude-sonnet-4-20250514
before:
latest_commit: git log -1 --oneline
current_date: date
file_count: find . -name "*.py" | wc -l
---
Latest commit: {{latest_commit}}
Current date: {{current_date}}
Python files: {{file_count}}
每个命令都在你配置的 shell($SHELL,默认为 /bin/sh)中运行,具有完整的 shell 功能(管道、重定向等)。成功时捕获 stdout。失败时捕获 stderr。所有输出都可用作单个变量加上一个组合的 {{BEFORE}} 变量。
模板变量作为环境变量传递给 shell,所以你可以引用它们:
---
model: anthropic/claude-sonnet-4-20250514
before:
model_info: echo "Using model: ${model}"
---
{{model_info}}
用 shebang 直接使 .prompt 文件可执行:
#!/usr/bin/env runprompt
---
model: anthropic/claude-sonnet-4-20250514
---
Hello, I'm {{name}}!
chmod +x hello.prompt
echo '{"name": "World"}' | ./hello.prompt
注意:runprompt 必须在你的 PATH 中,或在 shebang 中使用相对/绝对路径(例如 #!/usr/bin/env ./runprompt)。
使用 --chat 标志、RUNPROMPT_CHAT=1 环境变量或 prompt 前置元数据中的 chat: true 开始与 LLM 的交互式对话。对话历史会跨轮次保持。
用 prompt 文件启动聊天以设置初始上下文或角色:
./runprompt --chat expert.prompt
或者不用 prompt 文件启动普通聊天(需要指定模型):
./runprompt --chat --model anthropic/claude-sonnet-4-20250514
要在会话间持久化你的 readline 历史记录(用于聊天模式和 ask_user 工具),设置 RUNPROMPT_CHAT_HISTORY=1 或前置元数据中的 chat_history: true。你可以用 RUNPROMPT_HISTORY_FILE 自定义历史文件位置(默认为 .runprompt.history)。
在交互式聊天会话期间,你可以使用特殊命令动态修改上下文或工具:
/read <path-or-url>:读取文件或 URL 并将其内容追加到聊天上下文。
/edit <path>:动态为指定文件公开 write_file 工具,允许 LLM 写入或编辑该文件。
/drop <path>:移除指定文件的 write_file 工具。
./runprompt --model anthropic/claude-haiku-4-20250514 hello.prompt
./runprompt --output.format json extract.prompt
嵌套值使用点符号(例如 --output.format)。通过 stdin 或 JSON 参数传递模板变量:
echo '{"name": "Alice"}' | ./runprompt hello.prompt
./runprompt hello.prompt '{"name": "Alice"}'
查看 --help 了解所有选项。
虽然标准输出只打印最终提取的文本或 JSON,但你可以使用 --save-response 保存整个原始 API 信封(包括 token 使用情况、finish reason 和精确模型版本):
./runprompt --save-response api_out.json hello.prompt
---
model: anthropic/claude-sonnet-4-20250514
files:
- README.md
- src/**/*.py
---
Review these files and suggest improvements.
你可以在文件模式中使用模板变量(包括 before: 输出):
---
model: anthropic/claude-sonnet-4-20250514
before:
changed_files: git diff --name-only HEAD~1
files:
- "{{changed_files}}"
---
Review the recently changed files.
从 CLI 中(也支持 glob)。--file 是 --read 的别名:
./runprompt --read README.md --read "src/**/*.py" review.prompt
./runprompt --file README.md review.prompt
你可以组合两者:前置元数据 files: 条目加上任何 --read/--file 标志都会被包含。
加载附件时,runprompt 会为每个加载的文件/URL 向 stderr 打印一条黄色信息。
工具允许 LLM 在提示执行过程中调用 Python 函数。将工具定义为带有 docstring 的 Python 函数,LLM 就可以使用它们执行读取文件、进行 API 调用或与系统交互等操作。
创建一个 Python 文件,其中任何带有 docstring 的函数都成为工具:
# my_tools.py
def get_weather(city: str):
"""Gets the current weather for a city.
Returns the temperature and conditions for the specified location.
"""
# Your implementation here
return {"temp": 72, "conditions": "sunny"}
def calculate(expression: str):
"""Evaluates a mathematical expression.
Use this for arithmetic calculations.
"""
return eval(expression)
在前置元数据中使用 Python import 语法引用工具:
---
model: anthropic/claude-sonnet-4-20250514
tools:
- my_tools.*
---
What's the weather in Tokyo and what's 15% of 847?
module.* - 从 module.py 导入所有带有 docstring 的函数
module.function_name - 导入特定函数
当 LLM 想要调用工具时,系统会提示你确认:
$ ./runprompt weather.prompt
I'll check the weather for you.
Tool call: get_weather
Arguments: {"city": "Tokyo"}
Run this tool? [y/n]: y
The weather in Tokyo is currently 72°F and sunny.
将工具标记为"安全"以允许它们在使用 --safe-yes、环境变量 RUNPROMPT_SAFE_YES 或配置 safe_yes 时无需确认运行:
# my_tools.py
def get_weather(city: str):
"""Gets the current weather for a city (read-only operation)."""
return {"temp": 72, "conditions": "sunny"}
get_weather.safe = True # Mark as safe
def delete_file(path: str):
"""Deletes a file from the filesystem."""
os.remove(path)
return "deleted"
通过 --safe-yes 或环境变量 RUNPROMPT_SAFE_YES 或配置变量 safe_yes 自动批准安全工具:
./runprompt --safe-yes weather.prompt
标记为 fn.safe = True 的工具不提示确认直接运行
没有 safe 属性的工具仍会提示确认
这对自动化很有用,你可以信任特定的只读或低风险操作,同时仍然对潜在危险操作进行确认。
工具搜索路径:
当前工作目录
包含提示文件的目录
通过 --tool-path 或配置文件指定的路径
默认配置工具目录(如果存在):./.runprompt/tools、$XDG_CONFIG_HOME/runprompt/tools(默认:~/.config/runprompt/tools)、~/.runprompt/tools
./runprompt --tool-path ./my_tools --tool-path /shared/tools prompt.prompt
所有路径都会被搜索,包括配置文件中的任何 tool_path 条目。
函数参数的类型提示映射到 JSON Schema 类型:
没有类型提示的参数默认为字符串。
如果工具抛出异常,错误会被发送回 LLM,由其决定如何继续:
Tool call: read_file
Arguments: {"path": "missing.txt"}
Run this tool? [y/n]: y
FileNotFoundError: [Errno 2] No such file or directory: 'missing.txt'
I couldn't read that file because it doesn't exist. Would you like me to try a different path?
在提示中内联定义简单的 shell 脚本工具:
---
model: anthropic/claude-sonnet-4-20250514
shell_tools:
git_status: git status --short
count_py_files: find . -name "*.py" | wc -l
---
What's the current git status and how many Python files are there?
长格式及选项:
shell_tools:
git_log:
cmd: git log --oneline
safe: true
description: Show recent git commits
search_code:
cmd: grep -r
safe: true
description: Search for text in files
cmd(必需):要执行的 shell 命令
safe(可选,默认:false):标记为使用 --safe-yes 时自动批准
description(可选,默认:cmd):展示给 LLM 的描述
args(字符串):追加到命令
环境变量作为命名参数:
git_log(args="--author=alice -n 5")
search_code(args="TODO", PATH="/src")
Shell 工具使用与之前相同的 shell 解析方式:命令($SHELL,默认 /bin/sh)。
Runprompt 包含无需创建外部 Python 文件即可使用的内置工具:
---
model: anthropic/claude-sonnet-4-20250514
tools:
- builtin.fetch_clean
---
Please summarize this page: {{ARGS}}
可用的内置工具:
计算器、datetime、fetch_clean、sleep 和 ask_user 工具标记为安全(通过 --safe-yes 自动批准)。shell 和 write_file 工具需要确认,因为它们可以运行命令/修改文件系统。
某些内置工具是"工厂",它们接受参数来创建专用工具:
---
model: anthropic/claude-sonnet-4-20250514
tools:
- builtin.write_file('output.txt')
---
Write a haiku about coding to the file.
write_file('output.txt') 创建一个只能写入 output.txt 的工具。LLM 提供内容,但无法选择路径——这是一个安全特性,限制了 LLM 可以修改的文件。创建的工具以特定于文件名的名称(slug)暴露给 LLM,例如 write_file_output_txt。
使用 builtin.* 导入所有内置工具,或 builtin.tool_name 导入特定工具。
以 _ 开头的文件或函数被排除在通配符导入之外:
# _helpers.py - 此整个文件被排除在通配符导入之外
# my_tools.py
def _private_helper(): # 被排除在通配符导入之外
"""Internal helper function."""
pass
def public_tool(): # 包含在通配符导入中
"""A tool available to the LLM."""
pass
对于不想暴露为工具的辅助函数,请使用 _ 前缀。
模板使用 Handlebars/Mustache 语法的一个有用子集。
{{STDIN}} - 原始 stdin 内容(始终可用)
{{ARGS}} - 提示文件之后的命令行参数(始终可用)
{{INPUT}} - 如果提供了 STDIN,则为 STDIN,否则为 ARGS(始终可用)
{{BEFORE}} - 所有 before: 命令的组合输出
来自 before: 命令的单个变量(例如 {{latest_commit}})
变量插值:{{variableName}}、{{object.property}}
注释:{{! this is a comment }}
条件语句:{{#if key}}...{{/if}}、{{#if key}}...{{else}}...{{/if}}
否定条件语句:{{#unless key}}...{{/unless}}、{{#unless key}}...{{else}}...{{/unless}}
迭代:{{#each items}}...{{/each}},支持 @index、@first、@last、@key
分段:{{#key}}...{{/key}}(如果真值则渲染)
反向分段:{{^key}}...{{/key}}(如果假值则渲染)
假值:false、0、""(空字符串)、[](空列表)、未定义的变量。
配置值可以从配置文件、环境变量或命令行标志设置,标志覆盖环境变量,环境变量覆盖配置文件设置。
配置文件(优先级最低,按顺序加载):~/.runprompt/config.yml、$XDG_CONFIG_HOME/runprompt/config.yml(默认:~/.config/runprompt/config.yml)、./.runprompt/config.yml(项目本地)
环境变量(RUNPROMPT_* 前缀)
命令行标志(优先级最高)
API 密钥可以通过配置文件、RUNPROMPT_* 环境变量或原生环境变量设置:
API 密钥优先级:配置文件、环境变量,然后是标志作为备选。
# ./.runprompt/config.yml, ~/.config/runprompt/config.yml, or ~/.runprompt/config.yml
model: openai/gpt-4o
default_model: anthropic/claude-sonnet-4-20250514 # 在其他地方未指定模型时用作备选
cache: true
safe_yes: true
timeout: 120
tool_path:
- ./tools
- /shared/tools
openai_api_key: sk-...
当提示文件、配置、环境或命令行中未指定模型时,default_model 用作备选。这让你设置一个首选模型,仅在其他地方都未指定时才使用。
自定义端点(Ollama 等)
使用 base_url 指向任何兼容 OpenAI 的端点:
# 通过配置文件
# base_url: http://localhost:11434/v1
# 通过环境变量
export RUNPROMPT_BASE_URL="http://localhost:11434/v1"
# 通过命令行标志
./runprompt --base-url http://localhost:11434/v1 hello.prompt
# 旧版环境变量也支持(按此顺序检查)
export OLLAMA_BASE_URL="http://localhost:11434/v1"
export OPENAI_BASE_URL="http://localhost:11434/v1"
export OPENAI_API_BASE="http://localhost:11434/v1" # OpenAI SDK v0.x 风格
export BASE_URL="http://localhost:11434/v1"
设置了自定义基 URL 后,模型字符串中的提供者前缀会被忽略,并使用 OpenAI 兼容的 API 格式。
使用 -v 或设置 verbose: true 查看请求/响应详情:
./runprompt -v hello.prompt
模型指定为 provider/model-name 格式:
OpenRouter 通过单个 API 密钥提供来自多个提供者(Anthropic、Google、Meta 等)的模型访问。
启用响应缓存以避免开发期间的冗余 API 调用:
# 使用 -c 或 --cache 启用缓存
./runprompt --cache hello.prompt
# 第二次运行相同输入会使用缓存的响应
./runprompt --cache hello.prompt
你也可以在整个管道中使用环境变量启用缓存:
export RUNPROMPT_CACHE=1; echo "..." | ./runprompt a.prompt | ./runprompt b.prompt
缓存的响应存储在 ~/.cache/runprompt/(或 $XDG_CACHE_HOME/runprompt/),基于应用于模板和前置元数据的输入。
你可以随时清除缓存目录:
./runprompt --clear-cache
更多信息见 --help。
这是 Dotprompt 规范的最小实现。暂不支持:
多消息提示({{role}}、{{history}})
辅助函数({{json}}、{{media}}、{{section}})
模型配置(temperature、maxOutputTokens 等)
部分模板({{>partialName}})
嵌套 Picoschema(对象、对象数组、枚举)
YAML 解析器是最小实现,仅处理 Dotprompt 前置元数据所需的 YAML 子集(简单键值对、嵌套对象和列表)。在复杂的 YAML 特性(如锚点、多行字符串或流语法)上可能会失败。见下方可选依赖,使用 pyyaml 代替。
可选依赖
你可以安装可选依赖以增强功能:
pyyaml:在前置元数据中提供完整 YAML 规范支持。
playwright:通过 builtin.fetch_clean 工具提供高质量网页爬取。
如果你通过 pip 或 uv 安装,可以通过以下命令获取这些:
pip install "runprompt[full] @ git+https://github.com/chr15m/runprompt.git"
如果安装了 PyYAML,它会自动替代最小内部解析器被使用。