{"id":49041989,"url":"https://github.com/smart-ai-memory/attune-rag","last_synced_at":"2026-05-22T01:05:18.382Z","repository":{"id":352141078,"uuid":"1214005689","full_name":"Smart-AI-Memory/attune-rag","owner":"Smart-AI-Memory","description":"Lightweight, LLM-agnostic RAG pipeline with pluggable corpora. Works with Claude, OpenAI, Gemini, or any LLM.","archived":false,"fork":false,"pushed_at":"2026-04-23T05:52:22.000Z","size":503,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-23T19:35:00.435Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pypi.org/project/attune-rag/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Smart-AI-Memory.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-18T02:20:44.000Z","updated_at":"2026-04-23T05:52:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"910bd86a-7d07-4139-8dc5-6a6b92574ee0","html_url":"https://github.com/Smart-AI-Memory/attune-rag","commit_stats":null,"previous_names":["smart-ai-memory/attune-rag"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Smart-AI-Memory/attune-rag","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Smart-AI-Memory%2Fattune-rag","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Smart-AI-Memory%2Fattune-rag/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Smart-AI-Memory%2Fattune-rag/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Smart-AI-Memory%2Fattune-rag/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Smart-AI-Memory","download_url":"https://codeload.github.com/Smart-AI-Memory/attune-rag/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Smart-AI-Memory%2Fattune-rag/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32238748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T13:21:15.438Z","status":"ssl_error","status_checked_at":"2026-04-24T13:21:15.005Z","response_time":64,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-19T15:07:59.672Z","updated_at":"2026-05-22T01:05:18.373Z","avatar_url":"https://github.com/Smart-AI-Memory.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# attune-rag\n\nLightweight, LLM-agnostic RAG pipeline with pluggable\ncorpora. Works with Claude, Gemini, or any LLM.\n\n- **No LLM SDK at install time.** All provider deps are\n  optional extras. Two required runtime deps: `structlog`,\n  `jinja2`.\n- **Pluggable corpus.** Use attune-help (the default), any\n  markdown directory, or your own `CorpusProtocol`.\n- **Returns a prompt string + citation records** by default\n  — `pipeline.run()` never opens a network connection. You\n  call your own LLM however you like. Optional provider\n  adapters ship convenience wrappers.\n- **Optional hybrid retrieval.** `QueryExpander` and\n  `LLMReranker` layer Claude Haiku on top of keyword\n  retrieval to improve recall and precision — both opt-in,\n  both fail-safe.\n\n## Why attune-rag\n\nMost RAG libraries ship features. attune-rag ships **measured\nquality numbers** and gates merges against them. The CI badge\nisn't \"tests pass\" — it's `P@1 ≥ 0.95, R@3 = 1.00, mean\nfaithfulness ≥ 0.9686` (locked at\n[`docs/specs/release-quality-baseline/baseline-1.md`](docs/specs/release-quality-baseline/baseline-1.md))\nplus per-axis CPU + wall-clock perf thresholds (locked at\n[`docs/specs/downstream-validation/perf-baseline.md`](docs/specs/downstream-validation/perf-baseline.md)).\n\nA PR that drops `mean_faithfulness` below `0.9686` fails CI\nautomatically. Same for any latency hot-path regressing past\n`mean + 2σ`. That's the differentiator.\n\n### vs LangChain / LlamaIndex\n\n| | attune-rag | LangChain | LlamaIndex |\n|---|---|---|---|\n| Required runtime deps | 2 | many (transitively, ~30+) | many (~25+) |\n| LLM SDK at install | none | bundled | bundled |\n| Published quality regression thresholds | yes (P@1, R@3, faithfulness) | no | no |\n| Published perf thresholds (wall + CPU) | yes | no | no |\n| Citation primitives built-in | yes | add-on | add-on |\n| \"Get a string back, call your own LLM\" | default | possible w/ effort | possible w/ effort |\n\nLangChain and LlamaIndex are fantastic frameworks if you want\nbatteries-included orchestration. attune-rag is the alternative\nwhen you want a RAG component you can drop into an existing app\nwithout buying into a framework — and want the quality bar\nquantified, not implied.\n\n### What attune-rag is **not**\n\nHonest exclusions, so you can self-disqualify if you need any\nof these:\n\n- **Not an agent framework.** No multi-step chains, no tool-use\n  orchestration, no agent loops.\n- **Not a document-parsing toolkit.** Bring your markdown\n  already-parsed; use `unstructured.io` or similar upstream.\n- **Not a vector DB integration.** Keyword retrieval is the\n  default; you wire your own vector store if you need one (an\n  `EmbeddingRetriever` is on the post-freeze roadmap — see\n  below).\n- **Not a one-line-install batteries-included framework.** That's\n  LangChain / LlamaIndex. attune-rag is for the case where that's\n  too much.\n\n## Install\n\n```bash\npip install attune-rag                     # core only\npip install 'attune-rag[attune-help]'      # + bundled help corpus\npip install 'attune-rag[claude]'           # + Claude adapter\npip install 'attune-rag[gemini]'           # + Gemini adapter\npip install 'attune-rag[all]'              # everything\n```\n\n## Quick start — Claude\n\n```bash\npip install 'attune-rag[attune-help,claude]'\n```\n\n```python\nimport asyncio\nfrom attune_rag import RagPipeline\n\nasync def main():\n    pipeline = RagPipeline()  # defaults to AttuneHelpCorpus\n    response, result = await pipeline.run_and_generate(\n        \"How do I run a security audit with attune?\",\n        provider=\"claude\",\n    )\n    print(response)\n    print(\"\\nSources:\", [h.entry.path for h in result.citation.hits])\n\nasyncio.run(main())\n```\n\n## Quick start — Gemini\n\n```bash\npip install 'attune-rag[attune-help,gemini]'\n```\n\n```python\nresponse, result = await pipeline.run_and_generate(\n    \"...\", provider=\"gemini\", model=\"gemini-1.5-pro\",\n)\n```\n\n## Quick start — custom corpus, any LLM\n\n```python\nfrom pathlib import Path\nfrom attune_rag import RagPipeline, DirectoryCorpus\n\npipeline = RagPipeline(corpus=DirectoryCorpus(Path(\"./my-docs\")))\nresult = pipeline.run(\"How do I...?\")\n\n# Send result.augmented_prompt to whatever LLM you use.\n# The pipeline itself does NOT call an LLM unless you use\n# run_and_generate or call a provider adapter yourself.\n```\n\n## Hybrid retrieval (optional)\n\n`QueryExpander` and `LLMReranker` require the `[claude]` extra and an\n`ANTHROPIC_API_KEY`. Both are opt-in and fail-safe — any API error\nfalls back to keyword-only order automatically.\n\n```python\nfrom attune_rag import RagPipeline, LLMReranker, QueryExpander\n\n# Reranker only (recommended for precision):\npipeline = RagPipeline(reranker=LLMReranker())\n\n# Expander + reranker (max coverage):\npipeline = RagPipeline(\n    expander=QueryExpander(),\n    reranker=LLMReranker(),\n)\n```\n\n## Template editor primitives (`attune_rag.editor`)\n\nHeadless toolkit for tools that need to validate, lint, and refactor a\ntemplate corpus — used by the [`attune-gui`](https://pypi.org/project/attune-gui/)\ntemplate editor and the [`attune-author`](https://pypi.org/project/attune-author/)\n`edit` CLI, but works standalone with any\n[`CorpusProtocol`](https://github.com/Smart-AI-Memory/attune-rag).\n\n| API | What it does |\n|-----|---------------|\n| `load_schema()` | Loads `template_schema.json` (the v1 frontmatter contract: required `type` enum + `name`; optional `tags`, `aliases`, `summary`, `source`, `hash`; `additionalProperties: true`). |\n| `parse_frontmatter(text)` / `validate_frontmatter(data)` | Split a template into frontmatter + body and report typed `FrontmatterIssue`s — used by linters and editors. |\n| `lint_template(text, rel_path, corpus)` | Returns `Diagnostic[]` for schema violations, broken `[[alias]]` references, and depth-marker sequence errors. 1-indexed line/col ranges. |\n| `autocomplete_tags(corpus, prefix, limit)` / `autocomplete_aliases(corpus, prefix, limit)` | Prefix-match completions ranked by frequency (tags) or lexical proximity (aliases). Sub-ms on 1k templates. |\n| `find_references(corpus, name, kind)` | Locate every alias/tag/path occurrence across body, frontmatter, and `cross_links.json`. |\n| `plan_rename(corpus, old, new, kind)` | Build a `RenamePlan` (one `FileEdit` per affected file with unified-diff hunks) for `kind=\"alias\"` or `\"tag\"`. Raises `RenameCollisionError` on existing alias targets. |\n| `apply_rename(corpus, plan)` | Atomically apply the plan (tempfile-per-file + sequential rename + drift-detection rollback). Returns the list of affected paths. |\n\nSchema, lint, and rename are pure functions over `CorpusProtocol` — no I/O,\nno global state. All three pieces are tested as a unit and used live by the\nattune-gui editor's `/api/corpus/\u003cid\u003e/lint`, `/autocomplete`, and\n`/refactor/rename/{preview,apply}` routes.\n\n```python\nfrom attune_rag import DirectoryCorpus\nfrom attune_rag.editor import lint_template, plan_rename, apply_rename\n\ncorpus = DirectoryCorpus(Path(\"./templates\")).load()\n\n# Validate a template before saving\ndiagnostics = lint_template(\n    text=Path(\"./templates/concepts/foo.md\").read_text(),\n    rel_path=\"concepts/foo.md\",\n    corpus=corpus,\n)\n\n# Rename an alias across the whole corpus\nplan = plan_rename(corpus, old=\"oldname\", new=\"newname\", kind=\"alias\")\nprint(f\"Affects {len(plan.edits)} files\")\naffected = apply_rename(corpus, plan)\n```\n\n## Dashboard\n\n```bash\nattune-rag dashboard show    # live terminal dashboard\nattune-rag dashboard render --out report.html  # HTML snapshot\n```\n\n## Quality baselines\n\nattune-rag locks two baselines, both gated by CI. Thresholds\nare empirically derived (`mean ± 2σ`) from back-to-back\nbenchmark runs on an unchanged HEAD — grounded, not guessed.\n\n### Retrieval + faithfulness\n\n| Metric | Threshold (current) | Source |\n|---|---:|---|\n| `precision_at_1` | **≥ 0.95** | retrieval, deterministic |\n| `recall_at_3` | **= 1.00** | retrieval, deterministic |\n| `mean_faithfulness` | **≥ 0.9686** | Claude judge, σ ≈ 0.005 |\n\nGated by [`.github/workflows/benchmark.yml`](.github/workflows/benchmark.yml).\nFaithfulness gating engages when the PR touches retrieval,\nreranker, expander, pipeline, prompts, or eval paths, or when\nthe PR title contains `[full-bench]`. Methodology + raw numbers\nin [`docs/specs/release-quality-baseline/`](docs/specs/release-quality-baseline/baseline-1.md).\n\n### Per-hot-path latency\n\nLocked dual-axis (wall-clock + CPU-time) thresholds on the four\nbenchmarks. CPU-time is the gating axis (deterministic);\nwall-clock is advisory through Phase 4 burn-in, then revisited.\n\n| Benchmark | Axis | Mean | Threshold |\n|---|---|---:|---:|\n| `keyword_retriever_retrieve` | cpu | 3,212 µs | 34,493 µs |\n| `directory_corpus_load` | cpu | 47 µs | 66 µs |\n| `rag_pipeline_run` (retrieval-only) | cpu | 537 µs | 625 µs |\n| `llm_reranker_rerank` | wall | 728 ms | 1.07 s |\n\nNumbers measured from N=30 back-to-back runs on the\nlocked-baseline runner (Linux `ubuntu-latest`, CPython 3.11.15).\nTwo thresholds reflect different noise profiles:\n\n- **`keyword_retriever_retrieve`** has a wide CPU band because its\n  measured σ ≈ 15.6 ms reflects cold-cache effects on the first\n  few iterations — the threshold formula is `mean + 2σ`,\n  empirically derived rather than tuned for tightness.\n- **`llm_reranker_rerank`** is wall-clock-only because Anthropic\n  network variance (σ ≈ 170 ms) dominates the CPU axis; the\n  gate is set generously and is advisory through Phase 4 W3.\n\nGated by [`.github/workflows/perf.yml`](.github/workflows/perf.yml)\nper-PR (advisory comment in Phase 4 W1–W2, blocking in W3.1).\nRaw numbers + hardware fingerprint + the full 8-row dual-axis\ntable:\n[`docs/specs/downstream-validation/perf-baseline.md`](docs/specs/downstream-validation/perf-baseline.md).\n\n### Why this is the differentiator\n\nMost RAG libraries A/B-test internally and ship the result.\nattune-rag publishes the thresholds, gates merges against them,\nand re-measures whenever the corpus, judge prompt, or hardware\nchanges. The receipts are checked in.\n\n## Bundled `.help/` corpus\n\nThe repo ships a polished `.help/` corpus that documents\nattune-rag's own surface — 143 templates across 13 features ×\n11 kinds (`concept`, `task`, `reference`, `quickstart`, `faq`,\n`error`, `warning`, `tip`, `note`, `comparison`,\n`troubleshooting`). Generated by\n[`attune-author`](https://pypi.org/project/attune-author/) with\nstrict fact-check; queryable via `AttuneHelpCorpus` or as the\nbundled default for `RagPipeline()`. See\n[`.help/features.yaml`](.help/features.yaml) for the feature\nmap and [`.help/templates/`](.help/templates/) for the content.\n\nThe 13 features: `pipeline`, `retrieval`, `corpus`, `prompts`,\n`provenance`, `providers`, `eval`, `benchmark`, `cli`, `editor`,\n`dashboard`, `expander`, `reranker`.\n\n### What faithfulness measures\n\nFaithfulness scores how well an answer is **grounded in the retrieved\npassages** — `1.0` means every claim in the answer is supported by a\ncited source; lower scores mean some claims have no support in the\ncontext. It catches hallucination in a way that `precision_at_k` and\n`recall_at_k` can't: those only measure whether the *right documents*\nwere retrieved, not whether the *generated answer* actually used them.\n\nattune-rag uses **Claude as the judge** via Anthropic's tool-use API\nto produce a structured score in `[0.0, 1.0]` for each\n`(query, answer, retrieved_context)` triple. The reported metric is\nthe mean over the golden query set. Aggregate σ ≈ `0.005` over 40\nqueries even though per-query judge non-determinism can swing 40+\npercentage points on individual queries — averaging absorbs the noise.\n\n### Run faithfulness manually\n\n```bash\npip install 'attune-rag[claude]'\nexport ANTHROPIC_API_KEY=sk-ant-...\n\n# Retrieval metrics only (free, deterministic):\nattune-rag-benchmark --queries queries.yaml --json out.json\n\n# Add faithfulness (~1 Claude API call per query, costs tokens):\nattune-rag-benchmark --queries queries.yaml --with-faithfulness --json out.json\n\n# Compare extended-thinking on vs off (2× judge cost):\nattune-rag-benchmark --queries queries.yaml --with-faithfulness --compare-thinking --json out.json\n```\n\nThe judge implementation lives at\n`attune_rag.eval.faithfulness.FaithfulnessJudge`. Note: `attune_rag.eval.*`\nis currently INTERNAL and may move — the `attune-rag-benchmark\n--with-faithfulness` CLI is the stable contract.\n\nFor the methodology behind the `0.9686` threshold, the v1/v2 ground-truth\ncalibration runs, and the extended-thinking-vs-default decision record, see\n[`docs/rag/faithfulness-thinking-calibration.md`](https://github.com/Smart-AI-Memory/attune-rag/blob/main/docs/rag/faithfulness-thinking-calibration.md).\n\n## Roadmap — embeddings (post-freeze 0.2.0+)\n\nKeyword retrieval + optional Claude reranker currently meet\nthe locked `P@1 ≥ 0.95, R@3 = 1.00` thresholds against the\nattune-help golden set. The remaining hard queries\n(3 of 28, currently `xpass`-gated under `[no-embeddings]`)\nhave zero token overlap against their target doc (e.g.\n\"vulnerability scan\" → `tool-security-audit.md`). Closing\nthat gap needs vector search.\n\nThe plan is to ship `attune-rag[embeddings]` using\n[`fastembed`](https://github.com/qdrant/fastembed) for local,\nCPU-only embeddings — no new network dependency, no API key\nrequired at retrieval time. Keyword retrieval stays the default;\nembeddings layer in opt-in, same shape as `QueryExpander` and\n`LLMReranker`. Shipping is paced by the\n[Phase 4 feature-freeze](docs/specs/downstream-validation/)\ncurrently in progress — public surface additions wait for the\n0.2.0 cut.\n\nSee\n[CHANGELOG.md](https://github.com/Smart-AI-Memory/attune-rag/blob/main/CHANGELOG.md)\nfor the decision record and remaining-gap analysis.\n\n## Prompt caching (Claude only)\n\nWhen using the Claude provider, `run_and_generate` automatically enables\n[Anthropic prompt caching](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching)\non the stable RAG context prefix (≥ 1 024 chars). This eliminates\nrepeated token costs on the corpus portion of the prompt when the same\ncontext block is reused across calls.\n\nNo configuration needed — the provider handles the `cache_control`\nheader automatically.\n\n## Public API\n\nattune-rag's public surface is documented below and snapshot-tested\nin [tests/unit/test_api_surface.py](tests/unit/test_api_surface.py).\nFormal SemVer commitments begin with the 0.2.0 release — see\n[docs/POLICY.md](docs/POLICY.md) for the deprecation policy. Until\nthen the surface is honor-system: the lock test catches drift, but\ntreat 0.1.x as still-evolving.\n\n**Top-level (`from attune_rag import ...`):**\n\n- Pipeline — `RagPipeline`, `RagResult`\n- Corpus — `CorpusProtocol`, `RetrievalEntry`, `DirectoryCorpus`,\n  `AttuneHelpCorpus`\n- Retrieval — `KeywordRetriever`, `RetrievalHit`, `RetrieverProtocol`\n- Provenance — `CitationRecord`, `CitedSource`, `ClaimCitation`,\n  `format_citations_markdown`, `format_claim_citations_markdown`\n- Prompting — `build_augmented_prompt`, `PROMPT_VARIANTS`\n- Hybrid retrieval — `QueryExpander`, `LLMReranker`\n\n**PUBLIC submodules** (importable by qualified path):\n\n- `attune_rag.corpus` — exposes `AliasInfo`, `DuplicateAliasError`\n  in addition to the top-level corpus names\n- `attune_rag.corpus.attune_help` — `AttuneHelpCorpus`\n- `attune_rag.corpus.help_adapter` — `HelpCorpusAdapter` Protocol\n- `attune_rag.providers` — `LLMProvider`, `get_provider`,\n  `list_available`\n- `attune_rag.editor` — template-editor primitives (lint, schema,\n  rename, autocomplete, references); see \"Template editor primitives\"\n  above for the symbol list\n- `attune_rag.editor.{rename,schema,lint,autocomplete,references}` —\n  the individual editor submodules\n\nAnything not listed above is INTERNAL and may change in any release.\nThe underscore-prefixed editor modules (`attune_rag.editor._rename`\netc.) shipped in 0.1.x are deprecation shims as of 0.2.0; they\nre-export the new non-underscore names and emit `DeprecationWarning`.\nThey are removed in 0.3.0.\n\n## Status\n\nv0.1.19 (alpha). In\n[Phase 4 of the v1.0 roadmap](docs/specs/ROADMAP-v1.md) — a\nfour-week feature freeze + downstream validation soak; formal\n`0.2.0` SemVer cut follows. Until then the public surface is\nhonor-system + lock-tested; deprecation policy at\n[`docs/POLICY.md`](docs/POLICY.md).\n\nPart of the attune ecosystem\n([attune-ai](https://github.com/Smart-AI-Memory/attune-ai),\n[attune-help](https://github.com/Smart-AI-Memory/attune-help),\n[attune-author](https://github.com/Smart-AI-Memory/attune-author),\n[attune-gui](https://github.com/Smart-AI-Memory/attune-gui)).\n\n## License\n\nApache 2.0. See\n[LICENSE](https://github.com/Smart-AI-Memory/attune-rag/blob/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmart-ai-memory%2Fattune-rag","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmart-ai-memory%2Fattune-rag","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmart-ai-memory%2Fattune-rag/lists"}