Deep research over MFS-indexed sources
1. What this is (and what it replaces)
deep-searcher is an
open-source framework that reasons over private data: it decomposes a
question, iteratively searches a vector database, evaluates whether the
evidence is sufficient, and synthesizes a cited report. Built before
agentic coding tools existed, it had to hand-roll every piece itself —
document loaders, a multi-provider LLM/embedding/vector-DB matrix, and a
custom iterative-retrieval orchestration loop in Python.
None of that orchestration is needed anymore. MFS already does ingestion +
hybrid search over many source types, and an agent's own reasoning loop
already does "search, judge, follow up, repeat" natively once it has a
search tool. This skill is that missing piece: not new retrieval code, just
the strategy for running deep-searcher's decompose → search → evaluate
→ synthesize loop through mfs search / mfs cat.
This skill assumes mfs-find for the actual command mechanics (search
modes, locators, --peek/--skim, index-status diagnosis). Read that
skill for those details — this one only adds the multi-round strategy on
top.
2. Precondition: sources must be indexed
Same as mfs-find: mfs status / mfs connector inspect <uri> first. If
nothing relevant is indexed yet, redirect to mfs-ingest — don't run a
research loop against an empty index.
3. The loop
decompose search rounds evaluate synthesize
┌───────────┐ ┌───────────────────────┐ ┌──────────────────┐ ┌───────────┐
│ 2-4 angles│ → │ mfs search per angle, │ → │ enough coverage? │ → │ cited │
│ on the Q │ │ semantic + keyword │ │ gaps → new angles│ │ report │
└───────────┘ └───────────────────────┘ └──────┬───────────┘ └───────────┘
▲ │ not enough
└────────────────────────────┘ (max ~4 rounds)
Decompose. Break the question into 2-4 concrete angles before
searching anything. "Write a report on our rate-limiting story" becomes:
current implementation, past incidents/bugs, design
discussion/rationale, config knobs. A single search for the raw
question under-recalls on anything but the narrowest asks.
Search each angle, scope per mfs-find §6-7 (hybrid by default,
--all for genuinely cross-source asks, scoped to 2-3 likely sources
otherwise):
mfs search "<angle 1>" <scope> --top-k 15
mfs search "<angle 2>" <scope> --top-k 15
...
Track distinct objects found (dedupe by source), not raw hit
count — five chunks from one file is one citation, not five.
Evaluate coverage before reading everything. For each angle: is
there at least one strong hit? For the question as a whole: do the
found objects, read together, actually answer it, or do they only
establish that the topic exists? Common gaps: an angle returned nothing
(rephrase it, don't drop it silently), all hits are from one source
type when the question implies more (e.g. only code, no design docs),
or a hit references something ("see the migration doc") not yet found.
Follow up, don't restart. Gaps become 1-3 new targeted searches —
reuse the vocabulary actually found in round 1 (a real error code, a
real doc title) instead of guessing more synonyms of the original
question. This is the step deep-searcher's LLM-driven query refinement
automated; here it's just another mfs search call informed by what
came back.
Stop condition. Whichever comes first:
- a round adds no new distinct objects (saturation), or
- every decomposed angle has a strong hit and no unresolved reference
remains, or
- ~4 rounds (glance at whether the effort is still paying off,
don't hard-stop exactly at 4 if one more obvious query would close a
real gap — but don't grind past it chasing marginal recall either).
Read before writing. mfs cat --skim (or --peek for code) each
distinct candidate object before citing it — a search snippet is enough
to judge relevance, not enough to write a claim from. Full cat --range only the sections a claim actually rests on.
4. Report format
- Structure by the decomposed angles (or by whatever natural sections the
findings suggest), not by search-round order.
- Cite inline with the
source URI after each claim, e.g. ... retries with exponential backoff (server/python/src/mfs_server/engine/pipeline.py).
Never state a fact pulled from search without attributing which source
it came from — an uncited claim in a "report" is indistinguishable from a
guess.
- End with a flat Sources list of every distinct object cited, so the
user can jump straight to any of them.
- Say plainly when an angle came up empty ("no design rationale found for
X — only the implementation") rather than papering over the gap.
5. Anti-patterns
- Don't answer a "write a report" ask from one search call. That's the
exact failure mode this skill exists to prevent — one query under-covers
a multi-angle question even when the top hit looks relevant.
- Don't keep searching after saturation. If two rounds in a row surface
no new distinct objects, stop and write up what's there — more rounds
won't manufacture evidence that isn't indexed.
- Don't cite a chunk you didn't read. A snippet score is a relevance
signal, not a verified fact.
- Don't use this for a narrow, single-hit question ("what does
MFS_API_TOKEN do") — that's mfs-find's job in one call; running the
full loop on it just burns rounds for no benefit.
- Don't silently drop an angle that returned nothing — say so, or
rephrase it once with different vocabulary before giving up on it.
1---2name: deep-research3description: Answer a broad, open-ended, or multi-part question by iteratively searching MFS-indexed sources, following up on gaps, and synthesizing a cited report — the same "reason and search over private data" job zilliztech/deep-searcher does, but as a skill on top of `mfs-find` instead of a standalone framework. Use when the user asks for a report, a comprehensive/synthesized answer, a "what do we know about X across everything we have", or a question that can't be answered from a single search hit. Trigger phrases include "write a report on X", "deep-dive into X using our data", "research X across all our sources", "give me a comprehensive answer on X with citations", "synthesize what we know about X". Do NOT use for a single fact lookup or a targeted question with an obvious one-hit answer — use `mfs-find` directly for that; this skill is for genuinely broad, multi-angle asks. Requires `mfs-find` for the underlying search/read mechanics.4---56# Deep research over MFS-indexed sources78## 1. What this is (and what it replaces)910[deep-searcher](https://github.com/zilliztech/deep-searcher) is an11open-source framework that reasons over private data: it decomposes a12question, iteratively searches a vector database, evaluates whether the13evidence is sufficient, and synthesizes a cited report. Built before14agentic coding tools existed, it had to hand-roll every piece itself —15document loaders, a multi-provider LLM/embedding/vector-DB matrix, and a16custom iterative-retrieval orchestration loop in Python.1718None of that orchestration is needed anymore. MFS already does ingestion +19hybrid search over many source types, and an agent's own reasoning loop20already does "search, judge, follow up, repeat" natively once it has a21search tool. This skill is that missing piece: not new retrieval code, just22the **strategy** for running deep-searcher's decompose → search → evaluate23→ synthesize loop through `mfs search` / `mfs cat`.2425This skill assumes `mfs-find` for the actual command mechanics (search26modes, locators, `--peek`/`--skim`, index-status diagnosis). Read that27skill for those details — this one only adds the multi-round strategy on28top.2930## 2. Precondition: sources must be indexed3132Same as `mfs-find`: `mfs status` / `mfs connector inspect <uri>` first. If33nothing relevant is indexed yet, **redirect to `mfs-ingest`** — don't run a34research loop against an empty index.3536## 3. The loop3738```39 decompose search rounds evaluate synthesize40┌───────────┐ ┌───────────────────────┐ ┌──────────────────┐ ┌───────────┐41│ 2-4 angles│ → │ mfs search per angle, │ → │ enough coverage? │ → │ cited │42│ on the Q │ │ semantic + keyword │ │ gaps → new angles│ │ report │43└───────────┘ └───────────────────────┘ └──────┬───────────┘ └───────────┘44 ▲ │ not enough45 └────────────────────────────┘ (max ~4 rounds)46```47481. **Decompose.** Break the question into 2-4 concrete angles before49 searching anything. "Write a report on our rate-limiting story" becomes:50 *current implementation*, *past incidents/bugs*, *design51 discussion/rationale*, *config knobs*. A single search for the raw52 question under-recalls on anything but the narrowest asks.53542. **Search each angle**, scope per `mfs-find` §6-7 (hybrid by default,55 `--all` for genuinely cross-source asks, scoped to 2-3 likely sources56 otherwise):57 ```bash58 mfs search "<angle 1>" <scope> --top-k 1559 mfs search "<angle 2>" <scope> --top-k 1560 ...61 ```62 Track **distinct objects** found (dedupe by `source`), not raw hit63 count — five chunks from one file is one citation, not five.64653. **Evaluate coverage before reading everything.** For each angle: is66 there at least one strong hit? For the question as a whole: do the67 found objects, read together, actually answer it, or do they only68 establish that the topic exists? Common gaps: an angle returned nothing69 (rephrase it, don't drop it silently), all hits are from one source70 type when the question implies more (e.g. only code, no design docs),71 or a hit references something ("see the migration doc") not yet found.72734. **Follow up, don't restart.** Gaps become 1-3 new targeted searches —74 reuse the vocabulary actually found in round 1 (a real error code, a75 real doc title) instead of guessing more synonyms of the original76 question. This is the step deep-searcher's LLM-driven query refinement77 automated; here it's just another `mfs search` call informed by what78 came back.79805. **Stop condition.** Whichever comes first:81 - a round adds no new distinct objects (saturation), or82 - every decomposed angle has a strong hit and no unresolved reference83 remains, or84 - **~4 rounds** (glance at whether the effort is still paying off,85 don't hard-stop exactly at 4 if one more obvious query would close a86 real gap — but don't grind past it chasing marginal recall either).87886. **Read before writing.** `mfs cat --skim` (or `--peek` for code) each89 distinct candidate object before citing it — a search snippet is enough90 to judge relevance, not enough to write a claim from. Full `cat91 --range` only the sections a claim actually rests on.9293## 4. Report format9495- Structure by the decomposed angles (or by whatever natural sections the96 findings suggest), not by search-round order.97- **Cite inline** with the `source` URI after each claim, e.g. `... retries98 with exponential backoff (server/python/src/mfs_server/engine/pipeline.py)`.99 Never state a fact pulled from search without attributing which source100 it came from — an uncited claim in a "report" is indistinguishable from a101 guess.102- End with a flat **Sources** list of every distinct object cited, so the103 user can jump straight to any of them.104- Say plainly when an angle came up empty ("no design rationale found for105 X — only the implementation") rather than papering over the gap.106107## 5. Anti-patterns108109- **Don't answer a "write a report" ask from one search call.** That's the110 exact failure mode this skill exists to prevent — one query under-covers111 a multi-angle question even when the top hit looks relevant.112- **Don't keep searching after saturation.** If two rounds in a row surface113 no new distinct objects, stop and write up what's there — more rounds114 won't manufacture evidence that isn't indexed.115- **Don't cite a chunk you didn't read.** A snippet score is a relevance116 signal, not a verified fact.117- **Don't use this for a narrow, single-hit question** ("what does118 `MFS_API_TOKEN` do") — that's `mfs-find`'s job in one call; running the119 full loop on it just burns rounds for no benefit.120- **Don't silently drop an angle that returned nothing** — say so, or121 rephrase it once with different vocabulary before giving up on it.