All skills
simota avatar

/seek

@35ffd55
by shingo imotasimota/agent-skills85 stars
15

Designing search engines and vector DBs for full-text, vector, and hybrid retrieval, including permission-aware retrieval for multi-tenant or per-role corpora. Use for search design, index optimization, the RAG retrieval layer, or deciding where ACL filtering belongs in the query path.

Use this Skill: https://skilld.dev/gh/simota/agent-skills/seek

This session only. Nothing lands on disk.

referencepatterns.md

≈2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Search Design Patterns

Purpose: Core design patterns for full-text, vector, and hybrid search systems. Read when: Designing index mappings, query strategies, or ranking pipelines.


Full-Text Search Patterns

Mapping Example (Elasticsearch/OpenSearch)

Field types, analyzers, and multi-fields for language-aware search:

{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "custom_analyzer",
        "fields": {
          "keyword": { "type": "keyword" },
          "ngram": { "type": "text", "analyzer": "ngram_analyzer" }
        }
      },
      "content": { "type": "text", "analyzer": "content_analyzer" }
    }
  },
  "settings": {
    "analysis": {
      "analyzer": {
        "custom_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "synonym_filter", "stemmer"]
        }
      }
    }
  }
}

Analyzer Selection Guide

Use Case Tokenizer Filters Notes
English text standard lowercase, stop, stemmer Default for most cases
Japanese text kuromoji_tokenizer kuromoji_part_of_speech, ja_stop Requires analysis-kuromoji plugin
Autocomplete edge_ngram lowercase Index-time ngram, search-time standard
Exact match keyword lowercase For filters and facets

Pattern 1: Multi-Field Mapping

Use multi-fields for different analysis strategies on the same content.

{
  "title": {
    "type": "text",
    "analyzer": "standard",
    "fields": {
      "exact": { "type": "keyword" },
      "autocomplete": { "type": "text", "analyzer": "edge_ngram_analyzer" },
      "search_as_you_type": { "type": "search_as_you_type" }
    }
  }
}

When to use: Content needs keyword search, autocomplete, and exact match simultaneously.

Pattern 2: Japanese Full-Text Search

{
  "settings": {
    "analysis": {
      "tokenizer": {
        "kuromoji": {
          "type": "kuromoji_tokenizer",
          "mode": "search"
        }
      },
      "analyzer": {
        "ja_analyzer": {
          "type": "custom",
          "tokenizer": "kuromoji",
          "filter": [
            "kuromoji_baseform",
            "kuromoji_part_of_speech",
            "ja_stop",
            "kuromoji_stemmer",
            "lowercase"
          ]
        }
      }
    }
  }
}

When to use: Japanese text indexing. Always use mode: search for query-time segmentation.

Pattern 3: Synonym-Aware Search

{
  "filter": {
    "synonym_filter": {
      "type": "synonym_graph",
      "synonyms_path": "analysis/synonyms.txt",
      "updateable": true
    }
  }
}

When to use: Domain-specific terminology (e.g., "laptop" = "notebook computer").


Vector Search Patterns

Pattern 4: Matryoshka Embedding Reduction

from openai import OpenAI

client = OpenAI()
response = client.embeddings.create(
    model="text-embedding-3-large",
    input="search query",
    dimensions=256  # Reduce from 3072 to 256
)
# Trade-off: ~5% quality loss for 12x storage reduction

When to use: Storage/latency constraints outweigh marginal quality gains.

Pattern 5: Two-Phase Vector Search

-- Phase 1: Approximate kNN with pre-filter
SELECT id, embedding <=> $1::vector AS distance
FROM documents
WHERE category = ANY($2)
ORDER BY embedding <=> $1::vector
LIMIT 100;

-- Phase 2: Rerank with cross-encoder score
-- (application layer)

When to use: Filtered vector search where filter selectivity varies widely.

Pattern 6: Multi-Vector Retrieval

Store separate embeddings for title, content, and metadata. Query with field-weighted combination.

# Weighted multi-field vector search
title_results = search(query_embedding, index="title_vectors", top_k=50)
content_results = search(query_embedding, index="content_vectors", top_k=50)
combined = rrf_fusion(title_results, content_results, k=60)

When to use: Documents with semantically distinct sections (e.g., title vs body).

pgvector Configuration

-- Create vector column
ALTER TABLE documents ADD COLUMN embedding vector(1536);

