Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
Co-authored-by: Lance Martin <lance@langchain.dev>
Co-authored-by: Jacob Lee <jacoblee93@gmail.com>
This commit is contained in:
Erick Friis
2023-10-25 18:47:42 -07:00
committed by GitHub
parent 43257a295c
commit ebf998acb6
242 changed files with 53432 additions and 31 deletions

View File

@@ -0,0 +1 @@
.env

View File

@@ -0,0 +1,103 @@
# Self-querying with Supabase
> [Supabase](https://supabase.com/docs) is an open-source Firebase alternative. It is built on top of [PostgreSQL](https://en.wikipedia.org/wiki/PostgreSQL), a free and open-source relational database management system (RDBMS) and uses [pgvector](https://github.com/pgvector/pgvector) to store embeddings within your tables.
Use this package to host a LangServe API that can [self-query](https://python.langchain.com/docs/modules/data_connection/retrievers/self_query) Supabase. You'll be able to use natural language to generate a structured query against the database.
## Install Package
From within your `langservehub` project run:
```shell
poetry run poe add self-query-supabase
```
## Setup Supabase Database
Use these steps to setup your Supabase database if you haven't already.
1. Head over to https://database.new to provision your Supabase database.
2. In the studio, jump to the [SQL editor](https://supabase.com/dashboard/project/_/sql/new) and run the following script to enable `pgvector` and setup your database as a vector store:
```sql
-- Enable the pgvector extension to work with embedding vectors
create extension if not exists vector;
-- Create a table to store your documents
create table
documents (
id uuid primary key,
content text, -- corresponds to Document.pageContent
metadata jsonb, -- corresponds to Document.metadata
embedding vector (1536) -- 1536 works for OpenAI embeddings, change as needed
);
-- Create a function to search for documents
create function match_documents (
query_embedding vector (1536),
filter jsonb default '{}'
) returns table (
id uuid,
content text,
metadata jsonb,
similarity float
) language plpgsql as $$
#variable_conflict use_column
begin
return query
select
id,
content,
metadata,
1 - (documents.embedding <=> query_embedding) as similarity
from documents
where metadata @> filter
order by documents.embedding <=> query_embedding;
end;
$$;
```
## Setup Environment Variables
Since we are using [`SupabaseVectorStore`](https://python.langchain.com/docs/integrations/vectorstores/supabase) and [`OpenAIEmbeddings`](https://python.langchain.com/docs/integrations/text_embedding/openai), we need to load their API keys.
Create a `.env` file in the root of your project:
_.env_
```shell
SUPABASE_URL=
SUPABASE_SERVICE_KEY=
OPENAI_API_KEY=
```
To find your `SUPABASE_URL` and `SUPABASE_SERVICE_KEY`, head to your Supabase project's [API settings](https://supabase.com/dashboard/project/_/settings/api).
- `SUPABASE_URL` corresponds to the Project URL
- `SUPABASE_SERVICE_KEY` corresponds to the `service_role` API key
To get your `OPENAI_API_KEY`, navigate to [API keys](https://platform.openai.com/account/api-keys) on your OpenAI account and create a new secret key.
Add this file to your `.gitignore` if it isn't already there (so that we don't commit secrets):
_.gitignore_
```
.env
```
Install [`python-dotenv`](https://github.com/theskumar/python-dotenv) which we will use to load the environment variables into the app:
```shell
poetry add python-dotenv
```
Finally, call `load_dotenv()` in `server.py`.
_app/server.py_
```python
from dotenv import load_dotenv
load_dotenv()
```

1710
templates/self-query-supabase/poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
[tool.poetry]
name = "self_query_supabase"
version = "0.1.0"
description = ""
authors = ["Greg Richardson <greg@supabase.io>"]
readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.8.1,<4.0"
langchain = ">=0.0.313"
openai = "^0.28.1"
tiktoken = "^0.5.1"
supabase = "^1.2.0"
lark = "^1.1.8"
[tool.poetry.group.dev.dependencies]
python-dotenv = { extras = ["cli"], version = "^1.0.0" }
[tool.langserve]
export_module = "self_query_supabase.chain"
export_attr = "chain"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

View File

@@ -0,0 +1,64 @@
import os
from langchain.llms.openai import OpenAI
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain.chat_models import ChatOpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough, RunnableParallel
from langchain.chains.query_constructor.base import AttributeInfo
from supabase.client import create_client
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores.supabase import SupabaseVectorStore
supabase_url = os.environ.get("SUPABASE_URL")
supabase_key = os.environ.get("SUPABASE_SERVICE_KEY")
supabase = create_client(supabase_url, supabase_key)
embeddings = OpenAIEmbeddings()
vectorstore = SupabaseVectorStore(
client=supabase,
embedding=embeddings,
table_name="documents",
query_name="match_documents"
)
# Adjust this based on the metadata you store in the `metadata` JSON column
metadata_field_info = [
AttributeInfo(
name="genre",
description="The genre of the movie",
type="string or list[string]",
),
AttributeInfo(
name="year",
description="The year the movie was released",
type="integer",
),
AttributeInfo(
name="director",
description="The name of the movie director",
type="string",
),
AttributeInfo(
name="rating", description="A 1-10 rating for the movie", type="float"
),
]
# Adjust this based on the type of documents you store
document_content_description = "Brief summary of a movie"
llm = OpenAI(temperature=0)
retriever = SelfQueryRetriever.from_llm(
llm,
vectorstore,
document_content_description,
metadata_field_info,
verbose=True
)
chain = (
RunnableParallel({"query": RunnablePassthrough()})
| retriever
)