Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

semops-0.3.0.tar.gz (16.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

semops-0.3.0-py3-none-any.whl (18.7 kB view details)

Uploaded Python 3

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

Hashes for semops-0.3.0.tar.gz
Algorithm Hash digest
SHA256 c86d65fe6a50d409329e4d8b7eb20253af0261e4158abe5ec74d4576a77ef0b2
MD5 b20e82d09db02ba2e5919f4aa1ce7c30
BLAKE2b-256 3e9139a0205f92edfabee899a0ec18e1127db926da135ba859da57194e24c23b

See more details on using hashes here.

Provenance

The following attestation bundles were made for semops-0.3.0.tar.gz:

Publisher: python-publish.yml on AnantDhavale/semops

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for semops-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a0455f800933828f744144deba3f18f809610a61bf134681037510c699cc5470
MD5 f8cd6608cf7c38a1aae4cf8e9373c2a5
BLAKE2b-256 0050611c95a0f11e4f6be9e69269fb798b76ac696d727de9f5498ccb7defe085

See more details on using hashes here.

Provenance

The following attestation bundles were made for semops-0.3.0-py3-none-any.whl:

Publisher: python-publish.yml on AnantDhavale/semops

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page