|
| 1 | +# Prompt Evaluation System |
| 2 | + |
| 3 | +This module provides tools for benchmarking and comparing different keyword extraction prompts. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The evaluation system works in two stages: |
| 8 | + |
| 9 | +1. **Dataset Generation**: Create ground truth test cases (keywords → user inputs) |
| 10 | +2. **Prompt Evaluation**: Test prompts against the dataset and calculate Jaccard similarity scores |
| 11 | + |
| 12 | +## Quick Start |
| 13 | + |
| 14 | +### 1. Generate Evaluation Dataset |
| 15 | + |
| 16 | +First, create a keywords file with one keyword set per line (comma-separated): |
| 17 | + |
| 18 | +```bash |
| 19 | +# keywords.txt |
| 20 | +transformer, attention mechanism, BERT |
| 21 | +reinforcement learning, Q-learning, DQN |
| 22 | +convolutional neural network, CNN, image classification |
| 23 | +``` |
| 24 | + |
| 25 | +Then generate the dataset: |
| 26 | + |
| 27 | +```bash |
| 28 | +cd backend |
| 29 | +python -m app.llm.evaluation.dataset_generator \ |
| 30 | + --keywords-file keywords.txt \ |
| 31 | + --output evaluation_data/dataset.json |
| 32 | +``` |
| 33 | + |
| 34 | +Note: The default output is `evaluation_data/dataset.json` (directories are created automatically). |
| 35 | + |
| 36 | +This will create the dataset file with test cases containing: |
| 37 | +- `ground_truth_keywords`: The original keywords |
| 38 | +- `user_input`: Generated natural language query |
| 39 | +- `metadata`: Generation info |
| 40 | + |
| 41 | +### 2. Evaluate a Prompt |
| 42 | + |
| 43 | +Create a prompt file (e.g., `my_prompt.txt`): |
| 44 | + |
| 45 | +``` |
| 46 | +You are an expert in academic information retrieval. Extract 5 short search queries... |
| 47 | +``` |
| 48 | + |
| 49 | +Then evaluate it: |
| 50 | + |
| 51 | +```bash |
| 52 | +python -m app.llm.evaluation.prompt_evaluator \ |
| 53 | + --prompt-file my_prompt.txt \ |
| 54 | + --dataset evaluation_data/dataset.json \ |
| 55 | + --output evaluation_results/results.json |
| 56 | +``` |
| 57 | + |
| 58 | +Note: The default output is `evaluation_results/results.json` (directories are created automatically). |
| 59 | + |
| 60 | +The results will include: |
| 61 | +- `mean_jaccard`: Average Jaccard similarity score |
| 62 | +- `std_jaccard`: Standard deviation |
| 63 | +- `min_jaccard` / `max_jaccard`: Score range |
| 64 | +- `per_case_scores`: Detailed results for each test case |
| 65 | + |
| 66 | +## Metrics |
| 67 | + |
| 68 | +**Jaccard Similarity**: Measures overlap between extracted and ground truth keywords |
| 69 | +- Formula: `|A ∩ B| / |A ∪ B|` |
| 70 | +- Range: 0.0 (no overlap) to 1.0 (perfect match) |
| 71 | +- Keywords are normalized (lowercase, stripped) before comparison |
| 72 | + |
| 73 | +## File Structure |
| 74 | + |
| 75 | +``` |
| 76 | +app/llm/evaluation/ |
| 77 | +├── __init__.py |
| 78 | +├── metrics.py # Jaccard similarity calculation |
| 79 | +├── dataset_generator.py # Generate test dataset |
| 80 | +├── prompt_evaluator.py # Evaluate prompts |
| 81 | +└── README.md # This file |
| 82 | +``` |
| 83 | + |
| 84 | +## Example Workflow |
| 85 | + |
| 86 | +```bash |
| 87 | +# 1. Create keywords file |
| 88 | +cat > keywords.txt << EOF |
| 89 | +transformer, attention, BERT |
| 90 | +reinforcement learning, DQN, policy gradient |
| 91 | +CNN, image classification, ResNet |
| 92 | +EOF |
| 93 | + |
| 94 | +# 2. Generate dataset |
| 95 | +python -m app.llm.evaluation.dataset_generator \ |
| 96 | + --keywords-file keywords.txt \ |
| 97 | + --output evaluation/dataset.json \ |
| 98 | + --delay 20.0 |
| 99 | + |
| 100 | +# 3. Evaluate a single prompt |
| 101 | +python -m app.llm.evaluation.prompt_evaluator \ |
| 102 | + --prompt-file app/llm/openai/prompts.py \ |
| 103 | + --dataset dataset.json \ |
| 104 | + --output results_baseline.json \ |
| 105 | + --delay 20.0 |
| 106 | + |
| 107 | +# 4. Evaluate all prompts and compare (RECOMMENDED) |
| 108 | +python -m app.llm.evaluation.evaluate_all_prompts \ |
| 109 | + --prompts-dir app/llm/evaluation/prompts \ |
| 110 | + --dataset evaluation_data/dataset.json \ |
| 111 | + --output-dir evaluation_results \ |
| 112 | + --delay 20.0 \ |
| 113 | + --include-baseline |
| 114 | +``` |
| 115 | + |
| 116 | +## Evaluating Multiple Prompts |
| 117 | + |
| 118 | +The `evaluate_all_prompts.py` script evaluates all prompts in a directory and generates a comparison report: |
| 119 | + |
| 120 | +```bash |
| 121 | +python -m app.llm.evaluation.evaluate_all_prompts \ |
| 122 | + --prompts-dir app/llm/evaluation/prompts \ |
| 123 | + --dataset evaluation_data/dataset.json \ |
| 124 | + --output-dir evaluation_results \ |
| 125 | + --delay 20.0 \ |
| 126 | + --include-baseline |
| 127 | +``` |
| 128 | + |
| 129 | +This will: |
| 130 | +- Evaluate all prompts matching the pattern (default: `prompt_*.txt`) |
| 131 | +- Save individual results for each prompt |
| 132 | +- Generate a comparison report ranking prompts by mean Jaccard score |
| 133 | +- Optionally include the baseline prompt from `app/llm/openai/prompts.py` |
| 134 | + |
| 135 | +## Notes |
| 136 | + |
| 137 | +- Requires `OPENAI_API_KEY` to be set in your environment |
| 138 | +- Dataset generation uses the same OpenAI model as production |
| 139 | +- Evaluation runs sequentially (one test case at a time) |
| 140 | +- Results are saved as JSON for programmatic analysis |
0 commit comments