Taguru
taguru · documentation

手繰る (taguru) —
long-term memory for LLMs that pulls knowledge in from a cue

Taguru accumulates knowledge as (subject, label, object, weight, source) associations and retrieves it the way a thread is pulled in hand over hand: from the cue — what a question is about, the 糸口, the end of the thread — the association graph is walked to draw the knowledge out. Vector similarity is not the entrance to retrieval; it runs alongside as one lane of evidence.

License: MIT Implementation: Rust · single binary (~13 MB static) Interfaces: HTTP API / MCP (stdio · Streamable HTTP)

What the server does

What it keeps, how it searches, and who does which job.

The fact 「青嶺酒造の杜氏は高瀬」 — Aomine Brewery's master brewer is Takase — becomes the single association (青嶺酒造, 杜氏, 高瀬, 1.0, docs/aomine.md). The weight is signed: a negative value states a negation ("is not"). When another document re-asserts the same triple, the weights add up and a per-source attribution is kept — a fact supported independently by two sources and a fact asserted strongly by one source stay distinguishable to the end.

Retrieval starts from structure. The cue is resolved to a concept on the graph through normalized matching (absorbing spelling variation, kana/katakana differences, light typos), and the associations are pulled from there — that is the first lane. The original text can be searched as a second lane, paragraph by paragraph (BM25, plus embeddings when configured). Procedural details and conditions that never fit into a triple are only found on this lane.

Everything that needs language understanding — decomposing documents into facts, choosing a context, recomposing results into prose — is the client's (the LLM's) job. The server only stores and walks structure, and it distributes the playbook for doing so itself: GET /protocol.

Documentation

From first install to the internals. Every page is build-free static HTML and opens locally as-is.

Try it in 30 seconds

Start the server, create a context, store one fact, and pull it back out.

# install (brings the server `taguru` and the MCP bridge `taguru-mcp`)
cargo install taguru
taguru   # listens on 127.0.0.1:8248 (data in ./data)

# create a context
curl -X PUT localhost:8248/contexts/sake -H 'Content-Type: application/json' \
  -d '{"description":"青嶺酒造という架空の酒蔵の知識"}'

# store one association
curl -X POST localhost:8248/contexts/sake/associations -H 'Content-Type: application/json' \
  -d '[{"subject":"青嶺酒造","label":"代表銘柄","object":"青嶺","weight":1.0,"source":"第1段落"}]'

# pull the thread
curl -X POST localhost:8248/contexts/sake/activate -H 'Content-Type: application/json' \
  -d '{"origins":["青嶺酒造"]}'

The full endpoint list and the complete ingest/retrieval discipline are distributed by the running server itself at GET /protocol — the same primary source an LLM client receives. Continue with Getting started.

Design principles

Structure is the main line; similarity is one lane

The entrance is normalized matching and concept resolution. When embeddings are configured they act as a tier that backs up a weak entrance and as the parallel lane of text search. Which lane found a hit is always declared by lanes or tier in the result.

The client is an LLM

Decomposing documents, assembling answers, and choosing a context are language-understanding work, so they belong to the LLM. The server hands out its own playbook (/protocol) and tool definitions, so a connected LLM knows the correct order of calls from the first turn.

Every answer pulls back to the original text

The graph is an index, not an archive. Every fact carries its attribution, and the source and paragraph of an attribution lead back to the original paragraph itself through the citations API.

A write acknowledged with 200 is never lost

An accepted write is fsynced to the WAL before it applies. After a crash, replay on the next boot brings it back. Disk is the source of truth; memory is only a per-context cache.