|
import re |
|
import gradio as gr |
|
import os |
|
import pandas as pd |
|
import time |
|
from langchain.schema import SystemMessage |
|
from langchain_community.chat_models.gigachat import GigaChat |
|
from openpyxl import load_workbook |
|
import plotly.graph_objects as go |
|
import random |
|
import pymorphy2 |
|
import string |
|
|
|
morph = pymorphy2.MorphAnalyzer() |
|
|
|
|
|
gc_key = os.getenv('GC_KEY') |
|
chat_pro = GigaChat(credentials=gc_key, model='GigaChat-Pro', max_tokens=68, temperature=1, verify_ssl_certs=False) |
|
|
|
|
|
try: |
|
data = pd.read_excel('Признаки.xlsx', sheet_name=None) |
|
except Exception as e: |
|
print(f"Ошибка при загрузке Excel-файла: {e}") |
|
data = {} |
|
|
|
|
|
features = {} |
|
for sheet_name, df in data.items(): |
|
try: |
|
if sheet_name == "Пол Поколение Психотип": |
|
features[sheet_name] = df.set_index(['Пол', 'Поколение', 'Психотип'])['Инструкция'].to_dict() |
|
else: |
|
features[sheet_name] = df.set_index(df.columns[0]).to_dict()[df.columns[1]] |
|
except Exception as e: |
|
print(f"Ошибка при обработке данных листа {sheet_name}: {e}") |
|
features[sheet_name] = {} |
|
|
|
|
|
def create_gauge(value): |
|
fig = go.Figure(go.Indicator( |
|
mode="gauge+number", |
|
value=value, |
|
gauge={ |
|
'axis': {'range': [0, 100]}, |
|
'bar': {'color': "black"}, |
|
'steps': [ |
|
{'range': [0, 40], 'color': "#55efc4"}, |
|
{'range': [40, 70], 'color': "#ffeaa7"}, |
|
{'range': [70, 100], 'color': "#ff7675"} |
|
], |
|
'threshold': { |
|
'line': {'color': "black", 'width': 4}, |
|
'thickness': 0.75, |
|
'value': value |
|
} |
|
}, |
|
number={'font': {'size': 48}} |
|
)) |
|
fig.update_layout(paper_bgcolor="#f8f9fa", font={'color': "#2d3436", 'family': "Arial"}, width=250, height=150) |
|
return fig |
|
|
|
|
|
def generate_random_gauges(): |
|
return create_gauge(random.randint(60, 90)), create_gauge(random.randint(60, 90)), create_gauge(random.randint(60, 90)) |
|
|
|
|
|
def change_tab(id): |
|
return gr.Tabs(selected=id) |
|
|
|
|
|
def add_prefix_suffix(prompt, prefix, suffix): |
|
return f"{prefix}\n{prompt}\n{suffix}" |
|
|
|
|
|
def clean_message(message): |
|
if not message.endswith(('.', '!', '?')): |
|
last_period = max(message.rfind('.'), message.rfind('!'), message.rfind('?')) |
|
if last_period != -1: |
|
message = message[:last_period + 1] |
|
return message |
|
|
|
|
|
def generate_message_gigachat_pro(prompt): |
|
try: |
|
messages = [SystemMessage(content=prompt)] |
|
res = chat_pro(messages) |
|
cleaned_message = clean_message(res.content.strip()) |
|
return cleaned_message |
|
except Exception as e: |
|
return f"Ошибка при обращении к GigaChat-Pro: {e}" |
|
|
|
|
|
def generate_message_gigachat_pro_with_retry(prompt): |
|
for _ in range(10): |
|
message = generate_message_gigachat_pro(prompt) |
|
if len(message) <= 250: |
|
return message |
|
return message |
|
|
|
|
|
def generate_standard_prompt(description, advantages, key_message, *selected_values): |
|
prompt = ( |
|
f"Сгенерируй смс-сообщение для клиента.\n" |
|
f"Описание предложения: {description}\n" |
|
f"Преимущества: {advantages}\n" |
|
"В тексте смс запрещено использование:\n" |
|
"- Запрещенные слова: № один, номер один, № 1, вкусный, дешёвый, продукт, спам, доступный, банкротство, долги, займ, срочно, сейчас, лучший, главный, номер 1, гарантия, успех, лидер;\n" |
|
"- Обращение к клиенту;\n" |
|
"- Приветствие клиента;\n" |
|
"- Обещания и гарантии;\n" |
|
"- Использовать составные конструкции из двух глаголов;\n" |
|
"- Причастия и причастные обороты;\n" |
|
"- Деепричастия и деепричастные обороты;\n" |
|
"- Превосходная степень прилагательных;\n" |
|
"- Страдательный залог;\n" |
|
"- Порядковые числительные от 10 прописью;\n" |
|
"- Цепочки с придаточными предложениями;\n" |
|
"- Разделительные повторяющиеся союзы;\n" |
|
"- Вводные конструкции;\n" |
|
"- Усилители;\n" |
|
"- Паразиты времени;\n" |
|
"- Несколько существительных подряд, в том числе отглагольных;\n" |
|
"- Производные предлоги;\n" |
|
"- Сложные предложения, в которых нет связи между частями;\n" |
|
"- Сложноподчинённые предложения;\n" |
|
"- Даты прописью;\n" |
|
"- Близкие по смыслу однородные члены предложения;\n" |
|
"- Шокирующие, экстравагантные, кликбейтные фразы;\n" |
|
"- Абстрактные заявления без поддержки фактами и отсутствие доказательства пользы для клиента;\n" |
|
"- Гарантирующие фразы;\n" |
|
"- Узкоспециализированные термины;\n" |
|
"- Фразы, способные создать двойственное ощущение, обидеть;\n" |
|
"- Речевые клише, рекламные штампы, канцеляризмы;\n" |
|
"Убедись, что в готовом тексте до 250 знаков с пробелами.\n" |
|
) |
|
if key_message.strip(): |
|
prompt += f"Убедись, что в готовом тексте есть следующая ключевая информация: {key_message.strip()}" |
|
|
|
return prompt |
|
|
|
|
|
def generate_personalization_prompt(key_message, *selected_values): |
|
prompt = "Адаптируй, не превышая длину сообщения в 250 знаков с пробелами, текст с учетом следующих особенностей:\n" |
|
gender, generation, psychotype = selected_values[0], selected_values[1], selected_values[2] |
|
combined_instruction = "" |
|
additional_instructions = "" |
|
|
|
print(f"Выбранные значения: Пол={gender}, Поколение={generation}, Психотип={psychotype}") |
|
|
|
|
|
if gender and generation and psychotype: |
|
|
|
sheet = features.get("Пол Поколение Психотип", {}) |
|
|
|
|
|
key = (gender, generation, psychotype) |
|
if key in sheet: |
|
combined_instruction = sheet[key] |
|
print(f"Найдена комбинированная инструкция: {combined_instruction}") |
|
else: |
|
print(f"Комбинированная инструкция для ключа {key} не найдена.") |
|
|
|
|
|
if not combined_instruction: |
|
print("Добавляем индивидуальные инструкции для Пол, Поколение, Психотип.") |
|
for i, feature in enumerate(["Пол", "Поколение", "Психотип"]): |
|
if selected_values[i]: |
|
try: |
|
instruction = features[feature][selected_values[i]] |
|
additional_instructions += f"{instruction}\n" |
|
print(f"Добавлена инструкция из {feature}: {instruction}") |
|
except KeyError: |
|
return f"Ошибка: выбранное значение {selected_values[i]} не найдено в данных." |
|
|
|
|
|
for i, feature in enumerate(features.keys()): |
|
if feature not in ["Пол", "Поколение", "Психотип", "Пол Поколение Психотип"]: |
|
if i < len(selected_values) and selected_values[i]: |
|
try: |
|
instruction = features[feature][selected_values[i]] |
|
additional_instructions += f"{instruction}\n" |
|
print(f"Добавлена инструкция из {feature}: {instruction}") |
|
except KeyError: |
|
return f"Ошибка: выбранное значение {selected_values[i]} не найдено в данных." |
|
|
|
|
|
if combined_instruction: |
|
prompt += combined_instruction |
|
if additional_instructions: |
|
prompt += additional_instructions |
|
|
|
prompt += "Убедись, что в готовом тексте до 250 знаков с пробелами.\n" |
|
|
|
prompt += f"Убедись, что в готовом тексте есть следующая ключевая информация: {key_message.strip()}" |
|
|
|
if "призыва к действию" in prompt and "минимум прямых призывов к действию" in prompt: |
|
prompt = re.sub(r"Убедись, что готовый текст начинается с призыва к действию с продуктом.\n", "", prompt) |
|
|
|
return prompt.strip() |
|
|
|
|
|
|
|
def generate_all_messages(desc, benefits, key_message, gender, generation, psychotype, business_stage, industry, opf): |
|
|
|
standard_prompt = generate_standard_prompt(desc, benefits, key_message) |
|
yield standard_prompt, None, None, None, None, None, None, None |
|
|
|
|
|
time.sleep(1) |
|
|
|
|
|
personalization_prompt = generate_personalization_prompt(key_message, gender, generation, psychotype, business_stage, industry, opf) |
|
yield standard_prompt, personalization_prompt, None, None, None, None, None, None |
|
|
|
|
|
time.sleep(1) |
|
|
|
|
|
prefixes = [ |
|
"Начни сообщение с призыва к действию с продуктом.", |
|
"Начни сообщение с указания на пользу продукта. Используй глагол в побудительном наклонении.", |
|
"Начни сообщение с вопроса, который указывает на пользу продукта для клиента." |
|
] |
|
suffixes = [ |
|
"Убедись, что готовый текст начинается с призыва к действию с продуктом.", |
|
"Убедись, что готовый текст начинается с указания на пользу продукта и использования глагола в побудительном наклонении.", |
|
"Убедись, что готовый текст начинается с вопроса, который указывает на пользу продукта для клиента." |
|
] |
|
|
|
non_personalized_messages = [] |
|
personalized_messages = [] |
|
|
|
|
|
for i in range(3): |
|
|
|
prompt = add_prefix_suffix(standard_prompt, prefixes[i], suffixes[i]) |
|
non_personalized_message = generate_message_gigachat_pro_with_retry(prompt) |
|
non_personalized_length = len(non_personalized_message) |
|
non_personalized_display = f"{non_personalized_message}\n------\nКоличество знаков: {non_personalized_length}" |
|
non_personalized_messages.append(non_personalized_display) |
|
|
|
|
|
yield ( |
|
standard_prompt, personalization_prompt, |
|
non_personalized_messages[0] if i >= 0 else None, |
|
personalized_messages[0] if len(personalized_messages) > 0 else None, |
|
non_personalized_messages[1] if i >= 1 else None, |
|
personalized_messages[1] if len(personalized_messages) > 1 else None, |
|
non_personalized_messages[2] if i >= 2 else None, |
|
personalized_messages[2] if len(personalized_messages) > 2 else None |
|
) |
|
|
|
|
|
full_personalized_prompt = f"{personalization_prompt}\n\nТекст для адаптации: {non_personalized_message}" |
|
personalized_message = generate_message_gigachat_pro_with_retry(full_personalized_prompt) |
|
personalized_length = len(personalized_message) |
|
personalized_display = f"{personalized_message}\n------\nКоличество знаков: {personalized_length}" |
|
personalized_messages.append(personalized_display) |
|
|
|
|
|
yield ( |
|
standard_prompt, personalization_prompt, |
|
non_personalized_messages[0] if len(non_personalized_messages) > 0 else None, |
|
personalized_messages[0] if len(personalized_messages) > 0 else None, |
|
non_personalized_messages[1] if len(non_personalized_messages) > 1 else None, |
|
personalized_messages[1] if len(personalized_messages) > 1 else None, |
|
non_personalized_messages[2] if len(non_personalized_messages) > 2 else None, |
|
personalized_messages[2] if len(personalized_messages) > 2 else None |
|
) |
|
|
|
|
|
time.sleep(1) |
|
|
|
|
|
|
|
|
|
|
|
def check_forbidden_words(message): |
|
morph = pymorphy2.MorphAnalyzer() |
|
|
|
|
|
forbidden_patterns = [ |
|
r'№\s?1\b', r'номер\sодин\b', r'номер\s1\b', |
|
r'вкусный', r'дешёвый', r'продукт', |
|
r'спам', r'доступный', r'банкротство', r'долг[и]?', r'займ', |
|
r'срочный', r'сейчас', r'главный', |
|
r'гарантия', r'успех', r'лидер' |
|
] |
|
|
|
|
|
message_without_punctuation = message.translate(str.maketrans('', '', string.punctuation)) |
|
|
|
|
|
if re.search(r'лучш', message_without_punctuation, re.IGNORECASE): |
|
return False |
|
|
|
|
|
words = message_without_punctuation.split() |
|
lemmas = [morph.parse(word)[0].normal_form for word in words] |
|
normalized_message = ' '.join(lemmas) |
|
|
|
|
|
for pattern in forbidden_patterns: |
|
if re.search(pattern, normalized_message, re.IGNORECASE): |
|
return False |
|
|
|
return True |
|
|
|
|
|
|
|
|
|
def check_no_greeting(message): |
|
morph = pymorphy2.MorphAnalyzer() |
|
|
|
greeting_patterns = [ |
|
r"привет\b", r"здравствуй", r"добрый\s(день|вечер|утро)", |
|
r"дорогой\b", r"уважаемый\b", r"дорогая\b", r"уважаемая\b", |
|
r"господин\b", r"госпожа\b", r"друг\b", r"коллега\b", |
|
r"товарищ\b", r"приятель\b", r"друг\b", r"подруга\b" |
|
] |
|
|
|
|
|
greeting_regex = re.compile('|'.join(greeting_patterns), re.IGNORECASE) |
|
|
|
|
|
if greeting_regex.search(message.strip()): |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_promises(message): |
|
morph = pymorphy2.MorphAnalyzer() |
|
promise_patterns = [ |
|
"обещать", "гарантировать", "обязаться" |
|
] |
|
|
|
words = message.split() |
|
lemmas = [morph.parse(word)[0].normal_form for word in words] |
|
|
|
for pattern in promise_patterns: |
|
if pattern in lemmas: |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_double_verbs(message): |
|
morph = pymorphy2.MorphAnalyzer() |
|
|
|
words = re.split(r'\s+|[.!?]', message) |
|
morphs = [morph.parse(word)[0] for word in words] |
|
|
|
for i in range(len(morphs) - 1): |
|
|
|
if (morphs[i].tag.POS in {'VERB', 'INFN'}) and (morphs[i+1].tag.POS in {'VERB', 'INFN'}): |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_participles(message): |
|
morph = pymorphy2.MorphAnalyzer() |
|
words = message.split() |
|
morphs = [morph.parse(word)[0] for word in words] |
|
|
|
for morph in morphs: |
|
if 'PRTF' in morph.tag: |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_adverbial_participles(message): |
|
morph = pymorphy2.MorphAnalyzer() |
|
words = message.split() |
|
morphs = [morph.parse(word)[0] for word in words] |
|
|
|
for morph in morphs: |
|
if 'GRND' in morph.tag: |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_superlative_adjectives(message): |
|
morph = pymorphy2.MorphAnalyzer() |
|
words = message.split() |
|
morphs = [morph.parse(word)[0] for word in words] |
|
|
|
for morph in morphs: |
|
if 'COMP' in morph.tag or 'Supr' in morph.tag: |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_passive_voice(message): |
|
morph = pymorphy2.MorphAnalyzer() |
|
words = message.split() |
|
morphs = [morph.parse(word)[0] for word in words] |
|
|
|
for morph in morphs: |
|
if 'PRTF' in morph.tag and ('passive' in morph.tag or 'в' in morph.tag): |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_written_out_ordinals(message): |
|
morph = pymorphy2.MorphAnalyzer() |
|
ordinal_words = [ |
|
"десятый", "одиннадцатый", "двенадцатый", "тринадцатый", "четырнадцатый", "пятнадцатый", |
|
"шестнадцатый", "семнадцатый", "восемнадцатый", "девятнадцатый", "двадцатый" |
|
] |
|
|
|
words = message.split() |
|
lemmas = [morph.parse(word)[0].normal_form for word in words] |
|
|
|
for word in ordinal_words: |
|
if word in lemmas: |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_subordinate_clauses_chain(message): |
|
|
|
subordinate_clause_patterns = [ |
|
r'\b(который|которая|которое|которые)\b', |
|
r'\b(если|потому что|так как|что|когда)\b', |
|
r'\b(хотя|несмотря на то что)\b' |
|
] |
|
|
|
count = 0 |
|
for pattern in subordinate_clause_patterns: |
|
if re.search(pattern, message): |
|
count += 1 |
|
|
|
|
|
return count < 2 |
|
|
|
|
|
|
|
def check_no_repeating_conjunctions(message): |
|
|
|
repeating_conjunctions_patterns = r'\b(и|ни|то|не то|или|либо)\b\s*(.*?)\s*,\s*\b\1\b' |
|
|
|
|
|
sentences = re.split(r'[.!?]\s*', message) |
|
|
|
|
|
for sentence in sentences: |
|
if re.search(repeating_conjunctions_patterns, sentence, re.IGNORECASE): |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_introductory_phrases(message): |
|
introductory_phrases = [ |
|
r'\b(во-первых|во-вторых|с одной стороны|по сути|по правде говоря)\b', |
|
r'\b(может быть|кстати|конечно|естественно|безусловно|возможно)\b' |
|
] |
|
|
|
for pattern in introductory_phrases: |
|
if re.search(pattern, message, re.IGNORECASE): |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_amplifiers(message): |
|
amplifiers = [ |
|
r'\b(очень|крайне|чрезвычайно|совсем|абсолютно|полностью|чисто)\b' |
|
] |
|
|
|
for pattern in amplifiers: |
|
if re.search(pattern, message, re.IGNORECASE): |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_time_parasites(message): |
|
time_parasites = [ |
|
r'\b(сейчас|немедленно|срочно|в данный момент|теперь)\b' |
|
] |
|
|
|
for pattern in time_parasites: |
|
if re.search(pattern, message, re.IGNORECASE): |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_multiple_nouns(message): |
|
noun_count = 0 |
|
words = re.split(r'\s+|[.!?]', message) |
|
morph = pymorphy2.MorphAnalyzer() |
|
|
|
for word in words: |
|
parsed_word = morph.parse(word)[0] |
|
|
|
|
|
if 'NOUN' in parsed_word.tag: |
|
noun_count += 1 |
|
|
|
elif re.match(r'[.!?]', word): |
|
noun_count = 0 |
|
else: |
|
noun_count = 0 |
|
|
|
if noun_count > 2: |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_derived_prepositions(message): |
|
derived_prepositions = [ |
|
r'\b(в течение|в ходе|вследствие|в связи с|по мере|при помощи|согласно|вопреки|на основании|на случай|в продолжение|по причине|вблизи|вдалеке|вокруг|внутри|вдоль|посередине|вне|снаружи|благодаря|невзирая на|исходя из)\b' |
|
] |
|
|
|
for pattern in derived_prepositions: |
|
if re.search(pattern, message, re.IGNORECASE): |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_compound_sentences(message): |
|
subordinating_conjunctions = [ |
|
r'\bкогда\b', r'\bкак только\b', r'\bпока\b', r'\bпосле того как\b', |
|
r'\bпотому что\b', r'\bтак как\b', r'\bоттого что\b', r'\bблагодаря тому что\b', |
|
r'\bчтобы\b', r'\bдля того чтобы\b', r'\bесли\b', r'\bкогда бы\b', r'\bесли бы\b', |
|
r'\bхотя\b', r'\bнесмотря на то что\b', r'\bкак\b', r'\bбудто\b', r'\bсловно\b', r'\bкак будто\b', |
|
r'\bчто\b' |
|
] |
|
|
|
|
|
for pattern in subordinating_conjunctions: |
|
if re.search(pattern, message) and not re.search(r'\?', message): |
|
return False |
|
return True |
|
|
|
|
|
|
|
def check_no_dates_written_out(message): |
|
|
|
months = [ |
|
"января", "февраля", "марта", "апреля", "мая", "июня", |
|
"июля", "августа", "сентября", "октября", "ноября", "декабря" |
|
] |
|
|
|
|
|
date_written_out_patterns = [ |
|
r'\b(первого|второго|третьего|четвертого|пятого|шестого|седьмого|восьмого|девятого|десятого|одиннадцатого|двенадцатого|тринадцатого|четырнадцатого|пятнадцатого|шестнадцатого|семнадцатого|восемнадцатого|девятнадцатого|двадцатого|двадцать первого|двадцать второго|двадцать третьего|двадцать четвертого|двадцать пятого|двадцать шестого|двадцать седьмого|двадцать восьмого|двадцать девятого|тридцатого|тридцать первого)\b' |
|
] |
|
|
|
for month in months: |
|
for pattern in date_written_out_patterns: |
|
if re.search(f'{pattern}\\s{month}', message, re.IGNORECASE): |
|
return False |
|
|
|
return True |
|
|
|
|
|
|
|
def perform_checks(message): |
|
checks = { |
|
"forbidden_words": check_forbidden_words(message), |
|
"client_addressing": check_no_greeting(message), |
|
"promises": check_no_promises(message), |
|
"double_verbs": check_no_double_verbs(message), |
|
"participles": check_no_participles(message), |
|
"adverbial_participles": check_no_adverbial_participles(message), |
|
"superlative_adjectives": check_no_superlative_adjectives(message), |
|
"passive_voice": check_no_passive_voice(message), |
|
"written_out_ordinals": check_no_written_out_ordinals(message), |
|
"subordinate_clauses_chain": check_no_subordinate_clauses_chain(message), |
|
"repeating_conjunctions": check_no_repeating_conjunctions(message), |
|
"introductory_phrases": check_no_introductory_phrases(message), |
|
"amplifiers": check_no_amplifiers(message), |
|
"time_parasites": check_no_time_parasites(message), |
|
"multiple_nouns": check_no_multiple_nouns(message), |
|
"derived_prepositions": check_no_derived_prepositions(message), |
|
"compound_sentences": check_no_compound_sentences(message), |
|
"dates_written_out": check_no_dates_written_out(message) |
|
} |
|
return checks |
|
|
|
|
|
def format_checks(checks): |
|
translation = { |
|
"forbidden_words": "Запрещенные слова", |
|
"client_addressing": "Обращение к клиенту", |
|
"promises": "Обещания и гарантии", |
|
"double_verbs": "Два глагола подряд", |
|
"participles": "Причастия", |
|
"adverbial_participles": "Деепричастия", |
|
"superlative_adjectives": "Превосходная степень", |
|
"passive_voice": "Страдательный залог", |
|
"written_out_ordinals": "Порядковые числительные", |
|
"subordinate_clauses_chain": "Цепочки с придаточными предложениями", |
|
"repeating_conjunctions": "Разделительные повторяющиеся союзы", |
|
"introductory_phrases": "Вводные конструкции", |
|
"amplifiers": "Усилители", |
|
"time_parasites": "Паразиты времени", |
|
"multiple_nouns": "Несколько существительных подряд", |
|
"derived_prepositions": "Производные предлоги", |
|
"compound_sentences": "Сложноподчиненные предложения", |
|
"dates_written_out": "Даты прописью" |
|
} |
|
return " \n".join([f"{translation[rule]}: {'✔️' if result else '❌'}" for rule, result in checks.items()]) |
|
|
|
|
|
|
|
def perform_all_checks_and_show_results(personalized_message_1, personalized_message_2, personalized_message_3): |
|
|
|
checks_1 = perform_checks(personalized_message_1) |
|
checks_2 = perform_checks(personalized_message_2) |
|
checks_3 = perform_checks(personalized_message_3) |
|
|
|
|
|
formatted_checks_1 = format_checks(checks_1) |
|
formatted_checks_2 = format_checks(checks_2) |
|
formatted_checks_3 = format_checks(checks_3) |
|
|
|
|
|
return ( |
|
personalized_message_1, formatted_checks_1, |
|
personalized_message_2, formatted_checks_2, |
|
personalized_message_3, formatted_checks_3 |
|
) |
|
|
|
|
|
|
|
with gr.Blocks() as demo: |
|
|
|
|
|
with gr.Tabs() as tabs: |
|
|
|
|
|
with gr.TabItem("Исходные данные", id=0): |
|
with gr.Row(): |
|
with gr.Column(): |
|
desc = gr.Textbox( |
|
label="Описание предложения (предзаполненный пример можно поменять на свой)", |
|
lines=7, |
|
value=( |
|
"Необходимо предложить клиенту оформить дебетовую премиальную бизнес-карту Mastercard Preffered. " |
|
"Обслуживание карты стоит 700 рублей в месяц, но клиент может пользоваться ей бесплатно. " |
|
"Что необходимо сделать, чтобы воспользоваться предложением:\n" |
|
"1. Оформить премиальную бизнес-карту в офисе банка или онлайн в интернет-банке СберБизнес.\n" |
|
"2. Забрать карту.\n" |
|
"3. В течение календарного месяца совершить по ней покупки на сумму от 100 000 рублей.\n" |
|
"4. В течение следующего месяца пользоваться ей бесплатно." |
|
) |
|
) |
|
benefits = gr.Textbox( |
|
label="Преимущества (предзаполненный пример можно поменять на свой)", |
|
lines=5, |
|
value=( |
|
"Предложение по бесплатному обслуживанию — бессрочное.\n" |
|
"Оплата покупок без отчётов и платёжных поручений.\n" |
|
"Платёжные документы без комиссии.\n" |
|
"Лимиты на расходы сотрудников.\n" |
|
"Мгновенные переводы на карты любых банков." |
|
) |
|
) |
|
|
|
key_message = gr.Textbox( |
|
label="Ключевое сообщение (предзаполненный пример можно поменять на свой)", |
|
lines=3, |
|
value="Бесплатное обслуживание при покупках от 100 000 рублей в месяц." |
|
) |
|
|
|
with gr.Column(): |
|
gender = gr.Dropdown(label="Пол", choices=[None] + list(features.get('Пол', {}).keys())) |
|
generation = gr.Dropdown(label="Поколение", choices=[None] + list(features.get('Поколение', {}).keys())) |
|
psychotype = gr.Dropdown(label="Психотип", choices=[None] + list(features.get('Психотип', {}).keys())) |
|
business_stage = gr.Dropdown(label="Стадия бизнеса", choices=[None] + list(features.get('Стадия бизнеса', {}).keys())) |
|
industry = gr.Dropdown(label="Отрасль", choices=[None] + list(features.get('Отрасль', {}).keys())) |
|
opf = gr.Dropdown(label="ОПФ", choices=[None] + list(features.get('ОПФ', {}).keys())) |
|
btn_to_prompts = gr.Button("Создать") |
|
|
|
|
|
with gr.TabItem("Ассистент", id=1): |
|
with gr.Row(): |
|
with gr.Column(): |
|
non_personalized_prompt = gr.Textbox( |
|
label="Задание для копирайтера", |
|
lines=25, |
|
interactive=False) |
|
with gr.Column(): |
|
personalized_prompt = gr.Textbox(label="Задание для редактора", lines=25) |
|
|
|
|
|
with gr.TabItem("Сообщения", id=2): |
|
with gr.Row(): |
|
gr.Markdown("### Копирайтер") |
|
gr.Markdown("### Редактор") |
|
|
|
with gr.Row(): |
|
non_personalized_1 = gr.Textbox(label="Стандартное сообщение 1", lines=4, interactive=False) |
|
personalized_1 = gr.Textbox(label="Персонализированное сообщение 1", lines=4, interactive=False) |
|
|
|
with gr.Row(): |
|
non_personalized_2 = gr.Textbox(label="Стандартное сообщение 2", lines=4, interactive=False) |
|
personalized_2 = gr.Textbox(label="Персонализированное сообщение 2", lines=4, interactive=False) |
|
|
|
with gr.Row(): |
|
non_personalized_3 = gr.Textbox(label="Стандартное сообщение 3", lines=4, interactive=False) |
|
personalized_3 = gr.Textbox(label="Персонализированное сообщение 3", lines=4, interactive=False) |
|
|
|
|
|
with gr.Row(): |
|
btn_check = gr.Button("Проверить", elem_id="check3") |
|
btn_check.click(fn=change_tab, inputs=[gr.Number(value=3, visible=False)], outputs=tabs) |
|
|
|
|
|
btn_to_prompts.click( |
|
fn=change_tab, |
|
inputs=[gr.Number(value=1, visible=False)], |
|
outputs=tabs |
|
).then( |
|
fn=generate_all_messages, |
|
inputs=[desc, benefits, key_message, gender, generation, psychotype, business_stage, industry, opf], |
|
outputs=[ |
|
non_personalized_prompt, personalized_prompt, |
|
non_personalized_1, personalized_1, |
|
non_personalized_2, personalized_2, |
|
non_personalized_3, personalized_3 |
|
] |
|
) |
|
|
|
|
|
with gr.TabItem("Проверка", id=3): |
|
with gr.Row(): |
|
gr.Markdown("### Редактор") |
|
gr.Markdown("### Корректор") |
|
gr.Markdown("### Аналитик") |
|
|
|
with gr.Row(): |
|
personalized_message_1 = gr.Textbox(label="Персонализированное сообщение 1", lines=5, interactive=False) |
|
check_message_1 = gr.Textbox(label="Проверка сообщения 1", lines=5, interactive=False) |
|
with gr.Column(): |
|
gr.HTML("<div style='display:flex; justify-content:center; width:100%;'>") |
|
success_forecast_1 = gr.Plot(label="Прогноз успешности сообщения 1") |
|
gr.HTML("</div>") |
|
|
|
with gr.Row(): |
|
personalized_message_2 = gr.Textbox(label="Персонализированное сообщение 2", lines=5) |
|
check_message_2 = gr.Textbox(label="Проверка сообщения 2", lines=5, interactive=False) |
|
with gr.Column(): |
|
gr.HTML("<div style='display:flex; justify-content:center; width:100%;'>") |
|
success_forecast_2 = gr.Plot(label="Прогноз успешности сообщения 2") |
|
gr.HTML("</div>") |
|
|
|
with gr.Row(): |
|
personalized_message_3 = gr.Textbox(label="Персонализированное сообщение 3", lines=5, interactive=False) |
|
check_message_3 = gr.Textbox(label="Проверка сообщения 3", lines=5, interactive=False) |
|
with gr.Column(): |
|
gr.HTML("<div style='display:flex; justify-content:center; width:100%;'>") |
|
success_forecast_3 = gr.Plot(label="Прогноз успешности сообщения 3") |
|
gr.HTML("</div>") |
|
|
|
|
|
btn_check.click( |
|
fn=change_tab, |
|
inputs=[gr.Number(value=3, visible=False)], |
|
outputs=tabs |
|
).then( |
|
fn=perform_all_checks_and_show_results, |
|
inputs=[personalized_1, personalized_2, personalized_3], |
|
outputs=[ |
|
personalized_message_1, check_message_1, |
|
personalized_message_2, check_message_2, |
|
personalized_message_3, check_message_3 |
|
] |
|
).then( |
|
fn=generate_random_gauges, |
|
inputs=[], |
|
outputs=[success_forecast_1, success_forecast_2, success_forecast_3] |
|
) |
|
|
|
demo.launch() |