Skip to main content

Tutorial 2: Finding Code by Meaning

Text search is great when you know the name of what you're looking for. But what if you want to find "the function that retries failed HTTP requests" or "the class that handles rate limiting"? That's where semantic search comes in.

What you'll use: ciak scan --embeddings, ciak search --semantic, ciak search --hybrid, ciak vector

Time: ~15 minutes

Prerequisite: A CIAK-initialized project. If you haven't done that yet, follow Tutorial 1 first.


Step 1 — Generate embeddings​

Semantic search requires vector embeddings to be generated during the scan. If you haven't done this yet, run:

ciak scan --embeddings --parallel

If you've already scanned without embeddings, re-run with --embeddings — CIAK will only process files that changed:

ciak scan --embeddings --incremental-embeddings

The --incremental-embeddings flag skips files whose content hasn't changed since the last scan, making re-runs fast.


Step 2 — Check available embedding models​

CIAK ships with support for multiple embedding models. See what's available:

ciak vector models

Sample output:

Available embedding models:

sentence-transformers/all-MiniLM-L6-v2 [384-dim] fast, general purpose
microsoft/codebert-base [768-dim] code-optimized, higher accuracy

To download a model:

ciak vector download microsoft/codebert-base

Tip: codebert-base is optimized for source code and gives better results for code-specific queries. all-MiniLM-L6-v2 is faster and works well for general-purpose searches.


Now search by describing what the code does:

ciak search "function that retries failed HTTP requests" --semantic

Unlike text search, this doesn't look for those exact words in the code. It finds code that is conceptually similar to your description — even if the function is called withRetry, executeWithBackoff, or resilientFetch.

By default, semantic/hybrid search returns the top 10 results and applies a minimum similarity threshold of 0.3.

Sample output:

Semantic search results for: "function that retries failed HTTP requests"

src/http/retry.ts:12 withRetry() [function] score: 0.91
src/utils/resilience.ts:44 executeWithBackoff() [function] score: 0.87
src/client/http.ts:103 HttpClient.request() [method] score: 0.79

Step 4 — Hybrid search for best coverage​

Hybrid search combines text matching and semantic similarity. It's the best default when you're not sure which approach will work better:

ciak search "rate limiting middleware" --hybrid --with-context

Hybrid search scores each result using both approaches and merges them — so you get exact name matches and conceptually similar code in the same result set.


Step 5 — Query tips for better results​

The embedding model stores code in the format <type> <name> lang:<language> context:<code>. Queries that mirror this format tend to score higher.

Query styleExampleResult quality
Type + name + language"method validateToken typescript"Best
Descriptive phrase"validate JWT token expiry"Good
Symbol name alone"validateToken"Use text search instead

Try both styles and compare:

# Descriptive — finds by concept
ciak search "validate JWT token expiry" --semantic

# Type + name + language — finds by identity
ciak search "method validateToken typescript" --semantic

Step 6 — Filter semantic results​

Semantic search supports the same filters as text search. Narrow results to a specific language and path:

ciak search "database connection pooling" \
--semantic \
--language typescript \
--path-patterns "src/**,!src/**/*.spec.ts" \
--min-score 0.4 \
--limit 5

Use compact output when you want quick scanning in the terminal:

ciak search "database connection pooling" --semantic --compact

Or filter to only public classes:

ciak search "repository pattern data access" \
--hybrid \
--visibility public \
--group-by symbol_type

Step 7 — Use a specific model​

If you have multiple models downloaded, specify which one to use:

ciak search "error handling middleware" \
--semantic \
--embedding-model microsoft/codebert-base

When to use which search mode​

SituationRecommended mode
You know the function/class nameciak search "name" (text)
You know what it does but not its name--semantic
You want the best of both--hybrid
You need exact word matching--whole-word or --case-sensitive
Searching in a specific area of the codebaseAdd --path-patterns to any mode

What you've learned​

  • How to generate embeddings with ciak scan --embeddings
  • How to find code by describing its behavior with --semantic
  • How --hybrid combines text and semantic for broader coverage
  • How to write queries that get better semantic results
  • How to combine semantic search with filters

Next steps​