- Posted on
- • Artificial Intelligence
Artificial Intelligence Prompt Libraries
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Stop Rewriting Prompts: Build a Reusable AI Prompt Library in Your Bash Workflow
If you’ve ever typed the same “You are a helpful assistant. Use bullet points. Cite sources.” three times in one day, you’ve got a problem a prompt library can fix. Treat prompts like code: version them, test them, preview them, and run them from your terminal.
This article shows you how to stand up a simple, fast, shell-first prompt library on Linux. You’ll get structure, speed, and reproducibility without leaving Bash.
Why prompt libraries matter (especially on Linux)
Reuse and speed: You keep your best prompts as files, not in your head or browser history.
Consistency: A single source of truth reduces drift across teams and projects.
Reproducibility: Inputs in, outputs out. Prompts become part of your pipeline and logs.
Collaboration: Git review, diffs, branches, and pull requests work just as well for prompts as they do for scripts.
Auditability: A clear trail of which prompt generated which output is invaluable for compliance and debugging.
What we’ll build
A simple folder structure for prompts (Markdown/text with variables).
A tiny Bash tool to search, fill variables, and send prompts to an OpenAI-compatible API.
Real-world examples you can use immediately.
Package-install commands for apt, dnf, and zypper.
Note: The API bits use any OpenAI-compatible endpoint (OpenAI, Azure OpenAI, local servers that speak the same API, LM Studio, etc.). You control it via env vars.
1) Scaffold your prompt library
Create a home for prompts with a few domains and variables you can fill at run time.
mkdir -p ~/prompts/{code,ops,analytics}
Example prompt: code review for Bash scripts with variable placeholders.
cat > ~/prompts/code/bash_code_review.md <<'EOF'
# Title: Bash Code Review
# Purpose: Review a Bash script for correctness, portability, and security.
You are a senior Bash engineer. Review the following script.
Requirements:
- Point out POSIX portability issues.
- Flag any unsafe patterns (word splitting, globbing, unquoted variables).
- Suggest improvements and rationale.
- ${STYLE:-brief} tone.
Script metadata:
- File: ${FILENAME}
- Context: ${CONTEXT:-general use}
Script:
----------------
${SCRIPT}
----------------
EOF
Two more examples to make it a library:
cat > ~/prompts/ops/incident_postmortem.md <<'EOF'
# Title: Incident Postmortem
You are a reliability engineer documenting an incident.
Include:
- Summary (2-3 sentences)
- Impact (numbers if available)
- Timeline (UTC)
- Root cause analysis (5 Whys)
- Corrective actions (owner & date)
- Preventive measures
Use a neutral, blameless tone. Customer-facing summary at the top.
Incident:
${INCIDENT_TEXT}
EOF
cat > ~/prompts/analytics/sql_fixer.md <<'EOF'
# Title: SQL Fixer
You are a SQL expert. Given a broken query and an error message, return a corrected query and explain the fix.
DB dialect: ${DIALECT:-PostgreSQL}
Error message: ${ERROR}
Broken query:
${QUERY}
EOF
Version-control your library:
cd ~/prompts
git init
git add .
git commit -m "seed: code review, incident postmortem, sql fixer"
2) Install terminal tooling (fzf, ripgrep, jq, curl, gettext)
We’ll use:
fzf for fast selection
ripgrep (rg) for lightning search
jq to parse JSON responses
curl for HTTP
gettext’s envsubst for variable substitution
git for version control
Install with your package manager.
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y git curl jq fzf ripgrep gettext-base
- Fedora/RHEL/CentOS (dnf):
sudo dnf install -y git curl jq fzf ripgrep gettext
- openSUSE (zypper):
sudo zypper refresh
sudo zypper install -y git curl jq fzf ripgrep gettext-tools
3) A tiny Bash runner to search, fill, and send prompts
Save this as ~/bin/ai-prompt and make it executable. It:
Lets you pick a prompt with fzf
Detects variables like ${VAR}
Prompts for values if not set in your environment
Substitutes values and sends the prompt to an OpenAI-compatible API
Prints the model’s response
mkdir -p ~/bin
cat > ~/bin/ai-prompt <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
LIBDIR="${PROMPT_LIB:-$HOME/prompts}"
MODEL="${MODEL:-gpt-4o-mini}"
BASE_URL="${OPENAI_BASE_URL:-https://api.openai.com/v1}"
API_KEY="${OPENAI_API_KEY:-}"
need() { command -v "$1" >/dev/null 2>&1 || { echo "Missing: $1" >&2; exit 1; }; }
need fzf
need rg
need jq
need curl
need envsubst
if [[ ! -d "$LIBDIR" ]]; then
echo "Prompt library not found at $LIBDIR" >&2
exit 1
fi
# Pick a file
FILE="$(find "$LIBDIR" -type f \( -name '*.md' -o -name '*.txt' -o -name '*.prompt' \) | sort | fzf --prompt='Select prompt > ' --preview='sed -n "1,200p" {}' --preview-window=right:70%)"
[[ -n "${FILE:-}" ]] || { echo "No file selected."; exit 1; }
# Gather variables like ${VAR_NAME}
mapfile -t VARS < <(grep -o '\${[A-Za-z_][A-Za-z0-9_]*}' "$FILE" | tr -d '${}' | sort -u || true)
# Ask for missing values unless already in env or with default syntax ${VAR:-default}
render_tmp="$(mktemp)"
defaults_tmp="$(mktemp)"
# Extract defaults of the form ${VAR:-default text}
# We will use awk to capture var and default
awk '
{
while (match($0, /\$\{[A-Za-z_][A-Za-z0-9_]*:-[^}]*\}/)) {
token=substr($0,RSTART,RLENGTH)
gsub(/^\$\{|\}$/, "", token)
split(token, a, ":-")
var=a[1]; def=a[2]
print var "\t" def
$0=substr($0,1,RSTART-1) substr($0,RSTART+RLENGTH)
}
}
' "$FILE" | sort -u > "$defaults_tmp" || true
declare -A DEF
while IFS=$'\t' read -r k v; do
[[ -n "$k" ]] && DEF["$k"]="$v"
done < "$defaults_tmp" || true
# Prompt user for values only if not already set
for v in "${VARS[@]}"; do
# Skip variables that appear only as ${VAR:-default} since envsubst uses env or default
# But if env is set, it overrides default. If not set and default exists, no need to ask.
if [[ -z "${!v:-}" && -z "${DEF[$v]:-}" ]]; then
read -rp "$v: " val
export "$v=$val"
fi
done
# Render with envsubst (handles ${VAR} and ${VAR:-default})
envsubst < "$FILE" > "$render_tmp"
echo "=== Rendered prompt ($(basename "$FILE")) ==="
sed -n '1,120p' "$render_tmp"
echo "=== Sending to model: $MODEL ===" >&2
# Require API key for OpenAI-compatible flows
if [[ -z "$API_KEY" ]]; then
echo "OPENAI_API_KEY is not set. Export it, e.g.: export OPENAI_API_KEY=sk-..." >&2
echo "If using a local OpenAI-compatible server without auth, set OPENAI_API_KEY=dummy and override OPENAI_BASE_URL." >&2
exit 1
fi
resp="$(curl -sS -X POST "$BASE_URL/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @- <<JSON
{
"model": "$MODEL",
"messages": [
{ "role": "user", "content": $(jq -Rs . < "$render_tmp") }
],
"temperature": 0.2
}
JSON
)"
# Print model response or error
if [[ "$(echo "$resp" | jq -r '.choices[0].message.content? // empty')" != "" ]]; then
echo
echo "=== Model Response ==="
echo "$resp" | jq -r '.choices[0].message.content'
else
echo "Request failed or invalid response:" >&2
echo "$resp" | jq .
exit 1
fi
rm -f "$render_tmp" "$defaults_tmp"
EOF
chmod +x ~/bin/ai-prompt
Environment setup (put these in your shell profile if you like):
export OPENAI_API_KEY="sk-...your-key..."
# Optional: point to a different endpoint (LM Studio, local proxy, Azure OpenAI, etc.)
# export OPENAI_BASE_URL="http://localhost:1234/v1"
# export MODEL="gpt-4o-mini"
# export PROMPT_LIB="$HOME/prompts"
Run it:
ai-prompt
Pick a prompt, fill any variables, get the result.
Tip: If a variable has a default like ${STYLE:-brief}, you won’t be asked for it unless you export STYLE to override.
4) Real-world examples
- Code review a Bash script
export FILENAME="backup.sh"
export CONTEXT="Runs nightly via cron"
export STYLE="thorough"
export SCRIPT="$(sed -n '1,200p' ./backup.sh)"
ai-prompt
- Draft an incident postmortem
export INCIDENT_TEXT="$(cat incident_notes.txt)"
ai-prompt
- Fix a SQL query by dialect
export DIALECT="PostgreSQL"
export ERROR="ERROR: syntax error at or near 'fromm' LINE 1: select * fromm users"
export QUERY="select * fromm users where created_at > now() - interval '7 days';"
ai-prompt
Pro tip: Pre-export commonly used variables in task-specific shell aliases or tiny wrapper scripts for repeatability.
5) Treat prompts like code: search, test, and version
- Fast search across your library:
rg -n "postmortem|review" ~/prompts
- Branch, review, and tag:
cd ~/prompts
git checkout -b feature/tighter-bash-review
$EDITOR code/bash_code_review.md
git commit -am "bash review: add word-splitting check; default tone=brief"
git tag -a v0.2 -m "Improve Bash review template"
- Simple A/B checks (two prompt variants on the same input):
cat > ~/bin/prompt-ab <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
A="$1"; B="$2"; shift 2
export SCRIPT="$(cat "$1")"
export FILENAME="${2:-sample.sh}"
echo "== A: $(basename "$A") =="
PROMPT_LIB="$(dirname "$A")" MODEL="${MODEL:-gpt-4o-mini}" OPENAI_API_KEY="${OPENAI_API_KEY:?}" \
OPENAI_BASE_URL="${OPENAI_BASE_URL:-https://api.openai.com/v1}" ai-prompt <<< "$A" || true
echo
echo "== B: $(basename "$B") =="
PROMPT_LIB="$(dirname "$B")" MODEL="${MODEL:-gpt-4o-mini}" OPENAI_API_KEY="${OPENAI_API_KEY:?}" \
OPENAI_BASE_URL="${OPENAI_BASE_URL:-https://api.openai.com/v1}" ai-prompt <<< "$B" || true
EOF
chmod +x ~/bin/prompt-ab
Usage:
prompt-ab ~/prompts/code/bash_code_review.md ~/prompts/code/bash_code_review_alt.md ./backup.sh
You can redirect outputs to files and diff them to see which prompt works better for your use case.
Security note: Never paste secrets into prompts. Keep secrets out of your prompt files and inputs. Consider scanning your repo with your existing secret detectors before pushing.
Troubleshooting
fzf not found: Ensure you installed it with your package manager and that
~/binis on your PATH.API issues: Verify
OPENAI_API_KEY,OPENAI_BASE_URL, andMODELare correct. Some OpenAI-compatible servers use different model names; setMODELaccordingly.Variable not replaced: Ensure you used
${VAR}or${VAR:-default}syntax in the prompt template.
Conclusion and next steps
You now have:
A structured prompt library in
~/promptsA tiny Bash tool to pick, fill, and run prompts from the terminal
Real examples you can adapt to your workflow
Next steps:
Add your own domain-specific prompts (security reviews, SRE runbooks, migration guides).
Share your library via Git and code review your prompts like any other artifact.
Bake the tool into scripts, pre-commit hooks, or CI to make high-quality outputs repeatable.
Stop reinventing prompts. Start shipping them.