Skip to main content

Pinakes

A portable, agent-first knowledge base. One directory = one KB.

The Pinakes were Callimachus's catalogue of the Library of Alexandria — the first known index of a body of knowledge.

PyPI License Python Docs

📖 Documentation site — searchable, and the same files rendered below: Guide · CLI · Manifest · Design · What ships today


The idea

A knowledge base is a plain directory you can read, edit, diff, commit and hand to someone:

my-kb/
├── pinakes.toml              # manifest: sources, models, chunking, budget
├── docs/                     # SOURCE OF TRUTH — your files, unmodified
│   ├── paper.pdf
│   ├── paper.pdf.pnk.yaml    # sidecar: stable ID, tags, links, provenance
│   ├── notes.md
│   └── notes.md.pnk.yaml
└── .pinakes/                 # generated, disposable, gitignored
    └── index.db              # SQLite: chunks, FTS5, vectors, links

Your documents and their metadata are the truth. The index is derived state that can always be rebuilt. That split is what makes a KB both a reproducible recipe and a directory you can move.

What makes it different

It costs nothing to run. Retrieval is BM25 (SQLite FTS5) + local embeddings + local reranking, fused and scored entirely on your CPU. No API key is needed to search, and re-indexing is free — so there is never a cost reason not to improve your chunking or swap your embedding model. That the free path stays free is enforced by a CI gate, not by a promise.

Reasoning is the caller's, not the KB's. The MCP tools return ranked, cited evidence. pinakes_search → pinakes_get → pinakes_search is a plan-retrieve-read-refine loop, and your agent already runs it in its own context. Multi-hop reasoning falls out of composable tools rather than a second agent framework.

Money is opt-in and bounded by design. Every paid path is an explicit, enumerated entry point, and a pre-call reservation makes a hard cap a real ceiling rather than an after-the-fact report. See what is actually built.

KBs link to each other. Sidecars carry pnk://<kb-ulid>/<doc-ulid> references, so links survive renames, moves, and being shared with someone else. pnk links and the pinakes_links tool walk them — bounded, and a neighbour in another KB is returned but never expanded, because this index holds that KB's links pointing here and not its own. pnk sync --scan-links learns what points back by reading the other KB's committed sidecars, and pnk link authors one from the command line, straight into the source document's own sidecar.

Your sidecars are yours. They are read and written through a round-trip parser, so a rewrite keeps your comments, your quoting and your own key order — and a value is stored as you wrote it: country: NO stays NO.

Its limits are published, not hidden. No vector tier is sublinear; cross-KB answers will be capped by how well your KBs are linked; and the confidence heuristic's measured false-confidence rate is 0.25 — one no-answer question in four still gets a confident answer. A heuristic whose cost is unmeasured is worse than one whose cost is known.

Quickstart

uv add "pinakes[st]"                  # default backend
uv add "pinakes[light]"               # fastembed, no torch
uv add "pinakes[light,pdf]"           # + PDF ingest, free and local
uv add "pinakes[light,pdf,claude]"    # + the two opt-in paid paths: scanned PDFs, and `ask --deep`

[claude] installs the two paths that can spend money, and neither spends without you asking. Transcribing a scanned PDF takes --extract=claude-vision (or a manifest key); answering a question takes pnk ask --deep. Both also take a real API key in the environment, under a name only Pinakes reads. Everything else — search, sync, and pnk ask without the flag — is free and offline.

When you do ask, the whole run is priced before the first call and refused if it would breach any of the three [budget] caps — per_operation_eur, daily_eur or monthly_eur. Raising one and hitting the next is the discovery path those caps exist to prevent, so a refusal names every window that binds, not just the first, and prints the manifest edit that would admit the run. Every call is then reconciled to what it actually cost, and pnk budget reports it.

pnk init my-kb                        # stamp a KB
pnk sync                              # index what changed (git-hook friendly)
pnk search "hybrid retrieval"         # free: BM25 + vector + rerank
pnk ask "how does fusion work?"       # the same evidence, plus what answering would cost
pnk ask "…" --deep                    # ...and this one pays to answer it, under [budget]
pnk doctor                            # environment, coherence, orphans, link coverage
pnk upgrade                           # what your template changed; writes nothing