-- HNSW index (recommended for most cases)
CREATE INDEX idx_documents_embedding ON documents
  USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 200);

-- Query with distance
SELECT id, title, embedding <=> $1::vector AS distance
FROM documents
WHERE category = $2
ORDER BY embedding <=> $1::vector
LIMIT 20;

Hybrid Search Patterns

Reciprocal Rank Fusion (RRF)

RRF_score(d) = Σ 1 / (k + rank_i(d))

Default k = 60. Combine BM25 rank and vector rank for each document.

Hybrid Search Pipeline

Query → [BM25 Search] → Top-N₁ results (ranked by BM25)
     ↘ [Vector Search] → Top-N₂ results (ranked by similarity)
         ↓
     [Fusion Layer (RRF / Weighted)] → Combined Top-K
         ↓
     [Optional Reranker (Cross-Encoder)] → Final Top-K

Fusion Strategy Selection

Strategy When to Use Pros Cons
RRF Default for hybrid Simple, no tuning Equal weight assumed
Weighted Sum Known relevance distribution Tunable Requires labeled data
Cross-Encoder Rerank High-precision RAG Best quality Latency cost (50-100ms)
ColBERT Late Interaction High-recall + speed Token-level matching, precomputable Higher storage (multi-vector per doc)
SPLADE + ColBERT Default production pipeline Learned sparse + late interaction Two-model complexity
Cohere Rerank API Quick reranking Easy integration API dependency

Pattern 7: Elasticsearch Hybrid with RRF

{
  "retriever": {
    "rrf": {
      "retrievers": [
        {
          "standard": {
            "query": {
              "multi_match": {
                "query": "search terms",
                "fields": ["title^3", "content"]
              }
            }
          }
        },
        {
          "knn": {
            "field": "embedding",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my-embedding-model",
                "model_text": "search terms"
              }
            },
            "k": 50,
            "num_candidates": 100
          }
        }
      ],
      "rank_constant": 60,
      "rank_window_size": 100
    }
  }
}

Pattern 8: pgvector Hybrid Search

-- BM25 via pg_search + vector via pgvector
WITH bm25 AS (
  SELECT id, ts_rank(tsv, plainto_tsquery($1)) AS bm25_score
  FROM documents
  WHERE tsv @@ plainto_tsquery($1)
  ORDER BY bm25_score DESC
  LIMIT 100
),
vector AS (
  SELECT id, 1 - (embedding <=> $2::vector) AS vector_score
  FROM documents
  ORDER BY embedding <=> $2::vector
  LIMIT 100
),
fused AS (
  SELECT COALESCE(b.id, v.id) AS id,
    COALESCE(1.0 / (60 + b.rank), 0) + COALESCE(1.0 / (60 + v.rank), 0) AS rrf_score
  FROM (SELECT id, ROW_NUMBER() OVER (ORDER BY bm25_score DESC) AS rank FROM bm25) b
  FULL OUTER JOIN (SELECT id, ROW_NUMBER() OVER (ORDER BY vector_score DESC) AS rank FROM vector) v
  ON b.id = v.id
)
SELECT * FROM fused ORDER BY rrf_score DESC LIMIT 20;

Scaling Patterns

Pattern 9: Index Sharding Strategy

Data Size Shards Replicas Notes
<10M docs 1-2 1 Single node sufficient
10-100M docs 3-5 1-2 Distribute by time or category
100M-1B docs 5-20 2 Consider ILM policies
>1B docs 20+ 2-3 Shard by tenant or region

Pattern 10: Search Result Caching

CACHE_STRATEGY:
  layer_1:
    type: "query result cache"
    ttl: "5m"
    invalidation: "on index update"
    scope: "exact query match"
  layer_2:
    type: "embedding cache"
    ttl: "24h"
    scope: "query text → vector"
  layer_3:
    type: "application cache (Redis)"
    ttl: "1-15m"
    scope: "user-facing search results"

Source: SKILL.md on GitHub

No alerts13d4 checks · Risk SAFE
  • Gen Agent Trust Hub13d

    The skill 'seek' is a comprehensive design resource for search engines and vector databases. It promotes security best practices, such as retrieval authorization and multi-tenant isolation, and provides legitimate technical templates. No malicious patterns or security risks were identified.

  • Socket13d

    No alerts

  • Snyk13d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 35ffd55. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 days ago.

Activeupdated 2 weeks ago

README badge

README badge for simota/agent-skills/seek