84 lines
3.6 KiB
Python
84 lines
3.6 KiB
Python
import json
|
||
import re
|
||
import requests
|
||
from config import OLLAMA_URL, OLLAMA_MODEL
|
||
|
||
def ask_ollama(prompt, system_prompt=None):
|
||
"""
|
||
Универсальная функция отправки запросов к Ollama (поддерживает /api/generate и /api/chat)
|
||
"""
|
||
payload = {
|
||
"model": OLLAMA_MODEL,
|
||
"prompt": f"{system_prompt}\n\n{prompt}" if system_prompt else prompt,
|
||
"stream": False
|
||
}
|
||
|
||
try:
|
||
response = requests.post(OLLAMA_URL, json=payload, timeout=120)
|
||
if response.status_code == 200:
|
||
data = response.json()
|
||
# Проверяем формат /api/generate
|
||
if "response" in data:
|
||
return data["response"].strip()
|
||
# Проверяем формат /api/chat
|
||
elif "message" in data and "content" in data["message"]:
|
||
return data["message"]["content"].strip()
|
||
else:
|
||
return f"⚠️ Неизвестная структура ответа Ollama: {data}"
|
||
else:
|
||
return f"⚠️ Ошибка Ollama (Код {response.status_code}): {response.text}"
|
||
except requests.exceptions.ConnectionError:
|
||
return "⚠️ Не удалось подключиться к Ollama. Проверьте, запущен ли сервис (ollama run qwen2.5:14b)."
|
||
except Exception as e:
|
||
return f"⚠️ Ошибка при обращении к Ollama: {e}"
|
||
|
||
def ai_verify_scud_against_staff(unrecognized_scud_fios, staff_fios):
|
||
"""ИИ-сверка опечаток и несовпадений ФИО между СКУД и 1С:ЗУП"""
|
||
if not unrecognized_scud_fios or not staff_fios:
|
||
return {}
|
||
|
||
prompt = f"""
|
||
Ты — кадровый аудитор безопасности СКУД.
|
||
В СКУД записаны неопознанные ФИО: {json.dumps(unrecognized_scud_fios, ensure_ascii=False)}
|
||
В официальном Штатном расписании 1С записаны ЭТАЛОНЫ: {json.dumps(staff_fios, ensure_ascii=False)}
|
||
|
||
СТРОГИЕ ПРАВИЛА:
|
||
1. Запись из Штат 1С — это 100% ПРАВИЛЬНЫЙ эталон.
|
||
2. В СКУД допущена опечатка.
|
||
3. В поле "warning" описать опечатку.
|
||
4. Запрещено выдумывать опечатки!
|
||
|
||
ОТВЕЧАЙ ТОЛЬКО ИСКЛЮЧИТЕЛЬНО В ФОРМАТЕ JSON!
|
||
|
||
Формат ответа:
|
||
{{
|
||
"verified_matches": [
|
||
{{
|
||
"scud_fio": "ФИО из СКУД",
|
||
"staff_fio": "эталон ФИО из Штат 1С",
|
||
"warning": "Описание опечатки в СКУД или 'Точное совпадение (без опечаток)'"
|
||
}}
|
||
]
|
||
}}
|
||
"""
|
||
raw_response = ask_ollama(
|
||
prompt,
|
||
system_prompt="Ты — JSON API. Выдавай ТОЛЬКО валидный JSON без markdown-разметки."
|
||
)
|
||
mapping = {}
|
||
try:
|
||
match = re.search(r'\{.*\}', raw_response, re.DOTALL)
|
||
if match:
|
||
json_str = match.group(0)
|
||
json_str = re.sub(r'\}\s*[^}\]]*$', '}', json_str)
|
||
data = json.loads(json_str)
|
||
for item in data.get("verified_matches", []):
|
||
scud_f = item.get("scud_fio")
|
||
staff_f = item.get("staff_fio")
|
||
warn = item.get("warning", "Точное совпадение (без опечаток)")
|
||
if scud_f and staff_f:
|
||
mapping[scud_f] = {"staff_fio": staff_f, "warning": warn}
|
||
except Exception as e:
|
||
print(f"[!] Ошибка разбора JSON от ИИ при сверке опечаток: {e}")
|
||
|
||
return mapping |