Spaces:
Sleeping
Sleeping
import os | |
import gradio as gr | |
import pandas as pd | |
from langchain.schema import SystemMessage | |
from langchain_community.chat_models.gigachat import GigaChat | |
from openpyxl import load_workbook | |
# Авторизация в GigaChat Pro | |
gc_key = os.getenv('GPT_KEY') | |
chat_pro = GigaChat(credentials=gc_key, model='GigaChat-Pro', max_tokens=68, temperature=1, verify_ssl_certs=False) | |
# Загрузка данных из Excel-файла | |
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 add_prefix_suffix(prompt, prefix, suffix): | |
return f"{prefix}\n{prompt}\n{suffix}" | |
# Функция для генерации стандартного промпта | |
def generate_standard_prompt(description, advantages, key_message): | |
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.strip() | |
# Функция для генерации персонализированного промпта | |
def generate_personalization_prompt(key_message, gender, generation, psychotype, business_stage, industry, opf): | |
prompt = "Адаптируй, не превышая длину сообщения в 250 знаков с пробелами, текст с учетом следующих особенностей:\n" | |
combined_instruction = "" | |
additional_instructions = "" | |
if gender and generation and psychotype: | |
key = (gender, generation, psychotype) | |
combined_instruction = features.get("Пол Поколение Психотип", {}).get(key, "") | |
if not combined_instruction: | |
additional_instructions += f"{features.get('Пол', {}).get(gender, '')}\n" | |
additional_instructions += f"{features.get('Поколение', {}).get(generation, '')}\n" | |
additional_instructions += f"{features.get('Психотип', {}).get(psychotype, '')}\n" | |
additional_instructions += f"{features.get('Стадия бизнеса', {}).get(business_stage, '')}\n" | |
additional_instructions += f"{features.get('Отрасль', {}).get(industry, '')}\n" | |
additional_instructions += f"{features.get('ОПФ', {}).get(opf, '')}\n" | |
prompt += combined_instruction if combined_instruction else additional_instructions | |
prompt += f"Убедись, что в готовом тексте есть следующая ключевая информация: {key_message.strip()}" | |
return prompt.strip() | |
# Функция для генерации сообщения с GigaChat Pro | |
def generate_message_gigachat_pro(prompt): | |
try: | |
messages = [SystemMessage(content=prompt)] | |
res = chat_pro(messages) | |
return res.content.strip() | |
except Exception as e: | |
return f"Ошибка при обращении к GigaChat-Pro: {e}" | |
# Функция для повторной генерации сообщения, пока оно не станет короче 250 знаков | |
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 handle_generation(desc, benefits, key_message, gender, generation, psychotype, business_stage, industry, opf): | |
# Генерация стандартного промпта | |
standard_prompt = generate_standard_prompt(desc, benefits, key_message) | |
# Генерация персонализированного промпта | |
personalization_prompt = generate_personalization_prompt(key_message, gender, generation, psychotype, business_stage, industry, opf) | |
return standard_prompt, personalization_prompt | |
# Функция для генерации всех сообщений | |
def generate_all_messages(non_personalized_prompt, personalized_prompt): | |
# Варианты предложений для начала и конца | |
prefixes = [ | |
"Начни сообщение с призыва к действию с продуктом.", | |
"Начни сообщение с указания на пользу продукта. Используй глагол в побудительном наклонении.", | |
"Начни сообщение с вопроса, который указывает на пользу продукта для клиента." | |
] | |
suffixes = [ | |
"Убедись, что готовый текст начинается с призыва к действию с продуктом.", | |
"Убедись, что готовый текст начинается с указания на пользу продукта и использования глагола в побудительном наклонении.", | |
"Убедись, что готовый текст начинается с вопроса, который указывает на пользу продукта для клиента." | |
] | |
non_personalized_messages = [] | |
personalized_messages = [] | |
# Генерация трех неперсонализированных сообщений | |
for i in range(3): | |
prompt = add_prefix_suffix(non_personalized_prompt, prefixes[i], suffixes[i]) | |
message = generate_message_gigachat_pro_with_retry(prompt) | |
non_personalized_messages.append(message) | |
# Генерация трех персонализированных сообщений | |
for i in range(3): | |
full_personalized_prompt = f"{personalized_prompt}\n\nТекст для адаптации: {non_personalized_messages[i]}" | |
prompt = add_prefix_suffix(full_personalized_prompt, prefixes[i], suffixes[i]) | |
message = generate_message_gigachat_pro_with_retry(prompt) | |
personalized_messages.append(message) | |
return non_personalized_messages, personalized_messages | |
# Интерфейс Gradio | |
with gr.Blocks() as demo: | |
with gr.Tabs() as tabs: | |
# Вкладка 1: Исходные данные | |
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())) | |
non_personalized_prompt = gr.Textbox(label="Задание для копирайтера", lines=25, interactive=False) | |
personalized_prompt = gr.Textbox(label="Задание для редактора", lines=25) | |
btn_generate_prompts = gr.Button("Создать") | |
# Привязка кнопки к функции генерации промптов | |
btn_generate_prompts.click( | |
fn=handle_generation, | |
inputs=[desc, benefits, key_message, gender, generation, psychotype, business_stage, industry, opf], | |
outputs=[non_personalized_prompt, personalized_prompt] | |
) | |
# Вкладка 2: Промпты | |
with gr.TabItem("Ассистент", id=1): | |
with gr.Row(): | |
with gr.Column(): | |
gr.Markdown("Промпт для копирайтера:") | |
non_personalized_prompt # Здесь не нужно вызывать render(), просто добавьте блок | |
with gr.Column(): | |
gr.Markdown("Промпт для редактора:") | |
personalized_prompt # Аналогично, не вызывайте render() | |
# Вкладка 3: Сообщения | |
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) | |
# Привязка кнопки для генерации сообщений | |
btn_generate_messages = gr.Button("Генерировать сообщения") | |
btn_generate_messages.click( | |
fn=generate_all_messages, | |
inputs=[non_personalized_prompt, personalized_prompt], | |
outputs=[non_personalized_1, personalized_1, non_personalized_2, personalized_2, non_personalized_3, personalized_3] | |
) | |
demo.launch() |