Class: Langchain::Vectorsearch::Qdrant

Inherits:
Base
  • Object
show all
Defined in:
lib/langchain/vectorsearch/qdrant.rb

Constant Summary

Constants inherited from Base

Base::DEFAULT_METRIC

Instance Attribute Summary

Attributes inherited from Base

#client, #index_name, #llm

Instance Method Summary collapse

Methods inherited from Base

#add_data, #generate_hyde_prompt, #generate_rag_prompt, #similarity_search_with_hyde

Methods included from DependencyHelper

#depends_on

Constructor Details

#initialize(url:, api_key:, index_name:, llm:) ⇒ Qdrant

Initialize the Qdrant client

Parameters:

  • url (String)

    The URL of the Qdrant server

  • api_key (String)

    The API key to use

  • index_name (String)

    The name of the index to use

  • llm (Object)

    The LLM client to use



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/langchain/vectorsearch/qdrant.rb', line 20

def initialize(url:, api_key:, index_name:, llm:)
  depends_on "qdrant-ruby", req: "qdrant"

  @client = ::Qdrant::Client.new(
    url: url,
    api_key: api_key,
    logger: Langchain.logger
  )
  @index_name = index_name

  super(llm: llm)
end

Instance Method Details

#add_texts(texts:, ids: [], payload: {}) ⇒ Hash

Add a list of texts to the index

Parameters:

  • texts (Array<String>)

    The list of texts to add

Returns:

  • (Hash)

    The response from the server



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/langchain/vectorsearch/qdrant.rb', line 48

def add_texts(texts:, ids: [], payload: {})
  batch = {ids: [], vectors: [], payloads: []}

  Array(texts).each_with_index do |text, i|
    id = ids[i] || SecureRandom.uuid
    batch[:ids].push(id)
    batch[:vectors].push(llm.embed(text: text).embedding)
    batch[:payloads].push({content: text}.merge(payload))
  end

  client.points.upsert(
    collection_name: index_name,
    batch: batch
  )
end

#ask(question:, k: 4) {|String| ... } ⇒ String

Ask a question and return the answer

Parameters:

  • question (String)

    The question to ask

  • k (Integer) (defaults to: 4)

    The number of results to have in context

Yields:

  • (String)

    Stream responses back one String at a time

Returns:

  • (String)

    The answer to the question



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/langchain/vectorsearch/qdrant.rb', line 141

def ask(question:, k: 4, &block)
  search_results = similarity_search(query: question, k: k)

  context = search_results.map do |result|
    result.dig("payload").to_s
  end
  context = context.join("\n---\n")

  prompt = generate_rag_prompt(question: question, context: context)

  messages = [{role: "user", content: prompt}]
  response = llm.chat(messages: messages, &block)

  response.context = context
  response
end

#create_default_schemaHash

Create the index with the default schema

Returns:

  • (Hash)

    The response from the server



92
93
94
95
96
97
98
99
100
# File 'lib/langchain/vectorsearch/qdrant.rb', line 92

def create_default_schema
  client.collections.create(
    collection_name: index_name,
    vectors: {
      distance: DEFAULT_METRIC.capitalize,
      size: llm.default_dimensions
    }
  )
end

#destroy_default_schemaHash

Deletes the default schema

Returns:

  • (Hash)

    The response from the server



86
87
88
# File 'lib/langchain/vectorsearch/qdrant.rb', line 86

def destroy_default_schema
  client.collections.delete(collection_name: index_name)
end

#find(ids: []) ⇒ Hash

Find records by ids

Parameters:

  • ids (Array<Integer>) (defaults to: [])

    The ids to find

Returns:

  • (Hash)

    The response from the server



36
37
38
39
40
41
42
43
# File 'lib/langchain/vectorsearch/qdrant.rb', line 36

def find(ids: [])
  client.points.get_all(
    collection_name: index_name,
    ids: ids,
    with_payload: true,
    with_vector: true
  )
end

#get_default_schemaHash

Get the default schema

Returns:

  • (Hash)

    The response from the server



80
81
82
# File 'lib/langchain/vectorsearch/qdrant.rb', line 80

def get_default_schema
  client.collections.get(collection_name: index_name)
end

#remove_texts(ids:) ⇒ Hash

Remove a list of texts from the index

Parameters:

  • ids (Array<Integer>)

    The ids to remove

Returns:

  • (Hash)

    The response from the server



71
72
73
74
75
76
# File 'lib/langchain/vectorsearch/qdrant.rb', line 71

def remove_texts(ids:)
  client.points.delete(
    collection_name: index_name,
    points: ids
  )
end

#similarity_search(query:, k: 4) ⇒ Hash

Search for similar texts

Parameters:

  • query (String)

    The text to search for

  • k (Integer) (defaults to: 4)

    The number of results to return

Returns:

  • (Hash)

    The response from the server



106
107
108
109
110
111
112
113
114
115
116
# File 'lib/langchain/vectorsearch/qdrant.rb', line 106

def similarity_search(
  query:,
  k: 4
)
  embedding = llm.embed(text: query).embedding

  similarity_search_by_vector(
    embedding: embedding,
    k: k
  )
end

#similarity_search_by_vector(embedding:, k: 4) ⇒ Hash

Search for similar texts by embedding

Parameters:

  • embedding (Array<Float>)

    The embedding to search for

  • k (Integer) (defaults to: 4)

    The number of results to return

Returns:

  • (Hash)

    The response from the server



122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/langchain/vectorsearch/qdrant.rb', line 122

def similarity_search_by_vector(
  embedding:,
  k: 4
)
  response = client.points.search(
    collection_name: index_name,
    limit: k,
    vector: embedding,
    with_payload: true,
    with_vector: true
  )
  response.dig("result")
end

#update_texts(texts:, ids:) ⇒ Object



64
65
66
# File 'lib/langchain/vectorsearch/qdrant.rb', line 64

def update_texts(texts:, ids:)
  add_texts(texts: texts, ids: ids)
end