Semantic operations for Python. The NumPy of meaning.
Project description
semops
Semantic operations for Python. The NumPy of meaning.
semops is a local, model-agnostic semantic utility layer for Python.
It gives you reusable primitives for search, classification, deduplication, clustering, reference-set scoring, threshold calibration, lightweight evaluation, and local monitoring.
Install
pip install semops
pip install semops[openai]
pip install semops[local]
pip install semops[parquet]
Quickstart
import semops as so
from semops.adapters.local_adapter import LocalAdapter
adapter = LocalAdapter()
tickets = [
"I can't log into my account",
"Login is broken for me",
"Password reset email never arrived",
"Invoice PDF is missing",
]
match, score = so.nearest("Unable to sign in", tickets, adapter)
label, confidence = so.classify(
"reset email never arrived",
["login issue", "password reset", "billing issue"],
adapter,
)
duplicates = so.dedup(tickets, adapter, threshold=0.80)
print(match, score)
print(label, confidence)
print(duplicates)
What you can build with it
- Semantic search and relevance ranking
- Ticket, query, or document routing by meaning
- Deduplication and record cleanup
- Clustering unlabeled text into themes
- Brand, policy, or topic alignment checks
- Drift checks on outputs, content, or datasets
- Threshold calibration before wiring rules into production
Core primitives
vector = so.embed(text, adapter)
score = so.sim(a, b, adapter)
difference = so.diff(a, b, adapter)
shift = so.drift(old_text, new_text, adapter)
match, score = so.nearest(query, corpus, adapter)
ranked = so.rank(query, corpus, adapter)
groups = so.cluster(texts, adapter, k=3)
label, score = so.classify(text, labels, adapter)
duplicate_groups = so.dedup(texts, adapter, threshold=0.85)
Batch APIs
scores = so.sim_many(query, corpus, adapter)
matrix = so.sim_matrix(queries, corpus, adapter)
matches = so.nearest_many(queries, corpus, adapter)
rankings = so.rank_many(queries, corpus, adapter, top_k=3)
These are useful when you need to score many inputs without writing the loops yourself.
End-to-end examples
1. Search and routing
query = "customer cannot access account"
corpus = [
"login issue",
"billing issue",
"shipping delay",
]
label, score = so.classify(query, corpus, adapter)
print(label, score)
2. Deduplication
records = [
"I can't log into my account",
"Unable to sign in",
"Invoice PDF is missing",
"Login is broken for me",
]
duplicate_groups = so.dedup(records, adapter, threshold=0.80)
for group in duplicate_groups:
print(group)
3. Brand, policy, and topic scoring
brand_examples = [
"Write with clarity and restraint.",
"Avoid hype and overstatement.",
]
topic_examples = [
"Password resets and login issues",
"Authentication failures and locked accounts",
]
policy_examples = [
"Never promise guaranteed uptime.",
"Do not claim compliance that has not been verified.",
]
candidate_outputs = [
"Our product definitely guarantees zero downtime forever.",
"Customers are seeing login failures after password resets.",
]
brand_report = so.score_off_brand(candidate_outputs, brand_examples, adapter, threshold=0.50)
topic_report = so.score_off_topic(candidate_outputs, topic_examples, adapter, threshold=0.45)
policy_report = so.score_policy_distance(candidate_outputs, policy_examples, adapter, threshold=0.55)
Reference-set helpers
Use semantic examples as anchors for brand voice, policies, categories, or quality standards.
scores = so.score_references(candidate_outputs, brand_examples, adapter)
matches = so.match_references("This copy is bold and loud", brand_examples, adapter)
distance = so.reference_distance("Guaranteed forever", brand_examples, adapter)
centroid = so.reference_centroid(brand_examples, adapter)
These helpers are useful when you want to ask questions like:
- "How close is this output to our approved examples?"
- "Which example is it most similar to?"
- "How far has this content drifted from the reference set?"
Local monitoring primitives
semops includes local-only monitoring helpers for scoring batches of text.
drift_report = so.score_dataset_drift(baseline_outputs, candidate_outputs, adapter, threshold=0.35)
topic_report = so.score_off_topic(candidate_outputs, topic_examples, adapter, threshold=0.45)
brand_report = so.score_off_brand(candidate_outputs, brand_examples, adapter, threshold=0.50)
policy_report = so.score_policy_distance(candidate_outputs, policy_examples, adapter, threshold=0.55)
These return structured reports that you can inspect, export, or feed into your own pipelines.
Calibration and evaluation
scores = [0.92, 0.81, 0.34, 0.18]
labels = [True, True, False, False]
metrics = so.classification_metrics(scores, labels, threshold=0.5)
best = so.calibrate_threshold(scores, labels, metric="f1")
curve = so.sweep_thresholds(scores, labels)
queries = ["cannot log in", "reset email missing"]
expected = ["login is broken", "password reset email never arrived"]
corpus = [
"login is broken",
"password reset email never arrived",
"app crashes on startup",
]
retrieval = so.evaluate_retrieval(queries, expected, corpus, adapter)
Use these helpers when you need to choose thresholds or compare semantic retrieval quality on your own data.
Instrumentation and export
semops includes a simple local event schema and export helpers for notebooks and pipelines.
sink = so.ListSink()
report = so.score_off_brand(candidate_outputs, brand_examples, adapter, threshold=0.50)
so.emit_report(sink, report, tags={"project": "docs-bot"})
rows = sink.rows()
so.export_json(rows, "semops_events.json")
so.export_csv(rows, "semops_events.csv")
Parquet export is optional and requires semops[parquet].
Adapters
| Adapter | Install | Use case |
|---|---|---|
OpenAIAdapter |
pip install semops[openai] |
Best quality, bring your own key |
LocalAdapter |
pip install semops[local] |
Fully local embeddings |
StubAdapter |
core | Deterministic testing |
YourAdapter |
- | Bring your own model |
You can also implement your own adapter with one method:
from semops.base import BaseAdapter
import numpy as np
class MyAdapter(BaseAdapter):
def embed(self, text: str) -> np.ndarray:
...
Examples
Run the example scripts from the project root:
python semops/example_tickets.py
python semops/example_monitoring.py
OSS boundary
Included here:
- semantic primitives and batch helpers
- adapters and adapter interfaces
- local evaluation, calibration, and reference-set scoring
- local-only monitoring reports
- generic event records and file export helpers
Not included here:
- hosted ingestion clients
- dashboards, alerts, or scheduled jobs
- team workflows, review queues, or governance controls
- bundled API credits or managed model access
Contact
If you have any questions, suggestions or find the library useful, please drop me a line at anantdhavale@gmail.com
Also check Cerone on PyPI: pip install cerone
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file semops-0.3.0.tar.gz.
File metadata
- Download URL: semops-0.3.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c86d65fe6a50d409329e4d8b7eb20253af0261e4158abe5ec74d4576a77ef0b2
|
|
| MD5 |
b20e82d09db02ba2e5919f4aa1ce7c30
|
|
| BLAKE2b-256 |
3e9139a0205f92edfabee899a0ec18e1127db926da135ba859da57194e24c23b
|
Provenance
The following attestation bundles were made for semops-0.3.0.tar.gz:
Publisher:
python-publish.yml on AnantDhavale/semops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
semops-0.3.0.tar.gz -
Subject digest:
c86d65fe6a50d409329e4d8b7eb20253af0261e4158abe5ec74d4576a77ef0b2 - Sigstore transparency entry: 1535094548
- Sigstore integration time:
-
Permalink:
AnantDhavale/semops@a72816b4601c6516244ecff1b724da59e8bf7b1c -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/AnantDhavale
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@a72816b4601c6516244ecff1b724da59e8bf7b1c -
Trigger Event:
release
-
Statement type:
File details
Details for the file semops-0.3.0-py3-none-any.whl.
File metadata
- Download URL: semops-0.3.0-py3-none-any.whl
- Upload date:
- Size: 18.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0455f800933828f744144deba3f18f809610a61bf134681037510c699cc5470
|
|
| MD5 |
f8cd6608cf7c38a1aae4cf8e9373c2a5
|
|
| BLAKE2b-256 |
0050611c95a0f11e4f6be9e69269fb798b76ac696d727de9f5498ccb7defe085
|
Provenance
The following attestation bundles were made for semops-0.3.0-py3-none-any.whl:
Publisher:
python-publish.yml on AnantDhavale/semops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
semops-0.3.0-py3-none-any.whl -
Subject digest:
a0455f800933828f744144deba3f18f809610a61bf134681037510c699cc5470 - Sigstore transparency entry: 1535094706
- Sigstore integration time:
-
Permalink:
AnantDhavale/semops@a72816b4601c6516244ecff1b724da59e8bf7b1c -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/AnantDhavale
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@a72816b4601c6516244ecff1b724da59e8bf7b1c -
Trigger Event:
release
-
Statement type: