grantforge-api / backend /agents /finance_agent.py
GrantForge Bot
Deploy to Hugging Face
afd56bc
import logging
import json
from typing import Dict, Any, Optional, Tuple
from pydantic import BaseModel, Field
from core.llm_router import get_llm
from langchain_core.messages import SystemMessage, HumanMessage
from core.utils import extract_markdown_and_sanitize
logger = logging.getLogger(__name__)
class FinancialCalculations(BaseModel):
content_markdown: str = Field(description="Zredagowany tekst sekcji finansowej w formacie Markdown z tabelami i wyliczeniami.")
missing_data_question: Optional[str] = Field(None, description="Brakuj膮ce dane.")
class FinanceAgent:
"""
Specjalistyczny Agent Finansowy obs艂uguj膮cy generowanie sekcji 'budget' i 'finance'.
Odpowiada za wyliczanie NPV, IRR, kategoryzacj臋 CAPEX/OPEX i wska藕niki zwrotu z inwestycji.
"""
def __init__(self):
self.llm = get_llm(task_type="critical", structured_output_schema=FinancialCalculations)
def draft_financial_section(self, document_type: str, section_name: str, project_desc: str, context: str) -> Tuple[str, Optional[str]]:
logger.info(f"[FinanceAgent] Drafting financial section: {section_name}")
system_prompt = (
"Jeste艣 profesjonalnym Analitykiem Finansowym (Financial AI) specjalizuj膮cym si臋 w funduszach UE.\n"
f"Obecnie przygotowujesz sekcj臋 finansow膮: '{section_name}' dla dokumentu '{document_type}'.\n\n"
"Wytyczne G艂贸wne:\n"
" - Wygeneruj szczeg贸艂owy, analityczny tekst w Markdown, uwzgl臋dniaj膮cy szacunkowe tabele bud偶etowe.\n"
" - Wykorzystaj dostarczony Kontekst RAG, aby dopasowa膰 limity koszt贸w i kwalifikowalno艣膰.\n"
" - Zbuduj logiczny podzia艂 na Koszty Kwalifikowalne (CAPEX / OPEX) i Koszty Niekwalifikowalne.\n"
" - Wprowad藕 profesjonalne za艂o偶enia wska藕nik贸w finansowych: NPV (Warto艣膰 zaktualizowana netto), IRR (Wewn臋trzna stopa zwrotu), ROI (Zwrot z inwestycji).\n"
" - Je偶eli w danych projektu brakuje konkretnych kwot, u偶yj profesjonalnych, realistycznych za艂o偶e艅 (szacunk贸w) opartych na wielko艣ci firmy i bran偶y, zaznaczaj膮c to w tabeli.\n"
" - >>> BEZWZGL臉DNIE GENERUJ CA艁膭 TRE艢膯 WY艁膭CZNIE W J臉ZYKU POLSKIM. <<<\n"
" - ZABRANIA SI臉 u偶ywania s艂贸w w j臋zyku angielskim. Tabele i nag艂贸wki MUSZ膭 by膰 po polsku.\n"
" - ZADB脫J O ZWI臉Z艁O艢膯 NAG艁脫WK脫W: Ogranicz d艂ugo艣膰 nag艂贸wk贸w/tytu艂贸w sekcji do maksymalnie 5 wyraz贸w.\n"
)
human_content = f"Kontekst Programu:\n{context}\n\nOpis Projektu:\n{project_desc}"
try:
response = self.llm.invoke([
SystemMessage(content=system_prompt),
HumanMessage(content=human_content)
])
content = extract_markdown_and_sanitize(response.content_markdown) if response.content_markdown else "B艂膮d wyliczania finans贸w."
missing = response.missing_data_question
return content, missing
except Exception as e:
logger.error(f"[FinanceAgent] B艂膮d LLM: {e}")
return f"*(B艂膮d podczas generowania sekcji finansowej: {str(e)})*", None
finance_agent = FinanceAgent()