-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3ab7f37
Showing
15 changed files
with
662 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import os | ||
import json | ||
from dotenv import load_dotenv | ||
from loguru import logger | ||
from yandex_cloud_ml_sdk import YCloudML | ||
|
||
# Загрузка переменных окружения из файла .env | ||
load_dotenv() | ||
|
||
# Получение идентификаторов папки и API ключа из переменных окружения | ||
FOLDER_ID = os.getenv('YC_FOLDER_ID') | ||
API_KEY = os.getenv('YC_API_KEY') | ||
|
||
# Инициализация SDK Yandex Cloud с использованием полученных идентификаторов | ||
sdk = YCloudML(folder_id=FOLDER_ID, auth=API_KEY) | ||
|
||
def create_assistant(): | ||
"""Создает ассистента с заданными параметрами.""" | ||
# Открываем файл index_id.json для получения идентификатора индекса | ||
with open('index_id.json', 'r') as file: | ||
data = json.load(file) | ||
index_id = data.get('index_id') # Извлекаем index_id из данных | ||
|
||
# Получаем индекс поиска по его идентификатору | ||
search_index = sdk.search_indexes.get(index_id) | ||
# Создаем инструмент поиска с максимальным количеством результатов 5 | ||
search_tool = sdk.tools.search_index(search_index, max_num_results=5) | ||
|
||
# Создаем ассистента с заданными параметрами | ||
return sdk.assistants.create( | ||
name="foo-assistant", # Имя ассистента | ||
model='yandexgpt', # Модель, которую будет использовать ассистент | ||
temperature=0.1, # Параметр, определяющий креативность ответов | ||
instruction="Вы ассистируете пользователю в Telegram. Отвечайте на вопросы, которые он задает. Игнорируйте контекст, если считаете его нерелевантным.", # Инструкция для ассистента | ||
tools=[search_tool], # Инструменты, которые будет использовать ассистент | ||
ttl_days=30, # Время жизни ассистента в днях | ||
expiration_policy="SINCE_LAST_ACTIVE" # Политика истечения | ||
) | ||
|
||
# Создаем ассистента и сохраняем его в переменной | ||
assistant = create_assistant() | ||
|
||
async def ai_assistant(message: str, thread_id: str): | ||
"""Отправляет сообщение в указанный поток и получает ответ ассистента.""" | ||
# Получаем поток по его идентификатору | ||
thread = sdk.threads.get(thread_id) | ||
# Записываем сообщение в поток | ||
thread.write(message) | ||
|
||
# Запускаем ассистента и ждем ответа | ||
response = assistant.run(thread.id).wait() | ||
return response.message.parts[0] # Возвращаем первый элемент ответа | ||
|
||
async def ai_assistant_new_thread(chat_id: str) -> str: | ||
"""Создает новый поток для чата.""" | ||
# Создаем новый поток с заданным именем и временем жизни 7 дней | ||
thread = sdk.threads.create( | ||
name=f'thread-{chat_id}', # Имя потока, основанное на идентификаторе чата | ||
ttl_days=7, # Время жизни потока в днях | ||
expiration_policy="SINCE_LAST_ACTIVE" # Политика истечения | ||
) | ||
return thread.id # Возвращаем идентификатор нового потока |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import os | ||
import json | ||
from dotenv import load_dotenv | ||
from loguru import logger | ||
from yandex_cloud_ml_sdk import YCloudML | ||
from yandex_cloud_ml_sdk.search_indexes import VectorSearchIndexType, StaticIndexChunkingStrategy | ||
|
||
# Загрузка переменных окружения | ||
load_dotenv() | ||
|
||
# Получение идентификатора папки и API ключа из переменных окружения | ||
FOLDER_ID = os.getenv("YC_FOLDER_ID") | ||
YANDEX_API_KEY = os.getenv("YC_API_KEY") | ||
DATA_DIR = os.getenv("DATA_DIR") | ||
|
||
# Инициализация SDK с авторизацией | ||
sdk = YCloudML(folder_id=FOLDER_ID, auth=YANDEX_API_KEY) | ||
|
||
# Путь к директории с данными | ||
data_directory = f"knowledge/{DATA_DIR}" | ||
|
||
# Список для хранения ссылок на загруженные файлы | ||
uploaded_files = [] | ||
|
||
# Загрузка всех файлов из директории данных | ||
for filename in os.listdir(data_directory): | ||
file_path = os.path.join(data_directory, filename) | ||
if os.path.isfile(file_path): | ||
uploaded_file = sdk.files.upload( | ||
file_path, | ||
name=filename, | ||
description=f"Данные базы знаний из {data_directory}", | ||
ttl_days=30, | ||
expiration_policy="SINCE_LAST_ACTIVE" | ||
) | ||
uploaded_files.append(uploaded_file) | ||
|
||
# Создание типа векторного поискового индекса | ||
index_type = VectorSearchIndexType( | ||
chunking_strategy=StaticIndexChunkingStrategy( | ||
max_chunk_size_tokens=1000, | ||
chunk_overlap_tokens=200 | ||
), | ||
doc_embedder_uri=f"emb://{FOLDER_ID}/text-search-doc/rc", | ||
query_embedder_uri=f"emb://{FOLDER_ID}/text-search-query/rc" | ||
) | ||
|
||
# Создание поискового индекса с загруженными файлами | ||
operation = sdk.search_indexes.create_deferred( | ||
files=uploaded_files, | ||
index_type=index_type, | ||
name="rag_search_index", | ||
description=f"Данные базы знаний из {data_directory}", | ||
ttl_days=30, | ||
expiration_policy="SINCE_LAST_ACTIVE" | ||
) | ||
|
||
# Ожидание завершения создания поискового индекса | ||
index = operation.wait() | ||
|
||
# Сохранение идентификатора индекса в JSON файл | ||
index_id = {"index_id": index.id} | ||
with open("index_id.json", "w") as json_file: | ||
json.dump(index_id, json_file, indent=4) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import os | ||
import requests | ||
import dotenv | ||
from loguru import logger | ||
from yandex_cloud_ml_sdk import YCloudML | ||
|
||
# Загрузка переменных окружения | ||
dotenv.load_dotenv() | ||
|
||
# Получение идентификаторов папки и API ключа | ||
FOLDER_ID = os.getenv('YC_FOLDER_ID') | ||
API_KEY = os.getenv('YC_API_KEY') | ||
|
||
# URL для генеративного поиска | ||
SEARCH_API_GENERATIVE = f"https://ya.ru/search/xml/generative?folderid={FOLDER_ID}" | ||
SERP_SITE = os.getenv('SERP_SITE', None) | ||
SERP_HOST = os.getenv('SERP_HOST', None) | ||
SERP_URL = os.getenv('SERP_URL', None) | ||
|
||
# Инициализация SDK Yandex Cloud | ||
sdk = YCloudML(folder_id=FOLDER_ID, auth=API_KEY) | ||
|
||
def process_response(response): | ||
"""Обрабатывает ответ от API и возвращает комбинированный контент.""" | ||
content = "" | ||
sources = [] | ||
|
||
# Проверяем тип контента в ответе | ||
if "application/json" in response.headers.get("Content-Type", ""): | ||
content = response.json().get("message", {}).get("content", "") | ||
sources = response.json().get("links", []) | ||
logger.info(content) | ||
for i, link in enumerate(sources, start=1): | ||
logger.info(f"[{i}]: {link}") | ||
elif "text/xml" in response.headers.get("Content-Type", ""): | ||
logger.error(f"Ошибка: {response.text}") | ||
else: | ||
logger.error(f"Неожиданный тип контента: {response.text}") | ||
|
||
# Формируем комбинированный контент для ответа | ||
combined_content = f"Ответ SearchAPI:\n{content}\n\nИсточники:\n" + "\n".join(sources) | ||
return combined_content | ||
|
||
async def search_api_generative_contextual(message: str, thread_id: str): | ||
"""Выполняет генеративный поиск с учетом контекста треда.""" | ||
# Получаем сообщения из треда | ||
thread_messages = sdk.threads.get(thread_id).read() | ||
messages = [{"content": item.parts[0], "role": item.role} for item in thread_messages] | ||
|
||
# Добавляем новое сообщение от пользователя | ||
messages.append({"content": message, "role": "user"}) | ||
|
||
headers = {"Authorization": f"Api-Key {API_KEY}"} | ||
data = { | ||
"messages": messages, | ||
"site": SERP_SITE, | ||
"host": SERP_HOST, | ||
"url": SERP_URL | ||
} | ||
|
||
# Отправляем запрос к API | ||
response = requests.post(SEARCH_API_GENERATIVE, headers=headers, json=data) | ||
combined_content = process_response(response) | ||
|
||
# Записываем сообщения в тред | ||
thread = sdk.threads.get(thread_id) | ||
thread.write(message) | ||
thread.write(combined_content, labels={"role": "assistant"}) | ||
return combined_content | ||
|
||
async def search_api_generative(message: str): | ||
"""Выполняет генеративный поиск без контекста треда.""" | ||
headers = {"Authorization": f"Api-Key {API_KEY}"} | ||
data = { | ||
"messages": [{"content": message, "role": "user"}], | ||
"site": SERP_SITE, | ||
"host": SERP_HOST, | ||
"url": SERP_URL | ||
} | ||
|
||
# Отправляем запрос к API | ||
response = requests.post(SEARCH_API_GENERATIVE, headers=headers, json=data) | ||
combined_content = process_response(response) | ||
|
||
return combined_content |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import httpx | ||
|
||
async def send_post_request(name): | ||
url = f"https://functions.yandexcloud.net/d4ekuoccv9lmm79dh5rr?name={name}" | ||
async with httpx.AsyncClient() as client: | ||
response = await client.get(url) | ||
print(f"Status Code: {response.status_code}") | ||
print(f"Response Content: {response.text}") | ||
|
||
if __name__ == "__main__": | ||
import asyncio | ||
name = "Master" | ||
asyncio.run(send_post_request(name)) |
Binary file not shown.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import sqlite3 | ||
|
||
# Создаем соединение с базой данных | ||
conn = sqlite3.connect('data/example.db') | ||
cursor = conn.cursor() | ||
|
||
# Создаем таблицу products | ||
cursor.execute(''' | ||
CREATE TABLE IF NOT EXISTS products ( | ||
productId TEXT PRIMARY KEY, | ||
name TEXT NOT NULL, | ||
category TEXT NOT NULL, | ||
price REAL NOT NULL, | ||
num_of_orders INTEGER NOT NULL, | ||
rating REAL NOT NULL | ||
) | ||
''') | ||
|
||
# Заполняем таблицу 5 товарами категории электроника | ||
products = [ | ||
('1', 'Смартфон XYZ', 'электроника', 19999.99, 150, 4.5), | ||
('2', 'Ноутбук ABC', 'электроника', 59999.99, 75, 4.7), | ||
('3', 'Наушники DEF', 'электроника', 2999.99, 200, 4.2), | ||
('4', 'Телевизор GHI', 'электроника', 49999.99, 50, 4.6), | ||
('5', 'Планшет JKL', 'электроника', 24999.99, 100, 4.3), | ||
('6', 'Арбуз', 'ягоды', 100, 5000000, 5), | ||
] | ||
|
||
cursor.executemany(''' | ||
INSERT INTO products (productId, name, category, price, num_of_orders, rating) | ||
VALUES (?, ?, ?, ?, ?, ?) | ||
''', products) | ||
|
||
# Сохраняем изменения и закрываем соединение | ||
conn.commit() | ||
conn.close() |
Oops, something went wrong.