| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- import time
- import json
- from typing import Dict, List, Optional, Any
- from tenacity import retry, stop_after_attempt, wait_exponential
- import logging
- from openai import OpenAI
- from .config import config
- logger = logging.getLogger(__name__)
- class DeepSeekClient:
- """DeepSeek API kliendi klass"""
-
- def __init__(self):
- self.client = OpenAI(
- api_key=config.deepseek_api_key,
- base_url=config.deepseek_base_url
- )
- self.logger = logging.getLogger(__name__)
- self.max_tokens = config.max_tokens
-
- @retry(
- stop=stop_after_attempt(3),
- wait=wait_exponential(multiplier=1, min=4, max=10)
- )
- def call_api(self, messages: List[Dict], temperature: float = 0.7) -> str:
- """Kutsu DeepSeek API-d"""
- try:
- response = self.client.chat.completions.create(
- model=config.deepseek_model,
- messages=messages,
- max_tokens=self.max_tokens,
- temperature=temperature
- )
-
- content = response.choices[0].message.content
- tokens_used = response.usage.total_tokens if hasattr(response, 'usage') else 0
-
- self.logger.info(f"API kutsutud, tokenid: {tokens_used}")
- return content
-
- except Exception as e:
- self.logger.error(f"API viga: {str(e)}")
- raise
-
- def create_summary(self, text: str, context: Dict) -> Dict:
- """Loo põhjalik kokkuvõte artikkelist"""
- self.logger.info("Loon artikli kokkuvõtte DeepSeek-iga...")
-
- # Koosta süsteemipromt
- system_prompt = f"""Sa oled transpordiplaneerimise spetsialist ja teadusartiklite analüütik.
- Loo põhjalik kokkuvõte antud teadusartiklist EESTI KEELES.
- Kokkuvõte peaks sisaldama järgmisi osi:
- 1. ARTIKLI PEAMISED PUNKTID:
- - Uurimisküsimused ja eesmärgid
- - Teaduslik tähtsus
- - Uudne panus valdkonda
- 2. KASUTATUD MEETODID:
- - Andmete kogumise meetodid
- - Analüüsimeetodid
- - Mudelid ja algoritmid
- 3. PEAMISED TULEMUSED:
- - Olulisemad leidud
- - Statistilised tulemused
- - Mudeli täpsus ja piirangud
- 4. JÄRELDUSED JA SOOVITUSED:
- - Peamised järeldused
- - Rakendussoovitused
- - Edasised uurimissuunad
- 5. TRANSFORDIPLANEERIMISE KONTEKST:
- - Kuidas aitab see artikkel paremat transpordisüsteemi kujundada?
- - Millised on praktilised rakendused?
- - Mida võiks Eesti tingimustes rakendada?
- Kasuta selget ja asjakohast keelt. Olge konkreetne ja viida konkreetsetele leidudele.
- """
-
- # Koosta kasutaja promt
- user_prompt = f"""Loo põhjalik kokkuvõte järgmisest teadusartiklist:
- ARTIKLI INFO:
- Pealkiri: {context.get('title', 'Teadmata')}
- Autorid: {', '.join(context.get('authors', []))}
- Aasta: {context.get('year', 'Teadmata')}
- Žurnaal: {context.get('journal', 'Teadmata')}
- ARTIKLI SISU (esimesed 6000 märki):
- {text[:6000]}
- Palun loo struktureeritud kokkuvõte ülaltoodud nõuete järgi.
- """
-
- messages = [
- {"role": "system", "content": system_prompt},
- {"role": "user", "content": user_prompt}
- ]
-
- summary = self.call_api(messages, temperature=0.7)
-
- return {
- "summary_et": summary,
- "summary_length": len(summary),
- "language": "et"
- }
-
- def extract_key_concepts(self, text: str, summary: str) -> List[str]:
- """Eralda artikli olulisemad mõisted ja võtmesõnad"""
- self.logger.info("Eraldan võtmesõnu...")
-
- system_prompt = """Sa oled teadusartiklite analüütik. Eralda antud artiklist 5-10 olulisemat
- mõistet/võtmesõna, mis iseloomustavad artikli põhisisu. Tagasta need komadega eraldatud nimekirjana.
- """
-
- user_prompt = f"""Artikli kokkuvõte:
- {summary[:1000]}
- Artikli tekst (osa):
- {text[:2000]}
- Palun eralda olulisemad mõisted. Tagasta VAID komadega eraldatud nimekiri.
- """
-
- messages = [
- {"role": "system", "content": system_prompt},
- {"role": "user", "content": user_prompt}
- ]
-
- response = self.call_api(messages, temperature=0.3)
-
- # Puhasta vastus
- concepts = [c.strip() for c in response.split(',') if c.strip()]
- concepts = concepts[:10] # Piirangu 10 mõistele
-
- return concepts
-
- def identify_methods(self, text: str) -> List[str]:
- """Tuvasta artiklis kasutatud meetodid"""
- self.logger.info("Tuvastan kasutatud meetodeid...")
-
- system_prompt = """Sa oled teadusmeetodite spetsialist. Tuvasta antud teadusartiklist
- kasutatud peamised meetodid (nt: regressioonanalüüs, simulatsioon, juhtumianalüüs jne).
- Tagasta komadega eraldatud nimekiri.
- """
-
- user_prompt = f"""Artikli tekst (osa):
- {text[:3000]}
- Palun tuvasta kasutatud meetodid. Tagasta VAID komadega eraldatud nimekiri.
- """
-
- messages = [
- {"role": "system", "content": system_prompt},
- {"role": "user", "content": user_prompt}
- ]
-
- response = self.call_api(messages, temperature=0.3)
-
- methods = [m.strip() for m in response.split(',') if m.strip()]
- return methods
-
- def analyze_transport_context(self, summary: str) -> Dict:
- """Analüüsi artikli tähtsus transpordiplaneerimise kontekstis"""
- self.logger.info("Analüüsin transpordi konteksti...")
-
- system_prompt = """Sa oled transpordiplaneerimise ekspert. Analüüsi antud teadusartikli
- tähtsust ja rakendatavust transpordisüsteemide planeerimisel.
- Hinda järgmisi aspekte:
- 1. Teoreetiline panus
- 2. Praktiline rakendatavus
- 3. Reaalsete probleemide lahendamine
- 4. Piirangud ja edasised vajadused
- """
-
- user_prompt = f"""Artikli kokkuvõte:
- {summary}
- Palun analüüsi artikli tähtsust transpordiplaneerimise kontekstis. Tagasta JSON formaadis:
- {{
- "theoretical_contribution": "lühikirjeldus",
- "practical_applicability": "lühikirjeldus",
- "problem_solving": "lühikirjeldus",
- "limitations": "lühikirjeldus",
- "relevance_score": 1-10 (kus 10 on kõige relevantsem)
- }}
- """
-
- messages = [
- {"role": "system", "content": system_prompt},
- {"role": "user", "content": user_prompt}
- ]
-
- response = self.call_api(messages, temperature=0.5)
-
- try:
- # Proovi parsida JSON vastust
- if response.startswith('{') and response.endswith('}'):
- return json.loads(response)
- except:
- pass
-
- # Kui JSON parsimine ei õnnestu, tagasta struktureeritud tekst
- return {
- "analysis": response,
- "relevance_score": 5 # Vaikimisi skoor
- }
|