Module: OllamaChat::CollectionSearch
Overview
Shared collection search primitives for document retrieval and LLM reranking.
Extracted from Tools::SearchKnowledge so that the
/collection query command and the trigger mechanism can reuse
the same search + rerank pipeline without duplicating logic.
Instance Method Summary collapse
-
#find_document_records(query, tags: nil, text_size: nil, text_count: nil, min_similarity: nil) ⇒ Array<Documentrix::Utils::TagResult>
Searches the active document collection for records matching the given query.
-
#rerank_records(query, records, prompt_name: nil) ⇒ Array<Documentrix::Utils::TagResult>
Reranks a set of records using the LLM with the
rerankprompt. -
#trigger_inject(content, group_uuid:) ⇒ self?
Injects relevant snippets from the session's trigger collection into the conversation as a tool message.
Instance Method Details
#find_document_records(query, tags: nil, text_size: nil, text_count: nil, min_similarity: nil) ⇒ Array<Documentrix::Utils::TagResult>
Searches the active document collection for records matching the given query.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/ollama_chat/collection_search.rb', line 20 def find_document_records( query, tags: nil, text_size: nil, text_count: nil, min_similarity: nil ) = Documentrix::Utils::Tags.new( , valid_tag: /\A#*([-\w.\]\[]+)/ ) effective_query = query.first( config..model.context_length ) = config..model.prompt? log( :info, 'Embedding search request', data: { url: .base_url, model: config..model.to_h, collection: collection, query: effective_query, prompt: , } ) records = @documents.find_where( effective_query, tags:, prompt: , text_size:, text_count:, min_similarity: ) log( :info, 'Embedding search response', data: { url: .base_url, collection: collection, query: effective_query, result_count: records.size, top: records.first&.similarity&.round(4), } ) records end |
#rerank_records(query, records, prompt_name: nil) ⇒ Array<Documentrix::Utils::TagResult>
Reranks a set of records using the LLM with the rerank prompt.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/ollama_chat/collection_search.rb', line 69 def rerank_records(query, records, prompt_name: nil) candidates = records.each_with_index.map { |r, i| "[#{i}] #{r..to_s(link: false)} #{truncate(r.text.squeeze, length: 300)}" }.join("\n") prompt_name ||= 'default' rerank_prompt = prompt(prompt_name, context: 'rerank') or raise 'missing prompt %s' % prompt_name.inspect rerank_prompt = rerank_prompt.to_s .named_placeholders_interpolate({ query:, candidates: }) begin if response = generate(prompt: rerank_prompt).full? indices = response.scan(/\d+/).map(&:to_i) .select { |i| (0...records.size).include?(i) } records = records.values_at(*indices) if indices.any? end rescue => e log(:error, e, data: { context: 'rerank' }) end records end |
#trigger_inject(content, group_uuid:) ⇒ self?
Injects relevant snippets from the session's trigger collection into the conversation as a tool message.
Reads the first entry of the session's trigger hash, performs a
vector search in the configured collection, reranks the candidates
via the LLM, and appends a trigger_inject tool message containing
the surviving snippets (text, similarity, tags). The message is
grouped with the current user message via group_uuid.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/ollama_chat/collection_search.rb', line 109 def trigger_inject(content, group_uuid:) .on? or return trigger = session.trigger&.first or return collection, config = trigger unless config['enabled'] log(:info, 'Trigger for collection %s disabled.' % collection) return end unless col = database_collection?(collection) log(:error, 'Unknown collection named %s' % collection) return end prompt_name = config['prompt_name'] unless rerank_prompt = prompt(prompt_name, context: 'rerank').full?(:to_s) log( :error, 'Unknown rerank prompt named %s' % prompt_name, data: { config: } ) return end records = [] switch_collection(collection) do records = find_document_records(content, text_count: config['text_count']) records.empty? and return pre_rerank = records.size records = rerank_records(content, records, prompt_name:) log( :info, 'Trigger: %d/%d passed rerank for %s' % [ records.size, pre_rerank, collection ], data: { collection:, prompt_name:, records: records.map { |r| { text: r.text, similarity: r.similarity&.round(4), tags: r..to_s(link: false) } } }) records.empty? and return end snippets = records.map { |record| { text: record.text, similarity: record.similarity.to_f, tags: record..to_s(link: false), } } = { prompt: prompt('snippets_trigger').to_s, collection: { name: collection, description: col.description&.to_s, }, snippets: }.to_json tool_name = 'trigger_inject' << OllamaChat::Message.new( role: 'user', tool_name: , sender_name: tool_name, content: , group_uuid: ) self end |