Merge branch 'basic_set_up_RAG' into 1-langfuse-integration-for-llm-process-monitoring-and-prompt-management
Browse files- .gitignore +1 -1
- README.md +34 -33
- app.py +0 -6
- conversation/main.py +0 -79
- ingestion/main.py +0 -18
- static/style.css +0 -1
.gitignore
CHANGED
|
@@ -16,5 +16,5 @@ wheels/
|
|
| 16 |
.gradio
|
| 17 |
*.log
|
| 18 |
|
| 19 |
-
#
|
| 20 |
*.ipynb
|
|
|
|
| 16 |
.gradio
|
| 17 |
*.log
|
| 18 |
|
| 19 |
+
# sandboxes
|
| 20 |
*.ipynb
|
README.md
CHANGED
|
@@ -7,23 +7,33 @@ This is the code repository for the DEval project "Durchführung und Unterstütz
|
|
| 7 |
|
| 8 |
- **[Get Started](#get-started)**
|
| 9 |
|
| 10 |
-
- [
|
| 11 |
-
- [
|
| 12 |
-
- [
|
| 13 |
-
|
| 14 |
-
- [Contribute](#contribute)
|
| 15 |
-
- [Unit Tests](#unit-tests)
|
| 16 |
-
- [Deploy to Heroku](#deploy-to-heroku)
|
| 17 |
-
- [Support](#support)
|
| 18 |
-
- [License](#license)
|
| 19 |
|
| 20 |
---
|
| 21 |
|
| 22 |
## Get started
|
| 23 |
|
| 24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
-
###
|
| 27 |
We use `uv` as a python and our package dependency manager. Follow these [instructions](https://docs.astral.sh/uv/getting-started/installation/) to install with the standalone installer and `curl`
|
| 28 |
|
| 29 |
Next, to set up the local dependencies. You can find further information [here](https://docs.astral.sh/uv/guides/projects/#managing-dependencies)
|
|
@@ -31,16 +41,19 @@ Next, to set up the local dependencies. You can find further information [here](
|
|
| 31 |
uv sync
|
| 32 |
```
|
| 33 |
|
| 34 |
-
This should give you a package structure like this with a `.venv`
|
| 35 |
```
|
| 36 |
.
|
| 37 |
├── .venv
|
| 38 |
├── .python-version
|
|
|
|
|
|
|
| 39 |
├── README.md
|
| 40 |
-
|
| 41 |
-
└── pyproject.toml
|
| 42 |
```
|
| 43 |
|
|
|
|
|
|
|
| 44 |
|
| 45 |
Alternatively, with a different dependency manager such as `venv` install directly from `pyproject.toml`.
|
| 46 |
```Bash
|
|
@@ -49,27 +62,15 @@ Alternatively, with a different dependency manager such as `venv` install direct
|
|
| 49 |
**Note**: the dependencies then need to be documented manually in the `pyproject.toml`.
|
| 50 |
|
| 51 |
|
| 52 |
-
### Set up `.env` file for secrets
|
| 53 |
-
Locally set up a `.env` file for secrets. You require connection to an LLM, an embedding provider, and API keys for the Langfuse integration. The latter you can acquire after setting up a Langfuse project in the Langfuse GUI, either through a local setup or via Langfuse Cloud.
|
| 54 |
-
|
| 55 |
-
Here is how the `.env` file should look like:
|
| 56 |
-
```
|
| 57 |
-
# .env
|
| 58 |
-
LLM_API_KEY= # Your LLM API key
|
| 59 |
-
|
| 60 |
-
# Langfuse credentials
|
| 61 |
-
LANGFUSE_PUBLIC_API_KEY= # Your Langfuse public API key
|
| 62 |
-
LANGFUSE_SECRET_API_KEY= # Your Langfuse secret API key
|
| 63 |
-
LANGFUSE_HOST="https://cloud.langfuse.com" # EU server for langfuse Cloud, can be different for other deployments
|
| 64 |
-
```
|
| 65 |
-
**Note**: the `.env` file is not version-controlled.
|
| 66 |
-
|
| 67 |
### Setup for Langfuse Prompt Management
|
| 68 |
Langfuse Prompt Management is used within this project. Therefore, setting up the prompt templates within Langfuse is mandatory. As the prompts directly integrate with the code, alignment is necessary. Current setup requirements can be provided by the maintainers.
|
| 69 |
|
| 70 |
-
## To-Do
|
| 71 |
-
- create bsaic set-up with Qdrant in memory, ingestion pipeline
|
| 72 |
-
- create basic set-up where retrieval is not yet having an llm call
|
| 73 |
-
- connect to frontend with "invoke" and deletion of memory
|
| 74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
|
|
|
|
|
|
| 7 |
|
| 8 |
- **[Get Started](#get-started)**
|
| 9 |
|
| 10 |
+
- [Set up `.env` file](#set-up-env-file)
|
| 11 |
+
- [Set up the environment](#set-up-the-environment)
|
| 12 |
+
- [Setup for Langfuse Prompt Management](#setup-for-langfuse-prompt-management)
|
| 13 |
+
- [Run the code](#run-the-code)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
---
|
| 16 |
|
| 17 |
## Get started
|
| 18 |
|
| 19 |
+
### Set up `.env` file
|
| 20 |
+
To run, the project expects secret keys from a `.env` file. Locally set up this `.env` file. You require connection to an LLM, an embedding provider, and API keys for the Langfuse integration. The latter you can acquire after setting up a Langfuse project in the Langfuse GUI, either through a local setup or via Langfuse Cloud.
|
| 21 |
+
|
| 22 |
+
Here how the `.env` file should look like:
|
| 23 |
+
|
| 24 |
+
```
|
| 25 |
+
# .env
|
| 26 |
+
LLM_API_KEY= # Your LLM API key
|
| 27 |
+
|
| 28 |
+
# Langfuse credentials
|
| 29 |
+
LANGFUSE_PUBLIC_API_KEY= # Your Langfuse public API key
|
| 30 |
+
LANGFUSE_SECRET_API_KEY= # Your Langfuse secret API key
|
| 31 |
+
LANGFUSE_HOST="https://cloud.langfuse.com" # EU server for langfuse Cloud, can be different for other deployments
|
| 32 |
+
```
|
| 33 |
+
**Note**: Due to security reasons, this file should not be committed to version control!
|
| 34 |
+
|
| 35 |
|
| 36 |
+
### Set up the environment
|
| 37 |
We use `uv` as a python and our package dependency manager. Follow these [instructions](https://docs.astral.sh/uv/getting-started/installation/) to install with the standalone installer and `curl`
|
| 38 |
|
| 39 |
Next, to set up the local dependencies. You can find further information [here](https://docs.astral.sh/uv/guides/projects/#managing-dependencies)
|
|
|
|
| 41 |
uv sync
|
| 42 |
```
|
| 43 |
|
| 44 |
+
This should give you a package structure like this with a `.venv` directory:
|
| 45 |
```
|
| 46 |
.
|
| 47 |
├── .venv
|
| 48 |
├── .python-version
|
| 49 |
+
├── app.py
|
| 50 |
+
├── pyproject.toml
|
| 51 |
├── README.md
|
| 52 |
+
└── uv.lock
|
|
|
|
| 53 |
```
|
| 54 |
|
| 55 |
+
#### uv.lock
|
| 56 |
+
`uv.lock` is a cross-platform lockfile that contains exact information about the project's dependencies. Unlike the `pyproject.toml` which is used to specify the broad requirements of the project, the lockfile contains the exact resolved versions that are installed in the project environment via `uv`. This file should be checked into version control, allowing for consistent and reproducible installations across machines. `uv.lock` is a human-readable TOML file but is managed by `uv` and should NOT be edited manually.
|
| 57 |
|
| 58 |
Alternatively, with a different dependency manager such as `venv` install directly from `pyproject.toml`.
|
| 59 |
```Bash
|
|
|
|
| 62 |
**Note**: the dependencies then need to be documented manually in the `pyproject.toml`.
|
| 63 |
|
| 64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
### Setup for Langfuse Prompt Management
|
| 66 |
Langfuse Prompt Management is used within this project. Therefore, setting up the prompt templates within Langfuse is mandatory. As the prompts directly integrate with the code, alignment is necessary. Current setup requirements can be provided by the maintainers.
|
| 67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
+
### Run the code
|
| 70 |
+
After installing the needed dependencies for the project and setting up the environment, execute the code from the root of the repository by running the `app.py` script via `uv` with the following command:
|
| 71 |
+
|
| 72 |
+
```Bash
|
| 73 |
+
uv run app.py
|
| 74 |
+
```
|
| 75 |
|
| 76 |
+
You will see the logging in the terminal and receive a link to access the currently locally hosted Gradio User Interface.
|
app.py
CHANGED
|
@@ -98,11 +98,6 @@ graph_builder.add_edge("generate", END)
|
|
| 98 |
graph = graph_builder.compile(checkpointer=memory)
|
| 99 |
# -----
|
| 100 |
|
| 101 |
-
with open("static/style.css", "r") as f:
|
| 102 |
-
css = f.read()
|
| 103 |
-
logger.info("Successfully loaded styles.")
|
| 104 |
-
|
| 105 |
-
|
| 106 |
def bot(message, history) -> list[Any]:
|
| 107 |
"""Generate bot response and history from message.
|
| 108 |
|
|
@@ -143,7 +138,6 @@ demo = gr.ChatInterface(
|
|
| 143 |
textbox=gr.MultimodalTextbox(file_count="multiple"),
|
| 144 |
title="DEval Prototype 1",
|
| 145 |
description="I am a playground to test Citation and the Basic set-up.",
|
| 146 |
-
css=css
|
| 147 |
)
|
| 148 |
|
| 149 |
if __name__ == "__main__":
|
|
|
|
| 98 |
graph = graph_builder.compile(checkpointer=memory)
|
| 99 |
# -----
|
| 100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
def bot(message, history) -> list[Any]:
|
| 102 |
"""Generate bot response and history from message.
|
| 103 |
|
|
|
|
| 138 |
textbox=gr.MultimodalTextbox(file_count="multiple"),
|
| 139 |
title="DEval Prototype 1",
|
| 140 |
description="I am a playground to test Citation and the Basic set-up.",
|
|
|
|
| 141 |
)
|
| 142 |
|
| 143 |
if __name__ == "__main__":
|
conversation/main.py
DELETED
|
@@ -1,79 +0,0 @@
|
|
| 1 |
-
# from langchain.chat_models import init_chat_model
|
| 2 |
-
# from langchain_core.tools import tool
|
| 3 |
-
# from langchain_openai import OpenAIEmbeddings
|
| 4 |
-
# from langchain_qdrant import QdrantVectorStore
|
| 5 |
-
# from langgraph.checkpoint.memory import MemorySaver
|
| 6 |
-
# from langgraph.graph import MessagesState, StateGraph, END
|
| 7 |
-
# from langgraph.prebuilt import ToolNode, tools_condition
|
| 8 |
-
# from langgraph.prebuilt import ToolNode
|
| 9 |
-
# from qdrant_client import QdrantClient
|
| 10 |
-
# from qdrant_client.http.models import Distance, VectorParams, SparseVectorParams
|
| 11 |
-
|
| 12 |
-
# from config import app_settings
|
| 13 |
-
# from conversation.generate import generate
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
# llm = init_chat_model(
|
| 17 |
-
# app_settings.llm_model,
|
| 18 |
-
# model_provider="openai",
|
| 19 |
-
# api_key=app_settings.llm_api_key
|
| 20 |
-
# )
|
| 21 |
-
|
| 22 |
-
# embeddings = OpenAIEmbeddings(
|
| 23 |
-
# model=app_settings.embedding_model,
|
| 24 |
-
# api_key=app_settings.llm_api_key
|
| 25 |
-
# )
|
| 26 |
-
|
| 27 |
-
# client = QdrantClient(app_settings.vector_db_url)
|
| 28 |
-
# if not client.collection_exists(app_settings.vector_db_collection_name):
|
| 29 |
-
# client.create_collection(
|
| 30 |
-
# collection_name=app_settings.vector_db_collection_name,
|
| 31 |
-
# vectors_config=VectorParams(size=app_settings.embedding_size, distance=Distance.COSINE),
|
| 32 |
-
# sparse_vectors_config={'langchain-sparse': SparseVectorParams(index=None, modifier=None)}
|
| 33 |
-
# )
|
| 34 |
-
|
| 35 |
-
# vector_store = QdrantVectorStore(
|
| 36 |
-
# client=client,
|
| 37 |
-
# collection_name=app_settings.vector_db_collection_name,
|
| 38 |
-
# embedding=embeddings,
|
| 39 |
-
# )
|
| 40 |
-
|
| 41 |
-
# @tool(response_format="content_and_artifact")
|
| 42 |
-
# def retrieve(query: str):
|
| 43 |
-
# """Retrieve information related to a query."""
|
| 44 |
-
# retrieved_docs = vector_store.similarity_search(query, k=2)
|
| 45 |
-
# serialized = "\n\n".join(
|
| 46 |
-
# (f"Source: {doc.metadata}\n" f"Content: {doc.page_content}")
|
| 47 |
-
# for doc in retrieved_docs
|
| 48 |
-
# )
|
| 49 |
-
# return serialized, retrieved_docs
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
# def query_or_respond(state: MessagesState):
|
| 53 |
-
# """Generate tool call for retrieval or respond."""
|
| 54 |
-
# llm_with_tools = llm.bind_tools([retrieve])
|
| 55 |
-
# response = llm_with_tools.invoke(state["messages"])
|
| 56 |
-
# # MessagesState appends messages to state instead of overwriting
|
| 57 |
-
# return {"messages": [response]}
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
# graph_builder = StateGraph(MessagesState)
|
| 61 |
-
# tools = ToolNode([retrieve])
|
| 62 |
-
# memory = MemorySaver()
|
| 63 |
-
|
| 64 |
-
# graph_builder.add_node(query_or_respond)
|
| 65 |
-
# graph_builder.add_node(tools)
|
| 66 |
-
# graph_builder.add_node(generate)
|
| 67 |
-
|
| 68 |
-
# graph_builder.set_entry_point("query_or_respond")
|
| 69 |
-
|
| 70 |
-
# graph_builder.add_conditional_edges(
|
| 71 |
-
# "query_or_respond",
|
| 72 |
-
# tools_condition,
|
| 73 |
-
# {END: END, "tools": "tools"},
|
| 74 |
-
# )
|
| 75 |
-
|
| 76 |
-
# graph_builder.add_edge("tools", "generate")
|
| 77 |
-
# graph_builder.add_edge("generate", END)
|
| 78 |
-
|
| 79 |
-
# graph = graph_builder.compile(checkpointer=memory)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ingestion/main.py
CHANGED
|
@@ -11,24 +11,6 @@ from config import app_settings
|
|
| 11 |
|
| 12 |
logger = structlog.get_logger(__name__)
|
| 13 |
|
| 14 |
-
# embeddings = OpenAIEmbeddings(
|
| 15 |
-
# model=app_settings.embedding_model,
|
| 16 |
-
# api_key=app_settings.llm_api_key
|
| 17 |
-
# )
|
| 18 |
-
|
| 19 |
-
# client = QdrantClient(app_settings.vector_db_url)
|
| 20 |
-
# if not client.collection_exists(app_settings.vector_db_collection_name):
|
| 21 |
-
# client.create_collection(
|
| 22 |
-
# collection_name=app_settings.vector_db_collection_name,
|
| 23 |
-
# vectors_config=VectorParams(size=app_settings.embedding_size, distance=Distance.COSINE),
|
| 24 |
-
# sparse_vectors_config={'langchain-sparse': SparseVectorParams(index=None, modifier=None)}
|
| 25 |
-
# )
|
| 26 |
-
# vector_store = QdrantVectorStore(
|
| 27 |
-
# client=client,
|
| 28 |
-
# collection_name=app_settings.vector_db_collection_name,
|
| 29 |
-
# embedding=embeddings,
|
| 30 |
-
# )
|
| 31 |
-
|
| 32 |
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
|
| 33 |
|
| 34 |
def ingest_document(path, vector_store):
|
|
|
|
| 11 |
|
| 12 |
logger = structlog.get_logger(__name__)
|
| 13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
|
| 15 |
|
| 16 |
def ingest_document(path, vector_store):
|
static/style.css
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
footer { display: none !important; }
|
|
|
|
|
|