Skip to content
Back to skills

Cf Tools Ai Prompt Test

BSecurity

Send the same prompt to multiple LLM providers and compare outputs side-by-side. Trigger: /cf-tools-ai-prompt-test

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 11, 2026
ai-agentsgoshellbashapi

Works with

  • api

Security analysis

B84/100
  • mediumUses curl or wget to download content
  • criticalSends environment variables or credentials to an external URL

Pro shows the line behind each finding and how to fix it

Scanned November 11, 2026

npx -y skills add pauldx/claudifying --skill cf-tools-ai-prompt-test --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Cf Tools Ai Prompt Test?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Cf Tools Ai Prompt Test
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/pauldx-cf-tools-ai-prompt-test/badge)](https://www.skillsdirectory.com/skills/pauldx-cf-tools-ai-prompt-test)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cf-tools-ai-prompt-test
description: "Send the same prompt to multiple LLM providers and compare outputs side-by-side. Trigger: /cf-tools-ai-prompt-test"
trigger: /cf-tools-ai-prompt-test
version: 1.0.0
---

# /cf-tools-ai-prompt-test

Send one prompt to multiple providers (Anthropic, OpenAI, Ollama) and print a side-by-side comparison with token + estimated cost summary.

> Anthropic and OpenAI calls cost money. Ollama is free (local). The skill prints a cost estimate before issuing remote calls and supports `--dry-run` to skip them.

## Usage

```
/cf-tools-ai-prompt-test "Summarize CAP theorem in 2 sentences"
/cf-tools-ai-prompt-test --providers anthropic,openai --file prompt.md
/cf-tools-ai-prompt-test --providers ollama --models llama3.1,qwen2.5,phi3
/cf-tools-ai-prompt-test --dry-run "What would this cost?"
```

Arguments:
1. `prompt` (positional, optional) — user message
2. `--file <path>` — read prompt from file
3. `--system <text>` — system prompt sent to all providers
4. `--providers <list>` — comma-separated subset of `anthropic,openai,ollama`. Default: all available (env-gated).
5. `--models <list>` — comma-separated override per-provider in order. Default: `claude-opus-4-7,gpt-4o,llama3.1`.
6. `--max-tokens <n>` — default `1024`
7. `--temperature <n>` — default `0.7` (set to `0` for deterministic comparison)
8. `--dry-run` — print plan + cost estimate, skip actual calls
9. `--out <dir>` — save raw responses to `<dir>/<provider>.json` (default: tmp)

## Credentials (env vars; provider is skipped if missing)

```bash
export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..."
# Ollama needs no key — just `ollama serve` running locally
```

## What You Must Do When Invoked

### Step 1 — Resolve provider list

```bash
set +x  # NEVER xtrace — would leak API keys

PROMPT="${PROMPT_TEXT:-$(cat "$PROMPT_FILE")}"

PROVIDERS_REQUESTED="${PROVIDERS:-anthropic,openai,ollama}"
PROVIDERS_AVAILABLE=()
for p in ${PROVIDERS_REQUESTED//,/ }; do
  case "$p" in
    anthropic) [ -n "$ANTHROPIC_API_KEY" ] && PROVIDERS_AVAILABLE+=("anthropic") || echo "skip anthropic (no key)" ;;
    openai)    [ -n "$OPENAI_API_KEY" ]    && PROVIDERS_AVAILABLE+=("openai")    || echo "skip openai (no key)" ;;
    ollama)    curl -sf http://localhost:11434/api/tags -o /dev/null --max-time 1 \
                 && PROVIDERS_AVAILABLE+=("ollama") || echo "skip ollama (not running)" ;;
  esac
done
```

### Step 2 — Cost estimate (rough)

```bash
# Per-million-token prices — UPDATE quarterly
# Anthropic Opus 4.x: $15 in / $75 out
# OpenAI gpt-4o:      $2.50 in / $10 out
# Ollama:             $0
INPUT_TOKENS_EST=$(( $(echo -n "$PROMPT" | wc -c) / 4 ))   # crude: 4 chars/token
OUTPUT_BUDGET="${MAX_TOKENS:-1024}"

echo "## Plan"
echo "Prompt: ~$INPUT_TOKENS_EST input tokens, $OUTPUT_BUDGET output budget"
for p in "${PROVIDERS_AVAILABLE[@]}"; do
  case "$p" in
    anthropic) printf '  %-10s ~$%.4f\n' "$p" "$(awk -v i=$INPUT_TOKENS_EST -v o=$OUTPUT_BUDGET 'BEGIN{print (i*15 + o*75)/1e6}')" ;;
    openai)    printf '  %-10s ~$%.4f\n' "$p" "$(awk -v i=$INPUT_TOKENS_EST -v o=$OUTPUT_BUDGET 'BEGIN{print (i*2.5 + o*10)/1e6}')" ;;
    ollama)    printf '  %-10s $0.0000 (local)\n' "$p" ;;
  esac
done

[ "$DRY_RUN" = "1" ] && { echo "(dry run — no calls made)"; exit 0; }
```

### Step 3 — Issue calls in parallel

```bash
OUT_DIR="${OUT_DIR:-$(mktemp -d -t cf-prompt-test)}"
mkdir -p "$OUT_DIR"

# Anthropic
anthropic_call() {
  curl -sS https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    --data "$(jq -n --arg p "$PROMPT" --arg m "${ANTHROPIC_MODEL:-claude-opus-4-7}" --argjson max "${MAX_TOKENS:-1024}" \
      '{model:$m, max_tokens:$max, messages:[{role:"user", content:$p}]}')" \
    > "$OUT_DIR/anthropic.json"
}

# OpenAI
openai_call() {
  curl -sS https://api.openai.com/v1/chat/completions \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -H "Content-Type: application/json" \
    --data "$(jq -n --arg p "$PROMPT" --arg m "${OPENAI_MODEL:-gpt-4o}" --argjson max "${MAX_TOKENS:-1024}" \
      '{model:$m, max_tokens:$max, messages:[{role:"user", content:$p}]}')" \
    > "$OUT_DIR/openai.json"
}

# Ollama
ollama_call() {
  curl -sS http://localhost:11434/api/generate \
    --data "$(jq -n --arg p "$PROMPT" --arg m "${OLLAMA_MODEL:-llama3.1}" \
      '{model:$m, prompt:$p, stream:false}')" \
    > "$OUT_DIR/ollama.json"
}

# Parallel fan-out
pids=()
for p in "${PROVIDERS_AVAILABLE[@]}"; do
  case "$p" in
    anthropic) anthropic_call & ;;
    openai)    openai_call    & ;;
    ollama)    ollama_call    & ;;
  esac
  pids+=($!)
done
for pid in "${pids[@]}"; do wait $pid; done
```

### Step 4 — Render comparison

```bash
echo
echo "## Results (saved to $OUT_DIR)"
for p in "${PROVIDERS_AVAILABLE[@]}"; do
  echo
  echo "### $p"
  case "$p" in
    anthropic)
      jq -r '"_Model: \(.model)_\n_Tokens: \(.usage.input_tokens) in / \(.usage.output_tokens) out_\n\n\(.content[0].text)"' \
        "$OUT_DIR/anthropic.json" ;;
    openai)
      jq -r '"_Model: \(.model)_\n_Tokens: \(.usage.prompt_tokens) in / \(.usage.completion_tokens) out_\n\n\(.choices[0].message.content)"' \
        "$OUT_DIR/openai.json" ;;
    ollama)
      jq -r '"_Model: \(.model)_\n_Tokens: \(.prompt_eval_count) in / \(.eval_count) out_\n_Latency: \(.total_duration / 1e9 | floor)s_\n\n\(.response)"' \
        "$OUT_DIR/ollama.json" ;;
  esac
done
```

## Expected Response Shapes

Same as the individual provider skills:

- Anthropic: `.content[0].text`, `.usage.{input_tokens,output_tokens}`
- OpenAI: `.choices[0].message.content`, `.usage.{prompt_tokens,completion_tokens,total_tokens}`
- Ollama: `.response`, `.{prompt_eval_count,eval_count,total_duration}`

## Output Contract

```
## Plan
Prompt: ~<N> input tokens, <max> output budget
  anthropic   ~$<cost>
  openai      ~$<cost>
  ollama      $0.0000 (local)

## Results (saved to <dir>)

### anthropic
_Model: claude-opus-4-7_
_Tokens: 42 in / 128 out_

<response text>

### openai
...

### ollama
...
```

## Gotchas

- **Cost surprise on long prompts**: rough estimate is `chars/4`. Real tokenizers vary ±30%. Use `--dry-run` first on big prompts.
- **Apples-to-oranges**: different models have different defaults (temp, system prompts, RLHF style). Set `--temperature 0` for the closest you can get to deterministic comparison.
- **Anthropic Opus is much more expensive than OpenAI gpt-4o** for the same output length. Pick `claude-haiku-4-7` if cost-sensitive.
- **Ollama "tokens" are model-specific** — not directly comparable across model families. Use latency + char count as secondary measures.
- **Streaming not used here**: each provider returns its full response before comparison renders. For very long outputs, this means waiting for the slowest.
- **Rate limits stack**: parallel fan-out can trip provider-side throttles if you have low-tier accounts. Run sequentially on free tier.
- **No retries**: if any provider 5xx's, that cell will be empty. Re-run only that provider rather than the whole battery.
- **API keys never logged**: `set +x` enforced at entry. Raw responses in `$OUT_DIR` may include `id` and `model` but no keys.

## Cross-Platform Notes

- macOS / Linux: `curl` + `jq` standard. Ollama requires local daemon.
- Windows PowerShell: parallel via `Start-Job`. Same JSON shapes.
- CI: provide keys via secrets; pin `--providers` to remote providers (no ollama) and use `--temperature 0` for snapshot tests.

## Verification at install time

- `curl --version`, `jq --version` → present.
- Ollama check via `curl http://localhost:11434/api/tags` (skip cleanly if 404).
- **No real provider calls issued at install** — cost-bearing.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.