Skip to main content

wenji 文集

丟一個 markdown 資料夾,得到混合搜尋 + Web UI。零 LLM 建索引,語料越大越穩。

Python License: MIT CI

🇹🇼 繁體中文 · 🇬🇧 English

⚠️ Pre-1.0 — API 可能在 minor 版本間變更。


繁體中文

為什麼選 wenji?

大多數 RAG 框架預設「LLM-default」:建索引用 LLM 抽 entity、LLM 做摘要、LLM 重排序 — 成本隨語料線性成長,LLM 不可用時整個系統停擺。

wenji 走相反路線 — LLM-essential, not LLM-default:建索引零 LLM 呼叫、byte-identical 可重建;LLM 只允許在查詢時用(/api/ask 問答),必須 cache、必須有確定性 fallback。LLM 成本 = unique queries × cache miss rate,與語料大小無關。

特色 實現方式
零 LLM 建索引 SQLite FTS5 (BM25) + ONNX BGE-M3 INT8,byte-identical 重建
完全本地 一個 Python 行程 + 一個 SQLite 檔,無 vector DB、無外部 API
可量測 JSONL eval runner + 80 題回歸基準,檢索改動必過 before/after

適合:講道、課堂筆記、法律條文、古典詩詞、技術文章等中文(或中英混合)語料的本地搜尋與瀏覽。

快速上手

pip install wenji
wenji ingest dir <你的-markdown-目錄>/ --db wenji.db
wenji serve --db wenji.db --port 8000

打開 http://127.0.0.1:8000 — 完整 Web UI:搜尋(分軸 sidebar)、/tags 瀏覽、文章閱讀器(TOC + query-aware 捲動)。沒有語料可先 git clone 本 repo 用 examples/articles/ 示範集。

CLI 搜尋:

wenji search "勞動契約" --db wenji.db

首次執行自動下載 embed model(~600 MB)。支援 Python 3.10–3.12;平台支援與大語料運維(續跑、--skip-bad)見 docs/deployment.md

搜尋架構

Searcher.search() 執行 8 步 pipeline:

entity detect → intent detect → alias expand
  → BM25 + vector → chunk BM25 → RRF merge (intent boost)
  → entity scoring + filter → snippet hydration

entity/intent 層為選配(--entity-source example:corpus-christian --intent-source example:corpus-christian 啟用,可多來源組合,詳見 docs/extending.md);省略時退化為純 RRF + chunk signals。search.alpha 等調參走 wenji.yamldocs/deployment.md)。

分類引擎

# axes.yaml — 摘錄自 examples/axes.yaml
axes:
  - id: sermon
    name: 講道
    rules:
      - source_type: sermon
        primary: true

每條 rule 支援 source_type / tag / title_regex / subtype 的 AND 組合與階層 parent。Axes 是 derived data — wenji classify 隨時重建,不動原始 markdown。

常用命令

命令 用途
wenji ingest dir <path> 建索引(中斷後重跑同命令即續跑)
wenji search / wenji serve CLI 搜尋 / Web UI
wenji classify --config axes.yaml 套用分類軸
wenji doctor db 一致性 + 建庫環境健檢(部署前必跑)
wenji eval run-benchmark 80 題回歸基準(改檢索前後各跑一次)
wenji stats / wenji segment <q> corpus 快照 / query pipeline trace

完整子命令 wenji --help/api/ask 問答的 LLM 設定(任何 OpenAI-compatible endpoint)與密鑰安全見 docs/deployment.md

部署

wenji serve 預設無認證、無速率限制 — 對外發布前請照 docs/deployment.md 走一遍:API key / CORS / 反代 / SEO meta / wenji doctor 驗庫。

生態

專案 說明
trad-zh-search 繁體中文文本預處理 — CKIP 分詞 + bigram 索引,可搭配主流搜尋引擎
vault-curate Obsidian 本地語意搜尋 — 中文友善、無雲端、無 API Key