uvx --from "pinakes[st]" pnk serve    # MCP server, nothing installed

On a [light] install, stamp the models with the flag: pnk init my-kb --backend light. It is a flag rather than detection deliberately — pinakes.toml is committed, so baking in whatever the init machine happened to have installed breaks the KB for everyone with the other extra (Guide).

⚠️ The one thing pnk init cannot know: to index PDFs, add "**/*.pdf" to [sources] include.

→ Full guide — PDFs, filters, calibration, git hooks, MCP setup, troubleshooting.

Development

make install    # sync the dev environment (the light extra — CI's minimum leg)
make check      # every gate, stopping at the first failure — run before every commit
make demo       # index the synthetic demo KB
make eval       # golden-set evaluation against the recorded baseline
make corpus     # regenerate the synthetic PDF corpus in place
make pdf-eval   # extraction-quality baseline + floor-drift check (needs [pdf])
make budget     # the demo KB's spend ledger (free: it only reads)
make docs       # build the documentation site (--strict — exactly what CI runs)
make docs-serve # preview it at http://127.0.0.1:8000 with live reload
make help       # all targets

Every target wraps the command CI actually runs, so green locally means green on the runner. Note that make check formats Python inside Markdown fences too — a docs-only change can fail it.

Conventions are in CLAUDE.md, the increment workflow in docs/BUILDING.md; how the docs are organised — and which file to edit when you land a feature — is in docs/README.md. docs/VERIFICATION.md maps every promise this project makes to the test that holds it, and a test asserts every one of those tests exists.

Your data stays yours

This repository contains the engine only. Real knowledge bases live outside it. The only KBs here are two small synthetic corpora — an archive and a partner museum that transacts with it — used for tests, retrieval benchmarking and cross-KB linking, and the only other committed content is tests/pdf-corpus/ — PDFs generated from scratch by a committed script to exercise hard extraction cases. None of it was harvested from anywhere; no real-world document is committed here.

pnk init ships a .gitignore covering .pinakes/, so your index — and your spend ledger — never leaves your machine. Note that publishing a KB repo publishes docs/ and every sidecar: titles, tags and provenance URLs included.

Licence

Apache-2.0.

Metadata

Release files for pinakes 0.32.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pinakes 0.32.1
File Size Uploaded
pinakes-0.32.1.tar.gz 3.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pinakes 0.32.1
File Interpreter ABI Platform
pinakes-0.32.1-py3-none-any.whl Python 3 none any Details

Total release size: 3.8 MB

Release files / pinakes-0.32.1.tar.gz

Download URL pinakes-0.32.1.tar.gz
Size 3.3 MB
Tags Source
SHA-256 checksum
How to use checksums
f13f4fc1255094003656cf12e758dae9bd239e36f371bba32addf53ac7718657
BLAKE2b-256 checksum
How to use checksums
a4038835216b8b3ec20964201ba4cd2cd0bf9d8b95315246502278e2c9f1bd37
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / pinakes-0.32.1-py3-none-any.whl

Download URL pinakes-0.32.1-py3-none-any.whl
Size 470.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eb8dfb87187ea36c57894aff5997c18c8c54f4e0fa89b6df33587a11639b7b15
BLAKE2b-256 checksum
How to use checksums
40458fe514d0f1ee3369a59bbb8dc1c2fdec2b7bc702c9c2f91caa997ba2bb12
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.32.1 This release

2 release files

0.31.1

2 release files

0.31.0

2 release files

0.30.2

2 release files

0.30.1

2 release files

0.30.0

2 release files

0.29.2

2 release files

0.29.1

2 release files

0.29.0

2 release files

0.28.3

2 release files

0.28.2

2 release files

0.28.1

2 release files

0.28.0

2 release files

0.27.2

2 release files

0.27.1

2 release files

0.27.0

2 release files

0.26.0

2 release files

0.25.4

2 release files

0.25.3

2 release files

0.25.2

2 release files

0.25.1

2 release files

0.25.0

2 release files

0.24.0

2 release files

0.23.0

2 release files

0.22.2

2 release files

0.22.1

2 release files

0.22.0

2 release files

0.21.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page