langchainrb 0.7.5 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +28 -22
- data/lib/langchain/llm/azure.rb +1 -1
- data/lib/langchain/llm/google_vertex_ai.rb +55 -0
- data/lib/langchain/llm/llama_cpp.rb +18 -16
- data/lib/langchain/llm/openai.rb +18 -12
- data/lib/langchain/llm/response/google_vertex_ai_response.rb +24 -0
- data/lib/langchain/llm/response/llama_cpp_response.rb +13 -0
- data/lib/langchain/utils/token_length/openai_validator.rb +3 -1
- data/lib/langchain/vectorsearch/elasticsearch.rb +39 -3
- data/lib/langchain/vectorsearch/qdrant.rb +2 -2
- data/lib/langchain/version.rb +1 -1
- metadata +23 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ea2adff257b4151b8acf24a02de851df2d99fe8890d6afd06bcdc3a5f53e9e1
|
4
|
+
data.tar.gz: 646a5f9246bffc20654672393f9175c1f0f30533ba1546cef05ce951d449c9ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b2aaace63c46b7eec9d8cc04a2cd9cc84c79c90a5a1f1ce1bcb11e4416021f89293d40309ca35b0e4dbb2036a2962bde0faa28ad46d081846dcb00a9a1bf783
|
7
|
+
data.tar.gz: fd5e8e03053ab99a737b3ce17c12ae76da2bc1d0b4bda89eb16e16afe43f260325af78a7c62faf0041c8869cbd94c0a5bbbda920bb7e1d7f175ac35545b53f00
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.8.0]
|
4
|
+
- [BREAKING] Updated llama_cpp.rb to 0.9.4. The model file format used by the underlying llama.cpp library has changed to GGUF. llama.cpp ships with scripts to convert existing files and GGUF format models can be downloaded from HuggingFace.
|
5
|
+
- Introducing Langchain::LLM::GoogleVertexAi LLM provider
|
6
|
+
|
3
7
|
## [0.7.5] - 2023-11-13
|
4
8
|
- Fixes
|
5
9
|
|
data/README.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# Please fill out the [Ruby AI Survey 2023](https://docs.google.com/forms/d/1dH_0js1wpEyh1YqPTOxU3b5fXj76sb5lYp12lVoNNZE/edit).
|
2
|
+
Results will be anonymized and shared!
|
3
|
+
|
1
4
|
💎🔗 Langchain.rb
|
2
5
|
---
|
3
6
|
⚡ Building LLM-powered applications in Ruby ⚡
|
@@ -53,23 +56,24 @@ require "langchain"
|
|
53
56
|
Langchain.rb wraps all supported LLMs in a unified interface allowing you to easily swap out and test out different models.
|
54
57
|
|
55
58
|
#### Supported LLMs and features:
|
56
|
-
| LLM providers
|
57
|
-
| --------
|
58
|
-
| [OpenAI](https://openai.com
|
59
|
-
| [AI21](https://ai21.com
|
60
|
-
| [Anthropic](https://
|
61
|
-
| [AWS Bedrock](https://aws.amazon.com/bedrock)
|
62
|
-
| [Cohere](https://
|
63
|
-
| [GooglePalm](https://ai.google/discover/palm2
|
64
|
-
| [
|
65
|
-
| [
|
66
|
-
| [
|
59
|
+
| LLM providers | embed() | complete() | chat() | summarize() | Notes |
|
60
|
+
| -------- |:------------------:| :-------: | :-----------------: | :-------: | :----------------- |
|
61
|
+
| [OpenAI](https://openai.com/?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ | ✅ | ❌ | Including Azure OpenAI |
|
62
|
+
| [AI21](https://ai21.com/?utm_source=langchainrb&utm_medium=github) | ❌ | ✅ | ❌ | ✅ | |
|
63
|
+
| [Anthropic](https://anthropic.com/?utm_source=langchainrb&utm_medium=github) | ❌ | ✅ | ❌ | ❌ | |
|
64
|
+
| [AWS Bedrock](https://aws.amazon.com/bedrock?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ | ❌ | ❌ | Provides AWS, Cohere, AI21, Antropic and Stability AI models |
|
65
|
+
| [Cohere](https://cohere.com/?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ | ✅ | ✅ | |
|
66
|
+
| [GooglePalm](https://ai.google/discover/palm2?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ | ✅ | ✅ | |
|
67
|
+
| [Google Vertex AI](https://cloud.google.com/vertex-ai?utm_source=langchainrb&utm_medium=github) | ✅ | ❌ | ❌ | ❌ | |
|
68
|
+
| [HuggingFace](https://huggingface.co/?utm_source=langchainrb&utm_medium=github) | ✅ | ❌ | ❌ | ❌ | |
|
69
|
+
| [Ollama](https://ollama.ai/?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ | ❌ | ❌ | |
|
70
|
+
| [Replicate](https://replicate.com/?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ | ✅ | ✅ | |
|
67
71
|
|
68
72
|
#### Using standalone LLMs:
|
69
73
|
|
70
74
|
#### OpenAI
|
71
75
|
|
72
|
-
Add `gem "ruby-openai", "~>
|
76
|
+
Add `gem "ruby-openai", "~> 6.1.0"` to your Gemfile.
|
73
77
|
|
74
78
|
```ruby
|
75
79
|
llm = Langchain::LLM::OpenAI.new(api_key: ENV["OPENAI_API_KEY"])
|
@@ -303,15 +307,16 @@ Langchain.rb provides a convenient unified interface on top of supported vectors
|
|
303
307
|
|
304
308
|
#### Supported vector search databases and features:
|
305
309
|
|
306
|
-
| Database
|
307
|
-
| --------
|
308
|
-
| [Chroma](https://trychroma.com
|
309
|
-
| [Hnswlib](https://github.com/nmslib/hnswlib
|
310
|
-
| [Milvus](https://milvus.io
|
311
|
-
| [Pinecone](https://www.pinecone.io
|
312
|
-
| [Pgvector](https://github.com/pgvector/pgvector) |
|
313
|
-
| [Qdrant](https://qdrant.tech
|
314
|
-
| [Weaviate](https://weaviate.io
|
310
|
+
| Database | Open-source | Cloud offering |
|
311
|
+
| -------- |:------------------:| :------------: |
|
312
|
+
| [Chroma](https://trychroma.com/?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ |
|
313
|
+
| [Hnswlib](https://github.com/nmslib/hnswlib/?utm_source=langchainrb&utm_medium=github) | ✅ | ❌ |
|
314
|
+
| [Milvus](https://milvus.io/?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ Zilliz Cloud |
|
315
|
+
| [Pinecone](https://www.pinecone.io/?utm_source=langchainrb&utm_medium=github) | ❌ | ✅ |
|
316
|
+
| [Pgvector](https://github.com/pgvector/pgvector/?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ |
|
317
|
+
| [Qdrant](https://qdrant.tech/?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ |
|
318
|
+
| [Weaviate](https://weaviate.io/?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ |
|
319
|
+
| [Elasticsearch](https://www.elastic.co/?utm_source=langchainrb&utm_medium=github) | ✅ | ✅ |
|
315
320
|
|
316
321
|
### Using Vector Search Databases 🔍
|
317
322
|
|
@@ -341,7 +346,8 @@ client = Langchain::Vectorsearch::Hnswlib.new(...) # `gem "hnswlib", "~> 0.8.1"
|
|
341
346
|
client = Langchain::Vectorsearch::Milvus.new(...) # `gem "milvus", "~> 0.9.2"`
|
342
347
|
client = Langchain::Vectorsearch::Pinecone.new(...) # `gem "pinecone", "~> 0.1.6"`
|
343
348
|
client = Langchain::Vectorsearch::Pgvector.new(...) # `gem "pgvector", "~> 0.2"`
|
344
|
-
client = Langchain::Vectorsearch::Qdrant.new(...) # `gem"qdrant-ruby", "~> 0.9.3"`
|
349
|
+
client = Langchain::Vectorsearch::Qdrant.new(...) # `gem "qdrant-ruby", "~> 0.9.3"`
|
350
|
+
client = Langchain::Vectorsearch::Elasticsearch.new(...) # `gem "elasticsearch", "~> 8.2.0"`
|
345
351
|
```
|
346
352
|
|
347
353
|
Create the default schema:
|
data/lib/langchain/llm/azure.rb
CHANGED
@@ -4,7 +4,7 @@ module Langchain::LLM
|
|
4
4
|
# LLM interface for Azure OpenAI Service APIs: https://learn.microsoft.com/en-us/azure/ai-services/openai/
|
5
5
|
#
|
6
6
|
# Gem requirements:
|
7
|
-
# gem "ruby-openai", "~>
|
7
|
+
# gem "ruby-openai", "~> 6.1.0"
|
8
8
|
#
|
9
9
|
# Usage:
|
10
10
|
# openai = Langchain::LLM::Azure.new(api_key:, llm_options: {}, embedding_deployment_url: chat_deployment_url:)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Langchain::LLM
|
4
|
+
#
|
5
|
+
# Wrapper around the Google Vertex AI APIs: https://cloud.google.com/vertex-ai?hl=en
|
6
|
+
#
|
7
|
+
# Gem requirements:
|
8
|
+
# gem "google-apis-aiplatform_v1", "~> 0.7"
|
9
|
+
#
|
10
|
+
# Usage:
|
11
|
+
# google_palm = Langchain::LLM::GoogleVertexAi.new(project_id: ENV["GOOGLE_VERTEX_AI_PROJECT_ID"])
|
12
|
+
#
|
13
|
+
class GoogleVertexAi < Base
|
14
|
+
DEFAULTS = {
|
15
|
+
temperature: 0.2,
|
16
|
+
dimension: 768,
|
17
|
+
embeddings_model_name: "textembedding-gecko"
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
attr_reader :project_id, :client
|
21
|
+
|
22
|
+
def initialize(project_id:, default_options: {})
|
23
|
+
depends_on "google-apis-aiplatform_v1"
|
24
|
+
|
25
|
+
@project_id = project_id
|
26
|
+
|
27
|
+
@client = Google::Apis::AiplatformV1::AiplatformService.new
|
28
|
+
|
29
|
+
# TODO: Adapt for other regions; Pass it in via the constructor
|
30
|
+
@client.root_url = "https://us-central1-aiplatform.googleapis.com/"
|
31
|
+
@client.authorization = Google::Auth.get_application_default
|
32
|
+
|
33
|
+
@defaults = DEFAULTS.merge(default_options)
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Generate an embedding for a given text
|
38
|
+
#
|
39
|
+
# @param text [String] The text to generate an embedding for
|
40
|
+
# @return [Langchain::LLM::GooglePalmResponse] Response object
|
41
|
+
#
|
42
|
+
def embed(text:)
|
43
|
+
content = [{content: text}]
|
44
|
+
request = Google::Apis::AiplatformV1::GoogleCloudAiplatformV1PredictRequest.new(instances: content)
|
45
|
+
|
46
|
+
api_path = "projects/#{@project_id}/locations/us-central1/publishers/google/models/#{@defaults[:embeddings_model_name]}"
|
47
|
+
|
48
|
+
puts("api_path: #{api_path}")
|
49
|
+
|
50
|
+
response = client.predict_project_location_publisher_model(api_path, request)
|
51
|
+
|
52
|
+
Langchain::LLM::GoogleVertexAiResponse.new(response.to_h, model: @defaults[:embeddings_model_name])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -22,7 +22,7 @@ module Langchain::LLM
|
|
22
22
|
# @param n_ctx [Integer] The number of context tokens to use
|
23
23
|
# @param n_threads [Integer] The CPU number of threads to use
|
24
24
|
# @param seed [Integer] The seed to use
|
25
|
-
def initialize(model_path:, n_gpu_layers: 1, n_ctx: 2048, n_threads: 1, seed:
|
25
|
+
def initialize(model_path:, n_gpu_layers: 1, n_ctx: 2048, n_threads: 1, seed: 0)
|
26
26
|
depends_on "llama_cpp"
|
27
27
|
|
28
28
|
@model_path = model_path
|
@@ -33,30 +33,25 @@ module Langchain::LLM
|
|
33
33
|
end
|
34
34
|
|
35
35
|
# @param text [String] The text to embed
|
36
|
-
# @param n_threads [Integer] The number of CPU threads to use
|
37
36
|
# @return [Array<Float>] The embedding
|
38
|
-
def embed(text
|
37
|
+
def embed(text:)
|
39
38
|
# contexts are kinda stateful when it comes to embeddings, so allocate one each time
|
40
39
|
context = embedding_context
|
41
40
|
|
42
|
-
embedding_input =
|
41
|
+
embedding_input = @model.tokenize(text: text, add_bos: true)
|
43
42
|
return unless embedding_input.size.positive?
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
context.eval(tokens: embedding_input, n_past: 0, n_threads: n_threads)
|
48
|
-
context.embeddings
|
44
|
+
context.eval(tokens: embedding_input, n_past: 0)
|
45
|
+
Langchain::LLM::LlamaCppResponse.new(context, model: context.model.desc)
|
49
46
|
end
|
50
47
|
|
51
48
|
# @param prompt [String] The prompt to complete
|
52
49
|
# @param n_predict [Integer] The number of tokens to predict
|
53
|
-
# @param n_threads [Integer] The number of CPU threads to use
|
54
50
|
# @return [String] The completed prompt
|
55
|
-
def complete(prompt:, n_predict: 128
|
56
|
-
n_threads ||= self.n_threads
|
51
|
+
def complete(prompt:, n_predict: 128)
|
57
52
|
# contexts do not appear to be stateful when it comes to completion, so re-use the same one
|
58
53
|
context = completion_context
|
59
|
-
::LLaMACpp.generate(context, prompt,
|
54
|
+
::LLaMACpp.generate(context, prompt, n_predict: n_predict)
|
60
55
|
end
|
61
56
|
|
62
57
|
private
|
@@ -71,23 +66,30 @@ module Langchain::LLM
|
|
71
66
|
|
72
67
|
context_params.seed = seed
|
73
68
|
context_params.n_ctx = n_ctx
|
74
|
-
context_params.
|
69
|
+
context_params.n_threads = n_threads
|
75
70
|
context_params.embedding = embeddings
|
76
71
|
|
77
72
|
context_params
|
78
73
|
end
|
79
74
|
|
75
|
+
def build_model_params
|
76
|
+
model_params = ::LLaMACpp::ModelParams.new
|
77
|
+
model_params.n_gpu_layers = n_gpu_layers
|
78
|
+
|
79
|
+
model_params
|
80
|
+
end
|
81
|
+
|
80
82
|
def build_model(embeddings: false)
|
81
83
|
return @model if defined?(@model)
|
82
|
-
@model = ::LLaMACpp::Model.new(model_path: model_path, params:
|
84
|
+
@model = ::LLaMACpp::Model.new(model_path: model_path, params: build_model_params)
|
83
85
|
end
|
84
86
|
|
85
87
|
def build_completion_context
|
86
|
-
::LLaMACpp::Context.new(model: build_model)
|
88
|
+
::LLaMACpp::Context.new(model: build_model, params: build_context_params(embeddings: false))
|
87
89
|
end
|
88
90
|
|
89
91
|
def build_embedding_context
|
90
|
-
::LLaMACpp::Context.new(model: build_model(embeddings: true))
|
92
|
+
::LLaMACpp::Context.new(model: build_model, params: build_context_params(embeddings: true))
|
91
93
|
end
|
92
94
|
|
93
95
|
def completion_context
|
data/lib/langchain/llm/openai.rb
CHANGED
@@ -4,7 +4,7 @@ module Langchain::LLM
|
|
4
4
|
# LLM interface for OpenAI APIs: https://platform.openai.com/overview
|
5
5
|
#
|
6
6
|
# Gem requirements:
|
7
|
-
# gem "ruby-openai", "~>
|
7
|
+
# gem "ruby-openai", "~> 6.1.0"
|
8
8
|
#
|
9
9
|
# Usage:
|
10
10
|
# openai = Langchain::LLM::OpenAI.new(api_key:, llm_options: {})
|
@@ -29,7 +29,6 @@ module Langchain::LLM
|
|
29
29
|
LENGTH_VALIDATOR = Langchain::Utils::TokenLength::OpenAIValidator
|
30
30
|
|
31
31
|
attr_accessor :functions
|
32
|
-
attr_accessor :response_chunks
|
33
32
|
|
34
33
|
def initialize(api_key:, llm_options: {}, default_options: {})
|
35
34
|
depends_on "ruby-openai", req: "openai"
|
@@ -137,6 +136,7 @@ module Langchain::LLM
|
|
137
136
|
|
138
137
|
response = with_api_error_handling { client.chat(parameters: parameters) }
|
139
138
|
response = response_from_chunks if block
|
139
|
+
reset_response_chunks
|
140
140
|
Langchain::LLM::OpenAIResponse.new(response)
|
141
141
|
end
|
142
142
|
|
@@ -158,6 +158,12 @@ module Langchain::LLM
|
|
158
158
|
|
159
159
|
private
|
160
160
|
|
161
|
+
attr_reader :response_chunks
|
162
|
+
|
163
|
+
def reset_response_chunks
|
164
|
+
@response_chunks = []
|
165
|
+
end
|
166
|
+
|
161
167
|
def is_legacy_model?(model)
|
162
168
|
LEGACY_COMPLETION_MODELS.any? { |legacy_model| model.include?(legacy_model) }
|
163
169
|
end
|
@@ -242,18 +248,18 @@ module Langchain::LLM
|
|
242
248
|
end
|
243
249
|
|
244
250
|
def response_from_chunks
|
245
|
-
@response_chunks.
|
251
|
+
grouped_chunks = @response_chunks.group_by { |chunk| chunk.dig("choices", 0, "index") }
|
252
|
+
final_choices = grouped_chunks.map do |index, chunks|
|
246
253
|
{
|
247
|
-
"
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
}
|
254
|
-
]
|
254
|
+
"index" => index,
|
255
|
+
"message" => {
|
256
|
+
"role" => "assistant",
|
257
|
+
"content" => chunks.map { |chunk| chunk.dig("choices", 0, "delta", "content") }.join
|
258
|
+
},
|
259
|
+
"finish_reason" => chunks.last.dig("choices", 0, "finish_reason")
|
255
260
|
}
|
256
|
-
|
261
|
+
end
|
262
|
+
@response_chunks.first&.slice("id", "object", "created", "model")&.merge({"choices" => final_choices})
|
257
263
|
end
|
258
264
|
end
|
259
265
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Langchain::LLM
|
4
|
+
class GoogleVertexAiResponse < BaseResponse
|
5
|
+
attr_reader :prompt_tokens
|
6
|
+
|
7
|
+
def initialize(raw_response, model: nil)
|
8
|
+
@prompt_tokens = prompt_tokens
|
9
|
+
super(raw_response, model: model)
|
10
|
+
end
|
11
|
+
|
12
|
+
def embedding
|
13
|
+
embeddings.first
|
14
|
+
end
|
15
|
+
|
16
|
+
def total_tokens
|
17
|
+
raw_response.dig(:predictions, 0, :embeddings, :statistics, :token_count)
|
18
|
+
end
|
19
|
+
|
20
|
+
def embeddings
|
21
|
+
[raw_response.dig(:predictions, 0, :embeddings, :values)]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -15,7 +15,8 @@ module Langchain
|
|
15
15
|
# Source:
|
16
16
|
# https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo
|
17
17
|
"gpt-4-1106-preview" => 4096,
|
18
|
-
"gpt-4-vision-preview" => 4096
|
18
|
+
"gpt-4-vision-preview" => 4096,
|
19
|
+
"gpt-3.5-turbo-1106" => 4096
|
19
20
|
}
|
20
21
|
|
21
22
|
TOKEN_LIMITS = {
|
@@ -26,6 +27,7 @@ module Langchain
|
|
26
27
|
"gpt-3.5-turbo" => 4096,
|
27
28
|
"gpt-3.5-turbo-0301" => 4096,
|
28
29
|
"gpt-3.5-turbo-0613" => 4096,
|
30
|
+
"gpt-3.5-turbo-1106" => 16385,
|
29
31
|
"gpt-3.5-turbo-16k" => 16384,
|
30
32
|
"gpt-3.5-turbo-16k-0613" => 16384,
|
31
33
|
"text-davinci-003" => 4097,
|
@@ -46,6 +46,9 @@ module Langchain::Vectorsearch
|
|
46
46
|
super(llm: llm)
|
47
47
|
end
|
48
48
|
|
49
|
+
# Add a list of texts to the index
|
50
|
+
# @param texts [Array<String>] The list of texts to add
|
51
|
+
# @return [Elasticsearch::Response] from the Elasticsearch server
|
49
52
|
def add_texts(texts: [])
|
50
53
|
body = texts.map do |text|
|
51
54
|
[
|
@@ -57,6 +60,10 @@ module Langchain::Vectorsearch
|
|
57
60
|
es_client.bulk(body: body)
|
58
61
|
end
|
59
62
|
|
63
|
+
# Add a list of texts to the index
|
64
|
+
# @param texts [Array<String>] The list of texts to update
|
65
|
+
# @param texts [Array<Integer>] The list of texts to update
|
66
|
+
# @return [Elasticsearch::Response] from the Elasticsearch server
|
60
67
|
def update_texts(texts: [], ids: [])
|
61
68
|
body = texts.map.with_index do |text, i|
|
62
69
|
[
|
@@ -68,6 +75,8 @@ module Langchain::Vectorsearch
|
|
68
75
|
es_client.bulk(body: body)
|
69
76
|
end
|
70
77
|
|
78
|
+
# Create the index with the default schema
|
79
|
+
# @return [Elasticsearch::Response] Index creation
|
71
80
|
def create_default_schema
|
72
81
|
es_client.indices.create(
|
73
82
|
index: index_name,
|
@@ -75,6 +84,8 @@ module Langchain::Vectorsearch
|
|
75
84
|
)
|
76
85
|
end
|
77
86
|
|
87
|
+
# Deletes the default schema
|
88
|
+
# @return [Elasticsearch::Response] Index deletion
|
78
89
|
def delete_default_schema
|
79
90
|
es_client.indices.delete(
|
80
91
|
index: index_name
|
@@ -116,10 +127,30 @@ module Langchain::Vectorsearch
|
|
116
127
|
}
|
117
128
|
end
|
118
129
|
|
119
|
-
#
|
120
|
-
#
|
121
|
-
#
|
130
|
+
# Ask a question and return the answer
|
131
|
+
# @param question [String] The question to ask
|
132
|
+
# @param k [Integer] The number of results to have in context
|
133
|
+
# @yield [String] Stream responses back one String at a time
|
134
|
+
# @return [String] The answer to the question
|
135
|
+
def ask(question:, k: 4, &block)
|
136
|
+
search_results = similarity_search(query: question, k: k)
|
122
137
|
|
138
|
+
context = search_results.map do |result|
|
139
|
+
result[:input]
|
140
|
+
end.join("\n---\n")
|
141
|
+
|
142
|
+
prompt = generate_rag_prompt(question: question, context: context)
|
143
|
+
|
144
|
+
response = llm.chat(prompt: prompt, &block)
|
145
|
+
response.context = context
|
146
|
+
response
|
147
|
+
end
|
148
|
+
|
149
|
+
# Search for similar texts
|
150
|
+
# @param text [String] The text to search for
|
151
|
+
# @param k [Integer] The number of results to return
|
152
|
+
# @param query [Hash] Elasticsearch query that needs to be used while searching (Optional)
|
153
|
+
# @return [Elasticsearch::Response] The response from the server
|
123
154
|
def similarity_search(text: "", k: 10, query: {})
|
124
155
|
if text.empty? && query.empty?
|
125
156
|
raise "Either text or query should pass as an argument"
|
@@ -134,6 +165,11 @@ module Langchain::Vectorsearch
|
|
134
165
|
es_client.search(body: {query: query, size: k}).body
|
135
166
|
end
|
136
167
|
|
168
|
+
# Search for similar texts by embedding
|
169
|
+
# @param embedding [Array<Float>] The embedding to search for
|
170
|
+
# @param k [Integer] The number of results to return
|
171
|
+
# @param query [Hash] Elasticsearch query that needs to be used while searching (Optional)
|
172
|
+
# @return [Elasticsearch::Response] The response from the server
|
137
173
|
def similarity_search_by_vector(embedding: [], k: 10, query: {})
|
138
174
|
if embedding.empty? && query.empty?
|
139
175
|
raise "Either embedding or query should pass as an argument"
|
@@ -44,14 +44,14 @@ module Langchain::Vectorsearch
|
|
44
44
|
# Add a list of texts to the index
|
45
45
|
# @param texts [Array<String>] The list of texts to add
|
46
46
|
# @return [Hash] The response from the server
|
47
|
-
def add_texts(texts:, ids: [])
|
47
|
+
def add_texts(texts:, ids: [], payload: {})
|
48
48
|
batch = {ids: [], vectors: [], payloads: []}
|
49
49
|
|
50
50
|
Array(texts).each_with_index do |text, i|
|
51
51
|
id = ids[i] || SecureRandom.uuid
|
52
52
|
batch[:ids].push(id)
|
53
53
|
batch[:vectors].push(llm.embed(text: text).embedding)
|
54
|
-
batch[:payloads].push({content: text})
|
54
|
+
batch[:payloads].push({content: text}.merge(payload))
|
55
55
|
end
|
56
56
|
|
57
57
|
client.points.upsert(
|
data/lib/langchain/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: langchainrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrei Bondarev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: baran
|
@@ -290,6 +290,20 @@ dependencies:
|
|
290
290
|
- - "~>"
|
291
291
|
- !ruby/object:Gem::Version
|
292
292
|
version: 1.6.5
|
293
|
+
- !ruby/object:Gem::Dependency
|
294
|
+
name: google-apis-aiplatform_v1
|
295
|
+
requirement: !ruby/object:Gem::Requirement
|
296
|
+
requirements:
|
297
|
+
- - "~>"
|
298
|
+
- !ruby/object:Gem::Version
|
299
|
+
version: '0.7'
|
300
|
+
type: :development
|
301
|
+
prerelease: false
|
302
|
+
version_requirements: !ruby/object:Gem::Requirement
|
303
|
+
requirements:
|
304
|
+
- - "~>"
|
305
|
+
- !ruby/object:Gem::Version
|
306
|
+
version: '0.7'
|
293
307
|
- !ruby/object:Gem::Dependency
|
294
308
|
name: google_palm_api
|
295
309
|
requirement: !ruby/object:Gem::Requirement
|
@@ -366,14 +380,14 @@ dependencies:
|
|
366
380
|
requirements:
|
367
381
|
- - "~>"
|
368
382
|
- !ruby/object:Gem::Version
|
369
|
-
version: 0.
|
383
|
+
version: 0.9.4
|
370
384
|
type: :development
|
371
385
|
prerelease: false
|
372
386
|
version_requirements: !ruby/object:Gem::Requirement
|
373
387
|
requirements:
|
374
388
|
- - "~>"
|
375
389
|
- !ruby/object:Gem::Version
|
376
|
-
version: 0.
|
390
|
+
version: 0.9.4
|
377
391
|
- !ruby/object:Gem::Dependency
|
378
392
|
name: nokogiri
|
379
393
|
requirement: !ruby/object:Gem::Requirement
|
@@ -506,14 +520,14 @@ dependencies:
|
|
506
520
|
requirements:
|
507
521
|
- - "~>"
|
508
522
|
- !ruby/object:Gem::Version
|
509
|
-
version:
|
523
|
+
version: 6.1.0
|
510
524
|
type: :development
|
511
525
|
prerelease: false
|
512
526
|
version_requirements: !ruby/object:Gem::Requirement
|
513
527
|
requirements:
|
514
528
|
- - "~>"
|
515
529
|
- !ruby/object:Gem::Version
|
516
|
-
version:
|
530
|
+
version: 6.1.0
|
517
531
|
- !ruby/object:Gem::Dependency
|
518
532
|
name: safe_ruby
|
519
533
|
requirement: !ruby/object:Gem::Requirement
|
@@ -619,6 +633,7 @@ files:
|
|
619
633
|
- lib/langchain/llm/base.rb
|
620
634
|
- lib/langchain/llm/cohere.rb
|
621
635
|
- lib/langchain/llm/google_palm.rb
|
636
|
+
- lib/langchain/llm/google_vertex_ai.rb
|
622
637
|
- lib/langchain/llm/hugging_face.rb
|
623
638
|
- lib/langchain/llm/llama_cpp.rb
|
624
639
|
- lib/langchain/llm/ollama.rb
|
@@ -631,7 +646,9 @@ files:
|
|
631
646
|
- lib/langchain/llm/response/base_response.rb
|
632
647
|
- lib/langchain/llm/response/cohere_response.rb
|
633
648
|
- lib/langchain/llm/response/google_palm_response.rb
|
649
|
+
- lib/langchain/llm/response/google_vertex_ai_response.rb
|
634
650
|
- lib/langchain/llm/response/hugging_face_response.rb
|
651
|
+
- lib/langchain/llm/response/llama_cpp_response.rb
|
635
652
|
- lib/langchain/llm/response/ollama_response.rb
|
636
653
|
- lib/langchain/llm/response/openai_response.rb
|
637
654
|
- lib/langchain/llm/response/replicate_response.rb
|