BM25S Search Guide

This guide shows you how to use the search functionality in BM25S Retriever, both through the web interface and via API calls.

Using the Search Tab

Accessing the Search Interface

  1. Open the Web Interface

Search Query Interface

  1. Enter Your Query

  2. Configure Search Parameters

  3. Perform Search

Understanding Search Results

The search results table displays:

Advanced Search Techniques

  1. Temperature Experiments

  2. Cutoff Adjustment

  3. Zero-Relevance Filtering

Search Tips

Search API Calls

Basic Search Endpoint

curl -X POST http://localhost:9200/retrieve \
  -H "Content-Type: application/json" \
  -d '{
    "query": "machine learning algorithms",
    "temperature": 0.7,
    "llm_tools_cutoff": 8.0,
    "ignore_zero": true
  }'

Advanced Search Parameters

curl -X POST http://localhost:9200/retrieve \
  -H "Content-Type: application/json" \
  -d '{
    "query": "python data science",
    "temperature": 1.2,
    "llm_tools_cutoff": 5.0,
    "ignore_zero": false
  }'

Python Search Implementation

import requests
import json

class BM25SSearcher:
    def __init__(self, base_url="http://localhost:9200"):
        self.base_url = base_url
        self.retrieve_url = f"{base_url}/retrieve"
    
    def search(self, query, temperature=0.7, cutoff=8.0, ignore_zero=True):
        """Search documents with BM25S retriever."""
        
        payload = {
            "query": query,
            "temperature": temperature,
            "llm_tools_cutoff": cutoff,
            "ignore_zero": ignore_zero
        }
        
        try:
            response = requests.post(self.retrieve_url, json=payload)
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            return {"success": False, "error": str(e)}
    
    def search_and_format(self, query, **kwargs):
        """Search and return formatted results."""
        result = self.search(query, **kwargs)
        
        if not result.get("success"):
            return f"Search failed: {result.get('error', 'Unknown error')}"
        
        output = [
            f"Found {len(result['documents'])} documents (from {result['total_retrieved']} total)",
            f"Using temperature: {result['settings']['temperature']}",
            f"Cutoff: {result['cutoff_percentage']}%",
            ""
        ]
        
        for i, doc in enumerate(result["documents"], 1):
            output.extend([
                f"--- Document {i} ---",
                f"ID: {doc['id']}",
                f"Title: {doc['title']}",
                f"Content: {doc['content'][:100]}{'...' if len(doc['content']) > 100 else ''}",
                f"Keywords: {', '.join(doc.get('keywords', []))}",
                f"BM25 Score: {doc['bm25_score']:.3f}",
                f"Softmax Score: {doc['softmax_score']*100:.2f}%",
                ""
            ])
        
        return "\n".join(output)

# Example usage
if __name__ == "__main__":
    searcher = BM25SSearcher()
    
    # Basic search
    print("=== Basic Search ===")
    print(searcher.search_and_format("machine learning"))
    
    # Search with custom parameters
    print("\n=== Advanced Search ===")
    print(searcher.search_and_format(
        "python programming",
        temperature=1.5,
        cutoff=10.0,
        ignore_zero=False
    ))
    
    # Compare temperatures
    print("\n=== Temperature Comparison ===")
    query = "data science"
    
    print(f"Results for '{query}' with temperature 0.5:")
    print(searcher.search_and_format(query, temperature=0.5))
    
    print(f"\nResults for '{query}' with temperature 2.0:")
    print(searcher.search_and_format(query, temperature=2.0))

Batch Search Implementation

def batch_search(queries, temperatures=[0.5, 1.0, 1.5]):
    """Perform multiple searches with different parameters."""
    searcher = BM25SSearcher()
    results = {}
    
    for query in queries:
        results[query] = {}
        
        for temp in temperatures:
            result = searcher.search(query, temperature=temp)
            if result.get("success"):
                results[query][f"temp_{temp}"] = {
                    "count": len(result["documents"]),
                    "top_doc": result["documents"][0]["id"] if result["documents"] else None,
                    "avg_score": sum(doc["softmax_score"] for doc in result["documents"]) / len(result["documents"]) if result["documents"] else 0
                }
    
    return results

# Example batch search
queries = ["machine learning", "python", "data science"]
batch_results = batch_search(queries)

