Skip to main content

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

Project description

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

📖 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. The addressing ships today because IDs cannot be retrofitted; authoring and traversing those links is the links release.

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 opt-in paid extractor for scanned PDFs

[claude] installs a path that can spend money, and nothing spends without you asking: the default extractor is free, and reaching the paid one takes --extract=claude-vision (or a manifest key) and a real API key in the environment. When you do ask, the 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. pnk budget reports what has been spent.

pnk init my-kb                        # stamp a KB
pnk sync                              # index what changed (git-hook friendly)
pnk search "hybrid retrieval"         # free: BM25 + vector + rerank
pnk doctor                            # environment, coherence, orphans, link coverage

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

⚠️ Two things pnk init cannot know, each needing one manifest edit: on a [light] install set provider = "fastembed", and to index PDFs add "**/*.pdf" to [sources] include. Both are in the Guide.

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 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 and the increment workflow are in CLAUDE.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 sole KB here is a small synthetic corpus used for tests and retrieval benchmarking, and the only other committed content is tests/pdf-corpus/ — PDFs generated from scratch by a committed script to exercise hard extraction cases. Neither 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.

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

pinakes-0.4.0.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

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

pinakes-0.4.0-py3-none-any.whl (206.1 kB view details)

Uploaded Python 3

File details

Details for the file pinakes-0.4.0.tar.gz.

File metadata

  • Download URL: pinakes-0.4.0.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","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}

File hashes

Hashes for pinakes-0.4.0.tar.gz
Algorithm Hash digest
SHA256 0ee634a10de4c17d0d8d00bd0d075015e2615ca7032b38a2c91ef56b92da370e
MD5 275031492c3bfaa325dc57e512a95ada
BLAKE2b-256 18ef7de7f61cd3915791740ae199715d2520997fa4b473d7eafd17d8e1b61ed0

See more details on using hashes here.

File details

Details for the file pinakes-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: pinakes-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 206.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","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}

File hashes

Hashes for pinakes-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5476c12aa32a2ee62e252079768a4b4759e778cd97c66d55e59f8296622fb3f0
MD5 dffabdd71832fc3040ed14d7410d0ab6
BLAKE2b-256 0dd2b1fed2c1b39c693afade92b1dab93514fc34750f167e93b5a8baa841a38e

See more details on using hashes here.

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