LlamaIndex: создаем чат-бота с помощью ретривера BM25Retriever. Часть 3
Rasa — это платформа машинного обучения с открытым исходным кодом для автоматизации текстовых и голосовых разговоров. Создать контекстных помощников и чат-ботов, которые помогут клиентам, сложно.
Rasa предоставляет инфраструктуру и инструменты, необходимые для работы высокопроизводительных, устойчивых и запатентованных контекстных помощников.
С Rasa все разработчики могут создавать лучшие текстовые и голосовые помощники.
Rasa Open Source включает
- NLU: определяет, чего хочет пользователь, и фиксирует ключевую контекстную информацию.
- Core: выбирает следующий лучший ответ или действие на основе истории разговоров.
- Каналы и интеграции: подключите помощника к пользователям и бэкэнд-системам
Rasa X — это набор инструментов, который поможет вам использовать разговоры для улучшения вашего помощника.
Теперь перейдем к кодированию
Что ж, если вы ничего не знаете о кодировании, вы все равно можете это сделать. Иметь терпение!!
Шаг 1. Создайте и активируйте виртуальную среду
Перед установкой Rasa настоятельно рекомендуется использовать виртуальную среду, чтобы все установки были чистыми и находились в одном месте.
cd
sudo apt-get install python3-venv
python3 -m venv env
source env/bin/activate
Шаг 2. Установите Rasa
Если у вас возникают ошибки TensorFlow, используйте их для установки надстроек.
pip install —upgrade pip
pip3 install —upgrade tensorflow-addons rasa
Чтобы установить Rasa, используйте эти команды. Я использовал rasa версии 1.5.0.
pip install rasa
pip install rasa_nlu
pip install rasa_nlu[spacy]
python -m spacy download en_core_web_md
python -m spacy link en_core_web_md en –force
Это займет некоторое время. Убедитесь, что нет ошибок зависимостей.
rasa init
Через 100 эпох вы получите запрос «Вы хотите поговорить с обученным помощником из командной строки?». Пожалуйста, выберите «Нет».
← После инициализации структура каталогов должна выглядеть так.
Шаг 4. Настройте свою модель
Чтобы настроить модель, вам необходимо изменить эти файлы. nlu.md stories.md domain.yml
- credentials.yml
- Чтобы изменить файлы, вам необходимо знать эти условия.
- Намерения: что говорит пользователь. Rasa использует концепцию намерений, чтобы описать, как следует классифицировать сообщения пользователей.
- Response: Как бот отвечает на запрос. Если вы хотите, чтобы ваш бот отвечал на сообщения пользователей, вам необходимо управлять ответами бота.
- История: это представление разговора между пользователем и помощником AI, преобразованное в определенный формат, в котором вводимые пользователем данные выражаются как соответствующие намерения, а ответы помощника выражаются как соответствующие названия действий.
nlu.md
В файле nlu.md сохраняем интенты. Раса использует эту концепцию, чтобы описать, как пользователь будет взаимодействовать с ботом. Вы должны упомянуть различные способы вызвать конкретное намерение. Например, «привет», «привет» и т. Д. — все это вызовет намерение приветствия.
domain.yml
В domain.yml мы сохраняем ответы и действия (в исходной модели действий нет). Раса использует эту концепцию, чтобы описать, как бот будет реагировать на пользователя.
Stories.md
Наконец, в Stories.md мы опишем ход разговора. Необязательно перечислять все возможные пути. Раса выберет наиболее подходящий путь, основываясь на значении уверенности.
credentials.yml
Если вы хотите развернуть бота в различных приложениях, таких как мессенджер и Slack, создайте для этого приложения учетную запись разработчика. Затем сохраните токены в credentials.yml.
Вы также можете изучить другие файлы, такие как config.yml, и изменить их в соответствии с требованиями,
Шаг 5. Обучите новую модель
После всех доработок пора обучить вашу новую модель.
rasa train
Шаг 6. Проверьте своего бота
Поприветствуем нового чат-бота. Теперь вы можете развернуть его в различных приложениях или запустить в своем терминале. Чтобы запустить его на своем терминале Linux,
rasa shell
Пришло время разработать нового чат-бота .. Удачного обучения !!
По любым вопросам обращайтесь ко мне в LinkedIn.
BM25 Retriever
Back to top
In this guide, we define a bm25 retriever that search documents using bm25 method.
This notebook is very similar to the RouterQueryEngine notebook.
# NOTE: This is ONLY necessary in jupyter notebook.
# Details: Jupyter runs an event-loop behind the scenes.
# This results in nested event-loops when we start an event-loop to make async queries.
# This is normally not allowed, we use nest_asyncio to allow it for convenience.
import nest_asyncio nest_asyncio.apply()
import os
import openai os.environ[«OPENAI_API_KEY»] = «sk-…»
openai.api_key = os.environ[«OPENAI_API_KEY»]
import logging
import sys logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().handlers = []
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout)) from llama_index import ( SimpleDirectoryReader, ServiceContext, StorageContext, VectorStoreIndex,
)
from llama_index.retrievers import BM25Retriever
from llama_index.indices.vector_store.retrievers.retriever import VectorIndexRetriever
from llama_index.llms import OpenAI
We first show how to convert a Document into a set of Nodes, and insert into a DocumentStore.
# load documents
documents = SimpleDirectoryReader(«../data/paul_graham»).load_data()
# initialize service context (set chunk size)
llm = OpenAI(model=»gpt-4″)
service_context = ServiceContext.from_defaults(chunk_size=1024, llm=llm)
nodes = service_context.node_parser.get_nodes_from_documents(documents)
# initialize storage context (by default it's in-memory)
storage_context = StorageContext.from_defaults()
storage_context.docstore.add_documents(nodes)
index = VectorStoreIndex( nodes=nodes, storage_context=storage_context, service_context=service_context,
)
We will search document with bm25 retriever.
# We can pass in the index, doctore, or list of nodes to create the retriever
retriever = BM25Retriever.from_defaults(nodes=nodes, similarity_top_k=2)
from llama_index.response.notebook_utils import display_source_node # will retrieve context from specific companies
nodes = retriever.retrieve(«What happened at Viaweb and Interleaf?»)
for node in nodes: display_source_node(node)
Node ID: d95537b4-b398-4b47-94ff-da86f05a27f7Similarity: 5.171801938898801Text: I wanted to go back to RISD, but I was now broke and RISD was very expensive, so I decided to get…
Node ID: 6f84e2a5-1ab1-4389-8799-b7713e085931Similarity: 4.838241203957084Text: All you had to do was teach SHRDLU more words.
There weren’t any classes in AI at Cornell then, …
nodes = retriever.retrieve(«What did Paul Graham do after RISD?»)
for node in nodes: display_source_node(node)
Node ID: a4fd0b29-4138-4741-9e27-9f65d6968eb4Similarity: 8.090884087344435Text: Not so much because it was badly written as because the problem is so convoluted. When you’re wor…
Node ID: d95537b4-b398-4b47-94ff-da86f05a27f7Similarity: 5.830874349482576Text: I wanted to go back to RISD, but I was now broke and RISD was very expensive, so I decided to get…
Now we will combine bm25 retriever with vector index retriever.
from llama_index.tools import RetrieverTool vector_retriever = VectorIndexRetriever(index)
bm25_retriever = BM25Retriever.from_defaults(nodes=nodes, similarity_top_k=2) retriever_tools = [ RetrieverTool.from_defaults( retriever=vector_retriever, description=»Useful in most cases», ), RetrieverTool.from_defaults( retriever=bm25_retriever, description=»Useful if searching about specific information», ),
]
from llama_index.retrievers import RouterRetriever retriever = RouterRetriever.from_defaults( retriever_tools=retriever_tools, service_context=service_context, select_multi=True,
)
# will retrieve all context from the author's life
nodes = retriever.retrieve( «Can you give me all the context regarding the author's life?»
)
for node in nodes: display_source_node(node)
Selecting retriever 0: The author's life context is a broad topic, which may require a comprehensive approach that is useful in most cases..
Node ID: fcd399c1-3544-4df3-80a9-0a7d3fd41f1fSimilarity: 0.7942753162501964Text: [10]
Wow, I thought, there’s an audience. If I write something and put it on the web, anyone can…
Node ID: b203e140-d549-4284-99f4-b1b5bcd996eaSimilarity: 0.7788031317604815Text: Now all I had to do was learn Italian.
Only stranieri (foreigners) had to take this entrance exa…
Here we extend the base retriever class and create a custom retriever that always uses the vector retriever and BM25 retreiver.
Then, nodes can be re-ranked and filtered. This lets us keep intermediate top-k values large and letting the re-ranking filter out un-needed nodes.
To best demonstrate this, we will use a larger set of source documents – Chapter 3 from the 2022 IPCC Climate Report.
!curl https://www.ipcc.ch/report/ar6/wg2/downloads/report/IPCC_AR6_WGII_Chapter03.pdf —output IPCC_AR6_WGII_Chapter03.pdf
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 20.7M 100 20.7M 0 0 361k 0 0:00:58 0:00:58 —:—:— 422k
from llama_index import ( VectorStoreIndex, ServiceContext, StorageContext, SimpleDirectoryReader,
)
from llama_index.llms import OpenAI # load documents
documents = SimpleDirectoryReader( input_files=[«IPCC_AR6_WGII_Chapter03.pdf»]
).load_data() # initialize service context (set chunk size)
# — here, we set a smaller chunk size, to allow for more effective re-ranking
llm = OpenAI(model=»gpt-3.5-turbo»)
service_context = ServiceContext.from_defaults(chunk_size=256, llm=llm)
nodes = service_context.node_parser.get_nodes_from_documents(documents) # initialize storage context (by default it's in-memory)
storage_context = StorageContext.from_defaults()
storage_context.docstore.add_documents(nodes)
index = VectorStoreIndex( nodes, storage_context=storage_context, service_context=service_context
)
from llama_index.retrievers import BM25Retriever # retireve the top 10 most similar nodes using embeddings
vector_retriever = index.as_retriever(similarity_top_k=10) # retireve the top 10 most similar nodes using bm25
bm25_retriever = BM25Retriever.from_defaults(nodes=nodes, similarity_top_k=10)
from llama_index.retrievers import BaseRetriever class HybridRetriever(BaseRetriever): def __init__(self, vector_retriever, bm25_retriever): self.vector_retriever = vector_retriever self.bm25_retriever = bm25_retriever def _retrieve(self, query, **kwargs): bm25_nodes = self.bm25_retriever.retrieve(query, **kwargs) vector_nodes = self.vector_retriever.retrieve(query, **kwargs) # combine the two lists of nodes all_nodes = [] node_ids = set() for n in bm25_nodes + vector_nodes: if n.node.node_id not in node_ids: all_nodes.append(n) node_ids.add(n.node.node_id) return all_nodes
index.as_retriever(similarity_top_k=5) hybrid_retriever = HybridRetriever(vector_retriever, bm25_retriever)
# !pip install sentence_transformers
from llama_index.indices.postprocessor import SentenceTransformerRerank reranker = SentenceTransformerRerank(top_n=4, model=»BAAI/bge-reranker-base»)
Downloading (…)lve/main/config.json: 100%|██████████| 799/799 [00:00
Трудно быть ботом: как сделать чатбота с помощью DeepPavlov — Системный Блокъ
Сегодня уже мало кому нужно объяснять, что такое чат-боты. Мы неизбежно сталкиваемся с ними, когда хотим открыть вклад в банке, уточнить тариф у мобильного оператора или просто заказать пиццу.
Чат-боты вызывают интерес у бизнеса, ищущего способы сократить расходы на колл-центры и улучшить взаимодействие с клиентами.
Кто-то идет дальше — и создает Алису, способную болтать на разные темы, развлекая вас, когда вам скучно, а значит, повышая вашу лояльность.
Общая архитектура диалоговой системы состоит из четырех компонентов.
Схема общей архитектуры модели (здесь и далее [1])
Для начала нам необходимо получить входящие данные от пользователя. Это может быть текст, напечатанный в диалоговом окне, или речь, которую необходимо распознать и перевести в текстовый формат.
Далее на сцену выходит одна из самых сложных частей нашего чат-бота, призванная обеспечить понимание входного сообщения.
Для простых целеориентированных чат-ботов проблему понимания естественного языка (Natural Language Understanding, NLU) можно свести к следующим задачам: выделение тематики сообщения пользователя, выделение намерения (intent extraction) и распознавание именованных сущностей (Named Entity Recognition, NER).
После анализа информации, полученной от пользователя, происходит принятие решения о том, как нужно выстраивать общение дальше: уточнить недостающие детали, переспросить, поблагодарить и др.
Наконец, на финальном этапе происходит генерация ответа (Natural Language Generation).
В большинстве чат-ботов генерация реализована набором шаблонов, в которые вставляются кастомизированные данные (имя пользователя, заказ и т.д.).
Это делается для того, чтобы максимально исключить возможность генерации потенциально неприятных сообщений (все мы помним случай, как чат-бот советовал клиенту банка «отрезать пальцы»).
Обратимся к самой сложной части нашего чат-бота — пониманию сообщения пользователя. В основе всего лежит т.н. семантический фрейм (semantic frame) — набор знаний о нашем домене (предметной области).
Так, например, если мы создаем чат-бот для ресторанов, нам потребуется собрать онтологию, в которой, помимо специальной лексики, будут содержаться, например, знания о ценовой категории ресторана, типе кухни, адресах и т.д.
После определения тематики (домена) сообщения, необходимо понять, что же человек от нас (то есть от бота) хочет. Если продолжить наш пример о ресторанном чат-боте, то нужно определить, хочет ли пользователь найти ресторан, заказать доставку еды или узнать часы работы заведения. Эта задача называется распознаванием интентов (намерений).
Примеры доменов и интентов
Для каждого интента в семантическом фрейме есть свой шаблон со слотами, которые заполняются информацией, извлеченной из сообщения пользователя. Так, интент «найти_ресторан» может включать слоты «цена», «тип_кухни», «место» и др.
Пример заполнения слотов для интента «найти_ресторан»
Как извлечь информацию для заполнения слотов? Для этого необходимо в достаточно большом корпусе примеров выделить вручную важные для нас слова и фразы, а далее на размеченном корпусе обучить модель машинного обучения выделять необходимые нам факты и сущности автоматически. Такая модель способна извлекать необходимую нам информацию из сообщения пользователя, после чего специальный инструмент относит их к определенному слоту семантического фрейма.
Пример BIO-разметки именованных сущностей и заполнения слотов
После того, как мы постарались извлечь и структурировать всю необходимую нам информацию, наступает этап стратегического планирования: что необходимо сделать чат-боту в ответ на сообщение пользователя?
На концептуальном уровне управление диалогом представляет собой достаточно простую вещь: у нас есть последовательность наблюдений (непосредственно текст сообщения пользователя) и некоторое количество состояний диалоговой системы (история взаимодействия чат-бота и пользователя; по сути — заполненные слоты семантического фрейма). Также в систему управления должен входить определенный набор действий, которые система может предпринять: обратиться с вопросом к пользователю, если какой-то слот оказался незаполненным, сделать запрос к базе данных и т.д.
FAQ чат-бот с помощью библиотеки DeepPavlov
26.11.2020 Дмитрий Симонов, г. Воронеж
Время прочтения: 6 мин.
Страницы часто задаваемых вопросов — это самый распространенный способ для организаций уменьшить нагрузку на службу поддержки пользователей, автоматически отвечая на наиболее часто задаваемые вопросы.
Однако с течением времени количество вопросов может оказаться слишком большим и поиск нужного будет затруднительным для пользователя. В последние годы стали значительно популярны различные чат-боты.
В то время как предыдущее поколение чат-ботов было основано на правилах «если-то», сегодняшние чат-боты используют машинное обучение и искусственный интеллект для имитации диалогов с пользователями на естественном языке.
В данной статье будет показан способ создания модели чат-бота для ответов на часто задаваемые вопросы из готового набора пар «вопрос-ответ» с применением библиотеки DeepPavlov на python.
Создание модели в Deeppavlov
Библиотека DeepPavlov представляет собой открытую программную библиотеку разговорного AI для создания виртуальных диалоговых ассистентов и анализа текста. Библиотека содержит набор натренированных нейросетевых моделей для анализа текста, компонентов диалоговых систем и пайплайнов, а также компонентов для создания и тестирования диалоговых моделей.
Работа с DeepPavlov не требует от разработчика специальных навыков, библиотека бесплатна и дает широкие возможности для тонкой настройки. Построение и обучение модели чат-бота с помощью данной библиотеки представляет собой написание конфигурации пайплайна (конвеера операций) в виде json файла (примеры конфигураций для faq можно найти на github: ссылка.
После чего можно обучить или построить модель с помощью следующих команд:
from deeppavlov import train_model, build_model
from deeppavlov.core.common.file import read_json
model_config = read_json('model_config.json')
model = train_model(model_config) # или build_model(model_config)
После этого, для того чтобы отправить вопрос необходимо вызвать метод _faq c переданным текстом:
answers, probability = model._faq([question])
Модель возвратит наиболее подходящий ответ и массив вероятностей всех ответов.
Теперь поговорим о самой модели чатбота. Задача создания модели машинного обучения для faq чат-бота включает в себя 4 этапа:
- Загрузка набора данных. Нам понадобятся датасет вопрос-ответ, для каждого входящего вопроса пользователя будет произведен поиск ближайшего вопроса из набора и выведен соответствующий ответ.
- Нормализация и предварительная обработка текста. Каждый вопрос должен пройти процедуры нормализации и токенизации.
- Векторизация текста. Полученный на втором этапе массив токенов необходимо векторизировать.
- Модель сравнения векторов. Здесь необходимо для полученного вектора входящего вопроса найти ближайший вектор из датасета вопросов. Можно использовать либо модели классификации либо меры сходства.
Загрузка набора данных в DeepPavlov осуществляется с помощью добавления поля «dataset_reader» в конфигурацию.
На втором этапе необходимо провести:
- удаление всех нерелевантных символов
- токенизация текста
- перевод всех символов в нижний регистр
- удаление стоп-слов
- стемминг или лемматизацию
Данные операции можно осуществить с помощью встроенного класса RussianTokenizer, настроенный для русского языка. Параметры этих операций также можно настроить в файле конфигурации. В результате работы данного компонента вопросы преобразуются в массивы токенов, состоящие из лемм слов.
На третьем этапе нужно осуществить векторизацию текста. В библиотеке доступны два предустановленных способа это сделать. Первый — мешок слов с модификацией Tf-Idf, второй — с помощью word embeddings.
Tf-Idf векторизатор представлен в виде предобученной модели класса TfidfVectorizer из библиотеки sklearn. Данная модель была обучена на 1463888 статьях русской википедии. Альтернативой является модель векторного представления слов.
В данном случае используется библиотека fasttext с предобученной моделью для русского языка. В качестве алгоритма используется метод SkipGram. Эта модель обучена на корпусе текстов, составленном из русской википедии и новостей сайта lenta.ru.
Все вектора данной модели имеют размерность равную 300.
Последним шагом в цепочке процессов является поиск похожего вектора из датасета. Наиболее простым способом является поиск похожего вектора на основе косинусной меры. Другой подход — это использование любой модели классификации, например, многоклассовой логистической регрессии (количество классов равно количеству вопросов в датасете).
Такую модель необходимо либо предварительно обучить и в процессе работы пайплайна использовать уже обученную модель, либо указать в конфигурации пайплайна необходимость обучения в процессе сборки модели. В этом случае можно указать параметры обучения такие как параметр C и метод регуляризации.
За основу этой модели можно взять класс LogisticRegression из библиотеки sklearn.linear_model.
Пример модели
Следует обратить внимание на то, что ответа на вопрос может не содержаться в датасете, поэтому полученный ответ модели необходимо проверять на достоверность. Для этого можно сравнить вероятность самого близкого ответа с константным значением (threshold).
def _check_similarity(arr: list, threshold: float) -> bool:
max_value = max(arr)
if max_value < threshold:
return False
else:
return True
В качестве примера модели можно привести созданную мною модель чат-бота для ответов на вопросы абитуриентов факультета ПММ Воронежского государственного университета. На изображении 1 показана часть исходного датасета. Он состоит из двух столбцов: Question и Answer.
изображение 1
Для более удобной работы с моделью был написан класс-обёртка AmmChatBot. Загрузка модели (изображение 2) занимает некоторое время, происходящие процессы выводятся в логи.
изображение 2
После загрузки модели, использовать её можно через метод ask класса AmmChatBot (изображение 3).
Исходный код класса и модели можно найти по данной ссылке.
Интеграция и использование
Любая модель может быть развернута в виде REST веб-сервиса. В самом простом случае достаточно одного файла конфигурации и указания порта. Запуск сервиса может осуществляться следующей командой:
python -m deeppavlov riseapi -d [-p ]
В библиотеке также доступны возможности интеграции чат-бота с различными платформами, такими как: Telegram, Yandex Alisa, Amazon Alexa и AWS. Например, для интеграции с Telegram достаточно написать всего пару строк кода:
from deeppavlov.utils.telegram import interact_model_by_telegram interact_model_by_telegram(model_config=, token=)
Заключение
Сегодня чат-боты могут эффективно заменять службу поддержки в большинстве случаев. Многие компании используют их для снижения нагрузки на операторов. Например, чат-бот поддержки Ozon, отвечающий на вопросы по доставке и порядку возврата товара или чат-боты мобильных приложений банков СберБанк или Тинькофф, отвечающие на вопросы по комиссиям, условиям использования услуг и т. д.
Также существуют различные чат-бот платформы с возможностью создания диалогов, используя user-frendly интерфейс, однако возникают вопросы с масштабированием, привязкой к платным API-сервисам и поддержкой русского языка. Поэтому использование библиотеки Deeppavlov может быть отличной альтернативой, которое сильно упростит создание FAQ чат-бота для ответа на вопросы на русском языке.
MishaSok/discord_economy_bot_rus: Guide Book по созданию Discord бота с использованием sqlite3
Guide Book по созданию Discord бота с использованием sqlite3
Дата написания данного гайда 05.05.2021 Библиотека discord.py может обновляться, поэтому после крупных патчей разработка бота может отличаться. В любом случае ближайшие несколько месяцев данный гайд будет актуален.
Что нам потребуется?:
- Стабильное интернет соединение
- Знания языка Python на неплохом уровне
- Умение «гуглить» и находить нужную информацию
- Среда для написания кода
- Желательно понимать что такое DataBase и как с ним работать используя библиотеку sqlite3
Я советую для разработки бота создать отдельный сервер в Дискорде, где мы будем проверять нашего бота, потому что почти ни у кого не получается запустить сложный код с первого раза, а спамить другим не очень хочется.
Создание Application'a:
Для начала нам нужно создать Discord Application, для этого мы должны перейти по этой ссылке: https://discord.com/developers/applications. После успешного входа в ваш аккаунт Discord, вам нужно нажать на кнопку New Application и выбрать имя для приложения. ВАЖНО: ИМЯ ДЛЯ САМОГО БОТА ДИСКОРДА МЫ БДЕМ НАСТРАИВАТЬ ПОЗЖЕ.
После создания Application'а мы должны перейти во вкладку Bot, а затем нажать на кнопку Add Bot.
Если у вас появилось зеленая надпись по типу: A wild bot has appeared!, значит вы всё сделали правильно и бот у вас уже создан.
Подключаем нашего бота к серверу:
Для того чтобы подключить бота к вашему серверу Дискорд, нужно следовать простым инструкциям:
-
Нужно получить Client_ID вашего бота. Для этого мы переходим во вкладку General Information и копируем его нажав на кнопку Copy.
-
Копируем эту ссылку ==> https://discordapp.com/oauth2/authorize?&client_id=(тут)&scope=bot&permissions=8
-
В эту ссылку вместо слова «тут» вставляем наш Client_ID. Скобки естественно убираем. Доп. информация: В нашей ссылке bot&permissions=8 означает что наш permissions integer равен 8.
Проще говоря, это число отвечает за то, какие права будут выданы боту при подключении. Этот код можно узнать во вкладке Bot (в которой мы создавали бота).
Пролистав вниз, вы сможете сами выбрать нужные вам права, но я советую оставить 8, так как если вы будете сами выбирать права, могут произойти казусные ситуации при работе с ботом.
-
После создания нашей ссылки мы переходим по ней, выбираем сервер на который хотите пригласить бота и нажимаем кнопку Авторизовать. После прохождения капчи наш бот успешно присоединится к серверу, но будет оффлайн. Не пугайтесь, это нормально, ведь наш бот еще не запущен.
Создание проекта:
Ну вот мы и готовы начать писать код для нашего прекрасного бота. Если вы знаете Python на ОЧЕНЬ низком уровне, я советую воздержаться от создания ботов и заняться чем нибудь более простым.
Для начала я советую создать пустую папку где мы будем хранить все файлы для нашего бота.
Затем если у вас не установлена библиотека discord.py, вам нужно её устновить. Для этого переходим в командную строку и пишем: pip install discord.py
Внимание, для установки библиотек требуется pip, если он у вас не установлен, то гугл в помощь ^_^
После успешной установки библиотеки, переходим в вашу любимую среду разработки, в моём случае это PyCharm. Затем создаем новый файл Python файл с названием «main» (такое название не даст вам запутаться) и расширением .py и сразу сохраняем его в нашей папке с проектом.
Создаем еще один файлик .py названием config, для хранения в нём опасных данных. Почему мы не можем просто создать переменные с этими данными? Всё очень просто. Это самый простой способ защитить себя от злоумышленников. Если кто-то каким-то образом получит ваш код, то не сможет управлять вашим ботом. Все наши токены будут хранится в отдельном файлике.
В файле config.py создаем словарь, к которому мы будем обращаться при работе в ботом:
settings = {
'token': 'Введите ваш токен',
'bot': 'Название вашего бота',
'id': 'id вашего бота (без кавычек)',
'prefix': 'префикс'
}
Подготовка к работе с sqlite3:
Для того чтобы нам работать с sqlite3 мы можем использовать cmd (Командную строку) или же использовать очень удобное приложение которое называется
DB Browser for sqlite3. Установить его можно здесь: https://sqlitebrowser.org/ (Создание таблиц я буду проводить в этой программе)
Переходим в установленный DB Browser и нажимаем на кнопку «Новая база данных». Затем выбираем путь к нашему проекту и указываем название, я поставил «bot_test».
Можно переходить к созданию таблиц для работы. Самая первая таблица будет называться users, в неё мы будем записывать данные и пользователях (никнеймы, id, «упоминания и т.д.»)
Нажимаем на кнопку создать таблицу и указываем в названии «users». Затем записываем в таблицу наши данные, а именно:
- «id» INTEGER,
- «nickname» TEXT,
- «mention» TEXT,
- «money» INTEGER
После всех махинаций наша таблица в режиме пред.осмотра должна выглядеть так:
CREATE TABLE «users» (
«id» INTEGER,
«nickname» TEXT,
«mention» TEXT,
«money» INTEGER
);
Создаем вторую таблицу, которая называется shop (в нем будем хранить данные о товарах):
CREATE TABLE «shop» (
«name» TEXT,
«type» TEXT,
«cost» INTEGER,
«id» INTEGER
);
Ну вот мы и готовы начинать писать код:
Для начала нам нужно импортировать все нужные библиотеки:
import discord
import sqlite3
from discord.ext import commands
from config import *
Написание «тела» для бота и первый запуск:
Я буду стараться объяснять подробно каждый шаг и каждую строчку, потому что на первый взгляд это может показаться сложным, хотя таковым не является.
bot = commands.Bot(command_prefix=settings['prefix'])
Переменная bot — это «тело» нашего бота. Ему мы присваиваем значение commands.Bot с определёнными аргументами.
command_prefix=settings['prefix'] — это аргумент, в который мы вписываем значение нашего префикса. settings['prefix'] означает, кто мы обращаемся к словарю settings (который мы импортировали из файла config.py) и обращаемся к ключу prefix, в котором вписано нужное нам значение.
intents = discord.Intents.all()
Этой строчкой мы подключаем намерения к Discord боту. ВАЖНО: ЕСЛИ ВЫ ПОДКЛЮЧАЕТЕ НАМЕРЕНИЯ ВЫ ДОЛЖНЫ ТАК-ЖЕ ВКЛЮЧИТЬ ИХ НА САЙТЕ DISCORD DEVELOPERS В НАСТРОЙКАХ ВАШЕГО БОТА.
В discord py как и во всех мессенджерах есть ивенты. К примеру в discord.py есть ивент, который называется
on_ready. Он срабатывает, когда бот подключился к серверам Discord и готов к работе.
@bot.event
async def on_ready():
print('Bot launched successfully :)')
print(f'My name is {bot.user.name}')
print(f'My client id is {bot.user.id}')
for guild in bot.guilds:
print(f'Connected to server, id is: {guild.id}')
for member in guild.members:
cursor.execute(f»SELECT id FROM users where id={member.id}»)
if cursor.fetchone() is None:
cursor.execute(
f»INSERT INTO users VALUES ({member.id}, '{member.name}', '', 0)»)
else:
pass
data_base.commit()
Ниже я написал пример того, как может быть написан ивент on_ready с использованием sqlite3. Такой метод работает только для одного сервера.
Так-же у объекта bot, который мы создали есть большое количество методов, о которых я не вижу смысла
рассказывать, так как это займет большое количество времени.
Но если вам интересно то вот ссылка на документацию: https://discordpy.readthedocs.io/en/stable/#
В данном фрагменте кода мы просто перечисляем всех участников сервера и добавляем в базу данных, если их еще там нет. В качестве аргументов в таблицу BD мы указываем:
ID пользователя, Отображаемое имя, mention(то есть упоминание пользователя), а так-же количество денег которое ему дается при старте.
Мне кажется вам уже не терпится протестировать бота, поэтому мы в конце должны добавить еще одну строчку кода, которая запустит нашего бота.
bot.run(settings['token'])
Ну тут мы просто используем метод run, который запускает бота. В качестве аргумента используем токен, который у нас хранится в файлике config в словаре settings.
Если вы всё сделали правильно у вас есть база данных со всеми пользователями. Только есть небольшая проблемка: Пользователи даже не могут проверить сколько денег у них на балансе 🙁
Предлагаю создать команду !balance, которая позволит нам проверять сколько денег на данный момент у пользователя, написавшего команду.
@bot.command()
async def balance(ctx):
for row in cursor.execute(f»SELECT nickname, money FROM users where id={ctx.author.id}»):
embed = discord.Embed(title=f'Аккаунт пользователя {row[0]}', color=0x42f566)
embed.add_field(name='Баланс:', value=f'{row[1]} SH', inline=False)
await ctx.send(embed=embed)
Тут я использую крутую фишку Discord'a, которая называется Embed. По факту это красивый вывод информации, который можно кастомизировать.
Просто создаем объект класса Embed и используем большое кол-во разнообразных методов которые сделают из неё конфетку. Как это работает можно так-же посмотреть на оф.сайте discord.py, хотя тут по названиям и аргументам и так понятно что к чему.
Можем проверять нашего бота. Запомните что строчка, запускающая нашего бота должна быть последней
в скрипте.
Исходя из предыдущих функций и ивентов мы научились получать информацию из BD и заносить её в таблицу. Давайте научимся ОБНОВЛЯТЬ
информацию с помощью sqlite. Покажу на примере функции, которая выдает какое-либо количество денег пользователю.
async def give_money(ctx, mention, money):
try:
mention = str(mention).replace('!', '')
for row in cursor.execute(f'SELECT money FROM users where mention=?', (mention,)):
cursor.execute(f'UPDATE users SET money={int(money) + row[0]} where mention=?', (mention,))
data_base.commit()
for row in cursor.execute(f'SELECT nickname FROM users where mention=?', (mention,)):
embed = discord.Embed(title='Пополнение баланса', color=0x42f566)
embed.set_author(name='Community Bot')
embed.add_field(name='Оповещение', value=f'Баланс пользователя {row[0]} пополнен на {money} SH')
await ctx.send(embed=embed)
except Exception as E:
print(f'give_money command error: {E}')
embed = discord.Embed(title='Оповещение', color=0xFF0000)
embed.add_field(name='Оповещение', value='Ошибка при выполнение программы.')
await ctx.send(embed=embed)
Прошу заметить что в данном случае в качестве аргументов: ctx (который является объектов класса Contex, упоминание (То есть mention) и
кол-во денег).
Советую всегда использовать Try при создании крупных функций для того чтобы быстро понять где вы допустили ошибку. В моем случае
если человек ввел неправильные данные при использовании команды ему выводиться красивое оповещение об этом.
Так-же не забываем про переводы переменных в другие типы данных, чтобы избежать казусов со складыванием str и int.
При использовании Discord Embed, а именно в выборе цвета при создании объекта, я долго тупил как поменять цвет. Discord Embed использует hex colors, то есть Web colors, которые используются
например в HTML и т.д. и т.п.
Я думаю что я довольно подробно рассказал о слиянии Discord.py и sqlite3. Это очень просто. Я понимаю что тут могут быть люди, которые вообще ничего не понимают в Discord.py, поэтому я советую посетить им
мой другой репозиторий https://github.com/MishaSok/discord_bot_quick_start_rus, в котором вы сможете найти мой подробный гайд о том как начать писать ботов для Discord.
Retriever
You can combine a Retriever with a Reader in your pipeline to speed up the search. The Retriever passes the Documents it selected on to the Reader. This way, it saves the Reader from doing more work than it needs to.
In a query pipeline, when given a query, the Retriever sifts through the Documents in the DocumentStore, scores each Document for its relevance to the query, and returns the top candidates. Retriever and DocumentStore are tightly coupled. When configuring a Retriever, you must always specify its DocumentStore.
When used in indexing pipelines, vector-based Retrievers (DensePassagerRetriever and EmbeddingRetriever) take Documents as input, and for each Document, they calculate its vector representation (embedding).
This embedding is stored as part of the Document in the DocumentStore.
If you're using a keyword-based Retriever (BM25Retriever or TfidfRetriever) in your indexing pipeline, no embeddings are calculated and the Retriever creates a keyword-based index that it then uses to quickly look up the Documents.
- Pipeline type: Used in query pipelines and in indexing pipelines.
- Position in a pipeline:
- In query pipelines: At the beginning.
- In indexing pipelines: After a PreProcessor and before DocumentStore.
- Node input:
- In query pipelines: Query
- In indexing pipelines: Document
- Node output:
- In query pipelines: Documents
- In indexing pipelines: Documents
- Available node classes: BM25Retriever, DensePassageRetriever, EmbeddingRetriever, FilterRetriever, TfidfRetriever
There are two categories of retrievers: vector-based (dense) and keyword-based (sparse) retrievers.
Vector-based retrievers work with document embeddings. They embed both the documents and the query using deep neural networks, and then return the documents most similar to the query as top candidates.
Main features:
Available vector-based retrievers:
- EmbeddingRetriever
- DensePassageRetriever
Description | Uses one model to encode both the documents and the query. Can use a transformer model. Sentence transformers models are suited to this kind of retrieval. |
A highly performing retriever that uses two different models: one model to embed the query and one to embed the documents. Such a solution boosts the accuracy of the results it returns. |
Main Features | — Uses a transformer model — Uses one model to handle queries and documents |
— Uses one BERT base model to encode documents. — Uses one BERT base model to encode queries. — Ranks documents by dot product similarity between the query and document embeddings. |
- Keyword-based retrievers look for keywords shared between the documents and the query.
- Main features:
- Available keyword-based retrievers:
- TfidfRetriever
- BM25Retriever
- FilterRetriever
Description |