Install
openclaw skills install @sandeep85das/adaptive-classifierBuild, update and honestly evaluate text classifiers with the open-source adaptive-classifier library, which learns new examples and new classes without retraining from scratch. Use for small labeled sets, label sets that change over time, and routing, intent or moderation tasks; not for large static datasets where standard fine-tuning is better.
openclaw skills install @sandeep85das/adaptive-classifierUse this skill when the user wants a text classifier (https://github.com/codelion/adaptive-classifier) that starts from a few labeled examples and keeps learning. Everything runs locally. Do not call push_to_hub or any publish step unless the user explicitly asks.
Ask before anything downloads model weights or datasets. Creating AdaptiveClassifier(...) with a model name, from_pretrained(...) and ONNX export all fetch or write model files. Say which model and roughly why, and wait for a yes.
Good fit:
Poor fit:
Mechanism (from the source): texts are embedded by a pretrained encoder, per-class prototypes are kept in memory, and a small trainable head is blended with prototype similarity. Adding examples retrains the head briefly (10 epochs by default) with EWC protection for old classes.
python -c "import adaptive_classifier; print(adaptive_classifier.__version__)"
If this fails, tell the user the library is missing and point them to the Installation section of the README. Do not run install commands or fetch code for them. The checks below were made against version 0.2.0; if the printed version differs, inspect signatures before relying on this skill:
python -c "import inspect, adaptive_classifier as a; print(inspect.signature(a.AdaptiveClassifier.__init__))"
from adaptive_classifier import AdaptiveClassifier
clf = AdaptiveClassifier("sentence-transformers/all-MiniLM-L6-v2") # downloads weights: ask first
clf.add_examples(texts, labels) # parallel lists of str; labels are str
print(clf.predict("some text", k=3)) # [(label, score), ...] sorted, top k (default 5)
batch = clf.predict_batch(list_of_texts, k=3, batch_size=32)
Notes verified in the source:
add_examples raises ValueError on empty lists or mismatched lengths. predict raises on empty text.bert-base-uncased or sentence-transformers/all-MiniLM-L6-v2. Prefer an encoder trained for sentence similarity.pooling is auto (the model's own sentence-transformers pooling if published, else mean). Options: "auto", "mean", "cls". Classifiers saved before 0.2.0 keep CLS pooling when reloaded.AdaptiveClassifier(name, config={...}). Defaults checked: prototype_weight 0.7, neural_weight 0.3, new_class_example_threshold 10, new_class_prototype_weight 0.3, new_class_neural_weight 0.7, max_examples_per_class 1000, epochs 10. Other constructor args: device, seed=42, use_onnx="auto", trust_remote_code=False (leave it False).clf.add_examples(["Error 404 on login"], ["technical"]) # unseen label = new class
clf.add_examples(more_texts, more_labels) # more data for existing classes
print(clf.get_example_statistics()["examples_per_class"])
A label that has not been seen creates a new class: the head is expanded and trained with attention to the new class. A class with fewer than new_class_example_threshold trained examples leans on the head (0.3 prototype / 0.7 neural by default), so give new classes at least 10 examples before trusting them.
After any addition, re-run your held-out evaluation, because old classes can drift. Other tools: clear_memory(labels=None) drops stored examples (all, or the listed labels); merge_classifiers(other) merges another classifier with the same embedding size and retrains the head.
Order dependence: the README says example order can change predictions. For strict order independence set config={"prototype_weight": 1.0, "neural_weight": 0.0}, at some possible cost in accuracy (the README says "slightly lower"). Treat that as a claim to test on your data.
from adaptive_classifier import MultiLabelAdaptiveClassifier
m = MultiLabelAdaptiveClassifier(name, default_threshold=0.5, min_predictions=1, max_predictions=5)
m.add_examples(texts, [["a", "b"], ["b"]]) # list of label lists
m.predict_multilabel(text, threshold=None, max_labels=None)
m.get_label_statistics()
Thresholds are lowered automatically as the label count grows (README table: 0.5 for 2-4 labels down to 0.1 for 30+). Check precision per label after that adjustment.
Only for settings where users may rewrite text to game the classifier (spam, review scoring). Enable with config={"enable_strategic_mode": True}. Then predict blends regular and strategic outputs (0.6 / 0.4 by default); predict_strategic and predict_robust are the pure variants; evaluate_strategic_robustness(test_texts, test_labels, gaming_levels=[0.0, 0.5, 1.0]) measures it. README reports 80.00% vs 82.22% clean accuracy and 60.00% vs 82.22% on adversarial examples (regular vs strategic, AI-Secure/adv_glue). The README does not state the sample size; treat it as one benchmark, and run the evaluator on your own data.
add_examples. Remove near-duplicates across splits.prototype_weight / neural_weight and pooling settings on the validation split only, then touch the test split once.State the sample sizes with every number. The README figures for hallucination detection (51.54% F1) and LLM routing (32.40% cost savings on 500 queries) come from the project's own benchmarks on specific datasets; do not present them as expected results on the user's task.
clf.save("./my_classifier") # include_onnx=True by default
clf2 = AdaptiveClassifier.load("./my_classifier") # use_onnx="auto", prefer_quantized=True
clf3 = AdaptiveClassifier.load("./my_classifier", use_onnx=False) # force PyTorch
save(save_dir, include_onnx=True, quantize_onnx=True). Use include_onnx=False to skip the ONNX export. load(save_dir, device=None, use_onnx="auto", prefer_quantized=True, trust_remote_code=False). Loading a hub model with from_pretrained("owner/name") downloads files: ask first, and only for names the user gave. The README lists pretrained classifiers on the hub; check what each was trained on before use.
use_onnx="auto" uses ONNX on CPU and PyTorch on GPU. The README claims 2-4x faster CPU inference with ONNX (its example: 8.3 ms vs 2.1 ms per query for one model) and a quantized default that is smaller; use prefer_quantized=False when accuracy matters more. If the ONNX extras are missing, the library logs a warning and falls back to PyTorch. Compare predictions from both paths on your validation set before switching.
add_examples call retrains the head, so many tiny calls cost more than one batch.max_examples_per_class (1000), so old examples can be evicted.get_example_statistics()["num_classes"] after each update.A minimal complete example is in references/minimal_example.md.
Signatures, defaults and config keys above were checked with inspect and ModelConfig on version 0.2.0. Behavior that needs model weights (training, predictions, save/load, ONNX, strategic evaluation) was read from source and README, not run.