Тема нейро-сотрудников на базе LLM моделей уровня ChatGPT 3.5 и выше набирает обороты. Я уже постоянно слышу термины типа нейро-продавец, нейро-психолог, нейро-консультант и подобные.
Давайте попробуем разобраться как это устроено внутри и собрать для примера нейро-продавца автомобилей, выложенных на AVITO.
Механика сотрудника такая: мы берем ссылку на любое объявление о продаже машины в AVITO и наш нейро-продавец должен отвечать как бы "подсматривая" на эту страницу и убеждать потенциального покупателя купить автомобиль.
Шаг №1: Пишем системную роль
Системная роль в ChatGPT (далее роль) - это главная управляющая инструкция и она может принимать активное участие в диалоге с пользователем, поддерживая общение на различные темы. Она может задавать дополнительные вопросы, выражать мнение или предлагать альтернативы.
Давайте добавим еще чтобы наш нейро-продавец мог сам определять на каком языке его спрашивают и сам переключался на язык покупателя.
Тогда у нас получится такой текст роли:
Ты владелец машины, которая выставлена для продажи на портале объявлений AVITO.
Тебе пишет потенциальный покупатель и твоя задача продать машину, использую любые аргументы в её пользу.
Отвечай всегда на том же языке на котором был тебе задан вопрос.
При ответом на любой вопрос ты должен каждый раз выполнять функцию "parse_url" с параметром "url" равным "ТУТ_ССЫЛКА_НА_ОБЪЯВЛЕНИЕ" и использовать полученную информацию для ответа на вопрос покупателя с целью убедить его купить автомобиль.
Здесь мы видим вызов функции "parse_url". Что такое функции в ChatGPT 3.5? Давайте разбираться.
Шаг№2: Пишем функцию для ChatGPT для получения информации с сайта
Передача функции в ChatGPT реализуется так:
import requests
import json
openai_api_key = "YOUR_OPENAI_API_KEY"
openai_api_url = "<https://api.openai.com/v1/chat/completions>"
headers = {
"Content-Type": "application/json",
}
data = {
"model": "gpt-4",
"messages": [
{"role": "system", "content": "ТУТ_ТЕКСТ_НАШЕЙ_РОЛИ"},
{"role": "assistant", "content": "????"},
{"role": "user", "content": "А что такой небольшой пробег у тачки?"},
],
"functions": [
{
"name": "parse_url",
"description": "Получение данных с сайта",
"parameters": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Ссылка на сайт"
},
},
"required": ["url"]
}
}
]
}
response = requests.post(openai_api_url, auth=('', openai_api_key), headers=headers, data=json.dumps(data))
print(response.json())
При таком вызове мы получим ответ:
{
"id": "chatcmpl-123",
...
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"function_call": {
"name": "parse_url",
"arguments": "{ \\"url\\": \\"*___ТУТ_ССЫЛКА_НА_ОБЪЯВЛЕНИЕ___*\\"}"
}
},
"finish_reason": "function_call"
}]
}
Как мы видим в ответе ChatGPT содержится ключ “function_call” с названием нашей функции.
Далее мы должны вызвать функцию получения погоды, вот так:
import requests
import json
def parse_url(url):
url_content = requests.get(url).text
openai_api_key = "YOUR_OPENAI_API_KEY"
openai_api_url = "<https://api.openai.com/v1/chat/completions>"
headers = {
"Content-Type": "application/json",
}
data = {
"model": "gpt-4",
"messages": [
{"role": "system", "content": "ТУТ_ТЕКСТ_НАШЕЙ_РОЛИ" + url_content},
{"role": "assistant", "content": "????"},
{"role": "user", "content": "А что такой небольшой пробег у тачки?"},
],
}
response = requests.post(openai_api_url, auth=('', openai_api_key), headers=headers, data=json.dumps(data))
print(response.json())
В итоге мы получим подобный ответ (он будет у вас другой в зависимости от информации в объявлении):
Автомобиль новый, только из салона. Это связано с небольшим пробегом.
Если дальше мы спросим на английском “can you give a discount?” получим ответ:
We have a very competitive price already, considering the car is virtually brand new with only 20km mileage. However, I'd be willing to consider sensible offers. What would you propose?
Еще примеры из диалогов с таким сотрудником:
Резюме
Если вам интересно попробовать обучать таких нейро-сотрудников, пишите мне в телеграм и я дам доступ к платформе где с этим можно экспериментировать.
See
isBlaze
статью тоже писали с помощью чатгпт?
я правильно понимаю, что вы первым шагом получаете запрос пользователя, потом чатгпт обратным вызовом дергает функцию, получающую страницу объявления со всеми элементами, а дальше вы просто прикрепляете контент ко второму запросу и делаете его независимо?
что мешает получить контент до первого запроса, прикрепить его к промту и сразу, в один запрос к чатгпт получить результат? зачем тут вызов функций?
TAU15 Автор
Задача реализовать возможность этому нейро-сотруднику переключатся по нескольким объявлениям. Мы такого сейчас интегрируем в Битрикс24 в котором подключён на вход канал AVITO. При получении сообщения из AVITO мы видим ссылку на объявление, передаем эту ссылку в роль и вуаля - сотрудник ведет диалог по этому объявлению.
Но так как вы предлагаете тоже хороший вариант!
isBlaze
ну просто у вас уже на этапе первого запроса к нейросети есть ссылка, и логичнее дернуть ее контент сразу. второй запрос тут не нужен и просто тратит время и токены :)