Repository: pathwaycom/llm-app
Branch: main
Commit: 5fa97b75a177
Files: 83
Total size: 638.0 KB
Directory structure:
gitextract_2m1uy52v/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ └── config.yml
│ ├── pull_request_template.md
│ └── workflows/
│ └── python-lint.yml
├── .gitignore
├── .vscode/
│ └── settings.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── cookbooks/
│ └── self-rag-agents/
│ ├── pathway_deploy_langgraph_agents.ipynb
│ └── pathway_langgraph_agentic_rag.ipynb
├── pyproject.toml
├── setup.cfg
└── templates/
├── adaptive_rag/
│ ├── Dockerfile
│ ├── README.md
│ ├── app.py
│ ├── app.yaml
│ └── requirements.txt
├── document_indexing/
│ ├── Dockerfile
│ ├── README.md
│ ├── app.py
│ ├── app.yaml
│ ├── docker-compose.yml
│ └── requirements.txt
├── document_store_mcp_server/
│ ├── Dockerfile
│ ├── README.md
│ ├── __init__.py
│ ├── app.py
│ ├── app.yaml
│ ├── docker-compose.yml
│ └── requirements.txt
├── drive_alert/
│ ├── Dockerfile
│ ├── README.md
│ ├── __init__.py
│ ├── app.py
│ ├── docker-compose.yml
│ └── ui/
│ ├── Dockerfile
│ └── server.py
├── multimodal_rag/
│ ├── Dockerfile
│ ├── README.md
│ ├── app.py
│ ├── app.yaml
│ └── requirements.txt
├── private_rag/
│ ├── Dockerfile
│ ├── README.md
│ ├── app.py
│ ├── app.yaml
│ └── requirements.txt
├── question_answering_rag/
│ ├── Dockerfile
│ ├── README.md
│ ├── app.py
│ ├── app.yaml
│ ├── docker-compose.yml
│ ├── requirements.txt
│ └── ui/
│ ├── .streamlit/
│ │ └── config.toml
│ ├── Dockerfile
│ ├── requirements.txt
│ └── ui.py
├── slides_ai_search/
│ ├── .dockerignore
│ ├── .gitignore
│ ├── Dockerfile
│ ├── README.md
│ ├── app.py
│ ├── app.yaml
│ ├── docker-compose.yml
│ ├── nginx/
│ │ ├── Dockerfile
│ │ └── nginx.conf
│ ├── pathway_slides_ai_search/
│ │ └── __init__.py
│ ├── requirements.txt
│ └── ui/
│ ├── .streamlit/
│ │ └── config.toml
│ ├── Dockerfile
│ ├── requirements.txt
│ └── ui.py
└── unstructured_to_sql_on_the_fly/
├── Dockerfile
├── README.md
├── __init__.py
├── app.py
├── docker-compose.yml
├── postgres/
│ └── init-db.sql
├── requirements.txt
└── ui/
├── Dockerfile
└── server.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug Report
description: File a bug report
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: textarea
id: what-happened
attributes:
label: Steps to reproduce
description: What happened and how to reproduce it?
placeholder: Tell us what you see!
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
placeholder: Tell us what you see! It would be nice if you could leave us the logs.
render: text
validations:
required: true
- type: textarea
id: what-did-you-expect
attributes:
label: What did you expect to happen?
description: Also tell us, what did you expect to happen?
placeholder: Describe your expectations.
validations:
required: true
- type: input
id: pathway_version
attributes:
label: Version
description: On which version of Pathway are you working?
validations:
required: true
- type: input
id: docker_version
attributes:
label: Docker Versions (if used)
description: On which Docker version are you working?
validations:
required: false
- type: dropdown
id: os_version
attributes:
label: OS
description: On which OS did you run Pathway?
options:
- Linux
- MacOS
validations:
required: true
- type: dropdown
id: cpu_architecture
attributes:
label: On which CPU architecture did you run Pathway?
multiple: false
options:
- x86-64
- ARM64 (AArch64, Apple silicon)
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: New feature? Tell us about it on GitHub Discussions
url: https://github.com/pathwaycom/pathway/discussions
about: We are using Discussions as a place to connect with other members of the Pathway community.
- name: Discord
url: https://discord.com/invite/pathway
about: Ask questions you are wondering about.
================================================
FILE: .github/pull_request_template.md
================================================
### Introduction
To contribute code to the Pathway project, start by discussing your proposed changes on Discord or by filing an issue.
Once approved, follow the fork + pull request model against the main branch, ensuring you've signed the contributor license agreement.
### Context
### How has this been tested?
### Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature or improvement (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
### Related issue(s):
1.
2.
3.
### Checklist:
- [ ] My code follows the code style of this project,
- [ ] My change requires a change to the documentation,
- [ ] I described the modification in the CHANGELOG.md file.
================================================
FILE: .github/workflows/python-lint.yml
================================================
name: lint PR
on:
pull_request:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main'}}
jobs:
linter:
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- name: Git checkout
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install poetry
uses: abatilo/actions-poetry@v3
- name: Install linters
run: poetry install --no-root --only linters
- name: Run black
run: poetry run black --check .
- name: Run Flake8
run: poetry run flake8 .
- name: Run mypy
run: poetry run mypy .
- name: Run isort
run: poetry run isort --check .
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
**/.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
pw-env/
# llm debug
examples/ui/data/*
================================================
FILE: .vscode/settings.json
================================================
{
"python.defaultInterpreterPath": "${env:HOME}/pw-env/bin/python",
"python.formatting.provider": "none",
"editor.formatOnSave": true,
"python.linting.enabled": true,
"python.linting.flake8Enabled": true,
"python.linting.mypyEnabled": true,
"[python]": {
"files.trimTrailingWhitespace": true,
"editor.rulers": [88],
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
},
"editor.defaultFormatter": "ms-python.black-formatter"
},
"git.autofetchPeriod": 315360000
}
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Pathway Code of Conduct
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and our
community a harassment-free experience for everyone, regardless of age, body
size, disability, health condition, ethnicity, gender identity and expression, level of
experience, nationality, country of origin, personal appearance, race, religion, or sexual identity
and orientation, and any other criteria falling under discriminatory practices under the Law of France.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language.
* Being respectful of differing viewpoints and experiences.
* Gracefully accepting constructive criticism.
* Focusing on what is best for the community.
* Showing empathy towards other community members.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances.
* Trolling, insulting/derogatory comments, and personal or political attacks.
* Public or private harassment.
* Publishing others' private information, such as a physical or electronic
address, without explicit permission.
* Conduct which could reasonably be considered inappropriate for the forum in
which it occurs.
All Pathway forums and spaces are meant for professional interactions, and any behavior which could reasonably be considered inappropriate in a professional setting is unacceptable.
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies to all content on pathway.com, Pathway’s GitHub organization, or any other official Pathway web presence allowing for community interactions, as well as at all official Pathway events, whether offline or online.
The Code of Conduct also applies within project spaces and in public spaces whenever an individual is representing Pathway or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed or de facto representative at an online or offline event.
## Conflict Resolution
Conflicts in an open source project can take many forms, from someone having a bad day and using harsh and hurtful language in the issue queue, to more serious instances such as sexist/racist statements or threats of violence, and everything in between.
If the behavior is threatening or harassing, or for other reasons requires immediate escalation, please see below.
However, for the vast majority of issues, we aim to empower individuals to first resolve conflicts themselves, asking for help when needed, and only after that fails to escalate further. This approach gives people more control over the outcome of their dispute.
If you are experiencing or witnessing conflict, we ask you to use the following escalation strategy to address the conflict:
1. If you so wish and if you do not feel threatened or at risk of any form of personal abuse, address the perceived conflict directly with those involved, preferably in a real-time medium.
2. If this fails, get a third party (e.g. a mutual friend, and/or someone with
background on the issue, but not involved in the conflict) to intercede.
3. If you are still unable to resolve the conflict, and you believe it rises to
harassment or another code of conduct violation, report it.
Please note that if you are experiencing or witnessing a discriminatory practice that would be susceptible to be condemned by law, we ask you to directly escalate to 3.
## Reporting Violations
Violations of the Code of Conduct can be reported to Pathway via email to code_of_conduct@pathway.com. Project maintainers will determine whether the Code of Conduct was violated, and will issue an appropriate sanction, possibly including a written warning or expulsion from the project, project sponsored spaces, or project forums. We ask that you make a good-faith effort to resolve your conflict via the conflict resolution policy before submitting a report.
Violations of the Code of Conduct can occur in any setting, even those unrelated to the project. We will only consider complaints about conduct that has occurred within one year of the report.
## Enforcement
If the Project maintainers receive a report alleging a violation of the Code of Conduct, the Project maintainers will notify the accused of the report, and provide them an opportunity to discuss the report before a sanction is issued. The Project maintainers will do their utmost to keep the reporter anonymous. If the act is ongoing (such as someone engaging in harassment), or involves a threat to anyone's safety (e.g. threats of violence), the Project maintainers may issue sanctions without notice.
## Attribution
This Code of Conduct is adapted from the Tensorflow Code of Conduct, and based on Contributor Covenant, version 1.4, available at https://contributor-covenant.org/version/1/4, and includes some aspects of the Geek Feminism Code of Conduct and the Drupal Code of Conduct.
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Pathway
Welcome! This guide is intended to help developers that are new to the community
to make contributions to the Pathway project. Please be sure to also read our [code of conduct](CODE_OF_CONDUCT.md). We work hard to make this a welcoming community for all, and we're excited to have you on board!
## The basics:
* Use the [Issue Tracker](https://github.com/pathwaycom/llm-app/issues) to
report bugs, crashes, performance issues, etc... Please include as much detail
as possible.
* [Discussions](https://github.com/pathwaycom/pathway/discussions) is a great
venue to ask questions, start a design discussion, or post an RFC.
* [Discord](https://discord.com/invite/pathway) is our main gathering place - jump in and ask us anything!
## Contributing Code
We are eager to build Pathway together with the community and are excited to have you here!
Important: Before you contribute any changes to our repositories (make a Pull Request) please get in touch with us and explain what you want to work on. You can do so by filing an issue, or asking us on Discord. That way you can get coding advice and speedier reviews. If you start to work on an issue before hearing back from a Pathway core team engineer there is a chance that we will not be able to accept your changes - something we all want to avoid!
We use a standard GitHub fork + pull request model for merging and reviewing
changes. New pull requests should be made against the main upstream branch.
After a pull request is opened it will be reviewed, and merged after
passing continuous integration tests and being accepted by a project or
sub-system maintainer.
We ask that developers sign our [contributor license
agreement](https://cla-assistant.io/pathwaycom/llm-app). The
process of signing the CLA is automated, and you'll be prompted with instructions
the first time you submit a pull request to the project.
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2022 Pathway
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Pathway AI Pipelines



[](https://discord.gg/pathway)
[](https://x.com/intent/follow?screen_name=pathway_com)
Pathway's **AI Pipelines** allow you to quickly put in production AI applications that offer **high-accuracy RAG and AI enterprise search at scale** using the most **up-to-date knowledge** available in your data sources. It provides you ready-to-deploy **LLM (Large Language Model) App Templates**. You can test them on your own machine and deploy on-cloud (GCP, AWS, Azure, Render,...) or on-premises.
The apps connect and sync (all new data additions, deletions, updates) with data sources on your **file system, Google Drive, Sharepoint, S3, Kafka, PostgreSQL, real-time data APIs**. They come with no infrastructure dependencies that would need a separate setup. They include **built-in data indexing** enabling vector search, hybrid search, and full-text search - all done in-memory, with cache.
## Application Templates
The application templates provided in this repo scale up to **millions of pages of documents**. Some of them are optimized for simplicity, some are optimized for amazing accuracy. Pick the one that suits you best. You can use it out of the box, or change some steps of the pipeline - for example, if you would like to add a new data source, or change a Vector Index into a Hybrid Index, it's just a one-line change.
| Application (template) | Description |
| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`Question-Answering RAG App`](templates/question_answering_rag/) | Basic end-to-end RAG app. A question-answering pipeline that uses the GPT model of choice to provide answers to queries to your documents (PDF, DOCX,...) on a live connected data source (files, Google Drive, Sharepoint,...). You can also try out a [demo REST endpoint](https://pathway.com/solutions/rag-pipelines#try-it-out). |
| [`Live Document Indexing (Vector Store / Retriever)`](templates/document_indexing/) | A real-time document indexing pipeline for RAG that acts as a vector store service. It performs live indexing on your documents (PDF, DOCX,...) from a connected data source (files, Google Drive, Sharepoint,...). It can be used with any frontend, or integrated as a retriever backend for a [Langchain](https://pathway.com/blog/langchain-integration) or [Llamaindex](https://pathway.com/blog/llamaindex-pathway) application. You can also try out a [demo REST endpoint](https://pathway.com/solutions/ai-contract-management#try-it-out). |
| [`Multimodal RAG pipeline with GPT4o`](templates/multimodal_rag/) | Multimodal RAG using GPT-4o in the parsing stage to index PDFs and other documents from a connected data source files, Google Drive, Sharepoint,...). It is perfect for extracting information from unstructured financial documents in your folders (including charts and tables), updating results as documents change or new ones arrive.|
| [`Unstructured-to-SQL pipeline + SQL question-answering`](templates/unstructured_to_sql_on_the_fly/) | A RAG example which connects to unstructured financial data sources (financial report PDFs), structures the data into SQL, and loads it into a PostgreSQL table. It also answers natural language user queries to these financial documents by translating them into SQL using an LLM and executing the query on the PostgreSQL table. |
| [`Adaptive RAG App`](templates/adaptive_rag/) | A RAG application using Adaptive RAG, a technique developed by Pathway to reduce token cost in RAG up to 4x while maintaining accuracy. |
| [`Private RAG App with Mistral and Ollama`](templates/private_rag/) | A fully private (local) version of the `question_answering_rag` RAG pipeline using Pathway, Mistral, and Ollama. |
| [`Slides AI Search App`](templates/slides_ai_search/) | An indexing pipeline for retrieving slides. It performs multi-modal of PowerPoint and PDF and maintains live index of your slides."|
## How do these AI Pipelines work?
The apps can be run as **Docker containers**, and expose an **HTTP API** to connect the frontend. To allow quick testing and demos, some app templates also include an optional Streamlit UI which connects to this API.
The apps rely on the [Pathway Live Data framework](https://github.com/pathwaycom/pathway) for data source synchronization and for serving API requests (Pathway is a standalone Python library with a Rust engine built into it). They bring you a **simple and unified application logic** for back-end, embedding, retrieval, LLM tech stack. There is no need to integrate and maintain separate modules for your Gen AI app: ~Vector Database (e.g. Pinecone/Weaviate/Qdrant) + Cache (e.g. Redis) + API Framework (e.g. Fast API)~. Pathway's default choice of **built-in vector index** is based on the lightning-fast [usearch](https://github.com/unum-cloud/usearch) library, and **hybrid full-text indexes** make use of [Tantivy](https://github.com/quickwit-oss/tantivy) library. Everything works out of the box.
## Getting started
Each of the [App templates](templates/) in this repo contains a README.md with instructions on how to run it.
You can also find [more ready-to-run code templates](https://pathway.com/developers/templates/) on the Pathway website.
## Some visual highlights
Effortlessly extract and organize table and chart data from PDFs, docs, and more with multimodal RAG - in real-time:

(Check out [`Multimodal RAG pipeline with GPT4o`](templates/multimodal_rag/) to see the whole pipeline in the works. You may also check out the [`Unstructured-to-SQL pipeline`](templates/unstructured_to_sql_on_the_fly/) for a minimal example that works with non-multimodal models as well.)
Automated real-time knowledge mining and alerting:

(Check out the [`Alerting when answers change on Google Drive`](https://github.com/pathwaycom/llm-app/tree/main/templates/drive_alert) app example.)
### Do-it-Yourself Videos
▶️ [An introduction to building LLM apps with Pathway](https://www.youtube.com/watch?v=kcrJSk00duw) - by [Jan Chorowski](https://scholar.google.com/citations?user=Yc94070AAAAJ)
▶️ [Let's build a real-world LLM app in 11 minutes](https://www.youtube.com/watch?v=k1XGo7ts4tI) - by [Pau Labarta Bajo](https://substack.com/@paulabartabajo)
## Troubleshooting
To provide feedback or report a bug, please [raise an issue on our issue tracker](https://github.com/pathwaycom/pathway/issues).
## Contributing
Anyone who wishes to contribute to this project, whether documentation, features, bug fixes, code cleanup, testing, or code reviews, is very much encouraged to do so. If this is your first contribution to a GitHub project, here is a [Get Started Guide](https://docs.github.com/en/get-started/quickstart/contributing-to-projects).
If you'd like to make a contribution that needs some more work, just raise your hand on the [Pathway Discord server](https://discord.com/invite/pathway) (#get-help) and let us know what you are planning!
## Supported and maintained by
================================================
FILE: cookbooks/self-rag-agents/pathway_deploy_langgraph_agents.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"id": "d58d3552-9168-4f0f-8a79-4dbaa4a01bbf",
"metadata": {
"tags": []
},
"source": [
"> The following cookbook is an adaption of the original [LangGraph cookbook](https://github.com/langchain-ai/langgraph/blob/e3ca7bb3e9d34b09633852f4d08d55f6dcd4364b/examples/rag/langgraph_self_rag.ipynb)\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "b3e94de1-ca3d-4956-b212-4a558b68062a",
"metadata": {},
"source": [
"# Power and Deploy LangGraph Agents with Pathway: A Complete Guide\n",
"This notebook demonstrates how to use Pathway to power and deploy LangGraph Agents.\n",
"\n",
"In this notebook, you will learn:\n",
"- How to build a Pathway RAG app that indexes documents from your data sources\n",
"- How to create a Hybrid Index that is powered by semantic search and BM25 index\n",
"- How to use the Pathway LangChain Retriever in a LangGraph Agent\n",
"- How to use Pathway to serve LangGraph Agents"
]
},
{
"cell_type": "markdown",
"id": "d27aa0d3-9b11-4678-8a83-b3865b26f30c",
"metadata": {},
"source": [
"# Setup\n",
"\n",
"Install the required packages and set your OpenAI API key. \n",
"OpenAI is used for embeddings during the indexing stage and to power the LangGraph agent."
]
},
{
"cell_type": "markdown",
"id": "9e055de9-723f-44e3-ad39-70cc5f8932bf",
"metadata": {},
"source": [
"Magic library is used for detecting file types in the `UnstructuredParser` module.\n",
"\n",
"If you are running this notebook on **MacOS**, you can install it with:\n",
"> `brew install libmagic`\n",
"\n",
"If you are running the notebook on **colab** or any **linux** environment, you can install it with:\n",
"> `apt-get install libmagic1`"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "209efe9f-b9d3-4760-8863-0a6052617ebd",
"metadata": {},
"outputs": [],
"source": [
"!pip install -U \"pathway[all]\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b44f689e-0a62-4bbd-94e8-5bf31ece9cd9",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"!pip install -U langgraph langchain-community langchainhub langchain-openai"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3ff9da9f-66b8-4675-8c45-afa10e891462",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import os\n",
"\n",
"import json\n",
"from typing import Iterable, Literal, List\n",
"from pydantic import BaseModel, Field\n",
"\n",
"# needed for the OpenAI embedder and the LLM we will use below, you can change the embedding provider, see the documentation:\n",
"# https://pathway.com/developers/api-docs/pathway-xpacks-llm/embedders\n",
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
]
},
{
"cell_type": "markdown",
"id": "571d4836-4d08-4ee5-97fa-37132ccc8ef9",
"metadata": {},
"source": [
"Lets define a `DATA_PATH` folder that will store the text files/documents for indexing."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "54979252-13d3-4b94-b2ad-ec7b012aa320",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# folder that we will gather our docs in\n",
"DATA_PATH = \"./data\"\n",
"\n",
"os.makedirs(DATA_PATH, exist_ok=True)"
]
},
{
"cell_type": "markdown",
"id": "55c2fb67-c562-47f7-a08e-6a673b4b612b",
"metadata": {},
"source": [
"## Load & save a webpage\n",
"\n",
"Define utility functions to read content from a webpage and save it locally into `DATA_PATH`.\n",
" 1. `load_page_content`: Reads the raw text from a webpage using using a `WebBaseLoader` from `langchain_community.document_loaders`.\n",
" 2. `ingest_webpage`: Saves the loaded content as a text file into the `DATA_PATH`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "64538684-5b2b-460a-b3a5-1fe737fd8269",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import re\n",
"from urllib.parse import urlparse\n",
"from langchain_community.document_loaders import WebBaseLoader\n",
"\n",
"\n",
"def load_page_content(url: str) -> str:\n",
" \"\"\"Load web page content with Langchain utilities.\"\"\"\n",
" return WebBaseLoader(url).load()[0].page_content\n",
"\n",
"\n",
"def ingest_webpage(url: str) -> None:\n",
" \"\"\"Save a webpage to local `DATA_PATH` folder.\"\"\"\n",
" text_content = load_page_content(url)\n",
"\n",
" parsed_url = urlparse(url)\n",
" file_name = parsed_url.hostname + parsed_url.path.replace(\"/\", \"_\") + \".txt\"\n",
"\n",
" with open(os.path.join(DATA_PATH, file_name), \"w\", encoding=\"utf-8\") as f:\n",
" f.write(text_content)"
]
},
{
"cell_type": "markdown",
"id": "5bf15463-7da1-4d04-9f6d-423975e377cb",
"metadata": {
"tags": []
},
"source": [
"Download the Self-RAG paper"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fff7b382-2e25-415b-a3ee-06df976b3dbd",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"ingest_webpage(\"https://arxiv.org/html/2310.11511\")"
]
},
{
"cell_type": "markdown",
"id": "62376b16-e5bc-463d-bf84-bec69a7c2035",
"metadata": {
"tags": []
},
"source": [
"# Build the Pathway indexing pipeline\n",
"\n",
"Set up Pathway to read and index the documents saved under the `DATA_PATH`.\n",
"\n",
"\n",
"1. [Connectors](https://pathway.com/developers/user-guide/connect/pathway-connectors): Use Pathway’s file reader to ingest all text files under the `DATA_PATH`.\n",
"2. [Parsers](https://pathway.com/developers/api-docs/pathway-xpacks-llm/parsers): Utilize the UnstructuredParser to parse the documents. This parser supports multiple file types, including PDF, DOCX, and PPTX.\n",
"3. [Text Splitters](https://pathway.com/developers/api-docs/pathway-xpacks-llm/splitters): Split the document content into chunks.\n",
"4. [Embedders](https://pathway.com/developers/api-docs/pathway-xpacks-llm/embedders): Use OpenAI API for embeddings."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "27c3d42a-30e1-47f8-bf3c-bd44d4a490f0",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# host and port of the RAG app\n",
"pathway_host: str = \"0.0.0.0\"\n",
"pathway_port: int = 8000"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "094ec4e1-e972-441b-9c47-ff0ce3c8d2ff",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import pathway as pw\n",
"from pathway.stdlib.indexing import BruteForceKnnFactory, HybridIndexFactory\n",
"from pathway.stdlib.indexing.bm25 import TantivyBM25Factory\n",
"from pathway.udfs import DiskCache\n",
"from pathway.xpacks.llm import embedders, llms, parsers, splitters\n",
"from pathway.xpacks.llm.document_store import DocumentStore\n",
"from pathway.xpacks.llm.question_answering import BaseRAGQuestionAnswerer, RAGClient\n",
"\n",
"\n",
"# read the text files under the data folder, we can also read from Google Drive, Sharepoint, etc.\n",
"# See connectors documentation: https://pathway.com/developers/user-guide/connect/pathway-connectors to learn more\n",
"folder = pw.io.fs.read(\n",
" path=f\"{DATA_PATH}/*.txt\",\n",
" format=\"binary\",\n",
" with_metadata=True,\n",
")\n",
"\n",
"# list of data sources to be indexed\n",
"sources = [folder]\n",
"\n",
"# define the document processing steps\n",
"parser = parsers.UnstructuredParser()\n",
"\n",
"text_splitter = splitters.TokenCountSplitter(min_tokens=150, max_tokens=450)\n",
"\n",
"embedder = embedders.OpenAIEmbedder(cache_strategy=DiskCache())"
]
},
{
"cell_type": "markdown",
"id": "d3426ef8-90ee-4023-8094-5ce007d64b0e",
"metadata": {},
"source": [
"Hybrid index combines semantic search and keyword based BM25 search.\n",
"\n",
"[`HybridIndexFactory`](https://pathway.com/developers/api-docs/indexing#pathway.stdlib.indexing.HybridIndexFactory) combines different indexes to build an hybrid index:\n",
" 1. [BM25](https://pathway.com/developers/api-docs/indexing#pathway.stdlib.indexing.TantivyBM25) (via TantivyBM25Factory) → Keyword based BM25 search.\n",
" 2. [BruteForceKnn](https://pathway.com/developers/api-docs/indexing#pathway.stdlib.indexing.BruteForceKnn) → Vector-based semantic search"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a3f7c59b-925b-4ef3-88a8-89749479925e",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"index = HybridIndexFactory(\n",
" [\n",
" TantivyBM25Factory(),\n",
" BruteForceKnnFactory(embedder=embedder),\n",
" ]\n",
")"
]
},
{
"cell_type": "markdown",
"id": "8b55a446-cf97-4d47-b1ca-374bcf0e8a7b",
"metadata": {},
"source": [
"[DocumentStore](https://pathway.com/developers/api-docs/pathway-xpacks-llm/document_store#pathway.xpacks.llm.document_store.DocumentStore) manages document ingestion, parsing, splitting, and indexing.\n",
"\n",
"[BaseRAGQuestionAnswerer](https://pathway.com/developers/api-docs/pathway-xpacks-llm/question_answering#pathway.xpacks.llm.question_answering.BaseRAGQuestionAnswerer) creates a Pathway “RAG” application that:\n",
" * Indexes the documents (via `document_store`)\n",
" * Exposes a standard question-answering interface\n",
" * Enables us to create endpoint for the agent with Pathway."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7db0ab59-a641-43cc-901b-cc2713f03a99",
"metadata": {},
"outputs": [],
"source": [
"llm = llms.OpenAIChat(model=\"gpt-4o-mini\", cache_strategy=DiskCache())\n",
"\n",
"document_store = DocumentStore(\n",
" docs=sources, parser=parser, splitter=text_splitter, retriever_factory=index\n",
")\n",
"\n",
"# create the RAG app that will power the index, and serve the agent endpoint\n",
"rag_app = BaseRAGQuestionAnswerer(\n",
" llm=llm,\n",
" indexer=document_store,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "a027e277-fba8-4198-863b-2168ae6f8505",
"metadata": {},
"source": [
"# Create the LangGraph agent"
]
},
{
"cell_type": "markdown",
"id": "cf15141f-9612-4d0d-a21b-11bd8530686a",
"metadata": {},
"source": [
"### Create the Langchain Retriever\n",
"\n",
"You can now query Pathway and access up-to-date documents for your RAG applications from LangChain using [PathwayVectorClient](https://api.python.langchain.com/en/latest/vectorstores/langchain_community.vectorstores.pathway.PathwayVectorClient.html)\n",
"\n",
"The Langchain Retriever is a wrapper around the Pathway client, you will use it in `retrieve` part stage of the Agent"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fefffab6-d5a3-4925-a52d-5a5c574421ea",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain_community.vectorstores import PathwayVectorClient"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "51d365aa-5526-4ec8-932d-e65e83ee355d",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"vectorstore_client = PathwayVectorClient(pathway_host, pathway_port)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "59624377-8481-4407-8ee3-0f014bdff30e",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# this will not be able to fetch data until the RAG app is running\n",
"retriever = vectorstore_client.as_retriever()"
]
},
{
"attachments": {
"76895b7a-fcc5-4758-9fbb-510b17fdeda4.png": {
"image/png": "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+QwggAACCCCAAAIIIIAAAggggAACCCCAwAIEiBQXgMWpCCCAAAIIIIAAAggggAACCCCAAAIIIECkyGcAAQQQQAABBBBAAAEEEEAAAQQQQAABBBYgQKS4ACxORQABBBBAAAEEEEAAAQQQQAABBBBAAAEiRT4DCCCAAAIIIIAAAggggAACCCCAAAIIILAAASLFBWBxKgIIIIAAAggggAACCCCAAAIIIIAAAggQKfIZQAABBBBAAAEEEEAAAQQQQAABBBBAAIEFCBApLgCLUxFAAAEEEEAAAQQQQAABBBBAAAEEEECASJHPAAIIIIAAAggggAACCCCAAAIIIIAAAggsQIBIcQFYnIoAAggggAACCCCAAAIIIIAAAggggAACRIp8BhBAAAEEEEAAAQQQQAABBBBAAAEEEEBgAQJEigvA4lQEEEAAAQQQQAABBBBAAAEEEEAAAQQQIFLkM4AAAggggAACCCCAAAIIIIAAAggggAACCxAgUlwAFqcigAACCCCAAAIIIIAAAggggAACCCCAAJEinwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQWIAAkeICsDgVAQQQQAABBBBAAAEEEEAAAQQQQAABBIgU+QwggAACCCCAAAIIIIAAAggggAACCCCAwAIEiBQXgMWpCCCAAAIIIIAAAggggAACCCCAAAIIIECkyGcAAQQQQAABBBBAAAEEEEAAAQQQQAABBBYg8P8DAA3xveEZM1sAAAAASUVORK5CYII="
}
},
"cell_type": "markdown",
"id": "5894115c-0323-4098-83be-da49d949a53c",
"metadata": {
"tags": []
},
"source": [
"### Self-RAG\n",
"\n",
"Self-RAG is a strategy for RAG that incorporates self-reflection / self-grading on retrieved documents and generations.\n",
"\n",
"In the [paper](https://arxiv.org/abs/2310.11511), a few decisions are made:\n",
"\n",
"1. Should I retrieve from retriever, `R` -\n",
"\n",
"* Input: `x (question)` OR `x (question)`, `y (generation)`\n",
"* Decides when to retrieve `D` chunks with `R`\n",
"* Output: `yes, no, continue`\n",
"\n",
"2. Are the retrieved passages `D` relevant to the question `x` -\n",
"\n",
"* * Input: (`x (question)`, `d (chunk)`) for `d` in `D`\n",
"* `d` provides useful information to solve `x`\n",
"* Output: `relevant, irrelevant`\n",
"\n",
"3. Are the LLM generation from each chunk in `D` is relevant to the chunk (hallucinations, etc) -\n",
"\n",
"* Input: `x (question)`, `d (chunk)`, `y (generation)` for `d` in `D`\n",
"* All of the verification-worthy statements in `y (generation)` are supported by `d`\n",
"* Output: `{fully supported, partially supported, no support`\n",
"\n",
"4. The LLM generation from each chunk in `D` is a useful response to `x (question)` -\n",
"\n",
"* Input: `x (question)`, `y (generation)` for `d` in `D`\n",
"* `y (generation)` is a useful response to `x (question)`.\n",
"* Output: `{5, 4, 3, 2, 1}`\n",
"\n",
"We will implement some of these ideas from scratch using [LangGraph](https://langchain-ai.github.io/langgraph/).\n",
"\n",
"> Figure and the explanation taken from the [LangGraph cookbook](https://github.com/langchain-ai/langgraph/blob/e3ca7bb3e9d34b09633852f4d08d55f6dcd4364b/examples/rag/langgraph_self_rag.ipynb)"
]
},
{
"cell_type": "markdown",
"id": "1def042d-abcc-47af-8926-a9d1e2e8154f",
"metadata": {},
"source": [
"### Define the LangGraph Workflow\n",
"\n",
"\n",
"The LangGraph agent operates as a multi-step workflow.\n",
"\n",
"- It retrieves documents, grades their relevance, generates an answer, and ensures factual accuracy (e.g., no hallucinations).\n",
"- You can also implement self-reflection and query optimization using LangGraph nodes."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8c4c9be8-396c-4ebc-a9e4-d4e11504c05c",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain_core.prompts import ChatPromptTemplate\n",
"from langchain_core.pydantic_v1 import BaseModel, Field\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"\n",
"# Data model\n",
"class GradeDocuments(BaseModel):\n",
" \"\"\"Binary score for relevance check on retrieved documents.\"\"\"\n",
"\n",
" binary_score: str = Field(\n",
" description=\"Documents are relevant to the question, 'yes' or 'no'\"\n",
" )\n",
"\n",
"\n",
"# LLM with function call\n",
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0)\n",
"structured_llm_grader = llm.with_structured_output(GradeDocuments)\n",
"\n",
"# Prompt\n",
"system = \"\"\"You are a grader assessing relevance of a retrieved document to a user question. \\n \n",
" It does not need to be a stringent test. The goal is to filter out erroneous retrievals. \\n\n",
" If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \\n\n",
" Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.\"\"\"\n",
"grade_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
" (\"human\", \"Retrieved document: \\n\\n {document} \\n\\n User question: {question}\"),\n",
" ]\n",
")\n",
"\n",
"retrieval_grader = grade_prompt | structured_llm_grader"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "499173a5-8df0-4fe6-bb46-552ce496b8ba",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain_core.output_parsers import StrOutputParser\n",
"\n",
"# Prompt\n",
"prompt = hub.pull(\"rlm/rag-prompt\")\n",
"\n",
"# LLM\n",
"llm = ChatOpenAI(model_name=\"gpt-3.5-turbo\", temperature=0)\n",
"\n",
"\n",
"# Post-processing\n",
"def format_docs(docs):\n",
" return \"\\n\\n\".join(doc.page_content for doc in docs)\n",
"\n",
"\n",
"# Chain\n",
"rag_chain = prompt | llm | StrOutputParser()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d9055d3b-8e9b-494f-bf4f-d02c153639c7",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"class GradeHallucinations(BaseModel):\n",
" \"\"\"Binary score for hallucination present in generation answer.\"\"\"\n",
"\n",
" binary_score: str = Field(\n",
" description=\"Answer is grounded in the facts, 'yes' or 'no'\"\n",
" )\n",
"\n",
"\n",
"# LLM with function call\n",
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0)\n",
"structured_llm_grader = llm.with_structured_output(GradeHallucinations)\n",
"\n",
"# Prompt\n",
"system = \"\"\"You are a grader assessing whether an LLM generation is grounded in / supported by a set of retrieved facts. \\n \n",
" Give a binary score 'yes' or 'no'. 'Yes' means that the answer is grounded in / supported by the set of facts.\"\"\"\n",
"hallucination_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
" (\"human\", \"Set of facts: \\n\\n {documents} \\n\\n LLM generation: {generation}\"),\n",
" ]\n",
")\n",
"\n",
"hallucination_grader = hallucination_prompt | structured_llm_grader"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f92d351d-5ee1-48cc-ad8f-9b57ceed18ed",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"class GradeAnswer(BaseModel):\n",
" \"\"\"Binary score to assess answer addresses question.\"\"\"\n",
"\n",
" binary_score: str = Field(\n",
" description=\"Answer addresses the question, 'yes' or 'no'\"\n",
" )\n",
"\n",
"\n",
"# LLM with function call\n",
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0)\n",
"structured_llm_grader = llm.with_structured_output(GradeAnswer)\n",
"\n",
"# Prompt\n",
"system = \"\"\"You are a grader assessing whether an answer addresses / resolves a question \\n \n",
" Give a binary score 'yes' or 'no'. Yes' means that the answer resolves the question.\"\"\"\n",
"answer_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
" (\"human\", \"User question: \\n\\n {question} \\n\\n LLM generation: {generation}\"),\n",
" ]\n",
")\n",
"\n",
"answer_grader = answer_prompt | structured_llm_grader"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "286a9a2a-2a62-4004-84a2-fc82e6996cf1",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0)\n",
"\n",
"# Prompt\n",
"system = \"\"\"You a question re-writer that converts an input question to a better version that is optimized \\n \n",
" for vectorstore retrieval. Look at the input and try to reason about the underlying semantic intent / meaning.\"\"\"\n",
"re_write_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
" (\n",
" \"human\",\n",
" \"Here is the initial question: \\n\\n {question} \\n Formulate an improved question.\",\n",
" ),\n",
" ]\n",
")\n",
"\n",
"question_rewriter = re_write_prompt | llm | StrOutputParser()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb9bd597-a683-433a-879d-7991cfed5cf7",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from typing import List\n",
"\n",
"from typing_extensions import TypedDict\n",
"\n",
"\n",
"class GraphState(TypedDict):\n",
" \"\"\"\n",
" Represents the state of our graph.\n",
"\n",
" Attributes:\n",
" question: question\n",
" generation: LLM generation\n",
" documents: list of documents\n",
" \"\"\"\n",
"\n",
" question: str\n",
" generation: str\n",
" documents: List[str]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "398e5cc2-9c41-465d-a4f4-93c82ed452f2",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"def retrieve(state):\n",
" \"\"\"\n",
" Retrieve documents\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" state (dict): New key added to state, documents, that contains retrieved documents\n",
" \"\"\"\n",
" print(\"---RETRIEVE---\")\n",
" question = state[\"question\"]\n",
"\n",
" # Retrieval\n",
" documents = retriever.get_relevant_documents(question)\n",
" return {\"documents\": documents, \"question\": question}\n",
"\n",
"\n",
"def generate(state):\n",
" \"\"\"\n",
" Generate answer\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" state (dict): New key added to state, generation, that contains LLM generation\n",
" \"\"\"\n",
" print(\"---GENERATE---\")\n",
" question = state[\"question\"]\n",
" documents = state[\"documents\"]\n",
"\n",
" # RAG generation\n",
" generation = rag_chain.invoke({\"context\": documents, \"question\": question})\n",
" return {\"documents\": documents, \"question\": question, \"generation\": generation}\n",
"\n",
"\n",
"def grade_documents(state):\n",
" \"\"\"\n",
" Determines whether the retrieved documents are relevant to the question.\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" state (dict): Updates documents key with only filtered relevant documents\n",
" \"\"\"\n",
"\n",
" print(\"---CHECK DOCUMENT RELEVANCE TO QUESTION---\")\n",
" question = state[\"question\"]\n",
" documents = state[\"documents\"]\n",
"\n",
" # Score each doc\n",
" filtered_docs = []\n",
" for d in documents:\n",
" score = retrieval_grader.invoke(\n",
" {\"question\": question, \"document\": d.page_content}\n",
" )\n",
" grade = score.binary_score\n",
" if grade == \"yes\":\n",
" print(\"---GRADE: DOCUMENT RELEVANT---\")\n",
" filtered_docs.append(d)\n",
" else:\n",
" print(\"---GRADE: DOCUMENT NOT RELEVANT---\")\n",
" continue\n",
" return {\"documents\": filtered_docs, \"question\": question}\n",
"\n",
"\n",
"def transform_query(state):\n",
" \"\"\"\n",
" Transform the query to produce a better question.\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" state (dict): Updates question key with a re-phrased question\n",
" \"\"\"\n",
"\n",
" print(\"---TRANSFORM QUERY---\")\n",
" question = state[\"question\"]\n",
" documents = state[\"documents\"]\n",
"\n",
" # Re-write question\n",
" better_question = question_rewriter.invoke({\"question\": question})\n",
" return {\"documents\": documents, \"question\": better_question}\n",
"\n",
"\n",
"### Edges\n",
"\n",
"\n",
"def decide_to_generate(state):\n",
" \"\"\"\n",
" Determines whether to generate an answer, or re-generate a question.\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" str: Binary decision for next node to call\n",
" \"\"\"\n",
"\n",
" print(\"---ASSESS GRADED DOCUMENTS---\")\n",
" state[\"question\"]\n",
" filtered_documents = state[\"documents\"]\n",
"\n",
" if not filtered_documents:\n",
" # All documents have been filtered check_relevance\n",
" # We will re-generate a new query\n",
" print(\n",
" \"---DECISION: ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, TRANSFORM QUERY---\"\n",
" )\n",
" return \"transform_query\"\n",
" else:\n",
" # We have relevant documents, so generate answer\n",
" print(\"---DECISION: GENERATE---\")\n",
" return \"generate\"\n",
"\n",
"\n",
"def grade_generation_v_documents_and_question(state):\n",
" \"\"\"\n",
" Determines whether the generation is grounded in the document and answers question.\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" str: Decision for next node to call\n",
" \"\"\"\n",
"\n",
" print(\"---CHECK HALLUCINATIONS---\")\n",
" question = state[\"question\"]\n",
" documents = state[\"documents\"]\n",
" generation = state[\"generation\"]\n",
"\n",
" score = hallucination_grader.invoke(\n",
" {\"documents\": documents, \"generation\": generation}\n",
" )\n",
" grade = score.binary_score\n",
"\n",
" # Check hallucination\n",
" if grade == \"yes\":\n",
" print(\"---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---\")\n",
" # Check question-answering\n",
" print(\"---GRADE GENERATION vs QUESTION---\")\n",
" score = answer_grader.invoke({\"question\": question, \"generation\": generation})\n",
" grade = score.binary_score\n",
" if grade == \"yes\":\n",
" print(\"---DECISION: GENERATION ADDRESSES QUESTION---\")\n",
" return \"useful\"\n",
" else:\n",
" print(\"---DECISION: GENERATION DOES NOT ADDRESS QUESTION---\")\n",
" return \"not useful\"\n",
" else:\n",
" pprint(\"---DECISION: GENERATION IS NOT GROUNDED IN DOCUMENTS, RE-TRY---\")\n",
" return \"not supported\""
]
},
{
"cell_type": "markdown",
"id": "b77061d5-fa7f-4dbc-ad5b-cc409b931bf4",
"metadata": {},
"source": [
"### Compose the graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f5ae35f7-ff5c-40f1-9b0e-1a8bac0dc58f",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langgraph.graph import END, StateGraph, START\n",
"\n",
"workflow = StateGraph(GraphState)\n",
"\n",
"# Define the nodes\n",
"workflow.add_node(\"retrieve\", retrieve) # retrieve\n",
"workflow.add_node(\"grade_documents\", grade_documents) # grade documents\n",
"workflow.add_node(\"generate\", generate) # generatae\n",
"workflow.add_node(\"transform_query\", transform_query) # transform_query\n",
"\n",
"# Build graph\n",
"workflow.add_edge(START, \"retrieve\")\n",
"workflow.add_edge(\"retrieve\", \"grade_documents\")\n",
"workflow.add_conditional_edges(\n",
" \"grade_documents\",\n",
" decide_to_generate,\n",
" {\n",
" \"transform_query\": \"transform_query\",\n",
" \"generate\": \"generate\",\n",
" },\n",
")\n",
"workflow.add_edge(\"transform_query\", \"retrieve\")\n",
"workflow.add_conditional_edges(\n",
" \"generate\",\n",
" grade_generation_v_documents_and_question,\n",
" {\n",
" \"not supported\": \"generate\",\n",
" \"useful\": END,\n",
" \"not useful\": \"transform_query\",\n",
" },\n",
")\n",
"\n",
"# Compile\n",
"app = workflow.compile()"
]
},
{
"cell_type": "markdown",
"id": "598a9ef4-cfb2-479a-9a74-b82c5781daca",
"metadata": {},
"source": [
"# Serve the agent\n",
"\n",
"`BaseRAGQuestionAnswerer` provides `serve_callable` that lets you attach a custom Python function to an endpoint. This way, you can create your own endpoints on the Pathway server in addition to the [built-in ones](https://pathway.com/developers/ai-pipelines/rest-api).\n",
"\n",
"Use the `serve_callable` method to expose the LangGraph agent as an HTTP endpoint.\n",
"The `/agent` endpoint accepts user queries, processes them through the LangGraph pipeline, and returns the final answer."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fafc447a-c221-4251-ad40-c56cb77c338c",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"@rag_app.serve_callable(route=\"/agent\")\n",
"async def call_agent(user_query: str) -> str:\n",
" langgraph_input = {\"question\": user_query}\n",
" result = app.invoke(langgraph_input)\n",
" return result[\"generation\"]"
]
},
{
"cell_type": "markdown",
"id": "a71d3943-faf8-4f74-9f9d-a8f914db2acb",
"metadata": {},
"source": [
"The above Pathway endpoint,\n",
"* Takes a `user_query` as the JSON input.\n",
"* Passes it into the compiled LangGraph pipeline.\n",
"* Returns the final answer from the state (result[\"generation\"])"
]
},
{
"cell_type": "markdown",
"id": "6e86ac7c-db40-4636-b704-77df7c0d18a6",
"metadata": {},
"source": [
"# Build and Run the Pathway server"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "963e891e-4ccf-4186-a3f2-19997b44bb86",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# This creates and runs the index, also serves the agent endpoint defined above\n",
"\n",
"rag_app.build_server(pathway_host, pathway_port)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "065f68f6-99b9-4d5e-8abf-796fdf67c050",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"t = rag_app.run_server(threaded=True)"
]
},
{
"cell_type": "markdown",
"id": "95b9772b-42ce-422f-bd40-56ba317a8249",
"metadata": {},
"source": [
"List the indexed documents.\n",
"\n",
"This request may take a while since app is parsing the documents and building the index."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8bc8ab3c-cfb6-41e6-a102-281caa1bb19e",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"pathway_client = RAGClient(pathway_host, pathway_port)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "aebfab0c-c827-4a47-a5b4-36361c2c68c1",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"pathway_client.list_documents()"
]
},
{
"cell_type": "markdown",
"id": "1e682805-8d61-4054-aab0-47044d921157",
"metadata": {},
"source": [
"# Run with a sample question\n",
"\n",
"Test the `/agent` endpoint by sending a sample question. The server runs the entire RAG pipeline and returns the answer."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4676f4c8-26bd-4f36-aadf-80771b001b59",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"question: str = (\n",
" \"How does self-RAG work? Explain the steps involved in the implementation.\"\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b84144d8-e266-4a13-a515-a55fcdc02f11",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import requests\n",
"\n",
"# send request to the endpoint we defined above, put the expected fields as payload\n",
"response = requests.post(\n",
" pathway_client.url + \"/agent\",\n",
" json={\"user_query\": question},\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a5689309-1780-4725-8d3f-364841303def",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"response.json()"
]
},
{
"cell_type": "markdown",
"id": "35051a4c-1c70-4631-9005-5a06520640e1",
"metadata": {
"tags": []
},
"source": [
"## Summary\n",
"\n",
"1. **Data Ingestion:** Ingest a webpage (the Self-RAG arxiv page).\n",
"2. **Indexing:** Pathway reads these text documents, parses, splits, and indexes them using a hybrid BM25 + semantic index.\n",
"3. **LangGraph Agent:** Define a multi-step agent that:\n",
" * Re-writes the query if needed.\n",
" * Retrieves documents via the Pathway VectorStore.\n",
" * Grades those docs for relevance.\n",
" * Generates an answer.\n",
" * Grades that answer for hallucination and for how well it addresses the user’s question.\n",
" * Loops as necessary until it gets a satisfactory final response.\n",
"4. **Serving:** Pathway’s built-in server is launched, hosting an `/agent` endpoint for queries.\n",
"\n",
"\n",
"Thus, whenever you POST a `\"user_query\"` to the `/agent` endpoint, the agent pipeline runs, and returns the final answer."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
================================================
FILE: cookbooks/self-rag-agents/pathway_langgraph_agentic_rag.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"id": "09287484-c402-4d09-a26b-588a13a331f0",
"metadata": {
"tags": []
},
"source": [
"> The following cookbook is an adaption of the original [LangGraph cookbook](https://github.com/langchain-ai/langgraph/blob/e3ca7bb3e9d34b09633852f4d08d55f6dcd4364b/examples/rag/langgraph_self_rag.ipynb)\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "9b009d03-9465-4b1a-b64d-50a05c0dfbc5",
"metadata": {},
"source": [
"# LangGraph Agents Powered by Pathway: A Complete Guide\n",
"\n",
"This notebook demonstrates how to use Pathway VectorStore as a LangChain Retriever to power LangGraph Agents that are synced with your documents.\n",
"\n",
"In this notebook, you will learn:\n",
"- How to build a Pathway vector store that indexes documents from your data sources\n",
"- How to create a vector index that enables semantic search through your documents\n",
"- How to use the Pathway LangChain Retriever in a LangGraph Agent"
]
},
{
"cell_type": "markdown",
"id": "f42f3015-33e6-48f4-827a-1e44541507cd",
"metadata": {},
"source": [
"Magic library is used for detecting file types in the `UnstructuredParser` module.\n",
"\n",
"If you are running this notebook on **MacOS**, you can install it with:\n",
"> `brew install libmagic`\n",
"\n",
"If you are running the notebook on **colab** or any **linux** environment, you can install it with:\n",
"> `apt-get install libmagic1`"
]
},
{
"cell_type": "markdown",
"id": "727099e5-e1d8-4f20-8240-d74ec1299ddf",
"metadata": {},
"source": [
"# Setup\n",
"\n",
"Install the required packages and set your OpenAI API key. \n",
"OpenAI is used for embeddings during the indexing stage and to power the LangGraph agent."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7bdea4ea-882e-4043-8cda-4671690b33a1",
"metadata": {},
"outputs": [],
"source": [
"!pip install -U \"pathway[all]\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "88ec0f0e-7fa2-457f-a3d7-49a158653e24",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"!pip install -U langgraph langchain-community langchainhub langchain-openai"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3ff9da9f-66b8-4675-8c45-afa10e891462",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import os\n",
"\n",
"import json\n",
"from typing import Iterable, Literal, List\n",
"from pydantic import BaseModel, Field\n",
"\n",
"# needed for the OpenAI embedder and the LLM we will use below, you can change the embedding provider, see the documentation:\n",
"# https://pathway.com/developers/api-docs/pathway-xpacks-llm/embedders\n",
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
]
},
{
"cell_type": "markdown",
"id": "5b04f68d-2ca4-43e5-9c8d-c8392dd65edb",
"metadata": {},
"source": [
"Lets define a `DATA_PATH` folder that will store the text files/documents for indexing."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "54979252-13d3-4b94-b2ad-ec7b012aa320",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# folder that we will gather our docs in\n",
"DATA_PATH = \"./data\"\n",
"\n",
"os.makedirs(DATA_PATH, exist_ok=True)"
]
},
{
"cell_type": "markdown",
"id": "8169934b-9a2c-433e-b034-8a97ead8d25b",
"metadata": {},
"source": [
"## Load & save a webpage\n",
"\n",
"Define utility functions to read content from a webpage and save it locally into `DATA_PATH`.\n",
" 1. `load_page_content`: Reads the raw text from a webpage using using a `WebBaseLoader` from `langchain_community.document_loaders`.\n",
" 2. `ingest_webpage`: Saves the loaded content as a text file into the `DATA_PATH`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "64538684-5b2b-460a-b3a5-1fe737fd8269",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import re\n",
"from urllib.parse import urlparse\n",
"from langchain_community.document_loaders import WebBaseLoader\n",
"\n",
"\n",
"def load_page_content(url: str) -> str:\n",
" \"\"\"Load web page content with Langchain utilities.\"\"\"\n",
" return WebBaseLoader(url).load()[0].page_content\n",
"\n",
"\n",
"def ingest_webpage(url: str) -> None:\n",
" \"\"\"Save a webpage to local `DATA_PATH` folder.\"\"\"\n",
" text_content = load_page_content(url)\n",
"\n",
" parsed_url = urlparse(url)\n",
" file_name = parsed_url.hostname + parsed_url.path.replace(\"/\", \"_\") + \".txt\"\n",
"\n",
" with open(os.path.join(DATA_PATH, file_name), \"w\", encoding=\"utf-8\") as f:\n",
" f.write(text_content)"
]
},
{
"cell_type": "markdown",
"id": "5bf15463-7da1-4d04-9f6d-423975e377cb",
"metadata": {
"tags": []
},
"source": [
"Download the Self-RAG paper"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fff7b382-2e25-415b-a3ee-06df976b3dbd",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"ingest_webpage(\"https://arxiv.org/html/2310.11511\")"
]
},
{
"cell_type": "markdown",
"id": "f7e2f21e-2259-49f8-b295-0f442e35c337",
"metadata": {
"tags": []
},
"source": [
"# Build the Pathway indexing pipeline\n",
"\n",
"Set up Pathway to read and index the documents saved under the `DATA_PATH`.\n",
"\n",
"\n",
"1. [Connectors](https://pathway.com/developers/user-guide/connect/pathway-connectors): Use Pathway’s file reader to ingest all text files under the `DATA_PATH`.\n",
"2. [Parsers](https://pathway.com/developers/api-docs/pathway-xpacks-llm/parsers): Utilize the UnstructuredParser to parse the documents. This parser supports multiple file types, including PDF, DOCX, and PPTX.\n",
"3. [Text Splitters](https://pathway.com/developers/api-docs/pathway-xpacks-llm/splitters): Split the document content into chunks.\n",
"4. [Embedders](https://pathway.com/developers/api-docs/pathway-xpacks-llm/embedders): Use OpenAI API for embeddings.\n",
"5. [VectorStore](https://pathway.com/developers/api-docs/pathway-xpacks-llm/vectorstore): Orchestrates all the above modules."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "27c3d42a-30e1-47f8-bf3c-bd44d4a490f0",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# host and port of the RAG app\n",
"pathway_host: str = \"0.0.0.0\"\n",
"pathway_port: int = 8000"
]
},
{
"cell_type": "markdown",
"id": "3c68a48a-8263-4b52-8c5a-206baefd22d1",
"metadata": {},
"source": [
"Create the vector store that will power the index of our RAG application. \n",
"\n",
"We use the modules under the Pathway Xpacks to create a suitable vector store."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "094ec4e1-e972-441b-9c47-ff0ce3c8d2ff",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import pathway as pw\n",
"\n",
"from pathway.xpacks.llm.vector_store import VectorStoreServer, VectorStoreClient\n",
"from pathway.xpacks.llm import (\n",
" embedders,\n",
" llms,\n",
" parsers,\n",
" splitters,\n",
")\n",
"from pathway.udfs import DiskCache\n",
"\n",
"# read the text files under the data folder, we can also read from Google Drive, Sharepoint, etc.\n",
"# See connectors documentation: https://pathway.com/developers/user-guide/connect/pathway-connectors to learn more\n",
"folder = pw.io.fs.read(\n",
" path=f\"{DATA_PATH}/*.txt\",\n",
" format=\"binary\",\n",
" with_metadata=True,\n",
")\n",
"\n",
"# list of data sources to be indexed\n",
"sources = [folder]\n",
"\n",
"# define the document processing steps\n",
"parser = parsers.UnstructuredParser()\n",
"\n",
"text_splitter = splitters.TokenCountSplitter(min_tokens=150, max_tokens=450)\n",
"\n",
"embedder = embedders.OpenAIEmbedder(cache_strategy=DiskCache())\n",
"\n",
"vector_server = VectorStoreServer(\n",
" *sources,\n",
" embedder=embedder,\n",
" splitter=text_splitter,\n",
" parser=parser,\n",
")\n",
"\n",
"# deploy the vector store locally\n",
"t = vector_server.run_server(pathway_host, pathway_port, threaded=True)"
]
},
{
"cell_type": "markdown",
"id": "34cc8823-e184-47c0-aa09-7b4035817e7d",
"metadata": {},
"source": [
"[VectorStore](https://pathway.com/developers/api-docs/pathway-xpacks-llm/vectorstore) manages document ingestion, parsing, splitting, and indexing."
]
},
{
"cell_type": "markdown",
"id": "b2742133-a7ef-49a8-82d1-093c2d2ff2d2",
"metadata": {},
"source": [
"List the indexed documents"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8bc8ab3c-cfb6-41e6-a102-281caa1bb19e",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"pathway_client = VectorStoreClient(pathway_host, pathway_port)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "aebfab0c-c827-4a47-a5b4-36361c2c68c1",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"pathway_client.get_input_files()"
]
},
{
"cell_type": "markdown",
"id": "ba734b24-63bd-4b22-a3cb-fed2393a60f4",
"metadata": {},
"source": [
"# Create the LangGraph agent"
]
},
{
"cell_type": "markdown",
"id": "cf15141f-9612-4d0d-a21b-11bd8530686a",
"metadata": {},
"source": [
"### Create the Langchain Retriever\n",
"\n",
"You can now query Pathway and access up-to-date documents for your RAG applications from LangChain using [PathwayVectorClient](https://api.python.langchain.com/en/latest/vectorstores/langchain_community.vectorstores.pathway.PathwayVectorClient.html)\n",
"\n",
"The Langchain Retriever is a wrapper around the Pathway client, you will use it in `retrieve` part stage of the Agent"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fefffab6-d5a3-4925-a52d-5a5c574421ea",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain_community.vectorstores import PathwayVectorClient"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "51d365aa-5526-4ec8-932d-e65e83ee355d",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"vectorstore_client = PathwayVectorClient(pathway_host, pathway_port)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "59624377-8481-4407-8ee3-0f014bdff30e",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"retriever = vectorstore_client.as_retriever()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4623f53b-013b-4bc5-8c7c-e994a2e35c57",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# test the retriever\n",
"# retriever.invoke({\"question\": \"evaluation\"})"
]
},
{
"attachments": {
"76895b7a-fcc5-4758-9fbb-510b17fdeda4.png": {
"image/png": "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+QwggAACCCCAAAIIIIAAAggggAACCCCAwAIEiBQXgMWpCCCAAAIIIIAAAggggAACCCCAAAIIIECkyGcAAQQQQAABBBBAAAEEEEAAAQQQQAABBBYgQKS4ACxORQABBBBAAAEEEEAAAQQQQAABBBBAAAEiRT4DCCCAAAIIIIAAAggggAACCCCAAAIIILAAASLFBWBxKgIIIIAAAggggAACCCCAAAIIIIAAAggQKfIZQAABBBBAAAEEEEAAAQQQQAABBBBAAIEFCBApLgCLUxFAAAEEEEAAAQQQQAABBBBAAAEEEECASJHPAAIIIIAAAggggAACCCCAAAIIIIAAAggsQIBIcQFYnIoAAggggAACCCCAAAIIIIAAAggggAACRIp8BhBAAAEEEEAAAQQQQAABBBBAAAEEEEBgAQJEigvA4lQEEEAAAQQQQAABBBBAAAEEEEAAAQQQIFLkM4AAAggggAACCCCAAAIIIIAAAggggAACCxAgUlwAFqcigAACCCCAAAIIIIAAAggggAACCCCAAJEinwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQWIAAkeICsDgVAQQQQAABBBBAAAEEEEAAAQQQQAABBIgU+QwggAACCCCAAAIIIIAAAggggAACCCCAwAIEiBQXgMWpCCCAAAIIIIAAAggggAACCCCAAAIIIECkyGcAAQQQQAABBBBAAAEEEEAAAQQQQAABBBYg8P8DAA3xveEZM1sAAAAASUVORK5CYII="
}
},
"cell_type": "markdown",
"id": "4c02199d-6ba1-49fa-9bd6-ef36e906c553",
"metadata": {
"tags": []
},
"source": [
"### Self-RAG\n",
"\n",
"Self-RAG is a strategy for RAG that incorporates self-reflection / self-grading on retrieved documents and generations.\n",
"\n",
"In the [paper](https://arxiv.org/abs/2310.11511), a few decisions are made:\n",
"\n",
"1. Should I retrieve from retriever, `R` -\n",
"\n",
"* Input: `x (question)` OR `x (question)`, `y (generation)`\n",
"* Decides when to retrieve `D` chunks with `R`\n",
"* Output: `yes, no, continue`\n",
"\n",
"2. Are the retrieved passages `D` relevant to the question `x` -\n",
"\n",
"* * Input: (`x (question)`, `d (chunk)`) for `d` in `D`\n",
"* `d` provides useful information to solve `x`\n",
"* Output: `relevant, irrelevant`\n",
"\n",
"3. Are the LLM generation from each chunk in `D` is relevant to the chunk (hallucinations, etc) -\n",
"\n",
"* Input: `x (question)`, `d (chunk)`, `y (generation)` for `d` in `D`\n",
"* All of the verification-worthy statements in `y (generation)` are supported by `d`\n",
"* Output: `{fully supported, partially supported, no support`\n",
"\n",
"4. The LLM generation from each chunk in `D` is a useful response to `x (question)` -\n",
"\n",
"* Input: `x (question)`, `y (generation)` for `d` in `D`\n",
"* `y (generation)` is a useful response to `x (question)`.\n",
"* Output: `{5, 4, 3, 2, 1}`\n",
"\n",
"We will implement some of these ideas from scratch using [LangGraph](https://langchain-ai.github.io/langgraph/).\n",
"\n",
"> Figure and the explanation taken from the [LangGraph cookbook](https://github.com/langchain-ai/langgraph/blob/e3ca7bb3e9d34b09633852f4d08d55f6dcd4364b/examples/rag/langgraph_self_rag.ipynb)"
]
},
{
"cell_type": "markdown",
"id": "4244331f-1cdc-4548-b577-f758d1cd2bf9",
"metadata": {},
"source": [
"### Define the LangGraph Workflow\n",
"\n",
"\n",
"The LangGraph agent operates as a multi-step workflow.\n",
"\n",
"- It retrieves documents, grades their relevance, generates an answer, and ensures factual accuracy (e.g., no hallucinations).\n",
"- You can also implement self-reflection and query optimization using LangGraph nodes."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8c4c9be8-396c-4ebc-a9e4-d4e11504c05c",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain_core.prompts import ChatPromptTemplate\n",
"from langchain_core.pydantic_v1 import BaseModel, Field\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"\n",
"# Data model\n",
"class GradeDocuments(BaseModel):\n",
" \"\"\"Binary score for relevance check on retrieved documents.\"\"\"\n",
"\n",
" binary_score: str = Field(\n",
" description=\"Documents are relevant to the question, 'yes' or 'no'\"\n",
" )\n",
"\n",
"\n",
"# LLM with function call\n",
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0)\n",
"structured_llm_grader = llm.with_structured_output(GradeDocuments)\n",
"\n",
"# Prompt\n",
"system = \"\"\"You are a grader assessing relevance of a retrieved document to a user question. \\n \n",
" It does not need to be a stringent test. The goal is to filter out erroneous retrievals. \\n\n",
" If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \\n\n",
" Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.\"\"\"\n",
"grade_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
" (\"human\", \"Retrieved document: \\n\\n {document} \\n\\n User question: {question}\"),\n",
" ]\n",
")\n",
"\n",
"retrieval_grader = grade_prompt | structured_llm_grader\n",
"\n",
"\n",
"question = \"self rag performance\"\n",
"docs = retriever.get_relevant_documents(question)\n",
"doc_txt = docs[1].page_content\n",
"print(retrieval_grader.invoke({\"question\": question, \"document\": doc_txt}))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "499173a5-8df0-4fe6-bb46-552ce496b8ba",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain_core.output_parsers import StrOutputParser\n",
"\n",
"# Prompt\n",
"prompt = hub.pull(\"rlm/rag-prompt\")\n",
"\n",
"# LLM\n",
"llm = ChatOpenAI(model_name=\"gpt-3.5-turbo\", temperature=0)\n",
"\n",
"\n",
"# Post-processing\n",
"def format_docs(docs):\n",
" return \"\\n\\n\".join(doc.page_content for doc in docs)\n",
"\n",
"\n",
"# Chain\n",
"rag_chain = prompt | llm | StrOutputParser()\n",
"\n",
"# Run\n",
"generation = rag_chain.invoke({\"context\": docs, \"question\": question})\n",
"print(generation)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d9055d3b-8e9b-494f-bf4f-d02c153639c7",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"class GradeHallucinations(BaseModel):\n",
" \"\"\"Binary score for hallucination present in generation answer.\"\"\"\n",
"\n",
" binary_score: str = Field(\n",
" description=\"Answer is grounded in the facts, 'yes' or 'no'\"\n",
" )\n",
"\n",
"\n",
"# LLM with function call\n",
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0)\n",
"structured_llm_grader = llm.with_structured_output(GradeHallucinations)\n",
"\n",
"# Prompt\n",
"system = \"\"\"You are a grader assessing whether an LLM generation is grounded in / supported by a set of retrieved facts. \\n \n",
" Give a binary score 'yes' or 'no'. 'Yes' means that the answer is grounded in / supported by the set of facts.\"\"\"\n",
"hallucination_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
" (\"human\", \"Set of facts: \\n\\n {documents} \\n\\n LLM generation: {generation}\"),\n",
" ]\n",
")\n",
"\n",
"hallucination_grader = hallucination_prompt | structured_llm_grader\n",
"hallucination_grader.invoke({\"documents\": docs, \"generation\": generation})"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f92d351d-5ee1-48cc-ad8f-9b57ceed18ed",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"class GradeAnswer(BaseModel):\n",
" \"\"\"Binary score to assess answer addresses question.\"\"\"\n",
"\n",
" binary_score: str = Field(\n",
" description=\"Answer addresses the question, 'yes' or 'no'\"\n",
" )\n",
"\n",
"\n",
"# LLM with function call\n",
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0)\n",
"structured_llm_grader = llm.with_structured_output(GradeAnswer)\n",
"\n",
"# Prompt\n",
"system = \"\"\"You are a grader assessing whether an answer addresses / resolves a question \\n \n",
" Give a binary score 'yes' or 'no'. Yes' means that the answer resolves the question.\"\"\"\n",
"answer_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
" (\"human\", \"User question: \\n\\n {question} \\n\\n LLM generation: {generation}\"),\n",
" ]\n",
")\n",
"\n",
"answer_grader = answer_prompt | structured_llm_grader\n",
"answer_grader.invoke({\"question\": question, \"generation\": generation})"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "286a9a2a-2a62-4004-84a2-fc82e6996cf1",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0)\n",
"\n",
"# Prompt\n",
"system = \"\"\"You a question re-writer that converts an input question to a better version that is optimized \\n \n",
" for vectorstore retrieval. Look at the input and try to reason about the underlying semantic intent / meaning.\"\"\"\n",
"re_write_prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system),\n",
" (\n",
" \"human\",\n",
" \"Here is the initial question: \\n\\n {question} \\n Formulate an improved question.\",\n",
" ),\n",
" ]\n",
")\n",
"\n",
"question_rewriter = re_write_prompt | llm | StrOutputParser()\n",
"question_rewriter.invoke({\"question\": question})"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb9bd597-a683-433a-879d-7991cfed5cf7",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from typing import List\n",
"\n",
"from typing_extensions import TypedDict\n",
"\n",
"\n",
"class GraphState(TypedDict):\n",
" \"\"\"\n",
" Represents the state of our graph.\n",
"\n",
" Attributes:\n",
" question: question\n",
" generation: LLM generation\n",
" documents: list of documents\n",
" \"\"\"\n",
"\n",
" question: str\n",
" generation: str\n",
" documents: List[str]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "398e5cc2-9c41-465d-a4f4-93c82ed452f2",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"def retrieve(state):\n",
" \"\"\"\n",
" Retrieve documents\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" state (dict): New key added to state, documents, that contains retrieved documents\n",
" \"\"\"\n",
" print(\"---RETRIEVE---\")\n",
" question = state[\"question\"]\n",
"\n",
" # Retrieval\n",
" documents = retriever.get_relevant_documents(question)\n",
" return {\"documents\": documents, \"question\": question}\n",
"\n",
"\n",
"def generate(state):\n",
" \"\"\"\n",
" Generate answer\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" state (dict): New key added to state, generation, that contains LLM generation\n",
" \"\"\"\n",
" print(\"---GENERATE---\")\n",
" question = state[\"question\"]\n",
" documents = state[\"documents\"]\n",
"\n",
" # RAG generation\n",
" generation = rag_chain.invoke({\"context\": documents, \"question\": question})\n",
" return {\"documents\": documents, \"question\": question, \"generation\": generation}\n",
"\n",
"\n",
"def grade_documents(state):\n",
" \"\"\"\n",
" Determines whether the retrieved documents are relevant to the question.\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" state (dict): Updates documents key with only filtered relevant documents\n",
" \"\"\"\n",
"\n",
" print(\"---CHECK DOCUMENT RELEVANCE TO QUESTION---\")\n",
" question = state[\"question\"]\n",
" documents = state[\"documents\"]\n",
"\n",
" # Score each doc\n",
" filtered_docs = []\n",
" for d in documents:\n",
" score = retrieval_grader.invoke(\n",
" {\"question\": question, \"document\": d.page_content}\n",
" )\n",
" grade = score.binary_score\n",
" if grade == \"yes\":\n",
" print(\"---GRADE: DOCUMENT RELEVANT---\")\n",
" filtered_docs.append(d)\n",
" else:\n",
" print(\"---GRADE: DOCUMENT NOT RELEVANT---\")\n",
" continue\n",
" return {\"documents\": filtered_docs, \"question\": question}\n",
"\n",
"\n",
"def transform_query(state):\n",
" \"\"\"\n",
" Transform the query to produce a better question.\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" state (dict): Updates question key with a re-phrased question\n",
" \"\"\"\n",
"\n",
" print(\"---TRANSFORM QUERY---\")\n",
" question = state[\"question\"]\n",
" documents = state[\"documents\"]\n",
"\n",
" # Re-write question\n",
" better_question = question_rewriter.invoke({\"question\": question})\n",
" return {\"documents\": documents, \"question\": better_question}\n",
"\n",
"\n",
"### Edges\n",
"\n",
"\n",
"def decide_to_generate(state):\n",
" \"\"\"\n",
" Determines whether to generate an answer, or re-generate a question.\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" str: Binary decision for next node to call\n",
" \"\"\"\n",
"\n",
" print(\"---ASSESS GRADED DOCUMENTS---\")\n",
" state[\"question\"]\n",
" filtered_documents = state[\"documents\"]\n",
"\n",
" if not filtered_documents:\n",
" # All documents have been filtered check_relevance\n",
" # We will re-generate a new query\n",
" print(\n",
" \"---DECISION: ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, TRANSFORM QUERY---\"\n",
" )\n",
" return \"transform_query\"\n",
" else:\n",
" # We have relevant documents, so generate answer\n",
" print(\"---DECISION: GENERATE---\")\n",
" return \"generate\"\n",
"\n",
"\n",
"def grade_generation_v_documents_and_question(state):\n",
" \"\"\"\n",
" Determines whether the generation is grounded in the document and answers question.\n",
"\n",
" Args:\n",
" state (dict): The current graph state\n",
"\n",
" Returns:\n",
" str: Decision for next node to call\n",
" \"\"\"\n",
"\n",
" print(\"---CHECK HALLUCINATIONS---\")\n",
" question = state[\"question\"]\n",
" documents = state[\"documents\"]\n",
" generation = state[\"generation\"]\n",
"\n",
" score = hallucination_grader.invoke(\n",
" {\"documents\": documents, \"generation\": generation}\n",
" )\n",
" grade = score.binary_score\n",
"\n",
" # Check hallucination\n",
" if grade == \"yes\":\n",
" print(\"---DECISION: GENERATION IS GROUNDED IN DOCUMENTS---\")\n",
" # Check question-answering\n",
" print(\"---GRADE GENERATION vs QUESTION---\")\n",
" score = answer_grader.invoke({\"question\": question, \"generation\": generation})\n",
" grade = score.binary_score\n",
" if grade == \"yes\":\n",
" print(\"---DECISION: GENERATION ADDRESSES QUESTION---\")\n",
" return \"useful\"\n",
" else:\n",
" print(\"---DECISION: GENERATION DOES NOT ADDRESS QUESTION---\")\n",
" return \"not useful\"\n",
" else:\n",
" pprint(\"---DECISION: GENERATION IS NOT GROUNDED IN DOCUMENTS, RE-TRY---\")\n",
" return \"not supported\""
]
},
{
"cell_type": "markdown",
"id": "b77061d5-fa7f-4dbc-ad5b-cc409b931bf4",
"metadata": {},
"source": [
"### Compose the graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f5ae35f7-ff5c-40f1-9b0e-1a8bac0dc58f",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langgraph.graph import END, StateGraph, START\n",
"\n",
"workflow = StateGraph(GraphState)\n",
"\n",
"# Define the nodes\n",
"workflow.add_node(\"retrieve\", retrieve) # retrieve\n",
"workflow.add_node(\"grade_documents\", grade_documents) # grade documents\n",
"workflow.add_node(\"generate\", generate) # generatae\n",
"workflow.add_node(\"transform_query\", transform_query) # transform_query\n",
"\n",
"# Build graph\n",
"workflow.add_edge(START, \"retrieve\")\n",
"workflow.add_edge(\"retrieve\", \"grade_documents\")\n",
"workflow.add_conditional_edges(\n",
" \"grade_documents\",\n",
" decide_to_generate,\n",
" {\n",
" \"transform_query\": \"transform_query\",\n",
" \"generate\": \"generate\",\n",
" },\n",
")\n",
"workflow.add_edge(\"transform_query\", \"retrieve\")\n",
"workflow.add_conditional_edges(\n",
" \"generate\",\n",
" grade_generation_v_documents_and_question,\n",
" {\n",
" \"not supported\": \"generate\",\n",
" \"useful\": END,\n",
" \"not useful\": \"transform_query\",\n",
" },\n",
")\n",
"\n",
"# Compile\n",
"app = workflow.compile()"
]
},
{
"cell_type": "markdown",
"id": "074bd11c-0252-46cc-8903-5fa29c327e96",
"metadata": {},
"source": [
"# Run with a sample question\n",
"\n",
"Test the `/agent` endpoint by sending a sample question. The server runs the entire RAG pipeline and returns the answer."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4676f4c8-26bd-4f36-aadf-80771b001b59",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"inputs = {\n",
" \"question\": \"How does self-RAG work? Explain the steps involved in the implementation.\"\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b84144d8-e266-4a13-a515-a55fcdc02f11",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"result = app.invoke(inputs)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a5689309-1780-4725-8d3f-364841303def",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"result[\"generation\"]"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
================================================
FILE: pyproject.toml
================================================
[tool.poetry]
name = "llm-app"
version = "0.3.6"
description = "LLM-App is a library for creating responsive AI applications leveraging OpenAI/Hugging Face APIs to provide responses to user queries based on live data sources. Build your own LLM application in 30 lines of code, no vector database required."
authors = [
"Jan Chorowski ",
"Kamil Piechowiak ",
"Jakub Kowalski ",
"Michał Bartoszkiewicz ",
"Mohamed Malhou ",
"Sergey Kulik ",
"Adrian Kosowski ",
"Mateusz Lewandowski ",
"Olivier Ruas ",
]
license = "MIT"
readme = "README.md"
keywords = ["Pathway", "LLM"]
package-mode = false
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Programming Language :: Python :: Implementation :: CPython",
"License :: OSI Approved :: MIT License",
]
[tool.poetry.urls]
"Homepage" = "https://github.com/pathwaycom/llm-app"
"Source Code" = "https://github.com/pathwaycom/llm-app"
[tool.poetry.dependencies]
python = ">=3.10,<3.13"
pathway = "^0.12.0"
[tool.poetry.group.linters]
optional = true
[tool.poetry.group.linters.dependencies]
black = "^24.2.0"
isort = "^5.13.2"
mypy = "~1.10.0"
flake8 = "~7.0.0"
pytest = "^8.0.2"
types-requests = "^2.31.0"
types-PyYAML = "^6.0.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.black]
target-version = ["py310", "py311"]
[tool.isort]
profile = "black"
[tool.mypy]
python_version = "3.10"
exclude = ["templates/adaptive_rag", "templates/private_rag", "templates/document_indexing", "templates/multimodal_rag", "templates/question_answering_rag"]
ignore_missing_imports = true
check_untyped_defs = true
warn_redundant_casts = true
warn_unused_ignores = true
strict_equality = true
================================================
FILE: setup.cfg
================================================
[flake8]
exclude =
.git
max-line-length = 119
docstring-convention = google
extend-ignore =
# Black (https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#flake8)
E203, E701
================================================
FILE: templates/adaptive_rag/Dockerfile
================================================
FROM pathwaycom/pathway:latest
WORKDIR /app
RUN apt-get update \
&& apt-get install -y python3-opencv tesseract-ocr-eng \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
COPY requirements.txt .
RUN pip install -U --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]
================================================
FILE: templates/adaptive_rag/README.md
================================================
Deploy with GCP |
Deploy with AWS |
Deploy with Azure |
Deploy with Render
# End to end Adaptive RAG with Pathway
This is the accompanying code for deploying the `adaptive RAG` technique with Pathway. To understand the technique and learn how it can save tokens without sacrificing accuracy, read [our showcase](https://pathway.com/developers/templates/rag/adaptive-rag).
To learn more about building & deploying RAG applications with Pathway, including containerization, refer to [demo question answering](../question_answering_rag/README.md).
## Introduction
This app relies on modules provided under `pathway.xpacks.llm`.
`BaseRAGQuestionAnswerer` is the base class to build RAG applications with Pathway vector store and Pathway xpack components.
It is meant to get you started with your RAG application right away.
Here, we extend the `BaseRAGQuestionAnswerer` to implement the adaptive retrieval and reply to requests in the endpoint `/v2/answer`.
Since we are interested in changing the behavior and logic of the RAG, we only modify `answer` function that handles all this logic, and then replies to the post request.
`answer` function takes the `pw_ai_queries` table as the input, this table contains the prompt, and other arguments coming from the post request, see the `BaseRAGQuestionAnswerer` class and defined schemas to learn more about getting inputs with post requests.
We use the data in this table to call our adaptive retrieval logic.
To do that, we use `answer_with_geometric_rag_strategy_from_index` implementation provided under the `pathway.xpacks.llm.question_answering`.
This function takes an index, LLM, prompt and adaptive parameters such as the starting number of documents. Then, iteratively asks the question to the LLM with an increasing number of context documents retrieved from the index.
We encourage you to check the implementation of `answer_with_geometric_rag_strategy_from_index`.
## Customizing the pipeline
The code can be modified by changing the `app.yaml` configuration file. To read more about YAML files used in Pathway templates, read [our guide](https://pathway.com/developers/templates/configure-yaml).
In the `app.yaml` file we define:
- input connectors
- LLM
- embedder
- index
and any of these can be replaced or, if no longer needed, removed. For components that can be used check
Pathway [LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview), or you can implement your own.
You can also check our other templates - [Question Answering RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/question_answering_rag),
[Multimodal RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/multimodal_rag) or
[Private RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/private_rag). As all of these only differ
in the YAML configuration file, you can also use them as an inspiration for your custom pipeline.
Here some examples of what can be modified.
### LLM Model
You can choose any of the models offered by Open AI, like GPT-5, GPT-4.1, or GPT-4o.
You can find the whole list on their [models page](https://platform.openai.com/docs/models).
You simply need to change the `model` to the one you want to use, e.g., to use GPT-5:
```yaml
$llm: !pw.xpacks.llm.llms.OpenAIChat
model: "gpt-5"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DefaultCache
capacity: 8
```
The default model is `gpt-4.1-mini`.
You can also use different provider, by using different class from [Pathway LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview),
e.g. here is configuration for locally run Mistral model.
```yaml
$llm: !pw.xpacks.llm.llms.LiteLLMChat
model: "ollama/mistral"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DiskCache
temperature: 0
top_p: 1
api_base: "http://localhost:11434"
```
### Webserver
You can configure the host and the port of the webserver.
Here is the default configuration:
```yaml
host: "0.0.0.0"
port: 8000
```
### Cache
You can configure whether you want to enable cache or persistence, to avoid repeated API accesses, and where the cache is stored.
Default values:
```yaml
persistence_mode: !pw.PersistenceMode.UDF_CACHING
persistence_backend: !pw.persistence.Backend.filesystem
path: ".Cache"
```
### Data sources
You can configure the data sources by changing `$sources` in `app.yaml`.
You can add as many data sources as you want. You can have several sources of the same kind, for instance, several local sources from different folders.
The sections below describe how to configure local, Google Drive and Sharepoint source, and you can check the examples of YAML configuration in our [user guide](https://pathway.com/developers/templates/yaml-snippets/data-sources-examples/). While these are not described in this Section, you can also use any input [connector](https://pathway.com/developers/user-guide/connecting-to-data/connectors) from Pathway package.
By default, the app uses a local data source to read documents from the `data` folder.
#### Local Data Source
The local data source is configured by using map with tag `!pw.io.fs.read`. Then set `path` to denote the path to a folder with files to be indexed.
#### Google Drive Data Source
The Google Drive data source is enabled by using map with tag `!pw.io.gdrive.read`. The map must contain two main parameters:
- `object_id`, containing the ID of the folder that needs to be indexed. It can be found from the URL in the web interface, where it's the last part of the address. For example, the publicly available demo folder in Google Drive has the URL `https://drive.google.com/drive/folders/1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`. Consequently, the last part of this address is `1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`, hence this is the `object_id` you would need to specify.
- `service_user_credentials_file`, containing the path to the credentials files for the Google [service account](https://cloud.google.com/iam/docs/service-account-overview). To get more details on setting up the service account and getting credentials, you can also refer to [this tutorial](https://pathway.com/developers/user-guide/connectors/gdrive-connector#setting-up-google-drive).
Besides, to speed up the indexing process you may want to specify the `refresh_interval` parameter, denoted by an integer number of seconds. It corresponds to the frequency between two sequential folder scans. If unset, it defaults to 30 seconds.
For the full list of the available parameters, please refer to the Google Drive connector [documentation](https://pathway.com/developers/api-docs/pathway-io/gdrive#pathway.io.gdrive.read).
#### SharePoint Data Source
This data source requires Scale or Enterprise [license key](https://pathway.com/pricing) - you can obtain free Scale key on [Pathway website](https://pathway.com/get-license).
To use it, set the map tag to be `!pw.xpacks.connectors.sharepoint.read`, and then provide values of `url`, `tenant`, `client_id`, `cert_path`, `thumbprint` and `root_path`. To read about the meaning of these arguments, check the Sharepoint connector [documentation](https://pathway.com/developers/api-docs/pathway-xpacks-sharepoint#pathway.xpacks.connectors.sharepoint.read).
## Running the app
To run the app, depending on the configuration, you may need to set up environmntal variables with LLM provider keys. By default, this template uses OpenAI API, so to run it you need to set `OPENAI_API_KEY` environmental key or create an `.env` file in this directory with your key: `OPENAI_API_KEY=sk-...`. If you modify the code to use another LLM provider, you may need to set a relevant API key.
### With Docker
In order to let the pipeline get updated with each change in local files, you need to mount the folder onto the docker. The following commands show how to do that.
```bash
# Build the image in this folder
docker build -t adaptiverag .
# Run the image, mount the `data` folder into image
# -e is used to pass value of OPENAI_API_KEY environmental variable
docker run -v ./data:/app/data -e OPENAI_API_KEY -p 8000:8000 adaptiverag
```
### Locally
To run locally you need to install the Pathway app with LLM dependencies using:
```bash
pip install pathway[all]
```
Then change your directory in the terminal to this folder and run the app:
```bash
python app.py
```
## Using the app
Finally, query the application with;
```bash
curl -X 'POST' 'http://0.0.0.0:8000/v2/answer' -H 'accept: */*' -H 'Content-Type: application/json' -d '{
"prompt": "What is the start date of the contract?"
}'
```
> `{"response": "December 21, 2015 [6]"}`
================================================
FILE: templates/adaptive_rag/app.py
================================================
import logging
from warnings import warn
import pathway as pw
from dotenv import load_dotenv
from pathway.xpacks.llm.question_answering import SummaryQuestionAnswerer
from pathway.xpacks.llm.servers import QASummaryRestServer
from pydantic import BaseModel, ConfigDict, InstanceOf
# To use advanced features with Pathway Scale, get your free license key from
# https://pathway.com/features and paste it below.
# To use Pathway Community, comment out the line below.
pw.set_license_key("demo-license-key-with-telemetry")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
load_dotenv()
class App(BaseModel):
question_answerer: InstanceOf[SummaryQuestionAnswerer]
host: str = "0.0.0.0"
port: int = 8000
with_cache: bool | None = None # deprecated
persistence_backend: pw.persistence.Backend | None = None
persistence_mode: pw.PersistenceMode | None = pw.PersistenceMode.UDF_CACHING
terminate_on_error: bool = False
def run(self) -> None:
server = QASummaryRestServer( # noqa: F841
self.host, self.port, self.question_answerer
)
if self.persistence_mode is None:
if self.with_cache is True:
warn(
"`with_cache` is deprecated. Please use `persistence_mode` instead.",
DeprecationWarning,
)
persistence_mode = pw.PersistenceMode.UDF_CACHING
else:
persistence_mode = None
else:
persistence_mode = self.persistence_mode
if persistence_mode is not None:
if self.persistence_backend is None:
persistence_backend = pw.persistence.Backend.filesystem("./Cache")
else:
persistence_backend = self.persistence_backend
persistence_config = pw.persistence.Config(
persistence_backend,
persistence_mode=persistence_mode,
)
else:
persistence_config = None
pw.run(
persistence_config=persistence_config,
terminate_on_error=self.terminate_on_error,
monitoring_level=pw.MonitoringLevel.NONE,
)
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
if __name__ == "__main__":
with open("app.yaml") as f:
config = pw.load_yaml(f)
app = App(**config)
app.run()
================================================
FILE: templates/adaptive_rag/app.yaml
================================================
# This YAML configuration file is used to set up and configure the Adaptive RAG template.
# It defines various components such as data sources, language models, embedders, splitters, parsers, and retrievers.
# Each section is configured to specify how the template should process and handle data for generating responses.
# You can learn more about the YAML syntax here: https://pathway.com/developers/templates/configure-yaml
# $sources defines the data sources used to read the data which will be indexed in the RAG.
# You can learn more how to configure data sources here:
# https://pathway.com/developers/templates/yaml-examples/data-sources-examples
$sources:
# File System connector, reading data locally.
- !pw.io.fs.read
path: data
format: binary
with_metadata: true
# Uncomment to use the SharePoint connector
# - !pw.xpacks.connectors.sharepoint.read
# url: $SHAREPOINT_URL
# tenant: $SHAREPOINT_TENANT
# client_id: $SHAREPOINT_CLIENT_ID
# cert_path: sharepointcert.pem
# thumbprint: $SHAREPOINT_THUMBPRINT
# root_path: $SHAREPOINT_ROOT
# with_metadata: true
# refresh_interval: 30
# Uncomment to use the Google Drive connector
# - !pw.io.gdrive.read
# object_id: $DRIVE_ID
# service_user_credentials_file: gdrive_indexer.json
# file_name_pattern:
# - "*.pdf"
# - "*.pptx"
# object_size_limit: null
# with_metadata: true
# refresh_interval: 30
# Configures the LLM model settings for generating responses.
# The list of available Pathway LLM wrappers is available here:
# https://pathway.com/developers/api-docs/pathway-xpacks-llm/llms
# You can learn more about those in our documentation:
# https://pathway.com/developers/templates/rag-customization/llm-chats
$llm: !pw.xpacks.llm.llms.OpenAIChat
model: "gpt-4.1-mini"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DefaultCache {}
temperature: 0
capacity: 8
# Specifies the embedder model for converting text into embeddings.
$embedder: !pw.xpacks.llm.embedders.OpenAIEmbedder
model: "text-embedding-3-small"
cache_strategy: !pw.udfs.DefaultCache {}
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy {}
# Defines the splitter settings for dividing text into smaller chunks.
$splitter: !pw.xpacks.llm.splitters.TokenCountSplitter
max_tokens: 400
# Configures the parser for processing and extracting information from documents.
$parser: !pw.xpacks.llm.parsers.DoclingParser
async_mode: "fully_async"
chunk: false
cache_strategy: !pw.udfs.DefaultCache {}
# Sets up the retriever factory for indexing and retrieving documents.
$retriever_factory: !pw.indexing.UsearchKnnFactory
reserved_space: 1000
embedder: $embedder
metric: !pw.indexing.USearchMetricKind.COS
# Manages the storage and retrieval of documents for the RAG template.
$document_store: !pw.xpacks.llm.document_store.DocumentStore
docs: $sources
parser: $parser
splitter: $splitter
retriever_factory: $retriever_factory
# Configures the question-answering component using the RAG approach.
# The component builds a RAG over an index.
# You can interact with obtained RAG using a REST API.
# You can learn more about the available operations here:
# https://pathway.com/developers/templates/rag-customization/rest-api
question_answerer: !pw.xpacks.llm.question_answering.AdaptiveRAGQuestionAnswerer
llm: $llm
indexer: $document_store
n_starting_documents: 2
factor: 2
max_iterations: 4
# Change host and port of the webserver by uncommenting these lines
# host: "0.0.0.0"
# port: 8000
# By default, caching is enabled for UDFs with cache_strategy set.
# You can disable it by uncommenting the following line.
# persistence_mode: null
# You can also set persistence_mode to !pw.PersistenceMode.PERSISTING to enable persistence
# across restarts.
# By default, when enabled, Cache is stored in .Cache directory.
# You can customize the location by uncommenting and modifying the following lines:
# persistence_backend: !pw.persistence.Backend.filesystem
# path: ".Cache"
# If `terminate_on_error` is true then the program will terminate whenever any error is encountered.
# Defaults to false, uncomment the following line if you want to set it to true
# terminate_on_error: true
================================================
FILE: templates/adaptive_rag/requirements.txt
================================================
python-dotenv~=1.0
================================================
FILE: templates/document_indexing/Dockerfile
================================================
FROM pathwaycom/pathway:latest
WORKDIR /app
RUN apt-get update \
&& apt-get install -y python3-opencv tesseract-ocr-eng \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
COPY requirements.txt .
RUN pip install -U --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]
================================================
FILE: templates/document_indexing/README.md
================================================
Deploy with GCP |
Deploy with AWS |
Deploy with Azure |
Deploy with Render
# Realtime Document Indexing: Vector Store with always-up-to-date knowledge
This is a basic service for a real-time document indexing pipeline powered by [Pathway](https://github.com/pathwaycom/pathway).
The capabilities of the pipeline include:
- Real-time document indexing from Microsoft 365 SharePoint, Google Drive, or a local directory;
- Similarity search by user query;
- Filtering by the metadata according to the condition given in [JMESPath format](https://jmespath.org/);
- Basic stats on the indexer's health.
## Summary of the Pipeline
This example spawns a lightweight webserver that accepts queries on three possible endpoints:
- `/v1/retrieve` to perform similarity search;
- `/v1/statistics` to get the basic stats about the indexer's health;
- `/v1/inputs` to retrieve the metadata of all files currently processed by the indexer.
Please refer to the Open API doc on Hosted Pipelines [website](https://pathway.com/solutions/ai-pipelines) for the format of the requests to the endpoints.
## How It Works
This pipeline uses several Pathway connectors to read the data from the local drive, Google Drive, and Microsoft SharePoint sources. It allows you to poll the changes with low latency and to do the modifications tracking. So, if something changes in the tracked files, the corresponding change is reflected in the internal collections. The contents are read into a single Pathway Table as binary objects.
After that, those binary objects are parsed with [unstructured](https://unstructured.io/) library and split into chunks. With the usage of OpenAI API, the pipeline embeds the obtained chunks.
Finally, the embeddings are indexed with the capabilities of Pathway's machine-learning library. The user can then query the created index with simple HTTP requests to the endpoints mentioned above.
## Pipeline Organization
This folder contains several objects:
- `app.py`, the pipeline code using Pathway and written in Python;
- `app.yaml`, the file containing configuration of the pipeline, like embedding model, sources, or the server address;
- `requirements.txt`, the textfile denoting the pip dependencies for running this pipeline. It can be passed to `pip install -r ...` to install everything that is needed to launch the pipeline locally;
- `Dockerfile`, the Docker configuration for running the pipeline in the container;
- `docker-compose.yml`, the docker-compose configuration for running the pipeline along with the chat UI;
- `.env`, a short environment variables configuration file where the OpenAI key must be stored;
- `files-for-indexing/`, a folder with exemplary files that can be used for the test runs.
## Customizing the pipeline
The code can be modified by changing the `app.yaml` configuration file. To read more about YAML files used in Pathway templates, read [our guide](https://pathway.com/developers/templates/configure-yaml).
In the `app.yaml` file we define:
- input connectors
- embedder
- index
and any of these can be replaced or, if no longer needed, removed. For components that can be used check
Pathway [LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview), or you can implement your own.
Here some examples of what can be modified.
### Embedding Model
By default this template uses locally run model `mixedbread-ai/mxbai-embed-large-v1`. If you wish, you can replace this with any other model, by changing
`$embedder` in `app.yaml`. For example, to use OpenAI embedder, set:
```yaml
$embedder: !pw.xpacks.llm.embedders.OpenAIEmbedder
model: "text-embedding-ada-002"
cache_strategy: !pw.udfs.DiskCache
```
If you choose to use a provider, that requires API key, remember to set appropriate environmental values (you can also set them in `.env` file).
### Webserver
You can configure the host and the port of the webserver.
Here is the default configuration:
```yaml
host: "0.0.0.0"
port: 8000
```
### Cache
You can configure whether you want to enable cache, to avoid repeated API accesses, and where the cache is stored.
Default values:
```yaml
with_cache: True
cache_backend: !pw.persistence.Backend.filesystem
path: ".Cache"
```
### Data sources
You can configure the data sources by changing `$sources` in `app.yaml`.
You can add as many data sources as you want. You can have several sources of the same kind, for instance, several local sources from different folders.
The sections below describe how to configure local, Google Drive and Sharepoint source, and you can check the examples of YAML configuration in our [user guide](https://pathway.com/developers/templates/yaml-snippets/data-sources-examples/). While these are not described in this Section, you can also use any input [connector](https://pathway.com/developers/user-guide/connecting-to-data/connectors) from Pathway package.
By default, the app uses a local data source to read documents from the `files-from-indexing` folder.
#### Local Data Source
The local data source is configured by using map with tag `!pw.io.fs.read`. Then set `path` to denote the path to a folder with files to be indexed.
#### Google Drive Data Source
The Google Drive data source is enabled by using map with tag `!pw.io.gdrive.read`. The map must contain two main parameters:
- `object_id`, containing the ID of the folder that needs to be indexed. It can be found from the URL in the web interface, where it's the last part of the address. For example, the publicly available demo folder in Google Drive has the URL `https://drive.google.com/drive/folders/1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`. Consequently, the last part of this address is `1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`, hence this is the `object_id` you would need to specify.
- `service_user_credentials_file`, containing the path to the credentials files for the Google [service account](https://cloud.google.com/iam/docs/service-account-overview). To get more details on setting up the service account and getting credentials, you can also refer to [this tutorial](https://pathway.com/developers/user-guide/connectors/gdrive-connector#setting-up-google-drive).
Besides, to speed up the indexing process you may want to specify the `refresh_interval` parameter, denoted by an integer number of seconds. It corresponds to the frequency between two sequential folder scans. If unset, it defaults to 30 seconds.
For the full list of the available parameters, please refer to the Google Drive connector [documentation](https://pathway.com/developers/api-docs/pathway-io/gdrive#pathway.io.gdrive.read).
#### SharePoint Data Source
This data source requires Scale or Enterprise [license key](https://pathway.com/pricing) - you can obtain free Scale key on [Pathway website](https://pathway.com/get-license).
To use it, set the map tag to be `!pw.xpacks.connectors.sharepoint.read`, and then provide values of `url`, `tenant`, `client_id`, `cert_path`, `thumbprint` and `root_path`. To read about the meaning of these arguments, check the Sharepoint connector [documentation](https://pathway.com/developers/api-docs/pathway-xpacks-sharepoint#pathway.xpacks.connectors.sharepoint.read).
## Running the Example
### Locally
This example can be run locally by executing `python main.py` in this directory. It has several command-line arguments:
- `--host` denoting the host, where the server will run. The default setting is `0.0.0.0`;
- `--port` denoting the port, where the server will accept requests. The default setting is `8000`;
- `--sources-config` pointing to a data source configuration file, `sources_configuration.yaml` by default. You can customize it to change the folders indexed by the vector store. The free version supports `local` and `gdrive` hosted files, while the commercial one also supports `sharepoint` hosted folders. By default, the `local` option indexes files from the `files-for-indexing/` folder that is prefilled with exemplary documents.
Please note that the local run requires the dependencies to be installed. It can be done with a simple pip command:
```bash
pip install -r requirements.txt
```
### With Docker
First, create or fill the `.env` file in this folder (`/document_indexing_rag`) with your OpenAI key `OPENAI_API_KEY=sk-*******`.
To run jointly the vector indexing pipeline and a simple UI please execute:
```bash
docker compose up --build
```
Then, the UI will run at http://127.0.0.1:8501 by default. You can access it by following this URL in your web browser.
The `docker-compose.yml` file declares a [volume bind mount](https://docs.docker.com/reference/cli/docker/container/run/#volume) that makes changes to files under `files-for-indexing/` made on your host computer visible inside the docker container. If the index does not react to file changes, please check that the bind mount works
by running `docker compose exec pathway_vector_indexer ls -l /app/files-for-indexing/` and verifying that all files are visible.
Alternatively, you can launch just the indexing pipeline as a single Docker container:
```bash
docker build -t vector_indexer .
docker run -v `pwd`/files-for-indexing:/app/files-for-indexing -p 8000:8000 vector_indexer
```
The volume overlay is important - without it, docker will not see changes to files under the `files-for-indexing` folder.
## Querying the Example
Since the pipeline spawns an HTTP server and interacts with the user using the REST protocol, you can test it locally by sending requests with `curl`. To get the target address for the request, you can refer to the routes in the first section: `v1/retrieve`, `v1/statistics`, and `v1/inputs` and the Open API docs available at the Hosted Pipelines webpage.
Let's assume that the server runs with the default settings and therefore uses port 8000. That being said, you can query the similarity search endpoint with the following command:
```bash
curl -X 'GET' \
'http://localhost:8000/v1/retrieve?query=Pathway%20data%20processing%20framework&k=2' \
-H 'accept: */*'
```
Above, there are two CGI parameters to be customized: the `query`, which should contain the [urlencoded](https://en.wikipedia.org/wiki/Percent-encoding) search terms, and an integer `k` denoting the number of documents you want to retrieve.
Apart from the querying part, there is a health-check endpoint that shows the number of documents currently indexed and the most recent indexing time. It can be accessed, in a similar way, with the following command:
```bash
curl -X 'GET' \
'http://localhost:8000/v1/statistics' \
-H 'accept: */*'
```
Finally, there is a way to see the metadata of all documents that are currently indexed. To do that, you need to query the `v1/inputs` endpoint. The request command then looks as follows:
```bash
curl -X 'GET' \
'http://localhost:8000/v1/inputs' \
-H 'accept: */*'
```
Please make sure that you've changed the port in the requests if you did that when launching the main script.
## Adding Files to Index
To test index updates, simply add more files to the `files-for-indexing` folder if the local data source is used.
If you are using Google Drive, simply upload your files in the folder configured in the `sources_configuration.yaml` file.
Then you can use the similarity search and stats endpoints, provided below.
================================================
FILE: templates/document_indexing/app.py
================================================
import logging
from warnings import warn
import pathway as pw
from dotenv import load_dotenv
from pathway.xpacks.llm.document_store import DocumentStore
from pathway.xpacks.llm.servers import DocumentStoreServer
from pydantic import BaseModel, ConfigDict, InstanceOf
# To use advanced features with Pathway Scale, get your free license key from
# https://pathway.com/features and paste it below.
# To use Pathway Community, comment out the line below.
pw.set_license_key("demo-license-key-with-telemetry")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
load_dotenv()
class App(BaseModel):
document_store: InstanceOf[DocumentStore]
host: str = "0.0.0.0"
port: int = 8000
with_cache: bool | None = None # deprecated
persistence_backend: pw.persistence.Backend | None = None
persistence_mode: pw.PersistenceMode | None = pw.PersistenceMode.UDF_CACHING
terminate_on_error: bool = False
def run(self) -> None:
server = DocumentStoreServer( # noqa: F841
self.host, self.port, self.document_store
)
if self.persistence_mode is None:
if self.with_cache is True:
warn(
"`with_cache` is deprecated. Please use `persistence_mode` instead.",
DeprecationWarning,
)
persistence_mode = pw.PersistenceMode.UDF_CACHING
else:
persistence_mode = None
else:
persistence_mode = self.persistence_mode
if persistence_mode is not None:
if self.persistence_backend is None:
persistence_backend = pw.persistence.Backend.filesystem("./Cache")
else:
persistence_backend = self.persistence_backend
persistence_config = pw.persistence.Config(
persistence_backend,
persistence_mode=persistence_mode,
)
else:
persistence_config = None
pw.run(
persistence_config=persistence_config,
terminate_on_error=self.terminate_on_error,
monitoring_level=pw.MonitoringLevel.NONE,
)
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
if __name__ == "__main__":
with open("app.yaml") as f:
config = pw.load_yaml(f)
app = App(**config)
app.run()
================================================
FILE: templates/document_indexing/app.yaml
================================================
# This YAML configuration file is used to set up and configure the Document indexing RAG template.
# It defines various components such as data sources, embedders, splitters, parsers, and retrievers.
# Each section is configured to specify how the template should process and handle data for answering the queries.
# You can learn more about the YAML syntax here: https://pathway.com/developers/templates/configure-yaml
# $sources defines the data sources used to read the data which will be indexed in the RAG.
# You can learn more how to configure data sources here:
# https://pathway.com/developers/templates/yaml-examples/data-sources-examples
$sources:
# File System connector, reading data locally.
- !pw.io.fs.read
path: files-for-indexing
format: binary
with_metadata: true
# Uncomment to use the SharePoint connector
# - !pw.xpacks.connectors.sharepoint.read
# url: $SHAREPOINT_URL
# tenant: $SHAREPOINT_TENANT
# client_id: $SHAREPOINT_CLIENT_ID
# cert_path: sharepointcert.pem
# thumbprint: $SHAREPOINT_THUMBPRINT
# root_path: $SHAREPOINT_ROOT
# with_metadata: true
# refresh_interval: 30
# Uncomment to use the Google Drive connector
# - !pw.io.gdrive.read
# object_id: $DRIVE_ID
# service_user_credentials_file: gdrive_indexer.json
# file_name_pattern:
# - "*.pdf"
# - "*.pptx"
# object_size_limit: null
# with_metadata: true
# refresh_interval: 30
# Model used for embedding
$embedding_model: "mixedbread-ai/mxbai-embed-large-v1"
# Specifies the embedder model for converting text into embeddings.
$embedder: !pw.xpacks.llm.embedders.SentenceTransformerEmbedder
model: $embedding_model
call_kwargs:
show_progress_bar: False
# Defines the splitter settings for dividing text into smaller chunks.
$splitter: !pw.xpacks.llm.splitters.TokenCountSplitter
max_tokens: 400
# Configures the parser for processing and extracting information from documents.
$parser: !pw.xpacks.llm.parsers.DoclingParser
async_mode: "fully_async"
chunk: false
cache_strategy: !pw.udfs.DefaultCache {}
# Sets up the retriever factory for indexing and retrieving documents.
$retriever_factory: !pw.indexing.UsearchKnnFactory
reserved_space: 1000
embedder: $embedder
metric: !pw.indexing.USearchMetricKind.COS
# Manages the storage and retrieval of documents for the RAG template.
document_store: !pw.xpacks.llm.document_store.DocumentStore
docs: $sources
parser: $parser
splitter: $splitter
retriever_factory: $retriever_factory
# Change host and port of the webserver by uncommenting these lines
# host: "0.0.0.0"
# port: 8000
# By default, caching is enabled for UDFs with cache_strategy set.
# You can disable it by uncommenting the following line.
# persistence_mode: null
# You can also set persistence_mode to !pw.PersistenceMode.PERSISTING to enable persistence
# across restarts.
# By default, when enabled, Cache is stored in .Cache directory.
# You can customize the location by uncommenting and modifying the following lines:
# persistence_backend: !pw.persistence.Backend.filesystem
# path: ".Cache"
# If `terminate_on_error` is true then the program will terminate whenever any error is encountered.
# Defaults to false, uncomment the following line if you want to set it to true
# terminate_on_error: true
================================================
FILE: templates/document_indexing/docker-compose.yml
================================================
version: "3.8"
services:
pathway_vector_indexer:
build:
context: .
ports:
- "8000:8000"
environment:
OPENAI_API_KEY: "${OPENAI_API_KEY}"
volumes:
- "./files-for-indexing:/app/files-for-indexing"
streamlit_ui:
depends_on:
- pathway_vector_indexer
build:
context: https://github.com/pathway-labs/realtime-indexer-qa-chat.git
ports:
- "8501:8501"
environment:
OPENAI_API_KEY: "${OPENAI_API_KEY}"
PATHWAY_HOST: "pathway_vector_indexer"
PATHWAY_PORT: "8000"
================================================
FILE: templates/document_indexing/requirements.txt
================================================
python-dotenv~=1.0
================================================
FILE: templates/document_store_mcp_server/Dockerfile
================================================
FROM pathwaycom/pathway:latest
WORKDIR /app
RUN apt-get update \
&& apt-get install -y python3-opencv tesseract-ocr-eng \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
COPY requirements.txt .
RUN pip install -U --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8068
CMD ["python", "app.py"]
================================================
FILE: templates/document_store_mcp_server/README.md
================================================
Deploy with GCP |
Deploy with AWS |
Deploy with Azure |
Deploy with Render
# MCP Server with Realtime Document Indexing
This is a template for exposing a real-time document indexing pipeline powered by [Pathway](https://github.com/pathwaycom/pathway) as an Model Context Protocol (MCP) server.
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) is designed to standardize the way applications interact with large language models (LLMs). It serves as a bridge, much like a universal connector, enabling seamless integration between AI models and various data sources and tools. This protocol facilitates the creation of sophisticated AI workflows and agents, enhancing the capabilities of LLMs by connecting them with real-world data and functionalities.
The capabilities of the pipeline include:
- Real-time document indexing from Microsoft 365 SharePoint, Google Drive, or a local directory;
- Similarity search by user query;
- Filtering by the metadata according to the condition given in [JMESPath format](https://jmespath.org/);
- The documents are available from a standardized MCP server.
## Summary of the Pipeline
This example spawns an MCP server that has three tools:
- `retrieve_query` to perform similarity search on the indexed documents,
- `statistics_query` to get the basic stats about the indexer's health,
- `inputs_query` to retrieve the metadata of all files currently processed by the indexer.
You can get specification of those tools by querying the `list_tools` on the MCP server.
## How It Works
This pipeline uses several Pathway connectors to read the data from the local drive, Google Drive, or Microsoft SharePoint sources. It allows you to poll the changes with low latency and to do the modifications tracking. So, if something changes in the tracked files, the corresponding change is reflected in the internal collections. The contents are read into a single Pathway Table as binary objects.
After that, those binary objects are parsed with the [Docling](https://www.docling.ai/) library and split into chunks. With the usage of the [SentenceTransformer](https://www.sbert.net/) embedder, the pipeline embeds the obtained chunks.
Finally, the embeddings are indexed with the capabilities of Pathway's machine-learning library. The user can then query the created index by connecting to the MCP server using an MCP client.
## Pipeline Organization
This folder contains several objects:
- `app.py`, the pipeline code using Pathway and written in Python;
- `app.yaml`, the file containing configuration of the pipeline, like embedding model, sources, or the server address;
- `requirements.txt`, the textfile denoting the pip dependencies for running this pipeline. It can be passed to `pip install -r requirements.txt` to install everything that is needed to launch the pipeline locally;
- `Dockerfile`, the Docker configuration for running the pipeline in the container;
- `docker-compose.yml`, the docker-compose configuration for running the pipeline along with the chat UI;
- `files-for-indexing/`, a folder with exemplary files that can be used for the test runs.
## Customizing the pipeline
The code can be modified by changing the `app.yaml` configuration file. To read more about YAML files used in Pathway templates, read [our guide](https://pathway.com/developers/templates/configure-yaml).
In the `app.yaml` file we define:
- input connectors
- embedder
- index
and any of these can be replaced or, if no longer needed, removed. For components that can be used check
Pathway [LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview), or you can implement your own.
Here some examples of what can be modified.
### Embedding Model
By default this template uses locally run model `mixedbread-ai/mxbai-embed-large-v1`. If you wish, you can replace this with any other model, by changing
`$embedder` in `app.yaml`. For example, to use OpenAI embedder, set:
```yaml
$embedder: !pw.xpacks.llm.embedders.OpenAIEmbedder
model: "text-embedding-3-small"
cache_strategy: !pw.udfs.DefaultCache {}
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy {}
```
If you choose to use a provider, that requires API key, remember to set appropriate environmental values (you can also set them in the `.env` file) - e.g. for using OpenAI embedders, set the `OPENAI_API_KEY` variable.
### Webserver
You can configure the name, the host and the port of the MCP server.
Here is the default configuration:
```yaml
mcp_http: !pw.xpacks.llm.mcp_server.PathwayMcp
name: "Streamable MCP Server"
transport: "streamable-http"
host: "localhost"
port: 8068
serve:
- $document_store
```
### Cache
You can configure whether you want to enable cache or persistence, to avoid repeated API accesses, and where the cache is stored.
Default values:
```yaml
persistence_mode: !pw.PersistenceMode.UDF_CACHING
persistence_backend: !pw.persistence.Backend.filesystem
path: ".Cache"
```
### Data sources
You can configure the data sources by changing `$sources` in `app.yaml`.
You can add as many data sources as you want. You can have several sources of the same kind, for instance, several local sources from different folders.
The sections below describe how to configure local, Google Drive and Sharepoint source, and you can check the examples of YAML configuration in our [user guide](https://pathway.com/developers/templates/yaml-snippets/data-sources-examples/). While these are not described in this Section, you can also use any input [connector](https://pathway.com/developers/user-guide/connecting-to-data/connectors) from Pathway package.
By default, the app uses a local data source to read documents from the `files-from-indexing` folder.
#### Local Data Source
The local data source is configured by using map with tag `!pw.io.fs.read`. Then set `path` to denote the path to a folder with files to be indexed.
#### Google Drive Data Source
The Google Drive data source is enabled by using map with tag `!pw.io.gdrive.read`. The map must contain two main parameters:
- `object_id`, containing the ID of the folder that needs to be indexed. It can be found from the URL in the web interface, where it's the last part of the address. For example, the publicly available demo folder in Google Drive has the URL `https://drive.google.com/drive/folders/1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`. Consequently, the last part of this address is `1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`, hence this is the `object_id` you would need to specify.
- `service_user_credentials_file`, containing the path to the credentials files for the Google [service account](https://cloud.google.com/iam/docs/service-account-overview). To get more details on setting up the service account and getting credentials, you can also refer to [this tutorial](https://pathway.com/developers/user-guide/connectors/gdrive-connector#setting-up-google-drive).
Besides, to speed up the indexing process you may want to specify the `refresh_interval` parameter, denoted by an integer number of seconds. It corresponds to the frequency between two sequential folder scans. If unset, it defaults to 30 seconds.
For the full list of the available parameters, please refer to the Google Drive connector [documentation](https://pathway.com/developers/api-docs/pathway-io/gdrive#pathway.io.gdrive.read).
#### SharePoint Data Source
This data source requires Scale or Enterprise [license key](https://pathway.com/pricing) - you can obtain free Scale key on [Pathway website](https://pathway.com/get-license).
To use it, set the map tag to be `!pw.xpacks.connectors.sharepoint.read`, and then provide values of `url`, `tenant`, `client_id`, `cert_path`, `thumbprint` and `root_path`. To read about the meaning of these arguments, check the Sharepoint connector [documentation](https://pathway.com/developers/api-docs/pathway-xpacks-sharepoint#pathway.xpacks.connectors.sharepoint.read).
## Running the Template
### Pathway License Key
Pathway MCP Server requires a Pathway license key, so before you run the template, you need to set the license key. This template is available for free via [Pathway Scale](https://pathway.com/features), for which you can get the license key [here](https://pathway.com/user/license). Once you have your license key, create a `.env` file, in which set `PATHWAY_LICENSE_KEY` to your license key - see `.env.example` for an example of `.env` file.
### Locally
This template can be run locally by executing `python app.py` in this directory. Please note that the local run requires the `Pathway` library and other dependencies to be installed. It can be done with a pip command:
```bash
pip install pathway[all]
pip install -r requirements.txt
```
### With Docker`.
To run jointly the MCP server with real-time document indexint, please execute:
```bash
docker compose up --build
```
The `docker-compose.yml` file declares a [volume bind mount](https://docs.docker.com/reference/cli/docker/container/run/#volume) that makes changes to files under `files-for-indexing/` made on your host computer visible inside the docker container. If the index does not react to file changes, please check that the bind mount works
by running `docker compose exec pathway_vector_indexer ls -l /app/files-for-indexing/` and verifying that all files are visible.
## Querying the Template with an MCP client
To test your examples, you need an MCP client which will connect to your MCP server. You can use the fastmcp package to define a client as follows:
```python
import asyncio
from fastmcp import Client
# Change the URL if you change the default values in the app.yaml
PATHWAY_MCP_URL = "http://localhost:8068/mcp/"
client = Client(PATHWAY_MCP_URL)
async def main():
async with client:
tools = await client.list_tools()
print(tools)
async with client:
result = await client.call_tool(
name="retrieve_query",
arguments={"query": "How to create a webserver in Pathway?", "k": 3},
)
print(result)
asyncio.run(main())
```
You can list the different tools available in the MCP server using the `list_tools` of the client. To access a given tool, you can use the method call_tool, with the name and arguments parameters. The arguments should be a dict of the different values: in this case, the `retrieve_query` tool has two required arguments: `query` and `k`.
## Using MCP server in Claude Desktop
To use MCP server created by this template in Claude Desktop, follow the [guide in Pathway's documentation](https://pathway.com/developers/user-guide/llm-xpack/pathway-mcp-claude-desktop).
## Adding Files to Index
To test index updates, simply add more files to the `files-for-indexing` folder if the local data source is used.
If you are using Google Drive, simply upload your files in the folder configured in the `sources_configuration.yaml` file.
Then you can use the similarity search and stats endpoints, provided below.
================================================
FILE: templates/document_store_mcp_server/__init__.py
================================================
================================================
FILE: templates/document_store_mcp_server/app.py
================================================
import logging
import pathway as pw
from dotenv import load_dotenv
from pathway.xpacks.llm.mcp_server import PathwayMcp
from pydantic import BaseModel, ConfigDict
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
load_dotenv()
class App(BaseModel):
mcp_http: PathwayMcp
host: str = "0.0.0.0"
port: int = 8000
terminate_on_error: bool = False
persistence_backend: pw.persistence.Backend | None = None
persistence_mode: pw.PersistenceMode | None = pw.PersistenceMode.UDF_CACHING
def run(self) -> None:
if self.persistence_mode is not None:
if self.persistence_backend is None:
persistence_backend = pw.persistence.Backend.filesystem("./Cache")
else:
persistence_backend = self.persistence_backend
persistence_config = pw.persistence.Config(
persistence_backend,
persistence_mode=self.persistence_mode,
)
else:
persistence_config = None
pw.run(
terminate_on_error=self.terminate_on_error,
persistence_config=persistence_config,
monitoring_level=pw.MonitoringLevel.NONE,
)
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
if __name__ == "__main__":
with open("app.yaml") as f:
config = pw.load_yaml(f)
print(config)
app = App(**config)
app.run()
================================================
FILE: templates/document_store_mcp_server/app.yaml
================================================
# This YAML configuration file is used to set up and configure the Document indexing RAG template.
# It defines various components such as data sources, embedders, splitters, parsers, and retrievers.
# Each section is configured to specify how the template should process and handle data for answering the queries.
# You can learn more about the YAML syntax here: https://pathway.com/developers/templates/configure-yaml
# $sources defines the data sources used to read the data which will be indexed in the RAG.
# You can learn more how to configure data sources here:
# https://pathway.com/developers/templates/yaml-examples/data-sources-examples
$sources:
# File System connector, reading data locally.
- !pw.io.fs.read
path: files-for-indexing
format: binary
with_metadata: true
# Uncomment to use the SharePoint connector
# - !pw.xpacks.connectors.sharepoint.read
# url: $SHAREPOINT_URL
# tenant: $SHAREPOINT_TENANT
# client_id: $SHAREPOINT_CLIENT_ID
# cert_path: sharepointcert.pem
# thumbprint: $SHAREPOINT_THUMBPRINT
# root_path: $SHAREPOINT_ROOT
# with_metadata: true
# refresh_interval: 30
# Uncomment to use the Google Drive connector
# - !pw.io.gdrive.read
# object_id: $DRIVE_ID
# service_user_credentials_file: gdrive_indexer.json
# file_name_pattern:
# - "*.pdf"
# - "*.pptx"
# object_size_limit: null
# with_metadata: true
# refresh_interval: 30
# Model used for embedding
$embedding_model: "mixedbread-ai/mxbai-embed-large-v1"
# Specifies the embedder model for converting text into embeddings.
$embedder: !pw.xpacks.llm.embedders.SentenceTransformerEmbedder
model: $embedding_model
call_kwargs:
show_progress_bar: False
# Defines the splitter settings for dividing text into smaller chunks.
$splitter: !pw.xpacks.llm.splitters.TokenCountSplitter
max_tokens: 400
# Configures the parser for processing and extracting information from documents.
$parser: !pw.xpacks.llm.parsers.DoclingParser
async_mode: "fully_async"
chunk: false
cache_strategy: !pw.udfs.DefaultCache {}
# Sets up the retriever factory for indexing and retrieving documents.
$retriever_factory: !pw.indexing.UsearchKnnFactory
reserved_space: 1000
embedder: $embedder
metric: !pw.indexing.USearchMetricKind.COS
# Manages the storage and retrieval of documents for the RAG template.
$document_store: !pw.xpacks.llm.document_store.DocumentStore
docs: $sources
parser: $parser
splitter: $splitter
retriever_factory: $retriever_factory
# Streamable MCP server, can be proxied
mcp_http: !pw.xpacks.llm.mcp_server.PathwayMcp
name: "Streamable MCP Server"
transport: "streamable-http"
host: "0.0.0.0"
port: 8068
serve:
- $document_store
# By default, caching is enabled for UDFs with cache_strategy set.
# You can disable it by uncommenting the following line.
# persistence_mode: null
# You can also set persistence_mode to !pw.PersistenceMode.PERSISTING to enable persistence
# across restarts.
# By default, when enabled, Cache is stored in .Cache directory.
# You can customize the location by uncommenting and modifying the following lines:
# persistence_backend: !pw.persistence.Backend.filesystem
# path: ".Cache"
# If `terminate_on_error` is true then the program will terminate whenever any error is encountered.
# Defaults to false, uncomment the following line if you want to set it to true
# terminate_on_error: true
================================================
FILE: templates/document_store_mcp_server/docker-compose.yml
================================================
version: "3.8"
services:
pathway_mcp_server:
build:
context: .
ports:
- "8068:8068"
environment:
PATHWAY_LICENSE_KEY: $PATHWAY_LICENSE_KEY
volumes:
- "./files-for-indexing:/app/files-for-indexing"
================================================
FILE: templates/document_store_mcp_server/requirements.txt
================================================
python-dotenv~=1.0
================================================
FILE: templates/drive_alert/Dockerfile
================================================
FROM pathwaycom/pathway:latest
WORKDIR /app
COPY . .
EXPOSE 8080
CMD ["python", "app.py"]
================================================
FILE: templates/drive_alert/README.md
================================================
# Pathway + LLM + Slack notification: RAG App with real-time alerting when answers change in documents
Microservice for a context-aware alerting ChatGPT assistant.
This demo is very similar to the `alert` example, the only difference is the data source (Google Drive)
For the demo, alerts are sent to Slack (you need to provide `slack_alert_channel_id` and `slack_alert_token`),
you can either put these env variables in .env file,
or create env variables in the terminal (i.e. export in bash).
The program then starts a REST API endpoint serving queries about Google Docs stored in a
Google Drive folder.
We can create notifications by asking from Streamlit or sending query to API stating we want to be notified.
One example would be `Tell me and alert about the start date of the campaign for Magic Cola`
## How Does It Work?
First, Pathway connects to Google Drive, extracts all documents, splits them into chunks, turns them into
vectors using OpenAI embedding service, and store in a nearest neighbor index.
Each query text is first turned into a vector, then relevant document chunks are found
using the nearest neighbor index. A prompt is built from the relevant chunk
and sent to the OpenAI GPT3.5 chat service for processing and answering.
After an initial answer is provided, Pathway monitors changes to documents and selectively
re-triggers potentially affected queries. If the new answer is significantly different from
the previously presented one, a new notification is created.
## How to run the project
Before running the app, you will need to give the app access to the Google Drive folder, we follow the steps below.
In order to access files on your Google Drive from the Pathway app, you will need a Google Cloud project and a service user.
### Create a new project in the Google API console:
- Go to [https://console.cloud.google.com/projectcreate](https://console.cloud.google.com/projectcreate) and create new project
- Enable Google Drive API by going to [https://console.cloud.google.com/apis/library/drive.googleapis.com](https://console.cloud.google.com/apis/library/drive.googleapis.com), make sure the newly created project is selected in the top left corner
- Configure consent screen:
- Go to [https://console.cloud.google.com/apis/credentials/consent](https://console.cloud.google.com/apis/credentials/consent)
- If using a private Gmail, select "External", and go next.
- Fill required parameters: application name, user support, and developer email (your email is fine)
- On the next screen click "Add or remove scopes" search for "drive.readonly" and select this scope
- Save and click through other steps
- Create service user:
- Go to [https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)
- Click "+ Create credentials" and create a service account
- Name the service user and click through the next steps
- Generate service user key:
- Once more go to [https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials) and click on your newly created user (under Service Accounts)
- Go to "Keys", click "Add key" -> "Create new key" -> "JSON"
A JSON file will be saved to your computer.
Rename this JSON file to `secrets.json` and put it under `templates/drive_alert` next to `app.py` so that it is easily reachable from the app.
You can now share desired Google Drive resources with the created user.
Note the email ending with `gserviceaccount.com` we will share the folder with this email.
Once you've done it, you will need an ID of some file or directory. You can obtain it manually by right-clicking on the file -> share -> copy link. It will be part of the URL.
[https://drive.google.com/file/d/[FILE_ID]/view?usp=drive_link](https://drive.google.com/file/d/%5BFILE_ID%5D/view?usp=drive_link)
For folders,
First, right-click on the folder and click share, link will be of the format: [https://drive.google.com/drive/folders/[folder_id]?usp=drive_link](https://drive.google.com/drive/folders/%7Bfolder_id%7D?usp=drive_link)
Copy the folder_id from the URL.
Second, click on share and share the folder with the email ending with `gserviceaccount.com`
### Setup Slack notifications:
For this demo, Slack notifications are optional and notifications will be printed if no Slack API keys are provided. See: [Slack Apps](https://api.slack.com/apps) and [Getting a token](https://api.slack.com/tutorials/tracks/getting-a-token).
Your Slack application will need at least `chat:write.public` scope enabled.
### Setup environment:
Set your env variables in the .env file placed in this directory.
```bash
OPENAI_API_KEY=sk-...
SLACK_ALERT_CHANNEL_ID= # If unset, alerts will be printed to the terminal
SLACK_ALERT_TOKEN=
FILE_OR_DIRECTORY_ID= # file or folder ID that you want to track that we have retrieved earlier
GOOGLE_CREDS=./secrets.json # Default location of Google Drive authorization secrets
PATHWAY_PERSISTENT_STORAGE= # Set this variable if you want to use caching
```
### Run with Docker
To run jointly the Alert pipeline and a simple UI execute:
```bash
docker compose up --build
```
Then, the UI will run at http://0.0.0.0:8501 by default. You can access it by following this URL in your web browser.
The `docker-compose.yml` file declares a [volume bind mount](https://docs.docker.com/reference/cli/docker/container/run/#volume) that makes changes to files under `data/` made on your host computer visible inside the docker container. The files in `data/live` are indexed by the pipeline - you can paste new files there and they will impact the computations.
### Run manually
Alternatively, you can run each service separately.
Make sure you have installed poetry dependencies with `--extras unstructured`.
```bash
poetry install --with examples --extras unstructured
```
Then run:
```bash
poetry run python app.py
```
If all dependencies are managed manually rather than using poetry, you can alternatively use:
```bash
python app.py
```
To run the Streamlit UI, run:
```bash
streamlit run ui/server.py --server.port 8501 --server.address 0.0.0.0
```
### Querying the pipeline
To create alerts, you can call the REST API:
```bash
curl --data '{
"user": "user",
"query": "When does the magic cola campaign start? Alert me if the start date changes."
}' http://localhost:8080/ | jq
```
or access the Streamlit UI at `0.0.0.0:8501`.
================================================
FILE: templates/drive_alert/__init__.py
================================================
from .app import run
__all__ = ["run"]
================================================
FILE: templates/drive_alert/app.py
================================================
"""
Microservice for a context-aware alerting ChatGPT assistant.
This demo is very similar to the `alert` example, the only difference is the data source (Google Drive)
For the demo, alerts are sent to Slack (you need to provide `slack_alert_channel_id` and `slack_alert_token`),
you can either put these env variables in .env file under llm-app directory,
or create env variables in the terminal (i.e. export in bash).
The program then starts a REST API endpoint serving queries about Google Docs stored in a
Google Drive folder.
We can create notifications by asking from Streamlit or sending query to API stating we want to be notified.
One example would be `Tell me and alert about the start date of the campaign for Magic Cola`
How Does It Work?
First, Pathway connects to Google Drive, extracts all documents, splits them into chunks, turns them into
vectors using OpenAI embedding service, and store in a nearest neighbor index.
Each query text is first turned into a vector, then relevant document chunks are found
using the nearest neighbor index. A prompt is built from the relevant chunk
and sent to the OpenAI GPT3.5 chat service for processing and answering.
After an initial answer is provided, Pathway monitors changes to documents and selectively
re-triggers potentially affected queries. If the new answer is significantly different from
the previously presented one, a new notification is created.
Please check the README.md in this directory for how-to-run instructions.
"""
import asyncio
import os
import dotenv
import pathway as pw
from pathway.stdlib.ml.index import KNNIndex
from pathway.xpacks.llm.embedders import OpenAIEmbedder
from pathway.xpacks.llm.llms import OpenAIChat, prompt_chat_single_qa
from pathway.xpacks.llm.parsers import UnstructuredParser
from pathway.xpacks.llm.splitters import TokenCountSplitter
# To use advanced features with Pathway Scale, get your free license key from
# https://pathway.com/features and paste it below.
# To use Pathway Community, comment out the line below.
pw.set_license_key("demo-license-key-with-telemetry")
dotenv.load_dotenv()
class DocumentInputSchema(pw.Schema):
doc: str
class QueryInputSchema(pw.Schema):
query: str
user: str
# Helper Functions
@pw.udf
def build_prompt(documents, query):
docs_str = "\n".join(
[f"Doc-({idx}) -> {doc}" for idx, doc in enumerate(documents[::-1])]
)
prompt = f"""Given a set of documents, answer user query. If answer is not in docs, say it cant be inferred.
Docs: {docs_str}
Query: '{query}'
Final Response:"""
return prompt
@pw.udf
def build_prompt_check_for_alert_request_and_extract_query(query: str) -> str:
prompt = f"""Evaluate the user's query and identify if there is a request for notifications on answer alterations:
User Query: '{query}'
Respond with 'Yes' if there is a request for alerts, and 'No' if not,
followed by the query without the alerting request part.
Examples:
"Tell me about windows in Pathway" => "No. Tell me about windows in Pathway"
"Tell me and alert about windows in Pathway" => "Yes. Tell me about windows in Pathway"
"""
return prompt
@pw.udf
def split_answer(answer: str) -> tuple[bool, str]:
alert_enabled = "yes" in answer[:3].lower()
true_query = answer[3:].strip(' ."')
return alert_enabled, true_query
def build_prompt_compare_answers(new: str, old: str) -> str:
prompt = f"""
Are the two following responses deviating?
Answer with Yes or No.
First response: "{old}"
Second response: "{new}"
"""
return prompt
def make_query_id(user, query) -> str:
return str(hash(query + user))
@pw.udf
def construct_notification_message(query: str, response: str) -> str:
return f'New response for question "{query}":\n{response}'
@pw.udf
def construct_message(response, alert_flag, metainfo=None):
if alert_flag:
if metainfo:
response += "\n" + str(metainfo)
return response + "\n\n🔔 Activated"
return response
def decision_to_bool(decision: str) -> bool:
return "yes" in decision.lower()
def run(
*,
object_id=os.environ.get("FILE_OR_DIRECTORY_ID", ""),
api_key: str = os.environ.get("OPENAI_API_KEY", ""),
host: str = os.environ.get("PATHWAY_REST_CONNECTOR_HOST", "0.0.0.0"),
port: int = int(os.environ.get("PATHWAY_REST_CONNECTOR_PORT", "8080")),
embedder_locator: str = "text-embedding-ada-002",
embedding_dimension: int = 1536,
model_locator: str = "gpt-3.5-turbo",
max_tokens: int = 400,
temperature: float = 0.0,
slack_alert_channel_id=os.environ.get("SLACK_ALERT_CHANNEL_ID", ""),
slack_alert_token=os.environ.get("SLACK_ALERT_TOKEN", ""),
service_user_credentials_file=os.environ.get(
"GOOGLE_CREDS", "templates/drive_alert/secrets.json"
),
**kwargs,
):
# Part I: Build index
embedder = OpenAIEmbedder(
api_key=api_key,
model=embedder_locator,
retry_strategy=pw.asynchronous.FixedDelayRetryStrategy(),
cache_strategy=pw.asynchronous.DefaultCache(),
)
# We start building the computational graph. Each pathway variable represents a
# dynamically changing table.
# The files table contains contents of documents in Google Drive.
# Pathway automatically tracks changes to files and propagates these changes through
# following computations.
# Other Pathway connectors can be used as well - notably:
# - pw.io.fs.read to load and track changes to the local drive and
# - pw.io.s3.read to use an S3-compatible storage
files = pw.io.gdrive.read(
object_id=object_id,
service_user_credentials_file=service_user_credentials_file,
refresh_interval=30, # interval between fetch operations in seconds, lower this for more responsiveness
)
parser = UnstructuredParser()
documents = files.select(texts=parser(pw.this.data))
documents = documents.flatten(pw.this.texts)
documents = documents.select(texts=pw.this.texts[0])
splitter = TokenCountSplitter()
documents = documents.select(
chunks=splitter(pw.this.texts, min_tokens=40, max_tokens=120)
)
documents = documents.flatten(pw.this.chunks)
documents = documents.select(chunk=pw.this.chunks[0])
enriched_documents = documents + documents.select(data=embedder(pw.this.chunk))
# The index is updated each time a file changes.
index = KNNIndex(
enriched_documents.data, enriched_documents, n_dimensions=embedding_dimension
)
# Part II: receive queries, detect intent and prepare cleaned query
# The rest_connector returns a table of all queries under processing
query, response_writer = pw.io.http.rest_connector(
host=host,
port=port,
schema=QueryInputSchema,
autocommit_duration_ms=50,
delete_completed_queries=False,
)
model = OpenAIChat(
api_key=api_key,
model=model_locator,
temperature=temperature,
max_tokens=max_tokens,
retry_strategy=pw.asynchronous.FixedDelayRetryStrategy(),
cache_strategy=pw.asynchronous.DefaultCache(),
)
# Pre-process the queries:
# - detect alerting intent
# - then embed the query for nearest neighbor retrieval
query += query.select(
prompt=build_prompt_check_for_alert_request_and_extract_query(query.query)
)
query += query.select(
tupled=split_answer(
model(
prompt_chat_single_qa(pw.this.prompt),
max_tokens=100,
)
),
)
query = query.select(
pw.this.user,
alert_enabled=pw.this.tupled[0],
query=pw.this.tupled[1],
)
query += query.select(
data=embedder(pw.this.query),
query_id=pw.apply(make_query_id, pw.this.user, pw.this.query),
)
# Part III: respond to queries
# The context is a dynamic table: Pathway updates it each time:
# - a new query arrives
# - a source document is changed significantly enough to change the set of
# nearest neighbors
query_context = query + index.get_nearest_items(query.data, k=3).select(
documents_list=pw.this.chunk
).with_universe_of(query)
# then we answer the queries using retrieved documents
prompt = query_context.select(
pw.this.query_id,
pw.this.query,
pw.this.alert_enabled,
prompt=build_prompt(pw.this.documents_list, pw.this.query),
)
responses = prompt.select(
pw.this.query_id,
pw.this.query,
pw.this.alert_enabled,
response=model(
prompt_chat_single_qa(pw.this.prompt),
),
)
output = responses.select(
result=construct_message(pw.this.response, pw.this.alert_enabled)
)
# and send the answers back to the asking users
response_writer(output)
# Part IV: send alerts about responses which changed significantly.
# However, for the queries with alerts the processing continues
# whenever the set of documents retrieved for a query changes,
# the table of responses is updated.
responses = responses.filter(pw.this.alert_enabled)
def acceptor(new: str, old: str) -> bool:
if new == old:
return False
# TODO: clean after udfs can be used as common functions
prompt = [dict(role="system", content=build_prompt_compare_answers(new, old))]
decision = asyncio.run(model.__wrapped__(prompt, max_tokens=20))
return decision_to_bool(decision)
# Each update is compared with the previous one for deduplication
deduplicated_responses = pw.stateful.deduplicate(
responses,
col=responses.response,
acceptor=acceptor,
instance=responses.query_id,
)
# Significant alerts are sent to the user
alerts = deduplicated_responses.select(
message=construct_notification_message(pw.this.query, pw.this.response)
)
pw.io.slack.send_alerts(alerts.message, slack_alert_channel_id, slack_alert_token)
# Finally, we execute the computation graph
pw.run(monitoring_level=pw.MonitoringLevel.NONE)
if __name__ == "__main__":
run()
================================================
FILE: templates/drive_alert/docker-compose.yml
================================================
version: "3.8"
services:
pathway:
build:
context: .
ports:
- "8080:8080"
environment:
OPENAI_API_KEY:
PATHWAY_PERSISTENT_STORAGE:
streamlit_ui:
depends_on:
- pathway
build:
context: ./ui
ports:
- "8501:8501"
environment:
PATHWAY_REST_CONNECTOR_HOST: "pathway"
================================================
FILE: templates/drive_alert/ui/Dockerfile
================================================
FROM python:3.11
WORKDIR /app
RUN pip install streamlit python-dotenv
COPY . .
EXPOSE 8501
CMD ["streamlit", "run", "server.py", "--server.port", "8501", "--server.address", "0.0.0.0"]
================================================
FILE: templates/drive_alert/ui/server.py
================================================
import os
import requests
import streamlit as st
from dotenv import load_dotenv
api_host = "localhost"
api_port = 8080
load_dotenv()
api_host = os.environ.get("PATHWAY_REST_CONNECTOR_HOST", "127.0.0.1")
api_port = int(os.environ.get("PATHWAY_REST_CONNECTOR_PORT", 8080))
with st.sidebar:
st.markdown("## How to query your data\n")
st.markdown(
"""Enter your question, optionally
ask to be alerted.\n"""
)
st.markdown(
"Example: 'When does the magic cola campaign start? Alert me if the start date changes'",
)
st.markdown(
"""[View the source code on GitHub](
https://github.com/pathwaycom/llm-app/templates/drive_alert/app.py)"""
)
st.markdown("## Current Alerts:\n")
# Streamlit UI elements
st.title("Google Drive notifications with LLM")
prompt = st.text_input("How can I help you today?")
# prompt = st.chat_input("How can I help you today?")
# Initialize chat history
if "messages" not in st.session_state:
st.session_state.messages = []
# Display chat messages from history on app rerun
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# React to user input
if prompt:
# Display user message in chat message container
with st.chat_message("user"):
st.markdown(prompt)
# Add user message to chat history
st.session_state.messages.append({"role": "user", "content": prompt})
for message in st.session_state.messages:
if message["role"] == "user":
st.sidebar.text(f"📩 {message['content']}")
url = f"http://{api_host}:{api_port}/"
data = {"query": prompt, "user": "user"}
response = requests.post(url, json=data)
if response.status_code == 200:
response = response.json()
with st.chat_message("assistant"):
st.markdown(response)
st.session_state.messages.append({"role": "assistant", "content": response})
else:
st.error(f"Failed to send data. Status code: {response.status_code}")
================================================
FILE: templates/multimodal_rag/Dockerfile
================================================
FROM pathwaycom/pathway:latest
WORKDIR /app
RUN apt-get update \
&& apt-get install -y python3-opencv tesseract-ocr-eng \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
COPY requirements.txt .
RUN pip install -U --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]
================================================
FILE: templates/multimodal_rag/README.md
================================================
Deploy with GCP |
Deploy with AWS |
Deploy with Azure |
Deploy with Render
# Multimodal RAG with Pathway: Process your Financial Reports and Tables with GPT-4o
## **Overview**
This app template showcases how you can build a multimodal RAG application and launch a document processing pipeline that utilizes a vision language model like the `GPT-4o` for parsing. Pathway processes unstructured financial documents within specified directories, extracting and storing the information in a scalable in-memory index. This index is optimized for dynamic RAG, ensuring that search results are continuously updated as documents are modified or new files are added.
Using this approach, you can make your AI application run in permanent connection with your drive, in sync with your documents which include visually formatted elements: tables, charts, images, etc.
We specifically use `GPT-4o` to improve the table data extraction accuracy and demonstrate how this approach outperforms the industry-standard RAG toolkits.
In this showcase, we focused on the finance domain because financial documents often rely heavily on tables in various forms. This showcase highlights the limitations of traditional RAG setups, which struggle to answer questions based on table data. By contrast, our multimodal RAG approach excels in extracting accurate information from tables.
The following GIF shows a snippet from our experiments:

If you want to skip the explanations, you can directly find the code [here](#Running-the-app).
## Table of contents
This includes the technical details to the steps to create a REST Endpoint to run the dynamic RAG application via Docker and modify it for your use-cases.
- [Overview](#Overview)
- [Architecture](#Architecture)
- [Pipeline Organization](#Pipeline-Organization)
- [Customizing the pipeline](#Customizing-the-pipeline)
- [Running the app](#Running-the-app)
- [Conclusion](#Conclusion)
## Architecture
We use `GPT-4o` in two separate places in the flow of data:
- Extracting and understanding the tables inside the PDF
- Answering questions with the retrieved context

The architecture of this multimodal RAG application involves several key components:
- **Data Ingestion**: Ingests data from various sources like local folders, Google Drive, or SharePoint.
- **Document Parsing and Embedding**: Utilizes `DoclingParser` for parsing documents and `OpenAIEmbedder` for embedding text. This includes handling and processing images within PDFs.
- **Document Store**: The `DocumentStoreServer` indexes parsed documents and retrieves relevant chunks for answering questions.
- **Question Answering**: Uses the `BaseRAGQuestionAnswerer` class to call `GPT-4o` for generating responses based on the retrieved context.
- **Server Setup**: Sets up a REST endpoint to serve the RAG application.
For more advanced RAG options, make sure to check out [rerankers](https://pathway.com/developers/api-docs/pathway-xpacks-llm/rerankers) and the [adaptive rag example](../adaptive_rag/).
## Pipeline Organization
This folder contains several objects:
- `app.py`, the main application code using Pathway and written in Python. It reads configuration from `app.yaml`, and runs a server answering queries to the defined pipeline.
- `app.yaml`, YAML configuration file, that defines components of the pipeline.
- `Dockerfile`, the Docker configuration for running the pipeline in a container. It includes instructions for installing dependencies and setting up the runtime environment.
- `requirements.txt`, the dependencies for the pipeline. This file can be passed to `pip install -r requirements.txt` to install everything needed to launch the pipeline locally.
- `.env`, a short environment variables configuration file where the OpenAI key must be stored. This file ensures secure handling of sensitive information.
- `data/`, a folder with exemplary files that can be used for test runs. It includes sample financial documents to demonstrate the pipeline's capabilities.
## Customizing the pipeline
The code can be modified by changing the `app.yaml` configuration file. To read more about YAML files used in Pathway templates, read [our guide](https://pathway.com/developers/user-guide/llm-xpack/yaml-templates).
In the `app.yaml` file we define:
- input connectors
- LLM
- embedder
- index
and any of these can be replaced or, if no longer needed, removed. For components that can be used check
Pathway [LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview), or you can implement your own.
You can also check our other templates - [Question Answering RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/question_answering_rag),
[Multimodal RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/multimodal_rag) or
[Private RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/private_rag). As all of these only differ
in the YAML configuration file, you can also use them as an inspiration for your custom pipeline.
Here some examples of what can be modified.
### LLM Model
This template by default uses two llm models - GPT-4.1-mini for answering queries and GPT-4o for parsing tables and images.
You can replace either of them with other Open AI models, like GPT-4.1 or GPT-5, but keep in mind that the model used for parsing needs to support image input.
You can find the whole list on their [models page](https://platform.openai.com/docs/models).
To change the model of the answering llm, you simply need to change the `model` in the `$llm` variable to the one you want to use, e.g. to use `GPT-5` set:
```yaml
$llm: !pw.xpacks.llm.llms.OpenAIChat
model: "gpt-5"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DefaultCache {}
temperature: 0
capacity: 8
```
You can also use different provider, by using different class from [Pathway LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview),
e.g. here is configuration for locally run Mistral model with Ollama.
```yaml
$llm: !pw.xpacks.llm.llms.LiteLLMChat
model: "ollama/mistral"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DiskCache
temperature: 0
top_p: 1
api_base: "http://localhost:11434"
```
You can also change LLM used for parsing in the same way, by changing `!parsing_llm` in `app.yaml`, just keep in mind to use a multimodal model.
### Webserver
You can configure the host and the port of the webserver.
Here is the default configuration:
```yaml
host: "0.0.0.0"
port: 8000
```
### Cache
You can configure whether you want to enable cache or persistence, to avoid repeated API accesses, and where the cache is stored.
Default values:
```yaml
persistence_mode: !pw.PersistenceMode.UDF_CACHING
persistence_backend: !pw.persistence.Backend.filesystem
path: ".Cache"
```
### Data sources
You can configure the data sources by changing `$sources` in `app.yaml`.
You can add as many data sources as you want. You can have several sources of the same kind, for instance, several local sources from different folders.
The sections below describe how to configure local, Google Drive and Sharepoint source, and you can check the examples of YAML configuration in our [user guide](https://pathway.com/developers/templates/yaml-snippets/data-sources-examples/). While these are not described in this Section, you can also use any input [connector](https://pathway.com/developers/user-guide/connecting-to-data/connectors) from Pathway package.
By default, the app uses a local data source to read documents from the `data` folder.
## Running the app
> Note: Recommended way of running the Pathway on Windows is Docker, refer to [Running with the Docker section](#with-docker).
First, make sure to install the requirements by running:
```bash
pip install -r requirements.txt -U
```
Then, create a `.env` file in this directory and put your API key with `OPENAI_API_KEY=sk-...`, or add the `api_key` argument to `OpenAIChat` and `OpenAIEmbedder`.
Then, simply run with `python app.py` in this directory.
### With Docker
First, make sure to have your OpenAI API key in the environment, you can create a `.env` file as mentioned above, or specify the `api_key` argument in the `OpenAIChat` and `OpenAIEmbedder`.
In order to let the pipeline get updated with each change in local files, you need to mount the `data` folder inside the docker. The following commands show how to do that.
The following commands will:
- mount the `data` folder inside the Docker
- build the image
- run the app and expose the port `8000`.
You can omit the ```-v `pwd`/data:/app/data``` part if you are not using local files as a data source.
```bash
# Make sure you are in the right directory.
cd templates/multimodal_rag/
# Build the image in this folder
docker build -t rag .
# Run the image, mount the `data` folder into image and expose the port `8000`
docker run -v `pwd`/data:/app/data -p 8000:8000 rag
```
## Querying the pipeline
Follow the [steps below](#running-the-app) to set up the service. This will create a REST endpoint on your selected host and port, running a service that is connected to your file folder, and ready to answer your questions. There are no extra dependencies.
In this demo, we run the service on localhost (`0.0.0.0:8000`). You can connect your own front end or application to this endpoint. Here, we test the service with `curl`.
First, let's check the files contained in your folder are currently indexed:
```bash
curl -X 'POST' 'http://0.0.0.0:8000/v2/list_documents' -H 'accept: */*' -H 'Content-Type: application/json'
```
This will return the list of files e.g. if you start with the [data folder](./data) provided in the demo, the answer will be as follows:
> `[{"modified_at": 1715765613, "owner": "berke", "path": "data/20230203_alphabet_10K.pdf", "seen_at": 1715768762}]`
In the default app setup, the connected folder is a local file folder. You can add more folders and file sources, such as [Google Drive](https://pathway.com/developers/user-guide/connectors/gdrive-connector#google-drive-connector) or [Sharepoint](https://pathway.com/developers/user-guide/connecting-to-data/connectors#tutorials), by adding a line of code to the template.
If you now add or remove files from your connected folder, you can repeat the request and see the index file list has been updated automatically. You can look into the logs of the service to see the progress of the indexing of new and modified files. PDF files of 100 pages should normally take under 10 seconds to sync, and the indexing parallelizes if multiple files are added at a single time.
Now, let's ask a question from one of the tables inside the report. In our tests, regular RAG applications struggled with the tables and couldn't answer to this question correctly.
```bash
curl -X 'POST' 'http://0.0.0.0:8000/v2/answer' -H 'accept: */*' -H 'Content-Type: application/json' -d '{
"prompt": "How much was Operating lease cost in 2021?"
}'
```
> `{"response": "$2,699 million"}`
This response was correct thanks to the initial LLM parsing step.
When we check the context that is sent to the LLM, we see that Pathway included the table in the context where as other RAG applications failed to include the table.
Let's try another one,
```bash
curl -X 'POST' 'http://0.0.0.0:8000/v2/answer' -H 'accept: */*' -H 'Content-Type: application/json' -d '{
"prompt": "What is the operating income for the fiscal year of 2022?"
}'
```
> `{"response": "$74,842 million"}`
Another example, let's ask a question that can be answered from the table on the 48th page of the PDF.
```bash
curl -X 'POST' 'http://0.0.0.0:8000/v2/answer' -H 'accept: */*' -H 'Content-Type: application/json' -d '{
"prompt": "How much was Marketable securities worth in 2021 in the consolidated balance sheets?"
}'
```
> `{"response": "$118,704 million"}`
Now, let's also fetch the context documents,
```bash
curl -X 'POST' 'http://0.0.0.0:8000/v2/answer' -H 'accept: */*' -H 'Content-Type: application/json' -d '{
"prompt": "How much was Operating lease cost in 2021?", "return_context_docs": true
}'
```
> `{"response": "$2,699 million", "context_docs": [{"text": "..."}, ...]`
Looking good!
## Conclusion
This showcase demonstrates setting up a powerful RAG pipeline with advanced table parsing capabilities, unlocking new finance use cases. While we've only scratched the surface, there's more to explore:
- Re-ranking: Prioritize the most relevant results for your specific query.
- Knowledge graphs: Leverage relationships between entities to improve understanding.
- Hybrid indexing: Combine different indexing strategies for optimal retrieval.
- Adaptive reranking: Iteratively enlarge the context for optimal accuracy, see [our example](../adaptive_rag/README.md).
Stay tuned for future examples exploring these advanced techniques with Pathway!
RAG applications are most effective when tailored to your specific use case. Here's how you can customize yours:
- Document parsers and splitters: Fine-tune how documents are processed and broken down for analysis.
- Indexing and retrieval strategies: Choose the most efficient approach for your data and search needs.
- User Interface (UI): Design a user-friendly interface that caters to your end users' workflows.
Ready to Get Started?
Let's discuss how we can help you build a powerful, customized RAG application. [Reach us here to talk or request a demo!](https://pathway.com/solutions/slides-ai-search?modal=requestdemo)
## Quick Links:
- [Pathway Developer Documentation](https://pathway.com/developers/user-guide/introduction/welcome)
- [Pathway App Templates](https://pathway.com/developers/templates)
- [Discord Community of Pathway](https://discord.gg/pathway)
- [Pathway Issue Tracker](https://github.com/pathwaycom/pathway/issues)
- [End-to-end dynamic RAG pipeline with Pathway](https://github.com/pathwaycom/llm-app/tree/main/templates/question_answering_rag)
- [Using Pathway as a retriever with LlamaIndex](https://docs.llamaindex.ai/en/stable/examples/retrievers/pathway_retriever/)
Make sure to drop a "Star" to our repositories if you found this resource helpful!
================================================
FILE: templates/multimodal_rag/app.py
================================================
import logging
from warnings import warn
import pathway as pw
from dotenv import load_dotenv
from pathway.xpacks.llm.question_answering import SummaryQuestionAnswerer
from pathway.xpacks.llm.servers import QASummaryRestServer
from pydantic import BaseModel, ConfigDict, InstanceOf
# To use advanced features with Pathway Scale, get your free license key from
# https://pathway.com/features and paste it below.
# To use Pathway Community, comment out the line below.
pw.set_license_key("demo-license-key-with-telemetry")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
load_dotenv()
class App(BaseModel):
question_answerer: InstanceOf[SummaryQuestionAnswerer]
host: str = "0.0.0.0"
port: int = 8000
with_cache: bool | None = None # deprecated
persistence_backend: pw.persistence.Backend | None = None
persistence_mode: pw.PersistenceMode | None = pw.PersistenceMode.UDF_CACHING
terminate_on_error: bool = False
def run(self) -> None:
server = QASummaryRestServer( # noqa: F841
self.host, self.port, self.question_answerer
)
if self.persistence_mode is None:
if self.with_cache is True:
warn(
"`with_cache` is deprecated. Please use `persistence_mode` instead.",
DeprecationWarning,
)
persistence_mode = pw.PersistenceMode.UDF_CACHING
else:
persistence_mode = None
else:
persistence_mode = self.persistence_mode
if persistence_mode is not None:
if self.persistence_backend is None:
persistence_backend = pw.persistence.Backend.filesystem("./Cache")
else:
persistence_backend = self.persistence_backend
persistence_config = pw.persistence.Config(
persistence_backend,
persistence_mode=persistence_mode,
)
else:
persistence_config = None
pw.run(
persistence_config=persistence_config,
terminate_on_error=self.terminate_on_error,
monitoring_level=pw.MonitoringLevel.NONE,
)
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
if __name__ == "__main__":
with open("app.yaml") as f:
config = pw.load_yaml(f)
app = App(**config)
app.run()
================================================
FILE: templates/multimodal_rag/app.yaml
================================================
# This YAML configuration file is used to set up and configure the Multimodal RAG template.
# It defines various components such as data sources, language models, embedders, splitters, parsers, and retrievers.
# Each section is configured to specify how the template should process and handle data for generating responses.
# You can learn more about the YAML syntax here: https://pathway.com/developers/templates/configure-yaml
# $sources defines the data sources used to read the data which will be indexed in the RAG.
# You can learn more how to configure data sources here:
# https://pathway.com/developers/templates/yaml-examples/data-sources-examples
$sources:
# File System connector, reading data locally.
- !pw.io.fs.read
path: data
format: binary
with_metadata: true
# Uncomment to use the SharePoint connector
# - !pw.xpacks.connectors.sharepoint.read
# url: $SHAREPOINT_URL
# tenant: $SHAREPOINT_TENANT
# client_id: $SHAREPOINT_CLIENT_ID
# cert_path: sharepointcert.pem
# thumbprint: $SHAREPOINT_THUMBPRINT
# root_path: $SHAREPOINT_ROOT
# with_metadata: true
# refresh_interval: 30
# Uncomment to use the Google Drive connector
# - !pw.io.gdrive.read
# object_id: $DRIVE_ID
# service_user_credentials_file: gdrive_indexer.json
# file_name_pattern:
# - "*.pdf"
# - "*.pptx"
# object_size_limit: null
# with_metadata: true
# refresh_interval: 30
# Configures the LLM model settings for generating responses.
# The list of available Pathway LLM wrappers is available here:
# https://pathway.com/developers/api-docs/pathway-xpacks-llm/llms
# You can learn more about those in our documentation:
# https://pathway.com/developers/templates/rag-customization/llm-chats
$llm: !pw.xpacks.llm.llms.OpenAIChat
model: "gpt-4.1-mini"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DefaultCache {}
temperature: 0
capacity: 8
async_mode: "fully_async"
# Specifies the embedder model for converting text into embeddings.
$embedder: !pw.xpacks.llm.embedders.OpenAIEmbedder
model: "text-embedding-3-small"
cache_strategy: !pw.udfs.DefaultCache {}
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy {}
# Defines the llm to be used for parsing images.
$parsing_llm: !pw.xpacks.llm.llms.OpenAIChat
model: "gpt-4o"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DefaultCache {}
async_mode: "fully_async"
# Configures the parser for processing and extracting information from documents.
$parser: !pw.xpacks.llm.parsers.DoclingParser
multimodal_llm: $parsing_llm
image_parsing_strategy: "llm"
table_parsing_strategy: "llm"
async_mode: "fully_async"
chunk: false
cache_strategy: !pw.udfs.DefaultCache {}
# Sets up the splitter for chunking the documents.
$splitter: !pw.xpacks.llm.splitters.TokenCountSplitter
max_tokens: 400
# Sets up the retriever factory for indexing and retrieving documents.
$retriever_factory: !pw.indexing.UsearchKnnFactory
reserved_space: 1000
embedder: $embedder
metric: !pw.indexing.USearchMetricKind.COS
# Manages the storage and retrieval of documents for the RAG template.
$document_store: !pw.xpacks.llm.document_store.DocumentStore
docs: $sources
parser: $parser
splitter: $splitter
retriever_factory: $retriever_factory
# Configures the question-answering component using the RAG approach.
question_answerer: !pw.xpacks.llm.question_answering.BaseRAGQuestionAnswerer
llm: $llm
indexer: $document_store
# You can set the number of documents to be included as the context of the query
# search_topk: 6
# You can use your own prompt for querying.
# For that set prompt_template to string with `{query}` used as a placeholder for the question,
# and `{context}` as a placeholder for context documents.
# prompt_template: "Given these documents: {context}, please answer the question: {query}"
# Change host and port of the webserver by uncommenting these lines
# host: "0.0.0.0"
# port: 8000
# By default, caching is enabled for UDFs with cache_strategy set.
# You can disable it by uncommenting the following line.
# persistence_mode: null
# You can also set persistence_mode to !pw.PersistenceMode.PERSISTING to enable persistence
# across restarts.
# By default, when enabled, Cache is stored in .Cache directory.
# You can customize the location by uncommenting and modifying the following lines:
# persistence_backend: !pw.persistence.Backend.filesystem
# path: ".Cache"
# If `terminate_on_error` is true then the program will terminate whenever any error is encountered.
# Defaults to false, uncomment the following line if you want to set it to true
# terminate_on_error: true
================================================
FILE: templates/multimodal_rag/requirements.txt
================================================
pathway[all]
python-dotenv~=1.0
mpmath~=1.3
================================================
FILE: templates/private_rag/Dockerfile
================================================
FROM pathwaycom/pathway:latest
WORKDIR /app
RUN apt-get update \
&& apt-get install -y python3-opencv tesseract-ocr-eng \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
COPY requirements.txt .
RUN pip install -U --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]
================================================
FILE: templates/private_rag/README.md
================================================
Deploy with GCP |
Deploy with AWS |
Deploy with Azure |
Deploy with Render
# Fully private RAG with Pathway
## **Overview**
Retrieval-Augmented Generation (RAG) is a powerful method for answering questions using a private knowledge database. Ensuring data security is essential, especially for sensitive information like trade secrets, confidential IP, GDPR-protected data, and internal documents. This showcase demonstrates setting up a private RAG pipeline with adaptive retrieval using Pathway, Mistral, and Ollama. The provided code deploys this adaptive RAG technique with Pathway, ensuring no API access or data leaves the local machine.
The app utilizes modules under `pathway.xpacks.llm`. The `BaseRAGQuestionAnswerer` class is the foundation for building RAG applications with the Pathway vector store and xpack components, enabling a quick start with RAG applications.
This example uses `AdaptiveRAGQuestionAnswerer`, an extension of `BaseRAGQuestionAnswerer` with adaptive retrieval. For more on building and deploying RAG applications with Pathway, including containerization, refer to the demo on question answering.
The application responds to requests at the `/v2/answer` endpoint. The `answer_query` function takes the `pw_ai_queries` table as input, containing prompts and other arguments from the post request. This table's data is used to call the adaptive retrieval logic.
The `AdaptiveRAGQuestionAnswerer` implementation under `pathway.xpacks.llm.question_answering` builds a RAG app with the Pathway vector store and components. It supports two question answering strategies, short (concise) and long (detailed) responses, set during the post request. It allows LLM agnosticity, giving the freedom to choose between proprietary or open-source LLMs. It adapts the number of chunks used as a context, starting with `n_starting_documents` chunks and increasing until an answer is found.
To learn more about building & deploying RAG applications with Pathway, including containerization, refer to [demo question answering](../question_answering_rag/README.md).
## Table of contents
This includes the technical details to the steps to create a REST Endpoint to run the application via Docker and modify it for your use-cases.
- [Overview](#Overview)
- [Architecture](#Architecture)
- [Deploying and using a local LLM](#Deploying-and-using-a-local-LLM)
- [Running the app](#Running-the-app)
- [Querying the app/pipeline](#Querying-the-app/pipeline)
- [Modifying the code](#Modifying-the-code)
- [Conclusion](#Conclusion)
## Architecture

The architecture consists of two connected technology bricks, which will run as services on your machine:
- Pathway brings support for real-time data synchronization pipelines out of the box, and the possibility of secure private document handling with enterprise connectors for synchronizing Sharepoint and Google Drive incrementally. The Pathway service you'll run performs live document indexing pipeline, and will use Pathway’s built-in vector store.
- The language model you use will be a Mistral 7B, which you will locally deploy as an Ollama service. This model was chosen for its performance and compact size.
## Customizing the pipeline
The code can be modified by changing the `app.yaml` configuration file. To read more about YAML files used in Pathway templates, read [our guide](https://pathway.com/developers/templates/configure-yaml).
In the `app.yaml` file we define:
- input connectors
- LLM
- embedder
- index
and any of these can be replaced or, if no longer needed, removed. For components that can be used check
Pathway [LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview), or you can implement your own.
You can also check our other templates - [Question Answering RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/question_answering_rag),
[Multimodal RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/multimodal_rag) or
[Private RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/private_rag). As all of these only differ
in the YAML configuration file, you can also use them as an inspiration for your custom pipeline.
Here some examples of what can be modified.
### LLM Model
This template is prepared to run by default locally. However, the pipeline is LLM model agnostic, so you can change them to use other locally deployed model, or even
use LLM model available through API calls. For discussion on models used in this template check [the dedicated Section](#deploying-and-using-a-local-LLM).
### Webserver
You can configure the host and the port of the webserver.
Here is the default configuration:
```yaml
host: "0.0.0.0"
port: 8000
```
### Cache
You can configure whether you want to enable cache or persistence, to avoid repeated API accesses, and where the cache is stored.
Default values:
```yaml
persistence_mode: !pw.PersistenceMode.UDF_CACHING
persistence_backend: !pw.persistence.Backend.filesystem
path: ".Cache"
```
### Data sources
You can configure the data sources by changing `$sources` in `app.yaml`.
You can add as many data sources as you want. You can have several sources of the same kind, for instance, several local sources from different folders.
The sections below describe how to configure local, Google Drive and Sharepoint source, and you can check the examples of YAML configuration in our [user guide](https://pathway.com/developers/templates/yaml-snippets/data-sources-examples/). While these are not described in this Section, you can also use any input [connector](https://pathway.com/developers/user-guide/connecting-to-data/connectors) from Pathway package.
By default, the app uses a local data source to read documents from the `data` folder.
#### Local Data Source
The local data source is configured by using map with tag `!pw.io.fs.read`. Then set `path` to denote the path to a folder with files to be indexed.
#### Google Drive Data Source
The Google Drive data source is enabled by using map with tag `!pw.io.gdrive.read`. The map must contain two main parameters:
- `object_id`, containing the ID of the folder that needs to be indexed. It can be found from the URL in the web interface, where it's the last part of the address. For example, the publicly available demo folder in Google Drive has the URL `https://drive.google.com/drive/folders/1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`. Consequently, the last part of this address is `1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`, hence this is the `object_id` you would need to specify.
- `service_user_credentials_file`, containing the path to the credentials files for the Google [service account](https://cloud.google.com/iam/docs/service-account-overview). To get more details on setting up the service account and getting credentials, you can also refer to [this tutorial](https://pathway.com/developers/user-guide/connectors/gdrive-connector#setting-up-google-drive).
Besides, to speed up the indexing process you may want to specify the `refresh_interval` parameter, denoted by an integer number of seconds. It corresponds to the frequency between two sequential folder scans. If unset, it defaults to 30 seconds.
For the full list of the available parameters, please refer to the Google Drive connector [documentation](https://pathway.com/developers/api-docs/pathway-io/gdrive#pathway.io.gdrive.read).
#### SharePoint Data Source
This data source requires Scale or Enterprise [license key](https://pathway.com/pricing) - you can obtain free Scale key on [Pathway website](https://pathway.com/get-license).
To use it, set the map tag to be `!pw.xpacks.connectors.sharepoint.read`, and then provide values of `url`, `tenant`, `client_id`, `cert_path`, `thumbprint` and `root_path`. To read about the meaning of these arguments, check the Sharepoint connector [documentation](https://pathway.com/developers/api-docs/pathway-xpacks-sharepoint#pathway.xpacks.connectors.sharepoint.read).
## Deploying and using a local LLM
### Embedding Model Selection
You will use `pathway.xpacks.llm.embedders` module to load open-source embedding models from the HuggingFace model library. For this showcase, pick the `avsolatorio/GIST-small-Embedding-v0` model which has a dimension of 384 as it is compact and performed well in our tests.
```yaml
$embedding_model: "avsolatorio/GIST-small-Embedding-v0"
$embedder: !pw.xpacks.llm.embedders.SentenceTransformerEmbedder
model: $embedding_model
call_kwargs:
show_progress_bar: False
```
If you would like to use a higher-dimensional model, here are some possible alternatives you could use instead:
- mixedbread-ai/mxbai-embed-large-v1
- avsolatorio/GIST-Embedding-v0
For other possible choices, take a look at the [MTEB Leaderboard](https://huggingface.co/spaces/mteb/leaderboard) managed by HuggingFace.
### Local LLM Deployment
Due to its size and performance it is best to run the `Mistral 7B` LLM. Here you would deploy it as a service running on GPU, using `Ollama`.
To run local LLM, you can refer to these steps:
- Download Ollama from [ollama.com/download](https://ollama.com/download)
- In your terminal, run `ollama serve`
- In another terminal, run `ollama run mistral`
You can now test it with the following request:
```bash
curl -X POST http://localhost:11434/api/generate -d '{
"model": "mistral",
"prompt":"Here is a story about llamas eating grass"
}'
```
### LLM Initialization
Now you will initialize the LLM instance that will call the local model.
```yaml
$llm_model: "ollama/mistral"
$llm: !pw.xpacks.llm.llms.LiteLLMChat
model: $llm_model
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DefaultCache {}
temperature: 0
api_base: "http://localhost:11434"
# api_base: "http://host.docker.internal:11434" # use this when you are running the app in the Docker on Mac or Windows
async_mode: "fully_async"
```
## Running the app
First, make sure your local LLM is up and running. By default, the pipeline tries to access the LLM at `http://localhost:11434`. You can change that by setting `api_base` value in the app.yaml file.
### With Docker
In order to let the pipeline get updated with each change in local files, you need to mount the folder onto the docker. The following commands show how to do that.
#### Linux
```bash
# Build the image in this folder
docker build -t privaterag .
# Run the image, mount the `data` folder into image
docker run --net host -v ./data:/app/data privaterag
```
#### Mac or Windows
In the `app.yaml` change `api_base` to be `http://host.docker.internal:11434`. Then run:
```bash
# Build the image in this folder
docker build -t privaterag .
# Run the image, mount the `data` folder into image
docker run -v ./data:/app/data -p 8000:8000 privaterag
```
### Locally
To run locally you need to install the Pathway app with LLM dependencies using:
```bash
pip install pathway[all]
```
Then change your directory in the terminal to this folder and run the app:
```bash
python app.py
```
## Querying the app/pipeline
Finally, query the application with;
```bash
curl -X 'POST' 'http://0.0.0.0:8000/v2/answer' -H 'accept: */*' -H 'Content-Type: application/json' -d '{
"prompt": "What is the start date of the contract?"
}'
```
> `{"response": "December 21, 2015 [6]"}`
## Conclusion:
Now you have a fully private RAG set up with Pathway and Ollama. All your data remains safe on your system. Moreover, the set-up is optimized for speed, thanks to how Ollama runs the LLM, and how Pathway’s adaptive retrieval mechanism reduces token consumption while preserving the accuracy of the RAG.
This is a full production-ready set-up which includes reading your data sources, parsing the data, and serving the endpoint.
This private RAG setup can be run entirely locally with open-source LLMs, making it ideal for organizations with sensitive data and explainable AI needs.
## Quick Links:
- [Pathway Developer Documentation](https://pathway.com/developers/user-guide/introduction/welcome)
- [Pathway App Templates](https://pathway.com/developers/templates)
- [Discord Community of Pathway](https://discord.gg/pathway)
- [Pathway Issue Tracker](https://github.com/pathwaycom/pathway/issues)
- [End-to-end dynamic RAG pipeline with Pathway](https://github.com/pathwaycom/llm-app/tree/main/templates/question_answering_rag)
- [Using Pathway as a vector store with Langchain](https://python.langchain.com/v0.2/docs/integrations/vectorstores/pathway/)
- [Using Pathway as a retriever with LlamaIndex](https://docs.llamaindex.ai/en/stable/examples/retrievers/pathway_retriever/)
Make sure to drop a “Star” to our repositories if you found this resource helpful!
================================================
FILE: templates/private_rag/app.py
================================================
import logging
from warnings import warn
import pathway as pw
from dotenv import load_dotenv
from pathway.xpacks.llm.question_answering import SummaryQuestionAnswerer
from pathway.xpacks.llm.servers import QASummaryRestServer
from pydantic import BaseModel, ConfigDict, InstanceOf
# To use advanced features with Pathway Scale, get your free license key from
# https://pathway.com/features and paste it below.
# To use Pathway Community, comment out the line below.
pw.set_license_key("demo-license-key-with-telemetry")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
load_dotenv()
class App(BaseModel):
question_answerer: InstanceOf[SummaryQuestionAnswerer]
host: str = "0.0.0.0"
port: int = 8000
with_cache: bool | None = None # deprecated
persistence_backend: pw.persistence.Backend | None = None
persistence_mode: pw.PersistenceMode | None = pw.PersistenceMode.UDF_CACHING
terminate_on_error: bool = False
def run(self) -> None:
server = QASummaryRestServer( # noqa: F841
self.host, self.port, self.question_answerer
)
if self.persistence_mode is None:
if self.with_cache is True:
warn(
"`with_cache` is deprecated. Please use `persistence_mode` instead.",
DeprecationWarning,
)
persistence_mode = pw.PersistenceMode.UDF_CACHING
else:
persistence_mode = None
else:
persistence_mode = self.persistence_mode
if persistence_mode is not None:
if self.persistence_backend is None:
persistence_backend = pw.persistence.Backend.filesystem("./Cache")
else:
persistence_backend = self.persistence_backend
persistence_config = pw.persistence.Config(
persistence_backend,
persistence_mode=persistence_mode,
)
else:
persistence_config = None
pw.run(
persistence_config=persistence_config,
terminate_on_error=self.terminate_on_error,
monitoring_level=pw.MonitoringLevel.NONE,
)
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
if __name__ == "__main__":
with open("app.yaml") as f:
config = pw.load_yaml(f)
app = App(**config)
app.run()
================================================
FILE: templates/private_rag/app.yaml
================================================
# This YAML configuration file is used to set up and configure the Private RAG template.
# It defines various components such as data sources, language models, embedders, splitters, parsers, and retrievers.
# Each section is configured to specify how the template should process and handle data for generating responses.
# You can learn more about the YAML syntax here: https://pathway.com/developers/templates/configure-yaml
# $sources defines the data sources used to read the data which will be indexed in the RAG.
# You can learn more how to configure data sources here:
# https://pathway.com/developers/templates/yaml-examples/data-sources-examples
$sources:
# File System connector, reading data locally.
- !pw.io.fs.read
path: data
format: binary
with_metadata: true
# Uncomment to use the SharePoint connector
# - !pw.xpacks.connectors.sharepoint.read
# url: $SHAREPOINT_URL
# tenant: $SHAREPOINT_TENANT
# client_id: $SHAREPOINT_CLIENT_ID
# cert_path: sharepointcert.pem
# thumbprint: $SHAREPOINT_THUMBPRINT
# root_path: $SHAREPOINT_ROOT
# with_metadata: true
# refresh_interval: 30
# Uncomment to use the Google Drive connector
# - !pw.io.gdrive.read
# object_id: $DRIVE_ID
# service_user_credentials_file: gdrive_indexer.json
# file_name_pattern:
# - "*.pdf"
# - "*.pptx"
# object_size_limit: null
# with_metadata: true
# refresh_interval: 30
# Configures the LLM model settings for generating responses.
# The list of available Pathway LLM wrappers is available here:
# https://pathway.com/developers/api-docs/pathway-xpacks-llm/llms
# You can learn more about those in our documentation:
# https://pathway.com/developers/templates/rag-customization/llm-chats
$llm_model: "ollama/mistral"
$llm: !pw.xpacks.llm.llms.LiteLLMChat
model: $llm_model
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DefaultCache {}
temperature: 0
api_base: "http://localhost:11434"
# api_base: "http://host.docker.internal:11434" # use this when you are running the app in the Docker on Mac or Windows
async_mode: "fully_async"
$embedding_model: "avsolatorio/GIST-small-Embedding-v0"
# Specifies the embedder model for converting text into embeddings.
$embedder: !pw.xpacks.llm.embedders.SentenceTransformerEmbedder
model: $embedding_model
call_kwargs:
show_progress_bar: False
# Sets up the splitter for chunking the documents.
$splitter: !pw.xpacks.llm.splitters.TokenCountSplitter
max_tokens: 400
# Configures the parser for processing and extracting information from documents.
$parser: !pw.xpacks.llm.parsers.DoclingParser
table_parsing_strategy: "llm"
async_mode: "fully_async"
chunk: false
cache_strategy: !pw.udfs.DefaultCache {}
# Sets up the retriever factory for indexing and retrieving documents.
$retriever_factory: !pw.indexing.UsearchKnnFactory
reserved_space: 1000
embedder: $embedder
metric: !pw.indexing.USearchMetricKind.COS
# Manages the storage and retrieval of documents for the RAG template.
$document_store: !pw.xpacks.llm.document_store.DocumentStore
docs: $sources
parser: $parser
splitter: $splitter
retriever_factory: $retriever_factory
# Configures the question-answering component using the RAG approach.
question_answerer: !pw.xpacks.llm.question_answering.AdaptiveRAGQuestionAnswerer
llm: $llm
indexer: $document_store
n_starting_documents: 2
factor: 2
max_iterations: 4
strict_prompt: true
# Change host and port of the webserver by uncommenting these lines
# host: "0.0.0.0"
# port: 8000
# By default, caching is enabled for UDFs with cache_strategy set.
# You can disable it by uncommenting the following line.
# persistence_mode: null
# You can also set persistence_mode to !pw.PersistenceMode.PERSISTING to enable persistence
# across restarts.
# By default, when enabled, Cache is stored in .Cache directory.
# You can customize the location by uncommenting and modifying the following lines:
# persistence_backend: !pw.persistence.Backend.filesystem
# path: ".Cache"
# If `terminate_on_error` is true then the program will terminate whenever any error is encountered.
# Defaults to false, uncomment the following line if you want to set it to true
# terminate_on_error: true
================================================
FILE: templates/private_rag/requirements.txt
================================================
pathway[all]
python-dotenv~=1.0
mpmath~=1.3
================================================
FILE: templates/question_answering_rag/Dockerfile
================================================
ARG PATHWAY_SRC_IMAGE=pathwaycom/pathway:latest
FROM ${PATHWAY_SRC_IMAGE}
WORKDIR /app
RUN apt-get update \
&& apt-get install -y python3-opencv tesseract-ocr-eng poppler-utils libreoffice \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
COPY requirements.txt .
RUN pip install -U --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
================================================
FILE: templates/question_answering_rag/README.md
================================================
Deploy with GCP |
Deploy with AWS |
Deploy with Azure |
Deploy with Render
# Pathway RAG app with always up-to-date knowledge
This demo shows how to create a real-time RAG application using [Pathway](https://github.com/pathwaycom/pathway) that provides always up-to-date knowledge to your LLM without the need for a separate ETL.
You will see a running example of how to get started with the Pathway vector store that eliminates the need for ETL pipelines which are needed in the regular VectorDBs.
This significantly reduces the developer's workload.
This demo allows you to:
- Create a Document store with real-time document indexing from Google Drive, Microsoft 365 SharePoint, or a local directory;
- Connect an OpenAI LLM model of choice to your knowledge base;
- Get quality, accurate, and precise responses to your questions;
- Ask questions about folders, files or all your documents easily, with the help of filtering options;
- Use LLMs over API to summarize texts;
- Get an executive outlook for a question on different files to easily access available knowledge in your documents;
Note: This app relies on [Document Store](https://pathway.com/developers/api-docs/pathway-xpacks-llm/document_store) to learn more, you can check out [this blog post](https://pathway.com/developers/user-guide/llm-xpack/docs-indexing).
## Table of contents
- [Summary of available endpoints](#Summary-of-available-endpoints)
- [How it works](#How-it-works)
- [Customizing the pipeline](#Customizing-the-pipeline)
- [How to run the project](#How-to-run-the-project)
- [Using the app](#Query-the-documents)
## Summary of available endpoints
This example spawns a lightweight webserver using Pathway’s [`QASummaryRestServer`](https://pathway.com/developers/api-docs/pathway-xpacks-llm/servers#pathway.xpacks.llm.servers.QASummaryRestServer) that accepts queries on five possible endpoints, divided into two categories: document indexing and RAG with LLM.
### Document Indexing capabilities
- `/v1/retrieve` to perform similarity search;
- `/v1/statistics` to get the basic stats about the indexer's health;
- `/v2/list_documents` to retrieve the metadata of all files currently processed by the indexer.
### LLM and RAG capabilities
- `/v2/answer` to ask questions about your documents, or directly talk with your LLM;
- `/v2/summarize` to summarize a list of texts;
See the [using the app section](###Using-the-app) to learn how to use the provided endpoints.
## How it works
1. **Data Ingestion**
We define one or more sources in `app.yaml` (local directories, Google Drive, Microsoft SharePoint, etc.).
- The provided demo references a local folder `data/` by default.
- The code can poll these sources at configured intervals, so when new documents appear or existing ones change, they are automatically parsed and re-indexed in real-time.
2. **Parsing & Splitting**
Using [Docling](https://www.docling.ai/) (through Pathway’s [`DoclingParser`](https://pathway.com/developers/api-docs/pathway-xpacks-llm/parsers#pathway.xpacks.llm.parsers.DoclingParser)) and [TokenCountSplitter](https://pathway.com/developers/api-docs/pathway-xpacks-llm/splitters#pathway.xpacks.llm.splitters.TokenCountSplitter), documents are parsed and chunked into smaller parts.
3. **Embedding**
Via [`OpenAIEmbedder`](https://pathway.com/developers/api-docs/pathway-xpacks-llm/embedders#pathway.xpacks.llm.embedders.OpenAIEmbedder), the chunks get turned into embeddings. You can substitute your own embedder if you wish.
4. **Indexing**
Using [`USearchKnnFactory`](https://pathway.com/developers/api-docs/indexing#pathway.stdlib.indexing.UsearchKnnFactory), the embeddings are stored in a vector index. This is all streaming as well, so new embeddings are added or updated automatically.
5. **Serving**
- We create a [`SummaryQuestionAnswerer`](https://pathway.com/developers/api-docs/pathway-xpacks-llm/question_answering#pathway.xpacks.llm.question_answering.SummaryQuestionAnswerer) (as specified in `app.py`), which can handle both question-answering and summarization requests.
- A web server, [`QASummaryRestServer`](https://pathway.com/developers/api-docs/pathway-xpacks-llm/servers#pathway.xpacks.llm.servers.QASummaryRestServer), exposes multiple endpoints for retrieval, Q&A, summarization, and more.
Because Pathway is fully incremental, any changes to your source files immediately flow through parsing, embedding, indexing, and ultimately get reflected in the answers from the LLM. The user can then query the created index with simple HTTP requests to the endpoints mentioned above.
## Pipeline Organization
This folder contains several objects:
- `app.py`, the application code using Pathway and written in Python;
- `app.yaml`, the file containing configuration of the pipeline, like LLM models, sources or server address;
- `requirements.txt`, the dependencies for the pipeline. It can be passed to `pip install -r requirements.txt` to install everything that is needed to launch the pipeline locally;
- `Dockerfile`, the Docker configuration for running the pipeline in the container;
- `.env`, a short environment variables configuration file where the OpenAI key must be stored;
- `data/`, a folder with exemplary files that can be used for the test runs.
- `ui/`, a simple ui written in Streamlit for asking questions.
## Pathway tooling
### Prompts and helpers
Pathway allows you to define custom prompts in addition to the ones provided in [`pathway.xpacks.llm`](https://pathway.com/developers/user-guide/llm-xpack/overview).
You can also use user-defined functions using the [`@pw.udf`](https://pathway.com/developers/api-docs/pathway#pathway.udf) decorator to define custom functions that will run on streaming data.
### RAG
Pathway provides all the tools to create a RAG application and query it: a [Pathway Document store](https://pathway.com/developers/api-docs/pathway-xpacks-llm/document_store#pathway.xpacks.llm.document_store.DocumentStore) and a web server (defined with the [REST connector](https://pathway.com/developers/api-docs/pathway-io/http#pathway.io.http.rest_connector)).
For the sake of the demo, we kept the app simple, consisting of the main components you would find in a regular RAG application. It can be further enhanced with query writing methods, re-ranking layer and custom splitting steps.
Don't hesitate to take a look at our [documentation](https://pathway.com/developers/user-guide/introduction/welcome) to learn how Pathway works.
## OpenAI API Key Configuration
Default LLM provider in this template is OpenAI, so, unless you change the configuration, you need to provide OpenAI API key. Please configure your key in a `.env` file by providing it as follows: `OPENAI_API_KEY=sk-*******`. You can refer to the stub file `.env` in this repository, where you will need to paste your key instead of `sk-*******`.
## Customizing the pipeline
The code can be modified by changing the `app.yaml` configuration file. To read more about YAML files used in Pathway templates, read [our guide](https://pathway.com/developers/templates/configure-yaml).
In the `app.yaml` file we define:
- input connectors
- LLM
- embedder
- index
and any of these can be replaced or, if no longer needed, removed. For components that can be used check
Pathway [LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview), or you can implement your own.
You can also check our other templates - [Question Answering RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/question_answering_rag),
[Multimodal RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/multimodal_rag) or
[Private RAG](https://github.com/pathwaycom/llm-app/tree/main/templates/private_rag). As all of these only differ
in the YAML configuration file, you can also use them as an inspiration for your custom pipeline.
Here some examples of what can be modified.
### LLM Model
You can choose any of the models offered by Open AI, like GPT-5, GPT-4.1, or GPT-4o.
You can find the whole list on their [models page](https://platform.openai.com/docs/models).
You simply need to change the `model` to the one you want to use, e.g., to use GPT-5:
```yaml
$llm: !pw.xpacks.llm.llms.OpenAIChat
model: "gpt-5"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DefaultCache
capacity: 8
```
The default model is `gpt-4.1-mini`.
You can also use different provider, by using different class from [Pathway LLM xpack](https://pathway.com/developers/user-guide/llm-xpack/overview),
e.g. here is configuration for locally run Mistral model.
```yaml
$llm: !pw.xpacks.llm.llms.LiteLLMChat
model: "ollama/mistral"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DiskCache
temperature: 0
top_p: 1
api_base: "http://localhost:11434"
```
### Index of your choice
The [`DocumentStore`](https://pathway.com/developers/api-docs/pathway-xpacks-llm/document_store#pathway.xpacks.llm.document_store.DocumentStore) makes building and customizing a document indexing pipeline straightforward. It processes documents and enables querying the closest documents to a given query based on your chosen indexing strategy. Here's how you can use a hybrid indexing approach, combining vector-based and text-based retrieval:
Example: Hybrid Indexing with `USearchKNN` and `TantivyBM25`
The following example demonstrates how to configure and use the [HybridIndex](https://pathway.com/developers/api-docs/indexing#pathway.stdlib.indexing.HybridIndex) that combines:
- **`USearchKNN`**: A vector-based index leveraging embeddings for semantic similarity search.
- **[`TantivyBM25`](https://pathway.com/developers/api-docs/indexing#pathway.stdlib.indexing.TantivyBM25)**: A text-based index using BM25 for keyword matching.
```yaml
$knn_index: !pw.indexing.USearchKnnFactory
reserved_space: 1000
embedder: $embedder
metric: !pw.indexing.USearchKnnMetricKind.COS
dimensions: 1536
$bm25_index: !pw.indexing.TantivyBM25Factory
$hybrid_index_factory: !pw.indexing.HybridIndexFactory
retriever_factories:
- $knn_index
- $bm25_index
$document_store: !pw.xpacks.llm.document_store.DocumentStore
docs: $sources
parser: $parser
splitter: $splitter
retriever_factory: $hybrid_index_factory
```
Choose the indexing strategy that fits your requirements with `DocumentStore`
### Webserver
You can configure the host and the port of the webserver.
Here is the default configuration:
```yaml
host: "0.0.0.0"
port: 8000
```
### Cache
You can configure whether you want to enable cache or persistence, to avoid repeated API accesses, and where the cache is stored.
Default values:
```yaml
persistence_mode: !pw.PersistenceMode.UDF_CACHING
persistence_backend: !pw.persistence.Backend.filesystem
path: ".Cache"
```
### Data sources
You can configure the data sources by changing `$sources` in `app.yaml`.
You can add as many data sources as you want. You can have several sources of the same kind, for instance, several local sources from different folders.
The sections below describe how to configure local, Google Drive and Sharepoint source, and you can check the examples of YAML configuration in our [user guide](https://pathway.com/developers/templates/yaml-snippets/data-sources-examples/). While these are not described in this Section, you can also use any input [connector](https://pathway.com/developers/user-guide/connecting-to-data/connectors) from Pathway package.
By default, the app uses a local data source to read documents from the `data` folder.
#### Local Data Source
The local data source is configured by using map with tag `!pw.io.fs.read`. Then set `path` to denote the path to a folder with files to be indexed.
#### Google Drive Data Source
The Google Drive data source is enabled by using map with tag `!pw.io.gdrive.read`. The map must contain two main parameters:
- `object_id`, containing the ID of the folder that needs to be indexed. It can be found from the URL in the web interface, where it's the last part of the address. For example, the publicly available demo folder in Google Drive has the URL `https://drive.google.com/drive/folders/1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs`. The last part of this address is `1cULDv2OaViJBmOfG5WB0oWcgayNrGtVs` and this is the `object_id` you would need to specify.
- `service_user_credentials_file`, containing the path to the credentials files for the Google [service account](https://cloud.google.com/iam/docs/service-account-overview). To get more details on setting up the service account and getting credentials, you can also refer to [this tutorial](https://pathway.com/developers/user-guide/connectors/gdrive-connector#setting-up-google-drive).
Besides, to speed up the indexing process you may want to specify the `refresh_interval` parameter, denoted by an integer number of seconds. It corresponds to the frequency between two sequential folder scans. If unset, it defaults to 30 seconds.
For the full list of the available parameters, please refer to the Google Drive connector [documentation](https://pathway.com/developers/api-docs/pathway-io/gdrive#pathway.io.gdrive.read).
#### SharePoint Data Source
This data source requires Scale or Enterprise [license key](https://pathway.com/pricing) - you can obtain free Scale key on [Pathway website](https://pathway.com/get-license).
To use it, set the map tag to be `!pw.xpacks.connectors.sharepoint.read`, and then provide values of `url`, `tenant`, `client_id`, `cert_path`, `thumbprint` and `root_path`. To read about the meaning of these arguments, check the Sharepoint connector [documentation](https://pathway.com/developers/api-docs/pathway-xpacks-sharepoint#pathway.xpacks.connectors.sharepoint.read).
## How to run the project
Clone the llm-app repository from GitHub. This repository contains all the files you’ll need.
```bash
git clone https://github.com/pathwaycom/llm-app.git
```
### Locally
If you are on Windows, please refer to [running with docker](#With-Docker) section below.
To run locally, change your directory in the terminal to this folder. Then, run the app with `python`.
```bash
cd templates/question_answering_rag
python app.py
```
Please note that the local run requires the dependencies to be installed. It can be done with a simple pip command:
`pip install -r requirements.txt`
### With Docker
Build the Docker with:
```bash
docker compose build
```
And, run with:
```bash
docker compose up
```
This will start the pipeline and the ui for asking questions.
### Query the documents
You will see the logs for parsing & embedding documents in the Docker image logs.
Give it a few minutes to finish up on embeddings, you will see `0 entries (x minibatch(es)) have been...` message.
If there are no more updates, this means the app is ready for use!
To test it, let's query the stats:
```bash
curl -X 'POST' 'http://localhost:8000/v1/statistics' -H 'accept: */*' -H 'Content-Type: application/json'
```
For more information on available endpoints by default, see [above](#Summary-of-available-endpoints).
We provide some example `curl` queries to start with.
The general structure is sending a request to `http://{HOST}:{PORT}/{ENDPOINT}`.
Where HOST is the `host` variable you specify in your app configuration. PORT is the `port` number you are running your app on, and ENDPOINT is the specific extension for endpoints. They are specified in the application code, and they are listed with the versioning as `/v1/...`.
Note that, if you are using the Pathway hosted version, you should send requests to `https://...` rather than `http://...` and emit the `:{PORT}` part of the URL.
You need to add two headers, `-H 'accept: */*' -H 'Content-Type: application/json'`.
Finally, for endpoints that expect data in the query, you can pass it with `-d '{key: value}'` format.
#### Listing inputs
Get the list of available inputs and associated metadata.
```bash
curl -X 'POST' 'http://localhost:8000/v2/list_documents' -H 'accept: */*' -H 'Content-Type: application/json'
```
#### Searching in your documents
Search API gives you the ability to search in available inputs and get up-to-date knowledge.
`query` is the search query you want to execute.
`k` (optional) is an integer, the number of documents to be retrieved. Documents in this case means small chunks that are stored in your vector store.
`metadata_filter` (optional) String to filter results with Jmespath query.
`filepath_globpattern` (optional) String to filter results with globbing pattern. For example `"*"` would result in no filter, `"*.docx"` would result in only `docx` files being retrieved.
```bash
curl -X 'POST' \
'http://0.0.0.0:8000/v1/retrieve' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"query": "Which articles of General Data Protection Regulation are relevant for clinical trials?",
"k": 6
}'
```
#### Asking questions to LLM (With and without RAG)
- Note: The local version of this app does not require `openai_api_key` parameter in the payload of the query. Embedder and LLM will use the API key in the `.env` file. However, Pathway hosted public demo available on the [website](https://pathway.com/solutions/ai-pipelines) requires a valid `openai_api_key` to execute the query.
- Note: All of the RAG endpoints use the `model` provided in the config by default, however, you can specify another model with the `model` parameter in the payload to use a different one for generating the response.
For question answering without any context, simply omit `filters` key in the payload and send the following request.
```bash
curl -X 'POST' \
'http://0.0.0.0:8000/v2/answer' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"prompt": "What is the start date of the contract?"
}'
```
Question answering with the knowledge from a specific file, based on the path.
```bash
curl -X 'POST' \
'http://0.0.0.0:8000/v2/answer' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"prompt": "What is the start date of the contract?",
"filters": "globmatch(`"IdeanomicsInc_20160330_10-K_EX-10.26_9512211_EX-10.26_Content License Agreement.pdf"`, path)"
}'
```
Alternatively, with the knowledge from files that have the word `Ide` in their paths.
```bash
curl -X 'POST' \
'http://0.0.0.0:8000/v2/answer' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"prompt": "What is the start date of the contract?",
"filters": "contains(path, `"Ide"`)"
}'
```
You can also retrieve the context documents that were used to answer the question,
```bash
curl -X 'POST' \
'http://0.0.0.0:8000/v2/answer' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"prompt": "What is the start date of the contract?",
"return_context_docs": true
}'
```
- Note: You can limit the knowledge to a folder or, to only Word documents by using ```"contains(path, `docx`)"```
- Note: You could also use a few filters separated with `||` (`or` clause) or with `&&` (`and` clause).
You can further modify behavior in the payload by defining keys and values in `-d '{key: value}'`.
If you wish to use another model, specify in the payload as `"model": "gpt-4"`.
For more detailed responses add `"response_type": "long"` to payload.
#### Summarization
To summarize a list of texts, use the following `curl` command.
```bash
curl -X 'POST' \
'http://0.0.0.0:8000/v2/summarize' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"text_list": [
"I love apples.",
"I love oranges."
]
}'
```
Specifying the GPT model with `"model": "gpt-4"` is also possible.
This endpoint also supports setting different models in the query by default.
To execute similar curl queries as above, you can visit [ai-pipelines page](https://pathway.com/solutions/ai-pipelines/) and try out the queries from the Swagger UI.
#### Adding Files to Index
First, you can try adding your files and seeing changes in the index. To test index updates, simply add more files to the `data` folder.
If you are using Google Drive or other sources, simply upload your files there.
### Using the UI
This pipeline includes a simple ui written in Streamlit. After you run the pipeline with `docker compose up`, you can access the UI at `http://localhost:8501`. This UI uses the `/v2/answer` endpoint to answer your questions.
================================================
FILE: templates/question_answering_rag/app.py
================================================
import logging
from warnings import warn
import pathway as pw
from dotenv import load_dotenv
from pathway.xpacks.llm.question_answering import SummaryQuestionAnswerer
from pathway.xpacks.llm.servers import QASummaryRestServer
from pydantic import BaseModel, ConfigDict, InstanceOf
# To use advanced features with Pathway Scale, get your free license key from
# https://pathway.com/features and paste it below.
# To use Pathway Community, comment out the line below.
pw.set_license_key("demo-license-key-with-telemetry")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
load_dotenv()
class App(BaseModel):
question_answerer: InstanceOf[SummaryQuestionAnswerer]
host: str = "0.0.0.0"
port: int = 8000
with_cache: bool | None = None # deprecated
persistence_backend: pw.persistence.Backend | None = None
persistence_mode: pw.PersistenceMode | None = pw.PersistenceMode.UDF_CACHING
terminate_on_error: bool = False
def run(self) -> None:
server = QASummaryRestServer( # noqa: F841
self.host, self.port, self.question_answerer
)
if self.persistence_mode is None:
if self.with_cache is True:
warn(
"`with_cache` is deprecated. Please use `persistence_mode` instead.",
DeprecationWarning,
)
persistence_mode = pw.PersistenceMode.UDF_CACHING
else:
persistence_mode = None
else:
persistence_mode = self.persistence_mode
if persistence_mode is not None:
if self.persistence_backend is None:
persistence_backend = pw.persistence.Backend.filesystem("./Cache")
else:
persistence_backend = self.persistence_backend
persistence_config = pw.persistence.Config(
persistence_backend,
persistence_mode=persistence_mode,
)
else:
persistence_config = None
pw.run(
persistence_config=persistence_config,
terminate_on_error=self.terminate_on_error,
monitoring_level=pw.MonitoringLevel.NONE,
)
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
if __name__ == "__main__":
with open("app.yaml") as f:
config = pw.load_yaml(f)
app = App(**config)
app.run()
================================================
FILE: templates/question_answering_rag/app.yaml
================================================
# This YAML configuration file is used to set up and configure the Question Answering RAG template.
# It defines various components such as data sources, language models, embedders, splitters, parsers, and retrievers.
# Each section is configured to specify how the template should process and handle data for generating responses.
# You can learn more about the YAML syntax here: https://pathway.com/developers/templates/configure-yaml
# $sources defines the data sources used to read the data which will be indexed in the RAG.
# You can learn more how to configure data sources here:
# https://pathway.com/developers/templates/yaml-examples/data-sources-examples
$sources:
# File System connector, reading data locally.
- !pw.io.fs.read
path: data
format: binary
with_metadata: true
# Uncomment to use the SharePoint connector
# - !pw.xpacks.connectors.sharepoint.read
# url: $SHAREPOINT_URL
# tenant: $SHAREPOINT_TENANT
# client_id: $SHAREPOINT_CLIENT_ID
# cert_path: sharepointcert.pem
# thumbprint: $SHAREPOINT_THUMBPRINT
# root_path: $SHAREPOINT_ROOT
# with_metadata: true
# refresh_interval: 30
# Uncomment to use the Google Drive connector
# - !pw.io.gdrive.read
# object_id: $DRIVE_ID
# service_user_credentials_file: gdrive_indexer.json
# file_name_pattern:
# - "*.pdf"
# - "*.pptx"
# object_size_limit: null
# with_metadata: true
# refresh_interval: 30
# Configures the LLM model settings for generating responses.
# The list of available Pathway LLM wrappers is available here:
# https://pathway.com/developers/api-docs/pathway-xpacks-llm/llms
# You can learn more about those in our documentation:
# https://pathway.com/developers/templates/rag-customization/llm-chats
$llm: !pw.xpacks.llm.llms.OpenAIChat
model: "gpt-4.1-mini"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
cache_strategy: !pw.udfs.DefaultCache {}
temperature: 0
capacity: 8
async_mode: "fully_async"
# Specifies the embedder model for converting text into embeddings.
$embedder: !pw.xpacks.llm.embedders.OpenAIEmbedder
model: "text-embedding-3-small"
cache_strategy: !pw.udfs.DefaultCache {}
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy {}
# Defines the splitter settings for dividing text into smaller chunks.
$splitter: !pw.xpacks.llm.splitters.TokenCountSplitter
max_tokens: 400
# Configures the parser for processing and extracting information from documents.
$parser: !pw.xpacks.llm.parsers.DoclingParser
table_parsing_strategy: "llm"
async_mode: "fully_async"
chunk: false
cache_strategy: !pw.udfs.DefaultCache {}
# Sets up the retriever factory for indexing and retrieving documents.
$retriever_factory: !pw.indexing.UsearchKnnFactory
reserved_space: 1000
embedder: $embedder
metric: !pw.indexing.USearchMetricKind.COS
# Manages the storage and retrieval of documents for the RAG template.
$document_store: !pw.xpacks.llm.document_store.DocumentStore
docs: $sources
parser: $parser
splitter: $splitter
retriever_factory: $retriever_factory
# Configures the question-answering component using the RAG approach.
# The component builds a RAG over an index.
# You can interact with obtained RAG using a REST API.
# You can learn more about the available operations here:
# https://pathway.com/developers/templates/rag-customization/rest-api
question_answerer: !pw.xpacks.llm.question_answering.BaseRAGQuestionAnswerer
llm: $llm
indexer: $document_store
# You can set the number of documents to be included as the context of the query
# search_topk: 6
# You can use your own prompt for querying.
# For that set prompt_template to string with `{query}` used as a placeholder for the question,
# and `{context}` as a placeholder for context documents.
# prompt_template: "Given these documents: {context}, please answer the question: {query}"
# Change host and port of the webserver by uncommenting these lines
# host: "0.0.0.0"
# port: $PATHWAY_PORT
# By default, caching is enabled for UDFs with cache_strategy set.
# You can disable it by uncommenting the following line.
# persistence_mode: null
# You can also set persistence_mode to !pw.PersistenceMode.PERSISTING to enable persistence
# across restarts.
# By default, when enabled, Cache is stored in .Cache directory.
# You can customize the location by uncommenting and modifying the following lines:
# persistence_backend: !pw.persistence.Backend.filesystem
# path: ".Cache"
# If `terminate_on_error` is true then the program will terminate whenever any error is encountered.
# Defaults to false, uncomment the following line if you want to set it to true
# terminate_on_error: true
================================================
FILE: templates/question_answering_rag/docker-compose.yml
================================================
services:
app:
build:
context: .
args:
PATHWAY_SRC_IMAGE: ${PATHWAY_SRC_IMAGE:-pathwaycom/pathway:latest}
ports:
- "${PATHWAY_PORT:-8000}:${PATHWAY_PORT:-8000}"
networks:
- network
environment:
PATHWAY_PORT: "${PATHWAY_PORT:-8000}"
PATHWAY_LICENSE_KEY: $PATHWAY_LICENSE_KEY
volumes:
- ./data:/app/data
- ./Cache:/app/Cache
ui:
build:
context: ui
args:
PATHWAY_SRC_IMAGE: ${PATHWAY_SRC_IMAGE:-pathwaycom/pathway:latest}
networks:
- network
environment:
PATHWAY_HOST: "app"
PATHWAY_PORT: "${PATHWAY_PORT:-8000}"
UI_PORT: 8501
ports:
- "8501:8501"
networks:
network:
driver: bridge
================================================
FILE: templates/question_answering_rag/requirements.txt
================================================
pathway[all]
python-dotenv~=1.0
mpmath~=1.3
================================================
FILE: templates/question_answering_rag/ui/.streamlit/config.toml
================================================
[client]
toolbarMode = "minimal"
[server]
enableStaticServing = true
[theme]
base = "light"
================================================
FILE: templates/question_answering_rag/ui/Dockerfile
================================================
ARG PATHWAY_SRC_IMAGE=pathwaycom/pathway:latest
FROM ${PATHWAY_SRC_IMAGE}
ENV PYTHONUNBUFFERED=1
WORKDIR /ui
COPY requirements.txt .
RUN pip install -U --no-cache-dir -r requirements.txt
COPY . .
CMD exec streamlit run ui.py --server.port ${UI_PORT}
================================================
FILE: templates/question_answering_rag/ui/requirements.txt
================================================
streamlit==1.37.0
load_dotenv==0.1.0
================================================
FILE: templates/question_answering_rag/ui/ui.py
================================================
# Copyright © 2026 Pathway
import logging
import os
import streamlit as st
from dotenv import load_dotenv
from pathway.xpacks.llm.document_store import IndexingStatus
from pathway.xpacks.llm.question_answering import RAGClient
load_dotenv()
PATHWAY_HOST = os.environ.get("PATHWAY_HOST", "app")
PATHWAY_PORT = os.environ.get("PATHWAY_PORT", 8000)
st.set_page_config(page_title="Pathway RAG App", page_icon="favicon.ico")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
force=True,
)
logger = logging.getLogger("streamlit")
logger.setLevel(logging.INFO)
conn = RAGClient(url=f"http://{PATHWAY_HOST}:{PATHWAY_PORT}")
note = """
Ask a question"""
st.markdown(note, unsafe_allow_html=True)
st.markdown(
"""
""",
unsafe_allow_html=True,
)
question = st.text_input(label="", placeholder="Ask your question?")
def get_indexed_files(metadata_list: list[dict], opt_key: str) -> list:
"""Get all available options in a specific metadata key."""
only_indexed_files = [
file
for file in metadata_list
if file["_indexing_status"] == IndexingStatus.INDEXED
]
options = set(map(lambda x: x[opt_key], only_indexed_files))
return list(options)
def get_ingested_files(metadata_list: list[dict], opt_key: str) -> list:
"""Get all available options in a specific metadata key."""
not_indexed_files = [
file
for file in metadata_list
if file["_indexing_status"] == IndexingStatus.INGESTED
]
options = set(map(lambda x: x[opt_key], not_indexed_files))
return list(options)
logger.info("Requesting list_documents...")
document_meta_list = conn.list_documents(keys=[])
logger.info("Received response list_documents")
st.session_state["document_meta_list"] = document_meta_list
indexed_files = get_indexed_files(st.session_state["document_meta_list"], "path")
ingested_files = get_ingested_files(st.session_state["document_meta_list"], "path")
logo_htm = """
"""
with st.sidebar:
st.markdown(logo_htm, unsafe_allow_html=True)
st.info(
body="See the source code [here](https://github.com/pathwaycom/llm-app/tree/main/templates/question_answering_rag).", # noqa: E501
icon=":material/code:",
)
indexed_file_names = [i.split("/")[-1] for i in indexed_files]
ingested_file_names = [i.split("/")[-1] for i in ingested_files]
markdown_table = "| Indexed files |\n| --- |\n"
for file_name in indexed_file_names:
markdown_table += f"| {file_name} |\n"
if len(ingested_file_names) > 0:
markdown_table += "| Files being processed |\n| --- |\n"
for file_name in ingested_file_names:
markdown_table += f"| {file_name} |\n"
st.markdown(markdown_table, unsafe_allow_html=True)
st.button("⟳ Refresh", use_container_width=True)
css = """
"""
st.markdown(css, unsafe_allow_html=True)
if question:
logger.info(
{
"_type": "search_request_event",
"query": question,
}
)
with st.spinner("Retrieving response..."):
api_response = conn.answer(question, return_context_docs=True)
response = api_response["response"]
context_docs = api_response["context_docs"]
logger.info(
{
"_type": "search_response_event",
"query": question,
"response": type(response),
}
)
logger.info(type(response))
st.markdown(f"**Answering question:** {question}")
st.markdown(f"""{response}""")
with st.expander(label="Context documents"):
st.markdown("Documents sent to LLM as context:\n")
for i, doc in enumerate(context_docs):
st.markdown(
f"{i+1}. Path: {doc['metadata']['path']}\n ```\n{doc['text']}\n```"
)
================================================
FILE: templates/slides_ai_search/.dockerignore
================================================
Cache
================================================
FILE: templates/slides_ai_search/.gitignore
================================================
data
.env
storage
================================================
FILE: templates/slides_ai_search/Dockerfile
================================================
ARG PATHWAY_SRC_IMAGE=pathwaycom/pathway:latest
FROM ${PATHWAY_SRC_IMAGE}
ENV PYTHONUNBUFFERED=1
WORKDIR /app
RUN apt-get update && apt-get install -y \
poppler-utils \
libreoffice \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install -U --no-cache-dir -r requirements.txt
COPY . .
CMD [ "python", "app.py" ]
================================================
FILE: templates/slides_ai_search/README.md
================================================
Deploy with GCP |
Deploy with AWS |
Deploy with Azure |
Deploy with Render
# **Slides AI Search App**
## **Overview**
This app template will help you build a multi-modal search service using `GPT-4o` with Metadata Extraction and Vector Index. It uses [Pathway](https://github.com/pathwaycom/llm-app) for indexing and retrieving slides from PowerPoint and PDF presentations.
How is this different?
* Build highly accurate RAG pipelines powered by indexes that are updated in real-time.
* All of the steps, including parsing, embedding and indexing happen locally on your machine (local or cloud).
* Pathway uses vision language models to understand and index your presentations and PDFs, automatically updating as changes are made.
* Get started with a minimalistic and production-ready approach.
Boost productivity with accurate search across your PowerPoints, PDFs, and Slides all within your work environment. Try out the [demo](https://sales-rag-chat.demo.pathway.com/#search-your-slide-decks) here.
## Quickstart
Check the `.env.example`, create a new `.env` file and fill in the template.
For a quick start, you need to only change the following fields:
- `PATHWAY_LICENSE_KEY`
- `OPENAI_API_KEY`
This app template is available for free via [Pathway Scale](https://pathway.com/features). Get your [license key here](https://pathway.com/user/license) and fill in the `PATHWAY_LICENSE_KEY` here in the `.env` file.
To learn more about configuring the input sources, how to overcome OpenAI limits and other information, check out the [configuration section below](#prerequisitesconfiguration).
> **Note:** Pathway API is only used for logging basic statistics, everything happens and stays in your computer, except the OpenAI API calls. No personal or private data will be sent to Pathway servers. Handling of the data, processing, parsing and indexing are done locally.
## How it Helps
**1) Improved Efficiency:**
* **Save Efforts:** You no longer need to manually sift through countless presentations.
* **Faster Information Retrieval:** Instantly find specific information with a few keywords or descriptive prompts, saving you time when preparing for presentations or reviewing past projects.
**2) Enhanced Organization**
* **Automated Categorization:** You can organize your slide library by topic, project, or other criteria. Configure the schema file to customize the parsed fields.
**3) Enhanced Reliability**
* **Automatic Updates:** Hybrid indexes update automatically whenever a new slide is added or removed, ensuring your information is always current and accurate.
**4) Automated Slide Parsing:**
* Process PPTX and PDF slide decks with vision language models to extract the content. (The default setup loads PDF's).
**5) Flexible Data Sources:**
* Compatible with local directories, SharePoint, Google Drive, and other [Pathway connectors](https://pathway.com/developers/user-guide/connect/pathway-connectors), ensuring a wide range of application scenarios can be supported.
By automating the extraction and retrieval of slide information, this app addresses the critical pain point of managing and utilizing extensive slide decks efficiently, enhancing productivity and information accuracy for sales teams.
## Architecture:
The architecture of the Slides AI Search App is designed to connect various local or cloud repositories, transforming and indexing slides for efficient querying. It supports integration with closed and open-source LLMs for enhanced search capabilities.

This demo consists of three parts:
* `app.py`: Pathway app that handles parsing, indexing and backend.
* `nginx`: File server that hosts images to be consumed by the UI.
* `UI`: A Streamlit UI for interacting with the app.
## How it works:
### **Data Ingestion**
1. **Data Sources**:
* The application reads slide files (PPTX and PDF) from a specified directory. The directory is set to `./data/`in the `app.py` file.
* In the default app setup, the connected folder is a local file folder. You can add more folders and file sources, such as [Google Drive](https://pathway.com/developers/user-guide/connectors/gdrive-connector#google-drive-connector) or [Sharepoint](https://pathway.com/developers/user-guide/connecting-to-data/connectors#tutorials), by changing configuration in `app.yaml`.
* More inputs can be added by configuring the `sources` list in the `app.yaml`.
### **Slide Parsing and Indexing**
1. **Parsing**:
* The [`SlideParser`](https://pathway.com/developers/api-docs/pathway-xpacks-llm/parsers#pathway.xpacks.llm.parsers.SlideParser) from Pathway is used to parse the slides. The parser is configured to parse a text description and schema that is defined in the `app.yaml`.
* Our example schema includes fields such as `category`, `tags`, `title`, `main_color`, `language`, and `has_images`. This can be modified for specific use cases.
* Note that, UI is configured to make use of two extracted fields `category` and `language`, these need to be kept for the UI to work. However, the app can still be used without the UI with different schemas or no parsed schema.
2. **Embedding**:
* Parsed slide content is embedded with the OpenAI's `text-embedding-3-small` embedder.
* The embeddings are then stored in Pathway's vector store using the `SlidesVectorStoreServer`.
3. **Metadata Handling**:
* Images and files are dumped into local directories (`storage/pw_dump_images` and `storage/pw_dump_files`).
* Each slide gets a unique ID. This helps with opening files and images from the UI.
### **Query Handling**
1. **Retrieval Augmented Generation (RAG)**:
* The `DeckRetriever` class builds the backend, handling all steps of the application from parsing files to serving the endpoints. Refer to the [API docs](https://pathway.com/developers/api-docs/pathway-xpacks-llm/question_answering#pathway.xpacks.llm.question_answering.DeckRetriever) for more information.
## Pipeline Organization
This folder contains several components necessary for setting up and running the Sales Slide RAG application:
1. **app.py**:
* The main application that sets up the slide search functionality. It initializes the OpenAI vision-language model, slide parser, vector store, and initializes the DeckRetriever for handling queries.
2. **app.yaml**:
* Defines data sources, OpenAI vision-language model configuration, and other key settings.
* Defines the schema for parsing the slides and including fields such as `category`, `tags`, `title`, `main_color`, `language`, and `has_images`. These fields will be appended to the `metadata`, if you prefer to also add them to `text` field, set `include_schema_in_text` of `SlideParser` to `True`.
* **Note:** If you intend the use the default UI, `category` and the `language` fields in the schema are needed for the filtering options in the UI. The UI will not function properly without them.
3. **.env**:
* Config file for the environment variables, such as the OpenAI API key and Pathway key.
## **Prerequisites/Configuration**
### **Environment Setup**
1. **OpenAI API Key**:
* Get an API key from the [OpenAI’s API Key Management page](https://platform.openai.com/account/api-keys). Keep this API key secure.
* Configure your key in the `.env` file.
* You can refer to the stub file `.env.example` in this repository.
* Note: This is only needed in OpenAI LLMs and embedders. It is also possible to use other multi-modal, local LLMs and embedders.
**OpenAI API Usage**:
* This app relies on `gpt-4o` model for image parsing. OpenAI currently limits the usage to paid users only. It is possible to use any other model (including local models) with the modules under the `pathway.xpacks`.
* If you are experiencing API throttle, you can set the `capacity` parameter of the LLM instance `llms.OpenAIChat` to be lower. This parameter defines the number of parallel requests. Or, it is possible to disable parallel requests and only parse sequentially by changing the `run_mode` in the `SlideParser` to `run_mode="sequential"` instead of the `"parallel"`.
* Update: You can also change the model to any of the newer multimodal models, like GPT-5 or GPT-5.1, or their smaller variants.
2. **Pathway’s License Key**:
* This app template is available for free via [Pathway Scale](https://pathway.com/features).
* Get your [license key here](https://pathway.com/user/license).
* **Note:** Pathway API is only used for logging basic statistics, everything happens and stays in your computer except the OpenAI API calls. No personal or private data will be sent to Pathway servers.
### **Configuring the Inputs**
By default, the app takes the files under the `./data/` folder as input. Inputs can be set by adding more entries to the `sources` list under the `app.yaml`.
It is possible to configure the app to use any kind of input, `Google Drive`, `Microsoft 365 SharePoint`, or a `local directory` to name a few.
You can also use other kind of data sources using the [connectors](https://pathway.com/developers/user-guide/connecting-to-data/connectors) provided by Pathway.
Pathway polls the changes with low latency. So, if something changes in the tracked files, the corresponding change is reflected in real-time, and search results are updated accordingly.
To learn more about the data sources, you can check out [demo question answering](../question_answering_rag/README.md#data-sources)
## How to run the project on your machine
First, clone the Pathway LLM App Repository
```bash
git clone https://github.com/pathwaycom/llm-app.git
```
Make sure you are in the right directory:
```bash
cd templates/slides_ai_search
```
> Note: If your OpenAI API usage is throttled, you may want to change the `run_mode` in the `SlideParser` to `run_mode="sequential"` instead of the `"parallel"`.
## Deploying and running with Docker
Build the Docker with:
```bash
docker compose build
```
And, run with:
```bash
docker compose up
```
This will start all three components of the demo. This deployment method is recommended for production use.
## Using the app
After Docker is running, you will see a stream of logs of your files being parsed.
### Accessing the UI
On your browser, visit [`http://localhost:8501`](http://localhost:8501/) to access the UI.
Here, you will see a search bar, some filters, and information about the indexed documents on the left side.
### Sending requests to the server
#### With CURL
UI is not a necessary component, especially for developers. If you are interested in building your own app, check out the following ways to use the app:
First, let's check the indexed files:
```bash
curl -X 'POST' 'http://0.0.0.0:8000/v2/list_documents' -H 'accept: */*' -H 'Content-Type: application/json'
```
This will return a list of metadata from the indexed files.
Now, let's search through our slides:
```bash
curl -X 'POST' 'http://0.0.0.0:8000/v2/answer' -H 'accept: */*' -H 'Content-Type: application/json' -d '{
"prompt": "diagrams that contain value propositions"
}'
```
This will search through our files, and return parsed slides with the `text`, `slide_id` and other `metadata` (also including the parsed schema).
#### With the Pathway RAG Client
Import RAGClient with:
```python
from pathway.xpacks.llm.question_answering import RAGClient
```
Initialize the client:
```python
# conn = RAGClient(url=f"http://{PATHWAY_HOST}:{PATHWAY_PORT}")
# with the default config
conn = RAGClient(url=f"http://localhost:8000")
```
List the indexed files:
```python
conn.pw_list_documents()
```
> `[{'path': 'data/slide.pdf'}, ...`
Query the app:
```python
conn.pw_ai_answer("introduction slide")
```
> `[{'dist': 0.47761982679367065, 'metadata': ...`
## Advanced variant: Run locally without Open AI, using a local LLM and Embedder
To run the app fully locally, without needing any API access, we use [vLLM](https://github.com/vllm-project/vllm) and open source embedder from the HuggingFace.
### Running the local LLM
We use Phi 3 Vision for its relatively small size and good performance. It is possible to use any other VLM.
1. **Download and Install vLLM:**
See the [installation page](https://docs.vllm.ai/en/latest/getting_started/installation.html).
2. **Run the model:**
The following command will run the Phi 3 vision model and mimic the OpenAI API.
```bash
python -m vllm.entrypoints.openai.api_server --model microsoft/Phi-3-vision-128k-instruct --trust-remote-code --dtype=half --max-model-len=42500 --gpu-memory-utilization 0.9 --swap-space 16 --max-num-seqs 65
```
Check if the model is available with:
```bash
curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{
"model": "microsoft/Phi-3-vision-128k-instruct",
"prompt": "San Francisco is a",
"max_tokens": 7,
"temperature": 0
}'
```
### Set the LLM Instance in the configuration file
```yaml
llm: !pw.xpacks.llm.llms.OpenAIChat
model: "microsoft/Phi-3-vision-128k-instruct"
temperature: 0.0
capacity: 1
base_url: "http://localhost:8000/v1"
api_key: "ignore the key, not needed"
cache_strategy: !pw.udfs.DefaultCache {}
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 3
```
This will use your local Phi 3 vision model as the LLM for parsing the slides.
### Set an open-source embedder model for embeddings
Here, we can check [MTEB Leaderboard](https://huggingface.co/spaces/mteb/leaderboard) to find a good-performing embedder model.
From performance/computational-cost standpoint, `avsolatorio/GIST-Embedding-v0`, `avsolatorio/GIST-small-Embedding-v0`, `mixedbread-ai/mxbai-embed-large-v1`, `Alibaba-NLP/gte-large-en-v1.5` are some of the better models.
Here, we go with the `avsolatorio/GIST-small-Embedding-v0`.
Note that, larger models may take longer to process the inputs.
We replace the `embedder` with the following embedding model in `app.yaml`:
```yaml
$embedding_model: "avsolatorio/GIST-small-Embedding-v0"
embedder: !pw.xpacks.llm.embedders.SentenceTransformerEmbedder
model: $embedding_model
call_kwargs:
show_progress_bar: false
```
## Advanced variant: Running without Docker
Running the whole demo without Docker is a bit tricky as there are three components.
1. **Download and Install LibreOffice:**
* Download LibreOffice from the [LibreOffice website](https://www.libreoffice.org/download/download-libreoffice).
* Follow the installation instructions specific to your operating system. \
2. **Verify LibreOffice Installation:**
* Download LibreOffice from the LibreOffice website.
* Open a terminal or command prompt and run the following command:
* You should see the LibreOffice version information, indicating LibreOffice is installed correctly.
**Purpose:** LibreOffice helps with converting PPTX files into PDFs, which is essential for the document processing workflow in the Slides AI Search App.
If you are on Windows, please refer to the [running with Docker](#Running-with-docker) section below.
To run the Pathway app without the UI,
```bash
python app.py
```
## Not sure how to get started?
Let's discuss how we can help you build a powerful, customized RAG application. [Reach us here to talk or request a demo!](https://pathway.com/solutions/slides-ai-search?modal=requestdemo)
## FAQ
> I am getting OpenAI API throttle limit errors.
- You can change `run_mode` in `SlideParser` to `run_mode="sequential"`. This will parse images one by one, however, this will significantly slow down the parsing stage.
> UI shows that my file is being indexed, but I don't have that file in the inputs.
- App mounts `storage` folder from the Docker to the local file system. This helps the file server serve the content. This folder is not cleaned between the runs, files from the previous runs will be staying here. You can remove the folder after closing the app to get rid of these.
> Can I use other vision LMs or LLMs?
- Yes, you can configure the `OpenAIChat` to reach local LLMs or swap it with any other LLM wrappers (such as `LiteLLMChat`) to use other models. Make sure your model of choice supports vision inputs.
> Can I persist the cache between the runs?
- Yes, you can uncomment the `- ./Cache:/app/Cache` under the `app:/volumes:` section inside the `docker-compose.yml` to allow caching between the runs. You will see that requests are not repeated in the next runs.
================================================
FILE: templates/slides_ai_search/app.py
================================================
#!/usr/bin/env python
# Copyright © 2026 Pathway
# Copied and adapted from templates/slides_ai_search/app.py
# To use advanced features with Pathway Scale, get your free license key from
# https://pathway.com/features and paste it in the `.env` file (check `.env.example`).
from pathlib import Path
from typing import Any
from warnings import warn
import pathway as pw
from dotenv import load_dotenv
from pathway.xpacks import llm
from pathway.xpacks.llm.document_store import SlidesDocumentStore
from pathway_slides_ai_search import DeckRetrieverWithFileSave, add_slide_id, get_model
from pydantic import BaseModel, ConfigDict, FilePath, InstanceOf
class App(BaseModel):
host: str = "0.0.0.0"
port: int = 8000
sources: list[InstanceOf[pw.Table]]
llm: InstanceOf[pw.UDF]
retriever_factory: InstanceOf[pw.indexing.AbstractRetrieverFactory]
search_topk: int = 6
details_schema: FilePath | dict[str, Any] | None = None
with_cache: bool | None = None # deprecated
persistence_backend: pw.persistence.Backend | None = None
persistence_mode: pw.PersistenceMode | None = pw.PersistenceMode.UDF_CACHING
terminate_on_error: bool = False
def run(self) -> None:
if self.details_schema is not None:
detail_schema = get_model(self.details_schema)
else:
detail_schema = None
parser = llm.parsers.SlideParser(
detail_parse_schema=detail_schema,
run_mode="parallel",
include_schema_in_text=False,
llm=self.llm,
cache_strategy=pw.udfs.DefaultCache(),
async_mode="fully_async",
)
doc_store = SlidesDocumentStore(
self.sources,
retriever_factory=self.retriever_factory,
splitter=None,
parser=parser,
doc_post_processors=[add_slide_id],
)
app = DeckRetrieverWithFileSave(
indexer=doc_store,
search_topk=self.search_topk,
)
app.build_server(host=self.host, port=self.port)
if self.persistence_mode is None:
if self.with_cache is True:
warn(
"`with_cache` is deprecated. Please use `persistence_mode` instead.",
DeprecationWarning,
)
persistence_mode = pw.PersistenceMode.UDF_CACHING
else:
persistence_mode = None
else:
persistence_mode = self.persistence_mode
if persistence_mode is not None:
if self.persistence_backend is None:
persistence_backend = pw.persistence.Backend.filesystem("./Cache")
else:
persistence_backend = self.persistence_backend
persistence_config = pw.persistence.Config(
persistence_backend,
persistence_mode=persistence_mode,
)
else:
persistence_config = None
pw.run(
persistence_config=persistence_config,
terminate_on_error=self.terminate_on_error,
monitoring_level=pw.MonitoringLevel.NONE,
)
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
if __name__ == "__main__":
base_dir = Path(__file__).resolve().parent
load_dotenv(base_dir / ".env")
with open(base_dir / "app.yaml") as f:
config = pw.load_yaml(f)
app = App(**config)
app.run()
================================================
FILE: templates/slides_ai_search/app.yaml
================================================
# This YAML configuration file is used to set up and configure the Slides Search RAG template.
# It defines various components such as data sources, language models, embedders, indices, and data schema.
# Each section is configured to specify how the template should process and handle data for generating responses.
# You can learn more about the YAML syntax here: https://pathway.com/developers/templates/configure-yaml
# $sources defines the data sources used to read the data which will be indexed in the RAG.
# You can learn more how to configure data sources here:
# https://pathway.com/developers/templates/yaml-examples/data-sources-examples
sources:
# File System connector, reading data locally.
- !pw.io.fs.read
path: data
format: binary
with_metadata: true
# Uncomment to use the SharePoint connector
# - !pw.xpacks.connectors.sharepoint.read
# url: $SHAREPOINT_URL
# tenant: $SHAREPOINT_TENANT
# client_id: $SHAREPOINT_CLIENT_ID
# cert_path: sharepointcert.pem
# thumbprint: $SHAREPOINT_THUMBPRINT
# root_path: $SHAREPOINT_ROOT
# with_metadata: true
# refresh_interval: 30
# Uncomment to use the Google Drive connector
# - !pw.io.gdrive.read
# object_id: $DRIVE_ID
# service_user_credentials_file: gdrive_indexer.json
# file_name_pattern:
# - "*.pdf"
# - "*.pptx"
# object_size_limit: null
# with_metadata: true
# refresh_interval: 30
# Configures the LLM model settings for generating responses.
# The list of available Pathway LLM wrappers is available here:
# https://pathway.com/developers/api-docs/pathway-xpacks-llm/llms
# You can learn more about those in our documentation:
# https://pathway.com/developers/templates/rag-customization/llm-chats
llm: !pw.xpacks.llm.llms.OpenAIChat
model: "gpt-4o"
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy
max_retries: 6
initial_delay: 2500
backoff_factor: 2.5
cache_strategy: !pw.udfs.DefaultCache {}
temperature: 0.0
capacity: 8 # reduce this in case you are hitting API throttle limits
async_mode: "fully_async"
# Specifies the embedder model for converting text into embeddings.
$embedder: !pw.xpacks.llm.embedders.OpenAIEmbedder
cache_strategy: !pw.udfs.DefaultCache {}
retry_strategy: !pw.udfs.ExponentialBackoffRetryStrategy {}
model: "text-embedding-3-small"
# Sets up the retriever factory for indexing and retrieving documents.
retriever_factory: !pw.indexing.UsearchKnnFactory
reserved_space: 1000
embedder: $embedder
metric: !pw.indexing.USearchMetricKind.COS
# Defines the schema used for the data extraction of each slide.
details_schema:
category:
type: option
values:
- "Problem Statement"
- "Solution Overview"
- "Product/Service Demo"
- "Benefits and Value Proposition"
- "Competitive Landscape"
- "Case Studies and Testimonials"
- "Features and Specifications"
- "How it Works"
- "Return on Investment (ROI) and Cost Savings"
- "Call to Action (CTA) and Next Steps"
- "Company Overview and Credentials"
- "Market Opportunity and Trends"
- "Customer Success Stories and Use Cases"
- "Pricing and Packaging"
- "Implementation and Support"
tags:
type: list[str]
description: "Tags associated with the slide. For example ['price', 'shopping', 'consumer'] or ['beverage', 'cola', 'manufacturing']"
title:
type: str
description: "Title of the slide"
main_color:
type: str
description: "Most common color. For example 'black', 'blue', 'yellow'"
language:
type: str
description: "Language of the slide. For example 'fr', 'en'"
has_images:
type: bool
description: "Whether the slide contains photographs"
# Change host and port of the webserver by uncommenting these lines
# host: "0.0.0.0"
# port: $PATHWAY_PORT
# By default, caching is enabled for UDFs with cache_strategy set.
# You can disable it by uncommenting the following line.
# persistence_mode: null
# You can also set persistence_mode to !pw.PersistenceMode.PERSISTING to enable persistence
# across restarts.
# By default, when enabled, Cache is stored in .Cache directory.
# You can customize the location by uncommenting and modifying the following lines:
# persistence_backend: !pw.persistence.Backend.filesystem
# path: ".Cache"
# If `terminate_on_error` is true then the program will terminate whenever any error is encountered.
# Defaults to false, uncomment the following line if you want to set it to true
# terminate_on_error: true
================================================
FILE: templates/slides_ai_search/docker-compose.yml
================================================
services:
app:
build:
context: .
env_file:
- .env
environment:
PATHWAY_PORT: "${PATHWAY_PORT:-8000}"
PATHWAY_LICENSE_KEY: $PATHWAY_LICENSE_KEY
ports:
- "${PATHWAY_PORT:-8000}:${PATHWAY_PORT:-8000}"
networks:
- network
volumes:
- ./data:/app/data
- ./storage/pw_dump_files:/app/storage/pw_dump_files
- ./storage/pw_dump_images:/app/storage/pw_dump_images
- ./Cache:/app/Cache
nginx:
build:
context: nginx
ports:
- "8080:8080"
- "8443:8443"
networks:
- network
volumes:
- ./storage/pw_dump_files:/app/pw_dump_files
- ./storage/pw_dump_images:/app/pw_dump_images
ui:
build:
context: ui
environment:
PATHWAY_HOST: "app"
PATHWAY_PORT: "${PATHWAY_PORT:-8000}"
UI_PORT: 8501
ports:
- "8501:8501"
networks:
- network
networks:
network:
driver: bridge
================================================
FILE: templates/slides_ai_search/nginx/Dockerfile
================================================
FROM nginx:latest
COPY nginx.conf /etc/nginx/conf.d/default.conf
RUN mkdir -p /app/pw_dump_images /app/pw_dump_files
EXPOSE 8080 8443
================================================
FILE: templates/slides_ai_search/nginx/nginx.conf
================================================
server {
listen 8080;
listen 8443;
location = / {
deny all;
}
location /images {
alias /app/pw_dump_images;
autoindex on;
}
location /documents {
alias /app/pw_dump_files;
default_type application/pdf;
add_header Content-Disposition 'inline';
autoindex on;
}
}
================================================
FILE: templates/slides_ai_search/pathway_slides_ai_search/__init__.py
================================================
# Copyright © 2026 Pathway
import base64
import logging
import os
from pathlib import Path
from typing import Any, Literal
import pathway as pw
import yaml
from pathway.xpacks.llm.question_answering import DeckRetriever
from pydantic import BaseModel, Field, create_model
CUSTOM_FIELDS = {"option": Literal}
def get_model_from_file(file_path: str | os.PathLike[str]) -> type[BaseModel]:
"""
Return Pydantic schema from a YAML file.
Replaces types of `CUSTOM_FIELDS` with the definitions, other types are evaluated
as primitive Python type.
Args:
- file_path: Path of the YAML file.
"""
with open(file_path, "r") as file:
schema = yaml.safe_load(file)
return get_model_from_dict(schema)
def get_model_from_dict(schema: dict[str, Any]) -> type[BaseModel]:
fields: dict[str, Any] = {}
if schema.keys() == {"fields"} and "type" not in schema["fields"]:
schema = schema["fields"]
for field_name, field_info in schema.items():
field_type: object
match field_info.pop("type"):
case "option":
field_type = Literal[tuple(field_info.pop("values"))]
case f_type:
field_type = f_type
fields[field_name] = (field_type, Field(**field_info))
return create_model("ParsePydanticSchema", **fields)
def get_model(source: str | os.PathLike[str] | dict[str, Any]) -> type[BaseModel]:
if isinstance(source, dict):
return get_model_from_dict(source)
else:
return get_model_from_file(source)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
force=True, # instructor library overrides `basicConfig`, this fixes logging
)
STORAGE_FOLDER = Path("storage")
IMAGE_DUMP_FOLDER = STORAGE_FOLDER / "pw_dump_images"
FILE_DUMP_FOLDER = STORAGE_FOLDER / "pw_dump_files"
def encode_str(original_string: str) -> str:
return base64.urlsafe_b64encode(original_string.encode("utf-8")).decode("us-ascii")
def add_slide_id(text: str, metadata: dict) -> tuple[str, dict]:
encoded_name = encode_str(metadata["path"])
page = metadata["image_page"]
page_count = metadata["tot_pages"]
slide_id = f"{encoded_name}_{page}_{page_count}.png"
logging.info(f"`add_slide_id` for {slide_id}...")
metadata["slide_id"] = slide_id
return (text, metadata)
class DeckRetrieverWithFileSave(DeckRetriever):
def dump_img_callback(self, key, row, time, is_addition):
# save images parsed by the Pathway
metadata = row["data"]
slide_id = metadata["slide_id"].value
file_path = IMAGE_DUMP_FOLDER / slide_id
if is_addition:
data = base64.b64decode(metadata["b64_image"].value)
file_path.write_bytes(data)
else:
try:
file_path.unlink()
logging.info("Removed %s", file_path)
except Exception as e:
logging.info("Error removing %s: %s", file_path, e)
def dump_file_callback(self, key, row, time, is_addition):
# save parsed files
file_name = row["path"].value.rpartition("/")[-1] # XXX
file_path = FILE_DUMP_FOLDER / file_name
if is_addition:
file_path.write_bytes(row["data"])
else:
try:
file_path.unlink()
logging.info("Removed %s", file_path)
except Exception as e:
logging.info("Error removing %s: %s", file_path, e)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
IMAGE_DUMP_FOLDER.mkdir(parents=True, exist_ok=True)
FILE_DUMP_FOLDER.mkdir(parents=True, exist_ok=True)
chunked_docs = self.indexer.chunked_docs
t = chunked_docs.select(
data=pw.this.metadata,
)
pw.io.subscribe(t, on_change=self.dump_img_callback)
docs = self.indexer.input_docs
t = docs.select(data=docs.text, path=docs.metadata["path"])
pw.io.subscribe(t, on_change=self.dump_file_callback)
================================================
FILE: templates/slides_ai_search/requirements.txt
================================================
python-dotenv~=1.0
================================================
FILE: templates/slides_ai_search/ui/.streamlit/config.toml
================================================
[server]
enableStaticServing = true
[theme]
base = "light"
================================================
FILE: templates/slides_ai_search/ui/Dockerfile
================================================
ARG PATHWAY_SRC_IMAGE=pathwaycom/pathway:latest
FROM ${PATHWAY_SRC_IMAGE}
ENV PYTHONUNBUFFERED=1
WORKDIR /ui
COPY requirements.txt .
RUN pip install -U --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8501
CMD [ "streamlit", "run", "ui.py" ]
================================================
FILE: templates/slides_ai_search/ui/requirements.txt
================================================
streamlit==1.35.0
load_dotenv==0.1.0
nest_asyncio==1.6.0
aiohttp==3.9.5
beautifulsoup4==4.12.3
openai==1.35.10
================================================
FILE: templates/slides_ai_search/ui/ui.py
================================================
# Copyright © 2026 Pathway
import logging
import os
import urllib.parse
from itertools import cycle
from pathlib import PurePosixPath
import requests
import streamlit as st
from bs4 import BeautifulSoup
from dotenv import load_dotenv
from pathway.xpacks.llm.question_answering import RAGClient
load_dotenv()
PATHWAY_HOST = os.environ.get("PATHWAY_HOST", "app")
PATHWAY_PORT = os.environ.get("PATHWAY_PORT", 8000)
st.set_page_config(page_title="Find the right slide", page_icon="favicon.ico")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
force=True,
)
logger = logging.getLogger("streamlit")
logger.setLevel(logging.INFO)
conn = RAGClient(url=f"http://{PATHWAY_HOST}:{PATHWAY_PORT}")
file_server_base_url = os.environ.get("FILE_SERVER_URL", "http://localhost:8080/")
file_server_image_base_url = f"{file_server_base_url}images"
file_server_pdf_base_url = f"{file_server_base_url}documents"
internal_file_server_pdf_base_url = "http://nginx:8080/"
note = """
Search your slide decks"""
st.markdown(note, unsafe_allow_html=True)
st.markdown(
"""
""",
unsafe_allow_html=True,
)
question = st.text_input(label="", placeholder="What are you searching for?")
def get_options_list(metadata_list: list[dict], opt_key: str) -> list:
"""Get all available options in a specific metadata key."""
options = set(map(lambda x: x[opt_key], metadata_list))
return list(options)
def parse_slide_id_components(slide_id: str) -> tuple[str, int, int]:
stem = PurePosixPath(slide_id).stem
(name_page, _, page_count) = stem.rpartition("_")
(name, _, page) = name_page.rpartition("_")
return (name, int(page), int(page_count))
def create_slide_url(name: str, page: int, page_count: int) -> str:
return f"{file_server_image_base_url}/{name}_{page}_{page_count}.png"
def get_image_serve_url(metadata: dict) -> str:
name, page, page_count = parse_slide_id_components(metadata["slide_id"])
return create_slide_url(name, page, page_count)
def get_adjacent_image_urls(metadata: dict) -> list[str]:
logger.info(
{"_type": "create_adjacent_image_urls", "slide_id": metadata["slide_id"]}
)
name, page, page_count = parse_slide_id_components(metadata["slide_id"])
ret_images = []
for page in range(page - 2, page + 3):
if page < 0 or page >= page_count:
continue
ret_images.append(create_slide_url(name, page, page_count))
return ret_images
st.session_state["available_categories"] = None
st.session_state["available_languages"] = None
logger.info("Requesting list_documents...")
document_meta_list = conn.list_documents(keys=[])
logger.info("Received response list_documents")
st.session_state["document_meta_list"] = document_meta_list
available_categories = get_options_list(document_meta_list, "category")
st.session_state["available_categories"] = available_categories
available_languages = get_options_list(document_meta_list, "language")
st.session_state["available_languages"] = available_languages
available_files = get_options_list(st.session_state["document_meta_list"], "path")
def get_slide_link(file_name, page_num=None) -> str:
filename_encoded = urllib.parse.quote(file_name)
image_url = f"{file_server_pdf_base_url}/{filename_encoded}"
if page_num is not None:
image_url += f"#page={page_num}"
return image_url
def get_all_index_files() -> list[str]:
logger.info("request get_all_index_files")
response = requests.get(internal_file_server_pdf_base_url + "/")
logger.info("response get_all_index_files")
if response.status_code == 200:
soup = BeautifulSoup(response.content, "html.parser")
file_links = [a["href"] for a in soup.find_all("a", href=True)]
file_links = [link for link in file_links if not link.endswith("/")]
else:
file_links = []
return file_links
with st.sidebar:
st.info(
"""This demo app only allows `PDF` and `PPTX` documents.
For other file types, convert to `PDF` or contact **Pathway**."""
)
st.info(
body="See the source code [here](https://github.com/pathwaycom/llm-app/tree/main/templates/slides_ai_search).", # noqa: E501
icon=":material/code:",
)
file_names = [i.split("/")[-1] for i in available_files]
links = [get_slide_link(i) for i in file_names]
markdown_table = "| Slides Ready for Search |\n| --- |\n"
for file_name, link in zip(file_names, links):
markdown_table += f"| [{file_name}]({link}) |\n"
st.markdown(markdown_table, unsafe_allow_html=True)
all_drive_files = get_all_index_files()
all_drive_files = [urllib.parse.unquote(i) for i in all_drive_files]
all_drive_files = [
i for i in all_drive_files if i.endswith(".pdf") or i.endswith(".pptx")
]
logger.info(f"All source files: {all_drive_files}\nIndexed files: {file_names}")
currently_processing_files = set(all_drive_files) - set(file_names)
st.markdown("\n\n", unsafe_allow_html=True)
if currently_processing_files:
markdown_table = "| Indexing in Progress |\n| --- |\n"
links = [get_slide_link(i) for i in currently_processing_files]
for file_name, link in zip(currently_processing_files, links):
markdown_table += f"| [{file_name}]({link}) |\n"
st.markdown(markdown_table, unsafe_allow_html=True)
else:
st.markdown("## All files indexed.")
st.button("⟳ Refresh", use_container_width=True)
category_options = st.session_state["available_categories"]
lang_options = st.session_state["available_languages"]
cols = cycle(st.columns(2))
with next(cols):
cat_options = st.multiselect(
"Filtered Categories",
category_options or [],
[],
key="cat_selection",
label_visibility="hidden",
placeholder="Filtered Categories",
)
with next(cols):
language_options = st.multiselect(
"Languages",
lang_options or [],
[],
key="lang_selection",
label_visibility="hidden",
placeholder="Filtered Languages",
)
with st.sidebar:
cat_prefix = "cat_"
logger.info("All category options: %s", category_options)
selected_categories = category_options if len(cat_options) == 0 else cat_options
logger.info("Selected categories: %s", selected_categories)
lang_prefix = "lang_"
selected_languages = (
lang_options if len(language_options) == 0 else language_options
)
st.session_state.category_filter = selected_categories
st.session_state.language_filter = selected_languages
def get_category_filter(category: str) -> str:
return f"contains(`{str(category)}`, category)"
# TODO: merge these
def get_language_filter(lang: str) -> str:
return f"contains(`{str(lang)}`, language)"
def combine_filters(*args: str | None) -> str:
"""Construct single jmespath filter with `&&` from number of filters."""
return " && ".join([arg for arg in args if arg is not None])
css = """
"""
st.markdown(css, unsafe_allow_html=True)
def get_ext_img_with_href(url, target_url, *args) -> str:
width: int = 600
margin = 20
def get_img_html(dc):
return f"""
"""
slider_images = "\n".join([get_img_html(dc) for dc in args])
html_code = f"""
""" # noqa: E501
return html_code
def log_rate_answer(event, idx, kwargs):
logger.info({"_type": "rate_event", "rating": event, "rank": idx, **kwargs})
if question:
select_cat = st.session_state.category_filter
select_lang = st.session_state.language_filter
filter_ls = [get_category_filter(select_cat), get_language_filter(select_lang)]
combined_query_filter = combine_filters(*filter_ls)
logger.info(
{
"_type": "search_request_event",
"filter": combined_query_filter,
"query": question,
}
)
response = conn.answer(question, filters=combined_query_filter)
logger.info(
{
"_type": "search_response_event",
"filter": combined_query_filter,
"query": question,
"response": type(response),
}
)
if response:
logger.info(type(response[0]))
text_responses = [r["text"] for r in response]
image_metadatas = [r["metadata"] for r in response]
for m in image_metadatas:
logger.info("Retrieved metadatas: %s || %s", m["language"], m["category"])
st.markdown(f"**Searched for:** {question}")
for idx, cur_metadata in enumerate(image_metadatas):
file_name = cur_metadata["path"].split("/")[-1]
select_page = cur_metadata["image_page"] + 1
adjacent_urls = get_adjacent_image_urls(cur_metadata)
args = [{"url": i} for i in adjacent_urls]
image_html = get_ext_img_with_href(
get_image_serve_url(cur_metadata),
get_slide_link(file_name, select_page),
*args,
)
image_url = get_slide_link(file_name, select_page)
slide_id = cur_metadata["slide_id"]
st.markdown(f"Page `{select_page}` of [`{file_name}`]({image_url})")
st.markdown(image_html, unsafe_allow_html=True)
log_args = (
idx,
{
"slide_id": slide_id,
"filter": combined_query_filter,
"query": question,
"file_name": file_name,
"selected_cat": select_cat,
"selected_lang": select_lang,
},
)
col1, col2, col3 = st.columns([12, 1, 1])
else:
st.markdown(
f"""No results were found for search query: `{question}`
and filter criteria: `{combined_query_filter}`"""
)
================================================
FILE: templates/unstructured_to_sql_on_the_fly/Dockerfile
================================================
FROM pathwaycom/pathway:latest
WORKDIR /app
RUN apt-get update \
&& apt-get install -y python3-opencv \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
COPY requirements.txt .
RUN pip install --pre -U --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8080
CMD ["python", "app.py"]
================================================
FILE: templates/unstructured_to_sql_on_the_fly/README.md
================================================
Deploy with GCP |
Deploy with AWS |
Deploy with Azure |
Deploy with Render
# Pathway + PostgreSQL + LLM: app for querying financial reports with live document structuring pipeline
The aim of this pipeline is to extract and structure the data out of unstructured data (PDFs, queries)
on the fly.
This example consists of two separate parts that can be used independently.
1 - Pipeline 1: Proactive data pipeline that is always live and tracking file changes,
it reads documents, structures them and writes results to PostgreSQL.
2 - Pipeline 2: Query answering pipeline that reads user queries, and answers them by
generating SQL queries that are run on the data stored in PostgreSQL.
Specifically, Pipeline 1 reads in a collection of financial PDF documents from a local directory
(that can be synchronized with a Dropbox account), tokenizes each document using the tiktoken encoding,
then extracts, using the OpenAI API, the wanted fields.
The values are stored in a Pathway table which is then output to a PostgreSQL instance.
Pipeline 2 then starts a REST API endpoint serving queries about programming in Pathway.
Each query text is converted into a SQL query using the OpenAI API.
Architecture diagram and description are at
https://pathway.com/developers/templates/rag/unstructured-to-structured
⚠️ This project requires a running PostgreSQL instance.
🔵 The extracted fields from the PDFs documents are the following:
- company_symbol: str
- year: int
- quarter: str
- revenue_md: float
- eps: float
- net_income_md: float
⚠️ The revenue and net income are expressed in millions of dollars, the eps is in dollars.
🔵 The script uses a prompt to instruct the Language Model and generate SQL queries that adhere to the specified format.
The allowed queries follow a particular pattern:
1. The SELECT clause should specify columns or standard aggregator operators (SUM, COUNT, MIN, MAX, AVG).
2. The WHERE clause should include conditions using standard binary operators (<, >, =, etc.),
with support for AND and OR logic.
3. To prevent 'psycopg2.errors.GroupingError', relevant columns from the WHERE clause are included
in the GROUP BY clause.
4. For readability, if no aggregator is used, the company_symbol, year,
and quarter are included in addition to the wanted columns.
Example:
"What is the net income of all companies?" should return:
Response:
'SELECT company_symbol, net_income_md, quarter, net_income_md FROM table;'
## Project architecture:
```
.
├── postgresql/
│ └── init-db.sql
├── ui/
│ └── server.py
├── __init__.py
├── app.py
└── docker-compose.yml
```
## Running the Pipeline
### Setup environment:
Set your env variables in the .env file placed in this directory.
```bash
OPENAI_API_KEY=sk-...
PATHWAY_PERSISTENT_STORAGE= # Set this variable if you want to use caching
```
### With Docker
To run jointly the Unstructured to SQL on the fly pipeline and a simple UI please execute:
```bash
docker compose up --build
```
Then, the UI will run at http://127.0.0.1:8501 by default. You can access it by following this URL in your web browser.
The `docker-compose.yml` file declares a [volume bind mount](https://docs.docker.com/reference/cli/docker/container/run/#volume) that makes changes to files under `data/` made on your host computer visible inside the docker container. The files in `data/quarterly_earnings` are indexed by the pipeline - you can paste new files there and they will impact the computations.
### Manually
Alternatively, you can run each service separately. To run PostgreSQL use Docker. To run it, run:
`docker compose up -d postgres`.
To install the dependencies, run:
`pip install -r requirements.txt`
Then run:
`python app.py`
This will run the pipeline, which you can access through REST API at `localhost:8080`. For example, you can send questions using curl:
```
curl --data '{
"user": "user",
"query": "What is the maximum quarterly revenue achieved by Apple?"
}' http://localhost:8080/ | jq
```
You can also run the Streamlit interface:
`streamlit run ui/server.py`
================================================
FILE: templates/unstructured_to_sql_on_the_fly/__init__.py
================================================
from .app import run
__all__ = ["run"]
================================================
FILE: templates/unstructured_to_sql_on_the_fly/app.py
================================================
"""
Microservice for accounting assistant.
The aim of this project is to extract and structure the data out of unstructured data (PDFs, queries)
on the fly.
This example consists of two separate parts that can be used independently.
1 - Pipeline 1: Proactive data pipeline that is always live and tracking file changes,
it reads documents, structures them and writes results to PostgreSQL.
2 - Pipeline 2: Query answering pipeline that reads user queries, and answers them by
generating SQL queries that are run on the data stored in PostgreSQL.
Specifically, Pipeline 1 reads in a collection of financial PDF documents from a local directory
(that can be synchronized with a Dropbox account), tokenizes each document using the tiktoken encoding,
then extracts, using the OpenAI API, the wanted fields.
The values are stored in a Pathway table which is then output to a PostgreSQL instance.
Pipeline 2 then starts a REST API endpoint serving queries about programming in Pathway.
Each query text is converted into a SQL query using the OpenAI API.
Architecture diagram and description are at
https://pathway.com/developers/templates/rag/unstructured-to-structured
⚠️ This project requires a running PostgreSQL instance.
🔵 The extracted fields from the PDFs documents are the following:
- company_symbol: str
- year: int
- quarter: str
- revenue_md: float
- eps: float
- net_income_md: float
⚠️ The revenue and net income are expressed in millions of dollars, the eps is in dollars.
🔵 The script uses a prompt to instruct the Language Model and generate SQL queries that adhere to the specified format.
The allowed queries follow a particular pattern:
1. The SELECT clause should specify columns or standard aggregator operators (SUM, COUNT, MIN, MAX, AVG).
2. The WHERE clause should include conditions using standard binary operators (<, >, =, etc.),
with support for AND and OR logic.
3. To prevent 'psycopg2.errors.GroupingError', relevant columns from the WHERE clause are included
in the GROUP BY clause.
4. For readability, if no aggregator is used, the company_symbol, year,
and quarter are included in addition to the wanted columns.
Example:
"What is the net income of all companies?" should return:
Response:
'SELECT company_symbol, net_income_md, quarter, net_income_md FROM table;'
Please check the README.md in this directory for how-to-run instructions.
"""
import json
import logging
import os
import dotenv
import pathway as pw
import psycopg
import tiktoken
from pathway.stdlib.utils.col import unpack_col
from pathway.xpacks.llm.llms import OpenAIChat, prompt_chat_single_qa
from pathway.xpacks.llm.parsers import UnstructuredParser
# To use advanced features with Pathway Scale, get your free license key from
# https://pathway.com/features and paste it below.
# To use Pathway Community, comment out the line below.
pw.set_license_key("demo-license-key-with-telemetry")
dotenv.load_dotenv()
class FinancialStatementSchema(pw.Schema):
company_symbol: str
year: int
quarter: str
revenue_md: float
eps: float
net_income_md: float
class NLQuerySchema(pw.Schema):
query: str
user: str
@pw.udf
def build_prompt_structure(
texts: list[str],
max_tokens: int = 8000,
encoding_name: str = "cl100k_base",
):
"""
Insert instructions for the LLM here.
max_tokens for the context. If gpt-3.5-turbo-16k is used, set it to 16k.
"""
docs_str = " ".join(texts)
encoding = tiktoken.get_encoding(encoding_name)
prompt_prefix = "Given the following quarterly earnings release : \n"
prompt_suffix = (
f" \nfill in this schema for the quarter in question {FinancialStatementSchema.typehints()}\n"
+ """while respecting the instructions:
- amounts should be in millions of dollars.
- Parse quarterly data and ignore yearly records if present.
- Your answer should be parseable by json. i.e. json.loads(response) doesn't throw any errors."""
)
prefix_tokens = len(list(encoding.encode_ordinary(prompt_prefix)))
suffix_tokens = len(list(encoding.encode_ordinary(prompt_suffix)))
# Calculate available tokens for docs_str
available_tokens = max_tokens - (prefix_tokens + suffix_tokens)
# Tokenize docs_str and truncate if needed
doc_tokens = list(encoding.encode_ordinary(docs_str))
if len(doc_tokens) > available_tokens:
logging.warning("Document is too large for one query.")
docs_str = encoding.decode(doc_tokens[:available_tokens])
prompt = prompt_prefix + docs_str + prompt_suffix
return prompt
@pw.udf
def build_prompt_query(postresql_table: str, query: str) -> str:
prompt = f"""Transform the given query '{query}' into a specific SQL SELECT statement format.
For invalid queries, return the string 'None'. The result should be executable in PostgreSQL.
The query should include the following components:
The SELECT clause should specify one or more columns from the table {postresql_table}.
You can use column names or standard aggregator operators such as SUM, COUNT, MIN, MAX, or AVG
to retrieve data from the columns.
The WHERE clause should include conditions that use standard binary operators (e.g., <, >, =) to filter the data.
You can use AND and OR operators to combine multiple conditions.
If any columns from the WHERE clause are used in the conditions, please ensure that those columns are included
in the GROUP BY clause to prevent the 'psycopg2.errors.GroupingError.'
You may use logical reasoning to decide which columns should be part of the GROUP BY clause.
The columns are from {postresql_table} table whose schema is:
company_symbol (str)
year (int)
quarter (str)
revenue_md (float)
eps (float)
net_income_md (float)
Quarter values are Q1, Q2, Q3 or Q4.
The company_symbol is the stock name: for example AAPL for Apple and GOOG for Google.
If no aggregator are used, please always add the company_symbol, year,
and quarter in addition of the wanted columns:
"What is the net income of all companies?" should return:
'SELECT company_symbol, net_income_md, quarter, net_income_md FROM {postresql_table};'
Please ensure that the generated SQL query follows this structure and constraints.
For example, a valid query might look like:
'SELECT company_symbol, SUM(net_income_md) FROM {postresql_table}
WHERE year = 2022 AND eps > 1.0 GROUP BY company_symbol;'
Make sure the query adheres to the specified format, and that it includes GROUP BY clause
if you aggregate results
and do not include any other SQL commands or clauses besides the SELECT statement.
Thank you!"""
return prompt
@pw.udf
def parse_str_to_list(response: str) -> list:
dct = json.loads(response)
return [dct[k] for k in sorted(dct)]
def structure_on_the_fly(
documents: pw.Table,
api_key: str,
model_locator: str,
max_tokens: int,
temperature: float,
):
prompt = documents.select(prompt=build_prompt_structure(pw.this.texts))
model = OpenAIChat(
api_key=api_key,
model=model_locator,
temperature=temperature,
max_tokens=max_tokens,
retry_strategy=pw.udfs.ExponentialBackoffRetryStrategy(),
cache_strategy=pw.udfs.DefaultCache(),
)
responses = prompt.select(
result=model(prompt_chat_single_qa(pw.this.prompt)),
)
responses = responses.select(values=parse_str_to_list(pw.this.result))
result = unpack_col(responses.values, *sorted(FinancialStatementSchema.keys()))
result = result.with_columns(
eps=pw.apply(float, pw.this.eps),
net_income_md=pw.apply(float, pw.this.net_income_md),
revenue_md=pw.apply(float, pw.this.revenue_md),
)
return result
def unstructured_query(
postgreSQL_settings,
postgreSQL_table,
api_key: str,
model_locator: str,
max_tokens: int,
temperature: float,
host: str,
port: int,
):
query, response_writer = pw.io.http.rest_connector(
host=host,
port=port,
schema=NLQuerySchema,
autocommit_duration_ms=50,
delete_completed_queries=True,
)
query += query.select(prompt=build_prompt_query(postgreSQL_table, pw.this.query))
model = OpenAIChat(
api_key=api_key,
model=model_locator,
temperature=temperature,
max_tokens=max_tokens,
retry_strategy=pw.udfs.ExponentialBackoffRetryStrategy(),
cache_strategy=pw.udfs.DefaultCache(),
)
query += query.select(
sql_query=model(prompt_chat_single_qa(pw.this.prompt)),
)
# Connecting to the document database for queries
connection_string = psycopg.conninfo.make_conninfo(**postgreSQL_settings)
conn = psycopg.connect(connection_string)
cursor = conn.cursor()
@pw.udf
def execute_sql_query(sql_query):
cursor.execute(sql_query)
answer = cursor.fetchall()
# answer = answer[0][0]
conn.commit()
return answer
query = query.select(
pw.this.query,
pw.this.sql_query,
result=execute_sql_query(
pw.this.sql_query,
),
)
answers = query.select(result=pw.make_tuple(pw.this.sql_query, pw.this.result))
response_writer(answers)
@pw.udf
def strip_metadata(docs: list[tuple[str, dict]]) -> list[str]:
return [doc[0] for doc in docs]
def run(
*,
data_dir: str = os.environ.get("PATHWAY_DATA_DIR", "./data/quarterly_earnings"),
api_key: str = os.environ.get("OPENAI_API_KEY", ""),
host: str = os.environ.get("PATHWAY_REST_CONNECTOR_HOST", "0.0.0.0"),
port: int = int(os.environ.get("PATHWAY_REST_CONNECTOR_PORT", "8080")),
model_locator: str = "gpt-3.5-turbo", # "gpt-4", # gpt-3.5-turbo-16k
max_tokens: int = 120,
temperature: float = 0.0,
postresql_host: str = os.environ.get("POSTGRESQL_HOST", "localhost"),
postresql_port: str = os.environ.get("POSTGRESQL_PORT", "5432"),
postresql_db: str = os.environ.get("POSTGRESQL_DB", "STRUCTUREDDB"),
postresql_user: str = os.environ.get("POSTGRESQL_USER", "user"),
postresql_password: str = os.environ.get("POSTGRESQL_PASSWORD", "password"),
postresql_table: str = os.environ.get("POSTGRESQL_TABLE", "quarterly_earnings"),
**kwargs,
):
#
# # Pipeline 1 - parsing documents into a PostgreSql table
#
postgreSQL_settings = {
"host": postresql_host,
"port": postresql_port,
"dbname": postresql_db,
"user": postresql_user,
"password": postresql_password,
}
files = pw.io.fs.read(
data_dir,
format="binary",
)
parser = UnstructuredParser()
unstructured_documents = files.select(texts=parser(pw.this.data)).select(
texts=strip_metadata(pw.this.texts)
)
structured_table = structure_on_the_fly(
unstructured_documents, api_key, model_locator, max_tokens, temperature
)
pw.io.postgres.write(structured_table, postgreSQL_settings, postresql_table)
pw.io.csv.write(structured_table, "./data/quarterly_earnings.csv")
#
# # Pipeline 2 - query answering using PostgreSql
#
unstructured_query(
postgreSQL_settings,
postresql_table,
api_key,
model_locator,
max_tokens,
temperature,
host,
port,
)
pw.run(monitoring_level=pw.MonitoringLevel.NONE)
if __name__ == "__main__":
run()
================================================
FILE: templates/unstructured_to_sql_on_the_fly/docker-compose.yml
================================================
version: "3.8"
services:
postgres:
container_name: postgres
image: postgres
ports:
- 5432:5432
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=STRUCTUREDDB
- PGPASSWORD=password
volumes:
- ./postgres/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
expose:
- 5432
healthcheck:
test:
[
"CMD-SHELL",
"pg_isready -h 0.0.0.0 -p 5432 -U user -d STRUCTUREDDB"
]
interval: 5s
timeout: 5s
retries: 5
pathway:
depends_on:
postgres:
condition: service_healthy
build:
context: .
ports:
- "8080:8080"
environment:
OPENAI_API_KEY: "${OPENAI_API_KEY}"
PATHWAY_REST_CONNECTOR_HOST:
PATHWAY_REST_CONNECTOR_PORT:
PATHWAY_PERSISTENT_STORAGE:
POSTGRESQL_HOST: "postgres"
volumes:
- "./data:/app/data"
streamlit_ui:
depends_on:
- pathway
build:
context: ./ui
ports:
- "8501:8501"
environment:
PATHWAY_HOST: "pathway"
PATHWAY_PORT: "8080"
================================================
FILE: templates/unstructured_to_sql_on_the_fly/postgres/init-db.sql
================================================
CREATE TABLE IF NOT EXISTS quarterly_earnings (
company_symbol TEXT NOT NULL,
eps FLOAT NOT NULL,
net_income_md FLOAT NOT NULL,
quarter TEXT NOT NULL,
revenue_md FLOAT NOT NULL,
year BIGINT NOT NULL,
time BIGINT NOT NULL,
diff INTEGER NOT NULL
);
================================================
FILE: templates/unstructured_to_sql_on_the_fly/requirements.txt
================================================
python-dotenv~=1.0
psycopg~=3.1
================================================
FILE: templates/unstructured_to_sql_on_the_fly/ui/Dockerfile
================================================
FROM python:3.11
WORKDIR /app
RUN pip install streamlit
COPY . .
EXPOSE 8501
CMD ["streamlit", "run", "server.py", "--server.port", "8501", "--server.address", "0.0.0.0"]
================================================
FILE: templates/unstructured_to_sql_on_the_fly/ui/server.py
================================================
import os
import pandas as pd
import requests
import streamlit as st
api_host = os.environ.get("PATHWAY_HOST", "localhost")
api_port = os.environ.get("PATHWAY_PORT", 8000)
with st.sidebar:
st.markdown(
"## How to query your data\n"
"Enter your question about financial data\n"
"Example: What is the average quarterly net income achieved by all companies in the fourth quarter?"
)
st.markdown("---")
st.markdown("# Units")
st.markdown(
"⚠️ The revenue and net income are expressed in millions of dollars,"
" the eps is in dollars per share."
)
st.markdown("---")
st.markdown("# About")
st.markdown(
"Financial LLM app to synthesize on the fly the data in your financial documents."
"It uses Pathway's [LLM App features](https://github.com/pathwaycom/llm-app) "
"to build and maintain a real-time database and synthesize your documents "
" using LLM(Large Language Model) and store the data in PostgreSQL.\n"
)
st.markdown(
"""[View the source code on GitHub](
https://github.com/pathwaycom/llm-app/templates/unstructured_to_sql_on_the_fly/app.py)"""
)
# Streamlit UI elements
st.title("📈 Financial summary with LLM App")
question = st.text_input(
"Search for something",
placeholder="What summary are looking for?",
)
def json_to_table(json_value):
result = ""
for row in json_value:
for col_value in row:
result = result + str(col_value) + "\t"
result = result + "\n"
return result
# Handle Discounts API request if data source is selected and a question is provided
if question:
url = f"http://{api_host}:{api_port}/"
try:
data = {"user": "user", "query": question}
response = requests.post(url, json=data)
if response.status_code == 200:
response_JSON = response.json()
sql_query = response_JSON[0]
answer = response_JSON[1]
dataframe = pd.DataFrame.from_records(answer)
st.write("### Answer")
st.write("Resulting SQL query:")
st.write(sql_query)
st.write("SQL Answer:")
st.dataframe(dataframe)
else:
st.error(
f"Failed to send data to Finance API. Status code: {response.status_code}"
)
except Exception as e:
st.write("### Parsing error:")
st.write("Couldn't parse the entry.")
st.write(str(e))