feat(knowledge): retrieval quality improvements (verbatim search, rerank topN, per-query topK, qwen3 prefix)#17166
Draft
eeee0717 wants to merge 5 commits into
Draft
feat(knowledge): retrieval quality improvements (verbatim search, rerank topN, per-query topK, qwen3 prefix)#17166eeee0717 wants to merge 5 commits into
eeee0717 wants to merge 5 commits into
Conversation
The kb_search tool schema taught the model to keyword-ise and split queries: describe said "Self-contained keyword search" and the query max(200) error told it to "break long questions into multiple searches". Against the hybrid (vector + BM25) retrieval pipeline this discards the model's best vector input — the user's full natural-language question — and the 200-char cap hard-blocks longer questions outright. Re-guide both the shared schema and KNOWLEDGE_SEARCH_DESCRIPTION to search the full question verbatim first, refining with keywords / synonyms / sub-questions only when the first results fall short, and raise the query cap to 500. Add coverage guidance so multi-entity / exhaustive questions gather evidence per sub-question instead of stopping at the first batch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
rerankKnowledgeSearchResults resolved its topN from a second, independent `documentCount ?? DEFAULT_DOCUMENT_COUNT` (6), while KnowledgeService.search trims to `documentCount ?? 10`. When documentCount is unset the reranker was asked for only 6 candidates, silently capping search results at 6 instead of 10 whenever a rerank model was configured. Pass the caller's resolved topK into the reranker and drop the internal fallback so the request size and the trim can never diverge. Add a regression test covering the documentCount-unset case. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
kb_search always returned the base's fixed documentCount (or 10) results, so a caller could not ask for more on questions that need broad coverage — multiple entities, project-level roundups, exhaustive answers — where a handful of results is not enough evidence. Thread an optional per-query count into KnowledgeService.search, honored by every caller of that method with one precedence: `topK ?? documentCount ?? 10`. When set it overrides the base documentCount for that call; when omitted the base default is unchanged. The three search surfaces now agree: - kb_search tool: new optional `topK` (1–50) on the input. Mirror the kb_list two-schema split so the strict AI-SDK path keeps topK in `required` via `.nullable()` while the MCP/renderer path may omit it. - `knowledge.search` IPC route: new optional `topK` (canonical doc-count schema). - REST `/knowledge-bases/search`: `document_count` now feeds the per-base search (previously ignored there) and is optional (previously a forced default of 5). It still adds a cross-base cap when provided — a flat-list concern specific to the gateway that the tool path, which reads results itself, does not need. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
Qwen3-Embedding is an instruction-aware, asymmetric retrieval model: queries carry a task instruct prefix while documents stay plain. We were embedding queries plain — off the model's training distribution — which weakened query-document alignment. Add the official instruct prefix to query embeddings only, via a small per-model registry so other query-prefix models can be added with one entry. Documents are untouched (embedKnowledgeTexts unchanged), so existing indexes stay valid and no re-embedding is needed. Models that also need a document-side prefix (E5, nomic) are intentionally excluded: they require re-embedding the corpus and are a separate change. On EnterpriseRAG-Bench (500q standalone retrieval, qwen3-embedding:0.6b) this lifts overall Recall@10 +4.34pt, semantic +3.2pt, basic +6.85pt, MRR +4.79pt vs no prefix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
Generate bounded, single-span retrieval projections during vector indexing with the configured Quick Model while failing open to authoritative raw indexing when generation is unavailable or invalid. Store projections in the per-base index and use their best cosine score per raw unit without exposing generated text to BM25, reranking, or answer evidence. Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
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.
What this PR does
Bundles four focused knowledge-base retrieval-quality improvements that were developed and validated together on a retrieval benchmark.
Before this PR:
kb_searchrewrote the query into keywords before ever trying the user's verbatim text, so exact-match passages were often missed on the first search.topNwas decoupled from the searchtopK, so reranking could operate over a different candidate count than intended.kb_search; every query used the base default.After this PR:
kb_searchtries the verbatim query first, then falls back to keyword rewriting.topNis aligned with the searchtopK.topK(result count) tokb_search; default behavior is unchanged when omitted.Fixes # N/A
Why we need it and why it was done in this way
All four target the same goal — higher first-pass retrieval recall for the knowledge base — and were measured on a 500-question retrieval benchmark. The query-side Qwen3 instruct prefix alone lifted overall Recall@10 by ~4pt with no regression.
The following tradeoffs were made:
embedKnowledgeQuerykeeps indexed chunks plain, so existing indexes stay valid and the corpus does not need re-embedding.provider::modelregistry so more query-prefix models can be added with one entry, without touching the embedding path.topKis optional. Omitting it preserves the previous default, so existing IPC/tool callers are unaffected.The following alternatives were considered:
Links to places where the discussion took place: N/A
Breaking changes
None. The Qwen3 prefix affects query embeddings only (indexes unchanged); the per-query
topKis an optional parameter that defaults to prior behavior.Special notes for your reviewer
Kept as a draft while the associated benchmark round finishes. The four commits are individually scoped (verbatim-first search, rerank topN alignment, per-query topK, Qwen3 query prefix) and can be split into separate PRs if preferred for review.
Checklist
mainfor active development,v1for v1 maintenance fixesRelease note