vecscope 0.1.0__tar.gz
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.
- vecscope-0.1.0/.agents/skills/vecscope/SKILL.md +27 -0
- vecscope-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +27 -0
- vecscope-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- vecscope-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +20 -0
- vecscope-0.1.0/.github/pull_request_template.md +16 -0
- vecscope-0.1.0/.github/workflows/ci.yml +39 -0
- vecscope-0.1.0/.github/workflows/release.yml +37 -0
- vecscope-0.1.0/.gitignore +9 -0
- vecscope-0.1.0/AGENTS.md +31 -0
- vecscope-0.1.0/CHANGELOG.md +29 -0
- vecscope-0.1.0/CONTRIBUTING.md +44 -0
- vecscope-0.1.0/LICENSE +21 -0
- vecscope-0.1.0/PKG-INFO +392 -0
- vecscope-0.1.0/README.md +361 -0
- vecscope-0.1.0/SECURITY.md +17 -0
- vecscope-0.1.0/docs/readme/README_ko.md +362 -0
- vecscope-0.1.0/examples/make_examples.py +22 -0
- vecscope-0.1.0/examples/real_models.py +98 -0
- vecscope-0.1.0/pyproject.toml +52 -0
- vecscope-0.1.0/src/vecscope/__init__.py +6 -0
- vecscope-0.1.0/src/vecscope/_knn.py +46 -0
- vecscope-0.1.0/src/vecscope/cli.py +87 -0
- vecscope-0.1.0/src/vecscope/diagnostics/__init__.py +20 -0
- vecscope-0.1.0/src/vecscope/diagnostics/anisotropy.py +48 -0
- vecscope-0.1.0/src/vecscope/diagnostics/ann_recall.py +25 -0
- vecscope-0.1.0/src/vecscope/diagnostics/clusters.py +64 -0
- vecscope-0.1.0/src/vecscope/diagnostics/collapse.py +32 -0
- vecscope-0.1.0/src/vecscope/diagnostics/geometry.py +120 -0
- vecscope-0.1.0/src/vecscope/diagnostics/hubness.py +33 -0
- vecscope-0.1.0/src/vecscope/diagnostics/queries.py +65 -0
- vecscope-0.1.0/src/vecscope/evidence.py +337 -0
- vecscope-0.1.0/src/vecscope/io.py +58 -0
- vecscope-0.1.0/src/vecscope/mcp_server.py +64 -0
- vecscope-0.1.0/src/vecscope/sweep.py +207 -0
- vecscope-0.1.0/tests/test_audit.py +242 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vecscope
|
|
3
|
+
description: Audit an embedding matrix or vector index before trusting retrieval results. Use when building or debugging RAG, semantic search, or recommendation retrieval, when "the same chunks always come back", when similarity scores all look alike, or before choosing ANN index parameters.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# vecscope
|
|
7
|
+
|
|
8
|
+
Run `vecscope audit <embeddings> --json` (or the MCP tool `audit_embeddings`; `pip install vecscope` if missing) and read `verdict`. For files above 100k rows a seeded sample is audited; pass `--sample 0` when ANN recall must be scored on every row.
|
|
9
|
+
|
|
10
|
+
- `fail` on **anisotropy** or **effective_rank**: center/whiten the embeddings or switch models before tuning retrieval; cosine scores are not discriminative. `details.mean_random_cosine_after_centering` shows what centering alone would achieve; if it is near 0, centering is enough and the model can stay.
|
|
11
|
+
- `fail` on **hubness**: use mutual k-NN, local scaling, or re-rank; raw cosine top-k will over-return hub items.
|
|
12
|
+
- `fail` on **collapse**: deduplicate the corpus first; top-k is wasted on copies.
|
|
13
|
+
- `fail` on **ann_recall**: raise `ef_search`/`nprobe` or rebuild the index; the model is not the problem.
|
|
14
|
+
- `fail` on **rogue_dimensions**: standardize each dimension (z-score) or drop `details.rogue_dims` before indexing; cosine is being decided by a few coordinates.
|
|
15
|
+
- `fail` on **norms**: L2-normalize before indexing and drop zero vectors (usually empty or failed inputs). Check **metric_mismatch** next.
|
|
16
|
+
- `fail` on **metric_mismatch**: the index metric (cosine vs inner product) changes the results; pick one deliberately and normalize if cosine is intended.
|
|
17
|
+
- `fail` on **distance_concentration**: nearest neighbors are barely closer than random items; reduce dimensionality, change the model, or add a re-ranker. Expect poor ANN recall too.
|
|
18
|
+
- `fail` on **outliers**: inspect `details.sample_ids`; they are usually junk, empty or foreign-language items. Remove or re-embed them.
|
|
19
|
+
- `fail` on **ood_queries** (needs `--queries`): the queries do not live where the corpus lives. Check that queries use the same model and the model's query prefix/instruction; inspect `details.ood_sample_ids` for topics the corpus does not cover.
|
|
20
|
+
- `fail` on **query_hubness**: a few corpus items answer most queries; re-rank or apply hubness reduction before trusting top-k.
|
|
21
|
+
- `fail` on **connectivity**: the k-NN graph has islands; raise HNSW `M`/`ef_construction` or add bridging content, otherwise whole regions are unreachable.
|
|
22
|
+
|
|
23
|
+
Every finding carries `healthy_range`, `warn_at` and `fail_at`; quote them when explaining a verdict.
|
|
24
|
+
|
|
25
|
+
Pass `--clusters 10` (or `clusters=10`) to get a per-cluster map with sample ids when you need to tell the user *where* a problem lives. Run `vecscope sweep <embeddings>` (MCP: `sweep_index`) before choosing HNSW/IVF parameters; take the recommended configuration and quote its recall and qps. The sweep uses the GPU automatically when the faiss build has one (IVF only; HNSW is CPU-only); mention the device from the result when comparing qps.
|
|
26
|
+
|
|
27
|
+
Report the numbers verbatim to the user. Do not guess at embedding quality without this evidence.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: A finding, verdict, loader or CLI behaviour that looks wrong
|
|
3
|
+
labels: [bug]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what
|
|
7
|
+
attributes:
|
|
8
|
+
label: What happened
|
|
9
|
+
description: Paste the command (or MCP call) and the output. `--json` output is best.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: expected
|
|
14
|
+
attributes:
|
|
15
|
+
label: What you expected
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: input
|
|
19
|
+
id: shape
|
|
20
|
+
attributes:
|
|
21
|
+
label: Input shape and format
|
|
22
|
+
placeholder: "n=120000, dim=768, .parquet, float32"
|
|
23
|
+
- type: input
|
|
24
|
+
id: version
|
|
25
|
+
attributes:
|
|
26
|
+
label: vecscope and Python version
|
|
27
|
+
placeholder: "vecscope 0.1.0, Python 3.12, Windows 11"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: A new finding, input format, or agent integration
|
|
3
|
+
labels: [enhancement]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: What retrieval failure would this help an agent see?
|
|
9
|
+
description: Describe the symptom first ("same chunks for every query"), then the measurement.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: evidence
|
|
14
|
+
attributes:
|
|
15
|
+
label: Proposed evidence
|
|
16
|
+
description: The metric, how it is computed, and a reference if one exists.
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: verdict
|
|
19
|
+
attributes:
|
|
20
|
+
label: What should the agent do when it fails?
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## What this changes
|
|
2
|
+
|
|
3
|
+
<!-- One paragraph. If it adds or changes a finding, say what symptom it makes visible. -->
|
|
4
|
+
|
|
5
|
+
## Evidence
|
|
6
|
+
|
|
7
|
+
<!-- For a new or changed diagnostic: the synthetic case it detects, the healthy case it leaves
|
|
8
|
+
at `ok`, and the reference (paper or doc) for the measurement, if any. -->
|
|
9
|
+
|
|
10
|
+
## Checklist
|
|
11
|
+
|
|
12
|
+
- [ ] `pytest -q` passes
|
|
13
|
+
- [ ] `ruff check src tests examples` passes
|
|
14
|
+
- [ ] Output is still deterministic (fixed seeds, no learned components)
|
|
15
|
+
- [ ] README / SKILL.md updated if the CLI, MCP tool or verdicts changed
|
|
16
|
+
- [ ] CHANGELOG.md has an entry under Unreleased
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ${{ matrix.os }}
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
15
|
+
python: ["3.10", "3.13"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python }}
|
|
21
|
+
- run: python -m pip install -e ".[dev,mcp,index]"
|
|
22
|
+
- run: ruff check src tests examples
|
|
23
|
+
- run: pytest -q
|
|
24
|
+
- name: CLI smoke test
|
|
25
|
+
run: |
|
|
26
|
+
python examples/make_examples.py
|
|
27
|
+
vecscope audit examples/healthy.npy
|
|
28
|
+
vecscope --version
|
|
29
|
+
|
|
30
|
+
build:
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- uses: actions/setup-python@v5
|
|
35
|
+
with:
|
|
36
|
+
python-version: "3.12"
|
|
37
|
+
- run: python -m pip install build twine
|
|
38
|
+
- run: python -m build
|
|
39
|
+
- run: python -m twine check dist/*
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
# Publishes when a tag like v0.1.0 is pushed. Uses PyPI trusted publishing:
|
|
4
|
+
# register this repository/workflow at https://pypi.org/manage/account/publishing/
|
|
5
|
+
# (environment name: pypi) so no API token is stored in the repository.
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
tags: ["v*"]
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.12"
|
|
19
|
+
- run: python -m pip install build
|
|
20
|
+
- run: python -m build
|
|
21
|
+
- uses: actions/upload-artifact@v4
|
|
22
|
+
with:
|
|
23
|
+
name: dist
|
|
24
|
+
path: dist/
|
|
25
|
+
|
|
26
|
+
publish:
|
|
27
|
+
needs: build
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
environment: pypi
|
|
30
|
+
permissions:
|
|
31
|
+
id-token: write
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/download-artifact@v4
|
|
34
|
+
with:
|
|
35
|
+
name: dist
|
|
36
|
+
path: dist/
|
|
37
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
vecscope-0.1.0/AGENTS.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Repository guidelines
|
|
2
|
+
|
|
3
|
+
`vecscope` gives agents deterministic evidence about embedding spaces and vector indexes.
|
|
4
|
+
These rules apply to any agent or person changing this repository.
|
|
5
|
+
|
|
6
|
+
## Product rules
|
|
7
|
+
|
|
8
|
+
- Every finding reports a measured value, the verdict, the threshold that produced it, and an
|
|
9
|
+
explanation that states what the number means and what healthy looks like.
|
|
10
|
+
- Output is deterministic: fixed seeds, exact neighbors, no learned components, no network.
|
|
11
|
+
Two runs on the same input must produce identical JSON.
|
|
12
|
+
- The core depends on NumPy only. Loaders and the MCP server may use optional extras.
|
|
13
|
+
- Never guess at embedding quality in docs or messages. Point at the finding.
|
|
14
|
+
|
|
15
|
+
## Layout
|
|
16
|
+
|
|
17
|
+
- `src/vecscope/diagnostics/`: one pure function per finding, returning plain Python numbers
|
|
18
|
+
- `src/vecscope/evidence.py`: thresholds, `Finding`/`Evidence` models, the `audit` entry point
|
|
19
|
+
- `src/vecscope/sweep.py`: HNSW/IVF parameter sweep on top of faiss (optional extra)
|
|
20
|
+
- `src/vecscope/cli.py`, `src/vecscope/mcp_server.py`: thin adapters over `audit` and `sweep`
|
|
21
|
+
- `.agents/skills/vecscope/SKILL.md`: what an agent should do with each verdict
|
|
22
|
+
|
|
23
|
+
## Checks before a change is done
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pytest -q
|
|
27
|
+
ruff check src tests examples
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Update `README.md`, `docs/readme/README_ko.md`, the skill file and `CHANGELOG.md` when the
|
|
31
|
+
CLI, MCP tool, findings or verdicts change. Keep the English and Korean READMEs in sync.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0] - 2026-10-25
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `vecscope audit` CLI with text and `--json` output, `--fail-on` gate and non-zero exit on FAIL
|
|
14
|
+
- Findings: hubness, antihubs, anisotropy, effective rank, collapse, rogue dimensions, norms,
|
|
15
|
+
metric mismatch, distance concentration, outliers, k-NN graph connectivity, ANN recall
|
|
16
|
+
- Seeded sampling (`--sample`, default 100k rows) so large matrices stay tractable
|
|
17
|
+
- MCP server (`vecscope-mcp`) exposing `audit_embeddings`
|
|
18
|
+
- Query-side findings (`--queries`): out-of-distribution queries and query hubness
|
|
19
|
+
- Per-cluster report with sample ids (`--clusters N`)
|
|
20
|
+
- `vecscope sweep` / MCP `sweep_index`: HNSW and IVF parameter sweep with recall, build time and
|
|
21
|
+
QPS, plus a recommended configuration (optional `faiss-cpu` extra); IVF and the exact
|
|
22
|
+
baseline run on the GPU automatically with a faiss GPU build (`--device auto|cpu|gpu`)
|
|
23
|
+
- Loaders for `.npy`, `.npz`, `.parquet`, `.jsonl`, `.json`, `.csv`
|
|
24
|
+
- Agent skill file describing when to run the audit and how to act on verdicts
|
|
25
|
+
- Each finding reports `healthy_range`, `warn_at`, `fail_at`; `anisotropy` also reports the
|
|
26
|
+
mean-vector norm and the random-pair cosine after centering
|
|
27
|
+
- Thresholds calibrated on public embeddings from eight models (OpenAI ada-002 and 3-large,
|
|
28
|
+
Cohere embed-v3, all-MiniLM-L6-v2, bge-m3, mxbai-embed-large-v1, gte-base-en-v1.5);
|
|
29
|
+
`examples/real_models.py` reproduces the table in the README
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Contributing to vecscope
|
|
2
|
+
|
|
3
|
+
Thanks for helping agents see embedding spaces. This file explains how to work on the code
|
|
4
|
+
and what a good change looks like.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
git clone https://github.com/076923/vecscope
|
|
10
|
+
cd vecscope
|
|
11
|
+
python -m pip install -e ".[dev,mcp,index]"
|
|
12
|
+
pytest -q
|
|
13
|
+
ruff check src tests examples
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`python examples/make_examples.py` writes three small matrices into `examples/` so you can try
|
|
17
|
+
`vecscope audit examples/anisotropic.npy` right away.
|
|
18
|
+
|
|
19
|
+
## Scope
|
|
20
|
+
|
|
21
|
+
`vecscope` produces **deterministic evidence** about an embedding matrix or a vector index for
|
|
22
|
+
an agent to act on. A change fits when it:
|
|
23
|
+
|
|
24
|
+
- makes a retrieval failure visible that an agent could not see before, or
|
|
25
|
+
- makes an existing finding more accurate, cheaper, or easier to act on.
|
|
26
|
+
|
|
27
|
+
It does not fit when it needs a learned component, a network call, or a model download at
|
|
28
|
+
audit time, or when it makes two runs on the same input produce different output.
|
|
29
|
+
|
|
30
|
+
## Adding a finding
|
|
31
|
+
|
|
32
|
+
1. Put the measurement in `src/vecscope/diagnostics/<name>.py` as a pure function returning a
|
|
33
|
+
`dict` of plain Python numbers. Reuse the shared exact k-NN from `audit` when you can.
|
|
34
|
+
2. Register the threshold pair in `THRESHOLDS` and build the `Finding` in
|
|
35
|
+
`src/vecscope/evidence.py`. The explanation string must state the number, what it means, and
|
|
36
|
+
what "healthy" looks like.
|
|
37
|
+
3. Add a test with a synthetic case that fails and a healthy case that stays `ok`.
|
|
38
|
+
4. Describe the finding in the table in `README.md` and the action in
|
|
39
|
+
`.agents/skills/vecscope/SKILL.md`.
|
|
40
|
+
|
|
41
|
+
## Pull requests
|
|
42
|
+
|
|
43
|
+
Keep PRs focused on one change. Fill in the template, especially the evidence section.
|
|
44
|
+
Dependencies stay at NumPy for the core; optional extras are fine for loaders and the MCP server.
|
vecscope-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Daehee Yun
|
|
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.
|