feat(search): tiered BM25 search (briefs/summaries/sources) + taxonomy accessors - #259
Open
sebastianbraun25 wants to merge 3 commits into
Open
feat(search): tiered BM25 search (briefs/summaries/sources) + taxonomy accessors#259sebastianbraun25 wants to merge 3 commits into
sebastianbraun25 wants to merge 3 commits into
Conversation
added 3 commits
August 28, 2026 16:25
Adds a dependency-free BM25 full-text index (openkb/fulltext_index.py) over concepts/entities/summaries pages, exposed as a new search_wiki tool alongside index.md-driven navigation in build_query_agent. Additive hybrid retrieval: surfaces pages whose one-line index summary omits a buried detail, without replacing existing navigation. Resolves VectifyAI#233.
…axonomy accessors - fulltext_index.py: extract shared _BM25Scorer from WikiFullTextIndex (no behavior change), add Locator (line/page) on SearchHit, add TieredWikiSearch with three independent tiers over summaries/ (briefs + full body) and sources/ (whole-file .md + per-page PageIndex .json, never the whole long doc as one BM25 unit). - frontmatter.py: add resolve_description()/body_only() shared helpers (kept separate from agent.compiler._resolve_description, which is under active unrelated development). - agent/tools.py: add list_taxonomy_items()/get_taxonomy_item() for semantic browsing of persisted concepts/entities (pending candidates in PendingTopicsStore are structurally excluded). - No wiring into CLI/MCP/query-agent yet (follow-up PRs); WikiFullTextIndex and agent.tools.search_wiki keep their existing signature/behavior.
sebastianbraun25
pushed a commit
to sebastianbraun25/OpenKB
that referenced
this pull request
Sep 11, 2026
…o query/chat agent - cli.py: new 'openkb list-taxonomy [--kind concept|entity] [--json]' and 'openkb search <query> [--scope briefs,summaries,sources] [--top-k N] [--json]' commands. - agent/tools.py: search_wiki now searches the new tiered briefs/summaries/sources index instead of the old combined concepts+entities+summaries index (concepts/entities move to the new list_taxonomy tool - semantic browsing, not keyword search); new list_taxonomy() text-formatting wrapper over list_taxonomy_items(). - agent/query.py (+ chat.py via tool inheritance): wires list_taxonomy and the retiered search_wiki in as agent tools; search strategy instructions updated to browse taxonomy first, then use scope-restricted search_wiki as a keyword fallback. - README.md: updated hybrid-retrieval paragraph and command table. - Intentional behavior change to agent.tools.search_wiki (scope param, concepts/entities out of scope, output grouped by tier) - safe since VectifyAI#234/VectifyAI#259, which introduced it, are not yet merged upstream; existing tests updated to the new contract.
This was referenced Sep 11, 2026
sebastianbraun25
pushed a commit
to sebastianbraun25/OpenKB
that referenced
this pull request
Sep 11, 2026
- skills/openkb/SKILL.md: 'See what's available' now leads with list_taxonomy (MCP) / 'openkb list-taxonomy' (CLI) before falling back to reading the full index.md. - 'Read content' table adds search_wiki (MCP) / 'openkb search' (CLI) rows ahead of the existing grep fallback, with a note on why BM25 ranking beats raw grep occurrence count. - 'When the KB doesn't have the answer' and the openkb-query guidance updated to reference the new search options alongside grep. - Documentation-only change; no behavior change to the underlying tools/CLI/MCP server (VectifyAI#259/VectifyAI#261/VectifyAI#263).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This PR was created in collaboration between a human and AI: implementation, tests, and
PR text were created by an AI assistant under the guidance and review of the human author.
Problem
search_wiki(#233/#234) is a single BM25 index overconcepts/,entities/, andsummaries/combined. Concepts/entities are meant to be found by semantic browsing (anLLM scanning one-line briefs and picking a slug by meaning), not keyword search — but they
share one BM25 corpus with summaries today, so a keyword-dense concept page can outrank the
summary a caller actually needed. Separately, one combined BM25 tier conflates two very
different recall needs (a generic term like "case" wants precision over which document is
about that topic; a specific fact like an exact field name wants recall into full
document bodies), and long PageIndex documents (
sources/*.json) aren't searchable at alltoday, even though details like authorship/creation dates only ever live there.
Solution / Changes
openkb/fulltext_index.py:_BM25ScorerfromWikiFullTextIndex(pure refactor, same BM25 math, nobehavior change —
WikiFullTextIndex/search()keep their exact existing signatureand output for backward compatibility with the current
search_wikitool).Locator(kind: "line"|"page",value: int) onSearchHit, computed at querytime (first-match line) or fixed at indexing time (PageIndex page number).
TieredWikiSearchwith three independent BM25 tiers, deliberately excludingconcepts/entities (see
list_taxonomy_itemsbelow):briefs— one-linedescription/legacybrieffrontmatter persummaries/*.md.summaries— full body ofsummaries/*.md(frontmatter stripped).sources—sources/*.md(whole file,linelocator) +sources/*.jsonPageIndexdocs, indexed per page (never per document), each hit carrying
Locator(kind="page", value=N)directly usable withget_page_content(doc_name, pages=str(N)). Malformed/foreign JSON undersources/is skipped, not raised.
search(query, scope=None, top_k=5)returns{tier: [SearchHit, ...]};scoperestricts to a subset of
TIERED_SCOPES = ("briefs", "summaries", "sources").openkb/frontmatter.py: newresolve_description(fm)/body_only(text)sharedhelpers. Kept as a separate copy from
agent.compiler._resolve_description(same logic)rather than importing from
compiler.py, which has several other open, unrelated PRsactively touching it.
openkb/agent/tools.py: newlist_taxonomy_items(wiki_root, kind=None)/get_taxonomy_item(slug, wiki_root, kind=None)for semantic browsing of persistedconcepts//entities/pages. Only ever surfaces committed.mdpages —PendingTopicsStore's not-yet-paged candidates are a structurally separate buffer andare never returned.
PRs (tracked separately) wire this into
openkb list-taxonomy/openkb search, thequery/chat agent's tool set, and a new MCP server.
Testing
tests/test_fulltext_index.py: 8 existing tests unchanged/still passing (backwardcompatibility of
WikiFullTextIndex); +12 new tests forTieredWikiSearch(briefs vs.full-body matching, frontmatter exclusion from body search, line/page locators,
malformed-JSON tolerance, scope validation, concepts/entities never searched).
tests/test_agent_tools.py: +13 new tests forlist_taxonomy_items/get_taxonomy_item(kind filtering, legacy
brief:fallback, missing directories, path-traversalrejection, disambiguation by kind).
ruff check,ruff format --check,mypy openkb,pytestall green — full suite: 1267passed (18 pre-existing, environment-specific failures on Windows unrelated to this
change, e.g. POSIX-only symlink/chmod-mode tests, are unaffected and unchanged in count).
Dependencies
Depends on #234(feat/issue-233-hybrid-search) — this PR is built on top of thatbranch (
WikiFullTextIndex/agent.tools.search_wiki, which it extends without changingtheir behavior). The diff below includes feat(agent): hybrid BM25 search_wiki tool for query/chat agent #234's commits; once feat(agent): hybrid BM25 search_wiki tool for query/chat agent #234 merges first, this
PR's diff will shrink to just this PR's own commit.
Issues
Resolves #258