mirror of
https://gitflic.ru/project/maks1ms/ocab.git
synced 2024-12-23 16:23:01 +03:00
Реализован модуль YandexGPT первой версии. Реализованы методы: генерация ответа с помощью YandexGPT и YandexGPT-lite, перевод текста с помощью YandexGPT, проверка орфографии и пунктуации с помощью YandexGPT, краткий пересказ истории чата с помощью Yandex Text Summarization Model.
This commit is contained in:
parent
dee4f5bc79
commit
6f1efa6b7b
@ -1,5 +1,11 @@
|
||||
TELEGRAM:
|
||||
TOKEN: xxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
YANDEXGPT:
|
||||
TOKEN: xxxxxxxxxxxxxxxxxxxx
|
||||
CATALOGID: xxxxxxxxxxxxxxxxxxxx
|
||||
PROMPT: Тестовый пример промпта
|
||||
|
||||
ROLES:
|
||||
ADMIN: 0
|
||||
MODERATOR: 1
|
||||
|
224
src/modules/external/yandexgpt/yandexgpt.py
vendored
Normal file
224
src/modules/external/yandexgpt/yandexgpt.py
vendored
Normal file
@ -0,0 +1,224 @@
|
||||
import requests
|
||||
import json
|
||||
import asyncio
|
||||
import aiohttp
|
||||
|
||||
from ...standard.database import *
|
||||
from ...standard.config.config import *
|
||||
|
||||
|
||||
class YandexGPT:
|
||||
self.token = None
|
||||
self.catalog_id = None
|
||||
self.language = {
|
||||
"ru": "русский язык",
|
||||
"en": "английский язык",
|
||||
"de": "немецкий язык",
|
||||
"uk": "украинский язык",
|
||||
"es": "испанский язык",
|
||||
"be": "белорусский язык",
|
||||
}
|
||||
|
||||
def __init__(self, token, catalog_id):
|
||||
self.token = token
|
||||
self.catalog_id = catalog_id
|
||||
|
||||
async def async_token_check(self, messages, gpt, max_tokens, del_msg_id=1):
|
||||
url = "https://llm.api.cloud.yandex.net/foundationModels/v1/tokenize"
|
||||
while True:
|
||||
text = ""
|
||||
for message in messages:
|
||||
text += message["text"]
|
||||
try:
|
||||
response = requests.post(url, json={"model": gpt, "text": text})
|
||||
except Exception as e: # TODO: Переделать обработку ошибок
|
||||
print(e)
|
||||
continue
|
||||
if int(response.text) < max_tokens - 2000:
|
||||
break
|
||||
else:
|
||||
messages.pop(del_msg_id)
|
||||
return messages
|
||||
|
||||
async def async_request(*, url, headers, prompt) -> dict:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, headers=headers, json=prompt) as response:
|
||||
return await response.json()
|
||||
|
||||
async def async_yandexgpt_lite(self, system_prompt, input_messages, stream=False, temperature=0.6, max_tokens=8000):
|
||||
url = "https://llm.api.cloud.yandex.net/foundationModels/v1/completion"
|
||||
gpt = f"gpt://{self.catalog_id}/yandexgpt-lite/latest"
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Api-Key {self.token}"
|
||||
}
|
||||
|
||||
messages = [{"role": "system", "text": system_prompt}]
|
||||
for message in input_messages:
|
||||
messages.append(message)
|
||||
messages = await self.async_token_check(messages, gpt, max_tokens)
|
||||
|
||||
prompt = {
|
||||
"modelUri": gpt,
|
||||
"completionOptions": {
|
||||
"stream": stream,
|
||||
"temperature": temperature,
|
||||
"maxTokens": max_tokens
|
||||
},
|
||||
"messages": messages
|
||||
}
|
||||
|
||||
response = requests.post(url, headers=headers, json=prompt).text
|
||||
return json.loads(response)["result"]["alternatives"][0]["message"]["text"]
|
||||
|
||||
async def async_yandexgpt(self, system_prompt, input_messages, stream=False, temperature=0.6, max_tokens=8000):
|
||||
url = "https://llm.api.cloud.yandex.net/foundationModels/v1/completion"
|
||||
gpt = f"gpt://{self.catalog_id}/yandexgpt/latest"
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Api-Key {self.token}"
|
||||
}
|
||||
|
||||
messages = [{"role": "system", "text": system_prompt}]
|
||||
for message in input_messages:
|
||||
messages.append(message)
|
||||
messages = await self.async_token_check(messages, gpt, max_tokens)
|
||||
|
||||
prompt = {
|
||||
"modelUri": gpt,
|
||||
"completionOptions": {
|
||||
"stream": stream,
|
||||
"temperature": temperature,
|
||||
"maxTokens": max_tokens
|
||||
},
|
||||
"messages": messages
|
||||
}
|
||||
|
||||
response = requests.post(url, headers=headers, json=prompt).text
|
||||
return json.loads(response)["result"]["alternatives"][0]["message"]["text"]
|
||||
|
||||
async def async_yandexgpt_translate(self, input_language, output_language, text):
|
||||
input_language = self.languages[input_language]
|
||||
output_language = self.languages[output_language]
|
||||
|
||||
return await self.async_yandexgpt(
|
||||
f"Переведи на {output_language} сохранив оригинальный смысл текста. Верни только результат:",
|
||||
[{"role": "user", "text": text}],
|
||||
stream=False, temperature=0.6, max_tokens=8000
|
||||
)
|
||||
|
||||
async def async_yandexgpt_spelling_check(self, input_language, text):
|
||||
input_language = self.languages[input_language]
|
||||
|
||||
return await self.async_yandexgpt(
|
||||
f"Проверьте орфографию и пунктуацию текста на {input_language}. Верни исправленный текст "
|
||||
f"без смысловых искажений:",
|
||||
[{"role": "user", "text": text}],
|
||||
stream=False, temperature=0.6, max_tokens=8000
|
||||
)
|
||||
|
||||
async def async_yandexgpt_text_history(self, messages, stream=False, temperature=0.6, max_tokens=8000):
|
||||
url = "https://llm.api.cloud.yandex.net/foundationModels/v1/completion"
|
||||
gpt = f"gpt://{self.catalog_id}/summarization/latest"
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Api-Key {self.token}"
|
||||
}
|
||||
|
||||
messages = []
|
||||
for message in input_messages:
|
||||
messages.append(message)
|
||||
messages = await self.async_token_check(messages, gpt, max_tokens, del_msg_id=0)
|
||||
|
||||
prompt = {
|
||||
"modelUri": gpt,
|
||||
"completionOptions": {
|
||||
"stream": stream,
|
||||
"temperature": temperature,
|
||||
"maxTokens": max_tokens
|
||||
},
|
||||
"messages": messages
|
||||
}
|
||||
|
||||
response = requests.post(url, headers=headers, json=prompt).text
|
||||
return json.loads(response)["result"]["alternatives"][0]["message"]["text"]
|
||||
|
||||
async def async_yandex_cloud_text_to_speech(self, text, voice, emotion, speed, format, quality):
|
||||
tts = "tts.api.cloud.yandex.net/speech/v1/tts:synthesize"
|
||||
# TODO: Сделать функцию TTS
|
||||
return 0
|
||||
|
||||
async def async_yandex_cloud_vision(self, image, features, language):
|
||||
# TODO: Сделать функцию Vision
|
||||
return 0
|
||||
|
||||
async def collect_messages(self, message_id, chat_id):
|
||||
messages = []
|
||||
# Собираем цепочку сообщений в формате: [{"role": "user", "text": "<Имя_пользователя>: Привет!"},
|
||||
# {"role": "assistant", "text": "Привет!"}]
|
||||
while True:
|
||||
message = get_message_text(chat_id, message_id)
|
||||
if get_message_ai_model(chat_id, start_message_id) != None:
|
||||
messages.append({"role": "assistant", "text": message})
|
||||
else:
|
||||
sender_name = get_user_name(get_message_sender_id(chat_id, start_message_id))
|
||||
messages.append({"role": "user", "text": sender_name + ": " + message})
|
||||
message_id = get_message_answer_to_message_id(chat_id, message_id)
|
||||
if message_id is None:
|
||||
break
|
||||
return messages.reverse()
|
||||
|
||||
async def collecting_messages_for_history(self, start_message_id, end_message_id, chat_id):
|
||||
messages = []
|
||||
# Собираем цепочку сообщений в формате: [{"role": "user", "text": "<Имя_пользователя>: Привет!"},
|
||||
# {"role": "assistant", "text": "Привет!"}]
|
||||
while True:
|
||||
message = get_message_text(chat_id, start_message_id)
|
||||
if get_message_ai_model(chat_id, start_message_id) != None:
|
||||
messages.append({"role": "assistant", "text": message})
|
||||
else:
|
||||
sender_name = get_user_name(get_message_sender_id(chat_id, start_message_id))
|
||||
messages.append({"role": "user", "text": sender_name + ": " + message})
|
||||
start_message_id -= 1
|
||||
if start_message_id <= end_message_id:
|
||||
break
|
||||
return messages.reverse()
|
||||
|
||||
async def yandexgpt_request(self, message_id = None, type = "yandexgpt-lite", chat_id = None,
|
||||
message_id_end = None):
|
||||
if type == "yandexgpt-lite":
|
||||
messages = await self.collect_messages(message_id, chat_id)
|
||||
return await self.async_yandexgpt_lite(
|
||||
system_prompt=get_yandexgpt_prompt(),
|
||||
input_messages=messages,
|
||||
stream=False, temperature=0.6, max_tokens=8000
|
||||
)
|
||||
elif type == "yandexgpt":
|
||||
messages = await self.collect_messages(message_id, chat_id)
|
||||
return await self.async_yandexgpt(
|
||||
system_prompt=get_yandexgpt_prompt(),
|
||||
input_messages=messages,
|
||||
stream=False, temperature=0.6, max_tokens=8000
|
||||
)
|
||||
elif type == "yandexgpt-translate":
|
||||
return await self.async_yandexgpt_translate(
|
||||
input_language=get_message_language(chat_id, message_id),
|
||||
output_language=get_chat_language(chat_id),
|
||||
text=get_message_text(chat_id, message_id)
|
||||
)
|
||||
elif type == "yandexgpt-spelling-check":
|
||||
return await self.async_yandexgpt_spelling_check(
|
||||
input_language=get_message_language(chat_id, message_id),
|
||||
text=get_message_text(chat_id, message_id)
|
||||
)
|
||||
elif type == "yandexgpt-text-history":
|
||||
messages = await self.collect_messages_for_history(message_id, message_id_end, chat_id)
|
||||
return await self.async_yandexgpt_text_history(
|
||||
messages=messages,
|
||||
stream=False, temperature=0.6, max_tokens=8000
|
||||
)
|
||||
else:
|
||||
return "Ошибка: Неизвестный тип запроса | Error: Unknown request type"
|
||||
|
||||
|
||||
|
@ -16,4 +16,10 @@ def get_config(is_test: bool = False) -> dict:
|
||||
def get_yandexgpt_token() -> str:
|
||||
return get_config()["YANDEX_GPT_TOKEN"]
|
||||
|
||||
def get_yandexgpt_catalog_id() -> str:
|
||||
return get_config()["YANDEX_GPT_CATALOG_ID"]
|
||||
|
||||
def get_yandexgpt_prompt() -> str:
|
||||
return get_config()["YANDEX_GPT_PROMPT"]
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user