1818# pylint: disable=E1101
1919
2020import os
21- from typing import Tuple , Literal , Optional
21+ from typing import AsyncGenerator , Tuple , Literal , Optional
2222
2323import gradio as gr
2424import pandas as pd
2525from gradio .utils import NamedString
2626
2727from hugegraph_llm .config import resource_path , prompt , huge_settings , llm_settings
2828from hugegraph_llm .operators .graph_rag_task import RAGPipeline
29+ from hugegraph_llm .operators .llm_op .answer_synthesize import AnswerSynthesize
2930from hugegraph_llm .utils .log import log
3031
3132
@@ -56,25 +57,10 @@ def rag_answer(
5657 4. Synthesize the final answer.
5758 5. Run the pipeline and return the results.
5859 """
59-
60- gremlin_prompt = gremlin_prompt or prompt .gremlin_generate_prompt
61- should_update_prompt = (
62- prompt .default_question != text
63- or prompt .answer_prompt != answer_prompt
64- or prompt .keywords_extract_prompt != keywords_extract_prompt
65- or prompt .gremlin_generate_prompt != gremlin_prompt
66- or prompt .custom_rerank_info != custom_related_information
67- )
68- if should_update_prompt :
69- prompt .custom_rerank_info = custom_related_information
70- prompt .default_question = text
71- prompt .answer_prompt = answer_prompt
72- prompt .keywords_extract_prompt = keywords_extract_prompt
73- prompt .gremlin_generate_prompt = gremlin_prompt
74- prompt .update_yaml_file ()
75-
76- vector_search = vector_only_answer or graph_vector_answer
77- graph_search = graph_only_answer or graph_vector_answer
60+ graph_search , gremlin_prompt , vector_search = update_ui_configs (answer_prompt , custom_related_information ,
61+ graph_only_answer , graph_vector_answer ,
62+ gremlin_prompt , keywords_extract_prompt , text ,
63+ vector_only_answer )
7864 if raw_answer is False and not vector_search and not graph_search :
7965 gr .Warning ("Please select at least one generate mode." )
8066 return "" , "" , "" , ""
@@ -121,6 +107,106 @@ def rag_answer(
121107 raise gr .Error (f"An unexpected error occurred: { str (e )} " )
122108
123109
110+ def update_ui_configs (answer_prompt , custom_related_information , graph_only_answer , graph_vector_answer , gremlin_prompt ,
111+ keywords_extract_prompt , text , vector_only_answer ):
112+ gremlin_prompt = gremlin_prompt or prompt .gremlin_generate_prompt
113+ should_update_prompt = (
114+ prompt .default_question != text
115+ or prompt .answer_prompt != answer_prompt
116+ or prompt .keywords_extract_prompt != keywords_extract_prompt
117+ or prompt .gremlin_generate_prompt != gremlin_prompt
118+ or prompt .custom_rerank_info != custom_related_information
119+ )
120+ if should_update_prompt :
121+ prompt .custom_rerank_info = custom_related_information
122+ prompt .default_question = text
123+ prompt .answer_prompt = answer_prompt
124+ prompt .keywords_extract_prompt = keywords_extract_prompt
125+ prompt .gremlin_generate_prompt = gremlin_prompt
126+ prompt .update_yaml_file ()
127+ vector_search = vector_only_answer or graph_vector_answer
128+ graph_search = graph_only_answer or graph_vector_answer
129+ return graph_search , gremlin_prompt , vector_search
130+
131+
132+ async def rag_answer_streaming (
133+ text : str ,
134+ raw_answer : bool ,
135+ vector_only_answer : bool ,
136+ graph_only_answer : bool ,
137+ graph_vector_answer : bool ,
138+ graph_ratio : float ,
139+ rerank_method : Literal ["bleu" , "reranker" ],
140+ near_neighbor_first : bool ,
141+ custom_related_information : str ,
142+ answer_prompt : str ,
143+ keywords_extract_prompt : str ,
144+ gremlin_tmpl_num : Optional [int ] = 2 ,
145+ gremlin_prompt : Optional [str ] = None ,
146+ ) -> AsyncGenerator [Tuple [str , str , str , str ], None ]:
147+ """
148+ Generate an answer using the RAG (Retrieval-Augmented Generation) pipeline.
149+ 1. Initialize the RAGPipeline.
150+ 2. Select vector search or graph search based on parameters.
151+ 3. Merge, deduplicate, and rerank the results.
152+ 4. Synthesize the final answer.
153+ 5. Run the pipeline and return the results.
154+ """
155+
156+ graph_search , gremlin_prompt , vector_search = update_ui_configs (answer_prompt , custom_related_information ,
157+ graph_only_answer , graph_vector_answer ,
158+ gremlin_prompt , keywords_extract_prompt , text ,
159+ vector_only_answer )
160+ if raw_answer is False and not vector_search and not graph_search :
161+ gr .Warning ("Please select at least one generate mode." )
162+ yield "" , "" , "" , ""
163+ return
164+
165+ rag = RAGPipeline ()
166+ if vector_search :
167+ rag .query_vector_index ()
168+ if graph_search :
169+ rag .extract_keywords (extract_template = keywords_extract_prompt ).keywords_to_vid ().import_schema (
170+ huge_settings .graph_name
171+ ).query_graphdb (
172+ num_gremlin_generate_example = gremlin_tmpl_num ,
173+ gremlin_prompt = gremlin_prompt ,
174+ )
175+ rag .merge_dedup_rerank (
176+ graph_ratio ,
177+ rerank_method ,
178+ near_neighbor_first ,
179+ )
180+ # rag.synthesize_answer(raw_answer, vector_only_answer, graph_only_answer, graph_vector_answer, answer_prompt)
181+
182+ try :
183+ context = rag .run (verbose = True , query = text , vector_search = vector_search , graph_search = graph_search )
184+ if context .get ("switch_to_bleu" ):
185+ gr .Warning ("Online reranker fails, automatically switches to local bleu rerank." )
186+ answer_synthesize = AnswerSynthesize (
187+ raw_answer = raw_answer ,
188+ vector_only_answer = vector_only_answer ,
189+ graph_only_answer = graph_only_answer ,
190+ graph_vector_answer = graph_vector_answer ,
191+ prompt_template = answer_prompt ,
192+ )
193+ async for context in answer_synthesize .run_streaming (context ):
194+ if context .get ("switch_to_bleu" ):
195+ gr .Warning ("Online reranker fails, automatically switches to local bleu rerank." )
196+ yield (
197+ context .get ("raw_answer" , "" ),
198+ context .get ("vector_only_answer" , "" ),
199+ context .get ("graph_only_answer" , "" ),
200+ context .get ("graph_vector_answer" , "" ),
201+ )
202+ except ValueError as e :
203+ log .critical (e )
204+ raise gr .Error (str (e ))
205+ except Exception as e :
206+ log .critical (e )
207+ raise gr .Error (f"An unexpected error occurred: { str (e )} " )
208+
209+
124210def create_rag_block ():
125211 # pylint: disable=R0915 (too-many-statements),C0301
126212 gr .Markdown ("""## 1. HugeGraph RAG Query""" )
@@ -130,13 +216,17 @@ def create_rag_block():
130216
131217 # TODO: Only support inline formula now. Should support block formula
132218 gr .Markdown ("Basic LLM Answer" , elem_classes = "output-box-label" )
133- raw_out = gr .Markdown (elem_classes = "output-box" , show_copy_button = True , latex_delimiters = [{"left" :"$" , "right" :"$" , "display" :False }])
219+ raw_out = gr .Markdown (elem_classes = "output-box" , show_copy_button = True ,
220+ latex_delimiters = [{"left" : "$" , "right" : "$" , "display" : False }])
134221 gr .Markdown ("Vector-only Answer" , elem_classes = "output-box-label" )
135- vector_only_out = gr .Markdown (elem_classes = "output-box" , show_copy_button = True , latex_delimiters = [{"left" :"$" , "right" :"$" , "display" :False }])
222+ vector_only_out = gr .Markdown (elem_classes = "output-box" , show_copy_button = True ,
223+ latex_delimiters = [{"left" : "$" , "right" : "$" , "display" : False }])
136224 gr .Markdown ("Graph-only Answer" , elem_classes = "output-box-label" )
137- graph_only_out = gr .Markdown (elem_classes = "output-box" , show_copy_button = True , latex_delimiters = [{"left" :"$" , "right" :"$" , "display" :False }])
225+ graph_only_out = gr .Markdown (elem_classes = "output-box" , show_copy_button = True ,
226+ latex_delimiters = [{"left" : "$" , "right" : "$" , "display" : False }])
138227 gr .Markdown ("Graph-Vector Answer" , elem_classes = "output-box-label" )
139- graph_vector_out = gr .Markdown (elem_classes = "output-box" , show_copy_button = True , latex_delimiters = [{"left" :"$" , "right" :"$" , "display" :False }])
228+ graph_vector_out = gr .Markdown (elem_classes = "output-box" , show_copy_button = True ,
229+ latex_delimiters = [{"left" : "$" , "right" : "$" , "display" : False }])
140230
141231 answer_prompt_input = gr .Textbox (
142232 value = prompt .answer_prompt , label = "Query Prompt" , show_copy_button = True , lines = 7
@@ -184,7 +274,7 @@ def toggle_slider(enable):
184274 btn = gr .Button ("Answer Question" , variant = "primary" )
185275
186276 btn .click ( # pylint: disable=no-member
187- fn = rag_answer ,
277+ fn = rag_answer_streaming ,
188278 inputs = [
189279 inp ,
190280 raw_radio ,
@@ -254,13 +344,13 @@ def several_rag_answer(
254344 is_vector_only_answer : bool ,
255345 is_graph_only_answer : bool ,
256346 is_graph_vector_answer : bool ,
257- graph_ratio : float ,
258- rerank_method : Literal ["bleu" , "reranker" ],
259- near_neighbor_first : bool ,
260- custom_related_information : str ,
347+ graph_ratio_ui : float ,
348+ rerank_method_ui : Literal ["bleu" , "reranker" ],
349+ near_neighbor_first_ui : bool ,
350+ custom_related_information_ui : str ,
261351 answer_prompt : str ,
262352 keywords_extract_prompt : str ,
263- answer_max_line_count : int = 1 ,
353+ answer_max_line_count_ui : int = 1 ,
264354 progress = gr .Progress (track_tqdm = True ),
265355 ):
266356 df = pd .read_excel (questions_path , dtype = str )
@@ -273,10 +363,10 @@ def several_rag_answer(
273363 is_vector_only_answer ,
274364 is_graph_only_answer ,
275365 is_graph_vector_answer ,
276- graph_ratio ,
277- rerank_method ,
278- near_neighbor_first ,
279- custom_related_information ,
366+ graph_ratio_ui ,
367+ rerank_method_ui ,
368+ near_neighbor_first_ui ,
369+ custom_related_information_ui ,
280370 answer_prompt ,
281371 keywords_extract_prompt ,
282372 )
@@ -285,9 +375,9 @@ def several_rag_answer(
285375 df .at [index , "Graph-only Answer" ] = graph_only_answer
286376 df .at [index , "Graph-Vector Answer" ] = graph_vector_answer
287377 progress ((index + 1 , total_rows ))
288- answers_path = os .path .join (resource_path , "demo" , "questions_answers.xlsx" )
289- df .to_excel (answers_path , index = False )
290- return df .head (answer_max_line_count ), answers_path
378+ answers_path_ui = os .path .join (resource_path , "demo" , "questions_answers.xlsx" )
379+ df .to_excel (answers_path_ui , index = False )
380+ return df .head (answer_max_line_count_ui ), answers_path_ui
291381
292382 with gr .Row ():
293383 with gr .Column ():
0 commit comments