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:
parent
8fffe73050
commit
469625c0a3
7 changed files with 222 additions and 17 deletions
31
docs/docs/Components/components-rag.md
Normal file
31
docs/docs/Components/components-rag.md
Normal 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)
|
||||
46
docs/docs/Integrations/integrations-langwatch.mdx
Normal file
46
docs/docs/Integrations/integrations-langwatch.mdx
Normal 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
21
poetry.lock
generated
|
|
@ -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"
|
||||
|
|
|
|||
127
src/backend/base/langflow/components/vectorstores/vectara_rag.py
Normal file
127
src/backend/base/langflow/components/vectorstores/vectara_rag.py
Normal 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)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
11
src/backend/base/poetry.lock
generated
11
src/backend/base/poetry.lock
generated
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue