![Нейро-продавец автомобилей (фото сгенерировано нейросетью) Нейро-продавец автомобилей (фото сгенерировано нейросетью)](https://habrastorage.org/getpro/habr/upload_files/162/bd3/362/162bd3362c8ea5507fcb6f68e0b8b594.jpeg)
Тема нейро-сотрудников на базе 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?
![Пример автоматического переключения нейро-продавца на другой язык Пример автоматического переключения нейро-продавца на другой язык](https://habrastorage.org/getpro/habr/upload_files/76d/43f/f73/76d43ff73caab12bb081b269c9022419.png)
Еще примеры из диалогов с таким сотрудником:
![Тут видно как нейро-продавец сам взял информацию о возможности продажи в лизинг автомобиля со страницы объявления Тут видно как нейро-продавец сам взял информацию о возможности продажи в лизинг автомобиля со страницы объявления](https://habrastorage.org/getpro/habr/upload_files/33d/4d7/870/33d4d787048a178712da22d7cdd35e6c.png)
![Ответы максимально лаконичны и точны, очень близок уже нейро-продавец к реальному человеку Ответы максимально лаконичны и точны, очень близок уже нейро-продавец к реальному человеку](https://habrastorage.org/getpro/habr/upload_files/7d5/82b/5cb/7d582b5cb8003dd33ef9fb49b04f1d64.png)
Резюме
Если вам интересно попробовать обучать таких нейро-сотрудников, пишите мне в телеграм и я дам доступ к платформе где с этим можно экспериментировать.
See
isBlaze
статью тоже писали с помощью чатгпт?
я правильно понимаю, что вы первым шагом получаете запрос пользователя, потом чатгпт обратным вызовом дергает функцию, получающую страницу объявления со всеми элементами, а дальше вы просто прикрепляете контент ко второму запросу и делаете его независимо?
что мешает получить контент до первого запроса, прикрепить его к промту и сразу, в один запрос к чатгпт получить результат? зачем тут вызов функций?
TAU15 Автор
Задача реализовать возможность этому нейро-сотруднику переключатся по нескольким объявлениям. Мы такого сейчас интегрируем в Битрикс24 в котором подключён на вход канал AVITO. При получении сообщения из AVITO мы видим ссылку на объявление, передаем эту ссылку в роль и вуаля - сотрудник ведет диалог по этому объявлению.
Но так как вы предлагаете тоже хороший вариант!
isBlaze
ну просто у вас уже на этапе первого запроса к нейросети есть ссылка, и логичнее дернуть ее контент сразу. второй запрос тут не нужен и просто тратит время и токены :)