Upload folder using huggingface_hub
Browse files- README.md +1 -1
- patterns.json +21 -8
- run.py +65 -35
README.md
CHANGED
|
@@ -23,7 +23,7 @@ tags:
|
|
| 23 |
- 📱 **Работы на слабых устройствах** — Raspberry Pi, старые ноутбуки, телефоны,
|
| 24 |
- 🧪 **Создания своей нейросети** — идеальная отправная точка для начинающих.
|
| 25 |
|
| 26 |
-
> **Это
|
| 27 |
> - Понимает опечатки,
|
| 28 |
> - Отвечает на русском,
|
| 29 |
> - Работает **без интернета и GPU**,
|
|
|
|
| 23 |
- 📱 **Работы на слабых устройствах** — Raspberry Pi, старые ноутбуки, телефоны,
|
| 24 |
- 🧪 **Создания своей нейросети** — идеальная отправная точка для начинающих.
|
| 25 |
|
| 26 |
+
> ⚠️ **Это НЕ LLM**. Это **интеллектуальный чат-бот на правилах и нечётком сравнении**, который:
|
| 27 |
> - Понимает опечатки,
|
| 28 |
> - Отвечает на русском,
|
| 29 |
> - Работает **без интернета и GPU**,
|
patterns.json
CHANGED
|
@@ -2,9 +2,7 @@
|
|
| 2 |
"привет": [
|
| 3 |
"Привет! Как твои дела?",
|
| 4 |
"Здравствуй! Чем могу помочь?",
|
| 5 |
-
"Приветствую! О чём поговорим?"
|
| 6 |
-
"Здарова бро!",
|
| 7 |
-
"С возвращением!"
|
| 8 |
],
|
| 9 |
"как дела": [
|
| 10 |
"Отлично, спасибо! А у тебя?",
|
|
@@ -12,9 +10,9 @@
|
|
| 12 |
"Нормально, только скучаю без задачек :)"
|
| 13 |
],
|
| 14 |
"имя": [
|
| 15 |
-
"Я — Newton
|
| 16 |
"Меня зовут Newton, я помогаю в учёбе и не только!",
|
| 17 |
-
"Я Newton — умный помощник из Runget."
|
| 18 |
],
|
| 19 |
"школа": [
|
| 20 |
"Школа — это важно! Нужна помощь с уроками?",
|
|
@@ -30,7 +28,22 @@
|
|
| 30 |
"Интересно! Расскажи ещё.",
|
| 31 |
"Понятно. А что думаешь ты?",
|
| 32 |
"Хм... А если посмотреть с другой стороны?",
|
| 33 |
-
"Я ещё учусь. Можешь переформулировать?"
|
| 34 |
-
|
| 35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
}
|
|
|
|
| 2 |
"привет": [
|
| 3 |
"Привет! Как твои дела?",
|
| 4 |
"Здравствуй! Чем могу помочь?",
|
| 5 |
+
"Приветствую! О чём поговорим?"
|
|
|
|
|
|
|
| 6 |
],
|
| 7 |
"как дела": [
|
| 8 |
"Отлично, спасибо! А у тебя?",
|
|
|
|
| 10 |
"Нормально, только скучаю без задачек :)"
|
| 11 |
],
|
| 12 |
"имя": [
|
| 13 |
+
"Я — Newton Micro, твой мини-ИИ. Меня создал Kolyadual",
|
| 14 |
"Меня зовут Newton, я помогаю в учёбе и не только!",
|
| 15 |
+
"Я Newton — умный помощник из Runget. Меня создал Kolyadual"
|
| 16 |
],
|
| 17 |
"школа": [
|
| 18 |
"Школа — это важно! Нужна помощь с уроками?",
|
|
|
|
| 28 |
"Интересно! Расскажи ещё.",
|
| 29 |
"Понятно. А что думаешь ты?",
|
| 30 |
"Хм... А если посмотреть с другой стороны?",
|
| 31 |
+
"Я ещё учусь. Можешь переформулировать?"
|
| 32 |
+
],
|
| 33 |
+
|
| 34 |
+
"knowledge": {
|
| 35 |
+
"что такое любовь": "Любовь — это сильное чувство привязанности, заботы и привязанности к другому человеку.",
|
| 36 |
+
"что такое дружба": "Дружба — это близкие отношения, основанные на взаимном доверии, поддержке и уважении.",
|
| 37 |
+
"что такое ии": "Искусственный интеллект — это способность машин имитировать интеллектуальные функции человека.",
|
| 38 |
+
"что такое школа": "Школа — это учебное заведение для детей, где они получают базовые знания.",
|
| 39 |
+
"что такое солнце": "Солнце — это звезда, вокруг которой вращается Земля и другие планеты.",
|
| 40 |
+
"что такое вода": "Вода — это химическое соединение H₂O, необходимое для жизни.",
|
| 41 |
+
"как приготовить бутерброд": "Намажь масло на хлеб, положи сыр или колбасу. Готово!",
|
| 42 |
+
"как приготовить яичницу": "Разбей яйца на сковороду с маслом, жарь 2–3 минуты до готовности.",
|
| 43 |
+
"как приготовить чай": "Завари чайный пакетик кипятком на 3–5 минут. Добавь сахар по вкусу.",
|
| 44 |
+
"как приготовить пасту": "Отвари пасту в подсолённой воде 8–10 минут. Слей воду, добавь соус.",
|
| 45 |
+
"что такое кулинария": "Кулинария — это искусство приготовления пищи.",
|
| 46 |
+
"что такое рецепт": "Рецепт — это пошаговое описание, как приготовить блюдо.",
|
| 47 |
+
"что такое runget": "Runget - операционная система разрабатываемая Runget Team"
|
| 48 |
+
}
|
| 49 |
}
|
run.py
CHANGED
|
@@ -1,82 +1,112 @@
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
-
#
|
| 3 |
import json
|
| 4 |
import random
|
| 5 |
import re
|
|
|
|
| 6 |
from difflib import get_close_matches
|
| 7 |
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
# Ключевые слова для каждой категории (для fuzzy matching)
|
| 13 |
KEYWORDS = {
|
| 14 |
"привет": ["привет", "здравствуй", "хай", "прив", "здарова"],
|
| 15 |
"как дела": ["дела", "как ты", "ты как", "настроение"],
|
| 16 |
"имя": ["имя", "кто ты", "зовут", "тебя зовут"],
|
| 17 |
"школа": ["школа", "урок", "задача", "домашка", "математика", "геометрия"],
|
| 18 |
-
"пока": ["пока", "выход", "quit", "до свидания", "закончить", "стоп"]
|
|
|
|
| 19 |
}
|
| 20 |
|
| 21 |
def preprocess(text):
|
| 22 |
-
|
| 23 |
-
return re.sub(r'[^а-яё\s]', '', text.lower()).strip()
|
| 24 |
|
| 25 |
-
def
|
| 26 |
-
"""Определяет намерение даже при опечатках"""
|
| 27 |
clean = preprocess(user_input)
|
| 28 |
if not clean:
|
| 29 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
-
# Собираем все ключевые слова
|
| 32 |
all_keywords = []
|
| 33 |
keyword_to_intent = {}
|
| 34 |
for intent, words in KEYWORDS.items():
|
|
|
|
|
|
|
| 35 |
for word in words:
|
| 36 |
all_keywords.append(word)
|
| 37 |
keyword_to_intent[word] = intent
|
| 38 |
|
| 39 |
-
# Ищем наиболее похожие слова в вводе
|
| 40 |
-
found_intents = set()
|
| 41 |
for token in clean.split():
|
| 42 |
-
# Находим ближайшие совпадения (точность 70%)
|
| 43 |
matches = get_close_matches(token, all_keywords, n=1, cutoff=0.6)
|
| 44 |
if matches:
|
| 45 |
intent = keyword_to_intent[matches[0]]
|
| 46 |
-
|
| 47 |
|
| 48 |
-
|
| 49 |
-
if "пока" in found_intents:
|
| 50 |
-
return "пока"
|
| 51 |
-
# Иначе — возвращаем первое найденное
|
| 52 |
-
return found_intents.pop() if found_intents else None
|
| 53 |
|
| 54 |
def main():
|
| 55 |
-
print("Newton
|
| 56 |
-
print("
|
| 57 |
|
| 58 |
while True:
|
| 59 |
try:
|
| 60 |
-
user_input =
|
| 61 |
if not user_input:
|
| 62 |
continue
|
| 63 |
|
| 64 |
-
|
| 65 |
-
if any(word in user_input.lower() for word in ["пока", "выход", "quit", "стоп"]):
|
| 66 |
-
print("Newton micro: До свидания! 😊")
|
| 67 |
-
break
|
| 68 |
-
|
| 69 |
-
intent = find_intent(user_input)
|
| 70 |
-
if intent and intent in PATTERNS:
|
| 71 |
-
response = random.choice(PATTERNS[intent])
|
| 72 |
-
else:
|
| 73 |
-
response = random.choice(PATTERNS["default"])
|
| 74 |
-
|
| 75 |
print(f"Newton Micro: {response}\n")
|
| 76 |
|
|
|
|
|
|
|
|
|
|
| 77 |
except KeyboardInterrupt:
|
| 78 |
print("\nNewton Micro: Пока! Береги себя! ✨")
|
| 79 |
break
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
if __name__ == "__main__":
|
| 82 |
main()
|
|
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
+
# Newton Mini — сверхлёгкий ИИ. Теперь умнее!
|
| 3 |
import json
|
| 4 |
import random
|
| 5 |
import re
|
| 6 |
+
import sys
|
| 7 |
from difflib import get_close_matches
|
| 8 |
|
| 9 |
+
def robust_input(prompt):
|
| 10 |
+
try:
|
| 11 |
+
return input(prompt).strip()
|
| 12 |
+
except UnicodeDecodeError:
|
| 13 |
+
pass
|
| 14 |
+
|
| 15 |
+
sys.stdout.flush()
|
| 16 |
+
print(prompt, end='', flush=True)
|
| 17 |
+
try:
|
| 18 |
+
raw = sys.stdin.buffer.readline()
|
| 19 |
+
if not raw:
|
| 20 |
+
return ""
|
| 21 |
+
raw = raw.rstrip(b'\r\n')
|
| 22 |
+
for encoding in ['utf-8', 'cp1251', 'koi8-r', 'iso8859-5']:
|
| 23 |
+
try:
|
| 24 |
+
return raw.decode(encoding).strip()
|
| 25 |
+
except UnicodeDecodeError:
|
| 26 |
+
continue
|
| 27 |
+
return raw.decode('utf-8', errors='replace').strip()
|
| 28 |
+
except Exception:
|
| 29 |
+
return ""
|
| 30 |
+
|
| 31 |
+
try:
|
| 32 |
+
with open("patterns.json", "r", encoding="utf-8") as f:
|
| 33 |
+
PATTERNS = json.load(f)
|
| 34 |
+
except FileNotFoundError:
|
| 35 |
+
print("❌ Ошибка: файл patterns.json не найден!")
|
| 36 |
+
print("Создайте его или скачайте с Hugging Face.")
|
| 37 |
+
sys.exit(1)
|
| 38 |
+
except json.JSONDecodeError:
|
| 39 |
+
print("❌ Ошибка: повреждён файл patterns.json")
|
| 40 |
+
sys.exit(1)
|
| 41 |
|
|
|
|
| 42 |
KEYWORDS = {
|
| 43 |
"привет": ["привет", "здравствуй", "хай", "прив", "здарова"],
|
| 44 |
"как дела": ["дела", "как ты", "ты как", "настроение"],
|
| 45 |
"имя": ["имя", "кто ты", "зовут", "тебя зовут"],
|
| 46 |
"школа": ["школа", "урок", "задача", "домашка", "математика", "геометрия"],
|
| 47 |
+
"пока": ["пока", "выход", "quit", "до свидания", "закончить", "стоп"],
|
| 48 |
+
"knowledge": ["что такое", "как приготовить", "что значит", "расскажи про", "как сделать"]
|
| 49 |
}
|
| 50 |
|
| 51 |
def preprocess(text):
|
| 52 |
+
return re.sub(r'[^а-яё\s]', ' ', text.lower()).strip()
|
|
|
|
| 53 |
|
| 54 |
+
def find_response(user_input):
|
|
|
|
| 55 |
clean = preprocess(user_input)
|
| 56 |
if not clean:
|
| 57 |
+
return random.choice(PATTERNS["default"])
|
| 58 |
+
|
| 59 |
+
if any(word in clean for word in ["пока", "выход", "quit", "стоп", "закончить", "exit"]):
|
| 60 |
+
return random.choice(PATTERNS["пока"])
|
| 61 |
+
|
| 62 |
+
knowledge = PATTERNS.get("knowledge", {})
|
| 63 |
+
if clean in knowledge:
|
| 64 |
+
return knowledge[clean]
|
| 65 |
+
|
| 66 |
+
if knowledge:
|
| 67 |
+
matches = get_close_matches(clean, knowledge.keys(), n=1, cutoff=0.6)
|
| 68 |
+
if matches:
|
| 69 |
+
return knowledge[matches[0]]
|
| 70 |
|
|
|
|
| 71 |
all_keywords = []
|
| 72 |
keyword_to_intent = {}
|
| 73 |
for intent, words in KEYWORDS.items():
|
| 74 |
+
if intent == "knowledge":
|
| 75 |
+
continue
|
| 76 |
for word in words:
|
| 77 |
all_keywords.append(word)
|
| 78 |
keyword_to_intent[word] = intent
|
| 79 |
|
|
|
|
|
|
|
| 80 |
for token in clean.split():
|
|
|
|
| 81 |
matches = get_close_matches(token, all_keywords, n=1, cutoff=0.6)
|
| 82 |
if matches:
|
| 83 |
intent = keyword_to_intent[matches[0]]
|
| 84 |
+
return random.choice(PATTERNS[intent])
|
| 85 |
|
| 86 |
+
return random.choice(PATTERNS["default"])
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
|
| 88 |
def main():
|
| 89 |
+
print("Newton Micro — сверхлёгкий ИИ")
|
| 90 |
+
print("Поддерживает: опечатки, рецепты, определения, выход по 'пока'")
|
| 91 |
|
| 92 |
while True:
|
| 93 |
try:
|
| 94 |
+
user_input = robust_input("Ты: ")
|
| 95 |
if not user_input:
|
| 96 |
continue
|
| 97 |
|
| 98 |
+
response = find_response(user_input)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
print(f"Newton Micro: {response}\n")
|
| 100 |
|
| 101 |
+
if any(w in user_input.lower() for w in ["пока", "выход", "quit", "стоп"]):
|
| 102 |
+
break
|
| 103 |
+
|
| 104 |
except KeyboardInterrupt:
|
| 105 |
print("\nNewton Micro: Пока! Береги себя! ✨")
|
| 106 |
break
|
| 107 |
+
except EOFError:
|
| 108 |
+
print("\nNewton Micro: До свидания!")
|
| 109 |
+
break
|
| 110 |
|
| 111 |
if __name__ == "__main__":
|
| 112 |
main()
|