From ccf08fb91e3960b1b8457306ac231d18dc7f21e2 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 17 Feb 2024 22:29:52 -0800 Subject: [PATCH 1/5] feat: editable chunk params --- backend/apps/rag/main.py | 39 +++++++++++- src/lib/apis/rag/index.ts | 58 +++++++++++++++++ .../documents/Settings/General.svelte | 62 +++++++++++++++++-- 3 files changed, 152 insertions(+), 7 deletions(-) diff --git a/backend/apps/rag/main.py b/backend/apps/rag/main.py index f24b6b90..79981680 100644 --- a/backend/apps/rag/main.py +++ b/backend/apps/rag/main.py @@ -71,6 +71,9 @@ from constants import ERROR_MESSAGES app = FastAPI() +app.state.CHUNK_SIZE = CHUNK_SIZE +app.state.CHUNK_OVERLAP = CHUNK_OVERLAP + origins = ["*"] app.add_middleware( @@ -92,7 +95,7 @@ class StoreWebForm(CollectionNameForm): def store_data_in_vector_db(data, collection_name) -> bool: text_splitter = RecursiveCharacterTextSplitter( - chunk_size=CHUNK_SIZE, chunk_overlap=CHUNK_OVERLAP + chunk_size=app.state.CHUNK_SIZE, chunk_overlap=app.state.CHUNK_OVERLAP ) docs = text_splitter.split_documents(data) @@ -116,7 +119,39 @@ def store_data_in_vector_db(data, collection_name) -> bool: @app.get("/") async def get_status(): - return {"status": True} + return { + "status": True, + "chunk_size": app.state.CHUNK_SIZE, + "chunk_overlap": app.state.CHUNK_OVERLAP, + } + + +@app.get("/chunk") +async def get_chunk_params(user=Depends(get_admin_user)): + return { + "status": True, + "chunk_size": app.state.CHUNK_SIZE, + "chunk_overlap": app.state.CHUNK_OVERLAP, + } + + +class ChunkParamUpdateForm(BaseModel): + chunk_size: int + chunk_overlap: int + + +@app.post("/chunk/update") +async def update_chunk_params( + form_data: ChunkParamUpdateForm, user=Depends(get_admin_user) +): + app.state.CHUNK_SIZE = form_data.chunk_size + app.state.CHUNK_OVERLAP = form_data.chunk_overlap + + return { + "status": True, + "chunk_size": app.state.CHUNK_SIZE, + "chunk_overlap": app.state.CHUNK_OVERLAP, + } class QueryDocForm(BaseModel): diff --git a/src/lib/apis/rag/index.ts b/src/lib/apis/rag/index.ts index fc3571aa..5819badb 100644 --- a/src/lib/apis/rag/index.ts +++ b/src/lib/apis/rag/index.ts @@ -1,5 +1,63 @@ import { RAG_API_BASE_URL } from '$lib/constants'; +export const getChunkParams = async (token: string) => { + let error = null; + + const res = await fetch(`${RAG_API_BASE_URL}/chunk`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateChunkParams = async (token: string, size: number, overlap: number) => { + let error = null; + + const res = await fetch(`${RAG_API_BASE_URL}/chunk/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + chunk_size: size, + chunk_overlap: overlap + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + export const uploadDocToVectorDB = async (token: string, collection_name: string, file: File) => { const data = new FormData(); data.append('file', file); diff --git a/src/lib/components/documents/Settings/General.svelte b/src/lib/components/documents/Settings/General.svelte index c3c7df5b..038fa83b 100644 --- a/src/lib/components/documents/Settings/General.svelte +++ b/src/lib/components/documents/Settings/General.svelte @@ -1,6 +1,6 @@
{ - // console.log('submit'); + submitHandler(); saveHandler(); }} > @@ -93,14 +107,52 @@ + +
+ +
+
Chunk Params
+ +
+
+
Chunk Size
+ +
+ +
+
+ +
+
Chunk Overlap
+ +
+ +
+
+
+
- +
From 5270efa9e5cf5d39de326930344ac94611622935 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 17 Feb 2024 22:41:03 -0800 Subject: [PATCH 2/5] feat: editable rag template --- backend/apps/rag/main.py | 22 +++++++++++ backend/config.py | 15 ++++++++ src/lib/apis/rag/index.ts | 57 ++++++++++++++++++++++++++++ src/lib/utils/rag/index.ts | 32 +++++++++------- src/routes/(app)/+page.svelte | 6 ++- src/routes/(app)/c/[id]/+page.svelte | 6 ++- 6 files changed, 122 insertions(+), 16 deletions(-) diff --git a/backend/apps/rag/main.py b/backend/apps/rag/main.py index 79981680..fbfba258 100644 --- a/backend/apps/rag/main.py +++ b/backend/apps/rag/main.py @@ -62,6 +62,7 @@ from config import ( CHROMA_CLIENT, CHUNK_SIZE, CHUNK_OVERLAP, + RAG_TEMPLATE, ) from constants import ERROR_MESSAGES @@ -73,6 +74,8 @@ app = FastAPI() app.state.CHUNK_SIZE = CHUNK_SIZE app.state.CHUNK_OVERLAP = CHUNK_OVERLAP +app.state.RAG_TEMPLATE = RAG_TEMPLATE + origins = ["*"] @@ -154,6 +157,25 @@ async def update_chunk_params( } +@app.get("/template") +async def get_rag_template(user=Depends(get_current_user)): + return { + "status": True, + "template": app.state.RAG_TEMPLATE, + } + + +class RAGTemplateForm(BaseModel): + template: str + + +@app.post("/template/update") +async def update_rag_template(form_data: RAGTemplateForm, user=Depends(get_admin_user)): + # TODO: check template requirements + app.state.RAG_TEMPLATE = form_data.template + return {"status": True, "template": app.state.RAG_TEMPLATE} + + class QueryDocForm(BaseModel): collection_name: str query: str diff --git a/backend/config.py b/backend/config.py index f5acf06b..440256c4 100644 --- a/backend/config.py +++ b/backend/config.py @@ -144,6 +144,21 @@ CHROMA_CLIENT = chromadb.PersistentClient( CHUNK_SIZE = 1500 CHUNK_OVERLAP = 100 + +RAG_TEMPLATE = """Use the following context as your learned knowledge, inside XML tags. + + [context] + + +When answer to user: +- If you don't know, just say that you don't know. +- If you don't know when you are not sure, ask for clarification. +Avoid mentioning that you obtained the information from the context. +And answer according to the language of the user's question. + +Given the context information, answer the query. +Query: [query]""" + #################################### # Transcribe #################################### diff --git a/src/lib/apis/rag/index.ts b/src/lib/apis/rag/index.ts index 5819badb..78c220b6 100644 --- a/src/lib/apis/rag/index.ts +++ b/src/lib/apis/rag/index.ts @@ -58,6 +58,63 @@ export const updateChunkParams = async (token: string, size: number, overlap: nu return res; }; +export const getRAGTemplate = async (token: string) => { + let error = null; + + const res = await fetch(`${RAG_API_BASE_URL}/template`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateRAGTemplate = async (token: string, template: string) => { + let error = null; + + const res = await fetch(`${RAG_API_BASE_URL}/template/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + template: template + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + export const uploadDocToVectorDB = async (token: string, collection_name: string, file: File) => { const data = new FormData(); data.append('file', file); diff --git a/src/lib/utils/rag/index.ts b/src/lib/utils/rag/index.ts index 6b219ef2..ba1f29f8 100644 --- a/src/lib/utils/rag/index.ts +++ b/src/lib/utils/rag/index.ts @@ -1,17 +1,21 @@ -export const RAGTemplate = (context: string, query: string) => { - let template = `Use the following context as your learned knowledge, inside XML tags. - - [context] - - - When answer to user: - - If you don't know, just say that you don't know. - - If you don't know when you are not sure, ask for clarification. - Avoid mentioning that you obtained the information from the context. - And answer according to the language of the user's question. - - Given the context information, answer the query. - Query: [query]`; +import { getRAGTemplate } from '$lib/apis/rag'; + +export const RAGTemplate = async (token: string, context: string, query: string) => { + let template = await getRAGTemplate(token).catch(() => { + return `Use the following context as your learned knowledge, inside XML tags. + + [context] + + + When answer to user: + - If you don't know, just say that you don't know. + - If you don't know when you are not sure, ask for clarification. + Avoid mentioning that you obtained the information from the context. + And answer according to the language of the user's question. + + Given the context information, answer the query. + Query: [query]`; + }); template = template.replace(/\[context\]/g, context); template = template.replace(/\[query\]/g, query); diff --git a/src/routes/(app)/+page.svelte b/src/routes/(app)/+page.svelte index 604cb544..1d91a614 100644 --- a/src/routes/(app)/+page.svelte +++ b/src/routes/(app)/+page.svelte @@ -266,7 +266,11 @@ console.log(contextString); - history.messages[parentId].raContent = RAGTemplate(contextString, query); + history.messages[parentId].raContent = await RAGTemplate( + localStorage.token, + contextString, + query + ); history.messages[parentId].contexts = relevantContexts; await tick(); processing = ''; diff --git a/src/routes/(app)/c/[id]/+page.svelte b/src/routes/(app)/c/[id]/+page.svelte index aab03d74..b719ebf2 100644 --- a/src/routes/(app)/c/[id]/+page.svelte +++ b/src/routes/(app)/c/[id]/+page.svelte @@ -280,7 +280,11 @@ console.log(contextString); - history.messages[parentId].raContent = RAGTemplate(contextString, query); + history.messages[parentId].raContent = await RAGTemplate( + localStorage.token, + contextString, + query + ); history.messages[parentId].contexts = relevantContexts; await tick(); processing = ''; From 082d1d15c39bc37687afada7213875e367549055 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 17 Feb 2024 22:42:36 -0800 Subject: [PATCH 3/5] fix: template load issue --- src/lib/apis/rag/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/apis/rag/index.ts b/src/lib/apis/rag/index.ts index 78c220b6..ed36f014 100644 --- a/src/lib/apis/rag/index.ts +++ b/src/lib/apis/rag/index.ts @@ -82,7 +82,7 @@ export const getRAGTemplate = async (token: string) => { throw error; } - return res; + return res?.template ?? ''; }; export const updateRAGTemplate = async (token: string, template: string) => { From a31feccd64e53ef0934b3d59de03e9f3e50ada9e Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 17 Feb 2024 22:47:58 -0800 Subject: [PATCH 4/5] feat: editable rag template frontend --- .../documents/Settings/General.svelte | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/lib/components/documents/Settings/General.svelte b/src/lib/components/documents/Settings/General.svelte index 038fa83b..503cbc84 100644 --- a/src/lib/components/documents/Settings/General.svelte +++ b/src/lib/components/documents/Settings/General.svelte @@ -1,6 +1,12 @@ @@ -144,6 +155,15 @@ + +
+
RAG Template
+