貢獻與授權

pip install -e ".[dev]"
ruff check src/wenji tests/wenji && ruff format --check src/wenji tests/wenji
pytest                              # unit
pytest -m integration               # 真實 ONNX(需下載 ~600 MB)

詳見 CONTRIBUTING.mdMIT © 2026 notoriouslab


English

At a glance

What Drop a folder of markdown files in, get hybrid search + a web UI out.
Who for Anyone with a Chinese (or mixed-language) markdown corpus who wants real search without renting a vector DB.
Stack SQLite FTS5 (BM25) + ONNX BGE-M3 (vector) + libsimple (CJK tokenizer) + FastAPI
Indexing Zero LLM calls. Deterministic, byte-identical rebuild from disk.
LLM use Optional, query-time only (/api/ask), cached, with a deterministic fallback.
Deploy One Python process, one SQLite file. Python 3.10–3.12.

Quickstart

pip install wenji
wenji ingest dir <your-markdown-dir>/ --db wenji.db
wenji serve --db wenji.db --port 8000

Open http://127.0.0.1:8000 for the full web UI (search, tag browsing, article viewer). No corpus handy? Clone this repo and ingest examples/articles/.

Search pipeline

entity detect → intent detect → alias expand
  → BM25 + vector → chunk BM25 → RRF merge (intent boost)
  → entity scoring + filter → snippet hydration

The entity/intent layer is optional (--entity-source example:corpus-christian); without it the pipeline degrades to RRF + chunk signals. Classification axes come from a user-supplied axes.yaml (rules on source_type / tag / title_regex / subtype) and are derived data — rebuilt any time.

Going further

  • Deployment (auth, CORS, SEO meta, secrets hygiene, platforms, ops): docs/deployment.md
  • Extending (entity/intent dictionaries, wenji.yaml tuning, from_sources): docs/extending.md
  • Eval: wenji eval run-benchmark — run before/after any retrieval change; pass counts and miss lists must not regress.

Ecosystem

Project Description
trad-zh-search Traditional Chinese preprocessing: CKIP segmentation + bigram index generation.
vault-curate Obsidian local semantic search — Chinese-friendly, no cloud, no API key.

Star History

Star History Chart

Development & license

pip install -e ".[dev]"
ruff check src/wenji tests/wenji && ruff format --check src/wenji tests/wenji
pytest && pytest -m integration

See CONTRIBUTING.md. MIT © 2026 notoriouslab

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wenji-0.5.2.tar.gz (126.9 kB view details)

Uploaded Source

Built Distribution

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

wenji-0.5.2-py3-none-any.whl (154.9 kB view details)

Uploaded Python 3

File details

Details for the file wenji-0.5.2.tar.gz.

File metadata

  • Download URL: wenji-0.5.2.tar.gz
  • Upload date:
  • Size: 126.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wenji-0.5.2.tar.gz
Algorithm Hash digest
SHA256 0518a3722527aa768255e603babb05b3e53147ffd5abda0298f87bc8ee131c1d
MD5 38a8d4fe5160c60bb523c4694652f05f
BLAKE2b-256 c8c53880871d1beff57aca58087c9647142837d4813b7be665f1a5d33ce2c1ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for wenji-0.5.2.tar.gz:

Publisher: release.yml on notoriouslab/wenji

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wenji-0.5.2-py3-none-any.whl.

File metadata

  • Download URL: wenji-0.5.2-py3-none-any.whl
  • Upload date:
  • Size: 154.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wenji-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 240e5a3b25c40178288bbde4185bf67195bf19a34b04666e97ac0d7294ae5735
MD5 c09a1f14bc7094e5683ca0196efef7b6
BLAKE2b-256 18a0e4b7373d69acf20d045385ca9db86408e378b32973cce7878c032d4c93d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for wenji-0.5.2-py3-none-any.whl:

Publisher: release.yml on notoriouslab/wenji

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

This release

0.5.2 This release

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page