Quickstart

Install Antfly, load data, and run your first queries

Beginner45–90 min
getting-startedsetupquickstart
Prerequisites
  • curl and jq (for sample data)

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.

Allow 45–90 minutes on a laptop, excluding a source build. The basic full-text check takes seconds; model downloads and background indexing take most of the time. Slower hardware may need longer timeouts.

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

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://127.0.0.1:8080/db/v1/tables/hello \
  -H "Content-Type: application/json" \
  -d '{}'

curl -fsS -X POST http://127.0.0.1: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 text embedding model#

Now pull the text embedding model used for semantic search. Antfly inference runs models locally without an external API:

antfly inference pull hf:Qwen/Qwen3-Embedding-0.6B-GGUF:q8-0-bundle-v1
antfly inference list

Qwen3-Embedding uses an instruction for search queries but embeds indexed documents without it. Antfly applies that distinction automatically: index and artifact writes use the document role, while semantic searches use the query role. The Q8_0 bundle runs on native CPU on Linux and macOS, and uses Metal automatically when it is available.

If the running standalone process does not detect the newly installed model, restart it once before creating the embeddings index.

Once the embeddings index reaches queryable, Antfly durably preserves that published snapshot across later restarts while the remaining embeddings resume in the background. complete still means all source outcomes and the final vector publication have settled.

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": "Qwen/Qwen3-Embedding-0.6B-GGUF:q8-0-bundle-v1"
    },
    "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

Embedding generation runs in the background. Wait until 10% of documents have searchable embeddings; skipped documents are excluded:

antfly index wait --table wikipedia \
  --index title_body \
  --until source-covered=10% \
  --timeout 45m

Continue when this succeeds. Results improve as the remaining documents are indexed. To wait for the full corpus instead, use --until complete.

Use antfly index list --table wikipedia to check progress. Timing depends on hardware; if the wait times out, see Troubleshooting before continuing.

Search for articles containing specific terms:

antfly query --table wikipedia \
  --full-text-search 'body:"Korea"' \
  --fields "title,url" \
  --limit 5

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

Hybrid Search & Reranking#

Hybrid search combines full-text and semantic search using Reciprocal Rank Fusion (RRF). The Qwen3 text reranker jointly scores each query-document pair to improve the ordering of those candidates.

Pull the reranker model:

antfly inference pull hf:ggml-org/Qwen3-Reranker-0.6B-Q8_0-GGUF:gguf:Q8_0 --tasks rerank

The Q8 model is about 610 MiB and runs on native CPU or Metal. The first query loads it; reranking full articles can take tens of seconds, especially while indexing continues.

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": "ggml-org/Qwen3-Reranker-0.6B-Q8_0-GGUF:gguf:Q8_0",
      "field": "body"
    }' \
  --pruner '{"min_score_ratio": 0.01}'

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

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"}'

Antfly probes the selected embedding model during creation and stores its dimension in the normalized index definition. Specify dimension only when you also want creation to verify an explicit expected size.

Adding an index starts background image indexing. Articles without thumbnails are skipped; wait for 250 searchable images before continuing.

antfly index wait --table wikipedia \
  --index thumbnail \
  --until searchable-artifacts=250 \
  --timeout 45m

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

RAG (Retrieval-Augmented Generation)#

Combine search with local LLM answer generation using the retrieval agent.

Pull a generation model#

antfly inference pull hf:ggml-org/gemma-4-E4B-it-GGUF:gguf:Q4_0 \
  --tasks generate \
  --projector auto

Build a query and generate an answer#

Give Gemma an intent and a table. The retrieval agent delegates query planning to the query builder, searches, and answers from the results.

antfly agents retrieval --table wikipedia \
  --intent "What are the major events in Korean history?" \
  --fields "title,body" \
  --limit 5 \
  --generator '{
    "provider": "antfly",
    "model": "ggml-org/gemma-4-E4B-it-GGUF",
    "max_tokens": 512
  }' \
  --max-internal-iterations 8 \
  --streaming

The CLI and cURL commands stream Server-Sent Events as each step completes. A terminal event: done marks success; an error or incomplete stream makes the CLI exit nonzero. The SDK examples request structured JSON instead. Each example uses bounded, read-only tool calls and requests only a grounded answer. Use --no-streaming for JSON from the CLI.

Inspect a query plan (optional)#

To build a query without retrieving documents:

antfly agents query-builder --table wikipedia \
  --intent "Find articles about anatomy" \
  --generator '{"provider":"antfly","model":"ggml-org/gemma-4-E4B-it-GGUF","max_tokens":512,"temperature":0}' \
  --max-internal-iterations 8

Add --execute to run the same composed retrieval workflow shown above.

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 \
  --generate

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 judge config): 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 has reached the guide's readiness threshold. queryable_partial is safe to use while coverage grows, but an empty published generation cannot produce results. If index wait 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#

  1. Explore the Dashboard — Manage tables, run queries, and monitor your cluster at http://127.0.0.1:8080
  2. Image Search with CLIP — Build a full image search application
  3. Browse Models — Discover available embedding, reranking, and generation models with antfly inference list --remote
  4. SDKs — Build applications with Go, TypeScript, Python, or Rust
  5. Backup and Restore — Protect your data
  6. Production Deployment — Deploy on Kubernetes with the Antfly Operator

Additional Resources#