p3: map Brave LLM Context; RRF merge; per-source no_rerank
Live llm/context hits live in grounding.generic plus a URL-keyed sources map, not a sources array. Fan-in uses reciprocal-rank fusion instead of cosine. no_rerank keeps that source's own order as a prefix.
This commit is contained in:
+18
-18
@@ -112,12 +112,14 @@ the shared fan-in. This is the Hermes SearXNG provider's request (`plugins/web/s
|
||||
|
||||
### 3.2 Brave LLM Context
|
||||
|
||||
PLAN §2, verified earlier: `GET /res/v1/llm/context?q=…` with `BRAVE_API_KEY` from
|
||||
PLAN §2: `GET /res/v1/llm/context?q=…` with `BRAVE_API_KEY` from
|
||||
`/var/lib/sift/secret.env` (0640 root:sift). **Do not read SearXNG's secret.env.**
|
||||
Header `X-Subscription-Token`. Map result URLs and snippets from the live JSON
|
||||
(`sources` and any URL-bearing fields). Do **not** assume a model-written
|
||||
`grounding` answer exists — confirm against a live response before dropping or
|
||||
keeping any field that is not a URL/title/snippet.
|
||||
Header `X-Subscription-Token`. Live response (Brave docs + Open WebUI #24120):
|
||||
hits are `grounding.generic[]` (`url`, `title`, `snippets[]`); top-level `sources`
|
||||
is a URL-keyed metadata map, not a result array. Map generic first, join
|
||||
`snippets`, then URL keys in `sources` for anything generic missed. Do **not**
|
||||
treat a model-written `grounding` string as a snippet. Fixture:
|
||||
`tests/testdata/brave_llm_context.json`.
|
||||
|
||||
This is **not** Brave Web Search (`/res/v1/web/search`). SearXNG already runs `braveapi`
|
||||
as an engine; doubling that is wasted spend.
|
||||
@@ -148,25 +150,23 @@ placeholder line the same way (empty, on-box fill).
|
||||
dropped, trailing slash dropped on the path, `www.` left as-is (different sites). First
|
||||
snippet wins; `source` becomes the first source that produced it; later sources only
|
||||
affect rerank input if they brought a longer snippet (keep the longer one).
|
||||
5. Rerank (§5) unless `rerank: false` or Dixie cannot take the call.
|
||||
5. Merge: reciprocal-rank fusion across source lists unless `rerank: false`.
|
||||
A source with `no_rerank = true` keeps its own order as a prefix (first-source
|
||||
wins on URL). Cosine/honcho-embed is not used for search.
|
||||
6. Truncate to `k` (native) or `limit` (`/v2/search`, default 5, max 20).
|
||||
7. Store in the search cache **only if** every attempted source succeeded and
|
||||
rerank did not fall back. A timeout or fallback must not pin a partial result
|
||||
for the rest of the hour (skip the write, or use a short TTL such as 2 m — skip
|
||||
is the default). Return.
|
||||
7. Store in the search cache **only if** every attempted source succeeded.
|
||||
A timeout must not pin a partial result for the rest of the hour.
|
||||
|
||||
Search **never GETs a result URL**. Agents `sift fetch` those through the P1 guard.
|
||||
|
||||
## 5. Rerank and Dixie
|
||||
## 5. Merge (RRF)
|
||||
|
||||
Embed the query and each remaining snippet with `honcho-embed` (same engine, same
|
||||
`dixie.max_inflight` FIFO as digest). Cosine similarity → `score`. Restore nothing to
|
||||
source order except on fallback.
|
||||
Fan-in uses reciprocal-rank fusion (`1/(60+rank)`) over per-source lists. Search
|
||||
does not call `honcho-embed`; Dixie saturation cannot fail a search.
|
||||
|
||||
**Dixie saturation must not fail a search:** if the embed permit cannot be had within
|
||||
`dixie.queue_wait`, or embed errors, or the queue is full → keep source-fan-in order
|
||||
(SearXNG, then Brave, then Tavily, then original rank inside a source), warning
|
||||
`rerank fell back: <reason>`. Never call chat/digest for search in P3.
|
||||
`[search.tavily] no_rerank = true` keeps Tavily's own order at the front of the
|
||||
result list; remaining sources still RRF. `rerank = false` skips RRF and keeps
|
||||
source-fan-in order (SearXNG, then Brave, then Tavily).
|
||||
|
||||
## 6. Guard boundary (SSRF)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user