feat: папка dictionaries/prompts — словари промтов для каждой ИИ-кнопки
- prompts/suggest_object_params.json: жёсткие правила подбора характеристик — выбирать ТОЛЬКО из предоставленных списков (сферы/типы/архитектуры/ типовые объекты), ничего не выдумывать; назначение строго по форме «Объект предназначен для … с целью …»; типовой объект — дословно из 360-р - prompts/suggest_threats.json, check_security.json, check_company.json, declension.json — промты для остальных ИИ-кнопок - verify.py: _load_prompt() + подключение промтов в suggest_object_params_ai, suggest_threats_ai, check_security_ai; ИИ получает полные списки (spheres/object_types/architectures) и выбирает из них - ui.py: окно рекомендаций ИИ — галочки у каждого поля, применяются только отмеченные (ИИ может ошибаться в архитектуре — оператор решает)
This commit is contained in:
+75
-41
@@ -14,6 +14,18 @@
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
def _load_prompt(name):
|
||||
"""Загружает промт из dictionaries/prompts/<name>.json (system/rules/response_format)."""
|
||||
import os as _os
|
||||
p = _os.path.join(_os.path.dirname(_os.path.abspath(__file__)),
|
||||
'dictionaries', 'prompts', name + '.json')
|
||||
try:
|
||||
with open(p, encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
import urllib.parse
|
||||
@@ -526,20 +538,24 @@ def suggest_threats_ai(security_data, api_key, model='deepseek-chat', base_url=N
|
||||
else:
|
||||
threat_list_text = "(перечень не предоставлен — используй знания об актуальном перечне БДУ ФСТЭК)"
|
||||
|
||||
system = (
|
||||
pr = _load_prompt('suggest_threats')
|
||||
system = pr.get('system', (
|
||||
"Ты — эксперт ФСТЭК по безопасности критической информационной инфраструктуры "
|
||||
"(187-ФЗ, приказ ФСТЭК № 236). На основе характеристик объекта КИИ выбери из "
|
||||
"предоставленного перечня АКТУАЛЬНЫЕ угрозы безопасности информации и верни "
|
||||
"ТОЛЬКО JSON: "
|
||||
'{"threats": ["УБИ.xxx Название угрозы", ...]} — от 10 до 40 угроз, '
|
||||
"без пояснений и комментариев. Не выдумывай угрозы, которых нет в перечне; "
|
||||
"используй полные строки из перечня (код + название) как они есть."
|
||||
)
|
||||
"предоставленного перечня АКТУАЛЬНЫЕ угрозы безопасности информации."
|
||||
))
|
||||
rules = pr.get('rules', [])
|
||||
resp = pr.get('response_format',
|
||||
'Верни ТОЛЬКО JSON: {"threats": ["УБИ.xxx Название угрозы", ...]} '
|
||||
'— от 10 до 40 угроз, без пояснений.')
|
||||
user = (
|
||||
"Характеристики объекта КИИ:\n"
|
||||
f"{json.dumps(security_data, ensure_ascii=False)}\n\n"
|
||||
"Актуальный перечень угроз БДУ ФСТЭК:\n"
|
||||
f"{threat_list_text}"
|
||||
"Актуальный перечень угроз БДУ ФСТЭК (выбирай ТОЛЬКО из него, "
|
||||
"используй полные строки как они есть):\n"
|
||||
f"{threat_list_text}\n\n"
|
||||
+ ("Правила:\n" + "\n".join(f"{i+1}. {r}" for i, r in enumerate(rules)) + "\n\n" if rules else "")
|
||||
+ resp
|
||||
)
|
||||
js, err = _ai_json(api_key, model, base_url, system, user)
|
||||
if err:
|
||||
@@ -552,48 +568,66 @@ def suggest_threats_ai(security_data, api_key, model='deepseek-chat', base_url=N
|
||||
|
||||
|
||||
def suggest_object_params_ai(object_data, api_key, model='deepseek-chat', base_url=None,
|
||||
typical_objects=None):
|
||||
typical_objects=None, spheres=None, object_types=None,
|
||||
architectures=None):
|
||||
"""ИИ предлагает характеристики объекта КИИ: назначение, сферу, тип, архитектуру,
|
||||
типовой отраслевой объект — как рекомендацию оператору.
|
||||
|
||||
object_data — dict: name, description, purpose (что известно об объекте).
|
||||
typical_objects — перечень типовых отраслевых объектов (из 360-р) для выбора.
|
||||
typical_objects — перечень типовых отраслевых объектов (из 360-р) для выбора;
|
||||
spheres / object_types / architectures — полные списки допустимых значений.
|
||||
Промт берётся из dictionaries/prompts/suggest_object_params.json.
|
||||
|
||||
Возвращает (dict, ошибка): dict с полями
|
||||
purpose / sphere / object_type / architecture / typical_object / обоснование.
|
||||
назначение / сфера / тип / архитектура / типовой_объект / обоснование.
|
||||
"""
|
||||
if not api_key:
|
||||
return None, "Не задан API-ключ ИИ (Файл → Настройки → API)"
|
||||
|
||||
# Загрузка промта из папки dictionaries/prompts
|
||||
import os as _os
|
||||
prompt_path = _os.path.join(_os.path.dirname(_os.path.abspath(__file__)),
|
||||
'dictionaries', 'prompts', 'suggest_object_params.json')
|
||||
try:
|
||||
with open(prompt_path, encoding='utf-8') as _f:
|
||||
prompt = json.load(_f)
|
||||
except Exception:
|
||||
prompt = {}
|
||||
system = prompt.get('system', 'Ты — эксперт ФСТЭК по категорированию объектов КИИ.')
|
||||
rules = prompt.get('rules', [])
|
||||
response_format = prompt.get('response_format',
|
||||
'Верни ТОЛЬКО JSON: {"назначение": "...", "сфера": "...", '
|
||||
'"тип": "...", "архитектура": "...", "типовой_объект": "...", '
|
||||
'"обоснование": "..."}')
|
||||
|
||||
# Полные списки допустимых значений
|
||||
def _fmt_list(name, items):
|
||||
if not items:
|
||||
return f"{name}: (список не предоставлен)"
|
||||
return f"{name}:\n" + "\n".join(f"- {i}" for i in items)
|
||||
|
||||
lists_text = "\n\n".join([
|
||||
_fmt_list("Сферы деятельности (выбирай ТОЛЬКО из них)", spheres),
|
||||
_fmt_list("Типы объектов (выбирай ТОЛЬКО из них)", object_types),
|
||||
_fmt_list("Архитектуры (выбирай ТОЛЬКО из них)", architectures),
|
||||
])
|
||||
if typical_objects:
|
||||
to_text = "\n".join(f"{i+1}. {t}" for i, t in enumerate(typical_objects[:400]))
|
||||
else:
|
||||
to_text = "(перечень не предоставлен)"
|
||||
|
||||
system = (
|
||||
"Ты — эксперт ФСТЭК по категорированию объектов критической информационной инфраструктуры "
|
||||
"(187-ФЗ, ПП РФ № 127, Распоряжение ПРФ № 360-р, приказ ФСТЭК № 236). "
|
||||
"По описанию объекта КИИ предложи его характеристики. Верни ТОЛЬКО JSON: "
|
||||
'{"назначение": "короткое назначение объекта", '
|
||||
'"сфера": "одна из сфер: Здравоохранение, Наука, Транспорт, Связь, Энергетика, '
|
||||
'Государственная регистрация прав, Банковская сфера и финансовый рынок, '
|
||||
'Топливно-энергетический комплекс, Атомная энергетика, Оборонная промышленность, '
|
||||
'Ракетно-космическая промышленность, Горнодобывающая промышленность, '
|
||||
'Металлургическая промышленность, Химическая промышленность, Иная сфера деятельности", '
|
||||
'"тип": "Информационная система | Автоматизированные системы управления | '
|
||||
'Информационно-телекоммуникационная сеть", '
|
||||
'"архитектура": "одно из: клиент-серверная система, автономная (standalone), '
|
||||
'распределенная система, иное", '
|
||||
'"типовой_объект": "полная строка из предоставленного перечня, наиболее подходящая, '
|
||||
'или пустая строка", '
|
||||
'"обоснование": "почему выбраны такие характеристики (1-2 предложения)"} '
|
||||
"Не выдумывай типовой объект — бери только из перечня."
|
||||
)
|
||||
rules_text = "\n".join(f"{i+1}. {r}" for i, r in enumerate(rules))
|
||||
|
||||
user = (
|
||||
"Информация об объекте КИИ:\n"
|
||||
f"{json.dumps(object_data, ensure_ascii=False)}\n\n"
|
||||
"Перечень типовых отраслевых объектов КИИ (Распоряжение ПРФ № 360-р):\n"
|
||||
f"{to_text}"
|
||||
f"{lists_text}\n\n"
|
||||
"Перечень типовых отраслевых объектов КИИ (Распоряжение ПРФ № 360-р, "
|
||||
"выбирай ТОЛЬКО из него, копируй строку дословно):\n"
|
||||
f"{to_text}\n\n"
|
||||
"Правила:\n"
|
||||
f"{rules_text}\n\n"
|
||||
f"{response_format}"
|
||||
)
|
||||
js, err = _ai_json(api_key, model, base_url, system, user)
|
||||
if err:
|
||||
@@ -615,18 +649,18 @@ def check_security_ai(security_data, api_key, model='deepseek-chat', base_url=No
|
||||
"""
|
||||
if not api_key:
|
||||
return None, "Не задан API-ключ ИИ (Файл → Настройки → API)"
|
||||
system = (
|
||||
pr = _load_prompt('check_security')
|
||||
system = pr.get('system', (
|
||||
"Ты — эксперт по безопасности критической информационной инфраструктуры (187-ФЗ, "
|
||||
"приказ ФСТЭК России от 25.12.2017 № 239 «Об утверждении Требований по обеспечению "
|
||||
"безопасности значимых объектов КИИ» и приказ № 236). Проверь заполненные сведения "
|
||||
"об объекте КИИ и дай рекомендации. Верни ТОЛЬКО JSON: "
|
||||
'{"оценка": "ok|warning|error", '
|
||||
'"замечания": ["..."], '
|
||||
"приказ ФСТЭК России от 25.12.2017 № 239 и приказ № 236). Проверь заполненные "
|
||||
"сведения об объекте КИИ и дай рекомендации."
|
||||
))
|
||||
system = system + " " + pr.get('response_format',
|
||||
'Верни ТОЛЬКО JSON: {"оценка": "ok|warning|error", "замечания": ["..."], '
|
||||
'"предложения": {"attacker_category": "...", "threats": "...", "incidents": "...", '
|
||||
'"criteria_values": "...", "criteria_justification": "...", '
|
||||
'"org_measures": "...", "tech_measures": "..."}} '
|
||||
"В «предложениях» укажи, что добавить/исправить по каждому разделу, если нужно, иначе пустые строки."
|
||||
)
|
||||
'В «предложениях» укажи, что добавить/исправить по каждому разделу, иначе пустые строки.')
|
||||
user = json.dumps(security_data, ensure_ascii=False)
|
||||
js, err = _ai_json(api_key, model, base_url, system, user)
|
||||
if err:
|
||||
|
||||
Reference in New Issue
Block a user