aiqtech commited on
Commit
1b3ced8
Β·
verified Β·
1 Parent(s): 371c534

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -73
app.py CHANGED
@@ -351,7 +351,7 @@ class QualityChecker:
351
  class OptimizedStreaming:
352
  """슀트리밍 버퍼 μ΅œμ ν™”"""
353
 
354
- def __init__(self, chunk_size: int = 100, flush_interval: float = 0.1):
355
  self.chunk_size = chunk_size
356
  self.flush_interval = flush_interval
357
  self.buffer = ""
@@ -421,7 +421,7 @@ class SpeedOptimizedMultiAgentSystem:
421
  AgentRole.FINALIZER: """[μ΅œμ’…ν†΅ν•©]
422
  λͺ¨λ“ μ˜κ²¬ μ’…ν•©β†’μ΅œμ λ‹΅λ³€
423
  λͺ…확ꡬ쑰+μ‹€μš©μ •λ³΄+μ°½μ˜κ· ν˜•
424
- λ°”λ‘œ 핡심 λ‚΄μš©λΆ€ν„° μ‹œμž‘. λΆˆν•„μš”ν•œ ν—€λ”λ‚˜ λ§ˆν¬μ—… 없이."""
425
  }
426
 
427
  async def parallel_process_agents(
@@ -449,7 +449,7 @@ class SpeedOptimizedMultiAgentSystem:
449
  try:
450
  # === 1단계: κ°λ…μž + 검색 병렬 μ‹€ν–‰ ===
451
  if show_progress:
452
- agent_thoughts = "### πŸš€ 병렬 처리 μ‹œμž‘\n"
453
  agent_thoughts += "πŸ‘” κ°λ…μž 뢄석 + πŸ” μΆ”κ°€ 검색 λ™μ‹œ μ§„ν–‰...\n\n"
454
  yield accumulated_response, agent_thoughts
455
 
@@ -474,12 +474,12 @@ class SpeedOptimizedMultiAgentSystem:
474
  async for chunk in self.streaming.buffer_and_yield(supervisor_task):
475
  supervisor_response += chunk
476
  if show_progress and len(supervisor_response) < 300:
477
- agent_thoughts = f"### πŸ‘” κ°λ…μž 뢄석\n{supervisor_response[:300]}...\n\n"
478
  yield accumulated_response, agent_thoughts
479
 
480
  # === 2단계: μ°½μ˜μ„± + 비평 μ€€λΉ„ 병렬 ===
481
  if show_progress:
482
- agent_thoughts += "### 🎨 μ°½μ˜μ„± μƒμ„±μž + πŸ” λΉ„ν‰μž μ€€λΉ„...\n\n"
483
  yield accumulated_response, agent_thoughts
484
 
485
  # μ°½μ˜μ„± 생성 μ‹œμž‘
@@ -524,7 +524,7 @@ class SpeedOptimizedMultiAgentSystem:
524
 
525
  if show_progress:
526
  display_creative = creative_response[:400] + "..." if len(creative_response) > 400 else creative_response
527
- agent_thoughts = f"### 🎨 μ°½μ˜μ„± μƒμ„±μž\n{display_creative}\n\n"
528
  yield accumulated_response, agent_thoughts
529
 
530
  # λΉ„ν‰μž κ²°κ³Ό λŒ€κΈ°
@@ -532,7 +532,7 @@ class SpeedOptimizedMultiAgentSystem:
532
  critic_response = await critic_task
533
 
534
  if show_progress:
535
- agent_thoughts += f"### πŸ” λΉ„ν‰μž κ²€ν† \n{critic_response[:200]}...\n\n"
536
  yield accumulated_response, agent_thoughts
537
 
538
  # === 3단계: ν’ˆμ§ˆ 체크 및 μ‘°κΈ° μ’…λ£Œ ===
@@ -545,7 +545,7 @@ class SpeedOptimizedMultiAgentSystem:
545
  accumulated_response = creative_response
546
 
547
  if show_progress:
548
- agent_thoughts += f"### βœ… ν’ˆμ§ˆ μΆ©μ‘± (점수: {quality_score:.2f})\nμ‘°κΈ° μ™„λ£Œ!\n"
549
 
550
  # μΊμ‹œ μ €μž₯
551
  self.cache.set(query, {
@@ -558,7 +558,7 @@ class SpeedOptimizedMultiAgentSystem:
558
 
559
  # === 4단계: μ΅œμ’… 톡합 (슀트리밍) ===
560
  if show_progress:
561
- agent_thoughts += "### βœ… μ΅œμ’… 톡합 쀑...\n\n"
562
  yield accumulated_response, agent_thoughts
563
 
564
  final_prompt = f"""
@@ -566,7 +566,7 @@ class SpeedOptimizedMultiAgentSystem:
566
  μ°½μ˜μ„±λ‹΅λ³€: {creative_response}
567
  λΉ„ν‰ν”Όλ“œλ°±: {critic_response}
568
  κ°λ…μžκ΅¬μ‘°: {supervisor_response}
569
- μ΅œμ’…ν†΅ν•©β†’μ™„λ²½λ‹΅λ³€"""
570
 
571
  final_task = self.llm.chat_stream_async(
572
  messages=[
@@ -577,36 +577,38 @@ class SpeedOptimizedMultiAgentSystem:
577
  max_tokens=2500
578
  )
579
 
580
- # μ΅œμ’… λ‹΅λ³€ 슀트리밍
581
  accumulated_response = ""
582
- temp_buffer = "" # μž„μ‹œ 버퍼 μΆ”κ°€
583
 
584
- async for chunk in self.streaming.buffer_and_yield(final_task):
585
- temp_buffer += chunk
586
-
587
- # "| --- # 🌱 **μ΅œμ’…ν†΅ν•© λ‹΅λ³€:" οΏ½οΏ½οΏ½λΆ„ 제거
588
- if "| --- # 🌱 **μ΅œμ’…ν†΅ν•© λ‹΅λ³€:" in temp_buffer:
589
- # ν•΄λ‹Ή ν…μŠ€νŠΈ μ΄ν›„μ˜ λ‚΄μš©λ§Œ μΆ”μΆœ
590
- parts = temp_buffer.split("| --- # 🌱 **μ΅œμ’…ν†΅ν•© λ‹΅λ³€:")
591
- if len(parts) > 1:
592
- temp_buffer = parts[1]
593
-
594
- # "**β€“μ˜€λ₯˜: ---" 뢀뢄이 λ‚˜νƒ€λ‚˜λ©΄ κ·Έ μ „κΉŒμ§€λ§Œ μ‚¬μš©
595
- if "**β€“μ˜€λ₯˜: ---" in temp_buffer:
596
- temp_buffer = temp_buffer.split("**β€“μ˜€λ₯˜: ---")[0]
 
 
 
 
 
 
 
 
 
 
597
 
598
- # μ •λ¦¬λœ λ‚΄μš©μ„ accumulated_response에 μΆ”κ°€
599
- accumulated_response = temp_buffer
600
  yield accumulated_response, agent_thoughts
601
 
602
- # μ΅œμ’… 정리 - ν˜Ήμ‹œ λ‚¨μ•„μžˆμ„ 수 μžˆλŠ” λΆˆν•„μš”ν•œ λΆ€λΆ„ 제거
603
- if "| --- # 🌱 **μ΅œμ’…ν†΅ν•© λ‹΅λ³€:" in accumulated_response:
604
- accumulated_response = accumulated_response.split("| --- # 🌱 **μ΅œμ’…ν†΅ν•© λ‹΅λ³€:")[1]
605
-
606
- if "**β€“μ˜€λ₯˜: ---" in accumulated_response:
607
- accumulated_response = accumulated_response.split("**β€“μ˜€λ₯˜: ---")[0]
608
-
609
- # μ•žλ’€ 곡백 제거
610
  accumulated_response = accumulated_response.strip()
611
 
612
  # 처리 μ‹œκ°„ μΆ”κ°€
@@ -671,7 +673,7 @@ def create_optimized_gradio_interface():
671
  show_agent_thoughts: bool,
672
  search_count: int
673
  ):
674
- """μ΅œμ ν™”λœ 쿼리 처리 - 동기 버전"""
675
 
676
  if not message:
677
  yield history, "", ""
@@ -682,23 +684,7 @@ def create_optimized_gradio_interface():
682
  import nest_asyncio
683
  nest_asyncio.apply()
684
  except ImportError:
685
- pass # nest_asyncioκ°€ 없어도 μ§„ν–‰
686
-
687
- def run_async_function(coro):
688
- """비동기 ν•¨μˆ˜λ₯Ό λ™κΈ°μ μœΌλ‘œ μ‹€ν–‰ν•˜λŠ” 헬퍼"""
689
- try:
690
- loop = asyncio.get_event_loop()
691
- if loop.is_running():
692
- # 이미 μ‹€ν–‰ 쀑인 루프가 있으면 μƒˆ μŠ€λ ˆλ“œμ—μ„œ μ‹€ν–‰
693
- import concurrent.futures
694
- with concurrent.futures.ThreadPoolExecutor() as executor:
695
- future = executor.submit(asyncio.run, coro)
696
- return future.result()
697
- else:
698
- return loop.run_until_complete(coro)
699
- except RuntimeError:
700
- # 루프가 μ—†μœΌλ©΄ μƒˆλ‘œ 생성
701
- return asyncio.run(coro)
702
 
703
  try:
704
  # 검색 μˆ˜ν–‰ (동기화)
@@ -714,12 +700,15 @@ def create_optimized_gradio_interface():
714
  yield history_with_message, "", ""
715
 
716
  # 비동기 검색을 λ™κΈ°μ μœΌλ‘œ μ‹€ν–‰
717
- search_results = run_async_function(
718
- system.search.search_async(message, count=search_count)
719
- )
 
 
 
720
 
721
  if search_results:
722
- search_display = "## πŸ“š μ°Έκ³  자료\n\n"
723
  for i, result in enumerate(search_results[:3], 1):
724
  search_display += f"**{i}. [{result['title'][:50]}]({result['url']})**\n"
725
  search_display += f" {result['description'][:100]}...\n\n"
@@ -727,26 +716,37 @@ def create_optimized_gradio_interface():
727
  # μ‚¬μš©μž λ©”μ‹œμ§€ μΆ”κ°€
728
  current_history = history + [{"role": "user", "content": message}]
729
 
730
- # 병렬 처리 싀행을 λ™κΈ°μ μœΌλ‘œ μˆ˜μ§‘
731
- async def collect_responses():
732
- responses = []
733
  async for response, thoughts in system.parallel_process_agents(
734
  query=message,
735
  search_results=search_results,
736
  show_progress=show_agent_thoughts
737
  ):
738
- responses.append((response, thoughts))
739
- return responses
740
 
741
- # λͺ¨λ“  응닡 μˆ˜μ§‘
742
- all_responses = run_async_function(collect_responses())
 
743
 
744
- # μˆ˜μ§‘λœ 응닡을 yield
745
- for response, thoughts in all_responses:
746
- updated_history = current_history + [
747
- {"role": "assistant", "content": response}
748
- ]
749
- yield updated_history, thoughts, search_display
 
 
 
 
 
 
 
 
 
 
 
750
 
751
  except Exception as e:
752
  error_history = history + [
@@ -754,6 +754,12 @@ def create_optimized_gradio_interface():
754
  {"role": "assistant", "content": f"❌ 였λ₯˜: {str(e)}"}
755
  ]
756
  yield error_history, "", ""
 
 
 
 
 
 
757
 
758
  # Gradio μΈν„°νŽ˜μ΄μŠ€
759
  with gr.Blocks(
@@ -768,7 +774,7 @@ def create_optimized_gradio_interface():
768
  ) as demo:
769
  gr.Markdown("""
770
  # ⚑ 고속 Multi-Agent RAG System
771
- ### λ³΅μž‘ν•œ μ§ˆλ¬Έλ„ 5초 이내 처리 λͺ©ν‘œ
772
 
773
  **μ΅œμ ν™” 기술:**
774
  - πŸš€ 병렬 처리: μ—μ΄μ „νŠΈ λ™μ‹œ μ‹€ν–‰
@@ -802,7 +808,7 @@ def create_optimized_gradio_interface():
802
  search_sources = gr.Markdown()
803
 
804
  with gr.Column(scale=1):
805
- gr.Markdown("### βš™οΈ μ„€μ •")
806
 
807
  use_search = gr.Checkbox(
808
  label="πŸ” μ›Ή 검색 μ‚¬μš©",
@@ -823,7 +829,7 @@ def create_optimized_gradio_interface():
823
  )
824
 
825
  gr.Markdown("""
826
- ### ⚑ μ΅œμ ν™” μƒνƒœ
827
 
828
  **ν™œμ„±ν™”λœ μ΅œμ ν™”:**
829
  - βœ… 병렬 처리
 
351
  class OptimizedStreaming:
352
  """슀트리밍 버퍼 μ΅œμ ν™”"""
353
 
354
+ def __init__(self, chunk_size: int = 20, flush_interval: float = 0.05):
355
  self.chunk_size = chunk_size
356
  self.flush_interval = flush_interval
357
  self.buffer = ""
 
421
  AgentRole.FINALIZER: """[μ΅œμ’…ν†΅ν•©]
422
  λͺ¨λ“ μ˜κ²¬ μ’…ν•©β†’μ΅œμ λ‹΅λ³€
423
  λͺ…확ꡬ쑰+μ‹€μš©μ •λ³΄+μ°½μ˜κ· ν˜•
424
+ λ°”λ‘œ 핡심 λ‚΄μš©λΆ€ν„° μ‹œμž‘. λΆˆν•„μš”ν•œ ν—€λ”λ‚˜ λ§ˆν¬μ—… 없이. λ§ˆν¬λ‹€μš΄ 헀더(#, ##, ###) μ‚¬μš© κΈˆμ§€."""
425
  }
426
 
427
  async def parallel_process_agents(
 
449
  try:
450
  # === 1단계: κ°λ…μž + 검색 병렬 μ‹€ν–‰ ===
451
  if show_progress:
452
+ agent_thoughts = "πŸš€ 병렬 처리 μ‹œμž‘\n"
453
  agent_thoughts += "πŸ‘” κ°λ…μž 뢄석 + πŸ” μΆ”κ°€ 검색 λ™μ‹œ μ§„ν–‰...\n\n"
454
  yield accumulated_response, agent_thoughts
455
 
 
474
  async for chunk in self.streaming.buffer_and_yield(supervisor_task):
475
  supervisor_response += chunk
476
  if show_progress and len(supervisor_response) < 300:
477
+ agent_thoughts = f"πŸ‘” κ°λ…μž 뢄석\n{supervisor_response[:300]}...\n\n"
478
  yield accumulated_response, agent_thoughts
479
 
480
  # === 2단계: μ°½μ˜μ„± + 비평 μ€€λΉ„ 병렬 ===
481
  if show_progress:
482
+ agent_thoughts += "🎨 μ°½μ˜μ„± μƒμ„±μž + πŸ” λΉ„ν‰μž μ€€λΉ„...\n\n"
483
  yield accumulated_response, agent_thoughts
484
 
485
  # μ°½μ˜μ„± 생성 μ‹œμž‘
 
524
 
525
  if show_progress:
526
  display_creative = creative_response[:400] + "..." if len(creative_response) > 400 else creative_response
527
+ agent_thoughts = f"🎨 μ°½μ˜μ„± μƒμ„±μž\n{display_creative}\n\n"
528
  yield accumulated_response, agent_thoughts
529
 
530
  # λΉ„ν‰μž κ²°κ³Ό λŒ€κΈ°
 
532
  critic_response = await critic_task
533
 
534
  if show_progress:
535
+ agent_thoughts += f"πŸ” λΉ„ν‰μž κ²€ν† \n{critic_response[:200]}...\n\n"
536
  yield accumulated_response, agent_thoughts
537
 
538
  # === 3단계: ν’ˆμ§ˆ 체크 및 μ‘°κΈ° μ’…λ£Œ ===
 
545
  accumulated_response = creative_response
546
 
547
  if show_progress:
548
+ agent_thoughts += f"βœ… ν’ˆμ§ˆ μΆ©μ‘± (점수: {quality_score:.2f})\nμ‘°κΈ° μ™„λ£Œ!\n"
549
 
550
  # μΊμ‹œ μ €μž₯
551
  self.cache.set(query, {
 
558
 
559
  # === 4단계: μ΅œμ’… 톡합 (슀트리밍) ===
560
  if show_progress:
561
+ agent_thoughts += "βœ… μ΅œμ’… 톡합 쀑...\n\n"
562
  yield accumulated_response, agent_thoughts
563
 
564
  final_prompt = f"""
 
566
  μ°½μ˜μ„±λ‹΅λ³€: {creative_response}
567
  λΉ„ν‰ν”Όλ“œλ°±: {critic_response}
568
  κ°λ…μžκ΅¬μ‘°: {supervisor_response}
569
+ μ΅œμ’…ν†΅ν•©β†’μ™„λ²½λ‹΅λ³€. λ§ˆν¬λ‹€μš΄ 헀더(#, ##, ###) μ‚¬μš© κΈˆμ§€."""
570
 
571
  final_task = self.llm.chat_stream_async(
572
  messages=[
 
577
  max_tokens=2500
578
  )
579
 
580
+ # μ΅œμ’… λ‹΅λ³€ 슀트리밍 - κ°œμ„ λœ 필터링
581
  accumulated_response = ""
582
+ unwanted_header_found = False
583
 
584
+ async for chunk in final_task: # buffer_and_yield μ œκ±°ν•˜μ—¬ μ¦‰μ‹œ 슀트리밍
585
+ # λΆˆν•„μš”ν•œ 헀더 체크
586
+ if not unwanted_header_found:
587
+ accumulated_response += chunk
588
+
589
+ # 헀더 νŒ¨ν„΄ 감지
590
+ if "| --- # 🌱 **μ΅œμ’…ν†΅ν•© λ‹΅λ³€:" in accumulated_response:
591
+ unwanted_header_found = True
592
+ # 헀더 이후 λ‚΄μš©λ§Œ μΆ”μΆœ
593
+ parts = accumulated_response.split("| --- # 🌱 **μ΅œμ’…ν†΅ν•© λ‹΅λ³€:")
594
+ if len(parts) > 1:
595
+ accumulated_response = parts[1].lstrip()
596
+
597
+ # 였λ₯˜ ν‘Έν„° 감지 및 제거
598
+ if "**β€“μ˜€λ₯˜: ---" in accumulated_response:
599
+ accumulated_response = accumulated_response.split("**β€“μ˜€λ₯˜: ---")[0]
600
+ else:
601
+ # 헀더λ₯Ό 찾은 ν›„μ—λŠ” λ°”λ‘œ μΆ”κ°€
602
+ accumulated_response += chunk
603
+
604
+ # 였λ₯˜ ν‘Έν„° μ‹€μ‹œκ°„ 체크
605
+ if "**β€“μ˜€λ₯˜: ---" in accumulated_response:
606
+ accumulated_response = accumulated_response.split("**β€“μ˜€λ₯˜: ---")[0]
607
 
608
+ # μ‹€μ‹œκ°„ 슀트리밍 yield
 
609
  yield accumulated_response, agent_thoughts
610
 
611
+ # μ΅œμ’… 정리
 
 
 
 
 
 
 
612
  accumulated_response = accumulated_response.strip()
613
 
614
  # 처리 μ‹œκ°„ μΆ”κ°€
 
673
  show_agent_thoughts: bool,
674
  search_count: int
675
  ):
676
+ """μ΅œμ ν™”λœ 쿼리 처리 - μ‹€μ‹œκ°„ 슀트리밍 버전"""
677
 
678
  if not message:
679
  yield history, "", ""
 
684
  import nest_asyncio
685
  nest_asyncio.apply()
686
  except ImportError:
687
+ pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
688
 
689
  try:
690
  # 검색 μˆ˜ν–‰ (동기화)
 
700
  yield history_with_message, "", ""
701
 
702
  # 비동기 검색을 λ™κΈ°μ μœΌλ‘œ μ‹€ν–‰
703
+ async def search_wrapper():
704
+ return await system.search.search_async(message, count=search_count)
705
+
706
+ loop = asyncio.new_event_loop()
707
+ asyncio.set_event_loop(loop)
708
+ search_results = loop.run_until_complete(search_wrapper())
709
 
710
  if search_results:
711
+ search_display = "πŸ“š μ°Έκ³  자료\n\n"
712
  for i, result in enumerate(search_results[:3], 1):
713
  search_display += f"**{i}. [{result['title'][:50]}]({result['url']})**\n"
714
  search_display += f" {result['description'][:100]}...\n\n"
 
716
  # μ‚¬μš©μž λ©”μ‹œμ§€ μΆ”κ°€
717
  current_history = history + [{"role": "user", "content": message}]
718
 
719
+ # μ‹€μ‹œκ°„ μŠ€νŠΈλ¦¬λ°μ„ μœ„ν•œ 비동기 처리
720
+ async def stream_responses():
721
+ """μ‹€μ‹œκ°„ 슀트리밍 μ œλ„ˆλ ˆμ΄ν„°"""
722
  async for response, thoughts in system.parallel_process_agents(
723
  query=message,
724
  search_results=search_results,
725
  show_progress=show_agent_thoughts
726
  ):
727
+ yield response, thoughts
 
728
 
729
+ # μƒˆ 이벀트 λ£¨ν”„μ—μ„œ μ‹€μ‹œκ°„ 슀트리밍
730
+ loop = asyncio.new_event_loop()
731
+ asyncio.set_event_loop(loop)
732
 
733
+ # 비동기 μ œλ„ˆλ ˆμ΄ν„°λ₯Ό λ™κΈ°μ μœΌλ‘œ 순회
734
+ gen = stream_responses()
735
+
736
+ while True:
737
+ try:
738
+ # λ‹€μŒ ν•­λͺ© κ°€μ Έμ˜€κΈ°
739
+ task = asyncio.ensure_future(gen.__anext__(), loop=loop)
740
+ response, thoughts = loop.run_until_complete(task)
741
+
742
+ # μ‹€μ‹œκ°„ μ—…λ°μ΄νŠΈ
743
+ updated_history = current_history + [
744
+ {"role": "assistant", "content": response}
745
+ ]
746
+ yield updated_history, thoughts, search_display
747
+
748
+ except StopAsyncIteration:
749
+ break
750
 
751
  except Exception as e:
752
  error_history = history + [
 
754
  {"role": "assistant", "content": f"❌ 였λ₯˜: {str(e)}"}
755
  ]
756
  yield error_history, "", ""
757
+ finally:
758
+ # 루프 정리
759
+ try:
760
+ loop.close()
761
+ except:
762
+ pass
763
 
764
  # Gradio μΈν„°νŽ˜μ΄μŠ€
765
  with gr.Blocks(
 
774
  ) as demo:
775
  gr.Markdown("""
776
  # ⚑ 고속 Multi-Agent RAG System
777
+ **λ³΅μž‘ν•œ μ§ˆλ¬Έλ„ 5초 이내 처리 λͺ©ν‘œ**
778
 
779
  **μ΅œμ ν™” 기술:**
780
  - πŸš€ 병렬 처리: μ—μ΄μ „νŠΈ λ™μ‹œ μ‹€ν–‰
 
808
  search_sources = gr.Markdown()
809
 
810
  with gr.Column(scale=1):
811
+ gr.Markdown("**βš™οΈ μ„€μ •**")
812
 
813
  use_search = gr.Checkbox(
814
  label="πŸ” μ›Ή 검색 μ‚¬μš©",
 
829
  )
830
 
831
  gr.Markdown("""
832
+ **⚑ μ΅œμ ν™” μƒνƒœ**
833
 
834
  **ν™œμ„±ν™”λœ μ΅œμ ν™”:**
835
  - βœ… 병렬 처리