Gemma Embed Search
Lokale Dateien nach ihrer Bedeutung finden. Ein einziger Embedding-Raum enthält Bilder, Audio und Text, sodass eine Texteingabe die passenden Bilder, Clips oder Dokumente zurückgibt. Das Modell läuft auf der Hardware des Benutzers über einen lokalen Server; es wird nichts hochgeladen.
scripts/embed_search.py erledigt vier Aufgaben: doctor prüft den Server, init speichert die
Verbindung, index bettet Dateien in einen Cache ein und search ordnet sie nach einer Abfrage.
Lokale Konfiguration
Die Einstellungen befinden sich in config.json, niemals in dieser Datei:
- Linux und macOS:
~/.config/gemma-embed-search/config.json - Windows:
%USERPROFILE%\.config\gemma-embed-search\config.json
Lesen Sie diese Datei zuerst. Wenn sie url und model enthält, funktioniert jeder spätere Befehl ohne
Verbindungsflags und Sie können Schritt 2 überspringen.
Wenn sie fehlt oder unvollständig ist, fragen Sie den Benutzer nach der Server-URL und dem zu indizierenden Ordner, führen Sie
doctor aus, um die Modelle aufzulisten, die der Server tatsächlich anbietet, und führen Sie dann init aus, um die Datei zu schreiben.
init führt eine Zusammenführung durch, daher ist das Hinzufügen einer Einstellung nach der anderen sicher. Raten Sie niemals einen Modellnamen.
Das Kopieren von config.example.json aus diesem Ordner in diesen Pfad und das Bearbeiten erledigt dieselbe Arbeit
wie init, für einen Benutzer, der die Datei lieber direkt bearbeiten möchte. Fügen Sie "api_key" nur dort hinzu, wenn
der Server einen benötigt.
Speichern Sie Einstellungen niemals im Skill-Ordner selbst. Ein Update des Skills ersetzt jede Datei darin, und alles, was dort geschrieben wurde, geht verloren.
Einrichtungs-Checkliste
Fortschritt:
- Schritt 1: Server bestätigen und Modellnamen auswählen (
doctor) - Schritt 2: Verbindung speichern (
init) - Schritt 3: Einen Pilotdurchlauf mit 20 Dateien indizieren und eine Abfrage überprüfen
- Schritt 4: Den gesamten Ordner indizieren
- Schritt 5: Die eigentliche Abfrage des Benutzers beantworten, mit
--html, damit er die Treffer sehen kann
Überspringen Sie Schritt 2, wenn config.json bereits url und model enthält.
Führen Sie das Skript mit uv run scripts/embed_search.py aus (installiert Pillow über die Inline-Metadaten
des Skripts) oder python3 scripts/embed_search.py, wenn Pillow bereits importierbar ist.
Schritt 1 — Server und Modellname finden. Raten Sie niemals den Modellnamen; lesen Sie ihn vom Server ab.
uv run scripts/embed_search.py --url http://127.0.0.1:1235 doctor
doctor zeigt die Modelle an, die der Server anbietet, und testet ein Embedding. Wenn der Benutzer noch
keinen Server gestartet hat, lesen Sie references/setup.md und geben Sie ihm den
Befehl für sein Modell.
Schritt 2 — Speichern, damit spätere Aufrufe keine Flags benötigen. Übergeben Sie --api-key nur, wenn der Server
einen benötigt; es wird mit Modus 0600 in die Konfigurationsdatei geschrieben. Übergeben Sie --root bei jedem
späteren Befehl, um mit einem anderen Ordner zu arbeiten, ohne das Gespeicherte zu ändern.
uv run scripts/embed_search.py --url http://127.0.0.1:1235 --model <name-from-doctor> init --root <folder>
uv run scripts/embed_search.py index --limit 20
Schritt 3 — Pilot vor dem langen Lauf. Die Indizierung ist der teure Schritt: ungefähr 0,25 s pro Bild auf einer Desktop-GPU, also dauern 10.000 Dateien etwa 40 Minuten. Indizieren Sie 20 Dateien, führen Sie eine Abfrage aus und bestätigen Sie, dass die Ergebnisse richtig aussehen, bevor Sie sich auf den vollständigen Durchlauf festlegen.
Schritt 4 — Vollständige Indizierung. Ein erneuter Aufruf von index bettet nur neue oder geänderte Dateien ein, sodass
ein unterbrochener Lauf von selbst fortgesetzt wird.
uv run scripts/embed_search.py index
Schritt 5 — Suchen.
uv run scripts/embed_search.py search "ein schwarzer Labrador am Strand" --top 20 --html hits.html
Abfragen-Kochbuch
| Absicht | Befehl |
|---|---|
| Einfache semantische Suche | search "ein belebter Nachtmarkt" |
| Zwei Facetten, die beide zutreffen müssen | search "eine Frau" --must "die Farbe Gelb" |
| Synonyme, damit eine Formulierung nicht dominiert | search "eine Frau" --also "ein Mädchen" --also "weibliches Porträt" |
| Jedes Bild finden, das X enthält | search "Charaktere mit roten Haaren" --top 60 --html hits.html |
| Subjekt plus eine echte Farbbeschränkung | search "eine Frau" --color gelb --min-color 0.05 |
| Hauptsächlich monochrome oder dunkle Bilder | search "beliebiges Bild" --max-color blau --modality image |
| Nur eine Dateiart | search "Sirenengeräusche" --modality audio |
| Maschinenlesbar für weitere Arbeit | search "..." --json --top 50 |
| Schneller, etwas weniger genaue Bewertung | search "..." --dims 256 |
--also mittelt Paraphrase-Vektoren zu einer Abfrage. --must behält die Punktzahl der
schwächsten Facette bei, so drücken Sie UND aus. Verwenden Sie --also für Synonyme und --must für
unabhängige Bedingungen.
Ausgabe lesen
Die normale Ausgabe ist score [modality] path, beste zuerst. Farbläufe fügen das Pixelverhältnis
nach der Punktzahl ein. --json gibt {"query", "index", "total", "filtered_out", "results": [{"rank", "score", "color", "modality", "path"}]} auf stdout aus; alle Fortschrittsmeldungen gehen nach stderr, sodass
stdout immer sauber in jq weitergeleitet werden kann.
Cosinus-Ähnlichkeitswerte dieser Modellfamilie liegen zwischen etwa 0,3 und 0,8. Die absolute Zahl bedeutet wenig; der Unterschied zwischen Treffern und Nicht-Treffern ist wichtig. Wenn die Spitze der Liste falsch ist, ist die Abfrage falsch — formulieren Sie sie neu, anstatt der Rangfolge zu vertrauen. Präsentieren Sie niemals eine lange Liste als gleich gut: nennen Sie, wo die sicheren Ergebnisse aufhören und das Raten beginnt.
Eine kurze Liste ist nicht die ganze Antwort. Jede indizierte Datei erhält eine Punktzahl, daher sagt die total in der
Ausgabe die Größe des gesamten Korpus aus, sagt aber nie, wie viele Ergebnisse plausibel sind. Finden Sie stattdessen
den Abgrund — den Punkt, an dem die Punktzahlen nicht mehr stark fallen. Wenn die Liste, die Sie gezeigt haben, vorher endet,
sagen Sie, dass die Ergebnisse abgeschnitten sind, und bieten Sie einen längeren Durchlauf an: ein größeres --top kostet nur
einen weiteren Kontaktbogen, keine erneute Indizierung. Respektieren Sie eine vom Benutzer genannte Anzahl und geben Sie
immer noch den von Ihnen angewandten Grenzwert an. Behaupten Sie niemals "es gibt keine", ohne eine erweiterte Liste,
--top 100 oder mehr, die tatsächlich jemand angesehen hat.
Für die visuelle Überprüfung bieten Sie immer --html an: es schreibt einen Kontaktbogen mit Miniaturansichten,
Punktzahlen und Dateinamen, den der Benutzer in einem Browser öffnen kann. Ein bloßes --html schreibt hits.html
im Arbeitsverzeichnis; --html FILE legt den Pfad fest. Miniaturansichten werden als Base64 eingebettet, sodass
der Bogen in sich geschlossen ist und allein reisen kann. Der Bogen bettet echte Miniaturansichten der gefundenen
Dateien ein, behandeln Sie ihn daher als Kopie dieses Teils der Bibliothek: halten Sie ihn aus der Versionskontrolle
und allem, was Sie weiterleiten, heraus. Sie sind standardmäßig 512 Pixel breit; erhöhen Sie
--thumb-width für eine genaue Untersuchung von Details.
Fallstricke
- Ein Farbwort im Abfragetext ist ein weicher Hinweis, kein Filter.
"eine Frau mit einem gelben Thema"ordnet eine Frau in einer orangefarbenen Jacke an erster Stelle. Verwenden Sie--color gelb --min-color 0.05für eine echte Einschränkung; sie wird aus Pixeln berechnet, nicht aus dem Modell. - Ein Stilwort ist ebenfalls ein weicher Hinweis und ein noch schwächerer.
"eine fotorealistische Frau mit roten Haaren"ordnet eine Tintenzeichnung einer rothaarigen Frau an erster Stelle, weil die Subjektnomen den Stil überwiegen. Verschieben Sie den Stil in--must, damit er als eigene Facette bewertet wird, und fixieren Sie das visuelle Attribut mit--color. Keines ist ein echter Filter:--mustnimmt das Minimum über Facetten hinweg, daher wird durch starkes Drücken auf eine Facette die andere aufgegeben. - Mehrere Subjekte in einem Bild verschmelzen zu einem einzigen Vektor, daher schneidet das Bild bei einer
Einzelsubjekt-Abfrage schlechter ab als ein Bild, das diesem Subjekt gewidmet ist: ein Porträt einer rothaarigen Frau
neben einem Mann kann bei einer Suche nach
"Frau mit roten Haaren"weit unten landen, während es bei"Charaktere mit roten Haaren"nahe der Spitze rangiert. Synonyme derselben einzelnen Idee helfen nicht; die Plural- oder Kollektivform hilft. Erweitern Sie--top, wenn die Frage "finde alles, was X enthält" lautet. --colorbenötigt, dass der Index Farbstatistiken enthält, die nurindexberechnet. Ein Index, der mit einer älteren Version erstellt wurde, meldet 0,0 für alles: Indizieren Sie mit--forceneu, wenn die Farbfilterung stillschweigend jede Datei ausschließt.- Index und Abfrage müssen dasselbe Modell verwenden. Ein Wechsel von
--modelmischt stillschweigend inkompatible Vektoren; indizieren Sie nach jeder Modelländerung mit--forceneu und notieren Sie das Modell instats. - Der Server muss das Embedding-Modell mit Mean-Pooling und geladenem Vision-Projektor
(
--mmproj) ausführen. Ohne den Projektor schlagen Bildanforderungen fehl oder geben einen Vektor zurück, der das Bild ignoriert.doctorbeweist, dass Text funktioniert; führen Sie eine Bildabfrage aus, um die Bildverarbeitung zu beweisen. - Bilder werden als JPEG mit einer längsten Seite von 1536 neu codiert, bevor sie gesendet werden. Die Neucodierung ist
erforderlich, nicht kosmetisch: Server lehnen häufig WebP, 16-Bit oder falsch beschriftete Dateien ab, und
Pillow liest diese stattdessen. Das Modell hat kein Pixel-Limit — der Server tastet jedes Bild
auf ein festes Vision-Token-Budget um — daher tauscht
--resizeUpload-Größe gegen Genauigkeit, nicht Korrektheit. Gemessene Zahlen und die Details finden Sie in references/setup.md. - HEIC- und Raw-Kameraformate werden nicht gelesen, es sei denn, Pillow wurde mit dem entsprechenden Plugin erstellt. Das
Skript protokolliert
skip <file>: cannot identify image fileund fährt fort; überprüfen Sieskipped_errorsin der Indexzusammenfassung, anstatt von vollständiger Abdeckung auszugehen. searchin einem Ordner, der nie indiziert wurde, beendet sich mit Exit-Code 4 und einer Meldung. Behandeln Sie eine leere Ergebnisliste nicht als "keine Treffer", bis die Indexanzahl instatskorrekt aussieht.- Audio ist durch den Serverkontext begrenzt: etwa 5,5 Minuten pro Clip bei 25 Token pro Sekunde. Längere Dateien schlagen als Anforderungsfehler fehl, nicht als schlechter Treffer.
- Punktzahlen sind nicht über verschiedene Korpora oder Quantisierungen hinweg vergleichbar. Versprechen Sie niemals einen
Schwellenwert; stimmen Sie
--min-colorund--topauf das ab, was der Benutzer sieht.
Skript-Referenz
doctor Server prüfen, Modelle auflisten, ein Embedding testen
init [--root DIR] url, model, key und Standard-Root in der Konfigurationsdatei speichern
index --root DIR Neue und geänderte Dateien einbetten (inkrementell, fortsetzbar)
[--modality auto|image|audio|text] [--include '*.png,sub/*.jpg']
[--exclude-dir node_modules,.git] [--limit N] [--batch 16] [--resize 1536]
[--force] [--compact]
search "Abfrage" Indizierte Dateien bewerten; gibt Punktzahl, Modalität, Pfad aus
[--also P]... [--must P]... [--color NAME --min-color F | --max-color F]
[--modality image] [--dims 512|256|128] [--top 20] [--offset 0]
[--json] [--html [FILE]] [--thumb-width 512]
stats Eintragsanzahl, Modalitätsmix, Modell, Indexgröße
Exit-Codes: 0 Erfolg, 2 Anwendungsfehler, 3 Server nicht erreichbar oder Authentifizierung abgelehnt,
4 Index fehlt, 5 nichts zu tun, 6 Serverfehler während des Laufs. Führen Sie
scripts/embed_search.py <command> --help für die vollständige Flag-Dokumentation aus.
Die Konfigurationsauflösung ist Flag > Umgebung (EMBED_SEARCH_URL, EMBED_SEARCH_MODEL,
EMBED_SEARCH_API_KEY, EMBED_SEARCH_ROOT) > Konfigurationsdatei unter
~/.config/gemma-embed-search/config.json. Der Index standardmäßig auf
~/.cache/gemma-embed-search/<folder>-<hash>.jsonl, ein JSON-Datensatz pro Datei, daher ist es
sicher, mehrere Indizes für verschiedene Ordner zu führen.
Weitere Details
- references/setup.md — Server starten, Modell- und Flag-Anforderungen, was
doctorbedeutet - references/query-guide.md — Abfragekonstruktion, Facettenlogik, Farbschwellen, Abstimmung auf reale Ergebnisse
- references/errors.md — jeder Exit-Code und die Lösung für jeden Fehlermodus