async def ask(channel, question):
global current_model
lang = detect(question)
print(f"Detected language: {lang}")
data = load_data(data_folder, lang)
print("Loaded data.")
if PERSIST and os.path.exists("persist"):
print("Reusing index...\n")
vectorstore = Chroma(persist_directory="persist", embedding_function=OpenAIEmbeddings())
index = VectorStoreIndexWrapper(vectorstore=vectorstore)
print("Using existing index.")
else:
loader = DirectoryLoader(data_folder)
if PERSIST:
index = VectorstoreIndexCreator(vectorstore_kwargs={"persist_directory": "persist"}).from_loaders([loader])
else:
index = VectorstoreIndexCreator().from_loaders([loader])
print("Created new index.")
chain = ConversationalRetrievalChain.from_llm(
llm=ChatOpenAI(model=current_model),
retriever=index.vectorstore.as_retriever(search_kwargs={"k": 1}),
)
print("Initialized chain.")
result = chain({"question": question, "chat_history": []})
if result['answer']:
await channel.send(result['answer'])
print("Sent answer.")
else:
# Если ответ не найден, выполнить команду /search с вопросом пользователя
await channel.send(f"Извините, не удалось найти ответ на ваш вопрос.")
search_command = bot.get_command("search")
if search_command:
# Создаем контекст для выполнения команды /search с вопросом пользователя
ctx = await bot.get_context(channel.message)
ctx.message.content = f"/search {question}"
await bot.invoke(ctx)
else:
await channel.send("Команда /search не найдена.")
# Проверяем наличие ключевых слов для запроса дополнительной информации
keywords = ["биография"]
for keyword in keywords:
if keyword in question.lower():
if keyword == "биография":
bio_file = os.path.join(data_folder, "bio.txt")
if os.path.exists(bio_file):
with open(bio_file, "r", encoding="utf-8") as file:
bio_contents = file.read()
await channel.send(f"Биография: {bio_contents}")
else:
await channel.send("Биография не найдена.")
@bot.command()
async def search(ctx, *, query):
try:
search_results = googlesearch.search(query, num_results=3)
if search_results:
await ctx.send("Результаты поиска в Google:")
for result in search_results:
await ctx.send(result)
else:
await ctx.send("Ничего не найдено.")
except Exception as e:
await ctx.send(f"Произошла ошибка при выполнении поиска: {str(e)}")
search_results = googlesearch.search(query, num_results=3)
внутри ask(), и обработать полученные результаты - невелико повторение. Я бы сделал именно так.# Messageable - это что-то, чему можно послать текстовое сообщение. Это может быть канал, пользователь, контекст команды...
async def search_and_reply(query: str, ctx: discord.abc.Messageable) -> None:
try:
search_results = googlesearch.search(query, num_results=3)
if search_results:
await ctx.send("Результаты поиска в Google:")
for result in search_results:
await ctx.send(result)
else:
await ctx.send("Ничего не найдено.")
except Exception as e:
await ctx.send(f"Произошла ошибка при выполнении поиска: {str(e)}")
await search_and_reply(query, ctx)
, но будет брать на себя регистрацию как обработчика команды, проверку ролей и кулдаунов, и прочую мишуру, которой не место внутри search_and_reply(). Тогда ask() может просто сделать аналогичный вызов await search_and_reply(query, channel)
в нужный момент, не беспокоясь о специфике дискорд-обработчика, так как search_and_reply() таковым не является. Как вызвать одну функцию из другой в discord боте?Так же как не в дискорд боте.
Есть две командыВ приложенном коде только одна команда search, а ask просто функция.
# Создаем контекст для выполнения команды /search с вопросом пользователя
ctx = await bot.get_context(channel.message)
ctx.message.content = f"/search {question}"