Spaces:
Sleeping
Sleeping
Trololindo commited on
Commit 路
6695efd
1
Parent(s): 1a97c8b
backend/app/services/factcheck_service.py
CHANGED
|
@@ -2,17 +2,54 @@ import logging
|
|
| 2 |
import json
|
| 3 |
import re
|
| 4 |
import os
|
|
|
|
| 5 |
from typing import Dict, Any, List
|
| 6 |
import google.generativeai as genai
|
| 7 |
|
| 8 |
logger = logging.getLogger(__name__)
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
async def analyze_with_gemini_grounding(statement: str) -> Dict[str, Any]:
|
| 11 |
"""
|
| 12 |
Analizuje stwierdzenie, automatycznie przeszukuj膮c internet za pomoc膮
|
| 13 |
wbudowanego w Gemini narz臋dzia Google Search Grounding.
|
| 14 |
-
Rozwi膮zuje to ca艂kowicie problemy z blokowaniem i timeoutami wyszukiwarek.
|
| 15 |
"""
|
|
|
|
|
|
|
|
|
|
| 16 |
api_key = os.getenv("GEMINI_API_KEY")
|
| 17 |
|
| 18 |
if not api_key:
|
|
@@ -26,8 +63,6 @@ async def analyze_with_gemini_grounding(statement: str) -> Dict[str, Any]:
|
|
| 26 |
|
| 27 |
genai.configure(api_key=api_key)
|
| 28 |
|
| 29 |
-
# Poniewa偶 nie mo偶emy 艂膮czy膰 narz臋dzia wyszukiwania (Google Search) z trybem JSON w konfiguracji API,
|
| 30 |
-
# wymuszamy struktur臋 JSON za pomoc膮 precyzyjnego promptu systemowego.
|
| 31 |
prompt = f"""Jeste艣 zaawansowanym asystentem do weryfikacji fakt贸w (fact-checking).
|
| 32 |
Przeanalizuj poni偶sze stwierdzenie, korzystaj膮c z wyszukiwarki Google (masz do niej dost臋p jako narz臋dzie), aby zweryfikowa膰 jego prawdziwo艣膰 w czasie rzeczywistym.
|
| 33 |
|
|
@@ -48,23 +83,21 @@ Wskaz贸wki do werdyktu:
|
|
| 48 |
"""
|
| 49 |
|
| 50 |
try:
|
| 51 |
-
# Inicjalizacja modelu z wbudowanym narz臋dziem Google Search
|
| 52 |
model = genai.GenerativeModel(
|
| 53 |
model_name="gemini-1.5-flash",
|
| 54 |
-
tools=[{"google_search": {}}]
|
| 55 |
)
|
| 56 |
|
| 57 |
response = model.generate_content(
|
| 58 |
prompt,
|
| 59 |
generation_config=genai.types.GenerationConfig(
|
| 60 |
-
temperature=0.0
|
| 61 |
)
|
| 62 |
)
|
| 63 |
|
| 64 |
raw_text = response.text.strip()
|
| 65 |
logger.info(f"Surowa odpowied藕 Gemini: {raw_text}")
|
| 66 |
|
| 67 |
-
# Wyczyszczenie tekstu z ewentualnych znacznik贸w markdown ```json ... ```
|
| 68 |
if raw_text.startswith("```"):
|
| 69 |
match = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", raw_text, re.DOTALL)
|
| 70 |
if match:
|
|
@@ -72,7 +105,6 @@ Wskaz贸wki do werdyktu:
|
|
| 72 |
|
| 73 |
result_json = json.loads(raw_text)
|
| 74 |
|
| 75 |
-
# Wyci膮ganie realnych 藕r贸de艂 (link贸w i tytu艂贸w), z kt贸rych skorzysta艂 model
|
| 76 |
sources = []
|
| 77 |
candidate = response.candidates[0]
|
| 78 |
metadata = getattr(candidate, "grounding_metadata", None)
|
|
|
|
| 2 |
import json
|
| 3 |
import re
|
| 4 |
import os
|
| 5 |
+
from pathlib import Path
|
| 6 |
from typing import Dict, Any, List
|
| 7 |
import google.generativeai as genai
|
| 8 |
|
| 9 |
logger = logging.getLogger(__name__)
|
| 10 |
|
| 11 |
+
def load_env_fallback():
|
| 12 |
+
"""
|
| 13 |
+
R臋cznie wczytuje plik .env do os.environ.
|
| 14 |
+
Szuka pliku w kilku prawdopodobnych miejscach, zale偶nie od tego, sk膮d uruchomiono serwer.
|
| 15 |
+
"""
|
| 16 |
+
if os.getenv("GEMINI_API_KEY"):
|
| 17 |
+
return # Klucz ju偶 jest wczytany, nie musimy nic robi膰
|
| 18 |
+
|
| 19 |
+
# Sprawdzamy potencjalne 艣cie偶ki do pliku .env
|
| 20 |
+
possible_paths = [
|
| 21 |
+
Path(".env"), # Bie偶膮cy folder roboczy
|
| 22 |
+
Path("backend/.env"), # Folder backend (je艣li uruchomiono z g艂贸wnego)
|
| 23 |
+
Path(__file__).resolve().parent.parent.parent / ".env" # 艢cie偶ka relatywna do tego pliku serwisu
|
| 24 |
+
]
|
| 25 |
+
|
| 26 |
+
for path in possible_paths:
|
| 27 |
+
if path.exists():
|
| 28 |
+
logger.info(f"Wczytywanie pliku .env z lokalizacji: {path.resolve()}")
|
| 29 |
+
try:
|
| 30 |
+
with open(path, "r", encoding="utf-8") as f:
|
| 31 |
+
for line in f:
|
| 32 |
+
line = line.strip()
|
| 33 |
+
if line and not line.startswith("#") and "=" in line:
|
| 34 |
+
key, val = line.split("=", 1)
|
| 35 |
+
# Oczyszczamy klucz i warto艣膰 z cudzys艂ow贸w oraz spacji
|
| 36 |
+
os.environ[key.strip()] = val.strip().strip("'\"")
|
| 37 |
+
return
|
| 38 |
+
except Exception as e:
|
| 39 |
+
logger.warning(f"Nie uda艂o si臋 odczyta膰 pliku {path}: {e}")
|
| 40 |
+
|
| 41 |
+
# Uruchamiamy wczytywanie 艣rodowiska przy imporcie tego serwisu
|
| 42 |
+
load_env_fallback()
|
| 43 |
+
|
| 44 |
+
|
| 45 |
async def analyze_with_gemini_grounding(statement: str) -> Dict[str, Any]:
|
| 46 |
"""
|
| 47 |
Analizuje stwierdzenie, automatycznie przeszukuj膮c internet za pomoc膮
|
| 48 |
wbudowanego w Gemini narz臋dzia Google Search Grounding.
|
|
|
|
| 49 |
"""
|
| 50 |
+
# Upewniamy si臋, 偶e 艣rodowisko jest za艂adowane
|
| 51 |
+
load_env_fallback()
|
| 52 |
+
|
| 53 |
api_key = os.getenv("GEMINI_API_KEY")
|
| 54 |
|
| 55 |
if not api_key:
|
|
|
|
| 63 |
|
| 64 |
genai.configure(api_key=api_key)
|
| 65 |
|
|
|
|
|
|
|
| 66 |
prompt = f"""Jeste艣 zaawansowanym asystentem do weryfikacji fakt贸w (fact-checking).
|
| 67 |
Przeanalizuj poni偶sze stwierdzenie, korzystaj膮c z wyszukiwarki Google (masz do niej dost臋p jako narz臋dzie), aby zweryfikowa膰 jego prawdziwo艣膰 w czasie rzeczywistym.
|
| 68 |
|
|
|
|
| 83 |
"""
|
| 84 |
|
| 85 |
try:
|
|
|
|
| 86 |
model = genai.GenerativeModel(
|
| 87 |
model_name="gemini-1.5-flash",
|
| 88 |
+
tools=[{"google_search": {}}]
|
| 89 |
)
|
| 90 |
|
| 91 |
response = model.generate_content(
|
| 92 |
prompt,
|
| 93 |
generation_config=genai.types.GenerationConfig(
|
| 94 |
+
temperature=0.0
|
| 95 |
)
|
| 96 |
)
|
| 97 |
|
| 98 |
raw_text = response.text.strip()
|
| 99 |
logger.info(f"Surowa odpowied藕 Gemini: {raw_text}")
|
| 100 |
|
|
|
|
| 101 |
if raw_text.startswith("```"):
|
| 102 |
match = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", raw_text, re.DOTALL)
|
| 103 |
if match:
|
|
|
|
| 105 |
|
| 106 |
result_json = json.loads(raw_text)
|
| 107 |
|
|
|
|
| 108 |
sources = []
|
| 109 |
candidate = response.candidates[0]
|
| 110 |
metadata = getattr(candidate, "grounding_metadata", None)
|