Какую проблему решаем?
Любой GPT-бот на базе любой LLM (например на ChatGPT) должен сам и незаметно для пользователя запоминать в постоянную память нужные нам сведения из диалога.
Шаг№1: Создадим определение функции
{ "name": "ai_memory_v3", "description": "Call this function when you need to make adjustments to JSON memory.", "parameters": { "type": "object", "properties": { "key": { "type": "string", "description": "New or existing key from JSON memory", }, "value": { "type": "string", "description": "Text to be written by the specified key", }, "action": { "type": "string", "enum": ["+", '-', '.', '_'], "description": "Action type. `+` - means adding information to memory. `-` - means deleting information from memory. `.` - means changing information in memory. `_` - means clear all memory", }, }, "required": ["key", "value", "action"], }, },
Параметры нашей функции:
-
«key» — Новый или существующий ключ из JSON памяти. Этот параметр указывает, к какому ключу будет применено действие.
-
«value» — Текст, который будет записан по указанному ключу. Этот параметр содержит данные, которые будут добавлены, изменены или удалены в памяти.
-
«action» — Тип действия, которое будет выполнено с памятью. Возможные значения:
—+
— добавление информации в память.
—-
— удаление информации из памяти.
—.
— изменение информации в памяти.
—_
— очистка всей памяти.
Обработчик функции на нашем сервере
from flask import Flask, request, json import os import logging # Инициализация логгера logger = logging.getLogger(__name__) config.ROOT_PATH = '/path/to/your/application/' # Установите корректный путь к приложению # Создаем экземпляр приложения Flask app = Flask(__name__) # Определение маршрута и функции для записи в постоянную память @app.route('/write_memory_dict', methods=['POST']) def write_memory_dict(): # Получение данных из запроса в формате JSON data = GetJsonFromRequest(request) # Логирование данных запроса logger.debug(f"[/write_memory_dict] {data}") # Инициализация сообщения для пользователя Res = 'Покажи новое состояние памяти и получи подтверждение на внесение изменений пользователю.n' # Основная логика для обработки различных действий if data['action'] == '_': try: # Попытка удалить файл памяти os.remove(config.ROOT_PATH + 'json_memory/' + data['chat_id']) except Exception as e: # Если файл не найден, логируем предупреждение logger.warning(f"File not found {data['chat_id']}") # Ответ о том, что память очищена Res = 'Память очищена.n' else: # Имя файла соответствует chat_id filename = data['chat_id'] memory_json = {} if filename is not None: # Чтение существующего файла памяти memory_json = read_file(config.ROOT_PATH + 'json_memory/' + filename) try: # Попытка преобразовать прочитанные данные из файла в JSON memory_json = json.loads(memory_json) except: # Если преобразование не удалось, считаем что данных нет memory_json = {} # Добавление данных в память if data['action'] == '+' and data['key'] not in memory_json: memory_json[data['key']] = data['value'] Res = 'Данные добавлены в постоянную память.n' if data['action'] == '+' and data['key'] in memory_json: memory_json[data['key']] += ', ' + data['value'] Res = 'Данные добавлены в постоянную память.\n' # Удаление данных из памяти if data['action'] == '-' and data['key'] in memory_json: memory_json.pop(data['key']) Res = 'Данные удалены из постоянной памяти.n' # Обновление данных в памяти if data['action'] == '.' and data['key'] in memory_json: memory_json[data['key']] = data['value'] Res = 'Данные в постоянной памяти изменены.n' # Сохранение изменений в файл if filename is not None and memory_json is not {}: with open(config.ROOT_PATH + 'json_memory/' + filename, 'w', encoding='utf-8') as f: json.dump(memory_json, f, ensure_ascii=False, indent=4) # Логирование успешного сохранения logger.info(f"/write memory_json OK {filename}, {memory_json}") Res += 'Данные сохранены в постоянную память.n' # Возвращение ответа клиенту return json.dumps(Res), 200 # Функция для чтения файла, предполагается, что она определена где-то в коде def read_file(file_path): # Тут должна быть ваша реализация функции чтения файла pass # Функция для получения JSON из запроса, предполагается, что она определена где-то в коде def GetJsonFromRequest(req): # Тут должна быть ваша реализация функции извлечения JSON из запроса pass # Запустить приложение, если файл запущен напрямую if __name__ == '__main__': app.run()
Создаем бота для тестирования постоянной памяти
![Бот для теста постоянной памяти на платформе ProTalk Бот для теста постоянной памяти на платформе ProTalk](https://habrastorage.org/getpro/habr/upload_files/9f2/98f/7cd/9f298f7cd4cd647b26d5a77c0987d5a0.png)
![Подключаем нашу функцию к боту Подключаем нашу функцию к боту](https://habrastorage.org/getpro/habr/upload_files/e71/a00/a49/e71a00a493cb4d5676a266e828f94729.png)
![Указываем что именно мы хотим заносить в постоянную память Указываем что именно мы хотим заносить в постоянную память](https://habrastorage.org/getpro/habr/upload_files/df9/a6e/435/df9a6e435bf1aa92ce81f39bc9453c1b.png)
Поведение: При общении используй данные о пользователе в твоей JSON памяти и меняй свой стиль ответов согласно этим данным. Инструкции по работе с памятью: В память можно сохранять следующие данные о пользователе: имя, пол, возраст, привычки, интересы, увлечения.
Тестируем бота и работу памяти
Для начала мы просто назовем имя боту:
![Начало общения с ботом с постоянной памятью Начало общения с ботом с постоянной памятью](https://habrastorage.org/getpro/habr/upload_files/4ca/816/441/4ca816441e1143f89b18015dd5bd7236.png)
Видим, что имя попало в постоянную память.
Теперь назовем возраст:
![Уже два ключа в нашем JSON словаре для постоянной памяти Уже два ключа в нашем JSON словаре для постоянной памяти](https://habrastorage.org/getpro/habr/upload_files/3b4/85a/0ac/3b485a0ac8a39f7119b099a450726837.png)
Теперь протестируем изменения данных в памяти бота:
![Ключ с данными по возрасту пользователя был успешно изменен на новое значение Ключ с данными по возрасту пользователя был успешно изменен на новое значение](https://habrastorage.org/getpro/habr/upload_files/8d0/4eb/ad0/8d04ebad06d75b76dea15281c6a42ae8.png)
Теперь проверим как бот общается с такими данными в памяти:
{ "user_name": "Андрей", "user_age": "45", "user_habits": "кофе", "user_interests": "горы, велосипеды, море, пробежки по утрам" }
![Бот отвечает с учетом данных о пользователе из постоянной памяти Бот отвечает с учетом данных о пользователе из постоянной памяти](https://habrastorage.org/getpro/habr/upload_files/b83/d1c/435/b83d1c4351dd7863986882a7ed49f0d6.png)
Итоги
Если у вас есть идеи по улучшению работы предложенной модели постоянной памяти, пишите в комментариях или мне в Телеграм.
P.S.
У меня уже выходила статья по данной проблеме (https://habr.com/ru/articles/791916/), но решение было не очень стабильным и требовало дополнительный запрос к ИИ каждый раз при внесении изменений в данные постоянной памяти.
ссылка на оригинал статьи https://habr.com/ru/articles/821973/
Добавить комментарий