0.0
No release in over 3 years
A ruby gem for performing LLM-powered automated web search.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

>= 2.0
>= 5.0
>= 13.0
>= 0.9

Runtime

>= 2.0
>= 1.10
~> 1.0
 Project Readme

deepsearch-rb

A ruby gem for performing LLM-powered automated web search. The only runtime dependencies are ruby_llm and async.

single cycle diagram

🎥 A simple demo within a sinatra app demonstrating the basic 1-cycle flow. (`examples/simple_webapp`) ▶️

demo


NOTE: You can implement your own chains in the way it works for you, BFS/DFS search on any topic. A draft code might look like:

Deepsearch.search(initial search) -> 
  LLM(Generate additional queries) ->
    Async [for each additional query]{ Deepsearch.search(sub-query) } ->
      Aggregate()

Installation

Ruby

Quick installation via nix flakes

If you're using nix flakes, just run nix develop and you'll enter a fully prepared dev environment.

Otherwise, make sure you have installed required_ruby_version = ">= 3.2.0".

# Gemfile
gem 'deepsearch-rb'
# ..

bundle install

Or install from a local folder:

gem 'deepsearch-rb', path: '<path_to_gem>'

Examples

See the the examples/ folder for a simple test as well as mini sinatra application streaming gem events via websocket interface.

Configuration Options

Minimal config

  • The LLM configuration is fully based on ruby_llm gem.
  • There are two built-in search adapters you can use out of the box:
Deepsearch.configure do |config|
  config.search_adapter = :tavily  # or :serper, :mock
  config.tavily_api_key = "your_tavily_api_key"
  config.serper_api_key = "your_serper_api_key"
  
  # LLM configuration (all config options are coming from `ruby_llm` gem),
  # you can experiment with any model you like
  config.ruby_llm.gemini_api_key = ENV['GEMINI_API_KEY']
  config.ruby_llm.default_model = 'gemini-2.0-flash-lite'
  config.ruby_llm.default_embedding_model = 'text-embedding-004'
  # ..
end

Advanced config

Specifying your own search adapter

class MyCustomAdapter
  def initializeт;end

  def search(query, options = {})
    # Implement your search logic here
    {
      "results" => [
        { "url" => "https://example.com/result1", "content" => "Content 1 from custom search" }
      ]
    }
  end
end

Deepsearch.configure { |config| config.custom_search_adapter_class = MyCustomAdapter }

Specifying your own prompts

See the Deepsearch::PromptsConfig interface to learn what methods and arguments are expected.

class MyPromptsConfig < Deepsearch::PromptsConfig
  def subquery_prompt(query:)
    <<~PROMPT
      You are a search expert. Given this query: "#{query}",
      generate 3 alternative search queries that would help find more information.
      Return them as a simple list, one per line.
    PROMPT
  end

  # Override other prompt methods as needed
end

Deepsearch.configure { |config| config.prompts_config = MyPromptsConfig.new }

Specifying event listener

class MyListener
  def on_deepsearch_event(event, step:, result:)
    puts "Event: #{event}, Step: #{step}, Success: #{result.success?}"
  end
end

Deepsearch.configure { |c| c.listener = MyListener.new }

Specifying max total search results

result = Deepsearch.search("Ruby 3 unknown features", max_total_search_results: 25)

License

The gem is available as open source under the terms of the MIT License.