This guide walks you through installing Antfly, loading data, and running your first queries — from full-text search to semantic search to AI-powered RAG.
Install Antfly
brew install antflydb/taps/antfly
# Verify
antfly --version
Start Antfly
Start Antfly in standalone mode:
antfly standalone --inference-host-budget-mb 8192 2>&1 | tee "antfly.log"
If you installed with Homebrew, you can run Antfly as a service instead:
brew services start antfly
Standalone mode starts metadata, data nodes, and Antfly inference in a single process — ideal for local development. You can also access the web dashboard at http://localhost:8080 to manage tables, run queries, and monitor your cluster.
The 8 GiB inference host budget lets the later all-local RAG example use the embedding, reranking, and Gemma models in one request. If you use a hosted generator instead, you can omit that option.
Verify the basic data path
Before starting the longer semantic workflow, verify that storage and full-text search work with one document:
curl -fsS -X POST http://localhost:8080/db/v1/tables/hello \
-H "Content-Type: application/json" \
-d '{}'
curl -fsS -X POST http://localhost:8080/db/v1/tables/hello/batch \
-H "Content-Type: application/json" \
-d '{"inserts":{"first":{"title":"Hello","body":"Antfly is ready."}},"sync_level":"full_text"}'
antfly query --table hello \
--full-text-search 'body:Antfly' \
--fields 'title,body'
The last command should return the document with key first. If it does not,
stop here and use Troubleshooting.
Install the embedding model
Now pull the multimodal model used for text and image search. Antfly inference runs quantized models locally without an external API:
antfly inference pull antflydb/clipclap:gguf:Q4_K
antfly inference list
If the running standalone process does not detect the newly installed model, restart it once before creating the embeddings index.
Download Sample Data
In a new terminal, download 10,000 Wikipedia articles enriched with thumbnail images:
curl -L -o wiki-articles.jsonl https://cdn.antfly.io/datasets/wiki-articles-10k-v001.json
head -n 1 wiki-articles.jsonl | jq '.'
The fixture is newline-delimited JSON (JSONL): one article per line. Every
article has title, body, and url; 2,446 of the 10,000 articles also have
an optional thumbnail_url used later for image search.
Create a Table
Create a table with a text embedding index for semantic search:
antfly table create --table wikipedia \
--index '{
"name": "title_body",
"type": "embeddings",
"template": "{{title}} {{body}}",
"embedder": {
"provider": "antfly",
"model": "antflydb/clipclap"
},
"chunker": {
"provider": "antfly",
"text": {
"target_tokens": 200,
"overlap_tokens": 25
}
}
}'
Verify the table and index were created:
antfly table list
antfly index list --table wikipedia
Antfly also provisions full_text_index_v0 automatically. That default index
is what makes the full-text query later in this guide work; title_body is the
managed embeddings index created above.
Load Data
# Load all 10,000 articles using the title as the document ID
antfly load --table wikipedia \
--file wiki-articles.jsonl \
--id-field title \
--sync-level full_text
This shared load step ensures that every query tab below runs against the same
dataset. full_text fences the inexpensive text index for each load batch but
does not wait for embeddings, which continue asynchronously. The CLI reads
JSONL and batches documents automatically. Applications
that need to own ingestion should use the SDK Batch Operations
workflow with bounded batches and retries.
Embedding generation runs in the background. Managed embeddings indexes use progressive publication by default, so a safely checkpointed partial generation can serve semantic queries while source coverage continues in the background. To wait only for that first queryable generation, run:
antfly index wait --table wikipedia \
--index title_body \
--until queryable \
--timeout 20m
Continue as soon as this command succeeds. The examples below search the safely
published portion of the index while the remaining documents continue indexing,
so result counts and rankings can improve as coverage grows. When an application
requires a fixed, fully covered corpus, use --until complete to wait for the
stronger ready state instead.
Use antfly index list --table wikipedia for a compact progress summary, or
add --output json for the complete diagnostic payload.
Model startup and time-to-first-result depend on hardware. The wait command
reports bounded periodic progress and enforces the timeout; do not continue if
it times out before the index becomes queryable. Use publication_policy: atomic when a replacement generation must remain unavailable until fully built
and validated. See Troubleshooting below.
For chunked indexes, INDEXED and VISIBLE describe physical chunks or vector
records, not source documents, so they can exceed 10,000. The JSON status also
contains generation-scoped source coverage. queryable_partial means the active
generation is safe to query but incomplete; ready means coverage is complete.
Search
You can run these queries using the CLI (shown below) or the web dashboard at http://localhost:8080.
Full-Text Search
Search for articles containing specific terms:
antfly query --table wikipedia \
--full-text-search 'body:"Korea"' \
--fields "title,url" \
--limit 5
Semantic Search
Find articles semantically similar to a natural language query:
antfly query --table wikipedia \
--semantic-search "anatomy and physiology" \
--indexes "title_body" \
--fields "title,url" \
--limit 5
You've loaded 10,000 documents and run your first full-text and semantic searches. From here, the guide builds on what you have — adding reranking, image search, and RAG.
Hybrid Search & Reranking
Hybrid search combines full-text and semantic search using Reciprocal Rank Fusion (RRF). Adding a reranker further improves relevance by re-scoring results with a cross-encoder model.
Pull the reranker model:
antfly inference pull --tasks rerank --variants f32 cross-encoder/ms-marco-MiniLM-L6-v2
If Antfly doesn't detect the new model, restart antfly standalone.
antfly query --table wikipedia \
--full-text-search 'body:Einstein' \
--semantic-search "theory of relativity and physics" \
--indexes "title_body" \
--fields "title,url" \
--limit 10 \
--reranker '{
"provider": "antfly",
"model": "cross-encoder/ms-marco-MiniLM-L6-v2",
"field": "body"
}' \
--pruner '{"min_score_ratio": 0.01}'
Reranking vs Pruning:
- Reranking uses a cross-encoder model to re-score results based on query-document relevance. It improves ordering but keeps the same number of results.
- Pruning filters out low-relevance results based on score quality. Use
min_score_ratioto keep only results scoring at least N% of the top result, ormax_score_gap_percentto detect "elbows" in score distribution.
Image Search
Search by visual content using ClipClap, a multimodal embedding model that understands text, images, and audio.
Confirm the ClipClap model is available
antfly inference pull antflydb/clipclap:gguf:Q4_K
If Antfly doesn't detect the new model, restart antfly standalone.
Add an image index to your table
Add a ClipClap-based index to embed each article's Wikipedia thumbnail:
antfly index create --table wikipedia \
--index thumbnail \
--type embeddings \
--coverage-policy partial \
--template "{{#if thumbnail_url}}{{remoteMedia url=thumbnail_url}}{{/if}}" \
--embedder '{"provider": "antfly", "model": "antflydb/clipclap"}' \
--dimension 512
Adding an index to a table with existing data triggers background embedding generation. The partial coverage policy treats articles without a thumbnail_url as intentional skips while still requiring every article to reach a durable outcome. Wait until the image index is queryable before continuing:
antfly index wait --table wikipedia \
--index thumbnail \
--until queryable \
--timeout 20m
Use antfly index list --table wikipedia to monitor detailed progress.
Search by visual content
ClipClap understands visual concepts, so you can describe what you're looking for in natural language:
antfly query --table wikipedia \
--semantic-search "map of a country" \
--indexes "thumbnail" \
--fields "title,url,thumbnail_url" \
--limit 5
Multimodal image search responds best to concrete visual descriptions ("red sports car", "mountain landscape") rather than abstract concepts. For a deeper dive, see the Image Search with CLIP example.
RAG (Retrieval-Augmented Generation)
Combine search with LLM-powered classification and generation using the retrieval agent.
Pull a generation model
antfly inference pull ggml-org/gemma-4-E4B-it-GGUF:gguf:Q4_K_M
ggml-org/gemma-4-E4B-it-GGUF runs locally via Antfly inference and supports the full quickstart RAG flow — classification, generation, reasoning, and follow-up questions. The generator config caps output at 128 tokens for predictable local latency. For alternative providers, see the next step.
Classify and generate
Use the Gemma model to classify a query and generate an answer from search results:
antfly agents retrieval --table wikipedia \
--semantic-search "What are the major events in Korean history?" \
--indexes "title_body" \
--fields "title,body" \
--limit 5 \
--reranker '{
"provider": "antfly",
"model": "cross-encoder/ms-marco-MiniLM-L6-v2",
"field": "body"
}' \
--pruner '{"min_score_ratio": 0.6, "max_score_gap_percent": 40}' \
--generator '{
"provider": "antfly",
"model": "ggml-org/gemma-4-E4B-it-GGUF",
"max_tokens": 128
}' \
--max-context-tokens 512 \
--classify --reasoning --generate --followup
This command searches for semantically similar articles, reranks and prunes results for quality, classifies the query, generates a capped answer with reasoning, and suggests follow-up questions — all using the local Gemma model.
Pruning for RAG: Score-based pruning (--pruner) filters out marginally relevant documents, while token-based pruning (--max-context-tokens) ensures the context fits within the model's limits.
RAG with alternative providers
The previous step uses Antfly inference for local inference. You can also use cloud APIs or Ollama:
Requires a Google AI API key. Set the GEMINI_API_KEY environment variable — Antfly picks it up automatically:
export GEMINI_API_KEY="your-api-key-here"
antfly agents retrieval --table wikipedia \
--semantic-search "What are the major events in Korean history?" \
--indexes "title_body" \
--fields "title,body" \
--limit 5 \
--generator '{"provider": "gemini", "model": "gemini-2.5-flash"}' \
--max-context-tokens 2048 \
--classify --reasoning --generate --followup
Choosing a generator model:
ggml-org/gemma-4-E4B-it-GGUF— local GGUF inference via Antfly inference, no API key needed- Ollama
gemma3:4b-it-qat— local inference via Ollama, quantized for fast CPU/GPU performance - Gemini
gemini-2.5-flash— cloud API, fast and high quality, requires API key - OpenAI
gpt-4.1-mini— cloud API, fast and high quality, requires API key
Structured output
Add --no-streaming to get structured JSON output with source references instead of streaming text:
antfly agents retrieval --table wikipedia \
--semantic-search "Explain the theory of relativity" \
--indexes "title_body" \
--fields "title,body,url" \
--limit 5 \
--generator '{"provider": "gemini", "model": "gemini-2.5-flash"}' \
--no-streaming --generate
Evaluation
Add --eval to score the quality of retrieval and generation:
antfly agents retrieval --table wikipedia \
--semantic-search "What are the major events in Korean history?" \
--indexes "title_body" \
--fields "title,body" \
--limit 5 \
--generator '{"provider": "gemini", "model": "gemini-2.5-flash"}' \
--generate \
--eval '{
"evaluators": ["faithfulness", "relevance"],
"judge": {"provider": "gemini", "model": "gemini-2.5-flash"}
}'
Available evaluators:
- Retrieval metrics (require
ground_truth.relevant_ids):recall,precision,ndcg,mrr,map - LLM-as-judge metrics (require
judgeconfig):relevance,faithfulness,completeness,coherence,safety,helpfulness,correctness,citation_quality
Troubleshooting
antfly is not found after the Linux install
The user installer places the binary in ~/.local/bin. Make it available in
the current terminal, then retry:
export PATH="$HOME/.local/bin:$PATH"
antfly --version
Antfly reports a legacy data directory
Antfly refuses to overwrite a legacy Go-runtime directory. Keep that directory intact, back it up with the old runtime, and start this quickstart with a new database directory:
antfly standalone --data-dir "$HOME/.antfly-zig" 2>&1 | tee antfly.log
Models remain in the documented ~/.antfly/inference/models store unless you
explicitly pass --models-dir or set ANTFLY_INFERENCE_MODELS_DIR.
MODEL_NOT_FOUND
Confirm that the requested model is installed and inspect the resolved model directory printed in the standalone startup log:
antfly inference list
grep -F 'standalone inference paths' antfly.log
Pull the missing model again, or pass the intended directory explicitly with
antfly standalone --models-dir <path>.
An index remains pending or index wait times out
Do not continue to semantic, image, or RAG steps until the relevant index is
queryable. queryable_partial is safe to use while coverage grows; pending is
not. If index wait --until queryable times out, capture the full status and recent
watchdog messages:
antfly index list --table wikipedia --output json | jq '.'
grep -E 'watchdog|derived worker|NotFound|EnrichmentWaitTimeout' antfly.log | tail -n 100
Remember that physical chunk/vector counts can exceed source-document counts.
Continual growth for unchanged source data, no generation-coverage progress, or
an unexplained ready to pending transition should be reported with the JSON
status, log excerpt, Antfly version, and startup command.
Startup reports a port conflict or memory error
Stop the process already using ports 8080 or 4200, or select different public
and health ports with --port and --health-port. For memory errors, stop
other large local models and retry with a smaller model or a larger process
memory envelope appropriate for the machine.
Stop the quickstart
Press Ctrl+C in the standalone terminal. If you used Homebrew services, run:
brew services stop antfly
Next Steps
- Explore the Dashboard — Manage tables, run queries, and monitor your cluster at
http://localhost:8080 - Image Search with CLIP — Build a full image search application
- Browse Models — Discover available embedding, reranking, and generation models with
antfly inference list --remote - SDKs — Build applications with Go, TypeScript, Python, or Rust
- Backup and Restore — Protect your data
- Production Deployment — Deploy on Kubernetes with the Antfly Operator
Additional Resources
- Antfly CLI & REST API Documentation
- Hybrid Search Guide
- Inference Guide — Configure ML inference, embedding providers, and more
- Configuration Reference
- How do I install Antfly?
- How do I create my first table and index?
- How do I load data into Antfly?
- How do I run a search query?
- How do I use RAG with Antfly inference for AI-powered answers?