feat: new Vectara RAG Component (#2733)

* First implementation of LangWatch tracer

* Remove dependency from backend base internal and add langwatch docs

* Bump langwatch to v0.1.4

* Fix missing log parameter on method

* Move docs to the right folder

* chore: update lock

* Add Vectara RAG component and docs

* [autofix.ci] apply automated fixes

* refactor: update VectaraRAG component to the new component standard

* fix: update VectaraRagComponent filter parameter

Update the filter parameter in the VectaraRagComponent class to use the correct variable name 'self.filter' instead of 'filter'. This ensures that the correct filter value is passed to the VectaraQueryConfig object.

* fix: add condition to set_cache_coro in Graph class

Add a condition to the `set_cache_coro` function call in the `Graph` class. The condition checks if the `cache` variable is true and the `flow_id` is not empty before calling the function. This ensures that the cache is set only when both conditions are met, improving the efficiency of the code.

---------

Co-authored-by: Rogério Chaves <rogeriochaves@users.noreply.github.com>
Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
David Oplatka 2024-07-28 07:02:23 -07:00 committed by GitHub
commit 469625c0a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 222 additions and 17 deletions

View file

@ -0,0 +1,31 @@
---
title: RAG
sidebar_position: 9
slug: /components-rag
---
RAG (Retrieval-Augmented Generation) components process a user query by retrieving relevant documents and generating a concise summary that addresses the user's question.
### Vectara
`Vectara` performs RAG using a Vectara corpus, including document retrieval, reranking results, and summary generation.
**Parameters:**
- **Vectara Customer ID:** Customer ID.
- **Vectara Corpus ID:** Corpus ID.
- **Vectara API Key:** API key.
- **Search Query:** User query.
- **Lexical Interpolation:** How much to weigh lexical vs. embedding scores.
- **Metadata Filters:** Filters to narrow down the search documents and parts.
- **Reranker Type:** How to rerank the retrieved results.
- **Number of Results to Rerank:** Maximum reranked results.
- **Diversity Bias:** How much to diversify retrieved results (only for MMR reranker).
- **Max Results to Summarize:** Maximum search results to provide to summarizer.
- **Response Language:** The language code (use ISO 639-1 or 639-3 codes) of the summary.
- **Prompt Name:** The summarizer prompt.
For more information, consult the [Vectara documentation](https://docs.vectara.com/docs)

View file

@ -0,0 +1,46 @@
import Admonition from "@theme/Admonition";
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
# LangWatch
LangWatch is an all-in-one LLMOps platform for monitoring, observability, analytics, evaluations and alerting for getting user insights and improve your LLM workflows.
To integrate with Langflow, just add your LangWatch API as a Langflow environment variable and you are good to go!
## Step-by-step Configuration
1. Obtain your LangWatch API key from https://app.langwatch.com/
2. Add the following key to Langflow .env file:
```bash
LANGWATCH_API_KEY="your-api-key"
```
or export it in your terminal:
```bash
export LANGWATCH_API_KEY="your-api-key"
```
3. Restart Langflow using `langflow run --env-file .env`
4. Run any project and check the LangWatch dashboard for monitoring and observability.
<ZoomableImage
alt="LangWatch Flow Example"
sources={{
light: useBaseUrl("img/langwatch-flow.png"),
dark: useBaseUrl("img/langwatch-flow.png"),
}}
style={{ width: "100%", margin: "20px auto", boxShadow: "rgba(50, 50, 93, 0.2) 0px 0px 27px" }}
/>
<ZoomableImage
alt="LangSmith Trace"
sources={{
light: useBaseUrl("img/langwatch-trace.png"),
dark: useBaseUrl("img/langwatch-trace.png"),
}}
style={{ width: "100%", margin: "20px auto", background: "red", boxShadow: "rgba(50, 50, 93, 0.2) 0px 0px 27px" }}
/>

21
poetry.lock generated
View file

@ -1332,6 +1332,17 @@ files = [
{file = "coolname-2.2.0.tar.gz", hash = "sha256:6c5d5731759104479e7ca195a9b64f7900ac5bead40183c09323c7d0be9e75c7"},
]
[[package]]
name = "coolname"
version = "2.2.0"
description = "Random name and slug generator"
optional = false
python-versions = "*"
files = [
{file = "coolname-2.2.0-py2.py3-none-any.whl", hash = "sha256:4d1563186cfaf71b394d5df4c744f8c41303b6846413645e31d31915cdeb13e8"},
{file = "coolname-2.2.0.tar.gz", hash = "sha256:6c5d5731759104479e7ca195a9b64f7900ac5bead40183c09323c7d0be9e75c7"},
]
[[package]]
name = "couchbase"
version = "4.3.0"
@ -2707,8 +2718,8 @@ files = [
[package.dependencies]
cffi = {version = ">=1.12.2", markers = "platform_python_implementation == \"CPython\" and sys_platform == \"win32\""}
greenlet = [
{version = ">=3.0rc3", markers = "platform_python_implementation == \"CPython\" and python_version >= \"3.11\""},
{version = ">=2.0.0", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.11\""},
{version = ">=3.0rc3", markers = "platform_python_implementation == \"CPython\" and python_version >= \"3.11\""},
]
"zope.event" = "*"
"zope.interface" = "*"
@ -2867,12 +2878,12 @@ files = [
google-auth = ">=2.14.1,<3.0.dev0"
googleapis-common-protos = ">=1.56.2,<2.0.dev0"
grpcio = [
{version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
{version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""},
{version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
]
grpcio-status = [
{version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
{version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""},
{version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
]
proto-plus = ">=1.22.3,<2.0.0dev"
protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0"
@ -5220,8 +5231,8 @@ psutil = ">=5.9.1"
pywin32 = {version = "*", markers = "platform_system == \"Windows\""}
pyzmq = ">=25.0.0"
requests = [
{version = ">=2.32.2", markers = "python_version > \"3.11\""},
{version = ">=2.26.0", markers = "python_version <= \"3.11\""},
{version = ">=2.32.2", markers = "python_version > \"3.11\""},
]
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.11\""}
@ -6826,9 +6837,9 @@ files = [
[package.dependencies]
numpy = [
{version = ">=1.26.0", markers = "python_version >= \"3.12\""},
{version = ">=1.22.4", markers = "python_version < \"3.11\""},
{version = ">=1.23.2", markers = "python_version == \"3.11\""},
{version = ">=1.26.0", markers = "python_version >= \"3.12\""},
]
python-dateutil = ">=2.8.2"
pytz = ">=2020.1"

View file

@ -0,0 +1,127 @@
from langflow.custom import Component
from langflow.field_typing.range_spec import RangeSpec
from langflow.io import DropdownInput, FloatInput, IntInput, MessageTextInput, Output
from langflow.schema.message import Message
class VectaraRagComponent(Component):
display_name = "Vectara RAG"
description = "Vectara's full end to end RAG"
documentation = "https://docs.vectara.com/docs"
icon = "Vectara"
name = "VectaraRAG"
SUMMARIZER_PROMPTS = [
"vectara-summary-ext-24-05-sml",
"vectara-summary-ext-24-05-med-omni",
"vectara-summary-ext-24-05-large",
"vectara-summary-ext-24-05-med",
"vectara-summary-ext-v1.3.0",
]
RERANKER_TYPES = ["mmr", "rerank_multilingual_v1", "none"]
field_order = ["vectara_customer_id", "vectara_corpus_id", "vectara_api_key", "search_query", "reranker"]
# return {
# "vectara_customer_id": {"display_name": "Vectara Customer ID", "field_type": "str", "required": True},
# "vectara_corpus_id": {"display_name": "Vectara Corpus ID", "field_type": "str", "required": True},
# "vectara_api_key": {"display_name": "Vectara API Key", "field_type": "str", "required": True},
# "search_query": {"display_name": "Search Query", "field_type": "str", "info": "The query to receive an answer on.", "required": True},
# "lexical_interpolation": {"display_name": "Hybrid Search Factor", "field_type": "float", "value": 0.005, "info": "How much to weigh lexical scores compared to the embedding score. 0 means lexical search is not used at all, and 1 means only lexical search is used.", "advanced": True},
# "filter": {"display_name": "Metadata Filters", "field_type": "str", "value": '', "info": "The filter string to narrow the search to according to metadata attributes.", "advanced": True},
# "reranker": {"display_name": "Reranker Type", "options": RERANKER_TYPES, "value": RERANKER_TYPES[0], "info": "How to rerank the retrieved search results."},
# "reranker_k": {"display_name": "Number of Results to Rerank", "field_type": "int", "value": 50, "advanced": True},
# "diversity_bias": {"display_name": "Diversity Bias", "field_type": "float", "value": 0.2, "info": "Ranges from 0 to 1, with higher values indicating greater diversity (only applies to MMR reranker).", "advanced": True},
# "max_results": {"display_name": "Max Results to Summarize", "field_type": "int", "value": 7, "info": "The maximum number of search results to be available to the prompt.", "advanced": True},
# "response_lang": {"display_name": "Response Language", "field_type": "str", "value": "eng", "info": "Use the ISO 639-1 or 639-3 language code or auto to automatically detect the language.", "advanced": True},
# "prompt": {"display_name": "Prompt Name", "options": SUMMARIZER_PROMPTS, "value": SUMMARIZER_PROMPTS[0], "info": "Only vectara-summary-ext-24-05-sml is for Growth customers; all other prompts are for Scale customers only.", "advanced": True}
# }
inputs = [
MessageTextInput(name="search_query", display_name="Search Query", info="The query to receive an answer on."),
FloatInput(
name="lexical_interpolation",
display_name="Hybrid Search Factor",
range_spec=RangeSpec(min=0.005, max=0.1, step=0.005),
value=0.005,
info="How much to weigh lexical scores compared to the embedding score. 0 means lexical search is not used at all, and 1 means only lexical search is used.",
),
MessageTextInput(
name="filter",
display_name="Metadata Filters",
value="",
info="The filter string to narrow the search to according to metadata attributes.",
),
DropdownInput(
name="reranker",
display_name="Reranker Type",
options=RERANKER_TYPES,
value=RERANKER_TYPES[0],
info="How to rerank the retrieved search results.",
),
IntInput(
name="reranker_k",
display_name="Number of Results to Rerank",
value=50,
range_spec=RangeSpec(min=1, max=100, step=1),
),
FloatInput(
name="diversity_bias",
display_name="Diversity Bias",
value=0.2,
range_spec=RangeSpec(min=0, max=1, step=0.01),
info="Ranges from 0 to 1, with higher values indicating greater diversity (only applies to MMR reranker).",
),
IntInput(
name="max_results",
display_name="Max Results to Summarize",
value=7,
range_spec=RangeSpec(min=1, max=100, step=1),
),
DropdownInput(
name="response_lang",
display_name="Response Language",
options=["auto", "eng", "deu", "fra", "ita", "nld", "por", "rus", "spa", "zho"],
value="eng",
info="Use the ISO 639-1 or 639-3 language code or auto to automatically detect the language.",
),
DropdownInput(
name="prompt",
display_name="Prompt Name",
options=SUMMARIZER_PROMPTS,
value=SUMMARIZER_PROMPTS[0],
info="Only vectara-summary-ext-24-05-sml is for Growth customers; all other prompts are for Scale customers only.",
),
]
outputs = [
Output(name="answer", display_name="Answer", method="generate_response"),
]
def generate_response(
self,
) -> Message:
text_output = ""
try:
from langchain_community.vectorstores import Vectara
from langchain_community.vectorstores.vectara import RerankConfig, SummaryConfig, VectaraQueryConfig
except ImportError:
raise ImportError("Could not import Vectara. Please install it with `pip install langchain-community`.")
vectara = Vectara(self.vectara_customer_id, self.vectara_corpus_id, self.vectara_api_key)
rerank_config = RerankConfig(self.reranker, self.reranker_k, self.diversity_bias)
summary_config = SummaryConfig(
is_enabled=True, max_results=self.max_results, response_lang=self.response_lang, prompt_name=self.prompt
)
config = VectaraQueryConfig(
lambda_val=self.lexical_interpolation,
filter=self.filter,
summary_config=summary_config,
rerank_config=rerank_config,
)
rag = vectara.as_rag(config)
response = rag.invoke(self.search_query)
text_output = response["answer"]
return Message(text=text_output)

View file

@ -1013,7 +1013,7 @@ class Graph:
next_runnable_vertices.remove(v_id)
else:
self.run_manager.add_to_vertices_being_run(next_v_id)
if cache:
if cache and self.flow_id:
set_cache_coro = partial(get_chat_service().set_cache, key=self.flow_id)
await set_cache_coro(self, lock)
return next_runnable_vertices

View file

@ -1,6 +1,7 @@
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Dict, Optional
from uuid import UUID
from langflow.services.tracing.schema import Log
if TYPE_CHECKING:

View file

@ -1850,17 +1850,6 @@ files = [
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
]
[[package]]
name = "nanoid"
version = "2.0.0"
description = "A tiny, secure, URL-friendly, unique string ID generator for Python"
optional = false
python-versions = "*"
files = [
{file = "nanoid-2.0.0-py3-none-any.whl", hash = "sha256:90aefa650e328cffb0893bbd4c236cfd44c48bc1f2d0b525ecc53c3187b653bb"},
{file = "nanoid-2.0.0.tar.gz", hash = "sha256:5a80cad5e9c6e9ae3a41fa2fb34ae189f7cb420b2a5d8f82bd9d23466e4efa68"},
]
[[package]]
name = "nest-asyncio"
version = "1.6.0"