@botlearn/keyword-extractor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +35 -0
- package/knowledge/anti-patterns.md +74 -0
- package/knowledge/best-practices.md +114 -0
- package/knowledge/domain.md +131 -0
- package/manifest.json +26 -0
- package/package.json +35 -0
- package/skill.md +45 -0
- package/strategies/main.md +113 -0
- package/tests/benchmark.json +476 -0
- package/tests/smoke.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 BotLearn
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @botlearn/keyword-extractor
|
|
2
|
+
|
|
3
|
+
> Semantic-level keyword extraction, topic clustering, and domain-aware term ranking for OpenClaw Agent
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# via npm
|
|
9
|
+
npm install @botlearn/keyword-extractor
|
|
10
|
+
|
|
11
|
+
# via clawhub
|
|
12
|
+
clawhub install @botlearn/keyword-extractor
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Category
|
|
16
|
+
|
|
17
|
+
content-processing
|
|
18
|
+
|
|
19
|
+
## Dependencies
|
|
20
|
+
|
|
21
|
+
None
|
|
22
|
+
|
|
23
|
+
## Files
|
|
24
|
+
|
|
25
|
+
| File | Description |
|
|
26
|
+
|------|-------------|
|
|
27
|
+
| `manifest.json` | Skill metadata and configuration |
|
|
28
|
+
| `skill.md` | Role definition and activation rules |
|
|
29
|
+
| `knowledge/` | Domain knowledge documents |
|
|
30
|
+
| `strategies/` | Behavioral strategy definitions |
|
|
31
|
+
| `tests/` | Smoke and benchmark tests |
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
MIT
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
domain: keyword-extractor
|
|
3
|
+
topic: anti-patterns
|
|
4
|
+
priority: medium
|
|
5
|
+
ttl: 30d
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Keyword Extraction — Anti-Patterns
|
|
9
|
+
|
|
10
|
+
## Extraction Anti-Patterns
|
|
11
|
+
|
|
12
|
+
### 1. Surface-Only Extraction
|
|
13
|
+
- **Problem**: Extracting only explicitly stated words while ignoring implied concepts, synonyms, and latent topics
|
|
14
|
+
- **Symptom**: A text about "convolutional neural networks" yields keywords like "convolutional", "neural", "networks" but misses "deep learning", "image recognition", "computer vision"
|
|
15
|
+
- **Fix**: Apply semantic-level extraction using embeddings to discover implicit topic keywords; use topic modeling to surface latent themes; check that extracted keywords cover at least 80% of the text's identifiable topics
|
|
16
|
+
|
|
17
|
+
### 2. Frequency-Only Ranking
|
|
18
|
+
- **Problem**: Ranking keywords solely by how often they appear, causing common-but-generic terms to dominate
|
|
19
|
+
- **Symptom**: Words like "system", "data", "process", "method" rank highest even though they carry minimal topic-specific information
|
|
20
|
+
- **Fix**: Use TF-IDF or BM25 to discount terms that are frequent across many documents; apply the composite scoring formula from knowledge/best-practices.md that combines statistical, semantic, positional, and domain signals
|
|
21
|
+
|
|
22
|
+
### 3. Over-Extraction (Keyword Flooding)
|
|
23
|
+
- **Problem**: Extracting too many keywords, diluting the signal and overwhelming the consumer of the output
|
|
24
|
+
- **Symptom**: A 300-word paragraph produces 40+ keywords; every noun and adjective is treated as a keyword
|
|
25
|
+
- **Fix**: Apply the optimal keyword count guidelines from knowledge/best-practices.md; enforce primary/secondary/tertiary classification; default to outputting only primary + secondary keywords
|
|
26
|
+
|
|
27
|
+
### 4. Stopword Leakage
|
|
28
|
+
- **Problem**: Stopwords and function words slip through extraction and appear as keywords
|
|
29
|
+
- **Symptom**: Keywords include "the", "however", "various", "also", "including", "such"
|
|
30
|
+
- **Fix**: Apply comprehensive stopword filtering in preprocessing; extend standard stopword lists with domain-specific function words (e.g., "et al.", "respectively", "furthermore" in academic text)
|
|
31
|
+
|
|
32
|
+
### 5. Entity Fragmentation
|
|
33
|
+
- **Problem**: Multi-word named entities are split into individual tokens instead of being preserved as single keyword units
|
|
34
|
+
- **Symptom**: "United Nations" becomes two keywords: "United" and "Nations"; "New York Times" becomes "New", "York", "Times"
|
|
35
|
+
- **Fix**: Run NER before tokenization-based extraction; lock named entity spans as atomic units; apply multi-word expression detection using PMI thresholds
|
|
36
|
+
|
|
37
|
+
## Ranking Anti-Patterns
|
|
38
|
+
|
|
39
|
+
### 6. Ignoring Positional Signals
|
|
40
|
+
- **Problem**: Treating all keyword occurrences equally regardless of where they appear in the text
|
|
41
|
+
- **Symptom**: A term mentioned once in the title is scored lower than a term mentioned three times in footnotes
|
|
42
|
+
- **Fix**: Apply positional weight multipliers from knowledge/best-practices.md; title and heading terms receive 2-3x weight; footnote terms receive 0.5x
|
|
43
|
+
|
|
44
|
+
### 7. Flat Output (No Hierarchy)
|
|
45
|
+
- **Problem**: Returning keywords as an unstructured flat list with no grouping, ranking, or topic assignment
|
|
46
|
+
- **Symptom**: Output is a comma-separated list: "learning, neural, network, training, data, model, accuracy"
|
|
47
|
+
- **Fix**: Always cluster keywords into topic groups; rank within each cluster by score; provide cluster labels and hierarchical structure
|
|
48
|
+
|
|
49
|
+
### 8. Score Opacity
|
|
50
|
+
- **Problem**: Presenting keywords without explaining why they were selected or how they were scored
|
|
51
|
+
- **Symptom**: User receives a list of keywords with no scores, no confidence levels, and no extraction method attribution
|
|
52
|
+
- **Fix**: Include normalized scores (0-100), confidence levels (high/medium/low), and extraction level (lexical/phrasal/semantic) for each keyword
|
|
53
|
+
|
|
54
|
+
## Semantic Anti-Patterns
|
|
55
|
+
|
|
56
|
+
### 9. Synonym Duplication
|
|
57
|
+
- **Problem**: Treating synonyms and abbreviations as separate keywords, inflating keyword count without adding information
|
|
58
|
+
- **Symptom**: Output includes both "artificial intelligence" and "AI", both "natural language processing" and "NLP", both "machine learning" and "ML"
|
|
59
|
+
- **Fix**: Apply semantic deduplication using embedding similarity (threshold > 0.85); merge synonyms under the canonical (most frequent or most specific) form; note alternative forms as aliases
|
|
60
|
+
|
|
61
|
+
### 10. Over-Generalization
|
|
62
|
+
- **Problem**: Replacing specific, informative terms with vague parent categories during taxonomy mapping
|
|
63
|
+
- **Symptom**: "TensorFlow" is generalized to "software"; "BERT" becomes "language model"; "gradient descent" becomes "optimization"
|
|
64
|
+
- **Fix**: Preserve the original specific term as the keyword; use taxonomy categories only as metadata labels, not as replacements; never lose specificity in the primary keyword
|
|
65
|
+
|
|
66
|
+
### 11. Context-Blind Extraction
|
|
67
|
+
- **Problem**: Extracting keywords without considering the document's domain or the user's intent
|
|
68
|
+
- **Symptom**: A legal document's keyword list looks the same as a technical blog post's; domain-specific terms are not prioritized
|
|
69
|
+
- **Fix**: Detect the document domain in preprocessing; boost domain-specific terminology using DomScore; suppress cross-domain generic terms that are not informative within the detected domain
|
|
70
|
+
|
|
71
|
+
### 12. Negation Blindness
|
|
72
|
+
- **Problem**: Extracting keywords from negated or hypothetical statements as if they were affirmative
|
|
73
|
+
- **Symptom**: "This approach does NOT use reinforcement learning" produces "reinforcement learning" as a positive keyword
|
|
74
|
+
- **Fix**: Detect negation patterns ("not", "no", "without", "lacks", "unlike") and either exclude negated terms or flag them as "negated-context" keywords with reduced scores
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
domain: keyword-extractor
|
|
3
|
+
topic: multi-level-extraction-and-scoring
|
|
4
|
+
priority: high
|
|
5
|
+
ttl: 30d
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Keyword Extraction — Best Practices
|
|
9
|
+
|
|
10
|
+
## Multi-Level Extraction
|
|
11
|
+
|
|
12
|
+
### 1. Lexical Level (Surface Terms)
|
|
13
|
+
- Extract individual tokens after stopword removal and normalization
|
|
14
|
+
- Apply lemmatization to group inflected forms: "running", "runs", "ran" -> "run"
|
|
15
|
+
- Preserve case for proper nouns and acronyms: "API", "JavaScript", "NATO"
|
|
16
|
+
- Retain domain-specific compound terms: "machine-learning", "open-source"
|
|
17
|
+
|
|
18
|
+
### 2. Phrasal Level (Multi-Word Expressions)
|
|
19
|
+
- Extract n-grams (bigrams, trigrams) that co-occur more frequently than expected by chance
|
|
20
|
+
- Use Pointwise Mutual Information (PMI) to identify statistically significant phrases:
|
|
21
|
+
- PMI(x, y) = log2(P(x, y) / (P(x) * P(y)))
|
|
22
|
+
- PMI > 3.0 indicates a meaningful phrase
|
|
23
|
+
- Preserve noun phrases identified by POS patterns: ADJ* NOUN+ (e.g., "deep neural network")
|
|
24
|
+
- Named entities are automatically phrasal keywords — never split them
|
|
25
|
+
|
|
26
|
+
### 3. Semantic Level (Latent Concepts)
|
|
27
|
+
- Identify concepts implied but not explicitly stated
|
|
28
|
+
- Example: a text discussing "gradient descent", "loss function", and "epochs" implies the concept "model training"
|
|
29
|
+
- Use embedding similarity to surface these implicit topic markers
|
|
30
|
+
- Assign lower confidence scores to inferred concepts vs. explicit terms
|
|
31
|
+
|
|
32
|
+
## Contextual Scoring
|
|
33
|
+
|
|
34
|
+
### Composite Score Formula
|
|
35
|
+
```
|
|
36
|
+
Score(keyword) = w1*StatScore + w2*SemScore + w3*PosScore + w4*DomScore
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
| Component | Weight (w) | Description |
|
|
40
|
+
|-----------|-----------|-------------|
|
|
41
|
+
| StatScore | 0.30 | TF-IDF or BM25 statistical significance |
|
|
42
|
+
| SemScore | 0.30 | Semantic centrality in the keyword graph |
|
|
43
|
+
| PosScore | 0.20 | Positional weight (title > first paragraph > body > footnotes) |
|
|
44
|
+
| DomScore | 0.20 | Domain relevance — how central is this term to the detected domain? |
|
|
45
|
+
|
|
46
|
+
### Positional Weight Table
|
|
47
|
+
|
|
48
|
+
| Position | Weight Multiplier | Rationale |
|
|
49
|
+
|----------|------------------|-----------|
|
|
50
|
+
| Title / Heading | 3.0x | Titles contain the most important terms |
|
|
51
|
+
| First paragraph / Abstract | 2.0x | Introductions state the core topic |
|
|
52
|
+
| Section headings | 2.5x | Sub-topics are signaled by headings |
|
|
53
|
+
| Body text | 1.0x | Baseline weight |
|
|
54
|
+
| Lists and enumerations | 1.5x | Structured content highlights key items |
|
|
55
|
+
| Captions and labels | 1.2x | Annotated content carries keyword signal |
|
|
56
|
+
| Footnotes and references | 0.5x | Supporting material, lower priority |
|
|
57
|
+
|
|
58
|
+
### Score Normalization
|
|
59
|
+
- Normalize final scores to 0-100 scale for readability
|
|
60
|
+
- Top keyword = 100; all others scaled proportionally
|
|
61
|
+
- Report scores rounded to 1 decimal place
|
|
62
|
+
|
|
63
|
+
## Cluster Formation
|
|
64
|
+
|
|
65
|
+
### Topic Cluster Construction
|
|
66
|
+
1. Compute pairwise semantic similarity between all extracted keywords
|
|
67
|
+
2. Apply agglomerative clustering with a similarity threshold of 0.65
|
|
68
|
+
3. Name each cluster using the highest-scoring keyword within the cluster
|
|
69
|
+
4. Limit cluster count based on text length (see knowledge/domain.md, Topic Modeling section)
|
|
70
|
+
|
|
71
|
+
### Cluster Quality Checks
|
|
72
|
+
- **Minimum size**: Clusters with only 1 keyword should be merged into the nearest cluster or flagged as standalone terms
|
|
73
|
+
- **Maximum size**: Clusters with 15+ keywords should be examined for sub-topic splitting
|
|
74
|
+
- **Coherence**: All keywords in a cluster should have pairwise similarity > 0.5; outliers should be reassigned
|
|
75
|
+
- **Coverage**: The union of all cluster keywords should cover at least 80% of the text's core content
|
|
76
|
+
|
|
77
|
+
### Cluster Hierarchy
|
|
78
|
+
- Support 2-level hierarchy: primary clusters (broad topics) and sub-clusters (specific aspects)
|
|
79
|
+
- Example:
|
|
80
|
+
- Primary: "Machine Learning"
|
|
81
|
+
- Sub-cluster: "Neural Networks" (deep learning, CNN, RNN, transformer)
|
|
82
|
+
- Sub-cluster: "Training" (gradient descent, loss function, optimizer, epoch)
|
|
83
|
+
- Sub-cluster: "Evaluation" (accuracy, F1, precision, recall, ROC)
|
|
84
|
+
|
|
85
|
+
## Optimal Keyword Count
|
|
86
|
+
|
|
87
|
+
| Text Length | Recommended Keywords | Max Topics |
|
|
88
|
+
|------------|---------------------|------------|
|
|
89
|
+
| < 200 words | 5-8 | 2-3 |
|
|
90
|
+
| 200-500 words | 8-12 | 3-5 |
|
|
91
|
+
| 500-1500 words | 12-20 | 4-7 |
|
|
92
|
+
| 1500-5000 words | 15-30 | 5-10 |
|
|
93
|
+
| 5000+ words | 20-40 | 7-12 |
|
|
94
|
+
|
|
95
|
+
### Primary vs. Secondary Keywords
|
|
96
|
+
- **Primary keywords** (top 30%): Directly represent the text's main thesis or topic — always include in output
|
|
97
|
+
- **Secondary keywords** (next 40%): Supporting concepts that elaborate on primary topics — include by default
|
|
98
|
+
- **Tertiary keywords** (bottom 30%): Peripheral or contextual terms — include only when comprehensive extraction is requested
|
|
99
|
+
|
|
100
|
+
## Output Format Best Practices
|
|
101
|
+
|
|
102
|
+
### Structured Output
|
|
103
|
+
Each keyword entry should include:
|
|
104
|
+
- **term**: The keyword or phrase
|
|
105
|
+
- **score**: Normalized relevance score (0-100)
|
|
106
|
+
- **level**: lexical / phrasal / semantic
|
|
107
|
+
- **cluster**: Topic cluster assignment
|
|
108
|
+
- **type**: entity type (if NER-detected) or "concept"
|
|
109
|
+
- **confidence**: Extraction confidence (high / medium / low)
|
|
110
|
+
|
|
111
|
+
### Grouping
|
|
112
|
+
- Present keywords grouped by cluster, not as a flat list
|
|
113
|
+
- Within each cluster, sort by score descending
|
|
114
|
+
- Provide a cluster summary sentence describing the sub-topic
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
domain: keyword-extractor
|
|
3
|
+
topic: extraction-methods-and-theory
|
|
4
|
+
priority: high
|
|
5
|
+
ttl: 30d
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Keyword Extraction — Methods, Techniques & Theory
|
|
9
|
+
|
|
10
|
+
## 1. TF-IDF (Term Frequency-Inverse Document Frequency)
|
|
11
|
+
|
|
12
|
+
### Core Formula
|
|
13
|
+
- **TF(t, d)** = (Number of times term t appears in document d) / (Total number of terms in d)
|
|
14
|
+
- **IDF(t, D)** = log(Total number of documents in corpus D / Number of documents containing t)
|
|
15
|
+
- **TF-IDF(t, d, D)** = TF(t, d) x IDF(t, D)
|
|
16
|
+
|
|
17
|
+
### Interpretation
|
|
18
|
+
- High TF-IDF = term is frequent in the document but rare across the corpus — strong keyword signal
|
|
19
|
+
- Low TF-IDF = term is either rare in the document or common across many documents — weak signal
|
|
20
|
+
- Zero TF-IDF = term does not appear in the document
|
|
21
|
+
|
|
22
|
+
### Variants
|
|
23
|
+
- **Sublinear TF**: `1 + log(TF)` — dampens the effect of high-frequency terms
|
|
24
|
+
- **Smoothed IDF**: `log(1 + N/df)` — prevents division by zero for new terms
|
|
25
|
+
- **BM25 weighting**: Adds document length normalization — preferred for variable-length texts
|
|
26
|
+
|
|
27
|
+
### Single-Document Application
|
|
28
|
+
When no corpus is available (single-document extraction):
|
|
29
|
+
- Use a general-purpose reference corpus IDF (e.g., Wikipedia, Common Crawl frequencies)
|
|
30
|
+
- Alternatively, use sentence-level TF-IDF: treat each sentence as a "document" within the text
|
|
31
|
+
- Compare term frequencies against expected frequencies from domain language models
|
|
32
|
+
|
|
33
|
+
## 2. Named Entity Recognition (NER)
|
|
34
|
+
|
|
35
|
+
### Entity Categories for Keyword Extraction
|
|
36
|
+
| Entity Type | Examples | Keyword Priority |
|
|
37
|
+
|------------|---------|-----------------|
|
|
38
|
+
| PERSON | "Elon Musk", "Ada Lovelace" | High — often central to topic |
|
|
39
|
+
| ORGANIZATION | "OpenAI", "United Nations" | High — key actors or subjects |
|
|
40
|
+
| LOCATION | "Silicon Valley", "European Union" | Medium — contextual anchors |
|
|
41
|
+
| TECHNOLOGY | "Kubernetes", "GPT-4", "React" | High — core in technical texts |
|
|
42
|
+
| EVENT | "COP28", "Black Friday" | Medium-High — temporal anchors |
|
|
43
|
+
| CONCEPT | "machine learning", "supply chain" | High — abstract topic markers |
|
|
44
|
+
| PRODUCT | "iPhone 15", "Tesla Model S" | Medium — specific references |
|
|
45
|
+
| DATE/TIME | "Q3 2024", "2023 fiscal year" | Low — usually metadata, not keywords |
|
|
46
|
+
|
|
47
|
+
### NER as Keyword Signal
|
|
48
|
+
- Named entities are almost always keywords — they carry high information density
|
|
49
|
+
- Multi-word entities (e.g., "natural language processing") should be extracted as single keyword units, not split into individual words
|
|
50
|
+
- Entity type provides automatic categorization for topic clustering
|
|
51
|
+
|
|
52
|
+
### Entity Disambiguation
|
|
53
|
+
- "Apple" (company) vs "apple" (fruit) — resolve using surrounding context
|
|
54
|
+
- "Python" (language) vs "python" (snake) — use co-occurring terms as disambiguation signals
|
|
55
|
+
- When ambiguous, include the entity with its most probable interpretation noted
|
|
56
|
+
|
|
57
|
+
## 3. Semantic Similarity & Embeddings
|
|
58
|
+
|
|
59
|
+
### Concept
|
|
60
|
+
- Represent words/phrases as dense vectors in a high-dimensional space
|
|
61
|
+
- Semantically similar terms have vectors that are close together (high cosine similarity)
|
|
62
|
+
- Enables discovery of keywords that are conceptually important but may not appear frequently
|
|
63
|
+
|
|
64
|
+
### Applications to Keyword Extraction
|
|
65
|
+
|
|
66
|
+
#### Semantic Deduplication
|
|
67
|
+
- "machine learning" and "ML" — cosine similarity > 0.9 → merge as single keyword
|
|
68
|
+
- "artificial intelligence" and "AI" — same concept, different surface forms
|
|
69
|
+
- Group synonyms and abbreviations under a canonical keyword
|
|
70
|
+
|
|
71
|
+
#### Concept Expansion
|
|
72
|
+
- A text about "neural networks" likely also relates to "deep learning", "backpropagation", "gradient descent"
|
|
73
|
+
- Use embedding proximity to identify implicit keywords not explicitly stated in the text
|
|
74
|
+
- Threshold: cosine similarity > 0.7 for concept expansion candidates
|
|
75
|
+
|
|
76
|
+
#### Centrality-Based Ranking
|
|
77
|
+
- Build a keyword graph where edge weights = semantic similarity between terms
|
|
78
|
+
- Keywords with high graph centrality (many strong connections) are core topics
|
|
79
|
+
- Peripheral keywords (few weak connections) are supporting or tangential
|
|
80
|
+
|
|
81
|
+
### Embedding Models for Keyword Tasks
|
|
82
|
+
| Model Type | Best For | Trade-off |
|
|
83
|
+
|-----------|---------|-----------|
|
|
84
|
+
| Word-level (Word2Vec, GloVe) | Individual term similarity | Fast, but misses phrase-level meaning |
|
|
85
|
+
| Sentence-level (SBERT, E5) | Phrase and concept similarity | Better semantics, moderate speed |
|
|
86
|
+
| Document-level (Doc2Vec) | Overall topic similarity | Good for clustering, less granular |
|
|
87
|
+
|
|
88
|
+
## 4. Topic Modeling
|
|
89
|
+
|
|
90
|
+
### Latent Topic Discovery
|
|
91
|
+
- Discover hidden thematic structures that may not be obvious from individual keywords
|
|
92
|
+
- Maps documents to a mixture of topics; maps topics to distributions over words
|
|
93
|
+
|
|
94
|
+
### LDA (Latent Dirichlet Allocation)
|
|
95
|
+
- Probabilistic model: each document is a mixture of K topics
|
|
96
|
+
- Each topic is a distribution over vocabulary terms
|
|
97
|
+
- Top terms per topic become topic-level keywords
|
|
98
|
+
- Hyperparameters: K (number of topics), alpha (document-topic density), beta (topic-word density)
|
|
99
|
+
|
|
100
|
+
### Topic-Keyword Relationship
|
|
101
|
+
- Topic model outputs complement TF-IDF extraction:
|
|
102
|
+
- TF-IDF finds **statistically distinctive** terms
|
|
103
|
+
- Topic modeling finds **thematically coherent** term groups
|
|
104
|
+
- Use topic assignments to cluster TF-IDF keywords into meaningful groups
|
|
105
|
+
|
|
106
|
+
### Dynamic Topic Allocation
|
|
107
|
+
- For short texts (< 500 words): 2-4 topics maximum
|
|
108
|
+
- For medium texts (500-2000 words): 3-7 topics
|
|
109
|
+
- For long texts (2000+ words): 5-12 topics
|
|
110
|
+
- IF topics overlap significantly (shared top terms > 50%) THEN reduce K
|
|
111
|
+
|
|
112
|
+
## 5. Domain Taxonomy Mapping
|
|
113
|
+
|
|
114
|
+
### Purpose
|
|
115
|
+
- Map extracted keywords to standardized category hierarchies
|
|
116
|
+
- Provides consistent labeling across different texts in the same domain
|
|
117
|
+
- Enables cross-document keyword comparison and aggregation
|
|
118
|
+
|
|
119
|
+
### Common Taxonomies
|
|
120
|
+
| Domain | Taxonomy | Example Path |
|
|
121
|
+
|--------|----------|-------------|
|
|
122
|
+
| Technology | ACM Computing Classification | Computing > AI > Machine Learning > Deep Learning |
|
|
123
|
+
| Science | Library of Congress Subject Headings | Science > Computer Science > Algorithms |
|
|
124
|
+
| Business | NAICS Industry Codes | Information > Software Publishers |
|
|
125
|
+
| Academic | MESH (Medical), JEL (Economics) | Domain-specific controlled vocabularies |
|
|
126
|
+
|
|
127
|
+
### Mapping Strategy
|
|
128
|
+
1. Extract raw keywords from text
|
|
129
|
+
2. For each keyword, find the closest match in the domain taxonomy (exact match > partial match > semantic match)
|
|
130
|
+
3. Assign the taxonomy path as metadata to the keyword
|
|
131
|
+
4. IF no taxonomy match exists THEN flag as "uncategorized" and suggest the nearest taxonomy node
|
package/manifest.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@botlearn/keyword-extractor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Semantic-level keyword extraction, topic clustering, and domain-aware term ranking for OpenClaw Agent",
|
|
5
|
+
"category": "content-processing",
|
|
6
|
+
"author": "BotLearn",
|
|
7
|
+
"benchmarkDimension": "content-understanding",
|
|
8
|
+
"expectedImprovement": 40,
|
|
9
|
+
"dependencies": {},
|
|
10
|
+
"compatibility": {
|
|
11
|
+
"openclaw": ">=0.5.0"
|
|
12
|
+
},
|
|
13
|
+
"files": {
|
|
14
|
+
"skill": "skill.md",
|
|
15
|
+
"knowledge": [
|
|
16
|
+
"knowledge/domain.md",
|
|
17
|
+
"knowledge/best-practices.md",
|
|
18
|
+
"knowledge/anti-patterns.md"
|
|
19
|
+
],
|
|
20
|
+
"strategies": [
|
|
21
|
+
"strategies/main.md"
|
|
22
|
+
],
|
|
23
|
+
"smokeTest": "tests/smoke.json",
|
|
24
|
+
"benchmark": "tests/benchmark.json"
|
|
25
|
+
}
|
|
26
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@botlearn/keyword-extractor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Semantic-level keyword extraction, topic clustering, and domain-aware term ranking for OpenClaw Agent",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "manifest.json",
|
|
7
|
+
"files": [
|
|
8
|
+
"manifest.json",
|
|
9
|
+
"skill.md",
|
|
10
|
+
"knowledge/",
|
|
11
|
+
"strategies/",
|
|
12
|
+
"tests/",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"botlearn",
|
|
17
|
+
"openclaw",
|
|
18
|
+
"skill",
|
|
19
|
+
"content-processing"
|
|
20
|
+
],
|
|
21
|
+
"author": "BotLearn",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/readai-team/botlearn-awesome-skills.git",
|
|
26
|
+
"directory": "packages/skills/keyword-extractor"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/readai-team/botlearn-awesome-skills/tree/main/packages/skills/keyword-extractor",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/readai-team/botlearn-awesome-skills/issues"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
}
|
|
35
|
+
}
|
package/skill.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: keyword-extractor
|
|
3
|
+
role: Keyword Extraction Specialist
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
triggers:
|
|
6
|
+
- "extract keywords"
|
|
7
|
+
- "key terms"
|
|
8
|
+
- "topic extraction"
|
|
9
|
+
- "keyword analysis"
|
|
10
|
+
- "find keywords"
|
|
11
|
+
- "identify topics"
|
|
12
|
+
- "extract key phrases"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Role
|
|
16
|
+
|
|
17
|
+
You are a Keyword Extraction Specialist. When activated, you analyze text at multiple linguistic levels to extract semantically meaningful keywords, cluster them into coherent topics, and rank them by relevance, covering both surface-level terms and deep semantic concepts to achieve 90%+ topic coverage.
|
|
18
|
+
|
|
19
|
+
# Capabilities
|
|
20
|
+
|
|
21
|
+
1. Extract keywords at multiple levels: lexical (individual terms), phrasal (multi-word expressions), and semantic (latent concepts inferred from context)
|
|
22
|
+
2. Apply statistical methods (TF-IDF, co-occurrence analysis) and semantic similarity to identify high-signal terms beyond simple frequency counting
|
|
23
|
+
3. Recognize named entities (people, organizations, locations, technologies) and classify them as domain-specific keywords
|
|
24
|
+
4. Cluster related keywords into coherent topic groups using semantic proximity and co-occurrence patterns
|
|
25
|
+
5. Rank keywords by composite scoring that combines statistical significance, semantic centrality, positional weight, and domain relevance
|
|
26
|
+
6. Contextualize extracted keywords against domain taxonomies to map terms to standardized topic hierarchies
|
|
27
|
+
|
|
28
|
+
# Constraints
|
|
29
|
+
|
|
30
|
+
1. Never rely solely on term frequency to rank keywords — always incorporate semantic and positional signals
|
|
31
|
+
2. Never extract stopwords, boilerplate phrases, or formatting artifacts as keywords
|
|
32
|
+
3. Never return an unranked flat list — always provide scored, ordered results with topic cluster assignments
|
|
33
|
+
4. Always distinguish between primary keywords (core to the text's thesis) and secondary keywords (supporting concepts)
|
|
34
|
+
5. Always preserve the original semantic intent — do not generalize specific terms into vague categories without retaining the original term
|
|
35
|
+
6. Never exceed the optimal keyword density for the text length — follow the guidelines in knowledge/best-practices.md
|
|
36
|
+
|
|
37
|
+
# Activation
|
|
38
|
+
|
|
39
|
+
WHEN the user requests keyword extraction, topic identification, or key term analysis:
|
|
40
|
+
1. Preprocess the input text following strategies/main.md Step 1
|
|
41
|
+
2. Apply multi-level extraction using knowledge/domain.md techniques (TF-IDF, NER, semantic similarity)
|
|
42
|
+
3. Cluster and rank keywords following strategies/main.md Steps 2-4
|
|
43
|
+
4. Contextualize results against domain taxonomy using knowledge/best-practices.md
|
|
44
|
+
5. Verify output against knowledge/anti-patterns.md to avoid common extraction mistakes
|
|
45
|
+
6. Output ranked keywords with scores, cluster assignments, and domain context
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
strategy: keyword-extractor
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
steps: 5
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Keyword Extraction Strategy
|
|
8
|
+
|
|
9
|
+
## Step 1: Preprocessing & Domain Detection
|
|
10
|
+
- Receive the input text and determine its **length**, **structure** (plain text / structured document / code), and **language**
|
|
11
|
+
- Detect the document domain by analyzing high-frequency terms and named entities against known domain vocabularies:
|
|
12
|
+
- IF technical terms dominate (API, function, deploy) THEN domain = "technology"
|
|
13
|
+
- IF financial terms dominate (revenue, equity, margin) THEN domain = "finance"
|
|
14
|
+
- IF medical terms dominate (diagnosis, treatment, symptom) THEN domain = "healthcare"
|
|
15
|
+
- IF no clear domain signal THEN domain = "general"
|
|
16
|
+
- Normalize the text:
|
|
17
|
+
- Convert to consistent Unicode encoding (NFC normalization)
|
|
18
|
+
- Preserve original casing for NER but create a lowercased copy for statistical analysis
|
|
19
|
+
- Remove boilerplate elements: headers, footers, navigation text, disclaimers, copyright notices
|
|
20
|
+
- Segment into sentences for positional analysis
|
|
21
|
+
- Build a stopword filter:
|
|
22
|
+
- Start with standard stopword list (language-specific)
|
|
23
|
+
- EXTEND with domain-specific function words (e.g., "et al.", "ibid." for academic; "herein", "whereas" for legal)
|
|
24
|
+
- Never include domain-specific technical terms in the stopword list
|
|
25
|
+
- Identify text structure:
|
|
26
|
+
- Map title, headings, paragraphs, lists, captions, footnotes
|
|
27
|
+
- Assign positional weight multipliers from knowledge/best-practices.md
|
|
28
|
+
|
|
29
|
+
## Step 2: Multi-Level Extraction
|
|
30
|
+
- **Lexical extraction**:
|
|
31
|
+
- Tokenize the text and remove stopwords
|
|
32
|
+
- Apply lemmatization to group inflected forms
|
|
33
|
+
- Calculate TF-IDF scores for each unique term using knowledge/domain.md formulas
|
|
34
|
+
- IF no reference corpus is available THEN use sentence-level TF-IDF (each sentence = one document)
|
|
35
|
+
- Retain terms with TF-IDF score above the 60th percentile
|
|
36
|
+
- **Phrasal extraction**:
|
|
37
|
+
- Extract bigrams and trigrams using a sliding window
|
|
38
|
+
- Score multi-word expressions using PMI (retain PMI > 3.0)
|
|
39
|
+
- Apply POS pattern matching for noun phrases: (ADJ)* (NOUN)+
|
|
40
|
+
- Merge overlapping n-grams into the longest meaningful phrase
|
|
41
|
+
- **Named entity extraction**:
|
|
42
|
+
- Run NER to identify PERSON, ORGANIZATION, LOCATION, TECHNOLOGY, EVENT, CONCEPT, PRODUCT entities
|
|
43
|
+
- Lock entity spans as atomic keyword units — do not split
|
|
44
|
+
- Assign entity type metadata to each extracted entity keyword
|
|
45
|
+
- **Semantic extraction**:
|
|
46
|
+
- Generate embeddings for all candidate keywords
|
|
47
|
+
- Identify implicit concepts by finding high-centrality nodes in the keyword similarity graph
|
|
48
|
+
- IF a concept is implied by 3+ explicit keywords (similarity > 0.7) but not stated THEN add as a semantic-level keyword with confidence = "medium"
|
|
49
|
+
- Check for negation context: IF keyword appears in a negated clause THEN flag as "negated" and reduce score by 50%
|
|
50
|
+
|
|
51
|
+
## Step 3: Clustering & Topic Assignment
|
|
52
|
+
- Build a keyword similarity matrix using embedding cosine similarity
|
|
53
|
+
- Apply agglomerative clustering with similarity threshold 0.65:
|
|
54
|
+
- Each keyword starts as its own cluster
|
|
55
|
+
- Iteratively merge the two most similar clusters until no pair exceeds the threshold
|
|
56
|
+
- Post-process clusters:
|
|
57
|
+
- IF cluster size = 1 AND keyword score < 50 THEN merge into the nearest cluster
|
|
58
|
+
- IF cluster size > 15 THEN attempt to split into sub-clusters at threshold 0.75
|
|
59
|
+
- IF two clusters share > 50% of their top-5 keywords THEN merge them
|
|
60
|
+
- Name each cluster:
|
|
61
|
+
- Primary label = highest-scoring keyword in the cluster
|
|
62
|
+
- Secondary label = second-highest-scoring keyword (provides disambiguation)
|
|
63
|
+
- Assign topic hierarchy:
|
|
64
|
+
- Map cluster labels to domain taxonomy paths from knowledge/domain.md
|
|
65
|
+
- IF taxonomy match confidence < 0.5 THEN label as "uncategorized" with nearest taxonomy suggestion
|
|
66
|
+
- Validate coverage:
|
|
67
|
+
- Compute what percentage of the text's sentences contain at least one keyword from any cluster
|
|
68
|
+
- IF coverage < 80% THEN re-examine uncovered sentences for missed keywords and add them
|
|
69
|
+
|
|
70
|
+
## Step 4: Ranking & Scoring
|
|
71
|
+
- Compute the composite score for each keyword using the formula from knowledge/best-practices.md:
|
|
72
|
+
```
|
|
73
|
+
Score(keyword) = 0.30*StatScore + 0.30*SemScore + 0.20*PosScore + 0.20*DomScore
|
|
74
|
+
```
|
|
75
|
+
- **StatScore**: TF-IDF normalized to 0-1 range
|
|
76
|
+
- **SemScore**: Graph centrality score (eigenvector centrality) normalized to 0-1
|
|
77
|
+
- **PosScore**: Maximum positional weight multiplier for any occurrence of the keyword
|
|
78
|
+
- **DomScore**: 1.0 if the keyword matches a domain taxonomy term, 0.5 if partial match, 0.2 if no match
|
|
79
|
+
- Normalize all scores to 0-100 scale (top keyword = 100)
|
|
80
|
+
- Classify keywords:
|
|
81
|
+
- **Primary** (score >= 70): Core topic keywords — always included in output
|
|
82
|
+
- **Secondary** (score 40-69): Supporting concepts — included by default
|
|
83
|
+
- **Tertiary** (score < 40): Peripheral terms — included only on request
|
|
84
|
+
- Apply semantic deduplication:
|
|
85
|
+
- IF two keywords have embedding similarity > 0.85 THEN merge under the more specific or more frequent form
|
|
86
|
+
- Preserve the merged term as an alias in the output
|
|
87
|
+
- Re-rank within each cluster by score descending
|
|
88
|
+
- Verify keyword count against guidelines from knowledge/best-practices.md:
|
|
89
|
+
- IF count exceeds the recommended maximum THEN prune lowest-scoring tertiary keywords
|
|
90
|
+
- IF count is below the recommended minimum THEN lower the extraction threshold and re-extract
|
|
91
|
+
|
|
92
|
+
## Step 5: Domain Contextualization & Output
|
|
93
|
+
- For each keyword, enrich with domain context:
|
|
94
|
+
- Map to taxonomy path (if available)
|
|
95
|
+
- Note relationships to other keywords: "broader than", "narrower than", "related to"
|
|
96
|
+
- IF the keyword is a named entity THEN include entity type
|
|
97
|
+
- Assemble structured output:
|
|
98
|
+
- Group keywords by topic cluster
|
|
99
|
+
- Within each cluster, provide:
|
|
100
|
+
- **Cluster label** and taxonomy path
|
|
101
|
+
- **Cluster summary**: One sentence describing the sub-topic
|
|
102
|
+
- **Keywords**: Ordered by score, each with: term, score, level (lexical/phrasal/semantic), type, confidence
|
|
103
|
+
- After all clusters, provide:
|
|
104
|
+
- **Coverage metric**: Percentage of text content addressed by extracted keywords
|
|
105
|
+
- **Keyword count**: Total primary / secondary / tertiary breakdown
|
|
106
|
+
- SELF-CHECK against knowledge/anti-patterns.md:
|
|
107
|
+
- Are there any stopwords in the output? IF yes THEN remove
|
|
108
|
+
- Are any named entities fragmented? IF yes THEN reassemble
|
|
109
|
+
- Are there synonym duplicates? IF yes THEN merge
|
|
110
|
+
- Is the output a flat list without clustering? IF yes THEN re-cluster
|
|
111
|
+
- Are scores included for all keywords? IF no THEN add scores
|
|
112
|
+
- Is coverage below 80%? IF yes THEN loop back to Step 2 with lower thresholds
|
|
113
|
+
- IF any check fails THEN fix the issue before presenting output
|
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.0.1",
|
|
3
|
+
"dimension": "content-understanding",
|
|
4
|
+
"tasks": [
|
|
5
|
+
{
|
|
6
|
+
"id": "bench-easy-01",
|
|
7
|
+
"difficulty": "easy",
|
|
8
|
+
"description": "Extract keywords from a short product description",
|
|
9
|
+
"input": "Extract the key terms from this product description:\n\nThe Sony WH-1000XM5 wireless headphones feature industry-leading noise cancellation powered by two processors and eight microphones. With 30-hour battery life, multipoint Bluetooth connection, and speak-to-chat technology, these over-ear headphones deliver exceptional audio quality through 30mm carbon fiber composite drivers. Available in black, silver, and midnight blue.",
|
|
10
|
+
"rubric": [
|
|
11
|
+
{
|
|
12
|
+
"criterion": "Keyword Completeness",
|
|
13
|
+
"weight": 0.4,
|
|
14
|
+
"scoring": {
|
|
15
|
+
"5": "Extracts product name (Sony WH-1000XM5), key features (noise cancellation, multipoint Bluetooth, speak-to-chat), specs (30-hour battery, 30mm drivers, carbon fiber), and category (wireless headphones, over-ear)",
|
|
16
|
+
"3": "Extracts the product name and major features but misses technical specs or category terms",
|
|
17
|
+
"1": "Extracts only 2-3 obvious terms",
|
|
18
|
+
"0": "Fails to identify relevant keywords"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"criterion": "Entity Recognition",
|
|
23
|
+
"weight": 0.3,
|
|
24
|
+
"scoring": {
|
|
25
|
+
"5": "Correctly identifies Sony as ORGANIZATION, WH-1000XM5 as PRODUCT, Bluetooth as TECHNOLOGY; preserves multi-word entities intact",
|
|
26
|
+
"3": "Identifies some entities but fragments multi-word names or misclassifies types",
|
|
27
|
+
"1": "No entity recognition — treats all terms as generic keywords",
|
|
28
|
+
"0": "Fragments named entities into meaningless tokens"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"criterion": "Ranking Accuracy",
|
|
33
|
+
"weight": 0.3,
|
|
34
|
+
"scoring": {
|
|
35
|
+
"5": "Product name and primary differentiators (noise cancellation) ranked highest; color options and generic terms ranked lowest",
|
|
36
|
+
"3": "Reasonable ranking but some feature terms are over- or under-weighted",
|
|
37
|
+
"1": "No meaningful ranking distinction",
|
|
38
|
+
"0": "Generic terms ranked above specific product features"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"expectedScoreWithout": 40,
|
|
43
|
+
"expectedScoreWith": 80
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": "bench-easy-02",
|
|
47
|
+
"difficulty": "easy",
|
|
48
|
+
"description": "Extract keywords from a news headline and summary",
|
|
49
|
+
"input": "Extract keywords from this news summary:\n\nThe European Central Bank held interest rates steady at 4.5% on Thursday, signaling that rate cuts could begin in June if inflation continues to fall toward the 2% target. ECB President Christine Lagarde noted that wage growth is moderating and the eurozone economy shows signs of bottoming out after a period of stagnation.",
|
|
50
|
+
"rubric": [
|
|
51
|
+
{
|
|
52
|
+
"criterion": "Topic Identification",
|
|
53
|
+
"weight": 0.4,
|
|
54
|
+
"scoring": {
|
|
55
|
+
"5": "Identifies core topics: monetary policy, interest rates, inflation, eurozone economy; extracts key entities: ECB, Christine Lagarde, European Central Bank",
|
|
56
|
+
"3": "Identifies main topic (interest rates) but misses supporting economic concepts",
|
|
57
|
+
"1": "Extracts generic financial terms without capturing the specific topic",
|
|
58
|
+
"0": "Fails to identify the article's subject"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"criterion": "Specificity",
|
|
63
|
+
"weight": 0.3,
|
|
64
|
+
"scoring": {
|
|
65
|
+
"5": "Extracts specific values and terms: 4.5%, 2% target, rate cuts, wage growth, stagnation; preserves numeric context",
|
|
66
|
+
"3": "Extracts key terms but loses specific values and quantitative context",
|
|
67
|
+
"1": "Only general terms like 'economy' and 'bank'",
|
|
68
|
+
"0": "No domain-specific terms extracted"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"criterion": "Cluster Coherence",
|
|
73
|
+
"weight": 0.3,
|
|
74
|
+
"scoring": {
|
|
75
|
+
"5": "Groups into logical clusters: Monetary Policy (interest rates, rate cuts, ECB), Economic Indicators (inflation, wage growth, stagnation), Entities (ECB, Lagarde, eurozone)",
|
|
76
|
+
"3": "Some grouping present but clusters mix unrelated concepts",
|
|
77
|
+
"1": "No clustering — flat keyword list",
|
|
78
|
+
"0": "Incoherent grouping"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"expectedScoreWithout": 40,
|
|
83
|
+
"expectedScoreWith": 80
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"id": "bench-easy-03",
|
|
87
|
+
"difficulty": "easy",
|
|
88
|
+
"description": "Extract keywords from a recipe",
|
|
89
|
+
"input": "Extract the key terms and topics from this recipe:\n\nClassic Beef Bourguignon\nSlow-braised beef chuck in a rich Burgundy wine sauce with pearl onions, mushrooms, and bacon lardons. This traditional French stew combines aromatics — carrots, celery, garlic, and thyme — with a flour-thickened stock base. Braise at 325°F for 2.5 hours until the beef is fork-tender. Serve over egg noodles or crusty bread. Pairs well with a medium-bodied Pinot Noir.",
|
|
90
|
+
"rubric": [
|
|
91
|
+
{
|
|
92
|
+
"criterion": "Domain Keyword Coverage",
|
|
93
|
+
"weight": 0.4,
|
|
94
|
+
"scoring": {
|
|
95
|
+
"5": "Extracts dish name (Beef Bourguignon), technique (slow-braised, braise), key ingredients (beef chuck, Burgundy wine, pearl onions, mushrooms, bacon lardons), aromatics, and serving suggestions",
|
|
96
|
+
"3": "Extracts main ingredients and dish name but misses cooking techniques or serving context",
|
|
97
|
+
"1": "Only extracts 3-4 obvious food items",
|
|
98
|
+
"0": "Fails to extract culinary-relevant keywords"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"criterion": "Categorization",
|
|
103
|
+
"weight": 0.3,
|
|
104
|
+
"scoring": {
|
|
105
|
+
"5": "Categorizes keywords into: Dish Identity (Beef Bourguignon, French stew), Techniques (slow-braised, braise, flour-thickened), Main Ingredients, Aromatics, Serving",
|
|
106
|
+
"3": "Some categorization but mixes techniques with ingredients",
|
|
107
|
+
"1": "No categorization attempted",
|
|
108
|
+
"0": "Incorrect categorization"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"criterion": "Semantic Understanding",
|
|
113
|
+
"weight": 0.3,
|
|
114
|
+
"scoring": {
|
|
115
|
+
"5": "Recognizes 'Beef Bourguignon' as a single entity (not fragmented); identifies 'French cuisine' as an implied topic; understands 'fork-tender' as a doneness descriptor, not a keyword",
|
|
116
|
+
"3": "Preserves some multi-word terms but includes non-informative descriptors as keywords",
|
|
117
|
+
"1": "Fragments multi-word expressions; includes stopwords",
|
|
118
|
+
"0": "No semantic understanding demonstrated"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"expectedScoreWithout": 35,
|
|
123
|
+
"expectedScoreWith": 75
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"id": "bench-med-01",
|
|
127
|
+
"difficulty": "medium",
|
|
128
|
+
"description": "Extract keywords from a technical research abstract with domain-specific terminology",
|
|
129
|
+
"input": "Extract keywords and identify topics from this research abstract:\n\nWe present a novel approach to few-shot text classification using prompt-tuning with retrieval-augmented generation (RAG). Our method combines a frozen large language model (LLM) with a learned continuous prompt and a non-parametric retrieval module that fetches semantically similar examples from a labeled datastore at inference time. On the GLUE and SuperGLUE benchmarks, our approach achieves state-of-the-art performance with only 16 labeled examples per class, outperforming full fine-tuning by 3.2% on average. We demonstrate that the retrieval component reduces hallucination by 47% compared to prompt-only baselines, as measured by a factual consistency score. Ablation studies reveal that prompt length (20 tokens), retrieval top-k (k=5), and temperature scaling are the most impactful hyperparameters. Our code and models are available at github.com/example/rag-fewshot.",
|
|
130
|
+
"rubric": [
|
|
131
|
+
{
|
|
132
|
+
"criterion": "Technical Keyword Precision",
|
|
133
|
+
"weight": 0.3,
|
|
134
|
+
"scoring": {
|
|
135
|
+
"5": "Extracts all key technical terms: few-shot text classification, prompt-tuning, RAG, LLM, continuous prompt, non-parametric retrieval, GLUE, SuperGLUE, fine-tuning, hallucination, ablation study, hyperparameters, temperature scaling; preserves multi-word terms intact",
|
|
136
|
+
"3": "Extracts most technical terms but fragments some multi-word concepts or misses benchmark names",
|
|
137
|
+
"1": "Extracts generic ML terms but misses the specific methodology and metrics",
|
|
138
|
+
"0": "Fails to extract domain-specific terminology"
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"criterion": "Topic Clustering Quality",
|
|
143
|
+
"weight": 0.3,
|
|
144
|
+
"scoring": {
|
|
145
|
+
"5": "Creates coherent clusters: Methodology (prompt-tuning, RAG, continuous prompt, retrieval), Evaluation (GLUE, SuperGLUE, few-shot, state-of-the-art), Model Architecture (LLM, frozen model, non-parametric), Experimental Setup (ablation, hyperparameters, top-k, temperature)",
|
|
146
|
+
"3": "Clusters are present but some terms are misassigned or clusters are too broad",
|
|
147
|
+
"1": "Minimal clustering with poor coherence",
|
|
148
|
+
"0": "No clustering"
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"criterion": "Implicit Concept Detection",
|
|
153
|
+
"weight": 0.2,
|
|
154
|
+
"scoring": {
|
|
155
|
+
"5": "Identifies implied topics not explicitly stated: NLP, transfer learning, in-context learning, semantic search, embedding similarity; flags these as semantic-level with appropriate confidence",
|
|
156
|
+
"3": "Identifies 1-2 implied concepts but misses others",
|
|
157
|
+
"1": "Only extracts explicitly stated terms",
|
|
158
|
+
"0": "No semantic-level extraction"
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"criterion": "Quantitative Context Preservation",
|
|
163
|
+
"weight": 0.2,
|
|
164
|
+
"scoring": {
|
|
165
|
+
"5": "Preserves key quantitative context: 16 examples per class, 3.2% improvement, 47% hallucination reduction, 20 tokens, k=5; associates metrics with the correct terms",
|
|
166
|
+
"3": "Some quantitative context preserved but not linked to correct terms",
|
|
167
|
+
"1": "Numbers extracted but without context",
|
|
168
|
+
"0": "Quantitative context lost"
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
],
|
|
172
|
+
"expectedScoreWithout": 30,
|
|
173
|
+
"expectedScoreWith": 70
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"id": "bench-med-02",
|
|
177
|
+
"difficulty": "medium",
|
|
178
|
+
"description": "Extract keywords from a legal contract clause with domain-specific language",
|
|
179
|
+
"input": "Extract key terms and legal concepts from this contract clause:\n\nIndemnification and Limitation of Liability. The Service Provider shall indemnify, defend, and hold harmless the Client, its officers, directors, employees, and agents from and against any and all claims, damages, losses, liabilities, costs, and expenses (including reasonable attorneys' fees) arising out of or relating to (a) any breach of this Agreement by the Service Provider, (b) any negligent or wrongful act or omission of the Service Provider, or (c) any violation of applicable law by the Service Provider. Notwithstanding the foregoing, in no event shall the Service Provider's aggregate liability under this Agreement exceed the total fees paid by the Client during the twelve (12) months preceding the claim. Neither party shall be liable for any indirect, incidental, special, consequential, or punitive damages, including but not limited to loss of profits, data, or business opportunity, regardless of whether such damages were foreseeable.",
|
|
180
|
+
"rubric": [
|
|
181
|
+
{
|
|
182
|
+
"criterion": "Legal Term Extraction",
|
|
183
|
+
"weight": 0.35,
|
|
184
|
+
"scoring": {
|
|
185
|
+
"5": "Extracts all key legal terms: indemnify, hold harmless, limitation of liability, breach, negligent act, aggregate liability, consequential damages, punitive damages, attorneys' fees, foreseeable damages; preserves legal phrases intact",
|
|
186
|
+
"3": "Extracts major legal terms but misses nuanced concepts like 'hold harmless' or 'aggregate liability'",
|
|
187
|
+
"1": "Extracts only 3-4 obvious legal terms",
|
|
188
|
+
"0": "Fails to identify legal-specific terminology"
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"criterion": "Concept Hierarchy",
|
|
193
|
+
"weight": 0.3,
|
|
194
|
+
"scoring": {
|
|
195
|
+
"5": "Identifies the hierarchy: Indemnification (broader) containing breach, negligence, legal violation (triggers); Liability Cap (aggregate liability, twelve months, total fees); Damage Exclusions (indirect, consequential, punitive, loss of profits)",
|
|
196
|
+
"3": "Groups some related terms but misses the hierarchical relationship between indemnification triggers and the liability cap",
|
|
197
|
+
"1": "Flat list with no structural understanding",
|
|
198
|
+
"0": "No grouping"
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"criterion": "Domain Contextualization",
|
|
203
|
+
"weight": 0.2,
|
|
204
|
+
"scoring": {
|
|
205
|
+
"5": "Maps terms to contract law domain; identifies clause type (indemnification + liability limitation); notes that this is a standard commercial contract provision",
|
|
206
|
+
"3": "Identifies the legal domain but doesn't classify the clause type",
|
|
207
|
+
"1": "No domain context provided",
|
|
208
|
+
"0": "Misclassifies the domain"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"criterion": "Boilerplate Filtering",
|
|
213
|
+
"weight": 0.15,
|
|
214
|
+
"scoring": {
|
|
215
|
+
"5": "Correctly filters out boilerplate words (herein, notwithstanding, foregoing, including but not limited to) and does not include them as keywords",
|
|
216
|
+
"3": "Filters some boilerplate but includes 1-2 legal filler phrases as keywords",
|
|
217
|
+
"1": "Includes multiple boilerplate terms as keywords",
|
|
218
|
+
"0": "No boilerplate filtering"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
],
|
|
222
|
+
"expectedScoreWithout": 25,
|
|
223
|
+
"expectedScoreWith": 70
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"id": "bench-med-03",
|
|
227
|
+
"difficulty": "medium",
|
|
228
|
+
"description": "Extract keywords from a multilingual product review with sentiment signals",
|
|
229
|
+
"input": "Extract keywords and identify the main topics discussed in these product reviews:\n\nReview 1: 'The battery life on the Pixel 8 Pro is outstanding — easily lasts 2 days with moderate use. The Tensor G3 chip handles AI features like Magic Eraser and Best Take flawlessly. Camera quality rivals the iPhone 15 Pro, especially in low-light with Night Sight. However, the 6.7-inch display feels too large for one-handed use.'\n\nReview 2: 'Disappointed with the fingerprint sensor — it fails about 30% of the time. Software updates are frequent but sometimes introduce new bugs. The 50MP main camera produces oversaturated colors in auto mode. On the positive side, 7 years of OS updates is a huge commitment and the $999 price point is competitive for a flagship.'\n\nReview 3: 'Coming from a Samsung Galaxy S23, the Pixel's stock Android experience is refreshingly clean. Google Assistant integration is leagues ahead of Bixby. The 120Hz LTPO display is smooth, though peak brightness could be higher. Wireless charging and IP68 water resistance are expected at this price tier.'",
|
|
230
|
+
"rubric": [
|
|
231
|
+
{
|
|
232
|
+
"criterion": "Cross-Review Keyword Synthesis",
|
|
233
|
+
"weight": 0.3,
|
|
234
|
+
"scoring": {
|
|
235
|
+
"5": "Synthesizes keywords across all 3 reviews: identifies recurring themes (camera, battery, display, software), consolidates product references (Pixel 8 Pro), and captures both positive and negative aspect terms",
|
|
236
|
+
"3": "Extracts keywords from each review but doesn't synthesize or identify recurring themes",
|
|
237
|
+
"1": "Extracts keywords from only 1-2 reviews",
|
|
238
|
+
"0": "Fails to handle multi-document input"
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"criterion": "Feature-Level Clustering",
|
|
243
|
+
"weight": 0.3,
|
|
244
|
+
"scoring": {
|
|
245
|
+
"5": "Clusters by product features: Camera (50MP, Night Sight, Magic Eraser, low-light), Display (6.7-inch, 120Hz, LTPO), Performance (Tensor G3, AI features), Battery, Software (stock Android, OS updates), Biometrics (fingerprint sensor), Build (IP68, wireless charging)",
|
|
246
|
+
"3": "Some feature-level clustering but merges distinct features or misses categories",
|
|
247
|
+
"1": "Minimal clustering; most keywords ungrouped",
|
|
248
|
+
"0": "No feature clustering"
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"criterion": "Comparative Entity Handling",
|
|
253
|
+
"weight": 0.2,
|
|
254
|
+
"scoring": {
|
|
255
|
+
"5": "Correctly identifies compared products (Pixel 8 Pro, iPhone 15 Pro, Samsung Galaxy S23) and technologies (Tensor G3 vs Bixby vs Google Assistant) as distinct entity keywords; doesn't conflate them",
|
|
256
|
+
"3": "Identifies most product entities but misses technology comparisons",
|
|
257
|
+
"1": "Fragments product names or misses comparison context",
|
|
258
|
+
"0": "No entity recognition"
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"criterion": "Sentiment-Aware Extraction",
|
|
263
|
+
"weight": 0.2,
|
|
264
|
+
"scoring": {
|
|
265
|
+
"5": "Notes sentiment polarity for key feature keywords: battery (positive), fingerprint sensor (negative), camera (mixed), software updates (mixed); does not extract sentiment words themselves as topic keywords",
|
|
266
|
+
"3": "Some sentiment awareness but includes sentiment adjectives (outstanding, disappointed) as topic keywords",
|
|
267
|
+
"1": "No sentiment distinction — treats positive and negative aspects identically",
|
|
268
|
+
"0": "Sentiment interferes with keyword quality"
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
],
|
|
272
|
+
"expectedScoreWithout": 30,
|
|
273
|
+
"expectedScoreWith": 70
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"id": "bench-med-04",
|
|
277
|
+
"difficulty": "medium",
|
|
278
|
+
"description": "Extract keywords from a policy document with nested hierarchical topics",
|
|
279
|
+
"input": "Extract key terms and topic hierarchy from this policy summary:\n\nThe EU Artificial Intelligence Act establishes a risk-based regulatory framework for AI systems across the European Union. AI systems are classified into four risk tiers: (1) Unacceptable Risk — banned outright, including social scoring by governments, real-time biometric surveillance in public spaces, and manipulative AI targeting vulnerable groups; (2) High Risk — subject to strict requirements including conformity assessments, human oversight, data governance, and transparency obligations, covering areas such as employment screening, credit scoring, law enforcement, and critical infrastructure; (3) Limited Risk — requiring transparency measures such as disclosure that content is AI-generated, applicable to chatbots and deepfake generators; (4) Minimal Risk — freely permitted with no special requirements, covering spam filters, AI-enabled video games, and recommendation systems. General-purpose AI models (GPAI) face additional obligations including technical documentation, copyright compliance, and energy consumption reporting. Penalties for non-compliance reach up to 35 million euros or 7% of global annual turnover.",
|
|
280
|
+
"rubric": [
|
|
281
|
+
{
|
|
282
|
+
"criterion": "Hierarchical Term Extraction",
|
|
283
|
+
"weight": 0.35,
|
|
284
|
+
"scoring": {
|
|
285
|
+
"5": "Extracts the full hierarchy: EU AI Act (top-level), four risk tiers with their specific examples, GPAI obligations, and penalties; preserves the nested structure of risk categories and their associated requirements",
|
|
286
|
+
"3": "Extracts the risk tiers but misses specific examples within each tier or loses the hierarchical relationship",
|
|
287
|
+
"1": "Extracts flat terms like 'AI', 'risk', 'regulation' without hierarchy",
|
|
288
|
+
"0": "Fails to identify the regulatory structure"
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"criterion": "Domain Precision",
|
|
293
|
+
"weight": 0.3,
|
|
294
|
+
"scoring": {
|
|
295
|
+
"5": "Extracts precise regulatory terms: conformity assessment, human oversight, data governance, transparency obligations, social scoring, biometric surveillance, GPAI, global annual turnover; no over-generalization",
|
|
296
|
+
"3": "Extracts main regulatory concepts but generalizes some specific terms",
|
|
297
|
+
"1": "Only generic terms like 'regulation' and 'compliance'",
|
|
298
|
+
"0": "Misidentifies or omits domain-specific terms"
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"criterion": "Coverage Completeness",
|
|
303
|
+
"weight": 0.2,
|
|
304
|
+
"scoring": {
|
|
305
|
+
"5": "Covers all four risk tiers, GPAI provisions, and penalty structure; no major section of the text is left without keyword representation",
|
|
306
|
+
"3": "Covers 3 of the 4 risk tiers and most provisions",
|
|
307
|
+
"1": "Covers only 1-2 aspects of the policy",
|
|
308
|
+
"0": "Major gaps in coverage"
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"criterion": "Cluster Organization",
|
|
313
|
+
"weight": 0.15,
|
|
314
|
+
"scoring": {
|
|
315
|
+
"5": "Keywords organized into clusters matching the policy structure: Risk Classification, Requirements & Obligations, Prohibited Practices, GPAI Rules, Enforcement & Penalties",
|
|
316
|
+
"3": "Some organization but clusters don't align with the policy's natural structure",
|
|
317
|
+
"1": "Flat list despite clear hierarchical content",
|
|
318
|
+
"0": "No organization"
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
],
|
|
322
|
+
"expectedScoreWithout": 30,
|
|
323
|
+
"expectedScoreWith": 70
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
"id": "bench-hard-01",
|
|
327
|
+
"difficulty": "hard",
|
|
328
|
+
"description": "Extract keywords from a highly technical cross-disciplinary text spanning biology and computer science",
|
|
329
|
+
"input": "Extract keywords and map topic clusters from this cross-disciplinary passage:\n\nProtein structure prediction has been revolutionized by deep learning approaches, particularly AlphaFold2's use of attention mechanisms and multiple sequence alignments (MSAs) to achieve atomic-level accuracy. The model's Evoformer module processes evolutionary relationships between amino acid residues through axial attention, while the Structure Module generates 3D coordinates via invariant point attention (IPA). Training on the Protein Data Bank (PDB) with distillation from self-predictions, AlphaFold2 achieves a median GDT-TS score of 92.4 on CASP14 free-modeling targets.\n\nRecent extensions include ESMFold, which eliminates the MSA requirement using a protein language model (pLM) pretrained on 65 million sequences, and RoseTTAFold All-Atom, which extends predictions to protein-ligand and protein-nucleic acid complexes. Diffusion-based approaches like RFdiffusion enable de novo protein design by sampling from learned structure distributions, opening applications in enzyme engineering, drug delivery scaffolds, and biosensor design.\n\nCritically, confidence metrics such as pLDDT (predicted local distance difference test) and PAE (predicted aligned error) allow researchers to assess prediction reliability per-residue, distinguishing well-folded domains from intrinsically disordered regions (IDRs).",
|
|
330
|
+
"rubric": [
|
|
331
|
+
{
|
|
332
|
+
"criterion": "Cross-Domain Keyword Precision",
|
|
333
|
+
"weight": 0.3,
|
|
334
|
+
"scoring": {
|
|
335
|
+
"5": "Extracts terms from both domains: Biology (protein structure, amino acid residues, MSA, PDB, enzyme engineering, intrinsically disordered regions) and CS/ML (deep learning, attention mechanisms, axial attention, diffusion models, language model); preserves all acronyms with expansions",
|
|
336
|
+
"3": "Extracts terms from both domains but misses specialized terms in one domain",
|
|
337
|
+
"1": "Extracts terms from only one domain",
|
|
338
|
+
"0": "Fails to identify domain-specific terminology"
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
"criterion": "Named System Recognition",
|
|
343
|
+
"weight": 0.25,
|
|
344
|
+
"scoring": {
|
|
345
|
+
"5": "Correctly identifies all named systems as atomic entities: AlphaFold2, Evoformer, Structure Module, ESMFold, RoseTTAFold All-Atom, RFdiffusion, CASP14, PDB; classifies each appropriately (model/benchmark/database)",
|
|
346
|
+
"3": "Identifies most named systems but fragments some (e.g., 'RoseTTAFold' and 'All-Atom' as separate keywords)",
|
|
347
|
+
"1": "Identifies only the most prominent names (AlphaFold2)",
|
|
348
|
+
"0": "Fragments or misidentifies named systems"
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"criterion": "Topic Cluster Coherence",
|
|
353
|
+
"weight": 0.25,
|
|
354
|
+
"scoring": {
|
|
355
|
+
"5": "Creates coherent cross-disciplinary clusters: Structural Biology Methods (MSA, PDB, GDT-TS, residues), Deep Learning Architecture (attention, Evoformer, IPA, diffusion), Prediction Systems (AlphaFold2, ESMFold, RFdiffusion), Applications (enzyme engineering, drug delivery, biosensors), Confidence Metrics (pLDDT, PAE, IDR)",
|
|
356
|
+
"3": "Reasonable clusters but some terms misassigned across biology/CS boundaries",
|
|
357
|
+
"1": "Only broad 'biology' and 'CS' clusters without nuance",
|
|
358
|
+
"0": "No meaningful clustering"
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"criterion": "Metric and Acronym Handling",
|
|
363
|
+
"weight": 0.2,
|
|
364
|
+
"scoring": {
|
|
365
|
+
"5": "Preserves all metrics (GDT-TS 92.4, pLDDT, PAE) and acronyms (MSA, IPA, pLM, IDR) with their expansions; associates metrics with correct models",
|
|
366
|
+
"3": "Preserves most acronyms but misses expansions or metric associations",
|
|
367
|
+
"1": "Some acronyms extracted but without context",
|
|
368
|
+
"0": "Acronyms fragmented or omitted"
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
],
|
|
372
|
+
"expectedScoreWithout": 20,
|
|
373
|
+
"expectedScoreWith": 65
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
"id": "bench-hard-02",
|
|
377
|
+
"difficulty": "hard",
|
|
378
|
+
"description": "Extract keywords from an ambiguous text with negations, hypotheticals, and contrasting arguments",
|
|
379
|
+
"input": "Extract keywords from this analytical essay, handling negations and contrasting viewpoints correctly:\n\nThe claim that remote work universally increases productivity is not supported by the evidence. While studies from Stanford (Bloom et al., 2015) showed a 13% performance increase for call center employees, these results do not generalize to creative or collaborative roles. In fact, Microsoft's analysis of 61,000 employees found that cross-team collaboration decreased by 25% during remote work periods.\n\nIt would be misleading to conclude that office work is therefore superior. Hybrid models — combining 2-3 office days with remote flexibility — appear to optimize both individual focus time and team cohesion. However, this finding does not account for industries with strict security requirements (defense, healthcare) where remote access is fundamentally constrained.\n\nNotably, the productivity debate ignores several confounding variables: commute time savings (averaging 41 minutes per day in US metro areas), real estate cost reduction for employers ($11,000 per employee annually), and the environmental impact of reduced commuting (estimated 54 million tons of CO2 equivalent annually). These factors may outweigh marginal productivity differences in either direction.\n\nCritics argue that long-term innovation suffers without serendipitous in-person interactions, but no longitudinal study has yet confirmed this hypothesis with statistical significance.",
|
|
380
|
+
"rubric": [
|
|
381
|
+
{
|
|
382
|
+
"criterion": "Negation-Aware Extraction",
|
|
383
|
+
"weight": 0.3,
|
|
384
|
+
"scoring": {
|
|
385
|
+
"5": "Correctly handles negations: 'remote work increases productivity' is identified as a CONTESTED claim, not an affirmed keyword; 'does not generalize' is not used to assert generalizability; 'no longitudinal study has confirmed' flags innovation impact as UNPROVEN; negated terms are either excluded or clearly marked",
|
|
386
|
+
"3": "Handles some negations but treats 1-2 negated claims as affirmed keywords",
|
|
387
|
+
"1": "Ignores negation context entirely — extracts 'productivity increase' as a positive keyword",
|
|
388
|
+
"0": "Negation blindness — all terms extracted as if affirmed"
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
"criterion": "Argumentative Structure Keywords",
|
|
393
|
+
"weight": 0.3,
|
|
394
|
+
"scoring": {
|
|
395
|
+
"5": "Extracts keywords that reflect the debate structure: remote work productivity (contested), hybrid models (proposed solution), cross-team collaboration (declined), confounding variables (reframing), serendipitous interactions (hypothesis); captures the nuance of each position",
|
|
396
|
+
"3": "Extracts topic terms but loses the argumentative nuance — doesn't distinguish claims from counter-claims",
|
|
397
|
+
"1": "Extracts only surface-level terms without argumentative context",
|
|
398
|
+
"0": "Misrepresents the text's argumentative positions"
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
"criterion": "Quantitative Evidence Linking",
|
|
403
|
+
"weight": 0.2,
|
|
404
|
+
"scoring": {
|
|
405
|
+
"5": "Links statistics to correct claims: 13% increase (Stanford/call center), 25% decrease (Microsoft/collaboration), 41 min commute savings, $11K cost reduction, 54M tons CO2; associates each with its source and scope",
|
|
406
|
+
"3": "Extracts most statistics but doesn't link all to their correct claims or sources",
|
|
407
|
+
"1": "Extracts some numbers without context",
|
|
408
|
+
"0": "Quantitative data lost or misattributed"
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
"criterion": "Topic Coverage Despite Complexity",
|
|
413
|
+
"weight": 0.2,
|
|
414
|
+
"scoring": {
|
|
415
|
+
"5": "Covers all sub-topics: productivity evidence, collaboration impact, hybrid models, industry constraints, economic factors, environmental impact, innovation concerns; organizes into coherent clusters",
|
|
416
|
+
"3": "Covers 4-5 sub-topics but misses 1-2 or clusters poorly",
|
|
417
|
+
"1": "Covers only the main topic (remote work) without sub-topic differentiation",
|
|
418
|
+
"0": "Major gaps in topic coverage"
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
],
|
|
422
|
+
"expectedScoreWithout": 20,
|
|
423
|
+
"expectedScoreWith": 60
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
"id": "bench-hard-03",
|
|
427
|
+
"difficulty": "hard",
|
|
428
|
+
"description": "Extract keywords from a dense technical specification with overlapping terminology across sections",
|
|
429
|
+
"input": "Extract and deduplicate keywords from this API specification:\n\nEndpoint: POST /v2/models/{model_id}/predictions\nAuthentication: Bearer token (JWT, RS256 signed, 1-hour expiry)\nRate Limit: 100 requests/minute per API key, burst allowance of 20 requests/second\n\nRequest Body:\n- model_id (string, required): The unique identifier of the deployed model. Supports versioned IDs (e.g., 'gpt-4-turbo-2024-04-09').\n- messages (array, required): Conversation history. Each message object contains 'role' (system|user|assistant) and 'content' (string, max 128K tokens).\n- temperature (float, optional, default 1.0): Sampling temperature. Range [0.0, 2.0]. Lower values produce more deterministic outputs.\n- top_p (float, optional, default 1.0): Nucleus sampling parameter. Mutually exclusive with temperature when both differ from defaults.\n- max_tokens (integer, optional): Maximum tokens in the response. Model-dependent upper bound.\n- stream (boolean, optional, default false): Enable server-sent events (SSE) for streaming responses.\n- tools (array, optional): Function calling definitions. Each tool specifies 'name', 'description', and 'parameters' (JSON Schema).\n\nResponse:\n- id (string): Unique prediction identifier (UUID v4)\n- choices (array): Model outputs. Each choice contains 'message' (role + content), 'finish_reason' (stop|length|tool_calls|content_filter), and 'index'.\n- usage (object): Token consumption — 'prompt_tokens', 'completion_tokens', 'total_tokens'.\n- model (string): Actual model used (may differ from requested if aliased).\n\nError Codes: 400 (invalid request), 401 (authentication failed), 429 (rate limited), 500 (internal error), 503 (model unavailable).",
|
|
430
|
+
"rubric": [
|
|
431
|
+
{
|
|
432
|
+
"criterion": "API Concept Extraction",
|
|
433
|
+
"weight": 0.3,
|
|
434
|
+
"scoring": {
|
|
435
|
+
"5": "Extracts all key API concepts: endpoint, authentication (JWT, RS256, Bearer token), rate limiting, request/response schema, streaming (SSE), function calling, token counting; preserves technical precision",
|
|
436
|
+
"3": "Extracts most API concepts but misses technical details like RS256 or SSE",
|
|
437
|
+
"1": "Extracts only broad concepts like 'API' and 'authentication'",
|
|
438
|
+
"0": "Fails to identify API-specific terminology"
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
"criterion": "Parameter Keyword Organization",
|
|
443
|
+
"weight": 0.25,
|
|
444
|
+
"scoring": {
|
|
445
|
+
"5": "Organizes parameters into logical clusters: Sampling Control (temperature, top_p, max_tokens), Input Structure (messages, model_id, roles), Output Format (choices, finish_reason, usage), Configuration (stream, tools); distinguishes request from response terms",
|
|
446
|
+
"3": "Groups some parameters but mixes request and response terms or misclassifies",
|
|
447
|
+
"1": "Flat list of parameter names without grouping",
|
|
448
|
+
"0": "Parameters not extracted as keywords"
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"criterion": "Deduplication Across Sections",
|
|
453
|
+
"weight": 0.25,
|
|
454
|
+
"scoring": {
|
|
455
|
+
"5": "Correctly deduplicates: 'model_id' appears in endpoint path and request body — extracted once; 'tokens' appears in multiple contexts (max_tokens, prompt_tokens, 128K tokens) — unified under a token-related cluster; 'role' in messages and choices merged",
|
|
456
|
+
"3": "Some deduplication but 1-2 terms appear redundantly",
|
|
457
|
+
"1": "No deduplication — same terms appear multiple times from different sections",
|
|
458
|
+
"0": "Excessive duplication"
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
"criterion": "Technical Precision",
|
|
463
|
+
"weight": 0.2,
|
|
464
|
+
"scoring": {
|
|
465
|
+
"5": "Preserves precise technical terms: UUID v4, JSON Schema, SSE, RS256, JWT, nucleus sampling, server-sent events; includes constraint values where relevant (128K tokens, [0.0, 2.0] range)",
|
|
466
|
+
"3": "Preserves most technical terms but loses some precision or constraint context",
|
|
467
|
+
"1": "Generalizes technical terms (e.g., 'identifier' instead of 'UUID v4')",
|
|
468
|
+
"0": "Technical precision lost"
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
],
|
|
472
|
+
"expectedScoreWithout": 20,
|
|
473
|
+
"expectedScoreWith": 60
|
|
474
|
+
}
|
|
475
|
+
]
|
|
476
|
+
}
|
package/tests/smoke.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.0.1",
|
|
3
|
+
"timeout": 60,
|
|
4
|
+
"tasks": [
|
|
5
|
+
{
|
|
6
|
+
"id": "smoke-01",
|
|
7
|
+
"description": "Extract keywords from a technical article about cloud-native architecture with topic clustering and domain contextualization",
|
|
8
|
+
"input": "Extract the key terms and topics from the following article:\n\nCloud-native architecture has transformed how organizations build and deploy software at scale. By leveraging containerization through Docker and orchestration via Kubernetes, teams can achieve unprecedented levels of scalability and resilience. Microservices decompose monolithic applications into independently deployable units, each with its own database and API boundary.\n\nService meshes like Istio and Linkerd provide observability, traffic management, and mutual TLS authentication between services. Combined with CI/CD pipelines using tools like GitHub Actions, ArgoCD, and Tekton, organizations can ship code multiple times per day with confidence.\n\nHowever, cloud-native adoption introduces complexity in distributed tracing, eventual consistency, and network latency. Site Reliability Engineering (SRE) practices — including error budgets, service level objectives (SLOs), and chaos engineering — help teams manage this operational complexity while maintaining high availability.",
|
|
9
|
+
"rubric": [
|
|
10
|
+
{
|
|
11
|
+
"criterion": "Keyword Coverage",
|
|
12
|
+
"weight": 0.3,
|
|
13
|
+
"scoring": {
|
|
14
|
+
"5": "Extracts all major terms: cloud-native, containerization, Docker, Kubernetes, microservices, service mesh, Istio, CI/CD, SRE, SLOs, chaos engineering, distributed tracing; covers both explicit terms and implied concepts like DevOps and infrastructure automation",
|
|
15
|
+
"3": "Extracts most explicit technical terms but misses some named technologies or implied concepts",
|
|
16
|
+
"1": "Extracts only a few obvious terms; misses most domain-specific terminology",
|
|
17
|
+
"0": "Fails to extract meaningful keywords or returns generic words"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"criterion": "Topic Clustering",
|
|
22
|
+
"weight": 0.25,
|
|
23
|
+
"scoring": {
|
|
24
|
+
"5": "Groups keywords into coherent clusters (e.g., Container Orchestration, Service Communication, CI/CD Pipeline, Reliability Engineering) with clear labels and intra-cluster coherence",
|
|
25
|
+
"3": "Some clustering present but clusters are too broad or miss obvious groupings",
|
|
26
|
+
"1": "Flat list with no meaningful grouping",
|
|
27
|
+
"0": "No clustering attempted"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"criterion": "Ranking Quality",
|
|
32
|
+
"weight": 0.25,
|
|
33
|
+
"scoring": {
|
|
34
|
+
"5": "Keywords are scored and ranked with core architectural concepts (cloud-native, microservices, Kubernetes) ranked highest; supporting tools ranked lower; scores reflect actual importance in the text",
|
|
35
|
+
"3": "Rankings are present but some important terms are underweighted or generic terms are overweighted",
|
|
36
|
+
"1": "Keywords listed but not meaningfully ranked",
|
|
37
|
+
"0": "No ranking or scoring"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"criterion": "Output Structure",
|
|
42
|
+
"weight": 0.2,
|
|
43
|
+
"scoring": {
|
|
44
|
+
"5": "Each keyword includes: term, score, extraction level (lexical/phrasal/semantic), cluster assignment, and entity type where applicable; output is grouped by cluster with summaries",
|
|
45
|
+
"3": "Keywords have scores and some metadata but missing cluster summaries or extraction level",
|
|
46
|
+
"1": "Basic list of keywords with minimal metadata",
|
|
47
|
+
"0": "Unstructured raw output"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"passThreshold": 60
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|