Spaces:
Runtime error
Runtime error
Оновлення логіки мультизапитів
Browse files- Gradio_UI.py +33 -11
- agent.py +141 -89
- docs/agent_documentation.md +50 -19
Gradio_UI.py
CHANGED
|
@@ -8,12 +8,7 @@ logger = logging.getLogger(__name__)
|
|
| 8 |
|
| 9 |
class GradioUI:
|
| 10 |
def __init__(self, agent):
|
| 11 |
-
"""
|
| 12 |
-
Ініціалізація класу GradioUI.
|
| 13 |
-
|
| 14 |
-
Args:
|
| 15 |
-
agent: Екземпляр ResearchAgent для обробки запитів
|
| 16 |
-
"""
|
| 17 |
self.agent = agent
|
| 18 |
logger.info("GradioUI успішно ініціалізовано")
|
| 19 |
|
|
@@ -39,7 +34,7 @@ class GradioUI:
|
|
| 39 |
except Exception as e:
|
| 40 |
logger.error(f"Помилка завантаження документації: {e}")
|
| 41 |
return "# Помилка завантаження документації\nБудь ласка, перевірте наявність файлу docs/agent_documentation.md"
|
| 42 |
-
|
| 43 |
def build_interface(self):
|
| 44 |
"""Побудова інтерфейсу Gradio"""
|
| 45 |
with gr.Blocks(theme=gr.themes.Soft()) as interface:
|
|
@@ -76,7 +71,7 @@ class GradioUI:
|
|
| 76 |
gr.HTML("""
|
| 77 |
<style>
|
| 78 |
#process-steps {
|
| 79 |
-
height:
|
| 80 |
overflow-y: auto;
|
| 81 |
padding: 1rem;
|
| 82 |
border: 1px solid #e5e7eb;
|
|
@@ -95,7 +90,8 @@ class GradioUI:
|
|
| 95 |
|
| 96 |
with gr.Row():
|
| 97 |
submit_btn = gr.Button("Надіслати", variant="primary")
|
| 98 |
-
clear_btn = gr.Button("Очистити")
|
|
|
|
| 99 |
save_btn = gr.Button("Зберегти")
|
| 100 |
|
| 101 |
response_text = gr.Textbox(visible=False)
|
|
@@ -108,8 +104,8 @@ class GradioUI:
|
|
| 108 |
state = gr.State([])
|
| 109 |
current_model = gr.State(self.agent.model_initializer.config['default_model'])
|
| 110 |
|
| 111 |
-
# Функції обробки подій
|
| 112 |
def change_model(choice):
|
|
|
|
| 113 |
model_key = choice.split(" - ")[0]
|
| 114 |
self.agent.model_initializer.initialize_model(model_key)
|
| 115 |
return model_key
|
|
@@ -130,7 +126,12 @@ class GradioUI:
|
|
| 130 |
step_text = f"\n### Крок {step_num}: {step_data['info']}"
|
| 131 |
|
| 132 |
if step_data['result']:
|
| 133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
|
| 135 |
current_steps.append(step_text)
|
| 136 |
return "\n".join(current_steps)
|
|
@@ -139,7 +140,15 @@ class GradioUI:
|
|
| 139 |
response = self.agent.process_query(message)
|
| 140 |
chat_history[-1] = (message, response)
|
| 141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
current_steps.append("\n✅ Обробку завершено успішно!")
|
|
|
|
| 143 |
yield chat_history, "\n".join(current_steps), response
|
| 144 |
|
| 145 |
except Exception as e:
|
|
@@ -150,6 +159,7 @@ class GradioUI:
|
|
| 150 |
yield chat_history, "\n".join(current_steps), None
|
| 151 |
|
| 152 |
def save_response(response):
|
|
|
|
| 153 |
if response:
|
| 154 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 155 |
filename = f"research_report_{timestamp}.md"
|
|
@@ -161,6 +171,12 @@ class GradioUI:
|
|
| 161 |
return None
|
| 162 |
|
| 163 |
def clear_chat():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
return [], "", "", None
|
| 165 |
|
| 166 |
# Налаштування обробників подій
|
|
@@ -189,6 +205,12 @@ class GradioUI:
|
|
| 189 |
queue=False
|
| 190 |
)
|
| 191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
return interface
|
| 193 |
|
| 194 |
def launch(self, **kwargs):
|
|
|
|
| 8 |
|
| 9 |
class GradioUI:
|
| 10 |
def __init__(self, agent):
|
| 11 |
+
"""Ініціалізація інтерфейсу"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
self.agent = agent
|
| 13 |
logger.info("GradioUI успішно ініціалізовано")
|
| 14 |
|
|
|
|
| 34 |
except Exception as e:
|
| 35 |
logger.error(f"Помилка завантаження документації: {e}")
|
| 36 |
return "# Помилка завантаження документації\nБудь ласка, перевірте наявність файлу docs/agent_documentation.md"
|
| 37 |
+
|
| 38 |
def build_interface(self):
|
| 39 |
"""Побудова інтерфейсу Gradio"""
|
| 40 |
with gr.Blocks(theme=gr.themes.Soft()) as interface:
|
|
|
|
| 71 |
gr.HTML("""
|
| 72 |
<style>
|
| 73 |
#process-steps {
|
| 74 |
+
height: 500px;
|
| 75 |
overflow-y: auto;
|
| 76 |
padding: 1rem;
|
| 77 |
border: 1px solid #e5e7eb;
|
|
|
|
| 90 |
|
| 91 |
with gr.Row():
|
| 92 |
submit_btn = gr.Button("Надіслати", variant="primary")
|
| 93 |
+
clear_btn = gr.Button("Очистити чат")
|
| 94 |
+
clear_context_btn = gr.Button("Очистити контекст", variant="secondary")
|
| 95 |
save_btn = gr.Button("Зберегти")
|
| 96 |
|
| 97 |
response_text = gr.Textbox(visible=False)
|
|
|
|
| 104 |
state = gr.State([])
|
| 105 |
current_model = gr.State(self.agent.model_initializer.config['default_model'])
|
| 106 |
|
|
|
|
| 107 |
def change_model(choice):
|
| 108 |
+
"""Обробник зміни моделі"""
|
| 109 |
model_key = choice.split(" - ")[0]
|
| 110 |
self.agent.model_initializer.initialize_model(model_key)
|
| 111 |
return model_key
|
|
|
|
| 126 |
step_text = f"\n### Крок {step_num}: {step_data['info']}"
|
| 127 |
|
| 128 |
if step_data['result']:
|
| 129 |
+
if isinstance(step_data['result'], dict):
|
| 130 |
+
# Форматуємо словник для кращого відображення
|
| 131 |
+
result_text = "\n".join(f"- {k}: {v}" for k, v in step_data['result'].items())
|
| 132 |
+
step_text += f"\n```\n{result_text}\n```"
|
| 133 |
+
else:
|
| 134 |
+
step_text += f"\n```\n{step_data['result']}\n```"
|
| 135 |
|
| 136 |
current_steps.append(step_text)
|
| 137 |
return "\n".join(current_steps)
|
|
|
|
| 140 |
response = self.agent.process_query(message)
|
| 141 |
chat_history[-1] = (message, response)
|
| 142 |
|
| 143 |
+
# Додаємо інформацію про контекст
|
| 144 |
+
context_info = (
|
| 145 |
+
f"\n### Інформація про контекст\n"
|
| 146 |
+
f"Кількість попередніх запитів: {len(self.agent.conversation_context['previous_queries'])}\n"
|
| 147 |
+
f"Поточна тема: {self.agent.conversation_context['last_topic']}"
|
| 148 |
+
)
|
| 149 |
+
current_steps.append(context_info)
|
| 150 |
current_steps.append("\n✅ Обробку завершено успішно!")
|
| 151 |
+
|
| 152 |
yield chat_history, "\n".join(current_steps), response
|
| 153 |
|
| 154 |
except Exception as e:
|
|
|
|
| 159 |
yield chat_history, "\n".join(current_steps), None
|
| 160 |
|
| 161 |
def save_response(response):
|
| 162 |
+
"""Збереження відповіді у файл"""
|
| 163 |
if response:
|
| 164 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 165 |
filename = f"research_report_{timestamp}.md"
|
|
|
|
| 171 |
return None
|
| 172 |
|
| 173 |
def clear_chat():
|
| 174 |
+
"""Очищення чату"""
|
| 175 |
+
return [], "", "", None
|
| 176 |
+
|
| 177 |
+
def clear_chat_and_context():
|
| 178 |
+
"""Очищення чату та контексту"""
|
| 179 |
+
self.agent.clear_context()
|
| 180 |
return [], "", "", None
|
| 181 |
|
| 182 |
# Налаштування обробників подій
|
|
|
|
| 205 |
queue=False
|
| 206 |
)
|
| 207 |
|
| 208 |
+
clear_context_btn.click(
|
| 209 |
+
fn=clear_chat_and_context,
|
| 210 |
+
outputs=[chatbot, steps_log, response_text, file_output],
|
| 211 |
+
queue=False
|
| 212 |
+
)
|
| 213 |
+
|
| 214 |
return interface
|
| 215 |
|
| 216 |
def launch(self, **kwargs):
|
agent.py
CHANGED
|
@@ -8,22 +8,39 @@ logger = logging.getLogger(__name__)
|
|
| 8 |
|
| 9 |
class ResearchAgent(CodeAgent):
|
| 10 |
"""
|
| 11 |
-
Дослідницький агент для наукового пошуку та
|
| 12 |
"""
|
| 13 |
|
| 14 |
def __init__(self, model, tools, **kwargs):
|
| 15 |
"""
|
| 16 |
Ініціалізація дослідницького агента.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
"""
|
| 18 |
super().__init__(model=model, tools=tools, **kwargs)
|
| 19 |
self.available_tools = {tool.name: tool for tool in tools}
|
| 20 |
self.model_initializer = None
|
| 21 |
self.step_callback = None
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
logger.info(f"ResearchAgent ініціалізовано з інструментами: {list(self.available_tools.keys())}")
|
| 24 |
|
| 25 |
def _update_steps(self, step_info: str, step_result: Any = None):
|
| 26 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
if self.step_callback:
|
| 28 |
step_data = {
|
| 29 |
'info': step_info,
|
|
@@ -35,121 +52,156 @@ class ResearchAgent(CodeAgent):
|
|
| 35 |
logger.info(f"Result: {str(step_result)[:200]}...")
|
| 36 |
|
| 37 |
def _format_step_result(self, result: Any) -> str:
|
| 38 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
if result is None:
|
| 40 |
return ""
|
| 41 |
-
|
| 42 |
if isinstance(result, dict):
|
| 43 |
return "\n".join([f"{k}: {str(v)}" for k, v in result.items()])
|
| 44 |
elif isinstance(result, list):
|
| 45 |
return "\n".join([str(item) for item in result])
|
| 46 |
-
|
| 47 |
-
return str(result)
|
| 48 |
|
| 49 |
-
def
|
| 50 |
"""
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
try:
|
| 54 |
-
self.
|
| 55 |
-
|
| 56 |
-
# Step 1: Web Search
|
| 57 |
-
self._update_steps("Пошук інформації в інтернеті")
|
| 58 |
-
search_results = self.available_tools['web_search'](query=task)
|
| 59 |
-
self._update_steps("Отримано результати пошуку", search_results)
|
| 60 |
-
|
| 61 |
-
# Step 2: Формування запиту до моделі
|
| 62 |
-
prompt = (
|
| 63 |
-
"As a research assistant, analyze the following information and create a detailed report.\n\n"
|
| 64 |
-
f"Task: {task}\n\n"
|
| 65 |
-
f"Search Results:\n{search_results}\n\n"
|
| 66 |
-
"Create a comprehensive report with references to sources."
|
| 67 |
-
)
|
| 68 |
-
|
| 69 |
-
self._update_steps("Генерація звіту на основі знайденої інформації")
|
| 70 |
-
result = self.model(prompt)
|
| 71 |
-
self._update_steps("Згенеровано початковий варіант звіту", {
|
| 72 |
-
'length': len(result),
|
| 73 |
-
'preview': result[:200] + "..."
|
| 74 |
-
})
|
| 75 |
-
|
| 76 |
-
self._update_steps("Форматування фінального звіту")
|
| 77 |
-
return result
|
| 78 |
-
|
| 79 |
except Exception as e:
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
self._update_steps(f"Помилка", {'error': error_msg})
|
| 83 |
-
return error_msg
|
| 84 |
|
| 85 |
-
def
|
| 86 |
"""
|
| 87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
"""
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
"
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
"
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
| 118 |
|
| 119 |
def process_query(self, query: str, available_files: Optional[List[str]] = None) -> str:
|
| 120 |
"""
|
| 121 |
-
Обробка дослідницького
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
"""
|
| 123 |
try:
|
| 124 |
logger.info(f"Обробка дослідницького запиту: {query}")
|
| 125 |
self._update_steps("Початок обробки запиту")
|
| 126 |
|
| 127 |
-
#
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
|
| 138 |
self._update_steps("Запит успішно оброблено", {
|
| 139 |
-
'
|
| 140 |
-
'
|
| 141 |
})
|
| 142 |
|
| 143 |
-
|
| 144 |
-
return result
|
| 145 |
-
|
| 146 |
-
if isinstance(result, dict):
|
| 147 |
-
return self.format_research_report(result)
|
| 148 |
-
|
| 149 |
-
return str(result)
|
| 150 |
|
| 151 |
except Exception as e:
|
| 152 |
error_msg = f"Помилка при обробці запиту: {str(e)}"
|
| 153 |
logger.error(error_msg)
|
| 154 |
self._update_steps(f"Помилка", {'error': error_msg})
|
| 155 |
-
return error_msg
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
class ResearchAgent(CodeAgent):
|
| 10 |
"""
|
| 11 |
+
Дослідницький агент для наукового пошуку та аналізу з підтримкою контексту розмови.
|
| 12 |
"""
|
| 13 |
|
| 14 |
def __init__(self, model, tools, **kwargs):
|
| 15 |
"""
|
| 16 |
Ініціалізація дослідницького агента.
|
| 17 |
+
|
| 18 |
+
Args:
|
| 19 |
+
model: Модель для обробки запитів
|
| 20 |
+
tools: Інструменти для пошуку та обробки інформації
|
| 21 |
+
**kwargs: Додаткові параметри
|
| 22 |
"""
|
| 23 |
super().__init__(model=model, tools=tools, **kwargs)
|
| 24 |
self.available_tools = {tool.name: tool for tool in tools}
|
| 25 |
self.model_initializer = None
|
| 26 |
self.step_callback = None
|
| 27 |
+
# Ініціалізація контексту розмови
|
| 28 |
+
self.conversation_context = {
|
| 29 |
+
'previous_queries': [], # Історія запитів
|
| 30 |
+
'search_results': {}, # Результати пошуку для кожного запиту
|
| 31 |
+
'generated_content': {}, # Згенерований контент для кожного запиту
|
| 32 |
+
'last_topic': None # Остання обговорювана тема
|
| 33 |
+
}
|
| 34 |
logger.info(f"ResearchAgent ініціалізовано з інструментами: {list(self.available_tools.keys())}")
|
| 35 |
|
| 36 |
def _update_steps(self, step_info: str, step_result: Any = None):
|
| 37 |
+
"""
|
| 38 |
+
Оновлення інформації про кроки з результатами.
|
| 39 |
+
|
| 40 |
+
Args:
|
| 41 |
+
step_info: Інформація про поточний крок
|
| 42 |
+
step_result: Результат виконання кроку
|
| 43 |
+
"""
|
| 44 |
if self.step_callback:
|
| 45 |
step_data = {
|
| 46 |
'info': step_info,
|
|
|
|
| 52 |
logger.info(f"Result: {str(step_result)[:200]}...")
|
| 53 |
|
| 54 |
def _format_step_result(self, result: Any) -> str:
|
| 55 |
+
"""
|
| 56 |
+
Форматування результату кроку для відображення.
|
| 57 |
+
|
| 58 |
+
Args:
|
| 59 |
+
result: Результат для форматування
|
| 60 |
+
Returns:
|
| 61 |
+
str: Відформатований результат
|
| 62 |
+
"""
|
| 63 |
if result is None:
|
| 64 |
return ""
|
|
|
|
| 65 |
if isinstance(result, dict):
|
| 66 |
return "\n".join([f"{k}: {str(v)}" for k, v in result.items()])
|
| 67 |
elif isinstance(result, list):
|
| 68 |
return "\n".join([str(item) for item in result])
|
| 69 |
+
return str(result)
|
|
|
|
| 70 |
|
| 71 |
+
def _is_related_query(self, current_query: str, previous_context: Dict) -> bool:
|
| 72 |
"""
|
| 73 |
+
Визначає, чи є поточний запит пов'язаним з попереднім контекстом.
|
| 74 |
+
|
| 75 |
+
Args:
|
| 76 |
+
current_query: Поточний запит
|
| 77 |
+
previous_context: Попередній контекст
|
| 78 |
+
Returns:
|
| 79 |
+
bool: True якщо запит пов'язаний з попереднім контекстом
|
| 80 |
"""
|
| 81 |
+
if not previous_context['last_topic']:
|
| 82 |
+
return False
|
| 83 |
+
|
| 84 |
+
prompt = f"""Визначте, чи є це уточнюючим запитом до попередньої теми.
|
| 85 |
+
Попередня тема: {previous_context['last_topic']}
|
| 86 |
+
Новий запит: {current_query}
|
| 87 |
+
Відповідь має бути лише True або False."""
|
| 88 |
+
|
| 89 |
try:
|
| 90 |
+
response = self.model(prompt)
|
| 91 |
+
return 'true' in response.lower()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
except Exception as e:
|
| 93 |
+
logger.error(f"Помилка при визначенні зв'язку запитів: {e}")
|
| 94 |
+
return False
|
|
|
|
|
|
|
| 95 |
|
| 96 |
+
def _build_context_prompt(self, query: str, context: Dict) -> str:
|
| 97 |
"""
|
| 98 |
+
Формує промпт з урахуванням попереднього контексту.
|
| 99 |
+
|
| 100 |
+
Args:
|
| 101 |
+
query: Поточний запит
|
| 102 |
+
context: Контекст розмови
|
| 103 |
+
Returns:
|
| 104 |
+
str: Сформований промпт
|
| 105 |
"""
|
| 106 |
+
prompt_parts = []
|
| 107 |
+
|
| 108 |
+
if context['previous_queries']:
|
| 109 |
+
prompt_parts.append("Попередні запити та результати:")
|
| 110 |
+
for prev_query in context['previous_queries'][-3:]:
|
| 111 |
+
prompt_parts.append(f"Запит: {prev_query}")
|
| 112 |
+
if prev_query in context['search_results']:
|
| 113 |
+
prompt_parts.append("Знайдена інформація:")
|
| 114 |
+
prompt_parts.append(context['search_results'][prev_query])
|
| 115 |
+
if prev_query in context['generated_content']:
|
| 116 |
+
prompt_parts.append("Згенерований контент:")
|
| 117 |
+
prompt_parts.append(context['generated_content'][prev_query])
|
| 118 |
+
prompt_parts.append("---")
|
| 119 |
+
|
| 120 |
+
prompt_parts.append(f"Поточний запит: {query}")
|
| 121 |
+
prompt_parts.append("На основі всієї наведеної інформації створіть детальну відповідь.")
|
| 122 |
+
|
| 123 |
+
return "\n".join(prompt_parts)
|
| 124 |
+
|
| 125 |
+
def _update_context(self, query: str, search_results: str, generated_content: str):
|
| 126 |
+
"""
|
| 127 |
+
Оновлює контекст розмови.
|
| 128 |
+
|
| 129 |
+
Args:
|
| 130 |
+
query: Поточний запит
|
| 131 |
+
search_results: Результати пошуку
|
| 132 |
+
generated_content: Згенерований контент
|
| 133 |
+
"""
|
| 134 |
+
self.conversation_context['previous_queries'].append(query)
|
| 135 |
+
self.conversation_context['search_results'][query] = search_results
|
| 136 |
+
self.conversation_context['generated_content'][query] = generated_content
|
| 137 |
+
self.conversation_context['last_topic'] = query
|
| 138 |
|
| 139 |
def process_query(self, query: str, available_files: Optional[List[str]] = None) -> str:
|
| 140 |
"""
|
| 141 |
+
Обробка дослідницького запиту з підтримкою контексту.
|
| 142 |
+
|
| 143 |
+
Args:
|
| 144 |
+
query: Запит для обробки
|
| 145 |
+
available_files: Список доступних файлів
|
| 146 |
+
Returns:
|
| 147 |
+
str: Результат обробки запиту
|
| 148 |
"""
|
| 149 |
try:
|
| 150 |
logger.info(f"Обробка дослідницького запиту: {query}")
|
| 151 |
self._update_steps("Початок обробки запиту")
|
| 152 |
|
| 153 |
+
# Перевіряємо зв'язок з попереднім контекстом
|
| 154 |
+
is_related = self._is_related_query(query, self.conversation_context)
|
| 155 |
+
self._update_steps("Аналіз зв'язку з попереднім контекстом",
|
| 156 |
+
{'is_related': is_related})
|
| 157 |
+
|
| 158 |
+
# Виконуємо пошук
|
| 159 |
+
self._update_steps("Пошук інформації в інтернеті")
|
| 160 |
+
search_results = self.available_tools['web_search'](query=query)
|
| 161 |
+
self._update_steps("Отримано результати пошуку", search_results)
|
| 162 |
+
|
| 163 |
+
# Формуємо промпт
|
| 164 |
+
if is_related:
|
| 165 |
+
prompt = self._build_context_prompt(query, self.conversation_context)
|
| 166 |
+
self._update_steps("Формування запиту з урахуванням контексту",
|
| 167 |
+
{'context_length': len(self.conversation_context['previous_queries'])})
|
| 168 |
+
else:
|
| 169 |
+
prompt = f"Task: {query}\n\nSearch Results:\n{search_results}"
|
| 170 |
+
self._update_steps("Формування нового запиту")
|
| 171 |
+
|
| 172 |
+
# Генеруємо відповідь
|
| 173 |
+
self._update_steps("Генерація відповіді")
|
| 174 |
+
result = self.model(prompt)
|
| 175 |
|
| 176 |
+
# Оновлюємо контекст
|
| 177 |
+
self._update_steps("Оновлення контексту розмови")
|
| 178 |
+
self._update_context(query, search_results, result)
|
| 179 |
|
| 180 |
self._update_steps("Запит успішно оброблено", {
|
| 181 |
+
'context_size': len(self.conversation_context['previous_queries']),
|
| 182 |
+
'is_related_query': is_related
|
| 183 |
})
|
| 184 |
|
| 185 |
+
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
|
| 187 |
except Exception as e:
|
| 188 |
error_msg = f"Помилка при обробці запиту: {str(e)}"
|
| 189 |
logger.error(error_msg)
|
| 190 |
self._update_steps(f"Помилка", {'error': error_msg})
|
| 191 |
+
return error_msg
|
| 192 |
+
|
| 193 |
+
def clear_context(self):
|
| 194 |
+
"""
|
| 195 |
+
Очищення контексту розмови.
|
| 196 |
+
|
| 197 |
+
Returns:
|
| 198 |
+
str: Повідомлення про очищення контексту
|
| 199 |
+
"""
|
| 200 |
+
self.conversation_context = {
|
| 201 |
+
'previous_queries': [],
|
| 202 |
+
'search_results': {},
|
| 203 |
+
'generated_content': {},
|
| 204 |
+
'last_topic': None
|
| 205 |
+
}
|
| 206 |
+
logger.info("Контекст розмови очищено")
|
| 207 |
+
return "Контекст розмови очищено"
|
docs/agent_documentation.md
CHANGED
|
@@ -2,14 +2,16 @@
|
|
| 2 |
|
| 3 |
## Загальний опис
|
| 4 |
|
| 5 |
-
Research Agent - це інтелектуальний помічник для проведення наукових досліджень та створення структурованих звітів. Агент використовує потужні мовні моделі та має доступ до різних інструментів для пошуку та аналізу інформації.
|
| 6 |
|
| 7 |
## Основні можливості
|
| 8 |
|
| 9 |
-
- Пошук інформації в інтернеті
|
| 10 |
- Аналіз та синтез знайденої інформації
|
| 11 |
- Створення структурованих наукових звітів
|
|
|
|
| 12 |
- Збереження результатів дослідження
|
|
|
|
| 13 |
|
| 14 |
## Доступні інструменти
|
| 15 |
|
|
@@ -21,11 +23,22 @@ Research Agent - це інтелектуальний помічник для п
|
|
| 21 |
|
| 22 |
## Рекомендації з використання
|
| 23 |
|
|
|
|
| 24 |
- Формулюйте чіткі та конкретні запити
|
| 25 |
-
- Вказуйте бажану структуру звіту, якщо вона відрізняється від стандартної
|
| 26 |
- Використовуйте опцію збереження для важливих результатів
|
| 27 |
- Перевіряйте проміжні кроки у вікні Process Steps
|
| 28 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
## Формат звітів
|
| 31 |
|
|
@@ -39,37 +52,55 @@ Research Agent - це інтелектуальний помічник для п
|
|
| 39 |
- **Conclusion** - висновки
|
| 40 |
- **References** - використані джерела
|
| 41 |
|
| 42 |
-
## Приклади
|
| 43 |
|
| 44 |
-
###
|
| 45 |
```
|
| 46 |
-
Дослідіть сучасні тенденції в розвитку штучного інтелекту
|
|
|
|
|
|
|
|
|
|
| 47 |
```
|
| 48 |
|
| 49 |
-
###
|
| 50 |
```
|
| 51 |
-
|
|
|
|
| 52 |
```
|
| 53 |
|
| 54 |
-
|
| 55 |
-
```
|
| 56 |
-
Порівняйте ефективність різних методів машинного навчання в обробці медичних зображень
|
| 57 |
-
```
|
| 58 |
|
| 59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
|
| 61 |
### Вибір моделі
|
| 62 |
Агент підтримує різні мовні моделі:
|
| 63 |
- **Gemini Pro** - швидка та потужна модель від Google
|
| 64 |
- **Mistral** - оптимізована інструктивна модель
|
| 65 |
|
| 66 |
-
### Збереження результатів
|
| 67 |
-
- Використовуйте кнопку "Зберегти" для експорту звіту в форматі Markdown
|
| 68 |
-
- Всі звіти зберігаються з часовою міткою для легкого відстеження
|
| 69 |
-
|
| 70 |
### Моніторинг процесу
|
| 71 |
Вікно Process Steps показує:
|
| 72 |
- Поточний етап обробки
|
| 73 |
- Результати проміжних операцій
|
|
|
|
| 74 |
- Статус виконання запиту
|
| 75 |
-
- Можливі помилки та їх деталі
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
## Загальний опис
|
| 4 |
|
| 5 |
+
Research Agent - це інтелектуальний помічник для проведення наукових досліджень та створення структурованих звітів. Агент використовує потужні мовні моделі та має доступ до різних інструментів для пошуку та аналізу інформації. Підтримує контекстний діалог, що дозволяє вести послідовне дослідження теми через уточнюючі запитання.
|
| 6 |
|
| 7 |
## Основні можливості
|
| 8 |
|
| 9 |
+
- Пошук та аналіз інформації в інтернеті
|
| 10 |
- Аналіз та синтез знайденої інформації
|
| 11 |
- Створення структурованих наукових звітів
|
| 12 |
+
- Підтримка контекстного діалогу та уточнюючих запитань
|
| 13 |
- Збереження результатів дослідження
|
| 14 |
+
- Інтерактивне відображення процесу обробки
|
| 15 |
|
| 16 |
## Доступні інструменти
|
| 17 |
|
|
|
|
| 23 |
|
| 24 |
## Рекомендації з використання
|
| 25 |
|
| 26 |
+
### Загальні рекомендації
|
| 27 |
- Формулюйте чіткі та конкретні запити
|
|
|
|
| 28 |
- Використовуйте опцію збереження для важливих результатів
|
| 29 |
- Перевіряйте проміжні кроки у вікні Process Steps
|
| 30 |
+
- Слідкуйте за контекстом розмови в інформаційному блоці
|
| 31 |
+
|
| 32 |
+
### Робота з контекстом
|
| 33 |
+
- Використовуйте уточнюючі запитання для глибшого дослідження теми
|
| 34 |
+
- Слідкуйте за відображенням контексту у вікні Process Steps
|
| 35 |
+
- Використовуйте кнопку "Очистити контекст" для початку нової теми
|
| 36 |
+
- Зверніть увагу на індикатор зв'язку з попереднім контекстом
|
| 37 |
+
|
| 38 |
+
### Структура запитів
|
| 39 |
+
- Для нової теми: формулюйте повний, самодостатній запит
|
| 40 |
+
- Для уточнення: можна використовувати короткі, контекстні запитання
|
| 41 |
+
- При зміні теми: рекомендується очистити контекст
|
| 42 |
|
| 43 |
## Формат звітів
|
| 44 |
|
|
|
|
| 52 |
- **Conclusion** - висновки
|
| 53 |
- **References** - використані джерела
|
| 54 |
|
| 55 |
+
## Приклади діалогів
|
| 56 |
|
| 57 |
+
### Послідовне дослідження
|
| 58 |
```
|
| 59 |
+
Користувач: Дослідіть сучасні тенденції в розвитку штучного інтелекту
|
| 60 |
+
Агент: [надає загальний огляд]
|
| 61 |
+
Користувач: Розкажіть детальніше про застосування у медицині
|
| 62 |
+
Агент: [надає специфічну інформацію, використовуючи попередній контекст]
|
| 63 |
```
|
| 64 |
|
| 65 |
+
### Зміна теми
|
| 66 |
```
|
| 67 |
+
Користувач: [натискає "Очистити контекст"]
|
| 68 |
+
Користувач: Дослідіть нову тему...
|
| 69 |
```
|
| 70 |
|
| 71 |
+
## Інтерфейс користувача
|
|
|
|
|
|
|
|
|
|
| 72 |
|
| 73 |
+
### Основні елементи
|
| 74 |
+
- **Чат** - основне вікно діалогу
|
| 75 |
+
- **Process Steps** - відображення процесу обробки та контексту
|
| 76 |
+
- **Кнопки керування**:
|
| 77 |
+
- "Надіслати" - відправка запиту
|
| 78 |
+
- "Очистити чат" - очищення історії повідомлень
|
| 79 |
+
- "Очистити контекст" - скидання контексту розмови
|
| 80 |
+
- "Зберегти" - збереження результатів
|
| 81 |
|
| 82 |
### Вибір моделі
|
| 83 |
Агент підтримує різні мовні моделі:
|
| 84 |
- **Gemini Pro** - швидка та потужна модель від Google
|
| 85 |
- **Mistral** - оптимізована інструктивна модель
|
| 86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
### Моніторинг процесу
|
| 88 |
Вікно Process Steps показує:
|
| 89 |
- Поточний етап обробки
|
| 90 |
- Результати проміжних операцій
|
| 91 |
+
- Інформацію про контекст розмови
|
| 92 |
- Статус виконання запиту
|
| 93 |
+
- Можливі помилки та їх деталі
|
| 94 |
+
|
| 95 |
+
### Контекстна інформація
|
| 96 |
+
У вікні Process Steps відображається:
|
| 97 |
+
- Кількість попередніх запитів у контексті
|
| 98 |
+
- Поточна тема дослідження
|
| 99 |
+
- Зв'язок з попередніми запитами
|
| 100 |
+
- Статус обробки контексту
|
| 101 |
+
|
| 102 |
+
### Збереження результатів
|
| 103 |
+
- Використовуйте кнопку "Зберегти" для експорту звіту
|
| 104 |
+
- Всі звіти зберігаються в форматі Markdown
|
| 105 |
+
- Файли містять часову мітку для легкого відстеження
|
| 106 |
+
- Збережені звіти доступні в папці "saved_reports"
|