A(nother) semantic routing system that classifies user queries into hierarchical categories using OpenAI embeddings and cosine similarity.
- Hierarchical intent routing with configurable similarity thresholds
- Automatic embedding caching for performance optimization
- YAML-based configuration for routing tree structure
- Transactional updates to routing configuration
- OpenAI embedding model integration
- Python 3.12 and up.
- Access to any Open AI compatible endpoint (Ollama, LiteLLM, ...) with some embeddings model available.
- Install it with
pip install . - Setup the
.envfile (start with the provideddotenv.templateone). - Optionally, edit the
router_example.yamlto define your routes. - Play with the routes using the
aseroCLI command. - That's all!
- Install development dependencies:
pip install .[dev] - Enable up pre-commit hooks:
pre-commit install - Setup the
.envfile (start with the provideddotenv.templateone). - Hack, hack, hack (the
aseroCLI command, that runsmain.py, should be enough) - Test, test, test. Try to cover as much as possible always.
(see the Contributing section for more details)
Uses a configured LLM (accessed through any OpenAI-compatible endpoint) to synthetically paraphrase every utterance in your router YAML, producing a JSON file ready for asero --evaluate or asero --optimise.
augment [--input-file <router.yaml>] [--output-file <out.json>] [--model <name>] [--variations N] [--limit N]
--input-file— router YAML to read utterances from (defaults to$ROUTER_YAML_FILE).--output-file— destination JSON file (defaults to<input-stem>_eval.json).--model— LLM model name at the configured endpoint (default:llama3.3-70b).--variations— number of paraphrases to generate per utterance (default:5).--limit— process only the first N utterances;0means all (default:0).
Requires OPENAI_API_KEY and OPENAI_BASE_URL to be set (e.g. via .env). The script validates that the requested model is available at the endpoint before starting.
Run augment --help for full details.
Runs the current router against a JSON eval file and reports top-K accuracy and MRR(K+1).
asero --evaluate <path to eval file> [--metric top1|top2|top3|top4|top5]
--evaluate— path to the JSON evaluation file (produced byaugment).--metric— which top-K level to report as the headline accuracy figure (default:top1).
The evaluation runs in eval mode: all routing thresholds are disabled so every query always returns scores, giving a true picture of the embedding quality independent of threshold tuning.
Searches for the threshold values that maximise the chosen accuracy metric on a dataset, then optionally writes the results back to the router YAML.
asero --optimise <path to eval file> [--metric top1|top2|top3|top4|top5] [--write]
--optimise— path to the JSON evaluation file (produced byaugment).--metric— accuracy metric to maximise during the search (default:top1).--write— when set, the optimised thresholds are written back to the router YAML file; without this flag the results are printed but not persisted.
Don't forget to configure the .env file (see "Quick start" above).
from asero import config as asero_config
from asero.router import SemanticRouter
# Load the configuration from a YAML file (see router_example.yaml)
config = asero_config.get_config("path/to/valid/router.yaml")
# Create a router instance
router = SemanticRouter(config)
# Start making queries (explore options in the SemanticRouter class)
matches = router.top_n_routes(query="Hi!")
# Or, for async contexts:
matches = await router.atop_n_routes(query="Hi!")
# Print the top matches (route, score, depth, leaf)
[print(match) for match in matches]Will output something like:
('router_example/greetings/neutral', 0.9999999999999999, 3, True)
('router_example/chitchat', 0.48668323180162615, 2, True)
This project is licensed under the BSD 3-Clause License. See the LICENSE file for more information.
We welcome contributions! Please see our Contributing Guidelines for more details.
Please note that this project adheres to a Code of Conduct. By participating, you agree to uphold this code.
© 2025 Moodle Research Team