Spaces:
Runtime error
Runtime error
File size: 9,614 Bytes
ff6980a d1f023e ff6980a 65f6247 ff6980a 435589f 65f6247 ff6980a 435589f 65f6247 435589f ff6980a e32e103 65f6247 435589f e32e103 b0e5887 e32e103 65f6247 e32e103 65f6247 435589f 65f6247 ff6980a 65f6247 435589f 65f6247 435589f 65f6247 435589f 65f6247 435589f 65f6247 435589f 65f6247 ff6980a 65f6247 ff6980a 65f6247 ff6980a 435589f b0e5887 ff6980a 65f6247 ff6980a 65f6247 ff6980a e32e103 65f6247 e32e103 b0e5887 65f6247 ff6980a e32e103 65f6247 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
from smolagents import CodeAgent
import logging
from typing import Optional, List, Dict, Any
from datetime import datetime
import os
logger = logging.getLogger(__name__)
class ResearchAgent(CodeAgent):
"""
Дослідницький агент для наукового пошуку та аналізу з підтримкою контексту розмови.
"""
def __init__(self, model, tools, **kwargs):
"""
Ініціалізація дослідницького агента.
Args:
model: Модель для обробки запитів
tools: Інструменти для пошуку та обробки інформації
**kwargs: Додаткові параметри
"""
super().__init__(model=model, tools=tools, **kwargs)
self.available_tools = {tool.name: tool for tool in tools}
self.model_initializer = None
self.step_callback = None
# Ініціалізація контексту розмови
self.conversation_context = {
'previous_queries': [], # Історія запитів
'search_results': {}, # Результати пошуку для кожного запиту
'generated_content': {}, # Згенерований контент для кожного запиту
'last_topic': None # Остання обговорювана тема
}
logger.info(f"ResearchAgent ініціалізовано з інструментами: {list(self.available_tools.keys())}")
def _update_steps(self, step_info: str, step_result: Any = None):
"""
Оновлення інформації про кроки з результатами.
Args:
step_info: Інформація про поточний крок
step_result: Результат виконання кроку
"""
if self.step_callback:
step_data = {
'info': step_info,
'result': self._format_step_result(step_result)
}
self.step_callback(step_data)
logger.info(f"Step: {step_info}")
if step_result:
logger.info(f"Result: {str(step_result)[:200]}...")
def _format_step_result(self, result: Any) -> str:
"""
Форматування результату кроку для відображення.
Args:
result: Результат для форматування
Returns:
str: Відформатований результат
"""
if result is None:
return ""
if isinstance(result, dict):
return "\n".join([f"{k}: {str(v)}" for k, v in result.items()])
elif isinstance(result, list):
return "\n".join([str(item) for item in result])
return str(result)
def _is_related_query(self, current_query: str, previous_context: Dict) -> bool:
"""
Визначає, чи є поточний запит пов'язаним з попереднім контекстом.
Args:
current_query: Поточний запит
previous_context: Попередній контекст
Returns:
bool: True якщо запит пов'язаний з попереднім контекстом
"""
if not previous_context['last_topic']:
return False
prompt = f"""Визначте, чи є це уточнюючим запитом до попередньої теми.
Попередня тема: {previous_context['last_topic']}
Новий запит: {current_query}
Відповідь має бути лише True або False."""
try:
response = self.model(prompt)
return 'true' in response.lower()
except Exception as e:
logger.error(f"Помилка при визначенні зв'язку запитів: {e}")
return False
def _build_context_prompt(self, query: str, context: Dict) -> str:
"""
Формує промпт з урахуванням попереднього контексту.
Args:
query: Поточний запит
context: Контекст розмови
Returns:
str: Сформований промпт
"""
prompt_parts = []
if context['previous_queries']:
prompt_parts.append("Попередні запити та результати:")
for prev_query in context['previous_queries'][-3:]:
prompt_parts.append(f"Запит: {prev_query}")
if prev_query in context['search_results']:
prompt_parts.append("Знайдена інформація:")
prompt_parts.append(context['search_results'][prev_query])
if prev_query in context['generated_content']:
prompt_parts.append("Згенерований контент:")
prompt_parts.append(context['generated_content'][prev_query])
prompt_parts.append("---")
prompt_parts.append(f"Поточний запит: {query}")
prompt_parts.append("На основі всієї наведеної інформації створіть детальну відповідь.")
return "\n".join(prompt_parts)
def _update_context(self, query: str, search_results: str, generated_content: str):
"""
Оновлює контекст розмови.
Args:
query: Поточний запит
search_results: Результати пошуку
generated_content: Згенерований контент
"""
self.conversation_context['previous_queries'].append(query)
self.conversation_context['search_results'][query] = search_results
self.conversation_context['generated_content'][query] = generated_content
self.conversation_context['last_topic'] = query
def process_query(self, query: str, available_files: Optional[List[str]] = None) -> str:
"""
Обробка дослідницького запиту з підтримкою контексту.
Args:
query: Запит для обробки
available_files: Список доступних файлів
Returns:
str: Результат обробки запиту
"""
try:
logger.info(f"Обробка дослідницького запиту: {query}")
self._update_steps("Початок обробки запиту")
# Перевіряємо зв'язок з попереднім контекстом
is_related = self._is_related_query(query, self.conversation_context)
self._update_steps("Аналіз зв'язку з попереднім контекстом",
{'is_related': is_related})
# Виконуємо пошук
self._update_steps("Пошук інформації в інтернеті")
search_results = self.available_tools['web_search'](query=query)
self._update_steps("Отримано результати пошуку", search_results)
# Формуємо промпт
if is_related:
prompt = self._build_context_prompt(query, self.conversation_context)
self._update_steps("Формування запиту з урахуванням контексту",
{'context_length': len(self.conversation_context['previous_queries'])})
else:
prompt = f"Task: {query}\n\nSearch Results:\n{search_results}"
self._update_steps("Формування нового запиту")
# Генеруємо відповідь
self._update_steps("Генерація відповіді")
result = self.model(prompt)
# Оновлюємо контекст
self._update_steps("Оновлення контексту розмови")
self._update_context(query, search_results, result)
self._update_steps("Запит успішно оброблено", {
'context_size': len(self.conversation_context['previous_queries']),
'is_related_query': is_related
})
return result
except Exception as e:
error_msg = f"Помилка при обробці запиту: {str(e)}"
logger.error(error_msg)
self._update_steps(f"Помилка", {'error': error_msg})
return error_msg
def clear_context(self):
"""
Очищення контексту розмови.
Returns:
str: Повідомлення про очищення контексту
"""
self.conversation_context = {
'previous_queries': [],
'search_results': {},
'generated_content': {},
'last_topic': None
}
logger.info("Контекст розмови очищено")
return "Контекст розмови очищено" |