Find code you can describe but not name
What you get
Your agent does not need to know a function's name to find it. It describes what the code does, and greppy returns the matching definitions with file and line. Under each hit is a sentence on what it is for, so the agent picks the right one before it reads a line. You can write the description in German even when the code is in English.
Before and after
The question for serde: How does the deserializer know how many elements to expect?
Without greppy
grep needs a word that appears in the code. The agent guesses phrasings from comments and reads on at the most promising spot.
$ grep -rniE 'how many|number of elements' --include='*.rs' .
./serde_core/src/de/mod.rs:238: /// The `len` argument is the number of elements encountered. The sequence
./serde_core/src/de/mod.rs:1129: /// knows how many values there are without looking at the serialized data.
./serde_core/src/de/mod.rs:1776: /// Returns the number of elements remaining in the sequence, if known.
./serde_core/src/de/value.rs:1035: // First argument is the number of elements in the data, second
…
./serde/src/private/de.rs:2761: // argument is the number of elements expected by the Deserialize.
$ sed -n 1774,1780p serde_core/src/de/mod.rs
}
/// Returns the number of elements remaining in the sequence, if known.
#[inline]
fn size_hint(&self) -> Option<usize> {
None
}
With greppy
$ greppy search "wie viele Elemente der Deserializer erwarten soll"
serde/src/private/de.rs:1582 SeqDeserializer::size_hint — returns a size hint computed from the iterator bounds
serde/src/private/de.rs:1764 MapDeserializer::size_hint — returns a size hint computed from the iterator bounds
serde/src/private/de.rs:2541 SeqRefDeserializer::size_hint — returns a size hint computed from the iterator bounds
serde/src/private/de.rs:2710 MapRefDeserializer::size_hint — returns a size hint computed from the iterator bounds
serde_core/src/de/value.rs:1434 MapDeserializer::size_hint — returns a size hint computed from the value's iter
serde_core/src/de/value.rs:1103 SeqDeserializer::size_hint — returns a size hint computed from the value's iter
serde_core/src/de/mod.rs:1778 SeqAccess::size_hint — returns None unconditionally
serde_core/src/de/mod.rs:1937 MapAccess::size_hint — returns None unconditionally
| without greppy | with greppy | |
|---|---|---|
| Calls | 2 | 1 |
| Output characters | 3,535 | 850 |
| Tokens | 791 | 198 |
How it works
While indexing, greppy computes an embedding for every definition with Google's EmbeddingGemma. search embeds your description the same way and returns the definitions closest in meaning, eight per query. The sentences after the hits are written from the source by a Qwen3.5-0.8B that we trained by distillation. Both models run locally on your GPU; index and embeddings stay on your machine. For names and text you have search-symbol and search-pattern; plus combines text, name, meaning and graph signals into one ranked list.
The commands
| Command | what it does |
|---|---|
greppy search "…" |
definitions that do what the description says, each with a sentence on its purpose |
greppy search-symbol NAME |
definitions whose name contains NAME; without a hit, similar names follow |
greppy search-pattern REGEX |
every source line the regular expression matches, with the definition it sits in |
greppy plus QUERY |
one ranked list from text, symbol, meaning and graph signals as grep-style lines |
More in the docs
- Search: every search command, flag and example
- How greppy works: index, embeddings and the local models