for query, temps in batch_results.items():
    print(f"\nQuery: {query}")
    for temp_key, stats in temps.items():
        print(f"  {temp_key}: {stats['count']} docs, avg: {stats['avg_score']:.3f}")

Document Structure and Indexing

Which YAML Fields Are Indexed

The BM25S retriever indexes specific fields from your YAML documents to enable searching:

Indexed Fields (Searchable)

Stored Fields (Not Searchable)

How Indexing Works

The system combines indexed fields into a single searchable text:

# For each document, the search index contains:
title + " " + content + " keyword: keyword1 keyword: keyword2 ..."

Example:

- id: "create_order"
  title: "Create New Order"
  content: "Start a new purchase, buy a product, or place a customer order."
  keywords: ["buy", "purchase", "place order", "checkout"]

This becomes searchable as:

"Create New Order Start a new purchase, buy a product, or place a customer order. keyword: buy keyword: purchase keyword: place order keyword: checkout"

Search Optimization Tips

  1. Title: Use descriptive, action-oriented titles that users might search for
  2. Content: Include natural language descriptions with common search terms
  3. Keywords: Add synonyms, abbreviations, and alternative phrasing users might type
  4. Avoid: Don't put searchable content in id, parameters, or metadata fields

YAML Structure Requirements

Field Definitions and Usage

Required Fields

- id: "unique_identifier"     # Required: Document ID
  title: "Document Title"     # Required: Searchable title
  content: "Description..."   # Required: Searchable content

Keywords vs Metadata

Keywords (Searchable):

Metadata (Not Searchable):

Complete YAML Structure Example

documents:
  - id: "create_order"
    title: "Create New Order"
    content: "Start a new purchase, buy a product, or place a customer order. Use this to initiate a checkout process for items."
    keywords:
      - "buy"
      - "purchase"
      - "place order"
      - "checkout"
      - "start transaction"
      - "order item"
      - "buy product"
      - "new sale"
    parameters:
      customer_id: { type: "string" }
      product_id: { type: "string" }
      quantity: { type: "integer", minimum: 1 }
      price: { type: "number" }
    metadata:
      source: "yaml"
      category: "orders"
      provider: "internal"
      updated: "2025-04-07"

Field Compatibility

Search Parameters Reference

Parameter Type Default Range Description
query string required - Search query text
temperature float 0.7 0.1-10.0 Softmax temperature control
llm_tools_cutoff float 8.0 0-100 Minimum softmax percentage
ignore_zero boolean true - Filter zero BM25 scores

Parameter Effects

Temperature Impact

Understanding Temperature Effects

Temperature controls how "sharp" or "flat" the softmax distribution is:

Practical Temperature Ranges

Cutoff Percentage

Response Format

{
  "success": true,
  "message": "Documents retrieved successfully",
  "documents": [
    {
      "id": "doc1",
      "title": "Document Title",
      "content": "Full document content...",
      "keywords": ["keyword1", "keyword2"],
      "metadata": {},
      "bm25_score": 2.456,
      "softmax_score": 0.1234
    }
  ],
  "total_retrieved": 15,
  "cutoff_percentage": 8.0,
  "settings": {
    "temperature": 0.7,
    "ignore_zero": true,
    "llm_tools_cutoff": 8.0
  }
}

Search Best Practices

For Best Results

  1. Use Specific Terms

  2. Experiment with Temperature

  3. Adjust Cutoff Appropriately

  4. Compare Results

Common Use Cases

Research and Analysis

# Comprehensive search with low cutoff
searcher.search_and_format(
    "machine learning algorithms",
    temperature=1.0,
    cutoff=2.0,
    ignore_zero=False
)

Quick Lookup

# Focused search for best matches
searcher.search_and_format(
    "python lists",
    temperature=0.5,
    cutoff=15.0,
    ignore_zero=True
)

Exploration

# Broad search with uniform scoring
searcher.search_and_format(
    "data science",
    temperature=3.0,
    cutoff=5.0,
    ignore_zero=True
)

Troubleshooting

Common Issues

  1. No Results Found

  2. Too Many Results

  3. Unexpected Rankings

  4. API Errors

Performance Tips

For more advanced usage and integration examples, refer to the main documentation at http://localhost:9200/docs.