Хочу описать процесс создания приложения, которое работает с OpenAI API. Идея приложения возникла из потребности улучшить мой английский язык. Как говорится, если у вас есть молоток, то все проблемы выглядят как гвозди. Так как я программист, я решил написать Искусственный Интеллект, который будет заменять учителя английского языка.
Сценарий взаимодействия с приложением следующий: ученик задает тему урока, ИИ-учитель предоставляет список основных слов по теме. Ученик может спрашивать значение слов, которые ему не знакомы, ИИ-учитель предоставляет значения слов и примеры их использования. Затем ИИ-учитель вступает в диалог с учеником по заданной теме, ученик может отвечать на вопросы и задавать свои вопросы. ИИ-учитель также находит ошибки в ответах ученика.
Изначально я думал о создании полноценного веб-сервиса, на котором любой желающий сможет зарегистрироваться, привязать свою карту и начать обучение с ИИ-учителем. Однако в итоге, я решил начать с прототипа: консольного приложения на Rust, с которым можно будет вести диалог из терминала. Но потом я немного остыл от этой идеи, так как реализация полноценного сервиса требует открытия юридического лица, заключения договора с банком для обработки карт клиентов, аренды облака для сервера, разработки веб-версии ИИ-учителя и инвестиций в рекламную кампанию.
Я, конечно, могу выполнить все эти задачи, но создание такого сервиса будет достаточно долгим и необходимы значительные инвестиции. А сделать это на коленке и потерять свое время, и не иметь возможности составить конкуренцию с аналогичными стартапами из США, которые имеют достаточные средства на рекламу и развитие, неинтересно.
Вернемся к тонкостям реализации данного приложения. Для того чтобы получить список основных слов по теме, нужно выполнять запрос "completions" к OpenAI API. Этот запрос возвращает логическое завершение текста, который вы ему передадите, например, список основных слов по теме урока.
В итоге, методом проб и ошибок у меня получился запрос, который посылает программа, он выглядит следующим образом:
Give list of words linked with the subject "_TOPIC_". Words should comma separated. Only words
.
Где _TOPIC_ - тема урока с ИИ-учителем. Результатом работы этого запроса будет список слов, разделенных запятой, по нужной вам теме.
Далее по логике приложения необходимо было дать объяснение словам, которые не знает ученик. Получился следующий запрос:
Give answer what is "_WORD_" from the field "_TOPIC_".
Где _WORD_ - слово, которое требует объяснения, _TOPIC_ - тема урока. В ответ вы получите 1-2 предложения, объясняющие данное слово.
Для наглядности, необходимо сгенерировать примеры использования данного слова. У меня получились следующие два запроса:
Give sentence with word "_WORD_" in field "_TOPIC_".
Give rude sentence with word "_WORD_" in field "_TOPIC_".
На каждый из них я получил два разных предложения, в которых демонстрируется использование слова. Первое - общего характера, второе - немного с агрессией, для разнообразия, так сказать.
Далее приложение должно вступить в диалог с учащимся. Один из самых простых способов - это использовать список слов по теме урока и задать вопрос, используя его. У меня получился следующий запрос к OpenAI API:
Give _QUESTION_TYPE_. About "_TOPIC_". Use word "_WORD_". Do not use word "_TOPIC_".
Где _QUESTION_TYPE_ - тип вопроса, который выбирается случайным образом из списка:
Yes/No question
Wh-question
Choice question
Open-ended question
Hypothetical question
Leading question
Rhetorical question
Funnel question
Probing question
Clarifying question
Follow-up question
Forced-choice question
Matching question
Categorical question
Comparison question
Rude question
Polite question
Что позволяет генерировать всегда разные вопросы даже при многократном прохождении урока по одной и той же теме.
При том в этом запросе я добавил в конец "Do not use word "_TOPIC_", чтобы в каждом вопросе от учителя не было слова с упоминанием темы урока, а то все предложения будут одинаковыми. И выглядит это очень не естественно.
Далее стоит задача определить, есть ли ошибки в ответе ученика. Для этого у OpenAI API есть запрос "edits". Он позволяет взять кусок текста и изменить в него. Там два параметра: исходный текст и то, что с ним надо сделать. В итоге, я, вызывая эту функцию, передавал текст ответа ученика и следующую строку:
Fix grammar and spelling.
На выходе я получал строку с исправленным текстом. Если она не совпадала с тем что писал ученик, то я считал, что он ошибся, и выводил исправленный вариант.
В случае, когда ученик игнорирует вопрос ИИ-учителя и пишет в ответ свой вопрос, или отвечая на него, добавляет еще и свой, то я через OpenAI API "completions" генерирую ему ответ такой строкой:
Give _SENTENCE_TYPE_ answer on text: _STUDENT_QUESTION_.
Где _STUDENT_QUESTION_ - текст с вопросом учащегося, а _SENTENCE_TYPE_ - тип утвердительного предложения который выбирается случайным образом из следующего списка:
Declarative
Imperative
Assertive
Optative
Exhortative
Descriptive
Expository
Complex
Polite
Rude
Таким образом, даже на одни и те же вопросы ИИ-учитель всегда дает разный ответ, что вносит разнообразие во время общения.
Код консольной программы ИИ-учителя можно посмотреть здесь. Код библиотеки работающей с OpenAI API можно посмотреть здесь.
Ну и наконец, пример взаимодействия с этой программой, которая заменяет учителя английского языка:
Please enter a topic of the lesson:
hotel
Words of lesson:
Lodging
Accommodation
Suite
Room
Reception
Concierge
Check-in
Check-out
Amenities
Restaurant
Bar
Pool
Spa
Gym
Valet
Bellhop
Do you know all these words? Say: Yes or write unknown words comma separated:
bellhop, valet
Bellhop
A bellhop is a hotel employee who assists guests with their luggage and other needs. They are usually the first person a guest sees when they arrive at the hotel. Example 1: The bellhop carried our luggage to our room in the hotel. Example 2: "Hey bellhop, why are you so slow? Hurry up and get my bags to my room!"
Valet
Valet is a service offered by some hotels where a guest can have their car parked and retrieved by a hotel employee. Example 1: The hotel valet was very helpful in parking our car. Example 2: "If you can't do your job as a valet in this hotel, then you should find another job."
What type of establishment typically offers a variety of food and beverages for customers to enjoy?
I think it is restraunt.
I think it is restaurant. < grammar fixes
What is the process for check-in at a lodging establishment?
You need show a passport and student card. Is it correct?
You need to show a passport and student card. Is it correct? < grammar fixes
Yes, it is correct that you need to show a passport and student card in order to prove your identity and student status. Depending on the situation, you may need to provide additional documents such as a birth certificate or proof of address.
What kind of lodging would you prefer?
I prefer room with toulet and shower. If I visit hotel with wife then I prefer one big bad for two.
I prefer room with toilet and shower. If I visit hotel with wife then I prefer one big bad for two. < grammar fixes
What is the average wait time at the reception desk?
Usually it could take not more 5 minutes.
Usually it could take not more than 5 minutes. < grammar fixes
What services does a concierge provide?
You could ask a concierge call you at 7:00 am to wake you tommorow.
You could ask a concierge to call you at 7:00 am to wake you tomorrow. < grammar fixes
What kind of accommodation can you find when you travel?
When I travel I usualy take apartmant in hotel.
When I travel I usually take an apartment in a hotel. < grammar fixes
Do you have a swimming pool at your accommodation?
No We do not have swimming pool at the hotel.
No, we do not have a swimming pool at the hotel. < grammar fixes
Комментарии (28)
lair
24.01.2023 22:26Ну и наконец, пример взаимодействия с этой программой, которая заменяет учителя английского языка:
Пытается заменить, но не заменяет. Разбор ошибок нужен?
igumnov Автор
25.01.2023 04:49+1Ага. Это прототип. Первая версия. Написал всего за пару вечеров.
lair
25.01.2023 04:55Вы сам не видите, что ваш "учитель" (а) пропускает очень много языковых ошибок, и (б) вообще не проверяет текст на смысл?
igumnov Автор
25.01.2023 05:20Я вижу. Вы тоже. Что дальше?
lair
24.01.2023 22:44реализация полноценного сервиса требует [...] разработки веб-версии ИИ-учителя [..] Я, конечно, могу выполнить все эти задачи
Воу. Вы правда искренне считаете, что в одиночку можете сделать ИИ, который заменяет учителя иностранного языка?
KValery
25.01.2023 04:51Идея для новой фичи: пользователь задаёт уровень знания языка, тему конкретную или без темы. Далее нужно сделать интеграцию чата с голосовым помощником, чтобы реализовать следующий процесс имитации разговорного диалога: пользователь говорит фразу голосовому помощнику, тот ее распознает и отправляет в gpt, gpt выдает текстовый ответ, голосовой помощник его озвучивает.
Я протестировал такое взаимодействие пока только на уровне текста и это уже супер для имитации реального диалога. При этом я заранее задал условие, чтобы на все мои ответы gpt отвечал только ОК, если ответ был написан правильно. И NO плюс верное написание, если мой ответ был написан неверно.
Если же будет добавлена функция голосовая, то это будет аналог живого устного общения, которого обычно очень не хватает при обучении языку.
igumnov Автор
25.01.2023 04:53Годно, спасибо! Если случится чудо и бизнес ангел ворвется в мою дверь, то обязательно найму команду программистов и ученых лингвистов для реализации ваших идей. Ну или если заскучаю, может что-то сам допишу в рамках своего прототипа.
leonidv
25.01.2023 09:57Исходя из тэга Rust и Open API в названии, я ожидал прочитать про создание сервиса на Rust. Как мне кажется, тэг Rust здесь лишний.
PrinceKorwin
Спасибо за ссылки на код. Хочу себе сделать что-то подобное. В вашем коде смутило обилие . unwrap (). Это нормально? Тем более для библиотеки.
igumnov Автор
Не должна либа сваливаться в panic. Согласен с Вами. Просто хотел быстрее написать.
igumnov Автор
Убрал все unwrap
Теперь вот какая проблема, код стал тяжело читаем:
Может есть другой способ как красиво написать что бы читабельность была нормальная?
Ну и я что-то поленился заводить свои Error и просто возвращаю в случае ошибки String с текстом ошибки, наверное это не очень хорошо.
lain8dono
Для кода, написанного на скорую руку вполне. Но лучше по быстрому обернуть в thiserror.