Spaces:
Running
Running
| import logging | |
| import os | |
| from typing import Optional, Dict | |
| from langchain_core.messages import SystemMessage, HumanMessage | |
| from core.llm_router import get_llm | |
| try: | |
| from tools.web_search import general_web_search | |
| except ImportError: | |
| from backend.tools.web_search import general_web_search | |
| logger = logging.getLogger(__name__) | |
| class ResearchAgent: | |
| """ | |
| Sub-Agent badawczy Projektu TITAN. | |
| Zadaniem tego agenta jest przeszukiwanie sieci (OSINT / Web Search) | |
| oraz interpretacja wyników w przypadku braku danych w dokumencie. | |
| Zastępuje człowieka w trybie pełnej automatyzacji, znacznie zwiększając skuteczność. | |
| """ | |
| def __init__(self): | |
| # Inicjalizacja LLM dla analizy wyników badawczych. | |
| self.llm = get_llm(task_type="creative") # Używamy creative/standard | |
| def deep_search(self, query: str, context: str) -> str: | |
| """ | |
| Głębokie poszukiwanie danych w zewnętrznych bazach i sieci, | |
| oraz ich synteza przy użyciu LLM. | |
| """ | |
| logger.info(f"🔎 [Research Agent TITAN] Rozpoczęto głębokie wyszukiwanie dla: {query}") | |
| # 1. Wykonanie rzeczywistego wyszukiwania w sieci | |
| search_results = general_web_search(query) | |
| # 2. Jeśli nie znaleziono lub brak klucza, zwracamy stosowną informację, | |
| # ale możemy spróbować odpowiedzieć z wiedzy LLM z uwzględnieniem kontekstu. | |
| if "Błąd" in search_results or "Brak klucza" in search_results: | |
| logger.warning(f"[Research Agent TITAN] Problem z wyszukiwarką: {search_results}") | |
| search_context = "Nie udało się pobrać aktualnych danych z sieci z powodu braku dostępu do API wyszukiwania." | |
| else: | |
| search_context = f"Wyniki wyszukiwania:\n{search_results}" | |
| system_prompt = ( | |
| "Jesteś zaawansowanym Agentem Badawczym OSINT. Twoim zadaniem jest dostarczenie " | |
| "wyczerpujących i merytorycznych informacji na podstawie podanego kontekstu projektu " | |
| "oraz wyników wyszukiwania z sieci.\n\n" | |
| "Zasady:\n" | |
| "1. Twoim celem jest odpowiedź na brakujące zapytanie (pytanie o brakujące dane).\n" | |
| "2. Wykorzystaj informacje z 'Wyników wyszukiwania', jeśli są dostępne.\n" | |
| "3. Oprzyj się na 'Kontekście projektu', aby odpowiedź była dopasowana do specyfiki firmy i projektu.\n" | |
| "4. Jeśli z danych sieciowych i kontekstu nie da się jednoznacznie określić faktów (np. precyzyjnego przychodu małej firmy), " | |
| "zaproponuj profesjonalne i wiarygodne oszacowanie lub standardowe dla branży wartości rynkowe i zaznacz, że to szacunek, " | |
| "aby wniosek dotacyjny mógł zostać wygenerowany jako pełny szkic (użyj znaczników np. [SZACOWANY_PRZYCHÓD: 1.5 mln PLN]).\n" | |
| "5. Pisz wyłącznie w języku polskim, stylem profesjonalnym, odpowiednim do wniosków unijnych i biznesplanów." | |
| ) | |
| human_content = f"Pytanie o brakujące dane: {query}\n\nKontekst projektu:\n{context}\n\n{search_context}" | |
| try: | |
| response = self.llm.invoke([ | |
| SystemMessage(content=system_prompt), | |
| HumanMessage(content=human_content) | |
| ]) | |
| final_answer = response.content if hasattr(response, 'content') else str(response) | |
| logger.info("[Research Agent TITAN] Zakończono syntezę wyników badawczych.") | |
| return final_answer | |
| except Exception as e: | |
| logger.error(f"[Research Agent TITAN] Błąd generowania odpowiedzi przez LLM: {e}") | |
| return f"Nie udało się wygenerować odpowiedzi analitycznej na temat: {query}. Spróbuj użyć [BRAK DANYCH]." | |
| research_agent = ResearchAgent() | |