-
-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🚃 Langchain::ActiveRecord::Hooks
module for vectorsearch capabilities
#211
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
0293d4f
Langchain::ActiveRecord::Hooks module for vectorsearch capabilities
andreibondarev b7f3416
Merge branch 'main' into active-record-hooks
andreibondarev 6ecec3a
Railtie (#212)
technicalpickles 327f2f4
Merge branch 'main' into active-record-hooks
andreibondarev 035d692
standardrb fixes
andreibondarev 558e271
Update lib/langchain/active_record/hooks.rb
andreibondarev a07e432
Merge branch 'main' into active-record-hooks
andreibondarev 952558b
Introduce as_vector method
andreibondarev f38d833
similarity_search() returns AR collection; switch to using add_text()…
andreibondarev e2b781e
improvements
andreibondarev c259d27
Fix standardrb errors
andreibondarev f3dbfb6
Weaviate fixes
andreibondarev eb9790f
More specs
andreibondarev f2b1516
fix
andreibondarev 9a8af59
fix
andreibondarev 0b7de2e
fix
andreibondarev d4fabd1
more comments
andreibondarev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
# frozen_string_literal: true | ||
|
||
module Langchain | ||
module ActiveRecord | ||
# This module adds the following functionality to your ActiveRecord models: | ||
# * `vectorsearch` class method to set the vector search provider | ||
# * `similarity_search` class method to search for similar texts | ||
# * `upsert_to_vectorsearch` instance method to upsert the record to the vector search provider | ||
# | ||
# Usage: | ||
# class Recipe < ActiveRecord::Base | ||
# vectorsearch provider: Langchain::Vectorsearch::Weaviate.new( | ||
# api_key: ENV["WEAVIATE_API_KEY"], | ||
# url: ENV["WEAVIATE_URL"], | ||
# index_name: "Recipes", | ||
# llm: Langchain::LLM::OpenAI.new(api_key: ENV["OPENAI_API_KEY"]) | ||
# ) | ||
# | ||
# after_save :upsert_to_vectorsearch | ||
# | ||
# # Overwriting how the model is serialized before it's indexed | ||
# def as_vector | ||
# [ | ||
# "Title: #{title}", | ||
# "Description: #{description}", | ||
# ... | ||
# ] | ||
# .compact | ||
# .join("\n") | ||
# end | ||
# end | ||
# | ||
# Create the default schema | ||
# Recipe.class_variable_get(:@@provider).create_default_schema | ||
# Query the vector search provider | ||
# Recipe.similarity_search("carnivore dish") | ||
# Delete the default schema to start over | ||
# Recipe.class_variable_get(:@@provider).client.schema.delete class_name: "Recipes" | ||
# | ||
module Hooks | ||
def self.included(base) | ||
base.extend ClassMethods | ||
end | ||
|
||
# Index the text to the vector search provider | ||
# You'd typically call this method in an ActiveRecord callback | ||
# | ||
# @return [Boolean] true | ||
# @raise [Error] Indexing to vector search DB failed | ||
def upsert_to_vectorsearch | ||
if previously_new_record? | ||
self.class.class_variable_get(:@@provider).add_texts( | ||
texts: [as_vector], | ||
ids: [id] | ||
) | ||
else | ||
self.class.class_variable_get(:@@provider).update_texts( | ||
texts: [as_vector], | ||
ids: [id] | ||
) | ||
end | ||
end | ||
|
||
# Used to serialize the DB record to an indexable vector text | ||
# Overwrite this method in your model to customize | ||
# | ||
# @return [String] the text representation of the model | ||
def as_vector | ||
to_json | ||
end | ||
|
||
module ClassMethods | ||
# Set the vector search provider | ||
# | ||
# @param provider [Object] The `Langchain::Vectorsearch::*` instance | ||
def vectorsearch(provider:) | ||
class_variable_set(:@@provider, provider) | ||
end | ||
|
||
# Search for similar texts | ||
# | ||
# @param query [String] The query to search for | ||
# @param k [Integer] The number of results to return | ||
# @return [ActiveRecord::Relation] The ActiveRecord relation | ||
def similarity_search(query, k: 1) | ||
records = class_variable_get(:@@provider).similarity_search( | ||
query: query, | ||
k: k | ||
) | ||
ids = records.map { |record| record.dig("__id") } | ||
where(id: ids) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# frozen_string_literal: true | ||
|
||
module Langchain | ||
class Railtie < Rails::Railtie | ||
initializer "langchain" do | ||
ActiveSupport.on_load(:active_record) do | ||
::ActiveRecord::Base.include Langchain::ActiveRecord::Hooks | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# frozen_string_literal: true | ||
|
||
class Dummy | ||
include Langchain::ActiveRecord::Hooks | ||
end | ||
|
||
RSpec.describe Langchain::ActiveRecord::Hooks do | ||
it "responds to instance methods" do | ||
expect(Dummy.new).to respond_to(:upsert_to_vectorsearch) | ||
expect(Dummy.new).to respond_to(:as_vector) | ||
end | ||
|
||
it "responds to class methods" do | ||
expect(Dummy).to respond_to(:vectorsearch) | ||
expect(Dummy).to respond_to(:similarity_search) | ||
end | ||
end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see this handled automatically.
I was thinking this could be handled in a similar way to
ActiveRecord::Base.table_name
?Giving it more thought though, the index name is needed at the time vector search is instantiated. Could make it work if we made it lazily instantiated. Maybe something like...