diff --git a/content/ru/api_docs/chat/chat.md b/content/ru/api_docs/chat/chat.md new file mode 100644 index 00000000..a8278ea7 --- /dev/null +++ b/content/ru/api_docs/chat/chat.md @@ -0,0 +1,5 @@ +--- +title: Chat +openapi: "POST /chat" +--- + diff --git a/content/ru/api_docs/core/add_message.md b/content/ru/api_docs/core/add_message.md new file mode 100644 index 00000000..cbe233d4 --- /dev/null +++ b/content/ru/api_docs/core/add_message.md @@ -0,0 +1,5 @@ +--- +title: Add Message +openapi: "POST /add/message" +--- + diff --git a/content/ru/api_docs/core/delete_memory.md b/content/ru/api_docs/core/delete_memory.md new file mode 100644 index 00000000..994f8bda --- /dev/null +++ b/content/ru/api_docs/core/delete_memory.md @@ -0,0 +1,5 @@ +--- +title: Delete Memory +openapi: "POST /delete/memory" +--- + diff --git a/content/ru/api_docs/core/get_memory.md b/content/ru/api_docs/core/get_memory.md new file mode 100644 index 00000000..aadea450 --- /dev/null +++ b/content/ru/api_docs/core/get_memory.md @@ -0,0 +1,5 @@ +--- +title: Get Memory +openapi: "POST /get/memory" +--- + diff --git a/content/ru/api_docs/core/modify_memory.md b/content/ru/api_docs/core/modify_memory.md new file mode 100644 index 00000000..a391e03b --- /dev/null +++ b/content/ru/api_docs/core/modify_memory.md @@ -0,0 +1,7 @@ +--- +title: Изменение Памяти +openapi: "POST /add/feedback" +--- + + + diff --git a/content/ru/api_docs/core/search_memory.md b/content/ru/api_docs/core/search_memory.md new file mode 100644 index 00000000..39d1cd24 --- /dev/null +++ b/content/ru/api_docs/core/search_memory.md @@ -0,0 +1,5 @@ +--- +title: Search Memory +openapi: "POST /search/memory" +--- + diff --git a/content/ru/api_docs/help/error_codes.md b/content/ru/api_docs/help/error_codes.md new file mode 100644 index 00000000..3d58db8e --- /dev/null +++ b/content/ru/api_docs/help/error_codes.md @@ -0,0 +1,48 @@ +--- +title: Код Ошибки +--- + +| Код Ошибки | Значение | Рекомендуемое Решение | +| :--- | :--- | :--- | +| **Ошибка Параметра** | | | +| 40000 | Ошибка Запроса Параметра | Проверьте, соответствуют ли имена, типы и форматы параметров требованиям | +| 40001 | Запрашиваемые Данные Не Существуют | Проверьте, правильный ли ресурс ID (например, memory_id) | +| 40002 | Обязательный Параметр Не Может Быть Пустым | Дополните отсутствующие обязательные поля | +| 40003 | Параметр Пустой | Проверьте, не является ли переданный список или объект пустым | +| 40006 | Неподдерживаемый Тип | Проверьте значение поля type | +| 40007 | Неподдерживаемый Тип Файла | Загружайте только разрешенные форматы (.pdf, .docx, .doc, .txt, .json, .md, .xml) | +| 40008 | Неверное Содержимое Base64 | Проверьте, не содержит ли строка Base64 недопустимые символы | +| 40009 | Неверный Формат Base64 | Проверьте, правильный ли формат кодирования Base64 | +| 40010 | Слишком Длинный Пользовательский ID | Длина user_id не должна превышать 100 символов | +| 40011 | Слишком Длинный Идентификатор Сессии | Длина conversation_id не должна превышать 100 символов | +| 40020 | Неверный Идентификатор Проекта | Убедитесь, что формат Project ID правильный | +| **Ошибка Аутентификации и Разрешений** | | | +| 40100 | Требуется Аутентификация API Key | Добавьте действительный API Key в заголовок | +| 40130 | Требуется API Key Аутентификация | Добавьте действующий API Key в заголовок | +| 40132 | API Key недействителен или истек | Проверьте состояние API Key или сгенерируйте заново | +| **Ошибки Квоты и Ограничения** | | | +| 40300 | Превышен лимит вызовов интерфейса | Получить больше лимита | +| 40301 | Превышен лимит вызовов токена запроса | Уменьшите вводимый контент или получите больше лимита | +| 40302 | Превышен лимит вызовов токена ответа | Укоротите ожидаемый вывод или получите больше лимита | +| 40303 | Длина одного диалога превышает лимит | Уменьшите длину одного ввода/вывода | +| 40304 | Общие вызовы API аккаунта исчерпаны | Получить больше лимита | +| 40305 | Ввод превышает лимит одного токена | Уменьшите вводимый контент | +| 40306 | Ошибка аутентификации при удалении памяти | Убедитесь, что у вас есть право удалить эту память | +| 40307 | Удаляемая память не существует | Проверьте, действителен ли memory_id | +| 40308 | Пользователь, соответствующий удаляемой памяти, не существует | Проверьте, правильный ли user_id | +| **Ошибки Системы и Сервиса** | | | +| 50000 | Внутренняя ошибка системы | Сервер перегружен или возникла ошибка, пожалуйста, свяжитесь с поддержкой | +| 50002 | Операция не удалась | Проверьте логику операции или попробуйте позже | +| 50004 | Служба памяти временно недоступна | Повторите попытку записи/получения памяти позже | +| 50005 | Служба поиска временно недоступна | Повторите попытку поиска памяти позже | +| **Ошибка Базы Знаний и Операций** | | | +| 50103 | Превышено количество файлов | Максимальное количество файлов для загрузки за один раз не должно превышать 20 | +| 50104 | Размер одного файла превышает лимит | Убедитесь, что размер одного файла не превышает 100MB | +| 50105 | Общий размер всех файлов превышает лимит | Убедитесь, что общий размер загрузки за один раз не превышает 300MB | +| 50107 | Формат загружаемого файла не соответствует требованиям | Проверьте и измените формат файла | +| 50120 | База знаний не существует | Убедитесь, что ID базы знаний правильный | +| 50123 | База знаний не связана с этим проектом | Убедитесь, что база знаний была авторизована для текущего проекта | +| 50131 | Задача не существует | Проверьте, правильный ли task_id (часто встречается при проверке статуса обработки) | +| 50143 | Не удалось добавить память | Исключение при обработке алгоритмической службы, повторите попытку позже | +| 50144 | Не удалось добавить сообщение | Не удалось сохранить историю чата | +| 50145 | Не удалось сохранить отзыв и записать память | Произошло исключение в процессе обработки отзыва | diff --git a/content/ru/api_docs/knowledge/add_kb_doc.md b/content/ru/api_docs/knowledge/add_kb_doc.md new file mode 100644 index 00000000..8888cbfb --- /dev/null +++ b/content/ru/api_docs/knowledge/add_kb_doc.md @@ -0,0 +1,5 @@ +--- +title: Добавить Документ Знаний +openapi: "POST /add/knowledgebase-file" +--- + diff --git a/content/ru/api_docs/knowledge/create_kb.md b/content/ru/api_docs/knowledge/create_kb.md new file mode 100644 index 00000000..d02a423b --- /dev/null +++ b/content/ru/api_docs/knowledge/create_kb.md @@ -0,0 +1,5 @@ +--- +title: Создание Базы Знаний +openapi: "POST /create/knowledgebase" +--- + diff --git a/content/ru/api_docs/knowledge/delete_kb_doc.md b/content/ru/api_docs/knowledge/delete_kb_doc.md new file mode 100644 index 00000000..6996d9d6 --- /dev/null +++ b/content/ru/api_docs/knowledge/delete_kb_doc.md @@ -0,0 +1,5 @@ +--- +title: Удалить Документ Базы Знаний +openapi: "POST /delete/knowledgebase-file" +--- + diff --git a/content/ru/api_docs/knowledge/get_kb_doc.md b/content/ru/api_docs/knowledge/get_kb_doc.md new file mode 100644 index 00000000..e50990a0 --- /dev/null +++ b/content/ru/api_docs/knowledge/get_kb_doc.md @@ -0,0 +1,5 @@ +--- +title: Получение Документов Знаний +openapi: "POST /get/knowledgebase-file" +--- + diff --git a/content/ru/api_docs/knowledge/remove_kb.md b/content/ru/api_docs/knowledge/remove_kb.md new file mode 100644 index 00000000..226ed98e --- /dev/null +++ b/content/ru/api_docs/knowledge/remove_kb.md @@ -0,0 +1,5 @@ +--- +title: Удаление Базы Знаний +openapi: "POST /delete/knowledgebase" +--- + diff --git a/content/ru/api_docs/message/add_feedback.md b/content/ru/api_docs/message/add_feedback.md new file mode 100644 index 00000000..6dda7745 --- /dev/null +++ b/content/ru/api_docs/message/add_feedback.md @@ -0,0 +1,5 @@ +--- +title: Add Feedback +openapi: "POST /add/feedback" +--- + diff --git a/content/ru/api_docs/message/get_message.md b/content/ru/api_docs/message/get_message.md new file mode 100644 index 00000000..5c30bb97 --- /dev/null +++ b/content/ru/api_docs/message/get_message.md @@ -0,0 +1,5 @@ +--- +title: Get Message +openapi: "POST /get/message" +--- + diff --git a/content/ru/api_docs/message/get_status.md b/content/ru/api_docs/message/get_status.md new file mode 100644 index 00000000..45344c42 --- /dev/null +++ b/content/ru/api_docs/message/get_status.md @@ -0,0 +1,5 @@ +--- +title: Get Task Status +openapi: "POST /get/status" +--- + diff --git a/content/ru/api_docs/snippets/add_feedback.md b/content/ru/api_docs/snippets/add_feedback.md new file mode 100644 index 00000000..1ce229d8 --- /dev/null +++ b/content/ru/api_docs/snippets/add_feedback.md @@ -0,0 +1,60 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "memos_feedback_conv", + "feedback_content": "Нет, мы теперь изменили на 150 юаней в день на питание в городах первого уровня и 700 юаней в день на жилье; для городов второго и третьего уровня остается как раньше.", + "allow_knowledgebase_ids":["basee5ec9050-c964-484f-abf1-ce3e8e2aa5b7"] # Замените на ID базы знаний +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/feedback" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# # Пожалуйста, убедитесь, что MemoS установлен (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализируйте клиента с помощью API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +user_id = "memos_user_123" +conversation_id = "memos_feedback_conv" +feedback_content = "Нет, мы теперь изменили на 150 юаней в день на питание в городах первого уровня и 700 юаней в день на жилье; для городов второго и третьего уровня остается как раньше." +allow_knowledgebase_ids = ["basee5ec9050-c964-484f-abf1-ce3e8e2aa5b7"] # Замените на ID базы знаний + +res = client.add_feedback( + user_id=user_id, + conversation_id=conversation_id, + feedback_content=feedback_content, + allow_knowledgebase_ids=allow_knowledgebase_ids +) + +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/add/feedback \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "user_id": "memos_user_123", + "conversation_id": "memos_feedback_conv", + "feedback_content": "Нет, мы теперь изменили на 150 юаней в день на питание в городах первого уровня и 700 юаней в день на жилье; для городов второго и третьего уровня остается как раньше.", + "allow_knowledgebase_ids":["basee5ec9050-c964-484f-abf1-ce3e8e2aa5b7"] + }' +``` +:: diff --git a/content/ru/api_docs/snippets/add_knowledgebase-file.md b/content/ru/api_docs/snippets/add_knowledgebase-file.md new file mode 100644 index 00000000..d6aa7b3e --- /dev/null +++ b/content/ru/api_docs/snippets/add_knowledgebase-file.md @@ -0,0 +1,57 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "knowledgebase_id": "basec32f88c6-9dd3-4061-82c8-f0fa0e85a284",# Замените на ID базы знаний, в которую нужно загрузить документ + "file": [ + {"content": "https://cdn.memtensor.com.cn/file/出差报销额度说明.docx"} + ] +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/knowledgebase-file" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# Пожалуйста, убедитесь, что установлен MemOS (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализация клиента с использованием API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +knowledgebase_id = "basec32f88c6-9dd3-4061-82c8-f0fa0e85a284" # Замените на ID базы знаний, в которую нужно загрузить документ +file = [ + { + "content": "https://cdn.memtensor.com.cn/file/出差报销额度说明.docx" + } +] + +res = client.add_knowledgebase-file(knowledgebase_id=knowledgebase_id,file=file) +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/add/knowledgebase-file \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "knowledgebase_id": "basec32f88c6-9dd3-4061-82c8-f0fa0e85a284", + "file": [ + { + "content": "https://cdn.memtensor.com.cn/file/出差报销额度说明.docx" + } + ] + }' +``` diff --git a/content/ru/api_docs/snippets/add_message.md b/content/ru/api_docs/snippets/add_message.md new file mode 100644 index 00000000..88a3875c --- /dev/null +++ b/content/ru/api_docs/snippets/add_message.md @@ -0,0 +1,67 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "0610", + "messages": [ + {"role": "user", "content": "Я запланировал поездку в Гуанчжоу на летние каникулы, какие сетевые отели доступны для проживания?"}, + {"role": "assistant", "content": "Вы можете рассмотреть 【Семь Дней, Целый Сезон, Хилтон】 и так далее"}, + {"role": "user", "content": "Я выбрал Семь Дней"}, + {"role": "assistant", "content": "Хорошо, если есть другие вопросы, спрашивайте меня."} + ] + } +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# # Пожалуйста, убедитесь, что вы установили MemOS (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализация клиента с использованием API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +messages = [ + {"role": "user", "content": "Я запланировал поездку в Гуанчжоу на летние каникулы, какие сетевые отели доступны для проживания?"}, + {"role": "assistant", "content": "Вы можете рассмотреть 【Семь Дней, Целый Сезон, Хилтон】 и так далее"}, + {"role": "user", "content": "Я выбрал Семь Дней"}, + {"role": "assistant", "content": "Хорошо, если есть другие вопросы, спрашивайте меня."} +] +user_id = "memos_user_123" +conversation_id = "0610" + +res = client.add_message(messages=messages, user_id=user_id, conversation_id=conversation_id) + +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/add/message \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "user_id": "memos_user_123", + "conversation_id": "0610", + "messages": [ + {"role": "user", "content": "Я запланировал поездку в Гуанчжоу на летние каникулы, какие сетевые отели доступны для проживания?"}, + {"role": "assistant", "content": "Вы можете рассмотреть 【Семь Дней, Целый Сезон, Хилтон】 и так далее"}, + {"role": "user", "content": "Я выбрал Семь Дней"}, + {"role": "assistant", "content": "Хорошо, если есть другие вопросы, спрашивайте меня."} + ] + }' +``` +:: diff --git a/content/ru/api_docs/snippets/chat.md b/content/ru/api_docs/snippets/chat.md new file mode 100644 index 00000000..570730c0 --- /dev/null +++ b/content/ru/api_docs/snippets/chat.md @@ -0,0 +1,51 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "memos_chat_conv", + "query": "Представьте мне MemOS" +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/chat" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# Пожалуйста, убедитесь, что MemoS установлен (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализируйте клиент с помощью API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +user_id = "memos_user_123" +conversation_id = "memos_chat_conv" +query = "Представьте мне MemOS" + +res = client.chat(user_id=user_id,conversation_id=conversation_id,query=query) +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/chat \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "user_id": "memos_user_123", + "conversation_id": "memos_chat_conv", + "query": "Представьте мне MemOS" + }' +``` +:: diff --git a/content/ru/api_docs/snippets/create_knowledgebase.md b/content/ru/api_docs/snippets/create_knowledgebase.md new file mode 100644 index 00000000..729d387c --- /dev/null +++ b/content/ru/api_docs/snippets/create_knowledgebase.md @@ -0,0 +1,51 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "knowledgebase_name": "База Знаний По Финансовым Возвратам", + "knowledgebase_description": "Свод всех знаний, связанных с финансовыми возвратами нашей компании." +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/create/knowledgebase" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# Пожалуйста, убедитесь, что установлен MemOS (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализация клиента с использованием API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +knowledgebase_name = "База Знаний По Финансовым Возвратам" +knowledgebase_description = "Свод всех знаний, связанных с финансовыми возвратами нашей компании." + +res = client.create_knowledgebase( + knowledgebase_name=knowledgebase_name, + knowledgebase_description=knowledgebase_description +) +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/create/knowledgebase \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "knowledgebase_name": "База Знаний По Финансовым Возвратам", + "knowledgebase_description": "Свод всех знаний, связанных с финансовыми возвратами нашей компании." + }' +``` +:: diff --git a/content/ru/api_docs/snippets/delete_knowledgebase-file.md b/content/ru/api_docs/snippets/delete_knowledgebase-file.md new file mode 100644 index 00000000..3fae3897 --- /dev/null +++ b/content/ru/api_docs/snippets/delete_knowledgebase-file.md @@ -0,0 +1,45 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "file_ids": ["3711d404c51592c4eebae46900236f50"] # Замените на ID документа базы знаний +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/delete/knowledgebase-file" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# Пожалуйста, убедитесь, что установлен MemOS (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализируйте клиент с помощью API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +file_ids = ["3711d404c51592c4eebae46900236f50"] # Замените на ID документа базы знаний + +res = client.delete_knowledgebase-file(file_ids=file_ids) + +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/delete/knowledgebase-file \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "file_ids": ["3711d404c51592c4eebae46900236f50"] + }' +``` diff --git a/content/ru/api_docs/snippets/delete_knowledgebase.md b/content/ru/api_docs/snippets/delete_knowledgebase.md new file mode 100644 index 00000000..de7d9fba --- /dev/null +++ b/content/ru/api_docs/snippets/delete_knowledgebase.md @@ -0,0 +1,45 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "knowledgebase_id": "basee5ec9050-c964-484f-abf1-ce3e8e2aa5b7" # Замените на ID базы знаний, которую нужно удалить +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/delete/knowledgebase" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# Пожалуйста, убедитесь, что установлен MemOS (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализируйте клиента с помощью API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +knowledgebase_id = "basee5ec9050-c964-484f-abf1-ce3e8e2aa5b7" # Замените на ID базы знаний, которую нужно удалить + +res = client.delete_knowledgebase(knowledgebase_id=knowledgebase_id) +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/delete/knowledgebase \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "knowledgebase_id": "basee5ec9050-c964-484f-abf1-ce3e8e2aa5b7" + }' +``` +:: diff --git a/content/ru/api_docs/snippets/delete_memory.md b/content/ru/api_docs/snippets/delete_memory.md new file mode 100644 index 00000000..77317c42 --- /dev/null +++ b/content/ru/api_docs/snippets/delete_memory.md @@ -0,0 +1,45 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "memory_ids": ["6b23b583-f4c4-4a8f-b345-58d0c48fea04"] # Замените на реальный ID памяти +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/delete/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# # Пожалуйста, убедитесь, что MemoS установлен (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализируйте клиент с помощью API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +memory_ids = ["6b23b583-f4c4-4a8f-b345-58d0c48fea04"] # Замените на реальный ID памяти + +res = client.delete_memory(memory_ids=memory_ids) +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/delete/memory \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "memory_ids": ["6b23b583-f4c4-4a8f-b345-58d0c48fea04"] + }' +``` +:: diff --git a/content/ru/api_docs/snippets/get_knowledgebase-file.md b/content/ru/api_docs/snippets/get_knowledgebase-file.md new file mode 100644 index 00000000..64073cc0 --- /dev/null +++ b/content/ru/api_docs/snippets/get_knowledgebase-file.md @@ -0,0 +1,45 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "file_ids": ["3711d404c51592c4eebae46900236f50"] # Замените на ID документа базы знаний +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/get/knowledgebase-file" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# Пожалуйста, убедитесь, что установлен MemOS (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализируйте клиент с помощью API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +file_ids = ["3711d404c51592c4eebae46900236f50"] # Замените на ID документа базы знаний + +res = client.get_knowledgebase-file(file_ids=file_ids) + +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/get/knowledgebase-file \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "file_ids": ["3711d404c51592c4eebae46900236f50"] + }' +``` diff --git a/content/ru/api_docs/snippets/get_memory.md b/content/ru/api_docs/snippets/get_memory.md new file mode 100644 index 00000000..58cfcfb3 --- /dev/null +++ b/content/ru/api_docs/snippets/get_memory.md @@ -0,0 +1,46 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123" + } +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/get/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# # Убедитесь, что установлен MemOS (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализация клиента с использованием API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +user_id = "memos_user_123" + +res = client.get_memory(user_id=user_id) +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/get/memory \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "user_id": "memos_user_123" + }' +``` +:: + diff --git a/content/ru/api_docs/snippets/get_message.md b/content/ru/api_docs/snippets/get_message.md new file mode 100644 index 00000000..3dbff9f5 --- /dev/null +++ b/content/ru/api_docs/snippets/get_message.md @@ -0,0 +1,49 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "0610" +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/get/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# Пожалуйста, убедитесь, что установлен MemOS (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализируйте клиент с помощью API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +user_id = "memos_user_123" +conversation_id = "0610" + +res = client.get_message(user_id=user_id, conversation_id=conversation_id) + +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/get/message \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "user_id": "memos_user_123", + "conversation_id": "0610" + }' +``` +:: diff --git a/content/ru/api_docs/snippets/get_status.md b/content/ru/api_docs/snippets/get_status.md new file mode 100644 index 00000000..bfdcd244 --- /dev/null +++ b/content/ru/api_docs/snippets/get_status.md @@ -0,0 +1,45 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "task_id": "40aae834-4248-4944-b2bb-a674f37a2fdb" # Замените на ID задачи для запроса +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/get/status" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# Пожалуйста, убедитесь, что установлен MemOS (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализируйте клиент с помощью API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +task_id = "40aae834-4248-4944-b2bb-a674f37a2fdb" # Замените на реальный ID задачи + +res = client.get_task_status(task_id=task_id) +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/get/status \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "task_id": "40aae834-4248-4944-b2bb-a674f37a2fdb" + }' +``` +:: diff --git a/content/ru/api_docs/snippets/search_memory.md b/content/ru/api_docs/snippets/search_memory.md new file mode 100644 index 00000000..d46667a1 --- /dev/null +++ b/content/ru/api_docs/snippets/search_memory.md @@ -0,0 +1,51 @@ +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" +data = { + "query": "Я хочу поехать на праздник Национального дня, порекомендуйте мне город, в котором я еще не был, и гостиничную сеть, в которой я еще не останавливался", + "user_id": "memos_user_123", + "conversation_id": "0928" +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/search/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Python (SDK)] +# Пожалуйста, убедитесь, что MemOS установлен (pip install MemoryOS -U) +from memos.api.client import MemOSClient + +# Инициализация клиента с использованием API Key +client = MemOSClient(api_key="YOUR_API_KEY") + +query = "Я хочу поехать на праздник Национального дня, порекомендуйте мне город, в котором я еще не был, и гостиничную сеть, в которой я еще не останавливался" +user_id = "memos_user_123" +conversation_id = "0928" + +res = client.search_memory(query=query, user_id=user_id, conversation_id=conversation_id) + +print(f"result: {res}") +``` +```bash [Curl] +curl --request POST \ + --url https://memos.memtensor.cn/api/openmem/v1/search/memory \ + --header 'Authorization: Token YOUR_API_KEY' \ + --header 'Content-Type: application/json' \ + --data '{ + "query": "Я хочу поехать на праздник Национального дня, порекомендуйте мне город, в котором я еще не был, и гостиничную сеть, в которой я еще не останавливался", + "user_id": "memos_user_123", + "conversation_id": "0928" + }' +``` +:: diff --git a/content/ru/api_docs/start/configuration.md b/content/ru/api_docs/start/configuration.md new file mode 100644 index 00000000..bb7b542a --- /dev/null +++ b/content/ru/api_docs/start/configuration.md @@ -0,0 +1,51 @@ +--- +title: Конфигурация Проекта +desc: MemOS поддерживает управление ресурсами, правами и журналами вызовов на уровне проекта. Проект может быть приложением, агентом или любым модулем, который требует независимого управления ресурсами. +--- + +## 1. Создание Нового Проекта + +* Каждый новый пользователь по умолчанию имеет "Проект по Умолчанию". + +* При создании проекта через консоль введите название и описание, чтобы создать свой независимый проект. + + +![image.png](https://cdn.memtensor.com.cn/img/1766024162978_5nsoul_compressed.png) + +## 2. Удаление Проекта + +* При наличии нескольких проектов можно удалить ненужные проекты. + + +::warning +Удаление проекта приведет к очистке всех воспоминаний, сообщений и связанных данных в этом проекте, эта операция **неподдаётся восстановлению**. +:: + +![image.png](https://cdn.memtensor.com.cn/img/1766024215447_ywtqmb_compressed.png) + +## 3. Ключи Интерфейса Проекта + +* Каждый проект имеет независимый список ключей интерфейса, используемых для доступа ко всем воспоминаниям, сообщениям и данным в этом проекте. + +* В левом верхнем углу консоли переключите проект, чтобы просмотреть соответствующие ключи. + + +![image.png](https://cdn.memtensor.com.cn/img/1766024242682_flsty6_compressed.png) + +## 4. Журнал Вызовов Проекта + +* В левом верхнем углу консоли переключите проект, чтобы отслеживать состояние вызовов интерфейса и историю. + + +![image.png](https://cdn.memtensor.com.cn/img/1766024337178_5gwpgv_compressed.png) + +## 5. База Знаний Проекта + +* Создайте базу знаний в консоли или через интерфейс, добавив базу знаний, связанную с этим проектом. + + +::note +Чтобы узнать о принципах и методах использования базы знаний, перейдите на [**страницу введения в базу знаний**](/memos_cloud/features/advanced/knowledge_base) и следуйте инструкциям, чтобы шаг за шагом создать документы воспоминаний, которые могут быть вызваны вместе с воспоминаниями пользователей. +:: + +![image.png](https://cdn.memtensor.com.cn/img/1766024259664_hq383f_compressed.png) diff --git a/content/ru/api_docs/start/overview.md b/content/ru/api_docs/start/overview.md new file mode 100644 index 00000000..3ef966ec --- /dev/null +++ b/content/ru/api_docs/start/overview.md @@ -0,0 +1,45 @@ +--- +title: Обзор +--- + +## 1. Введение В Интерфейс + +MemOS предоставляет полный интерфейс, который позволяет интегрировать функции, связанные с памятью, в ваше AI-приложение с помощью простых API-запросов, реализуя производство, планирование, вызов и управление жизненным циклом памяти для различных пользователей и AI-агентов. + +::tip +**Быстрый старт:** Получите ваш ключ API на [**Консоли MemOS**](https://memos-dashboard.openmem.net/apikeys/), и вы сможете выполнить первую операцию с памятью за минуту. +:: + +## 2. Руководство По Началу Работы + +Начните использовать MemOS API с помощью следующих двух простых основных шагов: + +* [**Добавить Сообщение**](/api_docs/core/add_message):Сохраните оригинальное содержание сообщений пользователей, чтобы создать память; + +* [**Поиск Памяти**](/api_docs/core/search_memory):Извлеките связанные фрагменты памяти пользователей, чтобы предоставить справочную информацию для ответов, сгенерированных моделью. + + +## 3. Классификация Интерфейсов + +Изучите богатый функционал интерфейсов, предоставляемых MemOS: + +* [**Основной Интерфейс**](/api_docs/core/add_message):Обеспечивает основные операции с памятью, реализуя полный процесс от производства до потребления памяти. + +* [**Интерфейсы, Связанные С Сообщениями**](/api_docs/message/add_feedback):Используются для загрузки и управления данными оригинального содержания сообщений. + +* [**API, Связанные С Базой Знаний**](/api_docs/knowledge/create_kb):Используются для загрузки и управления базой знаний и ее документами. + + +## 4. Аутентификация + +Все API-запросы требуют аутентификации, пожалуйста, включите ваш ключ API в заголовок `Authorization`. Получите ключ API на [**Консоли MemOS**](https://memos-dashboard.openmem.net/apikeys/). + +::warning +Не раскрывайте ваш ключ API в клиенте или публичных репозиториях, все запросы должны выполняться через переменные окружения или серверные вызовы. +:: + +## 5. Следующие Шаги + +* 👉 [**Добавить Сообщение**](/api_docs/core/add_message):Создайте вашу первую память; + +* 👉 [**Поиск Памяти**](/api_docs/core/search_memory):Используйте фильтры памяти для реализации расширенного поиска памяти. diff --git a/content/ru/changelog.yml b/content/ru/changelog.yml new file mode 100644 index 00000000..91a47038 --- /dev/null +++ b/content/ru/changelog.yml @@ -0,0 +1,519 @@ +versions: + - name: v2.0.13 + date: 2026-04-09 + changedInfo: + Improvements: + - type: Оптимизация Уровней Журналов Планирования + changedInfo: + - Снизить журналы с высокой частотой, повторяющиеся и печатаемые по строкам с info до debug, значительно снизить шум журналов и нагрузку на хранение в онлайн-режиме. + - type: Структурирование Журналов Очереди + changedInfo: + - Локальные очереди и журналы очереди Redis унифицированы в структурированные поля (например, label/item_id/user_id/mem_cube_id/stream), избегая длинных журналов, что делает поиск и агрегацию более стабильными. + - type: Наблюдаемость Ключевых Путей Цепочки Планирования + changedInfo: + - Дополнить сводные журналы ключевых узлов "Отправка -> Извлечение -> Распределение", чтобы быстрее локализовать накопление, аномалии распределения и заторы задач. + + - name: v2.0.12 + date: 2026-04-02 + changedInfo: + Improvements: + - type: Оптимизация Сервиса + changedInfo: + - Добавлен минимальный размер потока как настраиваемый параметр, поддерживающий динамическую настройку размера пула потоков во время выполнения, эффективно контролируя количество активных соединений и избегая резкого увеличения нагрузки на систему из-за мгновенного всплеска трафика. + + - name: v2.0.11 + date: 2026-03-26 + changedInfo: + New Features: + - type: LLM и Поисковые Возможности + changedInfo: + - Добавлен MiniMax в качестве LLM Provider, следуя тому же режиму подключения, что и Qwen, DeepSeek, через совместимый с OpenAI API. + - Добавлен Tavily в качестве подключаемого интернет-поискового бэкенда. Tavily API может быть активирован через конфигурацию для выполнения реального сетевого поиска, предоставляя системе памяти возможность дополнения внешними знаниями. + - type: Развертывание и Эксплуатация + changedInfo: + - Добавлена конечная точка health check API для мониторинга состояния сервиса. Поддерживает контейнерную оркестрацию (например, Kubernetes liveness/readiness probe) и проверку состояния балансировщика нагрузки. + - Добавлен производственный Dockerfile (многоступенчатая сборка) и Kubernetes Helm Chart, включающий конфигурацию оркестрации для MemOS API сервиса, Neo4j графовой базы данных, Qdrant векторной базы данных, а также Ingress и пример файла values, поддерживающий однокнопочное развертывание в K8s кластере. + - type: Расширение Возможностей Интерфейса + changedInfo: + - Ранее интерфейс delete_memory поддерживал только удаление по memory_id. Это обновление расширяет условия фильтрации для удаления, поддерживая массовое удаление памяти по user_id и conversation_id, а также добавляет проверку параметров фильтрации на уровне API, одновременно реализуя метод delete_node_by_params для бэкенда PostgreSQL. + Bug Fixes: + - type: MCP и Обработка Сообщений + changedInfo: + - Исправлена проблема формата сообщения инструмента MCP add_memory; + - Исправлена проблема, из-за которой get_further_suggestion не мог обрабатывать входные параметры типа string. + - type: Память и Обратная Связь + changedInfo: + - Исправлена ошибка, из-за которой связанные узлы памяти ошибочно архивировались после выполнения пользователем операции обратной связи (feedback), что приводило к невозможности их нахождения при последующем поиске; + - type: Neo4j + changedInfo: + - Исправлена проблема логики фильтрации после поиска в Neo4j; + - Исправлена проблема записи вложенных метаданных в Neo4j. + + - name: v2.0.10 + date: 2026-03-19 + changedInfo: + Improvements: + - type: База Данных PolarDB + changedInfo: + - Оптимизация и обновление polardb, оптимизация путей выполнения запросов с несколькими условиями фильтрации, улучшение использования CPU и памяти за счет использования новых возможностей ядра, что позволяет ускорить запросы в несколько раз и снизить нагрузку на систему. + - type: Оптимизация Сервиса Версий Памяти + changedInfo: + - Плагинизация версий памяти. + - Добавлена высокая доступность для модели NLI. + - В memreader добавлен маршрут для версий памяти, если нет соответствующего вызова памяти/содержимого, которое по полному суждению модели nli считается не относящимся, то используется старый prompt и модель, иначе используется плагин версии памяти (qwen-flash). + - type: Оптимизация Сервиса + changedInfo: + - Оптимизация и улучшение задач планирования, улучшение использования памяти. + + - name: v2.0.9 + date: 2026-03-16 + changedInfo: + Improvements: + - type: Совместимость Версий Памяти с Обратной Связью + changedInfo: + - При обновлении узлов через Feedback используется логика версий памяти, обновления происходят в оригинальном узле, а старое содержимое перемещается в поле history. + - type: Оптимизация Версий Памяти + changedInfo: + - В процессе разрешения конфликтов/объединения дубликатов версия памяти была полностью оптимизирована для "восстановления независимых фактов из прошлых версий", в настоящее время она может более стабильно и точно восстанавливать независимые факты, сохраняя целостность информации о памяти и уменьшая путаницу памяти, вызванную нестабильными ответами модели. + Bug Fixes: + - type: Исправление ошибок параметров версий памяти и других + changedInfo: + - Исправлены несколько ошибок проверки параметров версий памяти, когда ключ пустой после обновления, и ошибка времени обновления. + - type: Исправление проблем с обратной связью + changedInfo: + - Исправлена проблема, когда sources пусты в процессе обратной связи. + - name: v2.0.8 + date: 2026-03-05 + changedInfo: + New Features: + - type: Новые Функции + changedInfo: + - При добавлении памяти автоматически выполняется проверка на конфликты/дубликаты, слияние и архивирование, сохраняется последнее содержимое памяти, а старое содержимое помещается в историческое поле; + Improvements: + - type: Миграция Предпочтений Памяти в Графовую Базу Данных + changedInfo: + - Миграция предпочтений памяти в графовую базу данных, унифицированная с другими типами памяти; + - type: Оптимизация Версий Памяти + changedInfo: + - Функция версий памяти полностью мигрирована на асинхронное выполнение, не влияя на задержку интерфейса addMessage при async_mode=true; + - type: Оптимизация Базы Данных + changedInfo: + - Использование семафоров для реализации детализированного ограничения параллелизма, в сочетании с автоматическим исключением неисправных соединений и управлением жизненным циклом потоков, повышает стабильность системы при высокой конкуренции. + - Оптимизация уровня и содержания журналов, сохранение ключевых исполнительных траекторий, снижение влияния записи журналов на производительность базы данных. + - С помощью триггерного предварительного прогрева горячие данные загружаются в кэш, избегая высокой задержки, вызванной холодным запуском. + Bug Fixes: + - type: Ошибка Быстрого Добавления Памяти + changedInfo: + - При добавлении памяти, если выбрана MultiModalStruct, в режиме fast в некоторых случаях не выполнялась операция embedding, что приводило к тому, что память в быстром режиме не могла быть найдена; + - type: Ошибка Мульти Модальной Памяти + changedInfo: + - Для изображений памяти исправлена ошибка, не интерпретирующая содержимое изображения. + - type: Поиск Памяти + changedInfo: + - Сокращение повторных вызовов get_by_metadata в поиске памяти, что снизило время поиска. + - type: Исправление проблемы с конкурентностью версий памяти. + changedInfo: + - Функция версий памяти теперь обрабатывает несколько запросов add в порядке времени, даже если они поступают в короткий промежуток времени, а не откатывается к игнорированию. + - name: v2.0.7 + date: 2026-02-27 + changedInfo: + Improvements: + - type: Оптимизация Параметров + changedInfo: + - Параметр relativity интерфейсов search и chat, используемый для фильтрации возвращенной памяти по баллу релевантности, теперь имеет значение по умолчанию 0.45. + - type: Оптимизация Логов + changedInfo: + - Перехват некоторых ошибок логов, изменение уровней некоторых логов. + - name: v2.0.6 + date: 2026-02-12 + changedInfo: + New Features: + - type: Оптимизация Поиска + changedInfo: + - На этапе search добавлен поиск по ключевым словам, а relativity по-прежнему использует косинусное сходство векторов. + - Интерфейс Chat добавил поле вывода relativity, пользователи могут использовать relativity для контроля порога поиска в чате. + Bug Fixes: + - type: Исправление Проблем + changedInfo: + - Исправлена ошибка использования поля в фильтрации по порогу предпочтительной памяти. + - Исправлена проблема, из-за которой вызов интерфейса get_memory с параметром filter, одновременно передающим field condition и логические операторы AND/OR/NOT, мог завершиться неудачей или зависанием. + - Исправлены некоторые проблемы с передачей LLM extra body, совместимость с вводом параметра enable thinking для LLM. + - name: v2.0.5 + date: 2026-02-10 + changedInfo: + New Features: + - type: Оптимизация Поиска в Базе Знаний + changedInfo: + - Двунаправленный Поиск: поддержка совместного хранения и поиска "оригинал + память", возможность настройки режима возврата. + - Контекстное Пробуждение: поддержка возврата контекста до и после фрагментов, улучшение семантической связности длинных текстов. + - Точная Фильтрация Релевантности: интерфейс search добавил поле relativity (0~1), поддержка фильтрации низкокачественного возврата по порогу. + - type: MindDock + changedInfo: + - Облачный Сервис Skill: добавлена поддержка облачных сервисов и быстрый доступ. + - Инъекция Prompt в Реальном Времени: динамическая инъекция модуля Skill в чате, реализация взаимодействия между несколькими моделями. + - type: Удаление Памяти MCP + changedInfo: + - При распознавании намерения удаления одновременно вызываются deleteMemory и addFeedback. + Improvements: + - type: Реконструкция Pipeline и Поиска + changedInfo: + - Реконструкция Pipeline: цепочка поиска переработана в четыре этапа: Search -> Enhance -> Rerank -> Filter, управляется единым API. + - Оптимизация Распределения: модульный обработчик задач, исправлены проблемы сериализации Redis Streams и передачи user_context. + - type: Оптимизация Skills + changedInfo: + - Локализация Документации Skills: поддержка локального хранения документации по навыкам и генерация уникального URL, доступного для прямого скачивания через API. + - Оптимизация Генерации Skills: теперь можно генерировать более богатые и полные навыки из исторической информации, добавленной пользователем. + Bug Fixes: + - type: Оптимизация Playground + changedInfo: + - Исправлены известные проблемы с опытом, повышена стабильность среды. + - name: v2.0.4 + date: 2026-01-30 + changedInfo: + New Features: + - type: Основные Возможности + changedInfo: + - Добавлен Skill Memory. + - Добавлена поддержка связанных модулей для функции версий памяти. + - Добавлен интерфейс chat/completions, совместимый с OAI. + Improvements: + - type: Оптимизация Поиска + changedInfo: + - Сокращено дублирование фактической памяти и предпочтительной памяти на этапе поиска. + Bug Fixes: + - type: Исправление Проблем + changedInfo: + - Решена ошибка для новых пользователей Playground. + - Исправлена случайная проблема зависания при добавлении памяти в облачном сервисе. + - Решена проблема эффективности графовой базы данных. + - name: v2.0.3 + date: 2026-01-22 + changedInfo: + New Features: + - type: Документация + changedInfo: + - Документация открытого проекта, исправлены проблемы с форматом, описанием примеров, несоответствием между китайским и английским, добавлены небольшие советы по использованию. + - type: Dashboard + changedInfo: + - База знаний добавила поддержку новых типов файлов, поддержка json, md, xml. + - type: Пример Репозитория GitHub + changedInfo: + - Изменен способ запуска (новый класс server router), удалена ссылка на src/memos/product_api.py. + Improvements: + - type: Открытый Проект + changedInfo: + - Оптимизация добавления текстовой и изображенческой памяти, обработка двух типов информации как одного сообщения. + - Поиск в базе знаний поддерживает поле all. + Bug Fixes: + - type: Открытый Проект + changedInfo: + - Исправлена ошибка вызова при слишком длинном вводе текста для поиска. + + - name: v2.0.2 + date: 2026-01-15 + changedInfo: + New Features: + - type: Выпущено руководство по созданию "Ассистента Вопросов и Ответов Базы Знаний". + changedInfo: + - Обновление официальной документации «Лучшие практики разработки помощника по вопросам на основе и знаний» пошагово обучает вас создавать «MemOS Помощник по Знаниям». + Improvements: + - type: Вызов документов базы знаний + changedInfo: + - Дальнейшее улучшение способности интерфейса поиска памяти к вызову деталей содержания документов базы знаний, оптимизация качества ответов на основе содержания документов. + - type: Механизм памяти инструментов + changedInfo: + - Добавление программного опыта, связанного с вызовами, для повышения вспомогательного эффекта памяти инструментов; + - Сжатие информации схемы инструмента, чтобы избежать повторного добавления ToolSchemaMemory. + - type: Механизм объединения и архивирования фактической памяти + changedInfo: + - В процессе обработки фактической памяти добавлен механизм объединения и архивирования, оптимизированы проблемы повторной записи и повторного вызова памяти, при этом обеспечивается сохранение целостности извлечения. + - type: Интерфейс получения памяти + changedInfo: + - Поддержка возврата памяти инструментов; + - Поддержка возврата памяти при определенных условиях фильтрации для отладки, демонстрации и других сценариев. + Bug Fixes: + - type: Интерфейс получения памяти + changedInfo: + - Исправлена ошибка вызова интерфейса получения памяти, когда входной параметр равен include_preference=False. + + - name: v2.0.1 + date: 2026-01-08 + changedInfo: + New Features: + - type: Запуск интерфейса получения памяти + changedInfo: + - Запуск интерфейса получения памяти, поддержка полного получения пользовательской памяти. + - type: Запуск функции диалога в облачном сервисе + changedInfo: + - Запуск функции диалога в облачном сервисе, одно нажатие для начала диалога «память постоянная». + - type: Обновление Playground + changedInfo: + - Страница управления памятью Playground поддерживает удаление памяти, поддерживает ручное управление пользователем для удаления устаревшей памяти. + Improvements: + - type: Интерфейс удаления памяти + changedInfo: + - Оптимизация интерфейса удаления памяти, поддержка удаления всех типов памяти, включая пользовательскую память, память базы знаний и т.д. + - type: Предпочтительная память + changedInfo: + - Интерфейс feedback добавляет операции обработки обратной связи для предпочтительной памяти. + - type: Оптимизация поиска памяти + changedInfo: + - Интерфейс search поддерживает необязательный параметр удаления дубликатов, поддерживает семантическое удаление дубликатов для повышения разнообразия результатов поиска. + Bug Fixes: + - type: Исправление проблем с kv cache + changedInfo: + - Решение проблемы с ошибками в коде kv cache в новой версии MemOS из-за проблем совместимости. + - type: Исправление проблем с модулем планирования + changedInfo: + - Исправлена ошибка, возникающая при включении локального режима планирования из-за отсутствия конфигурации redis. + + - name: v2.0.0 + date: 2025-12-24 + changedInfo: + New Features: + - type: Способности базы знаний и памяти + changedInfo: + - Добавлена функция базы знаний, поддерживающая создание самосовершенствующейся долгосрочной системы памяти на основе документов и URL. + - type: Обратная связь и управление памятью + changedInfo: + - Добавлена возможность обратной связи и исправления памяти, поддерживающая естественное языковое изменение существующей памяти. + - Добавлен интерфейс удаления памяти, поддерживающий удаление указанной пользовательской памяти по идентификатору памяти. + - MCP добавляет возможности удаления и обратной связи памяти. + - type: Диалог и поиск + changedInfo: + - Добавлен интерфейс чата, поддерживающий ответ на основе исторической памяти. + - Поддержка фильтрации памяти и поиска по пользовательским тегам / информации (облачный сервис и открытый проект). + - type: Мультимодальность и память инструментов + changedInfo: + - Добавлена поддержка памяти инструментов, поддерживающая извлечение и поиск опыта вызовов инструментов. + - Добавлена поддержка памяти для сообщений с изображениями, поддерживающая понимание изображений в диалогах и документах. + Improvements: + - type: Данные и инфраструктура + changedInfo: + - Обновление базового DB, повышение стабильности, управления подключениями и производительности операций с данными. + - type: Модуль планирования + changedInfo: + - Реконструкция системы планирования, внедрение Redis Streams и механизма изоляции многоуровневых очередей. + - Добавлены приоритет задач, автоматическое восстановление и возможности распределения квот. + - type: Развертывание и инженерия + changedInfo: + - Добавлен легковесный режим развертывания, поддерживающий два варианта развертывания: быстрый и полный. + Bug Fixes: + - type: Планирование памяти и задачи обновления + changedInfo: + - Исправлена проблема совместимости старого интерфейса планирования памяти, обеспечивающая правильную изоляцию пользовательской памяти. + - Исправлен аномальный журнал задач обновления памяти, обеспечивающий нормальное отображение новой памяти. + + - name: v1.1.3 + date: 2025-11-05 + changedInfo: + New Features: + - type: Добавление и Извлечение Памяти + changedInfo: + - Добавлен Асинхронный Режим Добавления (Поддержка Открытого Текста и Предпочтений) + - Поддержка Полной Цепочки Памяти Предпочтений + - Введение Набора Стратегий Reranker + - TreeTextMemory Поддерживает Алгоритм Извлечения BM25 + - type: Модуль планирования + changedInfo: + - Модульная Реконструкция API Диспетчеризации + - Оптимизация Redis ORM для Исторической Синхронизации и Гибридного Поиска + - type: Данные и инфраструктура + changedInfo: + - PolarDB Графовый Бэкенд Добавляет Пул Соединений и Контроль Времени Ожидания и Исправляет Связанные Проблемы + - Унифицированная Графовая Фабрика (Поддержка Neo4j / PolarDB / Nebula) + - Оптимизация Интерфейса Milvus и Структуры Данных + - Усиление Логов и Мониторинговой Информации + - Динамическое Управление Конфигурацией на Основе Nacos + - type: Оценочная Система + changedInfo: + - Стандартизация Поля PrefEval + - Обновление Процесса Оценки LoCoMo / LongMemEval / PrefEval / PersonaMem + Improvements: + - type: Открытый Текст Памяти + changedInfo: + - Стандартизация Полей Предпочтений + - type: Проектная Структура + changedInfo: + - Обновление Модуля Маршрутизации API + - Усиление Обработки Ошибок и Стабильности Отслеживания Контекста + Bug Fixes: + - type: Модуль планирования + changedInfo: + - Исправление Проблемы Граничных Условий Диспетчеризации Запросов + - Исправление Проблемы Schema Очереди Сообщений + - type: Открытый Текст Памяти + changedInfo: + - Исправление Ошибок, Связанных с Базой Данных PolarDB + - type: Проектная Структура + changedInfo: + - Исправление Аномалий Списка Пользователей SQLite + - name: v1.1.1 + date: 2025-09-25 + changedInfo: + New Features: + - type: Выпуск Бета-версии Облачного Сервиса 1.0 + changedInfo: + - 🛠️ Готово к Использованию: Без Сложной Установки, Прямое Подключение через Облачный API + - 🔄 Межсессионная Память: Автоматический Вызов Профиля Пользователя, Предпочтений, Поведения для Обеспечения Непрерывной Персонализации + - 📖 Удобно для Разработчиков: Документация, Примеры Кода Полностью Поддерживаются + - 🎁 Бесплатная Квота: Каждый Разработчик Может Получить Базовую Квоту для Удобного Исследования + - type: Корпоративный Чат-бот для Вопросов и Ответов + changedInfo: + - Поддержка Вопросов и Ответов из Облачной Базы Знаний + - name: v1.0.1 + date: 2025-09-10 + changedInfo: + New Features: + - type: Корпоративный Чат-бот для Вопросов и Ответов + changedInfo: + - Запуск Чат-бота для Ответов на Вопросы на Основе MemOS Cube + - type: Оптимизация Производительности KV-Cache + changedInfo: + - Обновление Данных Сравнительных Экспериментов KV-Cache на Разных GPU + - Оптимизация Тестового Бенчмарка и Статистических Методов + - type: Усиление Открытого Текста Памяти + changedInfo: + - Добавление Функции Сортировки Reranker для Открытого Текста Памяти + - type: Обновление Playground + changedInfo: + - Обновление Версии PlayGround, Синхронное Обновление Вышеуказанных Новых Функций + Improvements: + - type: Оптимизация Открытого Текста Памяти + changedInfo: + - Оптимизация Проблемы Иллюзий Открытого Текста Памяти + - name: v1.0.0 + date: 2025-08-07 + changedInfo: + New Features: + - type: Playground + changedInfo: + - Открытие Функции Playground и Оптимизация Эффективности Алгоритма; + - type: Создание MemCube + changedInfo: + - Добавление Демонстрационной Игры на Основе Романа MemCube + - type: Расширение Оценочного Набора + changedInfo: + - Добавление Результатов Оценки LongMemEval и Скрипта Оценки; + Improvements: + - type: Функция Открытого Текста Памяти + changedInfo: + - Подключение Интернет-Поиска к BoCha; + - Добавление Поддержки Базы Данных Nebula; + - Добавление Функции Понимания Контекста для Интерфейса Поиска Деревообразной Открытой Памяти; + Bug Fixes: + - type: Сшивание KV Cache + changedInfo: + - Исправить метод concat_cache; + - type: Открытый Текст Памяти + changedInfo: + - Исправить проблемы, связанные с поиском в nebula; + - name: v0.2.2 + date: 2025-07-29 + changedInfo: + New Features: + - type: Открытый Текст Памяти + changedInfo: + - Реализовать доступ к интернет-поиску и поддержку базы данных Nebula + - Усилить способность понимания контекста извлечения памяти + - Запустить интерфейс интернет-поиска и подключить memreader для обработки интернет-сообщений + - type: KV Cache + changedInfo: + - Провести оценку KV Cache, включая детальное исследование LMCache и тестирование производительности + - Завершить стресс-тестирование MemOS vllm (версия 0.2.1) в определенных условиях и моделях + - Уточнить тестовые данные ttft для предзагрузки KV Cache на модели Qwen2.5-72B-Instruct и добавить в отчет + - Совместно с отечественным оборудованием завершить исследование и проектирование первой версии системы высоко ROI вывода + - type: Модель операций памяти + changedInfo: + - Завершить оценку обучения модели и выпустить + - Выпустить модели 4b, 1.7b, 0.6b, поддерживающие извлечение и интеграцию памяти + Improvements: + - type: Документация + changedInfo: + - Добавить английскую версию первых трех глав Cookbook + - type: Планирование памяти + changedInfo: + - Начать работу по рефакторингу кода и улучшению функциональности + - Рефакторинг функциональных модулей monitor, dispatcher, retriever и др. + - Добавить код для больших категорий schemas и utils + - Усовершенствовать функцию печати сетевых логов + - Усилить надежность планировщика, добавить декоратор для захвата исключений + - Заблокировать некоторые общие ресурсы + - type: Разработка среды + changedInfo: + - Обновить конфигурацию Docker + - Обновить конфигурацию dim среды + - type: Усиление API + changedInfo: + - Добавить поддержку контекста playground + - Усилить функциональность API продукта + - Переписать модуль запросов + - Добавить функцию истории чата + Bug Fixes: + - type: Парсинг данных + changedInfo: + - Исправить ошибку парсинга даты + - Исправить проблему с примером кода memos_w_scheduler + - Исправить баг точного поиска в графовой базе данных Nebula + - Исправить логику получения фильтра metadata + - type: Системная интеграция + changedInfo: + - Согласовать подпись MOSProduct._build_system_prompt с MOSCore + - type: Открытый Текст Памяти + changedInfo: + - Исправить логику обработки общего текстового запоминания + - Исправить проблему с компонентом memreader + + - name: v0.2.1 + date: 2025-07-21 + changedInfo: + New Features: + - type: Функциональность MemCube + changedInfo: + - Добавить функцию открытой памяти + KV Cache, предоставить отчет о производительности декодирования推理 + - Завершить разработку интересной функции cube, успешно пройти полный процесс, поддерживать переключение моделей embedding + - type: Система MemOS + changedInfo: + - Выпустить легковесную версию MemOS Neo, упростить архитектуру, оставить только основные модули API + - Добавить поддержку MCP, расширить возможности MCP + - Создать документацию Pipeline для потока встраивания Agent, поддерживать интеграцию с Coze + - type: Развертывание и поддержка среды + changedInfo: + - Добавить поддержку развертывания Docker + - Поддержка многомодельных вызовов на уровне API, совместимость с основными моделями OpenAI/Qwen/DeepSeek и др. + - Усовершенствовать поддержку моделей embedding + - Добавить поддержку neo4j Community Edition/Nebular базы данных + - Добавить поддержку архитектуры многопользовательской базы данных + - type: Оценка и Тестирование + changedInfo: + - Адаптация Формата API Интерфейса MemOS для Оценки, Обновление Оценочного Кода + - type: Документация и Примеры + changedInfo: + - Добавлено Содержимое Cookbook + - Добавлен Пример Игры Mud + + - name: v0.2.0 + date: 2025-07-11 + changedInfo: + New Features: + - type: Обновление Удобства Использования Официального Сайта + changedInfo: + - Добавлена Функция Поискового Поля в Документации + - Добавлена Функция Переключения Между Русским и Английским Документами + - Добавлены Ссылки для Переключения в Подвале и Редактирования Страницы + - type: Модель Оператора + changedInfo: + - Добавлена Модель MemReader-4B, Сосредоточенная на Операциях Извлечения Памяти + - Поддержка Чисто Локального Развертывания, Подходит для Ограниченных Сетевых Условий + - Реализация Более Низкой Стоимости и Более Быстрой Скорости Операций Памяти, Производительность Превышает GPT-4o-mini + - Настройка на Основе Qwen3-4b, Совмещение Данных Ручной Разметки и Модельной Разметки для Супервизионной Настройки + - type: Кроссплатформенная Адаптация Фреймворка + changedInfo: + - Добавлена Адаптация для Развертывания на Платформе Windows + - Добавлена Адаптация для Развертывания на Платформе Mac + - Завершена Адаптация для Трех Основных Операционных Систем: Linux, Windows, macOS + - Тестирование на Платформах Ubuntu 20.04+/CentOS, Windows 10+/11, macOS 14 Ventura+ и др. + - Поддержка Стабильной Работы Основных Модулей (Управление Жизненным Циклом Памяти, Протокол Взаимодействия MIP, Планирование Кэша Памяти и др.) + - type: Прогресс Playground + changedInfo: + - Завершена Интеграция Инженерной, Фронтенд и Алгоритмической Частей, Ведется Исправление Ошибок и Оптимизация diff --git a/content/ru/mcp_agent/agent/guide.md b/content/ru/mcp_agent/agent/guide.md new file mode 100644 index 00000000..bfcfc4e2 --- /dev/null +++ b/content/ru/mcp_agent/agent/guide.md @@ -0,0 +1,81 @@ +--- +title: Руководство По Использованию +desc: Плагины, размещенные в магазине, напрямую обращаются к интерфейсу облачного сервиса MemOS, быстро добавляя функции долгосрочной памяти для вашего Агента, делая диалоги более заботливыми и непрерывными. +--- + +## Плагины Платформы Coze + +### 1. Информация О Размещении Плагина + +Плагин интерфейса облачного сервиса MemOS уже доступен в магазине Coze! Вы можете напрямую [перейти по ссылке на инструмент](https://www.coze.cn/store/plugin/7569918012912893995?from=store_search_suggestion) для добавления плагина и реализации интеграции без кода. + +### 2. Описание Плагина + +#### Функции Плагина + +* `search_memory`: Этот инструмент используется для запроса данных памяти пользователя и может вернуть наиболее релевантные фрагменты к введенному запросу. Поддерживает实时检索 памяти во время диалога пользователя с ИИ, а также может выполнять глобальный поиск по всей памяти, что может быть использовано для создания профиля пользователя или поддержки персонализированных рекомендаций. При запросе необходимо предоставить параметры, такие как ID диалога, ID пользователя, текст запроса и т.д., также можно установить количество возвращаемых элементов памяти. + +* `add_memory`: Этот инструмент позволяет массово импортировать одно или несколько сообщений в базу данных памяти MemOS, что упрощает поиск в будущих диалогах, поддерживая управление историей чата, отслеживание поведения пользователей и персонализированное взаимодействие. При использовании необходимо указать информацию, такую как ID диалога, содержание сообщения, роль отправителя, время диалога и ID пользователя. + +#### Описание Интерфейса + +* search_memory интерфейс + +| Параметр Название | Параметр Тип | Описание | Обязателен | +| --- | --- | --- | --- | +| memory_limit_number | string | Ограничение на количество возвращаемых элементов памяти, если не указано, по умолчанию 6 | Нет | +| memos_key | string | Авторизационный ключ MemOS облачного сервиса | Да | +| memos_url | string | URL адрес MemOS облачного сервиса | Да | +| query | string | Ввод пользователя | Да | +| user_id | string | Уникальный идентификатор пользователя, связанный с запрашиваемой памятью | Да | + +* add_memory интерфейс + +| Параметр Название | Параметр Тип | Описание | Обязателен | +| --- | --- | --- | --- | +| conversation_id | string | Уникальный идентификатор разговора | Да | +| memos_key | string | Авторизационный ключ MemOS облачного сервиса | Да | +| memos_url | string | URL адрес MemOS облачного сервиса | Да | +| messages | Array | Массив объектов сообщений | Да | +| user_id | string | Уникальный идентификатор пользователя, связанный с запрашиваемой памятью | Да | + +### 3. Примеры Вызова Агентом + +#### Примеры Разработки Персонажа Агента И Логики Ответов +``` +Вы — робот для вопросов и ответов, который каждый раз читает память и интересы пользователя и отвечает с очень ясной логикой, чтобы завоевать симпатию пользователя. + +## Содержимое Рабочего Процесса +# 1. Доступ к {search_memory} для извлечения данных + Каждый раз после того, как пользователь говорит, сначала вызывается функция поиска в памяти MemOS -- {search_memory} плагин, вводя информацию: + Запишите имя пользователя как user_id, если это первый доступ, установите user_id как случайно сгенерированную 16-значную строку UUID. + Используйте содержание речи пользователя в качестве query +# 2. Обработка {search_memory} Выходных Данных: + Получите данные, и если в них есть поле memory_detail_list, независимо от того, пуст ли список memory_detail_list, сразу выведите его в формате json; если возвращаемое сообщение не равно ok, то сообщите "Ошибка поиска плагина". +# 3. Ответьте на вопросы пользователя, используя найденный memory_detail_list + Извлеките значение поля memory_value для каждого элемента в memory_detail_list и соедините все строки с помощью "\n" в качестве контекста для ответа на вопрос пользователя; большой модель может ответить на запрос пользователя, основываясь на информации, предоставленной в контексте; если контекстная информация пустая строка, большая модель может просто ответить на запрос пользователя. + Затем запишите содержание ответа большой модели в answer. +# 4. Доступ к {add_memory} для хранения данных + Вызовите функцию add_memory, чтобы сохранить вопрос пользователя и соответствующий ответ, вводя информацию: + chat_time: Вызовите {current_time}, чтобы получить текущее время, отформатируйте временную метку в формате "%I:%M %p on %d %B, %Y UTC" + conversation_id: Запишите текущее время chat_time с точностью до минут, строка времени будет использоваться как conversation_id + user_id: Запишите имя пользователя как user_id + messages: Запишите введенный пользователем query и все полученные ответы answer как content в role и assistant соответственно, chat_time используйте только что полученное значение chat_time, организуйте это в одну запись messages: + [ + {"role": "user", "content": query, "chat_time": chat_time}, + {"role": "assistant", "content": answer, "chat_time": chat_time} + ] + Получите обратную связь от плагина {add_memory}, если поле success в data равно True, то это успешно, *не нужно сообщать пользователю*; если возвращаемое поле не равно True, сообщите пользователю, что доступ к add_memory не удался. + +## Требования +Каждый раз, когда вы обращаетесь к {search_memory} и {search_memory}, необходимо передавать два фиксированных параметра: +memos_url = "https://memos.memtensor.cn/api/openmem/v1" +memos_key = "Token mpg-XXXXXXXXXXXXXXXXXXXXXXXXXXX" + +Ваш персонаж — это мудрый и заботливый помощник по памяти, его зовут 小智. +Если все плагины работают без сбоев, в ответах большой модели не нужно уведомлять пользователя о том, что все прошло успешно. +Только при первом диалоге с пользователем сгенерируйте user_id с помощью UUID, этот user_id будет использоваться в дальнейшем. +``` + +[Пример агента](https://www.coze.cn/s/85NOIg062vQ) +![Рабочий процесс агента](https://cdn.memtensor.com.cn/img/coze_workflow_compressed.png) diff --git a/content/ru/mcp_agent/mcp/guide.md b/content/ru/mcp_agent/mcp/guide.md new file mode 100644 index 00000000..dc08b449 --- /dev/null +++ b/content/ru/mcp_agent/mcp/guide.md @@ -0,0 +1,171 @@ +--- +title: MCP Сервис Конфигурация +desc: MemOS предоставляет способ взаимодействия с облачной платформой через MCP, разработчики могут использовать услуги облачной платформы MemOS на различных клиентах (Claude, Cursor, Cline и т.д.). +--- + +## 1. Сервис Введение + +MemOS управление памятью MCP — это мощный плагин, который позволяет пользователям получать доступ к функциям добавления, поиска, удаления и обратной связи с памятью MemOS, обеспечивая доступ к содержимому диалога и предоставляя пользователям эффективные услуги управления памятью, что способствует повышению согласованности и персонализации взаимодействия пользователя с ИИ. + +## 2. Ссылки на Инструменты +* [npm пакет](https://www.npmjs.com/package/@memtensor/memos-api-mcp) +* [Github](https://github.com/MemTensor/memos-api-mcp) + + +## 3. Взаимодействие с Облачной Платформой MemOS через MCP + +Заполните следующую конфигурацию в клиенте: + +```json +{ + "mcpServers": { + "memos-api-mcp": { + "timeout": 60, + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@memtensor/memos-api-mcp@latest" + ], + "env": { + "MEMOS_API_KEY": "mpg-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "MEMOS_USER_ID": "your-user-id", + "MEMOS_CHANNEL": "MODELSCOPE" + } + } + } +} +``` + +Способы получения переменных окружения: +- `MEMOS_API_KEY`: Зарегистрируйте аккаунт на официальном сайте MemOS [API Консоль](https://memos-dashboard.openmem.net/cn/apikeys/), затем создайте api-key на странице ключей API и скопируйте его сюда. + +![Создание нового api-key в MemOS API консоли](https://cdn.memtensor.com.cn/img/1763452232848_t268eh_compressed.png) + +- `MEMOS_USER_ID`: Определяемый пользователем индивидуальный идентификатор. + - Для одного и того же пользователя эта переменная окружения должна оставаться одинаковой на разных устройствах/клиентах; + - Пожалуйста, не используйте случайные значения, идентификаторы устройств или идентификаторы сеансов чата в качестве идентификатора пользователя; + - Рекомендуется использовать: личный адрес электронной почты, полное имя или идентификатор сотрудника в качестве идентификатора пользователя. + +- `MEMOS_CHANNEL`: Заполните как "MODELSCOPE". + +## 4. Использование MemOS MCP на Разных Клиентах + +### Использование на Claude Desktop + +Чтобы использовать MemOS на Claude Desktop, необходимо нажать на аватар в левом нижнем углу -> "Настройки" -> "Разработчик" -> "Редактировать Конфигурацию", и вставить конфигурацию в файл Claude_desktop_config.json, затем перезапустите клиент, и когда вы увидите, что служба memos-api-mcp находится в состоянии работы, вы сможете использовать ее в чате. + +![Использование MemOS-верификации в Claude](https://cdn.memtensor.com.cn/img/1763105334517_9ayhrp_compressed.png) + +Для повышения эффективности использования рекомендуется пользователям изменить настройки предпочтений пользователя, которые применяются ко всем диалогам, когда они используют MemOS на Claude Desktop, конкретный метод: нажмите на аватар в левом нижнем углу -> "Общие", в поле ввода под "Какие личные предпочтения должен учитывать Claude в ответах?" вставьте следующее содержимое: + +``` +Вы являетесь помощником по управлению памятью MemOS, который стремится предоставить эффективные услуги управления памятью, извлекая воспоминания на основе предыдущего диалога пользователя и повышая согласованность и индивидуализацию общения пользователя с AI через поиск памяти. Перед тем как ответить на вопрос пользователя, вам необходимо вызвать сервис search_memory из memos-api-mcp, используя подходящие ключевые слова для поиска воспоминаний, связанных с текущей темой, в личной памяти пользователя. После завершения ответа на основе этих воспоминаний, снова вызовите сервис add_message из memos-api-mcp, чтобы записать краткое содержание текущего диалога. (Обратите внимание, что вызов add_message является обязательным, независимо от того, что сказал пользователь или какой вопрос он задал, это необходимо записать, иначе в последующих диалогах search_memory не сможет получить более детальную информацию о пользователе, что приведет к тому, что вы не сможете точно ответить на вопросы пользователя.) +``` + +![Изменение пользовательских предпочтений в MemOS на Claude Desktop](https://cdn.memtensor.com.cn/img/1763105396189_i1tupr_compressed.png) + +Ниже приведен пример использования MemOS на Claude Desktop, пользователи могут использовать его, чтобы определить, успешно ли они настроили MemOS на Claude Desktop. + +![Пример использования MemOS на Claude Desktop](https://cdn.memtensor.com.cn/img/1763105412700_asgfq9_compressed.png) + +### Использование на Cursor +Чтобы использовать MemOS на Cursor, необходимо перейти в "Настройки Cursor" -> "Инструменты и MCP" -> "Добавить Пользовательский MCP" (или "Новый MCP Сервер"), и вставить конфигурацию в открывшуюся страницу редактирования mcp.json, когда вы увидите, что memos-api-mcp находится в состоянии запуска, и сможете увидеть "add_message", "search_memory" и другие инструменты на странице деталей инструмента, вы сможете использовать их в панели чата Cursor. + +![Использование MemOS в Cursor](https://cdn.memtensor.com.cn/img/1763105278297_n23ukk_compressed.png) + +Для повышения эффективности использования рекомендуется пользователям изменить Правила Пользователя, когда они используют MemOS на Cursor, конкретный метод: перейдите в "Настройки Cursor" -> "Правила, Память, Команды" -> "Правила Пользователя" -> "+ Добавить Правило", затем скопируйте и вставьте следующее содержимое и сохраните: +``` +Вы являетесь помощником по управлению памятью MemOS, который стремится предоставить эффективные услуги управления памятью, извлекая воспоминания на основе предыдущего диалога пользователя и повышая согласованность и индивидуализацию общения пользователя с AI через поиск памяти. Перед тем как ответить на вопрос пользователя, вам необходимо вызвать сервис search_memory из memos-api-mcp, используя подходящие ключевые слова для поиска воспоминаний, связанных с текущей темой, в личной памяти пользователя. После завершения ответа на основе этих воспоминаний, снова вызовите сервис add_message из memos-api-mcp, чтобы записать краткое содержание текущего диалога. (Обратите внимание, что вызов add_message является обязательным, независимо от того, что сказал пользователь или какой вопрос он задал, это необходимо записать, иначе в последующих диалогах search_memory не сможет получить более детальную информацию о пользователе, что приведет к тому, что вы не сможете точно ответить на вопросы пользователя.) +``` + +![Использование MemOS в Cursor - настройка правил пользователя](https://cdn.memtensor.com.cn/img/1763105535408_2xtvd3_compressed.png) + +Ниже приведен пример использования MemOS на Cursor, пользователи могут использовать его, чтобы определить, успешно ли они настроили MemOS на Cursor. + +![Использование MemOS в Cursor - пример использования](https://cdn.memtensor.com.cn/img/1763105558821_imga5z_compressed.png) + +### Использование на Visual Studio Code или Trae +Чтобы использовать MemOS в VS Code или Trae, необходимо установить расширение Cline и настроить модель, затем нажмите на значок "MCP Servers" в правом верхнем углу панели Cline -> "Настроить" -> "Настроить MCP Серверы", и вставьте конфигурацию в файл cline_map_settings.json, когда вы увидите, что memos-api-mcp находится в состоянии запуска, вы сможете использовать его в агенте Cline. Также рекомендуется включить переключатель `Auto-approve` для каждого инструмента, чтобы избежать запроса агента перед каждым вызовом инструмента, что сделает использование более плавным. + +![Использование MemOS в Cline - Процесс Настройки](https://cdn.memtensor.com.cn/img/1763105573529_oo765m_compressed.png) + +Для повышения эффективности использования рекомендуется пользователям изменить глобальные правила, когда они используют MemOS в Cline, конкретный метод: нажмите на значок "Управление Правилами и Рабочими Процессами Cline" в левом нижнем углу панели Cline -> нажмите на значок "+" справа под Глобальными Правилами -> введите имя файла правил, например, "memos_rules.md" -> скопируйте и вставьте следующее содержимое в открывшемся редакторе: + +```markdown +# 🧠 MemOS Automatic Memory System — Mandatory Usage + +## ⚠️ Always-On (No User Opt-In Required) +This system must run **automatically for every turn**. Do **not** wait for the user to say “use memory”, “use MCP”, or “call a tool”. The **client/orchestrator is responsible** for auto-invoking the tools. + +## 🎯 Mandatory 3-Step Workflow (Enforced by Client Each Turn) +\`\`\` +Every user message + → 1) 🔍 search_memory (AUTO, before answering) + → 2) 💬 Answer (use only relevant memories; ignore noise) + → 3) 💾 add_message (AUTO, after answering) +\`\`\` + +### 1) 🔍 Search Memory (Auto-invoked BEFORE answering) +- **Trigger**: Must be auto-called **before** generating any answer (including simple greetings). +- **Tool**: `search_memory` + +**Relevance rule**: The model must judge relevance and **only use relevant** memories. If results are irrelevant or noisy, **ignore them** and proceed. + +### 2) 💬 Answer +Use retrieved memories **only if relevant**. If none are relevant, answer normally. + +### 3) 💾 Save Conversation (Auto-invoked AFTER answering) +- **Trigger**: Must be auto-called after producing the final answer on **every turn**. +- **Tool**: `add_message` + +**Purpose**: Persist Q&A for future personalization and continuity — even if no memory was used this turn. + +## ✅ Non-Negotiable Client Responsibilities +1. **Auto-invoke** `search_memory` before **every** answer and `add_message` after **every** answer. +2. **No user opt-in**: Do not wait for the user to mention memory/tools/MCP. +3. **Store both user and assistant** messages every turn. +4. **Sequence** must be strictly: Search → Answer → Save. +``` + +![Использование MemOS в VS Code или Trae - Изменение Global Rules](https://cdn.memtensor.com.cn/img/1763105598614_p0drfo_compressed.png) + +Ниже приведен пример использования MemOS в Cline, пользователи могут использовать его, чтобы определить, успешно ли они настроили MemOS в Cline. + +![Пример Использования MemOS в Cline](https://cdn.memtensor.com.cn/img/1763105618134_ggy3m0_compressed.png) + +### Использование в [Chatbox](https://chatboxai.app/zh) +Чтобы использовать MemOS в Chatbox, необходимо нажать в левом нижнем углу "Настройки" -> "MCP" -> "Настроить MCP-сервер - Добавить сервер" -> "Добавить пользовательский сервер", и добавить сервис memos-api-mcp согласно приведенной ниже конфигурации. +``` +Название: MemOS Ассистент Управления Памятью +Тип: Локальный (stdio) +Команда: npx -y @memtensor/memos-api-mcp@latest +Переменные Среды: +MEMOS_API_KEY= +MEMOS_USER_ID= +``` +После заполнения нажмите "Тест", если в нижней части диалогового окна вы увидите несколько инструментов, таких как "add_message", "search_memory" и т.д., это означает, что конфигурация прошла успешно. + +![Использование MemOS в Chatbox - Проверка](https://cdn.memtensor.com.cn/img/1763105637530_f98hyr_compressed.png) + +Чтобы улучшить эффективность использования, рекомендуется пользователям изменить system_prompt при использовании MemOS в Chatbox, конкретный способ: левый нижний угол "Настройки" -> "Настройки диалога" -> "Настройки по умолчанию для нового диалога", и изменить prompt следующим образом: + +``` +Вы являетесь помощником по управлению памятью MemOS, который стремится предоставить эффективные услуги управления памятью, извлекая воспоминания на основе предыдущего диалога пользователя и повышая согласованность и индивидуализацию общения пользователя с AI через поиск памяти. Перед тем как ответить на вопрос пользователя, вам необходимо вызвать сервис search_memory из memos-api-mcp, используя подходящие ключевые слова для поиска воспоминаний, связанных с текущей темой, в личной памяти пользователя. После завершения ответа на основе этих воспоминаний, снова вызовите сервис add_message из memos-api-mcp, чтобы записать краткое содержание текущего диалога. (Обратите внимание, что вызов add_message является обязательным, независимо от того, что сказал пользователь или какой вопрос он задал, это необходимо записать, иначе в последующих диалогах search_memory не сможет получить более детальную информацию о пользователе, что приведет к тому, что вы не сможете точно ответить на вопросы пользователя.) +``` + +![Изменение system_prompt при использовании MemOS в Chatbox](https://cdn.memtensor.com.cn/img/1763105656492_ky1wbw_compressed.png) + +Ниже приведен пример использования MemOS в Chatbox, пользователи могут использовать его, чтобы определить, успешно ли они настроили MemOS в Chatbox. + +![Использование MemOS в Chatbox - Пример Эффекта](https://cdn.memtensor.com.cn/img/1763105677226_cygzzf_compressed.png) + + +## 5. Q&A +В: Иногда возникает ситуация, когда агент не использует инструменты в сценах, где это необходимо? + +О: Из-за различий в используемых базовых моделях, разные агенты имеют разный уровень навыков в использовании инструментов. Когда агент забывает использовать инструмент, можно направить модель с помощью команды для вызова соответствующего инструмента или попробовать использовать другую базовую модель. + +## 6. Свяжитесь с нами + +![image.png](https://cdn.memtensor.com.cn/img/1758685658684_nbhka4_compressed.png) diff --git a/content/ru/memos_cloud/cloud_and_opensource.md b/content/ru/memos_cloud/cloud_and_opensource.md new file mode 100644 index 00000000..555bc52c --- /dev/null +++ b/content/ru/memos_cloud/cloud_and_opensource.md @@ -0,0 +1,111 @@ +--- +title: Облачная Платформа И Открытые Решения +desc: Полное сравнение MemOS облачных услуг и открытых фреймворков, чтобы помочь вам сделать наилучший выбор технологии. +--- + +::note +**Подсказка**
Перед тем как написать первую строку кода, вы можете быстро испытать эффект "памяти", используя **MemOS Playground**.
+ +* **Не требует установки**: просто откройте в браузере и используйте
+ +* **Реальное взаимодействие**: общайтесь как с обычным Chatbot, но система будет автоматически запоминать, что вы говорили
+ +* **Визуальная память**: вы можете видеть, какие данные были обработаны в память, как они были распределены и вызваны
+ +* **Многоуровневое тестирование**: поддерживает многоуровневое тестирование непрерывного диалога в Playground, чтобы проверить долговечность памяти
+ +👉 [Немедленно Попробуйте Playground](https://memos-playground.openmem.net/) +:: + +::warning +**Внимание**
Playground предназначен только для демонстрации, данные не будут сохраняться. Для официального подключения используйте MemOS облачную платформу или открытое решение. +:: + + +## 1. Наилучшее решение MemOS для вас + +MemOS предлагает **два** решения для "памяти" для AI приложений, удовлетворяющие всем требованиям от быстрой проверки до развертывания на уровне производства: + +* MemOS облачная платформа — упрощает разработку, легкое управление: использование облачных услуг за 5 минут, подходит для быстрой настройки и итерации AI приложений. + +* MemOS открытое решение — самостоятельное развертывание, полный контроль: развертывание в собственную среду, доработка и глубокая интеграция в зависимости от бизнес-требований. + +* **Гибридный режим развертывания** — гибкое сочетание: локализация основных бизнес-данных, подключение к облаку для несекретных сценариев, соблюдение норм и снижение затрат. + +> _Независимо от того, облачные услуги или открытые фреймворки, MemOS позволяет вашему AI легко получать долговременную память._ + + +## 2. Сравнение функций + +| Функция | MemOS Облачная Платформа | MemOS Открытое Решение | +|------|-------------|--------------| +| Сложность Развертывания | Очень Низкая, 5 Минут Для Запуска | Необходимо Настроить Среду | +| Место Хранения Данных | В Облаке (возможна приватизация) | Полностью Локально | +| Бесплатный Лимит | Есть | Без Ограничений (самостоятельный хостинг) | +| Пользовательский LLM | Поддержка Основных Моделей | Любая Модель | +| Мониторинг и Логи | Встроенная Консоль | Необходимо Интегрировать Самостоятельно | +| Гарантия SLA | Есть | Нет | +| Поддержка Сообщества | Есть | Есть | +| Коммерческая Поддержка | Есть | Нет | + + +## 3. Руководство по выбору + +### Выбор MemOS облачной платформы + +* **Быстрое развертывание**: всего за несколько минут ваш AI приложение будет иметь встроенную память. Вы можете сосредоточиться на бизнес-логике и реализации функций, не тратя время на поддержку сложной системы хранения и управления памятью. + +* **Нулевая стоимость проверки**: предоставляется достаточный объем бесплатного пробного использования, чтобы помочь вам проверить жизнеспособность решения и эффективность продукта с минимальными затратами. + +* **Логи и мониторинг**: в консоли можно в реальном времени просматривать журналы вызовов, получать полный анализ цепочки вызовов, что упрощает отладку, мониторинг и оптимизацию производительности. + +### Выбор MemOS открытого решения + +* **Суверенитет данных**: все данные памяти хранятся в вашей частной среде, соответствуют строгим требованиям к соблюдению данных. + +* **Настраиваемая конфигурация**: можно свободно выбирать поставщика LLM, бэкенд вывода, стратегию развертывания и т.д., обеспечивая большую гибкость и контроль. + +* **Расширение кода**: можно напрямую изменять кодовую базу, по мере необходимости расширять настраиваемые функции и вносить улучшения в сообщество. + +* **Оффлайн развертывание**: поддерживает полностью оффлайн среду, подходит для сценариев с требованиями к изоляции сети. + +### Сценарии, не подходящие для открытого решения + +> _Если в вашей команде нет штатных специалистов по эксплуатации, или проект находится на ранней стадии проверки, рекомендуется в первую очередь использовать облачную платформу._ + + +## 4. Пример быстрого подключения + +Подключение к облачной платформе занимает всего три шага: + +```python +from memos import MemOSClient + +# 1. Инициализация Клиента +client = MemOSClient(api_key="your_api_key") + +# 2. Создание Памяти Пользователя +client.memory.add( + user_id="user_123", + content="Предпочтения Пользователя: Нравится Лаконичный Стиль Ответов" +) + +# 3. Восстановление Связанных Памятей +memories = client.memory.search( + user_id="user_123", + query="Предпочтения Пользователя К Ответам" +) +``` + + +## 5. Все еще не уверены? + +* [Попробуйте бесплатную платформу](/memos_cloud/quick_start): зарегистрируйтесь и войдите в [MemOS облачную платформу](https://memos-dashboard.openmem.net/quickstart), чтобы бесплатно протестировать все функции. + +* [Изучите открытое решение](/open_source/getting_started/quick_start): клонируйте репозиторий проекта и запустите его локально для тестирования. + +* [Присоединяйтесь к сообществу](https://discord.gg/memos): общайтесь с другими разработчиками в сообществе Discord о выборе технологий. + +::tip +**Небольшой совет**: не уверены, как выбрать? Сначала используйте облачную платформу для проверки POC, подтвердите жизнеспособность решения, а затем при необходимости мигрируйте на локальное развертывание. API интерфейсы обоих решений остаются совместимыми, затраты на миграцию крайне низки. +:: diff --git a/content/ru/memos_cloud/faq.md b/content/ru/memos_cloud/faq.md new file mode 100644 index 00000000..471e2801 --- /dev/null +++ b/content/ru/memos_cloud/faq.md @@ -0,0 +1,111 @@ +--- +title: FAQs +desc: Мы сосредоточили самые распространенные вопросы, возникающие в процессе использования MemOS, чтобы вы могли быстро найти ответы, не перел翻资料. +--- + + +### Q:MemOS и обычный RAG фреймворк有什么区别? + +| **Сравнительные Параметры** | **RAG** | **MemOS** | **Преимущества MemOS** | +| --- | --- | --- | --- | +| Точность | Чем больше данных, тем больше шума | Через извлечение на этапе производства, схематизацию/моделирование отношений, в сочетании с управлением расписанием и жизненным циклом, формируется структурированная организация, память становится более четкой

Может эволюционировать на основе обратной связи от пользователей | **Более Точно**: уменьшение шума, снижение иллюзий | +| Организация Результатов | Прямо берется оригинальный абзац, избыточное содержание | Превращение исходной информации в память, извлечение в факты/предпочтения и т.д., содержание становится короче и чище | **Более Экономно**: меньше токенов при равном объеме информации | +| Область Поиска | Каждый раз ищет во всей базе данных, чем больше данных, тем медленнее | Динамическое обновление памяти, иерархическое управление, поэтапный вызов | **Быстрее**: избегает глобального сканирования, попадает в узкую область | +| Понимание | Не может извлекать предпочтения из истории диалогов пользователей (без персонализации), полагается только на статическое сопоставление в базе знаний | Автоматически извлекает память для моделирования предпочтений и преобразует в исполняемые инструкции во время вызова, позволяя модели действительно понять ситуацию. | **Более Понимающий**: ответы ближе к реальным потребностям | + + +### Q:MemOS 可以和已有 RAG 或知识图谱结合吗? + +可以。 +RAG 专注于 **фактический поиск и усиление знаний**,让模型“知道世界上有什么”; +MemOS 专注于 **управление состоянием и непрерывная память**,让模型“知道你是谁、你想要什么”。 + +两者结合后能形成互补的智能结构: + +> 🧠 **RAG 提供外部知识,MemOS 提供内在记忆。** +> 前者让模型更聪明,后者让模型更懂你。 + +在实践中,**MemOS 的记忆单元** 可以与 **RAG 的向量召回层** 直接对接,也能调用外部知识图谱。 +区别在于——RAG 管理的是 **静态事实**,而 MemOS 管理的是 **随时间演化的动态记忆**。 + +换句话说: +- **RAG** 让模型更像百科全书; +- **MemOS** 让模型更像你长期相处的助手。 + +当两者融合时,AI 就既能“知道世界”,也能“理解你”。 + + +### Q:MemOS如何工作? + +我们的云服务平台为您提供了两个核心接口: + +`addMessage` —把原始信息(用户与 AI 的对话、用户在APP上的操作日志 / 行动轨迹等)交给我们,我们自动加工并存储记忆; + +`searchMemory` —在后续对话中召回相关记忆并完成指令拼接(可选),让 AI 回答更贴近用户需求。 + + +### Q:MemOS核心功能有哪些? + +* **Управление памятью пользователя/агента**:支持长期保存用户与 AI 的交互内容,并能在多代理协同场景下共享或隔离记忆,保证任务连续。 + + +* **动态分层调度**:区别于静态 RAG,MemOS 会根据任务优先级在激活记忆、明文记忆之间动态切换,避免全局扫描,让调用更快更准。 + + +* **个性化偏好建模**:自动从历史交互中抽取用户偏好,并在实时生成中补全指令,使模型输出更贴近用户习惯。 + + +* **记忆生命周期治理**:通过合并、压缩、归档机制避免记忆膨胀,长期保持高效而稳定的知识库。 + + +* **开发者友好 API**:开放统一接口,既能调用开源框架,也能直接接入云服务,集成成本低。 + + +* **跨平台一致性**:无论本地部署还是云端托管,都能保持一致的记忆调度行为和数据格式。 + + +* **托管服务支持**:提供云服务托管,内置监控、弹性扩展,降低运维成本。 + + +* **成本节约**:通过记忆加工与优先级调度,只注入必要信息,比直接拼接原文更节省 token。 + + +### Q:如何评估使用 MemOS 带来的 ROI? + +典型指标包括:token 消耗下降(更省)、输出相关度提高(更准)、用户留存率提升(更懂)、知识沉淀率(多少被长期固化)。 + + +### Q:如何进一步提升MemOS在具体业务场景中的的效果? + +您可以联系我们做商业化定制(最快最好),另一方面MemOS本身开源,您的团队可深入研究自行改造(有理解成本可能会走弯路) + + +### Q:MemOS 是否支持私有化部署? +支持 + + +### Q:生命周期和调度有什么关系? +生命周期负责“记忆单元的状态流转”,调度负责“在任意时刻选中合适的记忆单元并送入模型”。两者互补,但不等价 + + +### Q:MemOS 如何避免记忆膨胀? +通过合并、压缩、归档机制:低价值记忆被下调频率,高价值记忆被合并或沉淀。最终保证存储和推理都保持高效。 + + +
+ +**В: Являются ли KV-Cache и активационная память одним и тем же?** +Нет. KV-Cache является реализацией на уровне вычислений, активационная память — это концепция на уровне бизнеса. В настоящее время активационная память в основном зависит от KV-Cache, но в будущем могут быть и другие способы реализации. + + +### В: Замедлит ли MemOS вывод? +Нет. Планировщик работает асинхронно и использует стратегию стабильного кэширования, чтобы обеспечить баланс между обновлением памяти и вызовом. В реальных тестах увеличение задержки обычно находится в пределах допустимого. + + +### В: Нужно ли планировать, если запрашиваемая информация уже близка, например, "вчерашние дела"? +Да. Планирование решает не только проблему "найти", но и проблему "быстро и точно, без избыточности". Даже если время близко, планировщик все равно будет оценивать, нужно ли объединять в полный контекст. + + +### В: Для каких продуктов предназначен MemOS? +В настоящее время MemOS уже применяется в нескольких областях, включая 【сопровождение, игры, туризм, операторов, финансовые рынки, производство и научные исследования】 и т.д. Партнеры включают несколько ведущих государственных и частных компаний, а также ведущие команды в отрасли, связанные проекты уже подтвердили эффективность памяти в таких сценариях, как воплощенный интеллект, AI-обслуживание клиентов, управление знаниями, интеллектуальные инвестиционные консультанты, производственная эксплуатация, AI-сопровождение обучения и т.д. +Некоторые проекты все еще находятся на стадии совместной доработки, поэтому детали пока не могут быть раскрыты, но в дальнейшем мы будем постепенно делиться более конкретными примерами. diff --git a/content/ru/memos_cloud/features/advanced/continuous_dialogue.md b/content/ru/memos_cloud/features/advanced/continuous_dialogue.md new file mode 100644 index 00000000..516fbffe --- /dev/null +++ b/content/ru/memos_cloud/features/advanced/continuous_dialogue.md @@ -0,0 +1,204 @@ +--- +title: Непрерывный Диалог Chat +desc: MemOS предоставляет интерфейс диалога, встроенные полные возможности управления памятью, вам больше не нужно вручную соединять контекст. +--- + +## 1. Когда Использовать Chat Интерфейс + +Интерфейс Chat, предоставляемый MemOS, поддерживает ввод и вывод сообщений диалога от конца до конца, позволяя вам реализовать: + +* **Интегрированный Диалоговый ИИ**: достаточно вызвать один интерфейс и передать сообщение пользователя для завершения диалога, не нужно строить сложные цепочки. + +* **Автоматическая Обработка Памяти**: MemOS автоматически извлекает, обновляет и извлекает память, не требуя ручного обслуживания, не упуская важных деталей. + +* **Постоянный "Контекст"**: поддерживает последовательное понимание в межсессионных, междневных и даже междиалоговых контекстах, позволяя модели постоянно "помнить" пользователя. + +## 2. Принцип Работы + +# ![chat接口流程.png](https://cdn.memtensor.com.cn/img/1765973438090_tskx7x_compressed.png) + +На рисунке выше показан полный процесс взаимодействия конечного пользователя, вашего AI приложения и MemOS: + +1. Если есть исторические сообщения пользователя, вы можете сначала вызвать интерфейс add/message для записи в MemOS. + +2. Когда конечный пользователь отправляет сообщение, ваше AI приложение вызывает интерфейс Chat и передает сообщение пользователя и соответствующие параметры. + +3. После получения запроса MemOS последовательно выполняет следующие действия: + + * Восстанавливает историческую память, связанную с текущим сообщением пользователя; + + * Объединяет пользовательскую инструкцию, контекст текущей сессии и восстановленную память пользователя в полный Prompt; + + * Вызывает большую модель для генерации ответа и возвращает результат вашему AI приложению. + +4. После получения ответа ваше AI приложение отображает содержимое конечному пользователю. + +5. В то же время MemOS по умолчанию обрабатывает сообщения пользователей и ответы модели в фоновом режиме асинхронно, обрабатывая и записывая в память. + +## 3. Быстрый Старт + +### Добавление Исторических Сообщений + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "0610", + "messages": [ + {"role": "user", "content": "Я запланировал поездку в Гуанчжоу на летние каникулы, какие сетевые отели доступны для проживания?"}, + {"role": "assistant", "content": "Вы можете рассмотреть 【Семь Дней, Целый Сезон, Хилтон】 и так далее"}, + {"role": "user", "content": "Я выбрал Семь Дней"}, + {"role": "assistant", "content": "Хорошо, если будут другие вопросы, спрашивайте."} + ] + } +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` + +### Диалог + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "query": "На праздники я хочу поехать развлекаться, порекомендуйте мне город, в котором я еще не был, и отель, в котором я еще не останавливался", + "conversation_id": "0928" +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/chat" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` + +## 4. Ограничения Использования + +Максимум входных токенов для интерфейса: 8,000. + +Максимум выходных токенов: количество извлеченных записей памяти — фактическая память 25 записей; предпочтительная память 25 записей. + + +## 5. Дополнительные Функции + +Помимо однокнопочного копирования кода быстрого старта, этот интерфейс также предлагает множество других настраиваемых параметров, вы можете обратиться к объяснению следующих полей для вызова интерфейса Chat для реализации диалога. + +:::note +Полный список информации о полях API, формате и т.д. см. в [документации интерфейса Chat](/api_docs/chat/chat). +::: + +### Фильтрация Восстановленной Памяти + +| **Функция** | **Поле** | **Описание** | +| -------------- | ------------------------------------------------- | ------------------------------------------------------------ | +| Фильтр Памяти | `filter` | Поддерживает настраиваемые структурированные условия запроса, точно отбирает память, см. [**Фильтр Памяти**](/memos_cloud/features/basic/filters). | +| Включение Предпочтительной Памяти | `include_preference`
 
`preference_limit_number` | Предпочтительная память — это информация о предпочтениях пользователя, сгенерированная на основе анализа исторических сообщений MemOS.
После включения можно вернуть предпочтительную память пользователя в результатах поиска, «лучше понимать пользователя». | +| Поиск в Указанном Знаниевом Базе | `knowledgebase_ids` | Указывает диапазон связанных знаниевых баз, доступных для текущего поиска, см. [**Знаниевая База**](/memos_cloud/features/advanced/knowledge_base). | + +### Настройка Ответа Модели + +| Функция | Поле | Описание & Допустимые Значения | +| ---------------- | -------------- | ------------------------------------------------------------ | +| Выбранная Модель | model\_name | В настоящее время MemOS предоставляет три модели, которые можно указать для получения ответов. Вы можете ознакомиться с подробным описанием моделей в [консоли - списке моделей](https://memos-dashboard.openmem.net/models/). Доступные названия моделей:
* qwen2.5-72b-instruct (по умолчанию)
* qwen3-32b
* deepseek-r1 | +| Пользовательский Системный Подсказка | system\_prompt | Поддерживает возможность настройки системных подсказок разработчиками. По умолчанию используются встроенные команды MemOS. | +| Потоковые/Непотоковые Ответы | stream | MemOS предлагает два способа получения ответов: потоковый и непотоковый. Вы можете выбрать любой из них в зависимости от ваших потребностей.
При вызове API передайте `stream=true или false`. По умолчанию используется: непотоковый вывод. | +| Ключевой Параметр | temperature | Контролирует случайность генерируемого контента моделью. Чем ниже значение, тем стабильнее ответ и ближе к фиксированному ответу; чем выше значение, тем более разнообразным и рассеянным становится ответ.
Допустимый диапазон значений: 0-2, значение температуры по умолчанию: 0.7 | +| | top\_p | Контролирует диапазон возможных кандидатов для выбора при генерации контента моделью. Чем меньше значение, тем уже диапазон выбора, вывод более сжатый; чем больше значение, тем шире диапазон выбора, вывод более разнообразный.
Допустимый диапазон значений: 0-1, значение по умолчанию: 0.95 | +| | max\_tokens | Ограничивает максимальную длину генерируемого контента моделью. Чем больше значение, тем длиннее может быть генерируемый контент; после достижения предела генерация остановится.
Значение по умолчанию: 8192 | + +::note +Если вы хотите, чтобы модель лучше ссылалась на память при ответе, при построении `system_prompt` вы можете обратиться к текущей инструкции по умолчанию MemOS. Как показано ниже, где `` является заполнителем для памяти, вы можете оставить +:: + +```python +# Role +Вы - интеллектуальный помощник с долгосрочной памятью (MemOS Assistant). Ваша цель - сочетать извлеченные фрагменты памяти, чтобы предоставить пользователю высоко персонализированные, точные и логически обоснованные ответы. + +# System Context +- Текущее Время: 2025-12-16 15:51 (используйте это как основу для оценки актуальности памяти) + +# Memory Data +Ниже представлена информация, извлеченная MemOS, разделенная на "факты" и "предпочтения". +- **Факты (Facts)**: могут содержать атрибуты пользователя, историю диалогов или информацию от третьих лиц. + - **Особое Внимание**: Содержимое, помеченное как `[assistant观点]`, `[模型总结]`, представляет собой **выводы ИИ в прошлом**, **а не** слова пользователя. +- **Предпочтения (Preferences)**: Явные/неявные требования пользователя к стилю, формату или логике ответа. + + +{memories} + + +# Critical Protocol: Memory Safety (记忆安全协议) +Извлеченная память может содержать **предположения ИИ**, **неуместный шум** или **ошибки субъекта**. Вы должны строго следовать следующим **«четырем шагам оценки»**; если хотя бы один шаг не пройден, **отбросьте** эту память: + +1. **Проверка Источника (Source Verification)**: + - **Суть**: Различать «слова пользователя» и «предположения ИИ». + - Если память содержит такие метки, как `[assistant观点]`, это лишь представляет собой **гипотезу** ИИ в прошлом, **нельзя** рассматривать это как абсолютный факт пользователя. + - *Пример противоречия*: Память показывает `[assistant观点] Пользователь обожает манго`. Если пользователь не упоминал это, не предполагайте, что пользователь любит манго, чтобы избежать циклической иллюзии. + - **Принцип: Резюме ИИ предназначено только для справки, его вес значительно ниже, чем прямые заявления пользователя.** + +2. **Проверка Атрибуции (Attribution Check)**: + - Является ли субъектом действия в памяти «сам пользователь»? + - Если память описывает **третью сторону** (например, «кандидат», «интервьюируемый», «вымышленный персонаж», «данные случая»), **строго запрещается** приписывать их свойства пользователю. + +3. **Проверка Релевантности (Relevance Check)**: + - Способствует ли память непосредственно ответу на текущий `Original Query`? + - Если память лишь совпадает по ключевым словам (например: оба упоминают «код»), но контекст совершенно другой, **необходимо игнорировать**. + +4. **Проверка Актуальности (Freshness Check)**: + - Соответствует ли содержимое памяти последним намерениям пользователя? В качестве высшего факта используется текущий `Original Query`. + +# Instructions +1. **Анализ**:Сначала прочитайте ``, выполните «четыре шага решения», исключите шум и ненадежные мнения ИИ. +2. **Выполнение**: + - Используйте только отфильтрованную память для дополнения контекста. + - Строго соблюдайте требования к стилю в ``. +3. **Вывод**:Прямо отвечайте на вопрос, **строго запрещено** упоминать такие внутренние термины системы, как «база памяти», «поиск» или «мнения ИИ». +``` + +### Однокнопочное Добавление Сообщений, Обработка в Памяти + +| Функция | Поле | Описание & Допустимые значения | +| -------------- | ------------------------- | ------------------------------------------------------------ | +| Включить эту функцию | `add_message_on_answer` | При включении этой функции MemOS автоматически сохраняет сообщения пользователя и ответы модели, обрабатывая их как память. Разработчикам не нужно управлять этим отдельно.
При вызове интерфейса передайте `add_message_on_answer=true или false`. В настоящее время эта функция включена по умолчанию. | +| Связать больше сущностей | `agent_id`
 
`app_id` | Уникальный идентификатор, связывающий сообщения текущего пользователя с сущностями, такими как агент и приложение, для удобства последующего поиска памяти по сущностям. | +| Асинхронный режим | `async_mode` | Управляет способом обработки после добавления сообщения, поддерживает асинхронный и синхронный режимы, см. [**Асинхронный режим**](/memos_cloud/features/basic/async_mode). | +| Пользовательские метки | `tags` | Добавляет пользовательские метки к сообщениям текущего пользователя для последующего поиска и фильтрации памяти, см. [**Пользовательские метки**](/memos_cloud/features/basic/custom_tags). | +| Метаданные | `info` | Пользовательское поле метаданных, используемое для дополнения сообщений текущего пользователя и использования в качестве условия фильтрации при последующем поиске памяти. | +| Запись В Общественную Память | `allow_public` | Контролирует, будет ли память, созданная в сообщениях диалога текущего пользователя, записана в общественную память на уровне проекта, доступную для всех пользователей проекта. | +| Запись В Память Базы Знаний | `allow_knowledgebase_ids` | Контролирует, будет ли память, созданная в сообщениях диалога текущего пользователя, записана в указанную связанную с проектом базу знаний. | + +## 6. Сравнение Интерфейсов Операций с Памятью + +| Сравнительные Измерения | Интерфейс Диалога | Интерфейс Управления Памятью | +| ------------ | -------------------------------------- | ----------------------------------- | +| Мультимодальная Память | Вход не поддерживается | ✅Поддерживается вход, поиск | +| Инструментальная Память | Вход, поиск не поддерживаются | ✅Поддерживается вход, поиск | +| Управление Памятью | ✅Автоматическое управление памятью пользователя | Ручное добавление сообщений, поиск памяти | +| Контекстный Проект | ✅Автоматическая сборка | Ручная сборка | +| Ответ Модели | ✅Бесплатное использование указанного списка моделей
Основные параметры модели | Самостоятельный вызов внешней модели
✅Богатые параметры модели | +| Сложность | ✅Простая, готова к использованию | Средняя, требуется разработка | +| Типичные Сценарии Использования | Универсальные AI диалоговые приложения
Бизнес PoC / Быстрая проверка | Сложные Agent приложения
Глубокая интеграция бизнес-систем | diff --git a/content/ru/memos_cloud/features/advanced/knowledge_base.md b/content/ru/memos_cloud/features/advanced/knowledge_base.md new file mode 100644 index 00000000..abfacc38 --- /dev/null +++ b/content/ru/memos_cloud/features/advanced/knowledge_base.md @@ -0,0 +1,510 @@ +--- +title: База ЗнанийKnowledgebase +desc: Создание базы знаний, связанной с проектом, с учетом памяти при поиске. +--- +::warning +**[Эта статья является развернутым описанием функции 【MemOS База Знаний】, вы можете нажать здесь, чтобы сразу просмотреть подробную документацию API](/api_docs/knowledge/create_kb)** +:: + +## 1. MemOS vs RAG + +Приложение на основе RAG (Улучшенное Генерирование Поиска) хорошо подходит для поиска информации, семантически схожей с запросами и вопросами, поэтому среди десятков тысяч слов в знаниях оно может быстро находить соответствующий и правильный контент. Однако сами знания не имеют состояния, каждый запрос является "одноразовым", и не хватает понимания конкретного пользователя и контекста. + +MemOS может использовать "память + базу знаний", связывая текущую проблему с исторической памятью, чтобы искать и использовать знания с учетом "контекста", позволяя AI приложениям не только более точно запрашивать материалы, но и лучше понимать контекст и пользователей, а в процессе взаимодействия автоматически накапливать новую память, постоянно дополняя и улучшая систему знаний. + + +::note +**Что может сделать MemOS с "памятью + базой знаний"?**
+* **Клиентская поддержка в международной электронной коммерции** — специализированные ответы по электронной почте каждому клиенту +* **Рассылка для продавцов в частном секторе** — использование прошлой памяти для привлечения высокоактивных клиентов +* **AI-советник для независимых сайтов (Chatbot)** — интеграция в правом нижнем углу сайта, активное начало рекомендаций +* **Корпоративный ассистент** — понимание корпоративных знаний, а также участие в вашей личной работе +* **...** + +👉 Если вы хотите попробовать на практике: [Используйте n8n + MemOS, чтобы создать торгового агента для SHEIN](https://mp.weixin.qq.com/s/qm4Av7KiLudaKfxNTC3Eng)。 +:: + + +Ниже приведены два реальных сценария, сравнивающих решения MemOS и RAG: + + +**Чат-бот для покупок** + +**Контекст** + +```python +DAY 1 Пользователь спрашивает: У меня есть трехмесячный золотистый ретривер, какой корм для собак лучше купить? Кстати, он не ест куриный вкус. +DAY 1 Пользователь купил корм для щенков с ягненком A по рекомендации помощника. +DAY 10 Пользователь спрашивает: Собака, едущая этот корм, поносит, я хочу сменить корм. +``` + +**RAG Решение** + +```python +# По запросам пользователя ищем фрагменты, связанные с "рекомендацией корма для щенков" и "поносом", но не можем вспомнить "собака пользователя не ест куриный вкус". Найдено знание: + +1. Объяснение распространенных причин поноса от корма для собак: можно сменить на гипоаллергенный корм. +2. Рекомендации по гипоаллергенному корму для щенков: B (курица), C (лосось). + +# 🤦 Помощник по покупкам: Если сейчас есть понос, можно попробовать B (вкус курицы), C (лосось). +``` + +**MemOS Решение** + +```python +# По запросам пользователя ищем связанные воспоминания, осознаем, что у пользователя трехмесячный золотистый ретривер, который не любит курицу, нужно рекомендовать корм для щенков, который не вызывает понос. Найдено воспоминание: + +1. У пользователя есть трехмесячный золотистый ретривер весом около 12 фунтов. +2. Собака пользователя не ест корм с куриным вкусом. +3. Ранее пользователь покупал корм для щенков с ягненком. +4. Объяснение распространенных причин поноса от корма для собак: можно сменить на гипоаллергенный корм. +5. Рекомендации по гипоаллергенному корму для щенков: B (курица), C (лосось). + +# ✅ Помощник по покупкам: Вы ранее упоминали, что вашей собаке 3 месяца и она не может есть корм с куриным вкусом, поэтому я исключил все корма для щенков с куриным вкусом. Вы ранее покупали корм для щенков с ягненком + лососем, если сейчас есть понос, можно попробовать более мягкий C (гипоаллергенный корм для щенков с лососем). +``` +
+
+ +**Ассистент корпоративной базы знаний** + +**Контекст** + +```python +DAY 1 Сотрудник спрашивает: "Мой компьютер - MacBook Pro 13 дюймов, с чипом Intel. Как мне установить прокси для внутренней сети компании?" +DAY 1 Ассистент предоставил шаги установки для версии Intel. +DAY 20 Сотрудник спрашивает: "Прокси для внутренней сети не открывается, какую версию мне переустановить?" +``` + +**RAG Решение** + +```python +# Поиск по высказыванию пользователя о "прокси для внутренней сети" и "не открывается", но не удалось вспомнить "модель устройства пользователя". Найдено знание: + +1. Распространенные неисправности прокси для внутренней сети +2. Инструкции по установке прокси для внутренней сети для версий M1/M2 (ARM) +3. Инструкции по установке клиента прокси для внутренней сети для Windows +4. Проблемы с сетевым подключением и сертификатами +5. Общие вопросы и ответы (FAQ) + +# 🤦 Ассистент базы знаний: Пожалуйста, попробуйте заново скачать и установить последнюю версию прокси для внутренней сети для Mac M1/M2 (ARM) или клиента прокси для Windows. Вот шаги установки:... +``` + +**MemOS Решение** + +```python +# Поиск по вопросу сотрудника о "прокси для внутренней сети" и "не открывается", автоматическое определение модели устройства сотрудника, найдено знание: + +1. Пользователь установил прокси для внутренней сети компании 20 дней назад, его устройство - MacBook Pro 13 (Intel) +2. Распространенные неисправности прокси для внутренней сети +3. Инструкции по установке прокси для внутренней сети версии Intel + +# ✅ Ассистент базы знаний: Вы используете MacBook Pro с чипом Intel, рекомендуется переустановить клиент прокси для внутренней сети версии Intel. Вот ссылка для скачивания и шаги установки для версии Intel:... +``` + + +## 2. Принцип Работы + + +На рисунке показан полный процесс взаимодействия конечного пользователя, созданного вами AI Agent и MemOS: + +1. Вызов интерфейса `create/knowledgebase` / Нажмите "Добавить базу знаний" в консоли, чтобы создать базу знаний MemOS. +2. Вызов интерфейса `add/knowledgebase-file` / Нажмите "Загрузить документ" в консоли, чтобы загрузить документ базы знаний в соответствующую базу знаний MemOS. +3. После получения запроса MemOS последовательно выполнит следующие действия, чтобы создать память базы знаний: +
a. Проверка документа: завершение аутентификации и проверка соответствия формата, размера и т.д.; +
b. Хранение документа: после успешной загрузки документа MemOS сохранит его и добавит в очередь обработки; +
c. Анализ документа: анализ содержания оригинального текста документа в зависимости от типа файла; +
d. Умное разбиение: разделение документа на более мелкие фрагменты содержания в зависимости от заголовков, структуры и семантики; +
e. Генерация памяти базы знаний: чтобы не потерять детали содержания, MemOS умно сгенерирует память, содержащую оригинал документа после разбиения и обработанную память. +
f. Встраивание и индексирование: все вышеуказанные содержательные воспоминания записываются в базу данных и создается индекс встраивания для поддержки поиска на уровне миллисекунд. +4. Вызов интерфейса `search/memory` для поиска памяти, MemOS вернет все факты, предпочтения, воспоминания о инструментах и память базы знаний, связанные с контекстом. +5. Соедините вышеуказанную память в полном запросе и передайте ее вашей развернутой модели, чтобы получить ответ и вернуть его пользователю. + + +::note +**Почему у памяти базы знаний нет отдельного интерфейса для поиска?**
+Это преднамеренный дизайн MemOS, мы хотим, чтобы MemOS позволял разработчикам получать одновременно "память базы знаний + пользователя" в одном запросе, не обращая внимания на источник, что значительно повышает фактическую полезность ответов и восприятие пользователем. +:: + +## 3. Требования к Базе Знаний + +### Ограничения по Вместимости + +MemOS облачный сервис в настоящее время предлагает разработчикам различные ценовые планы от бесплатной версии до корпоративной версии, разные версии имеют разные ограничения по объему и количеству баз знаний. + +::note +В настоящее время все версии временно бесплатны, добро пожаловать на [официальный сайт - Цены](https://memos.openmem.net/cn/pricing), чтобы запросить версию, соответствующую вашим потребностям. +:: + +| **Версия** | **Ограничение Хранения Знаний** | +| ---------- | ----------------------------------------- | +| **Бесплатная Версия** | Количество Знаний: 10; Объем Хранения Одного Знания: 1G | +| **Начальная Версия** | Количество Знаний: 30; Объем Хранения Одного Знания: 10G | +| **Профессиональная Версия** | Количество Знаний: 100; Объем Хранения Одного Знания: 100G | + + +::warning + Обратите Внимание
+Когда уровень вашего сервиса понижается, если существующая база знаний превышает ограничения по объему текущей версии, MemOS не очистит существующие данные базы знаний, но ограничит следующие операции:
+ +* Невозможно создать новую базу знаний +* Невозможно продолжить загрузку новых документов + +Необходимо отрегулировать использование в пределах объема текущей версии, после чего соответствующие функции могут быть восстановлены. +:: + +### Ограничения Документов + +1. Поддерживаемые типы загружаемых документов: PDF, DOCX, DOC, TXT, JSON, MD, XML + +2. Максимальный размер одного файла: не более 100 MB, 500 страниц + +3. Максимальное количество файлов для однократной загрузки: не более 20 + +::warning + Обратите Внимание
+Когда количество файлов для однократной загрузки, размер одного файла или количество страниц превышает указанные ограничения, эта задача загрузки будет признана неудачной.
+Пожалуйста, отрегулируйте файлы в соответствии с требованиями ограничений и повторно инициируйте запрос на загрузку. +:: + +## 4. Пример Использования + +Вот полный пример использования базы знаний, который поможет вам быстро начать использовать ваш собственный «Ассистент Базы Знаний». + +### Создание Базы Знаний: База Знаний по Финансовым Возвратам + +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "knowledgebase_name": "База Знаний По Финансовым Возвратам", + "knowledgebase_description": "Свод всех знаний, связанных с финансовыми возвратами нашей компании" + } +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/create/knowledgebase" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [вывод] +"result": { + "code": 0, + "data": { + "id": "idxxxxx" # Замените на ID базы знаний, созданной выше + }, + "message": "ok" +} +``` +:: + +### Загрузка Документа: Политика Возврата Расходов на Программное Обеспечение + +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "knowledgebase_id": "idxxxxx", # Замените на ID базы знаний, созданной выше + "file": [ + {"content": "https://cdn.memtensor.com.cn/file/Политика_возврата_программного_обеспечения.pdf"} + ] +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/knowledgebase-file" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [вывод] +"result": { + "code": 0, + "data": [ + { + "id": "1f35642253606ed1e9dd8cd8113a8998", + "name": "Политика_возврата_программного_обеспечения.pdf", + "sizeMB": 0.06331157684326172, + "status": "PROCESSING" + } + ], + "message": "ok" +} +``` +:: + +### Добавление Пользовательского Диалога + +::note{icon="websymbol:chat"} + Сессия A: 2025-06-10 произошла
+
+Дизайнер в чате указал, что он является 【дизайнером отдела креативной платформы】. +
+:: + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "0610", + "messages": [ + { + "role": "user", + "content": "Я дизайнер из отдела креативной платформы." + }, + { + "role": "assistant", + "content": "Хорошо, я запомнил." + } + ] +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` + +### Поиск Памяти Базы Знаний + +::note{icon="websymbol:chat"} + Сессия A: 2025-12-12 произошла
+
+Пользователь в новом сеансе спрашивает о 【политике возврата расходов на программное обеспечение】, MemOS автоматически вспомнит 【память базы знаний: содержание политики возврата расходов на программное обеспечение】【память пользователя: дизайнер креативной платформы】, чтобы дать более четкий и «понимающий пользователя» ответ о содержании возврата расходов на программное обеспечение. +
+:: + +::code-group + +```python [Python (HTTP)] +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "1211", + "query": "Помоги мне проверить лимит на возмещение расходов на закупку программного обеспечения.", + "knowledgebase_ids":["idxxxxx"] # Замените на созданный выше ID базы знаний +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/search/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + + +# Улучшение вывода JSON +json_res = res.json() +print(json.dumps(json_res, indent=2, ensure_ascii=False)) +``` + +```python [вывод] +"memory_detail_list": [ + { + "id": "2c760355-de4b-4a8f-b98d-b92851d23fa7", + "memory_key": "Правила Возмещения Расходов На Закупку Программного Обеспечения (Пробная Версия)", + "memory_value": "Данная система предназначена для стандартизации процесса закупки и возмещения расходов на различные виды программного обеспечения в компании, требуя, чтобы все закупки программного обеспечения соответствовали установленным лимитам по категориям. Лимит на закупку программного обеспечения для дизайна составляет 1000 юаней, применимо к графическому дизайну, видеомонтажу и проектированию прототипов, примеры включают Photoshop и Premiere. Лимит на закупку программного обеспечения для кодирования/разработки составляет 1500 юаней, охватывает IDE и фреймворки разработки, примеры включают PyCharm и Visual Studio. Лимит на закупку офисного программного обеспечения составляет 800 юаней, применимо к редактированию документов и обработке таблиц, примеры включают пакет Office и WPS. Лимит на закупку программного обеспечения для анализа данных составляет 1200 юаней, охватывает статистику данных и визуализацию, примеры включают Tableau и Power BI. Лимит на закупку программного обеспечения для безопасности и защиты составляет 1000 юаней, применимо к антивирусам и брандмауэрам. Лимит на закупку программного обеспечения для совместной работы/управления проектами составляет 900 юаней, примеры включают Jira и Slack. Лимит на закупку программного обеспечения для специализированных отраслей составляет 2000 юаней, требуется специальное одобрение. Все закупки должны соответствовать бюджету компании и требованиям информационной безопасности, программное обеспечение, превышающее лимит, должно иметь бизнес-обоснование и подлежит специальному одобрению.", + "memory_type": "WorkingMemory", + "create_time": 1765525947718, + "conversation_id": "default_session", + "status": "activated", + "confidence": 0.99, + "tags": [ + "Закупка Программного Обеспечения", + "Правила Возмещения Расходов", + "Процесс Одобрения", + "Бюджет", + "Информационная Безопасность", + "mode:fine", + "multimodal:file" + ], + "update_time": 1765525947720, + "relativity": 0.89308184 + }, + { + "id": "81fd1e79-65be-4d4e-81e0-8f76ba697c55", + "memory_key": "Информация О Должности", + "memory_value": "Пользователь является дизайнером в отделе креативной платформы.", + "memory_type": "WorkingMemory", + "create_time": 1765526247112, + "conversation_id": "0610", + "status": "activated", + "confidence": 0.99, + "tags": [ + "Должность", + "Отдел", + "Дизайн" + ], + "update_time": 1765526247113, + "relativity": 1.6319022e-05 + } +] +``` +:: + +### Обратная Связь для Оптимизации Базы Знаний + +В компаниях часто возникает проблема, когда корпоративные политики/знания обновляются, а база знаний не обновляется вовремя. В настоящее время MemOS поддерживает обратную связь по памяти базы знаний через **естественный языковой диалог**, чтобы быстро обновлять память базы знаний, тем самым повышая точность и актуальность. + +Попробуйте, используя самый простой способ взаимодействия, чтобы база знаний всегда оставалась актуальной. + +::note{icon="websymbol:chat"} + Сессия A: 2025-12-12 произошла
+
+Финансовый директор в другом новом сеансе сообщает, что 【максимальная сумма закупки офисного программного обеспечения составляет 600 юаней, а не 800 юаней】. +
+:: + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "1212", + "feedback_content": "Предел закупки офисного программного обеспечения составляет 600 юаней, а не 800 юаней.", + "allow_knowledgebase_ids":["idxxxxx"] # Замените на ID созданной выше базы знаний +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/feedback" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` + +::note{icon="websymbol:chat"} + Сессия A: 2025-12-12 произошла
+
+Любой другой пользователь, ищущий 【политику возврата расходов на программное обеспечение】, получает новую высокоприоритетную память 【максимальная сумма закупки офисного программного обеспечения составляет 600 юаней, а не 800 юаней】. +
+:: + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "1211", + "query": "Помоги мне проверить лимит на возмещение расходов на закупку программного обеспечения.", + "knowledgebase_ids":["idxxxxx"] # Замените на созданный выше ID базы знаний +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/search/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + + +# Улучшение вывода JSON +json_res = res.json() +print(json.dumps(json_res, indent=2, ensure_ascii=False)) +``` + +Результат вывода следующий (упрощенная версия): + +```python +"memory_detail_list": [ + { + "id": "8a4f3d2e-c417-4e53-bc25-54451abd5ac8", + "memory_key": "Правила Возмещения Расходов На Закупку Программного Обеспечения (Пробная Версия)", + "memory_value": "Данная система предназначена для стандартизации процесса закупки и возмещения расходов на различные виды программного обеспечения в компании, требуя, чтобы все закупки программного обеспечения соответствовали установленным лимитам по категориям. Лимит на закупку программного обеспечения для дизайна составляет 1000 юаней, применимо к графическому дизайну, видеомонтажу и проектированию прототипов, примеры включают Photoshop и Premiere. Лимит на закупку программного обеспечения для кодирования/разработки составляет 1500 юаней, охватывает IDE и фреймворки разработки, примеры включают PyCharm и Visual Studio. Лимит на закупку офисного программного обеспечения составляет 800 юаней, применимо к редактированию документов и обработке таблиц, примеры включают пакет Office и WPS. Лимит на закупку программного обеспечения для анализа данных составляет 1200 юаней, охватывает статистику данных и визуализацию, примеры включают Tableau и Power BI. Лимит на закупку программного обеспечения для безопасности и защиты составляет 1000 юаней, применимо к антивирусам и брандмауэрам. Лимит на закупку программного обеспечения для совместной работы/управления проектами составляет 900 юаней, примеры включают Jira и Slack. Лимит на закупку программного обеспечения для специализированных отраслей составляет 2000 юаней, требуется специальное одобрение. Все закупки должны соответствовать бюджету компании и требованиям информационной безопасности, программное обеспечение, превышающее лимит, должно иметь бизнес-обоснование и подлежит специальному одобрению.", + "memory_type": "LongTermMemory", + "create_time": 1765525947718, + "conversation_id": "default_session", + "status": "activated", + "confidence": 0.99, + "tags": [ + "Закупка Программного Обеспечения", + "Правила Возмещения Расходов", + "Процесс Одобрения", + "Бюджет", + "Информационная Безопасность", + "mode:fine", + "multimodal:file" + ], + "update_time": 1765525947720, + "relativity": 0.8931847 + }, + { + "id": "a72a04d1-d7ba-4ebd-9410-0097bfa6c20d", + "memory_key": "Предел Закупки Офисного Программного Обеспечения", + "memory_value": "Пользователь подтвердил, что предел закупки офисного программного обеспечения составляет 600 юаней, а не 800 юаней.", + "memory_type": "WorkingMemory", + "create_time": 1765531700539, + "conversation_id": "1212", + "status": "activated", + "confidence": 0.99, + "tags": [ + "Закупка", + "Офисное Программное Обеспечение", + "Бюджет" + ], + "update_time": 1765531700540, + "relativity": 0.7196722 + } +] +``` + +[Консоль - База Знаний](https://memos-dashboard.openmem.net/knowledgeBase/) отображает все детали исправления или дополнения памяти базы знаний через взаимодействие на естественном языке. + +![image.png](https://cdn.memtensor.com.cn/img/1765970178683_5tuxe4_compressed.png) + +::note +Полный список информации о полях, форматах и т.д. обратной связи API см. в [Документации интерфейса Add Feedback](/api_docs/message/add_feedback). +:: diff --git a/content/ru/memos_cloud/features/advanced/skill.md b/content/ru/memos_cloud/features/advanced/skill.md new file mode 100644 index 00000000..7cc3cfe4 --- /dev/null +++ b/content/ru/memos_cloud/features/advanced/skill.md @@ -0,0 +1,260 @@ +--- +title: НавыкиSkills +desc: Добавить сообщения диалога пользователя, сгенерировать файл навыков, который может быть повторно использован агентом. +--- + +## 1. Что такое MemOS навыки (Skills)? + +**Навыки (Skills)** — это **модульные пакеты возможностей**, которые агент может динамически вызывать при выполнении задач. Они автоматически планируются агентом в зависимости от контекста диалога и внедряются по мере необходимости, без вмешательства пользователя. Эти навыки обычно создаются разработчиками в сотрудничестве с большими моделями, основаны на открытых проектах или оригинальных концепциях и постоянно оптимизируются в процессе реального использования. + +MemOS утверждает, что "память — это актив". Мы считаем, что те пути решения и предпочтения пользователей, которые накапливаются в реальных диалогах, по сути, являются самыми ценными материалами для навыков. Исходя из этой идеи, MemOS **уже поддерживает автоматическое извлечение навыков из пользовательской памяти** — превращая разрозненную историю взаимодействий в повторно используемые, персонализированные профессиональные способности. + +::note +**В чем разница между навыками MemOS и существующей памятью?** + +* **Статические факты → Динамическое выполнение** + +Память обычно статична и фактическа, например: "Я живу в Шанхае", "Мне нравятся лаконичные ответы", эта информация предоставляет необходимый контекст для вывода агента; + +Навыки, с другой стороны, представляют собой исполняемые способности, основанные на памяти, которые инкапсулируют четкую логику обработки задач, например, «как спланировать полный маршрут поездки», направляя решения и действия агента. + +* **Фрагментарность → Структурированность** + +Память обычно фрагментарна, каждая запись описывает только один факт или предпочтение; + +Навыки, напротив, высоко структурированы, объединяя несколько связанных воспоминаний в полный план задачи, который можно повторно использовать в различных задачах. +:: + +## 2. Принцип работы + +![image.png](https://cdn.memtensor.com.cn/img/1769653199709_6ol3n7_compressed.png) + +На рисунке выше показан полный процесс взаимодействия конечного пользователя, созданного вами AI агента и MemOS: + +1. Вызов интерфейса `add/message`, чтобы передать сообщение диалога пользователя в MemOS. + +2. После получения запроса MemOS последовательно выполнит следующие действия, чтобы сгенерировать файл навыков (Skill): + + a. **Умное разбиение**: определение границ задач в истории диалога, разделение на текстовые блоки задач; + + b. **Кластеризация извлечения**: кластеризация текстовых блоков задач одного типа, в сочетании с исторической памятью пользователя, извлечение структурированного текста навыков. + + c. **Преобразование навыков**: преобразование навыков в исполняемый, распознаваемый файл навыков (Skill). + +3. Вызов интерфейса `search/memory` для поиска памяти, MemOS вернет все факты, предпочтения, инструменты памяти и соответствующие файлы навыков (Skill), связанные с контекстом. + +4. Загрузка файла навыков, передача памяти и файла навыков вашему собственному развернутому большому модели, чтобы эффективно использовать долгосрочный опыт и автоматически сгенерированные навыки. + +## 3. Примеры использования + +Ниже показан пример использования MemOS для генерации навыка "планирование поездки" на основе истории диалога. + +### 1. **Добавить сообщение** + +Добавить содержание диалога между "высокоэнергичным J человеком" и "ассистентом по планированию поездок", где "высокоэнергичный J человек" выразил несколько требований к планированию поездки: + +* Не любит возвращаться по тому же пути, спецназ + +* Нравятся культурные достопримечательности + +* Необходимо заранее подтвердить погоду и температуру + +``` +import os +import requests +import json + +# Замените на ваш API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "0127", + "messages": [ + {"role": "user", "content": "На следующей неделе я собираюсь поехать в Чэнду, помогите мне спланировать 5-дневный маршрут, мне нравится путешествовать как спецназ, помогите отметить на маршруте вкусные блюда, которые стоит попробовать."}, + {"role": "assistant", "content": "...здесь пропущено..."}, + {"role": "user", "content": "Мне больше нравится посещать культурные достопримечательности, торговые центры меня не интересуют."}, + {"role": "assistant", "content": "...здесь пропущено..."}, + {"role": "user", "content": "Пожалуйста, подтвердите погоду и температуру заранее при планировании, чтобы я мог подготовить багаж."}, + {"role": "assistant", "content": "...здесь пропущено..."} + ] + } +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") + +``` + +### 2. **Поиск памяти** + + Предположим, что этот пользователь снова обратился к ассистенту с просьбой о планировании поездки, передав запрос пользователя и активировав вызов навыка: + + ``` + import os + import requests + import json + + # Замените на ваш API Key + os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" + os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + data = { + "query": "На праздник Цинмин я планирую поехать в Юньнань, помогите мне спланировать 7-дневный маршрут.", + "user_id": "memos_user_123", + "conversation_id": "0301", + "include_skill": True # Включить вызов skill + } + headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" + } + url = f"{os.environ['MEMOS_BASE_URL']}/search/memory" + + res = requests.post(url=url, headers=headers, data=json.dumps(data)) + + print(f"result: {res.json()}") + ``` + +### 3. **Показ результатов** + +В следующих результатах поиска навыки включают: + +* Планирование маршрута спецназа + +* Рекомендация культурных достопримечательностей + +* Учет погоды, температуры, рекомендации по одежде. + +``` +# Ниже приведен Skill.md, сгенерированный MemOS + +--- +name: Планирование Путешествий +description: Разработка многодневного маршрута для путешественников, включая размещение достопримечательностей, способы передвижения и рекомендации по погоде. +--- + +## Procedure +1. Определите интересы и предпочтения путешественника 2. Соберите информацию о достопримечательностях и мероприятиях в пункте назначения 3. Спланируйте ежедневный маршрут, обеспечив эффективные перемещения и избегая возвратов 4. Добавьте рекомендации по местной кухне, чтобы обеспечить насыщенный опыт 5. Предоставьте рекомендации по транспорту и размещению, учитывая удобство и комфорт 6. Проверьте прогноз погоды, скорректируйте маршрут и подготовьте багаж + +## Experience +1. Эффективное проектирование маршрута для сокращения времени на дорогу +2. Приоритет достопримечательностям, избегая коммерческих мест +3. Рекомендации по Еде Увеличивают Богатство Опыта +4. Адаптация Погоды Обеспечивает Комфортные Поездки + +## User Preferences +- Не Возвращаться По Пройденному Маршруту +- Приоритет Культурным Достопримечательностям, Уделяя Внимание Истории И Культурному Опыту +- Корректировка Маршрута И Подготовка Багажа В Соответствии С Погодой + +## Examples + +### Example 1 + +# Пример Плана Поездки +## Day 1 +- **Маршрут**: База Панд → Восточные Припоминания → Улица Еды На Строительной Дороге +- **Адаптация Погоды**: Пасмурно, Защита От Ветра, Подходит Для Прогулок По Культурным Улицам +- **Рекомендации По Еде**: Цзюньтун Го Куэй, Соевое Молоко +- **Транспорт**: Метро + Пешком + +## Day 2 +- **Маршрут**: Парк Народов → Музей Чэнду → Храм Вэньшу +- **Адаптация Погоды**: Небольшой Дождь, Основное Время Внутри Музеев +- **Рекомендации По Еде**: Чжуншуй Цзяоцзы, Чэнь Мапо Тофу +- **Транспорт**: Метро + Такси + +... + +## Additional Information + +### Руководство По Подготовке Багажа +В зависимости от погодных условий в пункте назначения, используйте метод многослойной одежды, чтобы легко добавлять или убирать слои. + +### Руководство по Бронированию Культурных Достопримечательностей +Предоставление каналов бронирования достопримечательностей, цен на билеты и времени работы. + +``` + +::note +**Два способа использования навыков** +
+ +* Если модель / агент, который вы вызываете, имеет возможность использовать файлы навыков, вы можете напрямую загрузить файл по ссылке `skill_url`. + +* Если модель / агент, который вы вызываете, не имеет возможности использовать файлы навыков, вы можете напрямую преобразовать `skill_value` в строку и добавить в prompt. +:: + +### 4. **Создание уникальных для вас навыков** + +MemOS на основе сообщений диалога различных пользователей может создавать уникальные для каждого навыки. Например, мы также создали диалог между "низкоэнергичным P человеком" и "ассистентом по планированию поездок", когда он предложил: + +* Сова, не могу встать утром + +* Не хочу ехать слишком далеко, нужно спешить к достопримечательностям + +* Включить малознакомые достопримечательности, не идти по обычному пути + +Файл навыков, созданный MemOS, содержит: + +* Планирование поездки с вечера до ночи, не плотный график + +* Рекомендации по маршрутам, которые не слишком далеки и не требуют спешки + +* Включение малознакомых достопримечательностей. + +``` +# Ниже приведен Skill.md, сгенерированный MemOS +--- +name: Планирование Путешествий +description: Помогите пользователям спланировать маршрут путешествия, чтобы обеспечить комфортное и эффективное посещение пункта назначения. + +--- + +## Procedure + +1. Определите цель путешествия и предпочтения 2. Соберите информацию о достопримечательностях и мероприятиях в пункте назначения 3. Отфильтруйте достопримечательности в зависимости от предпочтений пользователя 4. Запланируйте ежедневный маршрут, включая транспорт и питание 5. Предоставьте советы и рекомендации. + +## Experience + +1. Избегайте долгих поездок, выбирая удобные для транспорта достопримечательности. +2. Разумно планируйте ежедневный маршрут, сочетая отдых и исследование. +3. Полностью используйте ночные мероприятия и достопримечательности для улучшения впечатлений от путешествия. +4. Исследуйте малознакомые достопримечательности, избегая толп, чтобы насладиться уникальным опытом. + +## User Preferences + +- Пользователь предпочитает поздний подъем, избегая долгих поездок. +- Предпочитайте достопримечательности, до которых можно добраться на метро. +- Обратите внимание на ночные мероприятия и впечатления. +- Исследуйте малознакомые и нетрадиционные туристические маршруты. + +## Examples + +### Example 1 + +### День 1: Время Драгоценностей После Полудня + Ночной Прогулка по Малознакомым Улицам +- **Полдень**: Пробуждение естественным образом + Уличная еда на улице Куэйсин. +- **После Полудня**: База Разведения Больших Панд В Чэнду +- **Вечером**: Улица Ши Цзы + Улица Османтуса + Ночной Прогулка По Улице Деревьев Сосны +... + +### Example 2 + +### День 2: Культура Трех Царств + Ночной Рынок Восточных Ворот +- **В Полдень**: Пробуждение Естественным Образом + Улица Вухоуцзы С Уличной Едой +- **После Полудня**: Храм Вухоу + Красные Стены И Тени Бамбука +- **Вечером**: Восточные Ворота + Улица Баров Дзяо Янь +... +``` +::note +**Начните исследовать навыки MemOS прямо сейчас! 🚀** +* Перейдите на [Консоль - Страница навыков](https://memos-dashboard.openmem.net/cn/skill/), чтобы просмотреть файл навыков, автоматически сгенерированный на основе истории диалогов пользователя. +* Еще нет навыков? [Добавьте сообщение](/memos_cloud/mem_operations/add_message), чтобы инициировать генерацию. +:: diff --git a/content/ru/memos_cloud/features/advanced/tool_calling.md b/content/ru/memos_cloud/features/advanced/tool_calling.md new file mode 100644 index 00000000..05da09ae --- /dev/null +++ b/content/ru/memos_cloud/features/advanced/tool_calling.md @@ -0,0 +1,202 @@ +--- +title: ВызовИнструментаToolCall +desc: Добавление информации о вызове инструмента, объединение решений, результатов выполнения и их траектории использования в памяти MemOS. + +::warning +Внимание +
+
+ +**[Необходимо сначала передать память инструмента при добавлении сообщения (нажмите здесь, чтобы просмотреть подробную документацию API)](/api_docs/core/add_message)** +
+ +**[Только тогда можно будет искать память инструмента при поиске памяти (нажмите здесь, чтобы просмотреть подробную документацию API)](/api_docs/core/search_memory)** +
+
+ +**Данный документ сосредоточен на функциональном описании, подробные поля интерфейса и ограничения можно просмотреть по ссылке выше** + +:: + +## 1. Когда Использовать + +Когда вашему Agent необходимо получить внешнюю информацию через инструмент (function / tool) и вы хотите, чтобы «контекст и результаты вызова инструмента» могли быть поняты, связаны и сохранены в MemOS как доступная память, подходит использование этой структуры сообщения. + +## 2. Принцип Работы + +Step1: Добавление информации о вызове инструмента + +`assistant` сообщение: `tool_calls` описывает поведение модели, решающей вызвать определенный инструмент и его параметры. + +`tool` сообщение: содержит реальные результаты, возвращенные инструментом, и точно связывается с соответствующими `tool_calls` через `tool_call_id`. + +
+ +Step2: MemOS обрабатывает связанную с инструментом память + +* **Информация об инструменте (Tool Schema)**: MemOS поддерживает структурированное управление и динамическое обновление информации об инструментах, унифицируя способы описания различных инструментов, позволяя модели эффективно осуществлять поиск, понимание и открытие инструментов без необходимости жесткого кодирования деталей инструментов в подсказках. + +* **Память Траектории (Tool Trajectory Memory)**: MemOS извлекает и сохраняет ключевые траектории в процессе использования инструмента, включая "в каком контексте был вызван какой инструмент, какие параметры использовались, какой результат был возвращен". Эти траектории могут быть извлечены и повторно использованы в последующих диалогах, помогая модели более стабильно воспроизводить модели использования инструмента, уменьшая повторные попытки и ошибки вызова. + +## 3. Примеры Использования + +Полный список информации о полях API, форматах и т.д. см. в [документации интерфейса Add Message](/api_docs/core/add_message), чтобы узнать, как добавить информацию о вызове инструмента. + +### Добавление Информации о Вызове Инструмента + +::note{icon="websymbol:chat"} + Сессия A: Пользователь спрашивает в диалоге 【Какова погода в Пекине】, помощник вызывает 【инструмент погоды】, инструмент погоды выдает результат 【Пекин, температура 7°C, облачно】. +:: + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +# Сообщения с tool_call +tool_schema = [{ + "name": "get_weather", + "description": "Get current weather information for a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "City name, e.g. Beijing" + } + }, + "required": [ + "location" + ] + } +}] + +data = { + "user_id": "memos_user_123", + "conversation_id": "demo-conv-id", + "messages": [ + { + "role": "system", + "content": f"""You are an assistant that can call tools. +When a user's request can be fulfilled by a tool, you MUST call the appropriate tool. + +{json.dumps(tool_schema, indent=2, ensure_ascii=False)} + +""" + }, + {"role": "user", "content": "What's the weather like in Beijing right now?"}, + { + "role": "assistant", + "tool_calls": [ + { + "id": "call_123", + "type": "function", + "function": { + "name": "get_weather", + "arguments": json.dumps({"location": "Beijing"}), + }, + } + ], + }, + { + "role": "tool", + "tool_call_id": "call_123", + "content": [ + { + "type": "text", + "text": json.dumps( + {"location": "Beijing", "temperature": "7°C", "condition": "Cloudy"} + ), + } + ], + }, + ], +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(json.dumps(res.json(), indent=2, ensure_ascii=False)) +``` + +### Извлечение Памяти Инструмента + +::note{icon="websymbol:chat"} + Сессия B: В новой сессии пользователь спрашивает 【Что надеть в Пекине】, MemOS может вспомнить связанную память о 【вызове инструмента погоды】, модель может использовать память инструмента в дальнейшем, повышая точность и эффективность использования инструмента. +:: + +```python +import os +import requests +import json + +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + + +data = { + "user_id": "memos_user_123", + "conversation_id": "0928", + "query": "Что надеть в Пекине", + "memory_limit_number": 10, + "include_preference": True, + "preference_limit_number": 10, + "include_tool_memory":True, + "tool_memory_limit_number":10, +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/search/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(json.dumps(res.json(), indent=2, ensure_ascii=False)) +``` + +### Результаты Вывода + +```python +"tool_memory_detail_list": [ + { + "id": "7ec50fd8-19ec-42a2-a7c7-ce3cebdb70cf", + "tool_type": "ToolSchemaMemory", + "tool_value": {"name": "get_weather", "description": "Get current weather information for a given location", "parameters": {"type": "object", "properties": {"location": {"type": "string", "description": "City name, e.g. Beijing"}}, "required": ["location"]}}, + "create_time": 1766494806624, + "conversation_id": "demo-conv-id", + "status": "activated", + "update_time": 1766494806625, + "relativity": 0.44700349055540967 + }, + { + "id": "4b208707-991a-481c-9dd6-c7f0577ff371", + "tool_type": "ToolTrajectoryMemory", + "tool_value": "User asked about the current weather in Beijing -> Tool 'get_weather' was called with the parameter 'location' set to 'Beijing' -> The tool returned the weather information: temperature is 7°C and condition is Cloudy.", + "tool_used_status": [ + { + "used_tool": "get_weather", + "error_type": "", + "success_rate": 1.0, + "tool_experience": "Инструмент 'get_weather' требует действительный параметр местоположения и предоставляет текущую информацию о погоде для этого местоположения." #新增:当前轨迹中该工具的经验。 + } + ], + "create_time": 1768390489180, + "conversation_id": "demo-conv-id", + "status": "activated", + "update_time": 1768390489181, + "relativity": 0.47883897395535013, + "experience": "при выполнении задач по запросу погоды убедитесь, что вызываете инструмент 'get_weather' с правильным параметром местоположения." #新增:整个轨迹的程序性经验,作为指导任务完成的总体经验。 + } +] +``` diff --git a/content/ru/memos_cloud/features/basic/async_mode.md b/content/ru/memos_cloud/features/basic/async_mode.md new file mode 100644 index 00000000..22f88763 --- /dev/null +++ b/content/ru/memos_cloud/features/basic/async_mode.md @@ -0,0 +1,148 @@ +--- +title: АсинхронныйРежимAsyncMode +desc: При добавлении сообщения используется асинхронный режим, запрос интерфейса немедленно возвращает ответ, а фактическая обработка выполняется в фоновом режиме MemOS. +::warning +**[Данная статья является развернутым описанием асинхронного режима в интерфейсе 【ДобавитьПамять-addMessage】, можно перейти по ссылке для просмотра подробной документации API](/api_docs/core/add_message)** +:: + +:::note +Параметр `async_mode` по умолчанию установлен в `true`, операция добавления памяти будет обрабатываться асинхронно, ожидая выполнения в фоновом режиме, а не дожидаясь завершения обработки перед возвратом ответа. +::: +## 1. Использование Асинхронного Режима + +### Процесс Обработки + +`async_mode` параметр установлен в `true`, API немедленно возвращает ответ и ставит память в очередь на обработку в фоновом режиме: + +```json +{ + "code": 0, + "data": { + "success": true, + "task_id": "c464e17e-f2ff-4e9a-a2c2-41cc55ab43b9", + "status": "running" + }, + "message": "ok" +} +``` + +В асинхронном режиме запись памяти делится на два этапа: "грубая обработка" и "тонкая обработка": система сначала выполняет грубую обработку текущего сообщения на уровне миллисекунд, чтобы оно могло быть быстро найдено в следующем диалоге; +
+затем в фоновом режиме продолжается тонкая обработка на уровне секунд и выше для повышения качества памяти. Прогресс обработки можно проверить через интерфейс [get/status](/api_docs/message/get_status): статус задачи на этапе грубой обработки будет "в процессе", а после завершения тонкой обработки статус обновится на "завершено". + +```json +"memory_detail_list": [ + { + "id": "c436a738-eec9-4010-b65d-dc9c135d3a37", + "memory_key": "user: [09:44 AM on 10 December, 2025 UTC]: Я запланировал поездку в Гуанчжоу на летние каникулы, какие сетевые отели доступны для проживания?" + "memory_value": "user: [09:44 AM on 10 December, 2025 UTC]: Я запланировал поездку в Гуанчжоу на летние каникулы, какие сетевые отели доступны для проживания?\nassistant: [09:44 AM on 10 December, 2025 UTC]: Вы можете рассмотреть 【Семь Дней, Цюань Цзи, Хилтон】 и так далее.\nuser: [09:44 AM on 10 December, 2025 UTC]: Я выбрал Семь Дней.\nassistant: [09:44 AM on 10 December, 2025 UTC]: Хорошо, если у вас есть другие вопросы, спрашивайте меня.\n" + "memory_type": "WorkingMemory", + "create_time": 1765359875901, + "update_time": 1765359875902, + "conversation_id": "0610", + "status": "activated", + "confidence": 0.99, + "relativity": 0.05407696, + "tags": ["mode:fast"] + } +] +``` + +С помощью интерфейса [get/status](/api_docs/message/get_status) можно получить статус асинхронной задачи: + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "task_id": "c464e17e-f2ff-4e9a-a2c2-41cc55ab43b9" +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/get/status" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` + +### Когда Использовать Асинхронный Режим + +* **Снижение Задержки Ответа Интерфейса**: пользователю не нужно ждать, он может продолжать использовать память в приложении; + +* **Пакетное Добавление Памяти**: одновременная обработка большого объема данных, чтобы избежать блокировки приложения; + + +* **Обработка Фоновых Задач**: выполнение времязатратных операций обработки памяти в фоновом режиме для повышения конкурентоспособности системы. + + +:::note +Обратите Внимание
+Когда сообщение содержит мультимодальный контент, время обработки файловой памяти будет длительным, и переданное вами поле `async_mode` будет недействительным, в этом случае будет использоваться "асинхронный режим" по умолчанию. Вы можете проверить прогресс обработки файловой памяти через интерфейс `get/status`. +::: + +## 2. Использование Синхронного Режима + +### Процесс Обработки + +`async_mode` параметр установлен в `false`, API вернет результат только после завершения обработки памяти: + +```json +{ + "code": 0, + "data": { + "success": true, + "task_id": "c464e17e-f2ff-4e9a-a2c2-41cc55ab43b9", + "status": "completed" + }, + "message": "ok" +} +``` + +В этом случае, при поиске памяти, вы сможете найти уже полностью обработанную память: + +```json +"memory_detail_list":[ + { + "memory_key": "План поездки в Гуанчжоу на летние каникулы" + "memory_value": "Пользователь планирует поездку в Гуанчжоу на летние каникулы и выбрал сеть отелей Семь Дней в качестве варианта проживания." + "conversation_id": "0610", + "tags": [ + "поездка" + "Гуанчжоу" + "проживание" + "отель" + ] + } +], +"preference_detail_list":[ + { + "preference_type": "implicit_preference", + "preference": "Пользователь, вероятно, предпочитает отели с хорошим соотношением цены и качества." + "reasoning": "Отели Семь Дней обычно известны своей экономичностью, и выбор пользователя Семь Дней может указывать на его склонность выбирать варианты с хорошим соотношением цены и качества. Хотя пользователь не упомянул конкретные ограничения по бюджету или предпочтения по отелям, выбор Семь Дней среди предложенных вариантов может отражать акцент на цене и практичности." + "conversation_id": "0610" + } +] +``` + +### Когда Использовать Синхронный Режим + +* **Этап Отладки и Разработки**: возможность напрямую просмотреть результаты обработки памяти, что упрощает отладку поиска памяти; + +* **Мгновенный Запрос**: необходимо подтвердить, что память была создана или обновлена в момент возврата вызова API, например, при тестировании производительности, верификации функций и т.д. + +* **Небольшие Операции**: при небольшом объеме данных и незначительном влиянии задержки можно использовать синхронный режим. + + +### Важное Примечание + +* Поведение асинхронной обработки по умолчанию теперь `async_mode=true`. + +* Если вам нужен синхронный режим, установите `async_mode=false` при добавлении сообщения. diff --git a/content/ru/memos_cloud/features/basic/custom_tags.md b/content/ru/memos_cloud/features/basic/custom_tags.md new file mode 100644 index 00000000..fb89f9bc --- /dev/null +++ b/content/ru/memos_cloud/features/basic/custom_tags.md @@ -0,0 +1,130 @@ +--- +title: Пользовательские Теги +desc: Добавляйте теги в соответствии с вашими бизнес-требованиями при добавлении сообщений. +--- +::warning +Внимание +
+
+ +**[Необходимо сначала передать список тегов при добавлении сообщения (нажмите здесь, чтобы просмотреть подробную документацию API)](/api_docs/core/add_message)** +
+ +**[Только тогда можно использовать теги для фильтрации при поиске памяти (нажмите здесь, чтобы просмотреть подробную документацию API)](/api_docs/core/search_memory)** +
+
+ +**Данный документ сосредоточен на описании функций, подробные поля интерфейса и ограничения можно просмотреть по ссылке выше** + +:: + +MemOS автоматически генерирует теги для каждой памяти, но эти теги могут не полностью совпадать с тегами, используемыми в вашем бизнесе. Вы можете передать список пользовательских тегов при добавлении сообщения, и MemOS автоматически применит соответствующие теги к содержимому памяти на основе значений, которые вы предоставили. + +:::note +Когда использовать пользовательские теги?
+ +Вы хотите, чтобы MemOS использовал существующую систему тегов вашей продуктовой команды для маркировки содержимого памяти. + +Вам необходимо применить эти теги для генерации структурированного контента. +::: + +## 1. Механизм работы тегов + +* **Автоматическая генерация тегов**: MemOS анализирует семантику при обработке памяти и автоматически генерирует соответствующие теги для последующего поиска и фильтрации. + +* **Пользовательские теги**: При добавлении сообщения вы можете передать набор пользовательских тегов через поле `tags`, как набор候选ных тегов. + +* **Семантическое соответствие**: MemOS будет оценивать семантическое сходство между содержимым памяти и предоставленным разработчиком списком тегов, выбирая соответствующие теги, которые будут записаны в поле `tags` памяти вместе с автоматически сгенерированными тегами. + + +## 2. Примеры использования + +:::note +Подсказка
+* Содержимое тегов должно оставаться кратким, при этом четко различая значения различных категорий для удобства распознавания и соответствия. + +* Используйте единый список в рамках одного проектного измерения, не заменяйте его без необходимости, чтобы обеспечить согласованность поиска и фильтрации. +::: + +## 3. Добавление сообщения + +```python +import os +import json +import requests + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "1210", + "messages": [ + {"role": "user","content": "Как погода сегодня?"}, + {"role": "assistant","content": "Шанхай, 10 декабря, облачно, температура 8-12 градусов."} + ], + "tags":["погода","облачно"], + "async_mode":False +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` + +### Поиск памяти + +```python +import os +import json +import requests + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "query": "Шанхай погода" +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/search/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` + +### Результаты вывода + +```json +"memory_detail_list": [ + { + "id": "9bc102cb-76d8-4a59-86d7-8fd1c4542407", + "memory_key": "состояние погоды", + "memory_value": "10 декабря 2025 года, погода в Шанхае облачная, температура от 8 до 12 градусов.", + "memory_type": "WorkingMemory", + "create_time": 1765376340736, + "conversation_id": "1210", + "status": "activated", + "confidence": 0.99, + "tags": [ + "погода", + "облачно", + "температура" + ], + "update_time": 1765376340737, + "relativity": 0.82587826 + } +] +``` diff --git a/content/ru/memos_cloud/features/basic/filters.md b/content/ru/memos_cloud/features/basic/filters.md new file mode 100644 index 00000000..cb8c3ddc --- /dev/null +++ b/content/ru/memos_cloud/features/basic/filters.md @@ -0,0 +1,166 @@ +--- +title: Фильтр Памяти + desc: Фильтр памяти используется для поиска памяти, позволяя фильтровать по заданным агентам, метаданным, диапазону времени и другим условиям. +--- + +::warning +Внимание +
+
+ +**[Необходимо сначала передать соответствующие поля при добавлении сообщения (нажмите здесь, чтобы просмотреть подробную документацию API)](/api_docs/core/add_message)** +
+ +**[Только тогда можно использовать условия фильтрации при поиске памяти (нажмите здесь, чтобы просмотреть подробную документацию API)](/api_docs/core/search_memory)** +
+
+ +**Данная статья сосредоточена на описании функций, подробные поля интерфейса и ограничения можно просмотреть по ссылке выше** + +:: + +## 1. Когда Использовать Фильтр Памяти + +При обработке больших объемов памяти вам необходимо точно контролировать диапазон памяти, который может быть извлечен. Фильтр памяти (Filter) предоставляет возможность тонкой настройки диапазона поиска, включая: + +* **Фильтрация памяти по агенту**: в памяти нескольких агентов одного пользователя отфильтровывается память, принадлежащая указанному агенту. + +* **Фильтрация памяти по времени**: ограничение диапазона поиска по временным меткам, например, запрос памяти за определенный день или период времени. + +* **Фильтрация памяти по пользовательскому диапазону**: фильтрация памяти по метаданным, только соответствующим бизнес-условиям. + + +## 2. Принцип Работы +1. **Точная фильтрация**: на основе заданных вами условий фильтрации осуществляется строгая фильтрация памяти пользователя, точно сохраняя подходящие записи памяти. +2. **Извлечение памяти**: среди отфильтрованных кандидатов выполняется [поиск памяти](/memos_cloud/mem_operations/search_memory), чтобы извлечь наиболее релевантные фрагменты памяти для запроса пользователя. + +## 3. Описание Структуры Фильтра + +Поддерживается использование формата JSON для определения фильтра памяти, можно использовать логические операторы на верхнем уровне для комбинирования нескольких условий фильтрации. + +```json +# Структура Базовых Данных Ниже +{ + "and": [ # Или 'or' + { "field_name": "value" }, + { "field_name": { "operator": "value" } } + ] +} +``` + +## 4. Доступные Поля и Операторы + +### 4.1 Поля Примера + +Подробное объяснение полей см. в ([6. Дополнительные Функции](/memos_cloud/mem_operations/add_message)) + +| Название Поля | Тип Данных | Оператор | Пример | +| --- | --- | --- | --- | +| agent\_id | str | `=` | `{"agent_id":"agent_123"}` | +| app\_id | str | `=` | `{"app_id":"app_123"}` | + +### 4.2 Поля Метаданных + +При поиске памяти (search) можно фильтровать по атрибутам метаданных, записанным на этапе добавления сообщения ([add](/memos_cloud/mem_operations/add_message)) через info. Для достижения лучшей производительности поиска рекомендуется в первую очередь использовать следующие 4 распространенных поля (индексированные в базе данных, скорость запроса выше). Подробное объяснение полей см. в ([6. Дополнительные Функции](/memos_cloud/mem_operations/add_message)). + +| Название Поля | Тип Данных | Оператор | Пример | +| --- | --- | --- | --- | +| business_type | str | `=` | `{"business_type":"购物"}` | +| biz_id | str | `=` | `{"biz_id":"order_123456"}` | +| scene | str | `=` | `{"scene":"支付"}` | +| custom_status | str | `=` | `{"custom_status":"VIP3"}` | + + +### 4.3 Поля Меток + +| Название Поля | Тип Данных | Оператор | Пример | +| --- | --- | --- | --- | +| tags | list | `contains` | `{"tags": {"contains": "finance"}}` | + +### 4.4 Поля Времени + +| Название Поля | Тип Данных | Оператор | Пример | +| --- | --- | --- | --- | +| create\_time | str | `lt`, `gt`, `lte`, `gte` | `{"create_time": {"gte": "2025-12-10"}}`
`{"create_time": {"gt": "2025-12-10 15:00:00"}}`| +| update\_time | str | `lt`, `gt`, `lte`, `gte` | `{"update_time": {"lte": "2025-12-10"}}`
`{"update_time": {"lt": "2025-12-10 23:00:00"}}`| | + +## 5. Примеры Использования + +::note +**Подсказка**
Корневой узел должен быть `and` или `or`, и комбинировать ряд условий, вложенные логические операторы не допускаются;
+Не поддерживается указание `user_id` в `filter`. +:: + +Использование следующего фильтра памяти может удовлетворить общие потребности в фильтрации, без необходимости заново строить логику фильтрации. + +--- + +**Агент** + +```json +# Фильтрация Памяти, Связанной С Любым Из Умных Агентов Ниже +"filter" : { + "or": [ + {"agent_id": "agent_123"}, + {"agent_id": "agent_456"} + ] +} +``` + +**Метаданные** + +```json +# Фильтрация Атрибутов В Пользовательской Метадате info +"filter" : { + "and": [ + {"business_type":"旅行"}, # Макро Бизнес Категория + {"biz_id":"travel_001"}, # Основной Бизнес Идентификатор + {"scene":"支付"}, # Конкретная Среда Или Этап Взаимодействия Сообщения + {"custom_status":"v1"} # Пользовательский Статус/Метка + ] +} +``` + +**Метки** + +```json +# Фильтрация Памяти, Содержащей Указанные Теги +"filter" : { + "and": [ + {"tags": {"contains": "天气"}} + ] +} +``` + +**Диапазон Дат** + +```json +# Фильтрация Памяти За Декабрь 2025 Года +"filter" : { + "and": [ + {"create_time": {"gt": "2025-12-01"}}, + {"create_time": {"lt": "2026-01-01"}} + ] +} + +# Фильтрация Недавних Обновлений Памяти +"filter" : { + "and": [ + {"update_time": {"gt": "2025-12-10"}} + ] +} +``` + +**Многомерность** + +```json +# Фильтрация Памяти Пользователя По Вопросам Счетов С Помощником Клиентской Поддержки В Q4 +"filter" : { + "and": [ + {"agent_id": "customer_service"}, + {"scene":"счет"}, + {"create_time": {"gt": "2025-10-01"}}, + {"create_time": {"lt": "2026-01-01"}} + ] +} +``` diff --git a/content/ru/memos_cloud/features/basic/multimodal.md b/content/ru/memos_cloud/features/basic/multimodal.md new file mode 100644 index 00000000..b2e45d76 --- /dev/null +++ b/content/ru/memos_cloud/features/basic/multimodal.md @@ -0,0 +1,413 @@ +--- +title: Мультимодальные Сообщения +desc: При добавлении сообщения интегрируйте изображения и документы в взаимодействие с MemOS. +--- +::warning +**[Данная статья является развернутым описанием того, как добавлять мультимодальные данные в интерфейсе 【Добавить Память-addMessage】, вы можете нажать здесь, чтобы напрямую просмотреть подробную документацию API](/api_docs/core/add_message)** +:: + +MemOS поддерживает не только текст, но и мультимодальные данные, включая документы и изображения. Пользователи могут бесшовно интегрировать текст, документы и изображения в взаимодействие с MemOS, позволяя системе извлекать соответствующую информацию из различных типов медиа, обогащать содержание памяти и улучшать возможности системы памяти. + +## 1. Как Добавить Мультимодальное Сообщение + +:::note +Внимание
+Когда сообщение содержит мультимодальное содержимое, поле `async_mode`, переданное вами, становится недействительным из-за длительного времени обработки файловой памяти, в этом случае по умолчанию используется "асинхронный режим". Вы можете проверить прогресс обработки файловой памяти через интерфейс `get/status`. +::: + +Когда пользователь загружает документы или изображения, MemOS извлекает текст, визуальную информацию и другие соответствующие детали и обрабатывает их в память пользователя. + +:::note +**Мультимодальные Сообщения и Инструментальная Память** + +Кроме обработки содержимого документов и изображений, MemOS также поддерживает обработку информации о вызовах инструментов. Когда вы добавляете информацию о вызовах инструментов в сообщение, система обрабатывает ее как инструментальную память, включая информацию об инструменте (Tool Schema) и память о траектории инструмента (Tool Trajectory Memory). Подробности см. в [Вызов Инструментов](/memos_cloud/features/advanced/tool_calling). +::: + +### Добавить Сообщение + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "1211", + "messages": [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "Я изучаю MemOS." + }, + { + "type": "image_url", + "image_url": { + "url": "https://cdn.memtensor.com.cn/img/1758706201390_iluj1c_compressed.png" + } + } + ] + }, + {"role": "assistant", "content": "Хорошо, нужно ли мне ответить на ваш вопрос?"} + ] + } +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(json.dumps(res.json(), indent=2, ensure_ascii=False)) +``` + +### Извлечь Память + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "query": "Помогите мне подвести итоги этой картинки", + "user_id": "memos_user_123", + "conversation_id": "1214" +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/search/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +# Замените часть печати +print("Результат:") +print(json.dumps(res.json(), indent=2, ensure_ascii=False)) +``` + +### Выходные Результаты +```python +{ + "code": 0, + "data": { + "memory_detail_list": [ + { + "id": "a5136287-de10-4df2-afc5-e412cdb8b649", + "memory_key": "Изучение MemOS", + "memory_value": "Пользователь изучает MemOS и делится связанной картинкой, время - 18 декабря 2025 года, 7:07 (UTC).\n"," + "memory_type": "WorkingMemory", + "create_time": 1766041646311, + "conversation_id": "1211", + "status": "activated", + "confidence": 0.99, + "tags": [ + "Изучение", + "MemOS", + "Поделиться картинкой" + ], + "update_time": 1766041689234, + "relativity": 0.5170716 + }, + { + "id": "4a1d42f4-c9fa-41bf-805d-2ea985bba984", + "memory_key": "Обзор функций MemOS", + "memory_value": "MemOS - это интеллектуальная система памяти, которая может хранить информацию, добавляя пути, и извлекать информацию с помощью функции запроса. Система поддерживает различные форматы документов, такие как PDF и DOC, и использует ИИ для интеллектуального ответа и обработки.\n"," + "memory_type": "WorkingMemory", + "create_time": 1766041689091, + "conversation_id": "1211", + "status": "activated", + "confidence": 0.99, + "tags": [ + "MemOS", + "Интеллектуальная память", + "Хранение информации", + "Функция запроса", + "image", + "visual" + ], + "update_time": 1766041689234, + "relativity": 0.38406307 + } + ], + "preference_detail_list": [], + "tool_memory_detail_list": [], + "preference_note": "" + }, + "message": "ok" +} +``` + +## 2. Типы Медиа + +MemOS в настоящее время поддерживает следующие типы медиа: + +1. **Изображения** - JPG, PNG и другие распространенные форматы изображений + +2. **Документы** - PDF, DOCX, DOC, TXT, JSON, MD, XML + + +## 3. Ограничения на Загрузку Файлов + +1. При добавлении сообщения количество файлов, загружаемых за один запрос, не должно превышать 20, размер одного файла не должен превышать 100 МБ и 500 страниц. Обратите внимание: входной лимит для интерфейса `add/message` составляет 20,000 токенов. + +2. Если количество файлов, размер одного файла или количество страниц превышает указанные ограничения, данная задача будет считаться "неудачной". Вам необходимо скорректировать запрос в соответствии с ограничениями и повторно его отправить. + + +## 4. Примеры Использования + +### Загрузить Сообщение С Изображением + +**Использовать URL Изображения** + +При добавлении сообщения вы можете напрямую загрузить URL изображения. + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "1211", + "messages": [ + { + "role": "user", + "content": [ + { + "type": "image_url", + "image_url": { + "url": "https://cdn.memtensor.com.cn/img/1758706201390_iluj1c_compressed.png" + } + } + ] + } + ] + } +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(json.dumps(res.json(), indent=2, ensure_ascii=False)) +``` + +**Использовать Кодирование Изображения Base64 Для Загрузки Локального Изображения** + +Для загрузки локального изображения или его прямого встраивания можно использовать кодирование изображения Base64. + +```python +import os +import requests +import json +import base64 + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +# Путь к файлу изображения +image_path = "path/to/your/image.jpg" + +# Кодирование изображения с помощью Base64 +with open(image_path, "rb") as image_file: + base64_image = base64.b64encode(image_file.read()).decode("utf-8") + + +data = { + "user_id": "memos_user_123", + "conversation_id": "1211", + "messages": [ + { + "role": "user", + "content": [ + { + "type": "image_url", + "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"} + } + ] + } + ] +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(json.dumps(res.json(), indent=2, ensure_ascii=False)) +``` + +### Загрузить Сообщение С Документом + +**Использовать URL Документа** + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "1211", + "messages": [ + { + "role": "user", + "content": [ + { + "type": "file", + "file": { + "file_data": "https://cdn.memtensor.com.cn/file/MemOS 2.pdf" + } + } + ] + } + ] + } +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(json.dumps(res.json(), indent=2, ensure_ascii=False)) +``` + +**Использовать Кодирование Изображения Base64 Для Загрузки Локального Документа** + +```python +import os +import requests +import json +import base64 + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +# Путь к файлу документа +document_path = "path/to/your/document.pdf" + +# Функция для преобразования файла в строку Base64 +def file_to_base64(file_path): + with open(file_path, "rb") as file: + return base64.b64encode(file.read()).decode('utf-8') + +# Кодирование документа с помощью Base64 +base64_document = file_to_base64(document_path) + +data = { + "user_id": "memos_user_123", + "conversation_id": "1211", + "messages": [ + { + "role": "user", + "content": [ + { + "type": "file", + "file": {"file_data": base64_document} + } + ] + } + ] +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print("Результат:") +print(json.dumps(res.json(), indent=2, ensure_ascii=False)) +``` + +### Полный Пример + +Вот полный пример, демонстрирующий, как добавить сообщение диалога пользователя с помощником, включающее различные типы медиа: + +```python +import os +import json +import requests + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "1211", + "messages": [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "Я изучаю MemOS." + } # Текстовое сообщение + ] + }, + { + "role": "user", + "content": [ + { + "type": "image_url", + "image_url": { + "url": "https://cdn.memtensor.com.cn/img/1758706201390_iluj1c_compressed.png" + } + } # Загрузка изображения + ] + }, + { + "role": "user", + "content": [ + { + "type": "file", + "file": { + "file_data": "https://cdn.memtensor.com.cn/file/MemOS 2.pdf" + } + } # Загрузка документа + ] + } + ] +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) +print(json.dumps(res.json(), indent=2, ensure_ascii=False)) +``` diff --git a/content/ru/memos_cloud/introduction/algorithm.md b/content/ru/memos_cloud/introduction/algorithm.md new file mode 100644 index 00000000..fe0ac492 --- /dev/null +++ b/content/ru/memos_cloud/introduction/algorithm.md @@ -0,0 +1,133 @@ +--- +title: Обзор Алгоритма MemOS +desc: Позволить большим моделям эволюционировать из одноразовых инструментов диалога в настоящие интеллектуальные агенты с долгосрочной памятью и адаптивными способностями. +--- + +::note +Подсказка
Адрес статьи: https://arxiv.org/abs/2507.03724 +:: + +## 1. Что такое MemOS? + +Современные большие языковые модели (LLM) уже продемонстрировали мощные способности к генерации и рассуждению, но они в целом лишены настоящей «памяти». + +* В многократных диалогах они часто забывают раннюю информацию; + +* В прикладных сценариях они не могут закрепить персонализированные предпочтения пользователей; + +* При итерации знаний они обновляются медленно и не могут гибко реагировать на новые требования. + +Это делает LLM, хотя и «умными», трудными для того, чтобы стать настоящими **учителями, коллегами или помощниками**. + + +
+ +**MemOS (Система Памяти)** была предложена именно для решения этого фундаментального недостатка. +Она поднимает «память» из разрозненной функции до уровня **системного ресурса**, столь же важного, как вычислительная мощность, предоставляя LLM: + +* **Единый уровень памяти**: охватывает отдельные диалоги, поддерживает долгосрочное накопление знаний и управление контекстом; + +* **Способности к долговременному хранению и структурированию**: позволяет памяти сохраняться, отслеживаться и повторно использоваться; + +* **Усиленное рассуждение на основе памяти**: при рассуждении использует исторический опыт и предпочтения, генерируя ответы, более соответствующие потребностям пользователей. + + +
+ +По сравнению с традиционными подходами (такими как простое полагание на параметрическую память или временный KV кэш), ценность MemOS заключается в том, что: + +* Она позволяет ИИ больше не быть «забудь, что видел», а продолжать эволюционировать и учиться; + +* Она может не только отвечать на текущие вопросы, но и использовать накопленный опыт для улучшения будущих результатов; + +* Она предоставляет разработчикам единый интерфейс, превращая «память» из сложной самописной логики в стандартизированную способность. + + +
+ +Короче говоря, цель MemOS заключается в том, чтобы: +**позволить большим моделям эволюционировать из одноразовых инструментов диалога в настоящие интеллектуальные агенты с долгосрочной памятью и адаптивными способностями.** + + +## 2. Дизайн Архитектуры MemOS + +Ядро дизайна MemOS заключается в том, чтобы рассматривать «память» как независимый уровень системы, который, наряду с вычислениями и хранением, становится базовой способностью AI-приложений. Его общая архитектура может быть обобщена как **трехуровневая структура**: **Уровень API и интерфейсов приложений, уровень управления и планирования памяти, уровень хранения памяти и инфраструктуры** + +![art.gif](https://statics.memtensor.com.cn/memos/art.gif) + +* На **Уровне API и интерфейсов приложений** MemOS предоставляет стандартизированный Memory API, разработчики могут реализовать операции **создания, удаления, обновления памяти** через простой интерфейс, позволяя большой модели обладать долговременной памятью, легко вызываемой и расширяемой, поддерживающей многократные диалоги, долгосрочные задачи и персонализацию между сессиями в сложных прикладных сценариях. + + +> Здесь `API уровень` относится к стандартизированному дизайну интерфейса внутри фреймворка, используемому для объяснения принципов системы и границ возможностей. **В отличие от интерфейсов разработки, предоставляемых облачными сервисами** (таких как `add`, `search` и другие упрощенные обертки), последние являются единым входом, основанным на абстракции возможностей MemOS на бэкенде. + + +
+ +* На уровне управления и планирования памяти MemOS предлагает **новую парадигму планирования памяти (Memory Scheduling)**, поддерживающую контекстуальное **«предсказание следующей сцены» (Next-Scene Prediction),** которое может заранее загружать потенциально необходимые фрагменты памяти во время генерации модели, значительно снижая задержку ответа и повышая эффективность рассуждения. + + +
+ +* А на **уровне хранения памяти и инфраструктуры,** MemOS через стандартизированный **MemCube** органически интегрирует три формы памяти: открытая память, активированная память и параметрическая память. Он поддерживает различные способы долговременного хранения, включая графовые базы данных, векторные базы данных и обладает **возможностями переноса и повторного использования памяти между моделями.** + + +
+ Стандартизированная MemCube(记忆立方体)的基础构成 +
Стандартизированная MemCube(记忆立方体)的基础构成
+
+ + +## 3. Почему MemOS эффективен? + +:::note{icon="ri:message-2-line"} +От Next-Token Prediction до Next-Scene Prediction +::: + +* В традиционных системах вопросов и ответов на основе больших моделей процесс генерации по-прежнему следует **синхронному механизму Next-Token**: модель получает вопрос пользователя → в реальном времени извлекает внешние фрагменты → генерирует ответ по токенам, слово за словом. + +* Любая задержка, возникающая при извлечении или вычислении, напрямую удлиняет всю цепочку вывода, инъекция знаний и генерация тесно связаны, что приводит к тому, что GPU часто простаивает, а задержка ответа на стороне пользователя становится заметной. + +* В отличие от этой традиционной парадигмы, MemOS с точки зрения моделирования памяти предлагает **парадигму планирования памяти**, создавая асинхронную структуру планирования, которая заранее предсказывает информацию о памяти, необходимую модели, что значительно снижает потери эффективности в процессе реальной генерации. + +* MemOS реализует **совместное планирование** для трех основных типов памяти в MemCube (параметрическая память, активная память, открытая память), а также для внешних баз знаний (включая интернет-извлечение и огромные локальные знания). + +* Опираясь на точное восприятие диалоговых раундов и временных задержек, система может интеллектуально предсказывать содержимое памяти, которое может быть вызвано в следующем сценарии, и динамически маршрутизировать и предварительно загружать необходимую открытую, параметрическую и активную память, что позволяет сразу же достичь максимальной эффективности ввода информации и плавности вывода. + + +![640.gif](https://statics.memtensor.com.cn/memos/ani.gif) + +
+ Основная идея планирования памяти +
Основная идея планирования памяти
+
+ + +## 4. Подробная Оценка Производительности Версии MemOS-Preview + +### 4.1 Оценка Памяти LoCoMo + +* Для системной проверки производительности MemOS в реальных приложениях команда MemOS провела всестороннюю оценку на основе **набора данных LoCoMo**. + +* В качестве широко признанного в отрасли эталона управления памятью, LoCoMo был принят многими основными фреймворками для проверки способности модели к доступу к памяти и согласованности многократных диалогов. + +* Судя по официально опубликованным данным оценки, **MemOS достиг значительного повышения как в точности, так и в вычислительной эффективности**, по сравнению с глобальным решением памяти OpenAI, продемонстрировав лучшие показатели по ключевым метрикам, что дополнительно подтверждает его техническое превосходство в области планирования памяти, управления и интеграции вывода. + + +![image.png](https://cdn.memtensor.com.cn/img/1758687655761_blkqnr_compressed.png) + + +### 4.2 Оценка Памяти KV Cache + +* Кроме общей оценки памяти, исследовательская группа также сосредоточила внимание на фактическом эффекте механизма памяти KV Cache, предложенного MemOS, в ускорении вывода. + +* Путем проведения сравнительных тестов на различных длинах контекста (Короткий/Средний/Длинный) и различных масштабах моделей (8B/32B/72B) была системно оценена время построения кэша (Build), **время ответа первого токена (TTFT) и общий коэффициент ускорения (Speedup)** и другие ключевые метрики. + +* Результаты эксперимента (см. рисунок 10) показывают, что **MemOS значительно оптимизировал эффективность построения и повторного использования KV Cache при различных конфигурациях**, что сделало процесс вывода более эффективным и плавным, эффективно сократив время ожидания пользователей и обеспечив значительное ускорение производительности в сценариях с большими моделями. + + +![image.png](https://cdn.memtensor.com.cn/img/1758687596553_iptom0_compressed.png) + + +## 5. Следующие Шаги + +* Узнайте о [облачных услугах и открытых решениях](/memos_cloud/cloud_and_opensource), чтобы испытать мощь MemOS! diff --git a/content/ru/memos_cloud/introduction/mem_lifecycle.md b/content/ru/memos_cloud/introduction/mem_lifecycle.md new file mode 100644 index 00000000..3b4d59d2 --- /dev/null +++ b/content/ru/memos_cloud/introduction/mem_lifecycle.md @@ -0,0 +1,140 @@ +--- +title: Управление Жизненным Циклом Памяти +desc: В MemOS память не является статичной, а постоянно эволюционирует со временем и в зависимости от использования. +--- + + +## 1. Введение в Возможности +Память с момента её создания может постепенно превращаться в стабильные долгосрочные предпочтения или может быть очищена из-за устаревания или неэффективности. +:::note +**Подсказка**
+Этот процесс эволюции называется **управлением жизненным циклом памяти**, и его цель — поддерживать память "чистой и упорядоченной"
+ +* **Недавние полезные записи** остаются активными, чтобы их можно было вызывать в любое время;
+ +* **Долгосрочные стабильные факты** оседают, уменьшая повторения и шум;
+ +* **Устаревшая или конфликтующая информация** архивируется или удаляется, чтобы гарантировать согласованность и соответствие.
+::: +> Следует отметить, что управление жизненным циклом фокусируется на **эволюции записей памяти на уровне хранения**; а конкретно в одном выводе "вызывать ли определённую память", по-прежнему решает механизм планирования. + +
+ +:::note{icon="ri:customer-service-2-fill"} +**Введение В Этапы Жизненного Цикла** +::: + +| **Этап** | **Описание** | **Поведение Системы** | +| ---- | --- | --- | +| Generated
生成 | Новые объекты памяти, содержащие метаданные, такие как источник, временная метка, уровень доверия и т. д. | Изначально сохраняются в хранилище, ожидая дальнейшего использования | +| Activated
激活 | Ссылаются в процессе вывода или задачи, переходят в состояние высокой активности | Легче выбираются механизмом планирования | +| Merged
合并 | Имеют семантическое перекрытие с исторической памятью или данные, дополненные пользователем, система объединяет их в новую версию | Несколько записей сжимаются и объединяются, формируя обновленный стабильный элемент | +| Archived
归档 | Долгое время не использовались, автоматически понижаются до состояния холодного хранения | Активируются только при специальном поиске или обратном отслеживании | +| Expired
过期,可选 | После архивирования дополнительно истекают или признаются недействительными по политике | Удаляются из индекса, больше не участвуют в выводе, оставляя только минимальный журнал | +| Frozen
冻结,特殊状态 | Ключевая или соответствующая память заблокирована, изменения не допускаются | Сохраняются полные исторические версии, поддерживают аудит и соответствие | + + +## 2. Пример: Жизненный Цикл Памяти Онлайн-Образовательного Ассистента + +:::note{icon="ri:message-2-line"} +Предположим, вы используете MemOS для создания **онлайн-образовательного ассистента**, который помогает студентам решать математические задачи. +::: + +**Сгенерировано (Generated)** + +* Студент, используя систему в первый раз, говорит: "Я всегда путаю квадратные и линейные функции." + +* Система извлекает память: + + +```json +{"fact": "Студенты часто путают квадратичные и линейные функции", "confidence": 0.8, "timestamp": "2025-09-11"} + +``` + +* Состояние: **Сгенерировано** + +* Действие: сохранено в хранилище памяти, ожидая последующего использования. + + +--- + +**Активировано (Activated)** + +* В последующих попытках решения задач система часто вызывает эту память для помощи в решении. + +* Состояние: **Активировано** + +* Действие: приоритетно кэшируется в MemoryCube, чтобы повысить скорость поиска. + + +--- + +**Объединено (Merged)** + +* С увеличением взаимодействий система обнаруживает, что студент путает не только линейные и квадратные функции, но и экспоненциальные функции. + +* Система объединяет несколько схожих записей в: + + +```json +{"fact": "У этого студента есть путаница в знаниях о функциях, особенно линейных, квадратичных и экспоненциальных функциях", "confidence": 0.95} + +``` + +* Состояние: **Объединено** + +* Действие: старые записи сжимаются, формируя новую версию, уменьшая избыточность. + + +--- + +**Архивировано (Archived)** + +* Через три месяца студент освоил связанные с функциями темы, и система давно не вызывала эту память. + +* Состояние: **Архивировано** + +* Действие: перемещено в MemVault (холодное хранилище), по умолчанию не участвует в выводах, но может быть вызвано в "обратном отслеживании учебной траектории". + + +--- + +**Истекло (Expired)** + +* Еще через год студент перешел на новый уровень обучения, старая память "путаница с функциями в средней школе" была признана стратегией недействительной. + +* Состояние: **Истекло** + +* Действие: полностью очищено из индекса, оставляя только минимальную информацию для аудита: + + +```json +{"deleted_fact_id": "12345", "deleted_at": "2026-09-11"} + +``` +--- + +**Заморожено (Frozen, специальное состояние)** + +* В то же время "отчет об оценке за семестр" этого студента является документом соответствия и не подлежит изменению. + +* Состояние: **Заморожено** + +* Действие: заблокировано, обновление запрещено, сохраняется полная история изменений для удобства аудита и проверки соответствия. + + +## 3. Продвинутый: Если Вы Хотите Сделать Глубокую Настройку + +| **Точки Расширения** | **Описание** | **Пример** | +| --- | --- | --- | +| Условия Перехода Состояний | Контроль условий активации различных состояний | "Если не использовалось 7 дней → архивировать" | +| Объединение и Сжатие | Определение способов обработки схожих воспоминаний | Несколько "нравятся научно-фантастические фильмы" объединяются в одно более достоверное утверждение | +| Разрешение Конфликтов | Обработка воспоминаний с противоречивыми временными метками или источниками | Выбор "новейшее заменяет старую запись" или "сохранить параллельно" | +| Механизм Очистки | Установка условий удаления, контроль размера индекса | Удаление воспоминаний с низкой достоверностью или отозванных пользователем | +| Аудит Трассировки | Определение, сохранять ли минимальную метаинформацию о удаленных записях | Включение "журнала отслеживания" в соответствии с требованиями соблюдения | + + +## 4. Следующие Шаги + +Есть вопросы? Посмотрите [Часто Задаваемые Вопросы](/memos_cloud/faq), возможно, они смогут вам помочь~ diff --git a/content/ru/memos_cloud/introduction/mem_production.md b/content/ru/memos_cloud/introduction/mem_production.md new file mode 100644 index 00000000..fa148dd5 --- /dev/null +++ b/content/ru/memos_cloud/introduction/mem_production.md @@ -0,0 +1,137 @@ +--- +title: Производство Памяти +desc: Модуль производства памяти преобразует исходные сообщения, события или знания в хранимые и доступные для поиска единицы памяти, служащие отправной точкой для всего процесса MemOS. +--- + +::warning +**[直接看 API文档 点这里哦](/api_docs/core/add_message)** +
+
+ +**Данный документ сосредоточен на функциональном описании, подробные поля интерфейса и ограничения можно посмотреть, нажав на текстовую ссылку выше** +:: + +## 1. Введение в Возможности: Почему Необходимо Обрабатывать Исходные Сообщения в Память + +В MemOS вы отправляете **исходную информацию** (диалоги пользователя с AI, журналы операций пользователя в приложении / действия, документы базы знаний и т.д.), система автоматически завершает процесс "памяти". + +::note{icon="ri:triangular-flag-fill"} +**Почему Необходимо Обрабатывать Память?** +:: + +Если просто сохранить всю исходную информацию и затем передать её большой модели, возникнут несколько проблем: + +- **Слишком Длинный Контекст**: Исходная информация обычно громоздка и содержит много повторяющегося и нерелевантного контента, передача целого блока в модель значительно увеличивает окно контекста, снижает эффективность обработки и расходует токены; +- **Неточная Поиск**: Необработанный и неструктурированный исходный текст трудно выделить ключевую информацию из диалога, при поиске легко вернуть много шумового контента, что влияет на качество ответов; +- **Непрерывность Опыта**: Исходный диалог является одноразовым статическим текстом, не может учитывать изменения предпочтений и эмоций пользователя, бизнес-контекста и правил, что приводит к искажению опыта непрерывного диалога. + +
+ +::note +**Что Такое Память После Обработки MemOS?** +:: + +MemOS преобразует исходные сообщения в структурированные единицы памяти, автоматически извлекая: + +- **Ключевые Факты**: + - Извлечение фактической информации из диалога пользователя, например, "пользователь планирует поехать в Гуанчжоу на летние каникулы 2025 года."; +- **Предпочтения Пользователя**: + - Извлечение явных выражений предпочтений пользователя в диалоге, например, "пользователь упомянул, что любит путешествовать с семьей"; + - Извлечение скрытых логических паттернов предпочтений пользователя, например, "пользователь, вероятно, предпочитает отели с хорошим соотношением цены и качества"; + - MemOS будет сохранять паттерны предпочтений пользователя, направляя модель на поддержание согласованности в последующих ответах. Например, когда пользователь использует AI для помощи в написании, демонстрируя "предпочтение к логически ясному стилю", MemOS будет продолжать направлять модель на поддержание "логического стиля написания" в других задачах. + +
+ +**Пример**: + +```json +User: Я запланировал поездку в Гуанчжоу на летние каникулы, какие сетевые отели доступны для проживания? +Assistant: Вы можете рассмотреть 【Семь Дней, Цюань Цзи, Хилтон】 и так далее. +User: Я выбрал Семь Дней. +Assistant: Хорошо, если будут другие вопросы, спрашивайте. +``` + +```json +Фактическая память: Пользователь планирует поездку в Гуанчжоу на летние каникулы и выбрал сеть отелей Семь Дней в качестве варианта проживания. + +Предпочтительная память: Пользователь, возможно, предпочитает отели с хорошим соотношением цены и качества. +Логика: Отели Семь Дней обычно известны своей экономичностью, и выбор пользователя в пользу Семь Дней может указывать на его склонность к выбору вариантов с хорошим соотношением цены и качества. Хотя пользователь не упомянул о бюджетных ограничениях или конкретных предпочтениях в отелях, выбор Семь Дней среди предложенных вариантов может отражать акцент на цене и практичности. +``` + +> Для вас это означает: достаточно сохранить исходный диалог, не нужно самостоятельно писать логику "извлечения ключевых слов" или "распознавания намерений", чтобы получить предпочтения пользователя, которые могут быть использованы в долгосрочной перспективе. + +
+ +Кроме текстовых диалоговых сообщений, для выполнения задач Agent, MemOS адаптировал память инструментов и навыков: +- **[Память Инструментов (tool memory)](/memos_cloud/features/advanced/tool_calling)**: + - Извлечение информации о вызовах инструментов в процессе выполнения задач Agent в память, запись типа инструмента, сценария использования и характеристик результатов вызова для последующего приоритета выбора инструментов в аналогичных задачах. +- **[Навыки (Skills)](/memos_cloud/features/advanced/skill)**: + - Извлечение диалога пользователя, создание повторно используемых исполнительных возможностей. + - Например, из многократного диалога о "генерации туристического плана" извлекается исполняемый "навык туристического планирования", который включает анализ мест назначения, разбивку маршрута и бюджетные ограничения, а не просто "пользователь любит путешествовать как спецназ" как память для логического вывода модели. + +Кроме того, MemOS также поддерживает обработку памяти на основе [базы знаний](/memos_cloud/features/advanced/knowledge_base) и [мультимодальных сообщений](/memos_cloud/features/basic/multimodal)! + +
+ +::note +**Как Обрабатывается Память?** +:: + +MemOS всегда считает, что память не является статической записью, а является объектом, который эволюционирует со временем, и она должна быстро, точно и непрерывно запоминать пользователя. +
+Чтобы лучше справляться с треугольной проблемой памяти: актуальность, точность, согласованность, MemOS разбивает весь процесс обработки памяти на следующие три этапа: +| Этап | Цель | Особенности | +| ------- | ------------ | ----------------------------------------------------------------------- | +| Быстрый | Не терять память | Простая обработка оригинала и быстрая запись, время обработки в миллисекундах, доступно для поиска в следующем раунде диалога. | +| Тонкий | Ближайшая организация | Обратный анализ текущего контекста и исторической памяти, если обнаружены конфликты, будет создана новая версия на основе оригинального Memory ID. | +| Офлайн | Глобальная организация | Регулярный долгосрочный анализ, исправление ранее нераспознанных конфликтов, поддержание общей согласованности. | + +Результат не является двумя конфликтующими воспоминаниями, а является: **Цепочка Эволюции Времени V1 / V2 / V3… для Одного Итого Memory ID** + +
+ +**Пример**: + +```json +# Предположим, что 2025 год +User: Я Сяо И, сейчас живу в Шанхае, не могу есть острое. + +# Предположим, что 2026 год +User: Недавно я переехал в Чэнду и внезапно полюбил сычуаньский хот-пот, люблю острые блюда! +``` + +```json +Память версии 1: Пользователь по имени Сяо И, живет в Шанхае, не может есть острое. +Память версии 2: Пользователь по имени Сяо И, живет в Чэнду, любит острое, любит сычуаньский хот-пот. +``` + +>Таким образом, одно и то же воспоминание может эволюционировать со временем, предоставляя "надежное текущее восприятие", одновременно сохраняя полную историческую траекторию. + +
+ +Таким образом, мы решили изначально упомянутую проблему: +- **Более эффективный вызов**: при соединении с большой моделью нужно передавать только отфильтрованную память, что снижает потребление токенов. +- **Быстрый и точный поиск**: прямое обращение к фактам / предпочтениям / инструментам / навыкам памяти, а не к целому оригинальному сообщению. +- **Более стабильный опыт**: модель может постоянно поддерживать понимание привычек пользователя и не отклоняться из-за потери контекста. + +
+ +## 2. Продвинутый: Если Вы Хотите Сделать Глубокую Настройку + +В MemOS **производство памяти** — это весь процесс обработки исходного ввода в планируемые и доступные для поиска единицы памяти. Конкретные детали конвейера (такие как методы извлечения, модели встраивания, хранилище) будут постоянно эволюционировать с версиями и практикой сообщества — поэтому в этом разделе не предоставляется фиксированный уникальный процесс, а объясняются **расширяемые этапы**, где вы можете вносить изменения в зависимости от ваших потребностей. + +| **Примеры точек расширения** | **Поведение по умолчанию** | **Способы настройки** | +| ------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------- | +| Извлечение И Структурирование | По Умолчанию Будет Сгенерирован MemoryItem (Содержит Содержимое, Временную Метку, Источник И Т.Д.) | Можно Заменить Модель Извлечения Или Шаблон, Или Добавить Поля Области В schema | +| Разделение И Встраивание | Система Будет Разделять Длинные Тексты И Отправлять В Модель Встраивания | Можно Настроить Гранулярность Разделения, Или Заменить На Более Подходящую Модель embedding (Например bge, e5) | +| Хранилище Заднего Плана | По Умолчанию Используется Векторная База Данных (Например Qdrant) | Можно Переключиться На Графовую Базу Данных, Или Смешанное Использование Оба | +| Объединение И Управление | Система Автоматически Обрабатывает Дубликаты И Конфликты | Можно Написать Пользовательские Правила (Например Приоритет Времени, Приоритет Источника) И Т.Д. | + + +## 3. Следующие Действия + +Узнайте больше о ключевых возможностях MemOS + +- [Планирование Памяти](/memos_cloud/introduction/mem_schedule) +- [Восстановление Памяти](/memos_cloud/introduction/mem_recall) +- [Управление Жизненным Циклом Памяти](/memos_cloud/introduction/mem_lifecycle) diff --git a/content/ru/memos_cloud/introduction/mem_recall.md b/content/ru/memos_cloud/introduction/mem_recall.md new file mode 100644 index 00000000..a23d92db --- /dev/null +++ b/content/ru/memos_cloud/introduction/mem_recall.md @@ -0,0 +1,55 @@ +--- +title: Воспоминание + desc: В MemOS воспоминание — это не просто архив информации, но и возможность динамически извлекать его по мере необходимости и преобразовывать в исполняемый ввод. +--- + +::warning +**[Прямо Смотрите Документацию API, Нажмите Здесь](/api_docs/core/search_memory)** +
+
+ +**Данная статья сосредоточена на функциональном описании, подробные поля интерфейса и ограничения можно посмотреть, нажав на текстовую ссылку выше** +:: + +## 1. Введение В Возможности + +Воспоминание отвечает за быструю выборку наиболее релевантных фрагментов памяти при инициировании нового запроса пользователем. + +* **Функция**: гарантирует, что модель при генерации ответа не начинает "с нуля", а учитывает историю, предпочтения и контекст пользователя. + +* **Результаты**: Воспоминания включают четыре типа: факты / предпочтения / инструменты / навыки. + + * Возможность отслеживания: каждое воспоминание сопровождается источником, временной меткой и уровнем доверия. + + * Высокая управляемость: разработчики могут полностью контролировать, какие воспоминания попадают в последующую логику. + +* **Особенности**: + + * Непринужденное воспоминание: пользователю не нужно повторно объяснять свои предыдущие выборы или предпочтения + + * Структурированный вывод: различение типов воспоминаний, что облегчает разработчикам контроль над тем, следует ли их внедрять + +* **Поддержка функций**: + * [Установить фильтры](/memos_cloud/features/basic/filters): только извлечение диалогов за последние 30 дней; только предпочтения, без фактов и т.д. + + * [Настроить стратегию воспоминания](memos_cloud/mem_operations/search_memory): повысить порог схожести, возвращать только воспоминания с уровнем доверия ≥0.9 и т.д. + + * Воспоминания основаны на [базе знаний](/memos_cloud/features/advanced/knowledge_base), [мультимодальных сообщениях](/memos_cloud/features/basic/multimodal) + + +## 2. Продвинутый: Если Вы Хотите Сделать Глубокую Настройку + +В MemOS реализация воспоминания и дополнения не является единственным путем, а достигается комбинацией различных стратегий и компонентов. Разные сценарии могут требовать различных конфигураций, в этом разделе перечислены основные этапы и настраиваемые точки, чтобы вы могли гибко выбирать в зависимости от потребностей бизнеса. + +| **Уровень** | **Настраиваемые Пункты** | **Пример** | +| --- | --- | --- | +| Управление Выводом И Аудит | Безопасность | Автоматически добавлять фразу «Ответ должен соответствовать нормативным требованиям» перед командой дополнения | +| | Логи И Обратная Связь | Записывать используемые записи памяти и выбор few-shot при каждом вызове | +| | A/B Тестирование | Одновременно запускать две версии шаблонов, сравнивать различия в удовлетворенности пользователей | + + +## 3. Следующие Шаги + +Узнать больше о ключевых возможностях MemOS + +* [Управление Жизненным Циклом Памяти](/memos_cloud/introduction/mem_lifecycle) diff --git a/content/ru/memos_cloud/introduction/mem_schedule.md b/content/ru/memos_cloud/introduction/mem_schedule.md new file mode 100644 index 00000000..fc29f1a1 --- /dev/null +++ b/content/ru/memos_cloud/introduction/mem_schedule.md @@ -0,0 +1,176 @@ +--- +title: Память Распределение +desc: Память распределение похоже на механизм внимания мозга, динамически определяя, когда вызывать подходящую память в нужный момент. +--- + +## 1. Введение в Возможности + +В MemOS, **память распределение (Memory Scheduling)** позволяет модели более эффективно и точно получать необходимую пользователю память, путем взаимного распределения [различной эффективности использования (параметры>активация>работа>другие открытые данные)]. Во время диалога и выполнения задач, предсказывая необходимую память для последующих диалогов пользователя и заранее загружая высокоэффективные типы памяти, такие как активная память и рабочая память, ускоряется цепочка вывода. + +::note{icon="ri:triangular-flag-fill"} +**Почему Нужен Планировщик** +:: + +В сложных взаимодействиях, если каждый раз полагаться только на простые глобальные поиски, система может: + +* **Слишком медленно**: ждать, пока пользователь закончит вопрос, прежде чем временно искать, задержка первого токена высокая. + +* **Неточно**: слишком много истории, что затмевает ключевую информацию, трудно извлекать. + +
+ +Распределение позволяет системе иметь возможность "мгновенной подготовки и быстрой реакции": + +* **Предварительная загрузка**: в начале диалога загружать часто используемый контекст пользователя. + +* **Предсказание вызова**: заранее подготавливать память, которая может понадобиться, пока пользователь еще не закончил ввод. + + +
+ +::note +**Как распределять — сочетая семантику задачи, контекст, частоту доступа, жизненный цикл и другую информацию, динамически организовывать вызов и хранение памяти** +:: + +| Размерность | Описание | +| ------------ | --- | +| Что Планировать? | Параметрическая Память (Долгосрочные Знания и Навыки)

Активная Память (KV Cache и Состояние Скрытого Слоя во Время Выполнения)

Открытая Память (Редактируемые Факты, Предпочтения Пользователя, Фрагменты Поиска)

Поддержка Динамической Миграции `Открытая ⇆ Активная ⇆ Параметрическая`, Фрагменты Открытой Памяти, Используемые Часто, Могут Быть Предварительно Скомпилированы в KV Cache; Долгосрочные Стабильные Шаблоны Могут Быть Закреплены в Параметрах. | +| Когда Планировать? | Оптимизация Структуры Памяти Происходит, Когда Контекст и Эффективная Память Недостаточны для Ответа на Вопросы Пользователя

Подготовка Содержимого Памяти, Которое Может Понадобиться Пользователю, В Соответствии с Намерениями и Потребностями Пользователя

В Процессе Непрерывных Вопросов, Планировщик Памяти Поддерживает Высокую Эффективность и Точность Сценария Диалога | +| Для Кого Планировать? | Текущий Пользователь, Специфический Агент, Или Общий Контекст Между Задачами | +| Как Планировать? | Память Будет Оценена По Параметрам Актуальности, Времени, Важности И Т.Д. Планировщик На Основе Этого Решает, Кого Загружать В Первую Очередь, Кого Оставить В Холодном Хранении, Кого Необходимо Архивировать. | + +При использовании облачного сервиса MemOS, эффект распределения можно наблюдать по производительности `searchMemory` API: + +* Он может быстро возвращать соответствующую память, избегая разрывов в контексте. + +* Возвращаемый контент уже оптимизирован распределителем, чтобы гарантировать, что результаты как актуальны, так и не перегружают ввод модели. + + +## 2. Пример: Память Распределение в Сценарии Семейного Ассистента + +* Недавно: пользователь занят покупкой дома + +::card-group + + :::card + --- + title: Пользователь часто говорит: + --- + * "Помоги мне узнать среднюю цену на вторичное жилье в районе XX." + + * "Напомни мне в субботу посмотреть дом." + + * "Запиши последние изменения в процентной ставке по ипотеке." + ::: + + :::card + --- + title: ✨Операции Системы MemOS + --- + * Система изначально создает все эти записи как **открытые данные**. + + * Поскольку информация, связанная с "покупкой дома", упоминается часто, распределитель в фоновом режиме определяет, что это **основная тема** в последнее время, и поэтому переносит эти открытые данные в **активную память**, чтобы последующие запросы были быстрее и более прямыми. + ::: + +:: + + +
+ +* Недавно: пользователь купил дом и начал ремонт + +::card-group + + :::card + --- + title: Пользователь начинает часто упоминать: + --- + * "В выходные нужно посмотреть плитку." + + * "Напомни мне подтвердить водоснабжение и электрификацию с компанией по ремонту." + + * "Запомни время доставки мебели на следующей неделе." + ::: + + :::card + --- + title: ✨Операции Системы MemOS + --- + * Система продолжает создавать новые **открытые данные**. + + * Распределитель обнаруживает, что "ремонт" стал новой темой с высокой частотой, и поэтому переносит эти записи в **активную память**. + + * В то же время, ранее активная память, связанная с "покупкой дома", больше не используется часто и будет автоматически **понижена до открытого уровня**, чтобы уменьшить активное использование. + ::: + +:: + + +
+ +* **Текущий момент: пользователь говорит — я чувствую, что много дел накопилось, помоги мне разобраться** + +::card-group + + :::card + --- + title: Если бы не было распределения, система могла бы только выполнять поиск по всей базе данных, извлекая все потенциально связанные записи: + --- + * Смотреть плитку (ремонт) + +* Подтвердить водоснабжение и электрификацию (ремонт) + +* Доставка мебели (ремонт) + +* Проверить цены на жилье (период покупки дома, устарело) + +* Смотреть дом (период покупки дома, устарело) + +* Покупка продуктов (обычные дела) + +* Смотреть фильм (обычные дела) + +* ::: + + :::card + --- + title: ✨Когда есть распределение, система может быстрее возвращать + --- + * Смотреть плитку + +* Подтвердить водоснабжение и электрификацию + +* Доставка мебели + + +
+ + 👉 **Пользовательский опыт UP** + +* Ответы быстрее (поскольку не требуется поиск по всей базе данных). + +* Перечисленные — это именно те вещи, которые его больше всего беспокоят → ощущение, что ассистент "очень понимает меня". + ::: + +:: + + + + + +## 3. Продвинутый: Если вы хотите сделать глубокую настройку + +Разработчики могут настраивать поведение системы через **Расширенные Стратегии Планирования**, которые в основном включают: +| **Уровень** | **Точка Настройки** | **Пример** | +| --- | --- | --- | +| Разрешения и Управление | Совмещение контроля доступа и проверки соответствия при планировании | Медицинские записи видны только врачам; Чувствительный контент не может быть передан между доменами | +| Показатели Планирования | Оптимизация планирования на основе частоты доступа и требований к задержке | Повышение приоритета для высокочастотной горячей памяти; Понижение приоритета для низкочастотной холодной памяти и архивирование | + + +## 4. Следующие Шаги + +Узнать больше о ключевых возможностях MemOS + +* [Вызов Памяти](/overview/quick_start/mem_recall) + +* [Управление Жизненным Циклом Памяти](/overview/quick_start/mem_lifecycle) diff --git a/content/ru/memos_cloud/limit.md b/content/ru/memos_cloud/limit.md new file mode 100644 index 00000000..a3b455bf --- /dev/null +++ b/content/ru/memos_cloud/limit.md @@ -0,0 +1,43 @@ +--- +title: Квоты И Ограничения +desc: Регистрация и вход в систему предоставляют бесплатный лимит, что позволяет быстро испытать и проверить функции памяти. +--- + + +## 1. Описание Лимита + +![image.png](https://cdn.memtensor.com.cn/img/1766481509513_5d4x8o_compressed.png) + +MemOS облачный сервис в настоящее время предлагает разработчикам различные тарифные планы от бесплатной версии до корпоративной версии, чтобы удовлетворить потребности команд разного размера. В настоящее время все версии временно бесплатны, добро пожаловать на [MemOS Официальный Сайт - Цены](https://memos.openmem.net/cn/pricing), чтобы подать заявку на версию, соответствующую вашим потребностям. +Действуйте сейчас, наслаждайтесь безграничными возможностями, которые предоставляет MemOS облачный сервис, и помогите вашему проекту быстро расти! + +::note +**Внимание** +- Использование лимита накапливается совместно по всем проектам под каждой учетной записью разработчика. +- Ошибки запросов (ошибка аутентификации, ошибка параметров, превышение лимита и т.д.) **не расходуют лимит**. +:: + +## 2. Ограничения Ресурсов + +Чтобы обеспечить стабильность и безопасность сервиса, MemOS облачный сервис имеет следующие ограничения на вызовы основных интерфейсов, рассчитываемые по учетной записи: + +| **Название Интерфейса** | **Максимум Входных Токенов** | **Максимум Выходных Токенов** | +|----------------|------------------|--------------| +| addMessage | 20,000 token | - | +| searchMemory | 20,000 токенов | Фактическая Память: 25 записей
Предпочтительная Память: 25 записей
Инструментальная Память: 25 записей
Навыки: 25 записей | + +Кроме того, функции, связанные с загрузкой документов базы знаний, в настоящее время ограничены до одного файла не более 100 МБ, 500 страниц, 20,000 токенов, и общее количество загрузок за один раз не превышает 20. +Если у вас есть более высокие или специальные требования, пожалуйста, свяжитесь с командой проекта для обсуждения. + +::note +**Внимание** +- Когда запрос превышает одноразовый лимит, система сразу возвращает соответствующий код ошибки и не уменьшает количество вызовов. +- Кроме того, мы рекомендуем максимальный QPS ≤ 50 (то есть не более 50 запросов в секунду), это не строгое ограничение, но высокие параллельные запросы могут быть затронуты возможностями обработки платформы, пожалуйста, разумно контролируйте частоту вызовов в зависимости от фактических потребностей. +:: + +## 3. Мониторинг Использования + +Вы можете просмотреть оставшийся лимит для каждого интерфейса через **API Консоль**, а также поддерживать фильтрацию по проекту, ключу интерфейса и дате, что удобно для отслеживания и управления состоянием вызовов. + +![image.png](https://cdn.memtensor.com.cn/img/1766632358212_mxan3a_compressed.png) + diff --git a/content/ru/memos_cloud/mem_operations/add_feedback.md b/content/ru/memos_cloud/mem_operations/add_feedback.md new file mode 100644 index 00000000..f64c8d20 --- /dev/null +++ b/content/ru/memos_cloud/mem_operations/add_feedback.md @@ -0,0 +1,192 @@ +--- +title: Добавить Обратную Связь +desc: Добавить естественную языковую обратную связь от пользователей, MemOS автоматически обновит память. +--- + +::warning +**[Чтобы просмотреть документацию API, нажмите здесь](/api_docs/core/add_feedback)** +
+
+ +**Данный документ сосредоточен на описании функций, подробные поля интерфейса и ограничения смотрите по ссылке выше** +:: + +## 1. Когда Добавлять Обратную Связь? + +::note +Механизм обратной связи MemOS используется для получения естественной языковой обратной связи от пользователей по ответам модели, что позволяет автоматически корректировать и обновлять содержимое памяти, без необходимости разработчикам вручную находить конкретные записи памяти.
+С помощью отдельного интерфейса addFeedback достигается цель **снижения затрат на ручное обслуживание + повышения точности памяти + поддержки непрерывной самокоррекции**. +:: + +Как показано в таблице, в отличие от изменения конкретной памяти, механизм естественной языковой обратной связи более подходит для **реальных бизнес-процессов** и **не технических пользователей**. + +| Сравнительное Измерение | Обратная Связь На Естественном Языке | Точная Коррекция Памяти | +| ---------- | ---------------- | ------------------ | +| Способ Использования | Описание Проблемы Или Исправление Информации На Естественном Языке | Прямое Указание На Определённую Память Для Редактирования | +| Порог Входа Для Пользователей | Низкий, Подходит Для Нетехнических Пользователей | Высокий, Обычно Осуществляется Разработчиками Или Администраторами | +| Участие Системы | Система Автоматически Анализирует, Локализует И Связывает Обновления | Обновления Под Руководством Человека | +| Область Обновления | Может Влиять На Несколько Связанных Памятей | Обычно Влияет Только На Одну Память | +| Подходящие Сценарии | Исправление Ошибок В Диалогах, Устаревание Знаний, Изменение Бизнес-Правил | Точные Исправления, Структурированное Обслуживание | + +## 2. Ключевые Параметры + +* **Содержимое Обратной Связи (feedback\_content)**: Естественная языковая обратная связь пользователя по ответу модели, используемая для понимания потребностей в обновлении памяти. + +* **Диапазон Базы Знаний (allow_knowledgebase\_ids)**: База знаний, на которую указывает естественная языковая обратная связь пользователя, используемая для ограничения диапазона [памяти базы знаний](/memos_cloud/features/advanced/knowledge_base). + +* **Идентификатор Сессии (conversation\_id)**: Уникальный идентификатор сессии, связанный с содержимым естественной обратной связи пользователя, используемый для связи контекстной информации текущей обратной связи. + +## 3. Принцип Работы + +Как показано на рисунке, в примере с Chabot, пользователь нажимает кнопку "Обратная Связь" под ответом модели, заполняет обратную связь по этому ответу и отправляет. +![image.png](https://cdn.memtensor.com.cn/img/1770716602140_1z3yi5_compressed.png) + +В зависимости от содержимого обратной связи, сервер выполняет вызов интерфейса MemOS `add/feedback`, инициируя обновление памяти, без необходимости ручного вмешательства в память пользователя. + +- **Анализ Эффективности**: После отправки обратной связи MemOS анализирует содержимое обратной связи в контексте текущей сессии, определяя, является ли это действительной информацией и связано ли это с содержанием диалога, чтобы решить, следует ли инициировать процесс обновления памяти. + +- **Идентификация Типа Обновления**: MemOS автоматически классифицирует запросы на обновление памяти, инициированные обратной связью, на два типа: замена ключевых слов и семантическое обновление, и завершает определение на основе содержимого обратной связи и семантики контекста. + +- **Обновление Памяти**: В зависимости от результатов классификации выполняется операция обновления памяти, записываются новые данные, обновляются или заменяются существующие данные, которые конфликтуют, устарели или были исправлены. + - **Замена Ключевых Слов**: Поиск связанных записей памяти, содержащих целевые ключевые слова, и выполнение точечного обновления; + - **Семантическое Обновление**: Генерация новой семантической памяти на основе обратной связи пользователя, после чего происходит объединение или замена обновлений на основе связанных данных памяти. + + +## 4. Примеры Использования + +### Семантическое Обновление Памяти Базы Знаний + +В компаниях часто возникает проблема, когда политика/знания компании обновляются, а база знаний не обновляется вовремя. Попробуйте использовать самый простой способ взаимодействия, чтобы поддерживать базу знаний всегда актуальной. + +::note{icon="websymbol:chat"} + Сессия A: 2025-12-12 Произошло
+
+Финансовый директор в разговоре сообщает обратную связь: 【Максимальная сумма закупки офисного ПО составляет 600 юаней, а не 800 юаней】. +
+:: + +```python +import os +import requests +import json + +# Замените На Ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "1212", + "feedback_content": "Предел Закупок Офисного ПО Составляет 600 Юаней, А Не 800 Юаней.", + "allow_knowledgebase_ids":["idxxxxx"] # Замените На ID Созданной Выше Базы Знаний +} + +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/feedback" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` + +::note{icon="websymbol:chat"} + Сессия A: 2025-12-12 Произошло
+
+Любой другой пользователь, ищущий 【Политику Возмещения ПО】, получает новую высокоценную память: 【Максимальная сумма закупки офисного ПО составляет 600 юаней, а не 800 юаней】. +
+:: + +```python +import os +import requests +import json + +# Замените На Ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "1211", + "query": "Помогите Мне Узнать Лимит На Возмещение Закупок ПО.", + "knowledgebase_ids":["idxxxxx"] # Замените На ID Созданной Выше Базы Знаний +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/search/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + + +# Улучшение Вывода JSON +json_res = res.json() +print(json.dumps(json_res, indent=2, ensure_ascii=False)) +``` + +Результат вывода следующий (упрощенная версия): + +```python +"memory_detail_list": [ + { + "id": "8a4f3d2e-c417-4e53-bc25-54451abd5ac8", + "memory_key": "Правила Возмещения Закупок ПО (Пробная Версия)", + "memory_value": "Данная система предназначена для регламентации процессов закупки и возмещения расходов на различные программные обеспечения компании, требуя, чтобы все закупки программного обеспечения соответствовали установленным лимитам по категориям. Лимит закупки программного обеспечения для дизайна составляет 1000 юаней, что применимо к графическому дизайну, видеомонтажу и проектированию прототипов, примеры включают Photoshop и Premiere. Лимит закупки программного обеспечения для кода/разработки составляет 1500 юаней, охватывает IDE и фреймворки разработки, примеры включают PyCharm и Visual Studio. Лимит закупки офисного программного обеспечения составляет 800 юаней, применимо к редактированию документов и обработке таблиц, примеры включают пакет Office и WPS. Лимит закупки программного обеспечения для анализа данных составляет 1200 юаней, охватывает статистику данных и визуализацию, примеры включают Tableau и Power BI. Лимит закупки программного обеспечения для безопасности и защиты составляет 1000 юаней, применимо к антивирусам и брандмауэрам. Лимит закупки программного обеспечения для совместной работы/управления проектами составляет 900 юаней, примеры включают Jira и Slack. Лимит закупки программного обеспечения для специализированных отраслей составляет 2000 юаней и требует специального одобрения. Все закупки должны соответствовать бюджету компании и требованиям информационной безопасности, программное обеспечение, превышающее лимит, должно предоставить бизнес-обоснование и пройти специальное одобрение.", + "memory_type": "LongTermMemory", + "create_time": 1765525947718, + "conversation_id": "default_session", + "status": "activated", + "confidence": 0.99, + "tags": [ + "Закупка Программного Обеспечения", + "Система Возмещения Расходов", + "Процесс Одобрения", + "Бюджет", + "Информационная Безопасность", + "mode:fine", + "multimodal:file" + ], + "update_time": 1765525947720, + "relativity": 0.8931847 + }, + { + "id": "a72a04d1-d7ba-4ebd-9410-0097bfa6c20d", + "memory_key": "Лимит Закупки Офисного Программного Обеспечения", + "memory_value": "Пользователь подтвердил, что лимит закупки офисного программного обеспечения составляет 600 юаней, а не 800 юаней.", + "memory_type": "WorkingMemory", + "create_time": 1765531700539, + "conversation_id": "1212", + "status": "activated", + "confidence": 0.99, + "tags": [ + "Закупка", + "Офисное Программное Обеспечение", + "Бюджет" + ], + "update_time": 1765531700540, + "relativity": 0.7196722 + } +] +``` + +[Консоль - База Знаний](https://memos-dashboard.openmem.net/knowledgeBase/) отображает все детали памяти базы знаний, которые были исправлены или дополнены через естественное языковое взаимодействие. + +![image.png](https://cdn.memtensor.com.cn/img/1765970178683_5tuxe4_compressed.png) + + +### Замена Ключевых Слов в Памяти + +Как показано ниже, помимо обновления семантической памяти, MemOS также поддерживает замену конкретных слов через описание, в этом случае не требуется вводить идентификатор сессии (conversation_id). + +```python +data = { + "user_id": "memos_user_123", + "feedback_content": "С этого момента я изменил имя, заменив пользователя 1 на пользователя 2", + "allow_knowledgebase_ids": ["123", "456"] + } +``` + diff --git a/content/ru/memos_cloud/mem_operations/add_message.md b/content/ru/memos_cloud/mem_operations/add_message.md new file mode 100644 index 00000000..4dc846f3 --- /dev/null +++ b/content/ru/memos_cloud/mem_operations/add_message.md @@ -0,0 +1,289 @@ +--- +title: Добавить Сообщение +desc: MemOS автоматически обрабатывает добавленный вами мультимедийный контент, такой как текст, файлы, изображения и т. д., в可检索的个人记忆. + +::warning +**[直接看 API文档 点这里哦](/api_docs/core/add_message)** +
+
+ +**Этот документ сосредоточен на описании функций, подробные поля интерфейса и ограничения можно посмотреть, нажав на текстовую ссылку выше** +:: + +## 1. Как Добавить Сообщение? + +Основой памяти являются исходные сообщения. MemOS обрабатывает добавленные вами сообщения в единую память для последующего поиска и использования. При создании AI-приложения, независимо от того, начали ли вы использовать MemOS для управления пользовательской памятью, вы можете выбрать подходящее время для добавления в зависимости от реальной ситуации, включая: + +* **Однократный импорт**: импортируйте существующие исторические диалоги пользователей в MemOS одним нажатием кнопки, быстро создавая начальную память; + +* **Реальное время добавления**: добавляйте сообщения в MemOS в реальном времени каждый раз, когда пользователь отправляет сообщение; + +* **Добавление по раундам**: в зависимости от бизнес-потребностей, устанавливайте, чтобы пользовательские сообщения добавлялись в MemOS каждые несколько раундов диалога. + +::note +** Почему Память Важна?** +
+ +* Возможность реализации долгосрочной памяти между сессиями, предотвращая потерю информации после завершения диалога; + +* Постоянное накопление взаимодействий, позволяющее AI все больше "**понимать пользователя**"; + +* Непрерывная запись новой информации в процессе диалога, динамическое обновление пользовательской памяти; + +* Совместное использование одной и той же памяти пользователя между вашими несколькими приложениями или продуктами, обеспечивая единый пользовательский опыт. +
+:: + + +## 2. Ключевые Параметры + +* **Идентификатор пользователя (user\_id)**: используется для идентификации уникального пользователя, к которому относится сообщение, все добавленные диалоговые данные должны быть связаны с конкретным и уникальным идентификатором пользователя. + +* **Идентификатор сессии (conversation\_id)**: используется для идентификации уникальной сессии, к которой относится сообщение, все добавленные диалоговые данные должны быть связаны с конкретным и уникальным идентификатором сессии. + +* **Сообщения (messages)**: упорядоченный список сообщений, содержащих диалог между пользователем и AI, который будет добавлен в MemOS. + + +## 3. Принцип Работы + +* **Извлечение информации**: MemOS использует LLM для извлечения фактов, предпочтений и т. д. из сообщений и обрабатывает их в память, включая: фактическую память, память предпочтений, память инструментов и т. д. + +* **Разрешение конфликтов**: существующая память проверяется на наличие дубликатов или противоречий, обновление завершается. + +* **Хранение памяти**: окончательная память будет храниться с использованием векторной базы данных и графовой базы данных, что позволяет быстро извлекать ее при последующих запросах. + + +Все вышеперечисленные процессы можно инициировать, просто вызвав интерфейс `add/message`, без необходимости вручную управлять памятью пользователя. + + +## 4. Быстрый Старт + +```python +import os +import requests +import json + +# Замените на ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "user_id": "memos_user_123", + "conversation_id": "0610", + "messages": [ + {"role": "user", "content": "Я запланировал поездку в Гуанчжоу на летние каникулы, какие сетевые отели доступны для проживания?"}, + {"role": "assistant", "content": "Вы можете рассмотреть 【七天、全季、希尔顿】 и другие"}, + {"role": "user", "content": "Я выбрал 七天"}, + {"role": "assistant", "content": "Хорошо, если будут другие вопросы, спрашивайте."} + ] + } +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/add/message" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +:::note +Хотите узнать, какие воспоминания были созданы? Скопируйте указанный выше код и выполните его, перейдите к [**Поиску Памяти**](/memos_cloud/mem_operations/search_memory). +::: + +## 5. Другие Способы Использования + +### Реальное Время Импорт Диалога + +Вы можете в реальном времени вызывать интерфейс для добавления сообщений каждый раз, когда пользователь получает ответ от модели, синхронизируя диалог между пользователем и помощником с MemOS. MemOS будет постоянно обновлять память пользователя на основе новых диалогов на заднем плане. + +```python +import os +import json +import requests + + +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +# Заголовки и базовый URL +headers = { + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}", + "Content-Type": "application/json" +} +BASE_URL = os.environ['MEMOS_BASE_URL'] + +def add_message(user_id, conversation_id, messages): + data = { + "user_id": user_id, + "conversation_id": conversation_id, + "messages": messages + } + + res = requests.post(f"{BASE_URL}/add/message", headers=headers, data=json.dumps(data)) + result = res.json() + + if result.get('code') == 0: + print(f"✅ Добавлено успешно") + else: + print(f"❌ Добавление не удалось, {result.get('message')}") + +# Добавление сообщений диалога между пользователем и помощником +add_message("memos_user_123", "memos_conversation_123", + [{"role": "user", "content": "Я сегодня утром пробежал 5 километров, колени немного болят"}, + {"role": "assistant", "content": "Вы сегодня пробежали 5 километров, колени немного болят, это означает, что суставы и мышцы все еще адаптируются к нагрузке. Завтра рекомендую ограничить дистанцию до 3 километров, сосредоточив внимание на хорошей разминке и расслаблении. Это поможет поддерживать тренировочный ритм и даст коленям время на восстановление."}]) + +``` + +
+ +### Импорт Исторических Диалогов + +Если вы уже создали AI-диалоговое приложение, MemOS также поддерживает массовый импорт существующих записей чата, помогая диалоговому помощнику запомнить пользователя и более персонализированно отвечать. + +```python +# Пример исторических данных диалога +"messages": [ + # Диалог пользователя с ИИ в первый день + {"role": "user", "content": "Мне нравится острая еда", "chat_time": "2025-09-12 08:00:00"}, + {"role": "assistant", "content": "Понял, я запомнил, что ты любишь острые блюда.", "chat_time": "2025-09-12 08:01:00"}, + # Разговор пользователя с ИИ через несколько дней + {"role": "user", "content": "Но мне не очень нравятся жирные блюда, такие как острый горячий горшок или маосян", "chat_time": "2025-09-25 12:00:00"}, + {"role": "assistant", "content": "Ты предпочитаешь легкие и острые блюда. Я могу порекомендовать тебе несколько острых деликатесов, которые тебе подойдут!~", "chat_time": "2025-09-25 12:01:00"} +] +``` + +
+ +### Запись Предпочтений или Поведения Пользователя + +Кроме импорта содержания диалога, личные предпочтения пользователя, данные о поведении и т. д., такие как информация из анкеты интересов, заполненной при первом запуске приложения, также могут быть импортированы в MemOS как часть памяти. + +```python +# Пример информации об интересах пользователя +"messages": [ + { + "role": "user", + "content": """ +Предпочитаемые жанры фильмов: Научная Фантастика, Экшн, Комедия +Предпочитаемые жанры сериалов: Детективы, Исторические Драмы +Предпочитаемые жанры книг: Научно-популярные, Технические, Личностный Рост +Предпочитаемые способы обучения: Статьи, Видео, Подкасты +Спортивные привычки: Бег, Фитнес +Пищевые предпочтения: Любит острое, Здоровое Питание +Предпочтения в путешествиях: Природные Пейзажи, Городская Культура, Приключения +Предпочитаемый стиль общения: Юмористический, Теплый, Непринужденный +Тип помощи, которую хотел бы получить от ИИ: Советы, Запрос информации, Вдохновение +Темы, которые меня больше всего интересуют: Искусственный Интеллект, Будущие Технологии, Кинокритика +Я надеюсь, что AI поможет мне в следующих вещах: планирование повседневного учебного расписания, рекомендации фильмов и книг, предоставление эмоциональной поддержки. + """ + } +] +``` + +
+ +### Добавление Сообщений с Использованием Фильтров Памяти +MemOS поддерживает разработчиков в извлечении памяти из выбранного диапазона в соответствии с их потребностями. При добавлении сообщений используйте следующие поля для маркировки создаваемой памяти, чтобы затем использовать [Фильтры Памяти (filter)](/memos_cloud/features/basic/filters) для точной фильтрации. + + +1. **Один и Тот Же Пользователь Общается с Несколькими Агентами (в Нескольких Приложениях)** + +При добавлении сообщений указывайте информацию, такую как `agent_id` `app_id`, чтобы идентифицировать текущего агента и приложение, с которым ведется диалог с пользователем, чтобы различать "память одного и того же пользователя в разных агентах / приложениях." + +```python +data = { + "user_id": "memos_user_123", + "agent_id":"health_assistant", # Агент, переданный разработчиком для текущего диалога. + "conversation_id": 0610, + "messages":[ + {"role": "user", "content": "Я сегодня утром пробежал 5 километров, колено немного болит"}, + {"role": "assistant", "content": "Вы сегодня пробежали 5 километров, колено немного болит, это означает, что суставы и мышцы все еще адаптируются к нагрузке. Завтра рекомендую ограничить дистанцию до 3 километров, сосредоточив внимание на хорошей разминке и расслаблении." + } + ] +} + +# В последующих запросах вы можете передать "agent_id":"health_assistant", чтобы получить доступ к памяти пользователя о разговоре с этим помощником. +``` + +
+ +2. **Используйте Существующую Систему Меток для Семантической Классификации Памяти** + +MemOS будет автоматически генерировать теги для каждой памяти, но эти теги могут не полностью совпадать с тегами, используемыми в вашем бизнесе. Вы можете передать пользовательские `tags` при добавлении сообщения, и MemOS автоматически применит соответствующие теги к содержимому памяти на основе значений, которые вы предоставили. + +```python +data = { + "user_id": "memos_user_123", + "conversation_id": 0610, + "tags":["рекомендации по спорту","планирование фитнеса","запись тренировок"], # Пользовательские теги, переданные разработчиком для классификации тем "фитнес-помощника". + "messages":[ + {"role": "user", "content": "Я сегодня утром пробежал 5 километров, колено немного болит"}, + {"role": "assistant", "content": "Вы сегодня пробежали 5 километров, колено немного болит, это означает, что суставы и мышцы все еще адаптируются к нагрузке. Завтра рекомендую ограничить дистанцию до 3 километров, сосредоточив внимание на хорошей разминке и расслаблении." + } + ] +} + +# В последующих запросах вы можете передать "tags":"рекомендации по спорту", чтобы получить доступ к памяти пользователя, связанной с "рекомендациями по спорту". +``` + +::note +Если вы хотите узнать больше, смотрите [Пользовательские Теги](/memos_cloud/features/basic/custom_tags) +:: + +
+ +3. **Используйте встроенную бизнес-информацию для точной фильтрации** + +Передайте `info` при добавлении сообщения, чтобы ввести больше структурированных бизнес-полей или пользовательской дополнительной информации, например, `scene = Заказ` и т.д., чтобы точно различать текущую сцену, бизнес-линию, источник, статус и так далее по бизнес-измерению. + + +```python +data = { + "user_id": "memos_user_123", + "conversation_id": 0610, + "messages":[ + {"role": "user", "content": "Помоги мне найти подходящие билеты"}, + {"role": "assistant", "content": "Я нашел несколько рейсов с подходящим временем: \n1. Пекин → Шанхай, вылет 15 февраля в 08:30, прибытие в 12:30\n2. Пекин → Шанхай, вылет 15 февраля в 14:00, прибытие в 18:00\n3. Пекин → Шанхай, вылет 16 февраля в 09:00, прибытие в 13:00\nКакой рейс вы хотите, чтобы я забронировал, или нужно отфильтровать по другим условиям?" + } + ], + "info":{ + "scene":"билеты" + } +} + +# В последующих запросах вы можете передать "info":{"scene":"билеты"}, чтобы получить доступ к памяти пользователя, связанной с бизнес-сценарием "покупка билетов". +``` + +
+ +**Используйте Подсказки** + +`info` поддерживает передачу любых пользовательских пар «ключ-значение», все поля могут быть нормально сохранены и извлечены. + +Текущая система предоставляет лучшую поддержку производительности запросов для следующих полей (поскольку эти поля уже индексированы): +- business_type(Тип Бизнеса) +- biz_id(Уникальный Идентификатор Бизнеса) +- scene(Бизнес или Сцена Диалога) +- custom_status(Пользовательский Статус) + +Использование указанных выше полей не является обязательным, использование других пользовательских полей функционально полностью идентично, только производительность извлечения может отличаться. + +::note +`info` представляет собой плоскую структуру пар «ключ-значение», имена полей и значения полей должны быть строковыми типами, используемыми для фильтрации условий при извлечении; нестроковые значения должны быть сначала преобразованы в строки, прежде чем передавать. +:: + +
+ +## 6. Больше Функций + +:::note +Полный список информации о полях API, форматах и т.д. смотрите в [Документации по Интерфейсу Add Message](/api_docs/core/add_message). +::: + +| **Функция** | **Поле** | **Описание** | +| --- | --- | --- | +| Мультимодальные сообщения | `messages` | Список сообщений для добавления в диалог.
Поддерживаемые типы ролей: user / assistant / system / tool;
Поддерживаемые типы сообщений включают:
• текст
• документы, изображения, см. [Мультимодальные сообщения](/memos_cloud/features/basic/multimodal).
• информация о вызове инструмента, см. [Вызов инструмента](/memos_cloud/features/advanced/tool_calling). | +| Асинхронный Режим | `async_mode` | Контролирует способ обработки после добавления сообщения, поддерживает асинхронный и синхронный режимы, подробнее см. в [Асинхронном Режиме](/memos_cloud/features/basic/async_mode). | +| Запись В Общественную Память | `allow_public` | Контролирует, будет ли память, созданная из сообщений текущего пользователя, записываться в общественную память на уровне проекта, доступную для всех пользователей проекта, по умолчанию отключено. | +| Запись В Память Базы Знаний | `allow_knowledgebase_ids` | Контролирует, будет ли память, созданная из сообщений текущего пользователя, записываться в указанную связанную с проектом базу знаний, доступную для всех пользователей, имеющих доступ к этой базе знаний. По умолчанию пусто, при использовании вы можете передать список баз знаний, которые нужно записать. Подробнее см. в [Базе Знаний](/memos_cloud/features/advanced/knowledge_base). | diff --git a/content/ru/memos_cloud/mem_operations/delete_memory.md b/content/ru/memos_cloud/mem_operations/delete_memory.md new file mode 100644 index 00000000..d751320e --- /dev/null +++ b/content/ru/memos_cloud/mem_operations/delete_memory.md @@ -0,0 +1,59 @@ +--- +title: Удаление Памяти +desc: Удаление памяти из MemOS, поддержка пакетного удаления. +--- + +::warning +**[Прямо Посмотреть Документацию API Нажмите Здесь](/api_docs/core/delete_memory)** +
+
+ +**Данный документ сосредоточен на описании функций, подробные поля интерфейса и ограничения можно посмотреть, кликнув на текстовую ссылку выше** +:: + +## 1. Ключевые Параметры + +* **Список ID Памяти (memory\_ids[])**: Каждая запись, хранящаяся в MemOS, соответствует уникальному идентификатору, поддерживает передачу в виде списка для точного удаления одной или нескольких заданных записей. + +* **ID Пользователя (user_id)**: Используется для удаления всех записей определенного пользователя. При передаче этого поля будут удалены все записи, связанные с данным пользователем (включая: факты, предпочтения, навыки, записи инструментов). + +:::note +**Как получить ID памяти для удаления** +
+
+При поиске памяти (`search/memory`) и получении памяти (`get/memory`) каждая запись в возвращаемых результатах содержит уникальное поле `id`, которое служит уникальным идентификатором этой записи.
+Когда вы обнаружите, что какая-либо запись устарела или не соответствует ожиданиям, вы можете просто взять `id` и передать его как параметр `memory_ids[]` в интерфейс `delete/memory`, чтобы удалить соответствующую запись. +::: + + +## 2. Быстрый Старт + +```python +import os +import requests +import json + +# Замените На Ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "memory_ids":["4a50618f-797d-4c3b-b914-94d7d1246c8d"], # Замените На Реальный ID Памяти + # "user_id": "12345" Если Необходимо Удалить Все Памяти Определенного Пользователя, Замените На Реальный ID Пользователя + ## Обратите Внимание, user_id И memory_ids[] Являются Двумя Разными Условиями Фильтрации, Использование Их Одновременно Приведет К Ошибке. + } +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/delete/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` + +::note + Хотите узнать, успешно ли удалено? +Одним нажатием скопируйте приведенный выше код и выполните его, затем снова [поиск памяти](/memos_cloud/mem_operations/search_memory), посмотрите, была ли память успешно удалена? +:: diff --git a/content/ru/memos_cloud/mem_operations/search_memory.md b/content/ru/memos_cloud/mem_operations/search_memory.md new file mode 100644 index 00000000..ff2787e3 --- /dev/null +++ b/content/ru/memos_cloud/mem_operations/search_memory.md @@ -0,0 +1,326 @@ +--- +title: Поиск Памяти +desc: С помощью семантического поиска и функций фильтрации, MemOS вызывает соответствующие воспоминания. +--- + +::warning +**[Прямо Посмотреть Документацию API Нажмите Здесь](/api_docs/core/search_memory)** +
+
+ +**Данный документ сосредоточен на описании функций, подробные поля интерфейса и ограничения можно посмотреть, нажав на текстовую ссылку выше** +:: + +## 1. Что Такое Поиск Воспоминаний? + +Поиск воспоминаний означает, что MemOS, когда пользователь задает вопрос, в сочетании с заранее определенными разработчиком условиями фильтрации, вызывает наиболее релевантные и важные воспоминания из базы данных. Модель при генерации ответа будет ссылаться на эти вызванные воспоминания, чтобы дать более точный, уместный и соответствующий контексту пользователя ответ. + +::note +** Почему Нужен Поиск Воспоминаний?** +
+ +* Не нужно заново строить контекст, можно сразу получить правильные и надежные воспоминания; + +* С помощью условий фильтрации и других способов гарантируется, что вызванные воспоминания всегда будут высоко релевантны текущему вопросу. +
+:: + + +## 2. Ключевые Параметры + +* **Содержимое Запроса (query)**: Вопрос пользователя, используемый для поиска, естественный язык вопроса или утверждения, система будет основывать поиск на семантическом соответствии соответствующим воспоминаниям. + +* **Фильтрация Воспоминаний (filter)**: Логические условия на основе JSON, используемые для фильтрации полей agent, create_time, tags, info и т.д., чтобы сузить область поиска воспоминаний; например, искать только "воспоминания за последние 30 дней". + +* **Порог Релевантности (relativity)**: Релевантность означает степень семантического соответствия вызванных воспоминаний содержимому вопроса пользователя, чем выше релевантность, тем более актуально это воспоминание для текущего вопроса пользователя. Порог релевантности используется для ограничения степени соответствия вызванных воспоминаний, текущее значение по умолчанию в системе составляет 0.45, воспоминания ниже этого значения будут отфильтрованы. + + +## 3. Принцип Работы + +- **Переписывание Содержимого Запроса**: MemOS очищает и усиливает семантику введенного естественного языка запроса, автоматически дополняя ключевую информацию и намерение поиска, чтобы повысить точность последующего поиска. + +- **Вызов Воспоминаний** + + - **Смешанный Поиск и Сортировка**: Система генерирует вектор встраивания на основе переписанного запроса, комбинируя ключевой поиск и смешанную стратегию семантического поиска векторов для вызова кандидатных воспоминаний, проводя единую сортировку кандидатных воспоминаний. + + - **Фильтрация и Отбор Воспоминаний**: На основе логических условий и операторов сравнения воспоминания структурно фильтруются, чтобы сузить область поиска воспоминаний; отбор отсортированных воспоминаний по установленному разработчиком порогу релевантности, контролируя качество результатов вызова. + + - **Удаление Дубликатов Результатов**: Кандидатные воспоминания проходят обработку по удалению дубликатов и семантической агрегации. + +- **Вывод Воспоминаний**: Конечный результат будет возвращен в соответствии с установленным лимитом на количество воспоминаний, ответ будет возвращен в течение 600 мс, используемый для последующего вывода и генерации ответов. + +Все вышеперечисленные процессы можно инициировать, просто вызвав интерфейс `search/memory`, без необходимости вручную управлять воспоминаниями пользователя. + + +## 4. Быстрый Старт +::code-group +```python [Python (HTTP)] +import os +import requests +import json + +# Замените На Ваш MemOS API Key +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +data = { + "query": "Я Хочу Поехать Отдохнуть На Праздники, Помогите Мне Рекомендовать Город, Где Я Еще Не Был, И Бренд Отеля, В Котором Я Еще Не Останавливался", + "user_id": "memos_user_123", + "conversation_id": "0928" # Текущий ID Сессии, Не Обязательный. Если Заполнен, Мы Будем Приоритизировать Содержимое Из Эта Сессия При Восстановлении Памяти, Но Это Не Обязательно, Только Увеличивает Вес Релевантности. +} +headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" +} +url = f"{os.environ['MEMOS_BASE_URL']}/search/memory" + +res = requests.post(url=url, headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Вывод] +# Пример Вывода (Для Удобства Понимания Здесь Упрощено, Только Для Справки) +{ + # Память Типа Фактов + memory_detail_list [ + { + "memory_key": "План Путешествия В Гуанчжоу На Летние Каникулы", + "memory_value": "Пользователь Планирует Поездку В Гуанчжоу На Летние Каникулы И Выбрал Сеть Отелей На Семь Дней В Качестве Варианта Проживания.", + "conversation_id": "0610", + "tags": [ + "Путешествие", + "Гуанчжоу", + "Проживание", + "Отель" + ] + } + ], + # Память Типа Предпочтений + preference_detail_list [ + { + "preference_type": "implicit_preference", # Имплицитные Предпочтения + "preference": "Пользователь, возможно, предпочитает отели с хорошим соотношением цены и качества." + "reasoning": "Отели Цзитянь обычно известны своей экономичностью, и выбор пользователя отеля Цзитянь может указывать на его склонность выбирать варианты с хорошим соотношением цены и качества. Хотя пользователь не упомянул о бюджетных ограничениях или конкретных предпочтениях в отелях, выбор отеля Цзитянь среди предложенных вариантов может отражать акцент на цене и практичности." + "conversation_id": "0610" + } + ] +} +``` +:: + +::note + Обратите внимание, что `user_id` является обязательным полем, в настоящее время каждый раз при поиске воспоминаний необходимо указывать одного пользователя. +:: + +## 5. Пример Сборки Воспоминаний В Prompt + +::note +**Сборка Воспоминаний**
+ +Использование вызванных воспоминаний требует определенных навыков, ниже приведен пример сборки +:: + +```text +# Role +Вы — интеллектуальный помощник с долгосрочной памятью (MemOS Assistant). Ваша цель — предоставить пользователю высоко персонализированные, точные и логически обоснованные ответы, комбинируя извлеченные фрагменты памяти. + +# System Context +- Текущее время: 2026-01-06 15:05 (используйте это как основу для оценки актуальности памяти) + +# Memory Data +Вот информация, извлеченная из MemOS, разделенная на "факты" и "предпочтения". +- **Факты (Facts)**: могут содержать атрибуты пользователя, историю диалогов или информацию от третьих лиц. +- **Особое внимание**: Содержимое, помеченное как '[мнение помощника]' и '[резюме модели]', представляет собой **предположения ИИ в прошлом**, **а не** слова пользователя. +- **Предпочтения (Preferences)**: явные/неявные требования пользователя к стилю, формату или логике ответов. + + + + -[2025-12-26 21:45] Пользователь планирует поехать в Гуанчжоу на летние каникулы и выбрал сеть отелей Цзитянь в качестве варианта проживания. + -[2025-12-26 14:26] Имя пользователя — Грейс. + + + + -[2026-01-04 20:41] [Явное предпочтение] Пользователь любит путешествовать на юг. + -[2025-12-26 21:45] [Неявное предпочтение] Пользователь, возможно, предпочитает отели с хорошим соотношением цены и качества. + + + +# Критический Протокол: Безопасность Памяти (Memory Safety Protocol) +Извлеченная память может содержать **предположения ИИ**, **неуместный шум** или **ошибки субъекта**. Вы должны строго следовать следующим **"четырем шагам оценки"**, и если хотя бы один шаг не пройден, вы должны **отбросить** эту память: + +1. **Проверка истинности источника (Source Verification)**: + - **Ядро**: Различайте "Прямые Слова Пользователя" и "Предположения AI". + - Если память содержит метки '[assistant观点]', это лишь представляет собой **гипотезу** AI в прошлом, **нельзя** рассматривать это как абсолютный факт пользователя. + - *Пример противоречия*: Память показывает '[assistant观点] Пользователь обожает манго'. Если пользователь не упоминал, не предполагайте, что пользователь любит манго, чтобы избежать циклической иллюзии. + - **Принцип: Резюме AI предназначено только для справки, его вес значительно ниже, чем прямые утверждения пользователя.** + +2. **Проверка атрибуции (Attribution Check)**: + - Является ли субъектом действия в памяти "сам пользователь"? + - Если память описывает **третью сторону** (например, "кандидат", "соискатель", "вымышленный персонаж", "данные случая"), **строго запрещено** приписывать их свойства пользователю. + +3. **Проверка релевантности (Relevance Check)**: + - Помогает ли память напрямую ответить на текущий 'Original Query'? + - Если память лишь совпадает по ключевым словам (например: оба упоминают "код"), но контекст совершенно другой, **необходимо игнорировать**. + +4. **Проверка актуальности (Freshness Check)**: + - Конфликтует ли содержание памяти с последними намерениями пользователя? В качестве высшего фактического стандарта используйте текущий 'Original Query'. + +# Instructions +1. **Оценка**: Сначала прочитайте '', выполните "Четыре Шага Судьбы", исключите шум и ненадежные мнения AI. +2. **Исполнение**: + - Используйте только отфильтрованную память для дополнения контекста. + - Строго соблюдать требования стиля в ''. +3. **Вывод**: Прямо отвечать на вопросы, **строго запрещено** упоминать такие внутренние термины системы, как "память", "поиск" или "мнение ИИ". + +# Original Query +На национальный праздник хочу поехать отдохнуть, помогите мне порекомендовать город, в котором я не был, и гостиничную сеть, в которой я не останавливался. + +``` + +## 6. Другие Способы Использования +### Получение Общего Портрета Пользователя + +Если вам нужно провести анализ пользователей для вашего разработанного приложения или вы хотите в AI приложении в реальном времени показывать пользователям их "личные ключевые впечатления", вы можете вызвать глобальный поиск воспоминаний пользователя в MemOS, чтобы помочь большой модели создать персонализированный портрет пользователя. В этом случае можно не заполнять `conversation_id`~ + +Как показано в следующем примере, если вы уже пробовали [добавить сообщение](/memos_cloud/mem_operations/add_message), добавив исторические сообщения диалога пользователя `memos_user_123`, вы можете одним нажатием скопировать этот пример для поиска воспоминаний пользователя. + +::code-group +```python [Python (HTTP)] +import os +import json +import requests + +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +# Заголовки и базовый URL +headers = { + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}", + "Content-Type": "application/json" +} +BASE_URL = os.environ['MEMOS_BASE_URL'] + +# Прямо спрашивать о профиле персонажа, как query +query_text = "Каковы ключевые слова моего персонажа?" + +data = { + "user_id": "memos_user_123", + "query": query_text, +} + +# Вызов /search/memory для запроса связанных воспоминаний +res = requests.post(f"{BASE_URL}/search/memory", headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +```python [Вывод] +# Пример Вывода (Для Удобства Понимания Здесь Упрощено, Только Для Справки) + +{ + # Память Типа Фактов + memory_detail_list [ + { + "memory_key": "Вопросы, по которым пользователь хочет помощи от ИИ", + "memory_value": "Пользователь хочет, чтобы ИИ помог спланировать повседневное обучение, рекомендовать фильмы и книги, а также предоставлять эмоциональную поддержку.", + "conversation_id": "0610", + "tags": [ + "Помощь", + "Учебный план", + "Рекомендации", + "Сопровождение" + ] + }, + { + "memory_key": "Типы помощи, которые пользователь хочет от ИИ", + "memory_value": "Пользователь хочет, чтобы ИИ предоставлял советы, информацию и вдохновение.", + "conversation_id": "0610", + "tags": [ + "AI", + "Помощь", + "Тип" + ] + } + ] +} +``` +:: + + +### Точный Фильтр Поиска Воспоминаний + +MemOS предоставляет мощную функцию фильтрации воспоминаний, позволяя разработчикам точно фильтровать по воспоминаниям, которые они ищут. Эта функция особенно полезна, когда необходимо искать по определенным характеристикам воспоминаний, таким как время создания воспоминания, теги, метаинформация и т.д. + +::note +Следующий пример демонстрирует использование фильтра памяти. Предположим, что пользователь хочет подвести итоги всех "разговоров" на тему "чтение" за этот год. В этом случае можно отфильтровать все записи, содержащие "чтение", созданные в 2025 году и относящиеся к сценарию "разговор": +:: + +::code-group +```python [Python (HTTP)] +import os +import json +import requests + +os.environ["MEMOS_API_KEY"] = "YOUR_API_KEY" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" + +# Заголовки и базовый URL +headers = { + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}", + "Content-Type": "application/json" +} +BASE_URL = os.environ['MEMOS_BASE_URL'] + +query_text = "Мой итоговый отчет о чтении" + +data = { + "user_id": "memos_user_123", + "query": query_text, + "filter": { + "and": [ + {"tags": {"contains": "чтение"}}, # MemOS извлеченные теги + {"create_time": {"gte": "2025-01-01"}}, # MemOS время создания памяти + {"create_time": {"gte": "2025-12-31"}}, # MemOS время создания памяти + {"info":{"scene":"чат"}} # добавление сообщения, переданного разработчиком + ] + } # Передавая поле filter, фильтруйте все воспоминания, содержащие "чтение", с временем создания в 2025 году и сценой "диалог". +} + +# Вызов /search/memory для запроса связанных воспоминаний +res = requests.post(f"{BASE_URL}/search/memory", headers=headers, data=json.dumps(data)) + +print(f"result: {res.json()}") +``` +:: + +::note +Для получения дополнительной информации о других параметрах фильтрации, пожалуйста, обратитесь к [фильтру памяти](/memos_cloud/features/basic/filters). +:: + +### Стратегия Вызова Памяти С Меньшим Количеством Токенов + +Чтобы помочь модели получать более качественный и экономящий токены контент памяти, тем самым уменьшая количество токенов, вводимых в модель, MemOS поддерживает возможность передачи разработчиками пользовательских **порогов релевантности (relativity)** и **максимального количества возвращаемых записей памяти (memory_limit_number и т.д.)**. + +Как показано ниже, разработчики передают `relativity = 0.8` `memory_limit_number = 9`, в результате чего возвращаются менее 9 записей, каждая из которых имеет релевантность выше 0.8. + +```python +data = { + "user_id": "memos_user_123", + "query": "Запланируй мне 5 дней поездки в Чэнду.", + "relativity": 0.8, # Порог релевантности, если не передан, по умолчанию 0, что означает ограничение на релевантность возвращаемых воспоминаний. + "memory_limit_number" = 9 # Максимальное количество возвращаемых воспоминаний, если не передано, по умолчанию 9, что означает возврат 9 самых релевантных воспоминаний. +} +``` +Обратите внимание, что текущий `relativity` действует только на фактические и предпочтительные записи памяти. + +## 7. Дополнительные Функции + +::note + Полный список полей API, форматов и другой информации доступен в [документации интерфейса Search Memory](/api_docs/core/search_memory). +:: + +| **Функция** | **Связанные поля** | **Описание** | +| -------------- | --------------------------------------------------- | ------------------------------------------------------------ | +| Воспоминания по предпочтениям | `include_preference`
 
`preference_limit_number` | Воспоминания по предпочтениям — это информация о предпочтениях пользователя, сгенерированная на основе анализа исторических сообщений пользователя в MemOS. После включения можно возвращать воспоминания по предпочтениям в результатах поиска. | +| Воспоминания по инструментам | `include_tool_memory`
 
`tool_memory_limit_number` | Воспоминания по инструментам — это воспоминания, сгенерированные после анализа информации о вызовах добавленных инструментов в MemOS. После включения можно возвращать воспоминания по инструментам в результатах поиска, см. [Вызов инструментов](/memos_cloud/features/advanced/tool_calling). | +| Вызов Навыков | `include_skill`
 
`skill_limit_number` | Навыки — это исполняемые возможности агента, генерируемые MemOS на основе памяти пользователя. После включения можно вызывать навыки в результатах поиска, см. [Навыки](/memos_cloud/features/advanced/skill). | +| Поиск Указанных Баз Знаний | `knowledgebase_ids` | Используется для указания диапазона связанных баз знаний, доступных для текущего поиска. Разработчики могут использовать это для реализации тонкого контроля доступа, гибко определяя наборы баз знаний, доступные различным конечным пользователям, см. [Базы Знаний](/memos_cloud/features/advanced/knowledge_base). | diff --git a/content/ru/memos_cloud/overview.md b/content/ru/memos_cloud/overview.md new file mode 100644 index 00000000..6e17f8b4 --- /dev/null +++ b/content/ru/memos_cloud/overview.md @@ -0,0 +1,56 @@ +--- +title: Введение в MemOS +desc: MemOS (Memory Operating System) — это операционная система управления памятью, ориентированная на AI-приложения. +--- + +Его цель: сделать так, чтобы ваша AI-система **имела долгосрочную память, как человек**, способную не только запоминать слова пользователей, но и активно вызывать, обновлять и планировать эти воспоминания. + +Для разработчиков MemOS подобен базе данных для приложений: вам не нужно заново изобретать колесо, чтобы решить проблему "как AI запоминает", достаточно вызвать услуги, предоставляемые MemOS, и вы сможете легко добавить "память" вашему Agent или приложению. + +Сравнение Памяти + +## 1. Почему нужен MemOS + +У памяти больших моделей есть ограничения: + +* **Ограниченный контекст**: даже если окно Token в одном разговоре велико, оно не может вместить долгосрочные знания. + +* **Серьезное забывание**: предпочтения пользователя, высказанные на прошлой неделе, исчезают в следующем разговоре. + +* **Трудности в управлении**: с увеличением взаимодействий память становится запутанной, разработчикам требуется дополнительная логика для обработки. +
+ +Ценность MemOS заключается в том, что он **абстрагирует уровень памяти**, позволяя вам сосредоточиться только на бизнес-логике: + +* Больше не нужно вручную писать сложные "долгие текстовые соединения" или "дополнительные вызовы базы данных". + +* Память может быть повторно использована и расширена, как модули, и даже может быть разделена между разными Agent и системами. + +* Благодаря активному планированию и многоуровневому управлению вызовы памяти становятся быстрее и точнее, что значительно снижает вероятность галлюцинаций. + +Проще говоря: **MemOS делает AI не просто машиной для одноразовых разговоров, а партнером, который может постоянно развиваться**. + +image + +## 2. Что может сделать MemOS + +* **Персонализированные разговоры**: запоминайте имя пользователя, привычки, интересы, предпочтения в командах, автоматически дополняйте в следующий раз. + +* **Командная база знаний**: преобразуйте фрагменты разговоров в структурированные знания для совместного использования несколькими Agent, подробнее см. [База знаний](/memos_cloud/features/advanced/knowledge_base). + +* **Непрерывность задач**: сохраняйте память между сессиями и приложениями, позволяя AI уверенно обрабатывать долгие процессы. + +* **Многоуровневое планирование памяти**: вызывайте наиболее подходящую память в зависимости от потребностей, повышая производительность и точность. + +* **Открытое расширение**: поддерживает использование в качестве отдельного API, также может быть интегрирован в существующие фреймворки (официальные инструкции по использованию скоро будут доступны, а спешащие учителя могут попробовать сделать это самостоятельно~) + +## 3. Следующие шаги + +👉 Перейдите в [Быстрый старт](/memos_cloud/quick_start), чтобы через минимальный пример показать, как добавить "память" вашему Agent. + +👉 Или начните разрабатывать бизнес-приложения, мы предоставляем практические проекты для вашего参考: +* [Позвольте финансовому помощнику понять предпочтения клиентов за их поведением](/usecase/financial_assistant) +* [Писательский помощник с памятью работает лучше](/usecase/writting_assistant) +* [Создайте помощника для домашней жизни с памятью](/usecase/home_assistant) +* [Claude MCP](/usecase/frameworks/claude_mcp) +* [Инструмент Coze Plugin](/usecase/frameworks/coze_plugin) diff --git a/content/ru/memos_cloud/quick_start.md b/content/ru/memos_cloud/quick_start.md new file mode 100644 index 00000000..f9e7393f --- /dev/null +++ b/content/ru/memos_cloud/quick_start.md @@ -0,0 +1,218 @@ +--- +title: Быстрый Старт +desc: Добро пожаловать на облачную платформу MemOS, следуйте этому руководству для новичков, чтобы подключить возможности памяти за несколько минут. +--- + +При использовании больших моделей для создания приложений, распространенный вопрос: **как заставить AI стабильно запоминать долгосрочные предпочтения пользователей?** +MemOS предоставляет два основных интерфейса, чтобы помочь вам в этом: + +- `addMessage` — передайте нам оригинальный диалог, мы автоматически обработаем и сохраним память [(нажмите здесь, чтобы просмотреть подробную документацию API)](/api_docs/core/add_message) +- `searchMemory` — вспомните память в последующих диалогах, чтобы AI отвечал ближе к потребностям пользователя [(нажмите здесь, чтобы просмотреть подробную документацию API)](/api_docs/core/search_memory) + +![image.svg](https://cdn.memtensor.com.cn/img/1762434889291_h9co0h_compressed.png) + + +## 1. Подготовка Перед Вызовом + +* Зарегистрируйтесь и войдите в облачную платформу MemOS [(нажмите для регистрации)](https://memos-dashboard.openmem.net/quickstart); + +* Подготовьте среду, способную отправлять HTTP-запросы (Python или cURL подойдут); + +* Получите API Key [(нажмите, чтобы получить)](https://memos-dashboard.openmem.net/apikeys) и настройте его в переменных окружения; + +* Подготовьте `conversation_id`, который можно использовать для тестирования (рекомендуется называть по дате, например, `20260413-demo`). + + +## 2. Конфигурация Кода + +### 2.1 Установка SDK +Если вы выбрали Python SDK, убедитесь, что у вас установлен Python 3.10+, затем выполните: + +``` +pip install MemoryOS -U +``` + +### 2.2 Добавление Оригинального Диалога (addMessage) + +::note +**Сессия A: 2025-06-10 Произошла**
+ +Вам нужно просто передать `оригинальные записи диалога` в MemOS, MemOS `автоматически абстрагирует, обрабатывает и сохраняет как память` +:: + +::code-snippet{name=add_message} +:: + +### 2.3 Вызов MemOS для Поиска Соответствующей Памяти (searchMemory) В Диалоге + +::note +**Сессия B: 2025-09-28 Произошла**
+ +Пользователь в новом диалоге запрашивает "рекомендуйте места для путешествий и отели на праздник", MemOS автоматически вспомнит 【фактическую память: где он уже был】 и 【предпочтительную память: предпочтения по бронированию отелей】 для AI, чтобы создать более персонализированный план путешествия. +:: + +::code-snippet{name=search_memory} +:: + +**Список выведенной памяти выглядит следующим образом:**
+ +```text +# Пример Выходных Данных (Для Удобства Понимания Здесь Упрощено, Только Для Справки) + +# Память О Типах Предпочтений +{ + preference_detail_list [ + { + "preference_type": "implicit_preference", #Неявное Предпочтение + "preference": "Пользователь, Возможно, Предпочитает Отели С Высоким Соотношением Цены И Качества.", + "confidence": 0.82, + "conversation_id": "0610" + }, + { + "preference_type": "explicit_preference", #Явное Предпочтение + "preference": "Пользователь Хотел Бы, Чтобы Оценка Отеля Не Была Ниже 4.5.", + "conversation_id": "0928" + } + ], + +# Память О Фактических Типах + memory_detail_list [ + { + "memory_key": "План Поездки В Гуанчжоу Летом", + "memory_value": "Пользователь Планирует Поездку В Гуанчжоу Летом И Выбрал Сеть Отелей На Семь Дней В Качестве Варианта Проживания.", + "conversation_id": "0610", + "memory_time": "2025-06-10 20:15:00", + "tags": [ + "Поездка", + "Гуанчжоу", + "Проживание", + "Отель" + ] + } + ] +} +``` + +### 2.4 Пример Сборки Памяти в Prompt + +::note +**Сборка Памяти**
+ +Использование вспомненной памяти требует определенных навыков, ниже приведен пример сборки +:: + +```text +# Role +Вы являетесь интеллектуальным помощником с долгосрочной памятью (MemOS Assistant). Ваша цель — сочетать извлеченные фрагменты памяти, чтобы предоставить пользователю высоко персонализированные, точные и логически обоснованные ответы. + +# System Context +- Текущее время: 2026-01-06 15:05 (используйте это как основу для оценки актуальности памяти) + +# Memory Data +Вот информация, извлеченная из MemOS, разделенная на «факты» и «предпочтения». +- **Факты (Facts)**: могут содержать атрибуты пользователя, историю диалогов или информацию от третьих лиц. +- **Особое внимание**: содержимое, помеченное как '[мнение помощника]' и '[резюме модели]', представляет собой **предположения ИИ в прошлом**, **а не** оригинальные слова пользователя. +- **Предпочтения (Preferences)**: явные/неявные требования пользователя к стилю, формату или логике ответов. + + + + -[2025-12-26 21:45] Пользователь планирует поехать в Гуанчжоу на летние каникулы и выбрал отель сети на семь дней в качестве варианта проживания. + -[2025-12-26 14:26] Имя пользователя — Грейс. + + + + -[2026-01-04 20:41] [Явное предпочтение] Пользователь предпочитает путешествовать на юг. + -[2025-12-26 21:45] [Неявное предпочтение] Пользователь, возможно, предпочитает отели с хорошим соотношением цены и качества. + + + +# Критический Протокол: Безопасность Памяти (Memory Safety Protocol) +Извлеченная память может содержать **предположения ИИ**, **неуместный шум** или **ошибки субъекта**. Вы должны строго выполнять следующие **«четыре шага оценки»**, и если хотя бы один шаг не пройден, **отбросьте** эту память: + +1. **Проверка истинности источника (Source Verification)**: + - **Суть**: различать «оригинальные слова пользователя» и «предположения ИИ». + - Если память содержит '[assistant观点]' и другие метки, это лишь представляет собой **гипотезу** AI в прошлом, **не следует** рассматривать это как абсолютный факт пользователя. + - *Пример противоречия*: Память показывает '[assistant观点] Пользователь обожает манго'. Если пользователь не упоминал, не следует предполагать, что пользователь любит манго, чтобы избежать циклической иллюзии. + - **Принцип: Резюме AI предназначено только для справки, его вес значительно ниже, чем прямые утверждения пользователя.** + +2. **Проверка атрибуции (Attribution Check)**: + - Является ли субъектом действия в памяти "сам пользователь"? + - Если память описывает **третью сторону** (например, "кандидат", "интервьюируемый", "вымышленный персонаж", "данные случая"), **строго запрещается** приписывать их свойства пользователю. + +3. **Проверка релевантности (Relevance Check)**: + - Помогает ли память напрямую ответить на текущий 'Original Query'? + - Если память лишь совпадает по ключевым словам (например: оба упоминают "код"), но контекст совершенно другой, **необходимо игнорировать**. + +4. **Проверка актуальности (Freshness Check)**: + - Конфликтует ли содержание памяти с последними намерениями пользователя? В качестве высшего фактического стандарта принимается текущий 'Original Query'. + +# Instructions +1. **Оценка**: Сначала прочитайте '', выполните "четыре шага оценки", исключите шум и ненадежные мнения AI. +2. **Исполнение**: + - Используйте только отфильтрованную память для дополнения контекста. + - Строго соблюдайте требования стиля в ''. +3. **Выход**: Прямо отвечайте на вопросы, **строго запрещено** упоминать "память", "поиск" или "мнения ИИ" и другие внутренние термины системы. + +# Original Query +На праздники я хочу поехать развлекаться, помогите мне порекомендовать город, в котором я не был, и гостиничную сеть, в которой я не останавливался. + +``` + + +## 3. Следующие Шаги + +Теперь вы можете использовать MemOS, рекомендуется продолжить исследовать другие функции облачной платформы: + +* [**Основные Операции с Памятью**](/memos_cloud/mem_operations/add_message): Полное понимание того, как добавлять, извлекать и удалять память; + +* [**Описание Функций**](/memos_cloud/features/basic/filters): Исследуйте больше функций облачной платформы, таких как: фильтрация памяти, мультимодальные сообщения, базы знаний и т.д.; + +* [**Документация API**](/api_docs/start/overview): Просмотрите полную документацию API и примеры вызовов; + +* [**Инструкция по Подключению SDK**](/api_docs/start/quickstart): Просмотрите инициализацию, аутентификацию и обработку ошибок по языкам. + + +## 4. Дополнительные Материалы + +### Понимание Процесса Производства Памяти MemOS + +Подробное описание 【как сообщение обрабатывается в память, когда оно попадает в систему, и как оно эффективно используется в будущих диалогах】, чтобы помочь вам лучше понять механизм и преимущества памяти MemOS. + +::note +**Глубокое Понимание**
+Механизм памяти MemOS можно рассматривать как полный «рабочий процесс»: +вы отправляете оригинальное сообщение → обрабатываете память → механизм планирования организует вызовы и хранение в зависимости от задач и контекста, и может динамически изменять форму памяти → при необходимости вызывается соответствующая память → одновременно управление жизненным циклом поддерживает эволюцию и обновление. +:: + +- [Производство MemOS](/memos_cloud/introduction/mem_production) +- [Планирование MemOS](/memos_cloud/introduction/mem_schedule) +- [Вызов MemOS](/memos_cloud/introduction/mem_recall) +- [Управление Жизненным Циклом MemOS](/memos_cloud/introduction/mem_lifecycle) + +### Практическое Использование MemOS + +MemOS предоставляет множество примеров проектов, в зависимости от вашего конкретного проекта вы можете обратиться к следующим материалам: + +- [Позвольте Финансовому Ассистенту Понять Предпочтения За Клиентом](/usecase/financial_assistant) + - В сценах интеллектуального инвестирования действия пользователей, такие как клики, просмотры, сохранения и общение, являются поведением, формирующим профиль. + - MemOS может абстрагировать эти действия в память, например, «Предпочтение Риска = Консервативное». + - И когда пользователь спрашивает «Какое инвестирование мне подходит?», это напрямую влияет на рекомендации консультанта, делая их более профессиональными и соответствующими реальности. + +- [Создание Семейного Ассистента с Памятью](/usecase/home_assistant) + - Семейный ассистент не просто отвечает на текущие вопросы, он также может запоминать ваши задачи, предпочтения и семейную информацию. + - Например, «В субботу сводить детей в зоопарк» или «При напоминании сначала перечислить пункты», MemOS превратит это в память. + - В последующих разговорах это будет автоматически использоваться, делая ассистента ближе к реальной жизни. + +- [Ассистент Письма с Памятью Более Удобен](/usecase/writting_assistant) + - Ассистент письма должен не только помогать вам генерировать контент, но и поддерживать единый тон и стиль. + - С помощью MemOS предпочтения пользователя в письме, часто используемая информация и контекстные команды могут быть запомнены. + - В следующий раз, когда вы будете писать резюме или электронное письмо, не нужно будет повторно подчеркивать, что обеспечит последовательный и персонализированный опыт создания. + +- [Coze × MemOS Плагин Инструмент](/usecase/frameworks/coze_plugin) + - Используйте плагин MemOS, размещенный на платформе Coze, для быстрого добавления функции долгосрочной памяти в ваш агент, получая доступ к облачным сервисам прямо в рабочем процессе. + +- [Claude MCP](/usecase/frameworks/claude_mcp) + - MemOS предоставляет способ взаимодействия с облачной платформой через MCP, позволяя напрямую получать доступ к облачным сервисам в клиенте Claude. + +- [Интеграция LangChain × MemOS](/usecase/frameworks/langchain) + - В рабочем процессе LangChain интегрируйте `searchMemory` в качестве инструмента поиска, поддерживающего многократные контексты диалога. diff --git a/content/ru/open_source/best_practice/common_errors_solutions.md b/content/ru/open_source/best_practice/common_errors_solutions.md new file mode 100644 index 00000000..17c4e780 --- /dev/null +++ b/content/ru/open_source/best_practice/common_errors_solutions.md @@ -0,0 +1,155 @@ +--- +title: Распространенные Ошибки И Решения +--- + +## 1. Ошибки, Связанные С Базой Данных И Векторами + +### Несоответствие Размерности Встраивания + +**Явление**: +После изменения модели встраивания (например, с `openai` на `ollama`), система выдает ошибку или качество поиска крайне низкое. +В логах может появиться ошибка `Dimension mismatch` или связанная с Qdrant ошибка `Wrong input vector size`. + +**Причина**: +Qdrant фиксирует размерность векторов при создании коллекции на основе `vector_dimension` в конфигурационном файле. +* OpenAI `text-embedding-3-small`: 1536 измерений +* Ollama `nomic-embed-text`: 768 измерений +* BAAI `bge-m3`: 1024 измерений + +MemOS `QdrantVecDB` при инициализации, если обнаруживает, что коллекция уже существует, пропускает шаг создания. В этом случае, если используется модель с новой размерностью, при записи векторов возникнет ошибка. + +**Решение**: +1. **Изменить Название Коллекции**:Измените `collection_name` в конфигурационном файле, чтобы MemOS создал новую коллекцию. + ```yaml + vec_db: + config: + collection_name: "memos_v2" # Исходное название memos_v1 + vector_dimension: 768 # Убедитесь, что этот размер соответствует новой модели + ``` +2. **Удалить Старые Данные**:Если вы находитесь в среде разработки, вы можете просто удалить хранилище Qdrant или удалить старую коллекцию. + +### Ошибка Запуска Бэкенда Данных (Neo4j/Qdrant) + +**Явление**: +При запуске MemOS возникает ошибка `ConnectionRefusedError`, `ServiceUnavailable` или `AuthError`. + +**Распространенные Причины И Чек-лист**: + +1. **Контейнер Docker Не Запущен**: + Убедитесь, что вы запустили необходимые контейнеры промежуточного ПО. + ```bash + docker ps + # Проверьте, работают ли контейнеры neo4j и qdrant + ``` + +2. **Порт Не Сопоставлен**: + Проверьте, содержит ли команда `docker run` параметр `-p`. + * Qdrant необходимо открыть `6333` (gRPC/HTTP) + * Neo4j необходимо открыть `7474` (HTTP) и `7687` (Bolt) + +3. **Ошибка Аутентификации Neo4j**: + Конфигурация по умолчанию MemOS обычно использует `neo4j/password` или `neo4j/neo4j`. + Пожалуйста, проверьте ваши переменные окружения или конфигурационный файл: + ```bash + export NEO4J_PASSWORD="your_actual_password" + ``` + *Примечание: При первом запуске Neo4j требуется изменить пароль по умолчанию, убедитесь, что вы завершили этот шаг в браузере (http://localhost:7474).* + +## 2. Ошибки Службы Моделей + +### Ошибка Подключения К Ollama + +**Явление**: +Ошибка `Connection refused`, не удалось подключиться к `localhost:11434`, или сообщение о том, что модель не существует. + +**Решение**: +1. **Запустите Службу**:Убедитесь, что вы запустили `ollama serve` в терминале. +2. **Загрузите Модель**:MemOS `OllamaEmbedder` попытается проверить локальную модель, если она отсутствует, попытается выполнить pull, но рекомендуется выполнить это вручную для гарантии успеха: + ```bash + ollama pull nomic-embed-text + ``` +3. **Проблема С Адресом**:Если MemOS работает в Docker, `localhost` указывает на внутреннюю часть контейнера. Необходимо использовать `host.docker.internal` (Mac/Windows) или IP хоста (Linux) для настройки `api_base`. + +## 3. Ошибки Конфигурации + +### Отсутствие Необходимых Полей + +```python +# ✅ Всегда необходимо включать обязательные поля +llm_config = { + "backend": "openai", + "config": { + "api_key": "your-api-key", + "model_name_or_path": "gpt-4" + } +} +``` + +### Несоответствие Бэкенда + +```python +# ✅ KVCache необходимо использовать с бэкендом HuggingFace +# Ссылка на src/memos/memories/activation/kv.py +kv_config = { + "backend": "kv_cache", + "config": { + "extractor_llm": { + "backend": "huggingface", + "config": { + "model_name_or_path": "Qwen/Qwen3-1.7B" + } + } + } +} +``` + +## 4. Проблемы С Ресурсами Во Время Выполнения + +### Ошибка Загрузки Памяти (Несоответствие Схемы) + +**Явление**: +Ошибка `mem_cube.load()`, обычно из-за несовместимости структуры JSON файла с текущей версией кода. + +**Решение**: +Переинициализируйте MemCube и перезапишите старые данные (обратите внимание на риск потери данных): + +```python +try: + mem_cube.load("memory_dir") +except Exception: + logger.warning("Loading failed, initializing new memory cube") + mem_cube = GeneralMemCube(config) + # Будьте осторожны: это перезапишет старые данные + mem_cube.dump("memory_dir") +``` + +### Недостаточно Видеопамяти GPU + +**Решение**: +Используйте `CUDA_VISIBLE_DEVICES` для указания видеокарты или переключитесь на меньшую модель (например, версии 0.5B/1.5B). + +```python +import os +os.environ["CUDA_VISIBLE_DEVICES"] = "0" +``` + +## 5. Распространенные Проблемы С Управлением Пользователями + +**Явление**: +Вызов `get_user` возвращает None или выдает ошибку. + +**Решение**: +MemOS требует четкого процесса регистрации пользователей. + +```python +# 1. Зарегистрируйте MemCube для конкретного пользователя +mos.register_mem_cube(cube_path="path", user_id="user_id", cube_id="cube_id") + +# 2. Создайте или получите пользователя +try: + # Попробуйте создать пользователя + user_id = mos.create_user(user_name="john", role=UserRole.USER) +except ValueError: + # Если пользователь уже существует, получите его + user = mos.user_manager.get_user_by_name("john") +``` diff --git a/content/ru/open_source/best_practice/mcp_for_cozespace_and_tools.md b/content/ru/open_source/best_practice/mcp_for_cozespace_and_tools.md new file mode 100644 index 00000000..5a838348 --- /dev/null +++ b/content/ru/open_source/best_practice/mcp_for_cozespace_and_tools.md @@ -0,0 +1,416 @@ +--- +title: MemOS MCP Интеграционное Руководство +description: Настройка службы MCP MemOS на платформах, таких как Coze, для бесшовной интеграции агентов и системы памяти +--- + +Это руководство поможет вам настроить службу MCP MemOS на платформах, таких как Coze, для бесшовной интеграции агентов и системы памяти. + +## Выбор Способа Развертывания MCP + +MemOS предлагает два способа развертывания MCP, вы можете выбрать в зависимости от ваших потребностей: + +### Использование Облачной Службы MemOS (Рекомендуется) + +Если вы хотите быстро подключиться и не хотите развертывать сервер самостоятельно, рекомендуется использовать официальную облачную службу MemOS. + +**Преимущества:** +- ✅ Готово к использованию, не требует развертывания +- ✅ Гарантия высокой доступности +- ✅ Автоматическое масштабирование и обслуживание +- ✅ Поддержка различных клиентов (Claude, Cursor, Cline и др.) + +**Способ Настройки:** + +Пожалуйста, посетите [Руководство по Настройке MCP Облачной Службы MemOS](https://memos-docs.openmem.net/cn/mcp_agent/mcp/guide) для получения подробных инструкций по настройке. + +Основные Шаги: +1. Зарегистрируйте аккаунт на [MemOS API控制台](https://memos-dashboard.openmem.net/cn/apikeys/) и получите API Key +2. Настройте сервис `@memtensor/memos-api-mcp` в клиенте MCP +3. Установите переменные окружения (`MEMOS_API_KEY`, `MEMOS_USER_ID`, `MEMOS_CHANNEL`) + +### Самостоятельное Развертывание Службы MCP + +Если вам требуется приватное развертывание или индивидуальные настройки, вы можете развернуть службу MCP на своем сервере. + +**Преимущества:** +- ✅ Полная приватизация данных +- ✅ Настраиваемая конфигурация +- ✅ Полный контроль над службой +- ✅ Подходит для внутреннего использования в компании + +**Предварительные Требования:** +- Python 3.9+ +- База данных Neo4j (или другая поддерживаемая графовая база данных) +- HTTPS домен (для платформ, таких как Coze) + +Продолжайте читать ниже, чтобы узнать подробные шаги развертывания. + +--- + +## Настройка Самостоятельно Развернутой Службы MCP + +Следующее содержание предназначено для пользователей, которым необходимо самостоятельно развернуть службу MCP. + +## Описание Архитектуры + +Самостоятельно развернутая служба MCP использует следующую архитектуру: + +``` +Клиент (Coze/Claude и др.) + ↓ [HTTPS] +Сервер MCP (порт 8002) + ↓ [HTTP调用] +Сервер API (порт 8001) + ↓ +Основной сервис MemOS +``` + +**Описание Компонентов:** +- **Server API**: Предоставляет REST API интерфейс (`/product/*`), обрабатывает операции добавления, удаления, изменения и поиска памяти +- **Сервер MCP**: Экспонирует протокол MCP через HTTP, вызывает Server API для выполнения операций +- **HTTPS Обратный Прокси**: Платформы, такие как Coze, требуют использования безопасного соединения HTTPS + +::steps{level="3"} + +### Шаг 1: Запуск Server API + +Server API является бэкендом службы MCP, предоставляющим фактические функции управления памятью. + +```bash +cd /path/to/MemOS +python src/memos/api/server_api.py --port 8001 +``` + +Проверьте, работает ли Server API нормально: + +```bash +curl http://localhost:8001/docs +``` + +Если возвращается страница документации API, значит, запуск успешен. + +::note +**Конфигурационный Файл**
+Server API автоматически загрузит конфигурацию, убедитесь, что зависимости, такие как Neo4j, правильно настроены. Вы можете обратиться к `examples/data/config/tree_config_shared_database.json` для примера конфигурации. +:: + +### Шаг 2: Запуск MCP HTTP Службы + +Запустите службу MCP в другом терминале: + +```bash +cd /path/to/MemOS +python examples/mem_mcp/simple_fastmcp_serve.py --transport http --port 8002 +``` + +После запуска службы MCP будет отображена информация, похожая на следующую: + +``` +╭──────────────────────────────────────────────────╮ +│ MemOS MCP via Server API │ +│ Transport: HTTP │ +│ Server URL: http://localhost:8002/mcp │ +╰──────────────────────────────────────────────────╯ +``` + +**Настройка Переменных Среды (по желанию):** + +Вы можете настроить адрес Server API через файл `.env` или переменные среды: + +```bash +export MEMOS_API_BASE_URL="http://localhost:8001/product" +``` + +::note +**Список Инструментов**
+Служба MCP предоставляет следующие инструменты: +- `add_memory`: Добавить память +- `search_memories`: Искать память +- `chat`: Общаться с системой памяти + +Полный список инструментов см. в `examples/mem_mcp/simple_fastmcp_serve.py` +:: + +### Шаг 3: Настройка HTTPS Обратного Прокси + +Платформы, такие как Coze, требуют использования HTTPS соединения. Вам необходимо настроить HTTPS обратный прокси (например, Nginx), чтобы перенаправить трафик на службу MCP. + +**Пример Конфигурации Nginx:** + +```nginx +server { + listen 443 ssl http2; + server_name your-domain.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + location /mcp { + proxy_pass http://localhost:8002/mcp; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Поддержка SSE + proxy_buffering off; + proxy_cache off; + } +} +``` + +::warning +**SSL Сертификат**
+Убедитесь, что вы используете действительный SSL сертификат, самоподписанные сертификаты могут не быть приняты платформами, такими как Coze. Вы можете получить сертификат бесплатно с помощью Let's Encrypt. +:: + +### Шаг 4: Тестирование Службы MCP + +Используйте клиентский тестовый скрипт для проверки службы: + +```bash +cd /path/to/MemOS +python examples/mem_mcp/simple_fastmcp_client.py +``` + +Успешный вывод примера: + +``` +Working FastMCP Client +======================================== +Connected to MCP server + + 1. Adding memory... + Result: Memory added successfully + + 2. Searching memories... + Результат: [搜索结果] + + 3. Chatting... + Результат: [AI响应] + +✓ All tests completed! +``` + +:: + +## Настройка MCP в Coze + +После завершения развертывания службы настройте соединение MCP в пространстве Coze. + +::steps{level="3"} + +### Шаг 1: Откройте Пространство Coze и Перейдите на Страницу Настройки Инструментов + +![Страница конфигурации Coze](https://statics.memtensor.com.cn/memos/coze_space_1.png) + +### Шаг 2: Добавьте Пользовательский Инструмент MCP + +На странице настройки инструментов добавьте пользовательский инструмент: + +![Добавить пользовательский инструмент](https://statics.memtensor.com.cn/memos/coze_space_2.png) + +### Шаг 3: Настройка URL Соединения MCP + +Настройте URL соединения MCP, используя ваш настроенный HTTPS адрес: + +``` +https://your-domain.com/mcp +``` +Доступные инструменты MCP: +- **add_memory**: Добавить новую память +- **search_memories**: Поиск существующей памяти +- **chat**: Диалог на основе памяти + +::note +**Тестирование соединения**
+После завершения настройки проверьте, работает ли соединение MCP в Coze. Убедитесь, что вы можете успешно вызывать различные инструменты. +:: + +:: + +--- + +## Прямое использование REST API (Расширенный) + +Для сценариев, требующих более гибкой интеграции, вы можете напрямую использовать REST интерфейс Server API. + +::steps{level="3"} + +### Шаг 1: Запуск Server API + +```bash +cd /path/to/MemOS +python src/memos/api/server_api.py --port 8001 +``` +**Описание порта** +- Server API по умолчанию работает на порту 8001 +- Предоставляет REST API конечные точки `/product/*` + +### Шаг 2: Настройка пользовательских инструментов в Coze IDE + +1. В Coze выберите способ создания "IDE плагин" +2. Настройте запрос к вашему развернутому сервису Server API + +![Конфигурация плагина Coze IDE](https://statics.memtensor.com.cn/memos/coze_tools_1.png) + +### Шаг 3: Реализация инструмента add_memory + +![Конфигурация add_memory операции](https://statics.memtensor.com.cn/memos/coze_tools_2.png) + +**Пример кода:** Настройка операции `add_memory` в IDE и публикация: + +![Конфигурация add_memory операции](https://statics.memtensor.com.cn/memos/coze_tools_2.png) +Подробный код ниже + +```python +import json +import requests +from runtime import Args +from typings.add_memory.add_memory import Input, Output + +def handler(args: Args[Input])->Output: + memory_content = args.input.memory_content + user_id = args.input.user_id + cube_id = args.input.cube_id + + # Вызов интерфейса add Server API + url = "https://your-domain.com:8001/product/add" + payload = json.dumps({ + "user_id": user_id, + "messages": memory_content, # Поддерживает строки или массивы сообщений + "writable_cube_ids": [cube_id] if cube_id else None + }) + headers = { + 'Content-Type': 'application/json' + } + + response = requests.post(url, headers=headers, data=payload, timeout=30) + response.raise_for_status() + + return response.json() +``` + +**Реализация других инструментов:** + +Аналогично реализуйте инструменты search и chat: + +```python +# Инструмент Search +def search_handler(args: Args[Input]) -> Output: + url = "https://your-domain.com:8001/product/search" + payload = json.dumps{ + "user_id": args.input.user_id, + "query": args.input.query, + }) + headers = { + 'Content-Type': 'application/json' + } + + response = requests.post(url, headers=headers, data=payload, timeout=30) + response.raise_for_status() + + return response.json() + +# Инструмент Chat +def chat_handler(args: Args[Input]) -> Output: + url = "https://your-domain.com:8001/product/chat/complete" + payload = json.dumps({ + "user_id": args.input.user_id, + "query": args.input.query + }) + response = requests.post(url, json=payload, timeout=30) + return response.json() +``` + +### Шаг 4: Публикация и тестирование инструментов + +После завершения публикации вы можете просмотреть плагин в "Мои ресурсы": + +![Ресурсы плагина после публикации](https://statics.memtensor.com.cn/memos/coze_tools_3.png) + +### Шаг 5: Интеграция в рабочий процесс агента + +Добавьте плагин в рабочий процесс агента: + +1. Создайте нового агента или отредактируйте существующего +2. В списке инструментов добавьте опубликованный плагин MemOS +3. Настройте рабочий процесс, вызовите инструменты памяти +4. Протестируйте функции хранения и извлечения памяти + +:: + +--- + +## Часто задаваемые вопросы + +### Q1: MCP служба не может подключиться к Server API + +**Решение:** +- Проверьте, работает ли Server API: `curl http://localhost:8001/docs` +- Проверьте, правильно ли настроена переменная окружения `MEMOS_API_BASE_URL` +- Просмотрите журналы службы MCP, чтобы подтвердить адрес вызова + +### Q2: Coze не может подключиться к MCP службе + +**Решение:** +- Убедитесь, что используется HTTPS соединение +- Проверьте, действителен ли SSL сертификат +- Проверьте конфигурацию обратного прокси: `curl https://your-domain.com/mcp` +- Проверьте настройки брандмауэра и группы безопасности + +### Q3: Ошибка подключения к Neo4j + +**Решение:** +- Убедитесь, что служба Neo4j работает нормально +- Проверьте информацию о подключении в конфигурационном файле (uri, user, password) +- Смотрите пример конфигурации в `examples/data/config/tree_config_shared_database.json` + +### Q4: Как посмотреть полный пример API? + +**Справочный документ:** +- MCP сервер: `examples/mem_mcp/simple_fastmcp_serve.py` +- MCP клиент: `examples/mem_mcp/simple_fastmcp_client.py` +- Тест API: `examples/api/server_router_api.py` + +--- + +## Резюме + +С помощью этого руководства вы можете: +- ✅ Выбрать подходящий способ развертывания MCP (облачный сервис или собственное развертывание) +- ✅ Завершить полный процесс развертывания службы MCP +- ✅ Интегрировать функции памяти MemOS на платформах, таких как Coze +- ✅ Прямо интегрировать с помощью REST API + +Независимо от выбранного способа, MemOS может предоставить вашему агенту мощное управление памятью. + +::note +**Описание параметров API** +- Используйте стандартный формат параметров Server API +- `messages`: заменяет прежний `memory_content`, поддерживает строки или массивы сообщений +- `writable_cube_ids`: заменяет прежний `mem_cube_id`, поддерживает несколько кубов +- Server API работает на порту 8001, путь `/product/add` +- Убедитесь, что он соответствует интерфейсу MemOS Server API, можно обратиться к примеру в `examples/api/server_router_api.py` +**Настройка IDE**
В IDE вы можете настроить параметры инструмента, формат возвращаемых значений и т. д., чтобы убедиться, что они соответствуют интерфейсу MemOS API. Используйте этот метод для завершения написания интерфейса search и интерфейса регистрации пользователя, и нажмите на публикацию +:: + +### Публикация и использование плагина + +После завершения публикации вы можете просмотреть плагин в "Мои ресурсы", чтобы интегрировать его в рабочий процесс агента: + +![Ресурсы плагина после публикации](https://statics.memtensor.com.cn/memos/coze_tools_3.png) + +### Создание агента и тестирование + +После создания самого простого агента вы можете протестировать операции с памятью: + +1. Создайте нового агента +2. Добавьте опубликованный плагин памяти +3. Настройте рабочий процесс +4. Протестируйте функции хранения и извлечения памяти + +С помощью вышеуказанной настройки вы сможете успешно интегрировать функции памяти MemOS в пространство Coze, предоставив вашему агенту мощные возможности памяти. diff --git a/content/ru/open_source/best_practice/memory_structure_design.md b/content/ru/open_source/best_practice/memory_structure_design.md new file mode 100644 index 00000000..c8374ae8 --- /dev/null +++ b/content/ru/open_source/best_practice/memory_structure_design.md @@ -0,0 +1,138 @@ +--- +title: Лучшие Практики Проектирования Структуры Памяти +--- + +## Выбор Типа Памяти + +### Деревовидная Открытая Память + +**Лучше всего подходит для**: Управление знаниями, Помощник по исследованиям, Иерархические данные +```python +tree_config = { + "backend": "tree_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b" + } + }, + "graph_db": { + "backend": "neo4j", + "config": { + "host": "localhost", + "port": 7687 + } + } + } +} +``` + +### Память Открытых Предпочтений + +**Лучше всего подходит для**: Персонализированные диалоги, Умные рекомендации, Обслуживание клиентов + +```python +preference_config = { + "backend": "preference_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b", + } + }, + "vector_db": { + "backend": "milvus", + "config": { + "collection_name": [ + "explicit_preference", + "implicit_preference" + ], + "vector_dimension": 768, + "distance_metric": "cosine", + "uri": "./milvus_demo.db" + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": "nomic-embed-text:latest" + } + }, + "reranker": { + "backend": "cosine_local", + "config": { + "level_weights": { + "topic": 1.0, + "concept": 1.0, + "fact": 1.0 + }, + "level_field": "background" + } + } + } +} +``` + +### Универсальная Открытая Память (с векторным индексом) + +**Лучше всего подходит для**: Диалоговый ИИ, Личный помощник, Системы вопросов и ответов + +```python +general_config = { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b" + } + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": "general" + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": "nomic-embed-text" + } + } + } +} +``` + +### Чистая Открытая Память (только текст) + +**Лучше всего подходит для**: Простые приложения, Прототипирование + +```python +naive_config = { + "backend": "naive_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b" + } + } + } +} +``` + +## Планирование Вместимости + +Если вы включили планировщик, вы можете установить емкость памяти для контроля использования ресурсов: + +```python +scheduler_config = { + "memory_capacities": { + "working_memory_capacity": 20, # Рабочая Память + "user_memory_capacity": 500, # Память Пользователя + "long_term_memory_capacity": 2000 # Долговременная Память + } +} +``` diff --git a/content/ru/open_source/best_practice/network_workarounds.md b/content/ru/open_source/best_practice/network_workarounds.md new file mode 100644 index 00000000..ccac1a9f --- /dev/null +++ b/content/ru/open_source/best_practice/network_workarounds.md @@ -0,0 +1,116 @@ +--- +title: Решение Проблем С Сетью +desc: Ниже приведены некоторые решения сетевых проблем, с которыми можно столкнуться в процессе разработки. +--- + +## **Скачать Модель Huggingface** + +### Зеркальный Сайт (HF-Mirror) + +Чтобы скачать модель Huggingface через зеркальный сайт, выполните следующие шаги: + +::steps{level="4"} + +#### Установка Зависимостей + +Запустите следующую команду для установки необходимых зависимостей: + +```bash +pip install -U huggingface_hub +``` + +#### Установка Переменных Среды + +Установите переменную среды `HF_ENDPOINT` в `https://hf-mirror.com`. + +#### Скачать Модель Или Набор Данных + +Используйте huggingface-cli для скачивания модели или набора данных. Например: + +- Скачайте Модель: + + ```bash + huggingface-cli download --resume-download gpt2 --local-dir gpt2 + ``` +- Скачайте Набор Данных: + ``` + huggingface-cli download --repo-type dataset --resume-download wikitext --local-dir wikitext + ``` + +:: + +Для получения более подробных инструкций и других методов, смотрите [эту ссылку](https://hf-mirror.com/). + +### Другие Источники + +В некоторых регионах все еще может быть недоступен доступ к некоторым моделям. В этом случае можно использовать modelscope: + +::steps{level="4"} + +#### Установка ModelScope + +Запустите следующую команду для установки необходимых зависимостей: + +```bash +pip install modelscope[framework] +``` + +#### Скачать Модель Или Набор Данных + +Используйте modelscope для скачивания модели или набора данных. Например: + +* Скачайте Модель: + + ```bash + modelscope download --model 'Qwen/Qwen2-7b' --local_dir 'path/to/dir' + ``` + +* Скачайте Набор Данных: + + ```bash + modelscope download --dataset 'Tongyi-DataEngine/SA1B-Dense-Caption' --local_dir './local_dir' + ``` + +:: + +Для получения более подробных инструкций и других методов, смотрите [официальную документацию](https://modelscope.cn/docs/home). + +## **Использование Poetry** + +### Сетевые Ошибки Во Время Установки + +В некоторых регионах использование "poetry install" может привести к сетевым ошибкам, вы можете решить это следующим образом: + +::steps{level="4"} + +#### Обновить Конфигурацию + +Добавьте следующую конфигурацию в файл `pyproject.toml`, чтобы использовать зеркальный источник: + +```toml +[[tool.poetry.source]] +name = "mirrors" +url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/" +priority = "primary" +``` + +#### Переконфигурировать Poetry + +Запустите команду `poetry lock` в терминале, чтобы переконфигурировать Poetry с новым зеркальным источником. + +:: + +**Подсказка:** +Обратите внимание, что `poetry lock` изменит файлы `pyproject.toml` и `poetry.lock`. Чтобы избежать внесения ненужных изменений: + +- Вариант 1: После успешного выполнения `poetry install`, используйте `git reset --hard HEAD`, чтобы вернуться к узлу Git HEAD. +- Вариант 2: При выполнении `git add`, исключите файлы `pyproject.toml` и `poetry.lock`, добавляя только другие файлы. + +В будущем, при добавлении или удалении пакетов зависимостей, вы можете использовать следующую команду: + +```bash +poetry add +``` + +Для получения дополнительных команд и инструкций, смотрите [официальную документацию Poetry CLI](https://python-poetry.org/docs/cli/). + diff --git a/content/ru/open_source/best_practice/performance_tuning.md b/content/ru/open_source/best_practice/performance_tuning.md new file mode 100644 index 00000000..d83f57a3 --- /dev/null +++ b/content/ru/open_source/best_practice/performance_tuning.md @@ -0,0 +1,132 @@ +--- +title: Оптимизация Производительности +--- + +Оптимизация производительности MemOS в основном сосредоточена на **Извлечении Памяти (Mem-Reader)**, **Векторном Встраивании (Embedding)** и **Ранжировании Поиска (Search Ranking)**. Большинство настроек можно выполнить, изменив YAML конфигурационный файл (например, `memos_config_w_scheduler.yaml`) или непосредственно отредактировав исходный код. + +## 1. Оптимизация Извлечения Памяти (Mem-Reader Prompt) + +slow_embedder = { + "backend": "sentence_transformer", + "config": { + "model_name_or_path": "nomic-ai/nomic-embed-text-v1.5" + } +} +``` +`Mem-Reader` компонент отвечает за извлечение ключевой информации из диалога. В текущей реализации Prompt определен в шаблоне исходного кода. + +### Изменение Шаблона Prompt + +Чтобы настроить логику извлечения (например, игнорировать болтовню, сосредоточиться на конкретных фактах), вам нужно напрямую изменить файл исходного кода: + +* **Путь к файлу**: `src/memos/templates/mem_reader_prompts.py` +* **Целевая переменная**: `SIMPLE_STRUCT_MEM_READER_PROMPT` (для английского) или `SIMPLE_STRUCT_MEM_READER_PROMPT_ZH` (для китайского) + +**Пример изменения**: + +В `src/memos/templates/mem_reader_prompts.py`: + +```python +SIMPLE_STRUCT_MEM_READER_PROMPT = """ +You are a preference extraction expert. +Your task is to extract ONLY user preferences and dislikes from the conversation. +Ignore all other information including plans and daily events. +... +""" +``` + +## 2. Оптимизация Моделей Векторного Встраивания (Embedding Models) + +Выбор модели векторного встраивания определяет точность и скорость семантического поиска. Обычно это настраивается в YAML конфигурационном файле. + +### Изменение Конфигурационного Файла + +В вашем конфигурационном файле (например, `memos_config.yaml`), найдите раздел `embedder` под `mem_reader` или `text_mem`: + +```yaml +mem_reader: + backend: "simple_struct" + config: + # ... другие настройки + embedder: + # Вариант A: Использовать Ollama (быстро, подходит для локального использования) + backend: "ollama" + config: + model_name_or_path: "nomic-embed-text:latest" + + # Вариант B: Использовать Sentence Transformer (высокая точность, большое использование видеопамяти) + # backend: "sentence_transformer" + # config: + # model_name_or_path: "BAAI/bge-m3" +``` + +* **Рекомендуемые модели**: + * **Быстро/Локально**: `nomic-embed-text` (Ollama) + * **Высокая точность**: `BAAI/bge-m3` или `OpenAI` `text-embedding-3-small` (необходимо использовать `universal_api` backend) + +## 3. Оптимизация Ранжирования Поиска (Search Ranking) + +Производительность поиска в основном зависит от количества извлечений (`top_k`) и стратегии повторного ранжирования. + +### Настройка Количества Извлечений (Top-K) + +Настройте `top_k` в конфигурации `mem_scheduler`. Увеличение этого значения может повысить уровень извлечения, но увеличит время обработки. + +```yaml +mem_scheduler: + backend: "general_scheduler" + config: + # Начальное количество кандидатов для поиска + top_k: 20 + # ... +``` + +### Введение Reranker (Продвинутый) + +MemOS поддерживает введение Reranker для точной сортировки после извлечения. Обычно это требует указания при инициализации компонента `Searcher`. Если вы интегрируете MemOS как разработчик, вы можете настроить это в коде: + +```python +from memos.reranker.factory import RerankerFactory + +# При инициализации Searcher +reranker = RerankerFactory.from_config({ + "backend": "sentence_transformer", + "config": { + "model_name_or_path": "BAAI/bge-reranker-base" + } +}) +``` + +## 4. Ограничения Системных Ресурсов и Вместимости + +Разумное ограничение емкости различных типов памяти может предотвратить бесконечный рост памяти и поддерживать скорость поиска. Обычно это настраивается в конфигурации `mem_cube`. + +### Настройка Емкости Памяти (Memory Size) + +В YAML конфигурационном файле настройте словарь `memory_size`: + +```yaml +mem_cube: + backend: "general" + config: + text_mem: + backend: "tree" + config: + # Ограничение количества записей различных типов памяти + memory_size: + WorkingMemory: 10 # Краткосрочная память последних нескольких раундов диалога + LongTermMemory: 2000 # Предел долгосрочной памяти + UserMemory: 500 # Предел профиля/предпочтений пользователя +``` + +### Пакетная Обработка и Параллелизм + +В `mem_scheduler` можно настроить возможности параллельной обработки: + +```yaml +mem_scheduler: + config: + thread_pool_max_workers: 10 # Количество потоков для параллельной обработки + consume_interval_seconds: 0.01 # Интервал потребления в очереди сообщений + enable_parallel_dispatch: true # Включить параллельную рассылку +``` diff --git a/content/ru/open_source/contribution/commit_guidelines.md b/content/ru/open_source/contribution/commit_guidelines.md new file mode 100644 index 00000000..bd5e7039 --- /dev/null +++ b/content/ru/open_source/contribution/commit_guidelines.md @@ -0,0 +1,18 @@ +--- +title: Стандарты Подачи +--- + +Пожалуйста, следуйте формату [Conventional Commits](https://www.conventionalcommits.org/) : + +- `feat:` Используется для добавления новой функции +- `fix:` Используется для исправления ошибки +- `docs:` Используется для обновления документации +- `style:` Используется для изменения формата (не влияет на логику кода) +- `refactor:` Используется для рефакторинга кода +- `test:` Используется для добавления или обновления тестов +- `chore:` Используется для других задач по обслуживанию +- `ci:` Используется для изменений, связанных с CI/CD или рабочими процессами + +**Пример:** +`feat: add user authentication` + diff --git a/content/ru/open_source/contribution/development_workflow.md b/content/ru/open_source/contribution/development_workflow.md new file mode 100644 index 00000000..f5ddda3e --- /dev/null +++ b/content/ru/open_source/contribution/development_workflow.md @@ -0,0 +1,75 @@ +--- +title: Процесс Разработки +--- + +Следуйте приведенным ниже шагам, чтобы участвовать в разработке проекта. + +::steps{level="4"} + +#### Синхронизация с Внешним Репозиторием + +Если вы ранее сделали форк этого репозитория, пожалуйста, поддерживайте синхронизацию с изменениями в внешнем репозитории: + +```bash +git checkout dev # Переключиться на ветку dev +git fetch upstream # Получить последние изменения из upstream репозитория +git pull upstream dev # Объединить изменения в локальную ветку dev +git push origin dev # Отправить объединенный код в ваш собственный fork +``` + +#### Создание Функциональной Ветки + +Создайте новую ветку для вашей новой функции или исправления: + +```bash +git checkout -b feat/descriptive-name +``` + +#### Добавление Вашей Функции или Исправления + +Реализуйте вашу функцию, исправление или улучшение в соответствующих файлах. + +* Например, вы можете добавить функцию в `src/memos/hello_world.py` и написать соответствующие тестовые случаи в `tests/test_hello_world.py`. + +#### Тестирование Ваших Изменений + +Запустите тестовый пакет, чтобы убедиться, что изменения корректны: + +```bash +make test +``` + +#### Отправка Изменений + +Перед отправкой или PR выполните rebase на последнюю версию upstream/dev: + +```bash +git fetch upstream +git rebase upstream/dev # Переместить вашу ветку feat на основе последнего dev +``` + +При отправке изменений следуйте стандартам коммитов проекта (см. [Стандарты Коммитов](commit_guidelines.md)). + +#### Отправка в Ваш Форк Репозиторий + +Отправьте функциональную ветку в ваш удаленный репозиторий форка: + +```bash +git push origin feat/descriptive-name +``` + +#### Создать Pull Request + +Отправьте ваши изменения на рассмотрение: + +* **Важно:** Обязательно отправьте Pull Request в: + + * ✅ Ветку `dev` внешнего репозитория, + * ❎ А не в ветку `main` внешнего репозитория. +* Откройте оригинальный репозиторий на GitHub +* Нажмите "Pull Requests" +* Нажмите "New Pull Request" +* Выберите `dev` в качестве целевой ветки, а вашу ветку в качестве ветки для сравнения +* Тщательно заполните описание PR + +:: diff --git a/content/ru/open_source/contribution/overview.md b/content/ru/open_source/contribution/overview.md new file mode 100644 index 00000000..27230183 --- /dev/null +++ b/content/ru/open_source/contribution/overview.md @@ -0,0 +1,15 @@ +--- +title: Участие в Разработке MemOS +desc: Добро пожаловать в руководство по вкладу в MemOS! Узнайте, как настроить среду разработки, следовать нашему процессу разработки, писать корректные сообщения о коммитах, улучшать документацию и добавлять тестовые случаи. +--- + +- **Первый раз вносите вклад?** Пожалуйста, сначала прочитайте [Руководство по Настройке Среды](setting_up.md), чтобы подготовить вашу среду разработки. +- **Готовы начать кодировать?** Пожалуйста, ознакомьтесь с [Процессом Разработки](development_workflow.md), чтобы понять наш процесс внесения изменений. +- **Пишите корректные сообщения о коммитах:** Пожалуйста, ознакомьтесь с нашими [Руководством по Коммитам](commit_guidelines.md). +- **Участвуйте в написании документации:** Если вы помогаете нам улучшить документацию, пожалуйста, прочитайте [Руководство по Написанию Документации](writing_docs.md). +- **Добавляйте или улучшайте тестовые случаи:** Пожалуйста, ознакомьтесь с [Руководством по Написанию Тестов](writing_tests.md). + +Ваш вклад делает этот проект лучше! ✨ Если у вас есть какие-либо вопросы, не стесняйтесь подавать issue или участвовать в обсуждениях, вы также можете отсканировать QR-код ниже, чтобы присоединиться к нашему Discord или WeChat-сообществу и связаться с нами. + +QR Code + diff --git a/content/ru/open_source/contribution/setting_up.md b/content/ru/open_source/contribution/setting_up.md new file mode 100644 index 00000000..4a9ecf69 --- /dev/null +++ b/content/ru/open_source/contribution/setting_up.md @@ -0,0 +1,205 @@ +--- +title: Настройка Разработческой Среды +desc: Чтобы участвовать в разработке MemOS, вам необходимо настроить разработческую среду на локальном компьютере. +--- + +::steps{level="4"} + +#### Форк и Клонирование Репозитория + +Настройка проектного репозитория на локальном компьютере: + +- Сделайте форк репозитория на GitHub +- Клонируйте ваш форк на локальный компьютер: + + ```bash + git clone https://github.com/YOUR-USERNAME/MemOS.git + cd MemOS + ``` + +- Добавьте upstream репозиторий как удаленный источник: + + ```bash + git remote add upstream https://github.com/MemTensor/MemOS.git + ``` + +#### Подготовка Зависимостей Для Разработки + +Убедитесь, что на локальном компьютере установлено: + +- Git +- Python 3.9+ +- Make + +Проверьте Python: + +```bash +python3 --version +``` + +#### Установка Poetry + +MemOS использует Poetry для управления зависимостями Python. Рекомендуется использовать официальный скрипт установки: + +```bash +curl -sSL https://install.python-poetry.org | python - +``` + +Проверьте, успешно ли выполнена установка: + +```bash +poetry --version +``` + +Если появится сообщение `poetry: command not found`, добавьте каталог исполняемого файла Poetry, указанный в выводе установщика, в PATH, затем закройте и снова откройте терминал для проверки. + +Дополнительные варианты установки см. в: [Официальное Руководство По Установке](https://python-poetry.org/docs/#installing-with-the-official-installer). + +#### Установка Зависимостей И Настройка Pre-commit Хуков + +Установите все зависимости и инструменты разработки в корневом каталоге репозитория: + +```bash +make install +``` + +Подсказка: + +- Если вы переключаете ветки или зависимости изменяются, возможно, вам потребуется **снова запустить `make install`**, чтобы поддерживать согласованность среды. + +### Понимание Модулей Памяти И Выбор Зависимостей +Перед настройкой среды нам нужно понять классификацию модулей памяти MemOS и соответствующие зависимости баз данных. Это определит, какие компоненты вам нужно установить. + +#### Типы Памяти + +Система памяти MemOS в основном делится на два типа (идентификаторы для параметра конфигурации `backend` в скобках): + +- **Текстовая Память (Textual Memory)**: относится к фактической памяти, **необходимо выбрать один из вариантов**. + - `tree` (`tree_text`): Деревовидная память (рекомендуется), с наивысшей степенью структурированности. + - `general` (`general_text`): Общая память, основанная на векторном поиске. + - `naive` (`naive_text`): Простая память, без специальных зависимостей (используется только для тестирования). +- **Память Предпочтений (Preference Memory)**: относится к пользовательским предпочтениям, **опционально**. + - `pref`: используется для хранения и извлечения пользовательских предпочтений. + +#### Матрица Зависимостей Баз Данных + +Разные типы памяти требуют различной поддержки баз данных: + +| Тип Памяти | Зависимые Компоненты | Примечания | +| :--- | :--- | :--- | +| **Tree** | **Графовая База Данных** | Обязательно. Поддерживает Neo4j Desktop, Neo4j Community, PolarDB | +| **General** | **Векторная База Данных** | Обязательно. Рекомендуется использовать Qdrant (или совместимую векторную БД) | +| **Naive** | Нет | Не требуется установка базы данных | +| **Pref** | **Milvus** | Если включена память предпочтений, необходимо установить Milvus | + +#### О Выборе Деревовидной Памяти И Графовых Баз Данных + +Если вы выбрали использовать **деревовидный текстовый бэкенд памяти** (идентификатор конфигурации обычно `tree_text`), вам необходимо подготовить **графовую базу данных (Graph DB)** в качестве основы для хранения и запросов. В настоящее время доступны следующие варианты: + +- **Neo4j Desktop** (рекомендуется для ПК): установите на локальном компьютере и управляйте базой данных через графический интерфейс, подходит для быстрого освоения и отладки. +- **PolarDB**: облачный сервис графовой базы данных (платный), подходит для производственных или командных сценариев. +- **Neo4j Community** (сообщество): открытый и бесплатный, подходит для развертывания на серверах или в среде Linux. + +**Особое Замечание**: + +- При использовании **Neo4j Desktop** вам нужно сосредоточиться только на запуске и подключении к базе данных, что упрощает повседневную отладку. +- При использовании **Neo4j Community** необходимо учитывать: он **не предоставляет нативные возможности векторного индексации**. Если ваш процесс требует векторного поиска/поиска по сходству, обычно необходимо использовать **внешнюю векторную библиотеку** (например, Qdrant) для дополнения соответствующих возможностей. + +#### Конфигурационный План Для Настройки В этом Учебнике + +Для удобства разработчиков, чтобы быстро запустить основные цепочки, в этом учебнике используется следующая комбинация: + +- **Текстовый Бэкенд Памяти**: `tree_text` (концептуально соответствует деревовидной памяти) +- **Графовая База Данных**: Neo4j Community (можно запустить с помощью Docker) +- **Векторные Возможности**: Qdrant (локальный режим) + +Поскольку Neo4j Community не поддерживает нативную векторную индексацию, в этом учебнике вводится Qdrant в качестве дополнения к векторным возможностям. Чтобы снизить сложность среды, мы **не запускаем серверный процесс Qdrant** (не запускаем контейнер Qdrant), а используем **локальный режим** Qdrant: в конфигурации указывается путь к локальному хранилищу (`path`), и система инициализирует и читает необходимые файлы данных в этом каталоге. Если путь не указан явно, будет использоваться путь по умолчанию для инициализации и постоянного хранения (конкретное местоположение по умолчанию зависит от реализации и конфигурации проекта). + +#### Создание Конфигурационного Файла + +.env Содержимое, Быстрая Конфигурация См. В [env Конфигурация](/open_source/getting_started/installation#2.-.env-内容) Под Установкой Docker +Подробная Конфигурация .env См. В [env Конфигурация](/open_source/getting_started/rest_api_server/#本地运行) + +::note +**Пожалуйста, Обратите Внимание**
+Конфигурация .env Файла Должна Находиться В Корневом Каталоге Проекта MemOS +:: + +```bash +cd MemOS +touch .env +``` +#### Конфигурация Dockerfile Файла +::note +**Пожалуйста, Обратите Внимание**
+Dockerfile Файл Находится В Каталоге Docker +:: + +```bash +# Перейдите в каталог docker +cd docker +``` +Содержит Быстрый Режим И Полный Режим, Может Различать Использование Упрощенного Пакета (Различает arm И x86) И Полного Пакета (Различает arm И x86) + +```bash + +● Упрощенный пакет: Упрощает зависимости, связанные с nvidia и т.д., для уменьшения размера образа, делая локальное развертывание более легким и быстрым. +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-base:v1.0 +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-base-arm:v1.0 + +● Полный пакет: Упаковывает все зависимости MemOS в образ, позволяя использовать полный функционал, можно напрямую построить и запустить через конфигурацию Dockerfile. +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-full-base:v1.0.0 +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-full-base-arm:v1.0.0 +``` + +```bash +# Текущий пример использует упрощенный пакет url +FROM registry.cn-shanghai.aliyuncs.com/memtensor/memos-base-arm:v1.0 + +WORKDIR /app + +ENV HF_ENDPOINT=https://hf-mirror.com + +ENV PYTHONPATH=/app/src + +COPY src/ ./src/ + +EXPOSE 8000 + +CMD ["uvicorn", "memos.api.server_api:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] + +``` + +#### Запуск Docker Клиента +```bash + # Если Docker не установлен, пожалуйста, установите соответствующую версию, ссылка для загрузки ниже: + https://www.docker.com/ + + # После завершения установки вы можете запустить Docker через клиент или через командную строку. + # Запуск Docker через командную строку + sudo systemctl start docker + +# После завершения установки проверьте состояние Docker +docker ps + +# Просмотр образов Docker (необязательно) +docker images + +``` + +#### Построить И Запустить Сервис : +::note +**Пожалуйста, Обратите Внимание**
+Команда Построения Также Находится В Каталоге Docker +:: +```bash +# В каталоге Docker +docker compose up neo4j +``` +#### Создать Терминал Для Запуска Порта Сервера : + +```bash +cd MemOS +make serve +``` +:: diff --git a/content/ru/open_source/contribution/writing_docs.md b/content/ru/open_source/contribution/writing_docs.md new file mode 100644 index 00000000..8dfc3986 --- /dev/null +++ b/content/ru/open_source/contribution/writing_docs.md @@ -0,0 +1,547 @@ +--- +title: Руководство По Написанию Документации +desc: Этот проект использует Nuxt Content для создания системы документации, поддерживающей Markdown и богатые Vue компоненты. +--- + +## Создание Нового Документа + +::steps +### Создание Markdown Файла +Создайте новый `.md` файл в директории `content/` или ее поддиректориях. Выберите подходящее место в зависимости от типа содержимого. + +### Добавить Frontmatter +Добавьте YAML frontmatter в верхней части файла для предоставления метаданных. Frontmatter поддерживает следующие поля: + +::card{title="Поля Frontmatter"} +**Обязательные поля:** +- `title` (строка) - Заголовок документа, отображаемый в навигации и заголовке страницы. + +**Необязательные поля:** +- `desc` (строка) - Краткое описание содержания документа. +- `banner` (строка) - Ссылка на изображение баннера, отображаемого в верхней части страницы. +- `links` (массив) - Массив связанных ссылок, содержащий метки, URL и иконки. + +![Пример Frontmatter](https://statics.memtensor.com.cn/memos/frontmatter.png) +:: + +**Пример Полного Frontmatter:** + +```yaml +--- +title: MemOS Документация +desc: Добро пожаловать в официальную документацию MemOS — пакет Python, предназначенный для расширения возможностей больших языковых моделей (LLMs) в реализации продвинутых, модульных возможностей памяти. +banner: https://statics.memtensor.com.cn/memos/memos-banner.gif +links: + - label: 'PyPI' + to: https://pypi.org/project/MemoryOS/ + target: _blank + avatar: + src: https://statics.memtensor.com.cn/icon/pypi.svg + alt: PyPI logo + - label: 'Адрес репозитория' + to: https://github.com/MemTensor/MemOS + target: _blank + icon: i-simple-icons-github +--- +``` + +### Написание Содержимого +Используйте синтаксис Markdown и компоненты MDC для написания содержания документа. Используйте существующие компоненты для создания четкой структуры, удобного взаимодействия и богатого содержания. + +### Обновление Навигации +Добавьте новый документ в раздел `nav` файла `content/settings.yml`, чтобы получить доступ к нему в навигации сайта. + +### Слияние В Основную Ветку +Как только изменения будут слиты в ветку `main`, документация будет автоматически обновлена и развернута. +:: + +## Примеры Компонентов + +Этот проект использует синтаксис MDC (Markdown Components) от Nuxt Content, который поддерживает использование Vue компонентов в Markdown. Эти компоненты помогают создавать стилистически согласованное, хорошо структурированное и качественное содержание документации. + +### Image + +При добавлении изображений в документацию можно использовать несколько способов ссылки: + +#### Использование Компонента Base64Image Для Ссылки На Локальные Изображения + +Для изображений, хранящихся в директории `public/assets`, рекомендуется использовать компонент `Base64Image`, который может встраивать изображения непосредственно в страницу для повышения производительности: + +```mdc +:Base64Image{src="/assets/memos-architecture.png" alt="MemOS Architecture"} +``` + +#### Использование Синтаксиса Markdown Для Ссылки На Удаленные Изображения + +Для изображений, размещенных на внешних серверах, используйте стандартный синтаксис изображений Markdown: + +```markdown +![MemOS Architecture](https://statics.memtensor.com.cn/memos/memos-architecture.png) +``` + +### Steps + +Используйте компонент `steps` для автоматической нумерации заголовков документа, создавая пошаговые руководства. + +::code-preview +--- +class: "[&>div]:*:w-full" +--- + :::steps{level="4"} +#### Форк И Клонирование Репозитория + +Настройте проектный репозиторий локально: + +- Форкнуть репозиторий на GitHub +- Клонировать ваш форк на локальный компьютер: + + ```bash + git clone https://github.com/YOUR-USERNAME/MemOS.git + cd MemOS + ``` + +- Добавить upstream репозиторий как удаленный источник: + + ```bash + git remote add upstream https://github.com/MemTensor/MemOS.git + ``` + +#### Подготовка Зависимостей Для Разработки + +Убедитесь, что у вас установлено: + +- Git +- Python 3.9+ +- Make + +Проверьте Python: + +```bash +python3 --version +``` + +#### Установка Poetry + +MemOS использует Poetry для управления зависимостями Python. Рекомендуется использовать официальный скрипт установки: + +```bash +curl -sSL https://install.python-poetry.org | python3 - +``` + +Проверьте, успешно ли выполнена установка: + +```bash +poetry --version +``` + +Если появится сообщение `poetry: command not found`, добавьте каталог исполняемого файла Poetry, указанный в выводе установщика, в PATH, затем снова откройте терминал и проверьте. + +Дополнительные варианты установки смотрите в: [Официальное Руководство По Установке](https://python-poetry.org/docs/#installing-with-the-official-installer). + +#### Установка Зависимостей И Настройка Pre-commit Хуков + +Установите все зависимости и инструменты разработки в корневом каталоге репозитория: + +```bash +make install +``` + +Подсказка: + +- Если вы переключаете ветки или зависимости изменяются, возможно, вам потребуется **снова запустить `make install`**, чтобы поддерживать согласованность среды +::: + +#code +````mdc +::steps{level="4"} + +#### Форкнуть и клонировать репозиторий + +Настроить проектный репозиторий локально: + +- Форкнуть репозиторий на GitHub +- Клонировать ваш форк на локальный компьютер: + + ```bash + git clone https://github.com/YOUR-USERNAME/MemOS.git + cd MemOS + ``` + +- Добавить upstream репозиторий как удаленный источник: + + ```bash + git remote add upstream https://github.com/MemTensor/MemOS.git + ``` + +#### Подготовить зависимости для разработки + +Убедитесь, что у вас установлено: + +- Git +- Python 3.9+ +- Make + +Проверить Python: + +```bash +python3 --version +``` + +#### Установка Poetry + +MemOS использует Poetry для управления зависимостями Python. Рекомендуется использовать официальный скрипт установки: + +```bash +curl -sSL https://install.python-poetry.org | python3 - +``` + +Проверьте, успешна ли установка: + +```bash +poetry --version +``` + +Если появится сообщение `poetry: command not found`, добавьте каталог исполняемого файла Poetry, указанный в выводе установщика, в PATH, затем снова откройте терминал и проверьте. + +Дополнительные варианты установки см. в: [Официальное руководство по установке](https://python-poetry.org/docs/#installing-with-the-official-installer). + +#### Установка зависимостей и настройка хуков Pre-commit + +Установите все зависимости и инструменты разработки в корневом каталоге репозитория: + +```bash +make install +``` + +Подсказка: + +- Если вы переключаете ветки или зависимости изменяются, возможно, вам потребуется **снова запустить `make install`**, чтобы поддерживать согласованность среды. +:: +```` +:: + + +### Accordion + +Используйте `accordion` и `accordion-item` для создания сворачиваемых областей содержимого. Подходит для организации FAQ, разворачиваемых деталей или сгруппированной информации. + +::code-preview +--- +class: "[&>div]:*:my-0" +--- + :::accordion + ::::accordion-item + --- + icon: i-lucide-circle-help + label: Совместим ли MemOS с большими языковыми моделями (LLM), доступными через API? + --- + Да. MemOS разработан с учетом совместимости с различными типами моделей. Однако имейте в виду, что если вы используете модель на основе API, активация памяти и параметров памяти будет недоступна. + :::: + + ::::accordion-item + --- + icon: i-lucide-circle-help + label: Как MemOS улучшает эффективность приложений на основе больших языковых моделей? + --- + MemOS улучшает эффективность приложений на основе больших языковых моделей, предоставляя структурированные, постоянные функции памяти, интеллектуальный механизм планирования, способность к долгосрочному сохранению знаний и KV cache для быстрого вывода. Он поддерживает детализированный контроль доступа и изоляцию пользователей, обеспечивая безопасность памяти в многопользовательской среде. Его модульная архитектура позволяет бесшовно интегрировать новые типы памяти, LLM и хранилища, что делает его подходящим для различных интеллектуальных приложений. + :::: + + ::::accordion-item{icon="i-lucide-circle-help" label="Какова цена MemOS?"} + Открытая версия MemOS бесплатна. + :::: +::: + + +#code +```mdc +::accordion + +:::accordion-item{label="Совместим ли MemOS с большими языковыми моделями (LLM), доступными через API?" icon="i-lucide-circle-help"} +Да. Целью дизайна MemOS является максимальная совместимость с различными типами моделей. Однако следует отметить, что если вы используете модель на основе API, активация памяти и параметрической памяти будет недоступна. +::: + +:::accordion-item{label="Как MemOS улучшает эффективность приложений на основе больших языковых моделей?" icon="i-lucide-circle-help"} +MemOS эффективно усиливает возможности применения больших языковых моделей, предоставляя структурированную, постоянную память, в сочетании с интеллектуальным планированием, механизмом долгосрочного хранения знаний и KV cache для быстрого вывода. Он поддерживает тонкую настройку контроля доступа и механизмы изоляции пользователей, обеспечивая безопасность памяти в многопользовательской среде. Его модульная архитектура поддерживает бесшовную интеграцию новых типов памяти, LLM и хранилищ, что позволяет адаптироваться к различным интеллектуальным сценариям применения. +::: + +:::accordion-item{label="Какова цена MemOS?" icon="i-lucide-circle-help"} +Открытая версия MemOS бесплатна. +::: + +:: +``` +:: + +### Badge + +Используйте badge для отображения индикаторов состояния или меток. Это очень полезно для выделения номера версии, состояния или информации о категории в содержимом. + +::code-preview +--- +label: Preview +--- + :::badge + **v1.0.0** + ::: + +#code +```mdc +::badge +**v1.0.0** +:: +``` +:: + + + +### Callout + +Используйте callout, чтобы подчеркнуть важную контекстную информацию. Callout используется для привлечения внимания пользователя, например, для заметок, подсказок, предупреждений или примечаний, чтобы выделить ключевую информацию. + +Вы можете настроить стиль с помощью свойств `icon` и `color`, или использовать предопределенные семантические стили `note`, `tip`, `warning`, `caution` для быстрого вызова. + +::code-preview +--- +class: "[&>div]:*:my-0 [&>div]:*:w-full" +--- + :::callout + Это `callout` окно, поддерживающее полный **markdown**. + ::: + +#code +```mdc +::callout +Это `callout` окно с поддержкой полного **markdown**. +:: +``` +:: + +::code-preview + :::div{.flex.flex-col.gap-4.w-full} + ::::note{.w-full.my-0} + Основное примечание + :::: + + ::::note{.w-full.my-0 to="/open_source/getting_started/quick_start"} + Примечание с ссылкой — нажмите, чтобы перейти к руководству по быстрому началу + :::: + + ::::note{.w-full.my-0 to="/open_source/modules/mem_cube" icon="ri:database-line"} + Примечание с пользовательским значком — узнайте больше о MemCube + :::: + + ::::tip{.w-full.my-0} + Вот полезный совет. + :::: + + ::::warning{.w-full.my-0} + Пожалуйста, действуйте осторожно, это действие может привести к неожиданным результатам. + :::: + + ::::caution{.w-full.my-0} + Это действие нельзя отменить. + :::: + ::: + +#code +```mdc +::note +Основное примечание +:: + +::note{to="/open_source/getting_started/quick_start"} +Примечание с ссылкой — нажмите, чтобы перейти к руководству по быстрому началу +:: + +::note{to="/open_source/modules/mem_cube" icon="ri:database-line"} +Примечание с пользовательским значком — узнайте больше о MemCube +:: + +::tip +Вот полезный совет. +:: + +::warning +Пожалуйста, будьте осторожны при выполнении этого действия, оно может привести к неожиданным результатам. +:: + +::caution +Это действие нельзя отменить. +:: +``` +:: + +### Card + +Используйте `card`, чтобы выделить содержимое модуля. Карты подходят для отображения функций, ресурсов или связанной информации, визуально различая и усиливая интерактивность. + +Вы можете настроить стиль с помощью атрибутов `title`, `icon` и `color`. Card также поддерживает использование атрибута `` для навигации. + +::code-preview +--- +class: "[&>div]:*:my-0 [&>div]:*:w-full" +--- + :::card + --- + icon: i-simple-icons-github + target: _blank + title: Открытый Проект + to: https://github.com/MemTensor/MemOS + --- + Используйте нашу открытую версию + ::: + +#code +```mdc +::card +--- +title: Открытый Проект +icon: i-simple-icons-github +to: https://github.com/MemTensor/MemOS +target: _blank +--- +Используйте нашу открытую версию +:: +``` +:: + +### CardGroup + +Используйте `card-group`, чтобы расположить несколько карт в виде сетки. Подходит для отображения структурированных, адаптивных макетов коллекции карт с хорошим визуальным эффектом. + +::code-preview + :::card-group{.w-full} + ::::card + --- + icon: ri:play-line + title: Минимальный Pipeline + to: /open_source/getting_started/examples#example-1-minimal-pipeline + --- + Минимально жизнеспособный Pipeline — добавление, поиск, обновление и экспорт открытых воспоминаний. + :::: + + ::::card + --- + icon: ri:tree-line + title: Только TreeTextMemory + to: /open_source/getting_started/examples#example-2-treetextmemory-only + --- + Используйте иерархическую память на основе Neo4j для построения структурированных, многослойных графов знаний. + :::: + + ::::card + --- + icon: ri:database-2-line + title: Только KVCacheMemory + to: /open_source/getting_started/examples#example-3-kvcachememory-only + --- + Ускорьте сессии с помощью краткосрочного KV cache для быстрого внедрения контекста. + :::: + + ::::card + --- + icon: hugeicons:share-07 + title: Смешанный TreeText + KVCache + to: /open_source/getting_started/examples#example-4-hybrid + --- + Объедините интерпретируемую графовую память и быстрый KV cache в одном MemCube. + :::: + ::: + +#code +```mdc +::card-group + +:::card +--- +icon: ri:play-line +title: Пример Минимального Pipeline +to: /open_source/getting_started/examples#example-1-minimal-pipeline +--- +Минимально работоспособный пример Pipeline — добавление, поиск, обновление и экспорт открытых воспоминаний. +::: + +:::card +--- +icon: ri:tree-line +title: Использование Только TreeTextMemory +to: /open_source/getting_started/examples#example-2-treetextmemory-only +--- +Используйте основанную на Neo4j иерархическую память для построения структурированных многослойных графов знаний. +::: + +:::card +--- +icon: ri:database-2-line +title: Используйте Только KVCacheMemory +to: /open_source/getting_started/examples#example-3-kvcachememory-only +--- +Ускорьте сессии с помощью краткосрочного KV cache для быстрого внедрения контекста. +::: + +:::card +--- +icon: hugeicons:share-07 +title: Смешанное Использование TreeText и KVCache +to: /open_source/getting_started/examples#example-4-hybrid +--- +Объедините интерпретируемую графовую память и высокоскоростной KV cache в одном MemCube. +::: + +:: +``` +:: + +## Навигационные Иконки + +При добавлении элементов навигации в `content/settings.yml` вы можете использовать синтаксис `(ri:имя_иконки)` для встраивания иконок: + +```yaml +- "(ri:home-line) Главная страница": overview.md +- "(ri:team-line) Управление пользователями": modules/mos/users.md +- "(ri:flask-line) Написание тестов": contribution/writing_tests.md +``` + +Доступные иконки можно найти по адресу: [https://icones.js.org/](https://icones.js.org/) + +## Локальный Предпросмотр + +Если вам нужен локальный предпросмотр документа, выполните следующую команду в корневом каталоге проекта. + +Сначала установите зависимости: + +```bash +pnpm install +``` + +Запустите сервер разработки: + +```bash +pnpm dev +``` + +Указанная команда запустит локальный веб-сервер, обычно доступ по адресу `http://127.0.0.1:3000`. + +## Углубленное Изучение + +### Nuxt Content и Система Верстки + +Этот проект использует Nuxt Content, поддерживающий богатые компоненты верстки и стили. Для получения дополнительной информации о использовании компонентов и параметрах настройки, пожалуйста, обратитесь к: + +* [Документация по типографике Nuxt UI](https://ui.nuxt.com/getting-started/typography) + +## Рекомендации по Написанию + +::note +**Рекомендации по написанию документации** + +1. **Четкая структура**: используйте соответствующие уровни заголовков для организации содержания +2. **Рациональное использование компонентов**: такие как note, card и другие компоненты для повышения читаемости и интерактивности +3. **Четкие примеры кода**: предоставьте четкие фрагменты кода для технической документации и используйте подсветку синтаксиса +4. **Использование иконок**: используйте подходящие иконки в навигации для улучшения пользовательского опыта и иерархии +:: + +::card{title="Быстрая Справка"} +Перед отправкой сначала протестируйте ваш документ локально. Запустите `pnpm dev`, чтобы просмотреть ваши изменения и убедиться, что все компоненты правильно отображаются. +:: + diff --git a/content/ru/open_source/contribution/writing_tests.md b/content/ru/open_source/contribution/writing_tests.md new file mode 100644 index 00000000..de772ffa --- /dev/null +++ b/content/ru/open_source/contribution/writing_tests.md @@ -0,0 +1,43 @@ +--- +title: Как Написать Юнит-Тесты +desc: Этот проект использует [pytest](https://docs.pytest.org/) для юнит-тестирования. +--- + +## Написание Тестов + +1. Создайте новый Python файл в директории `tests/`, имя файла должно начинаться с `test_`. +2. В этом файле определите функции, начинающиеся с `test_`. +3. Используйте оператор `assert` для проверки ожидаемых результатов. + +Вот базовый пример: + +```python +# tests/test_example.py + +def test_addition(): + assert 1 + 1 == 2 +``` + +## Запуск Тестов + +Чтобы запустить все тесты, выполните следующую команду в корневой директории проекта: + +```bash +make test +``` + +Эта команда автоматически обнаружит и запустит все тестовые случаи в директории `tests/`. + +## Продвинутые Приемы + +Pytest предлагает множество продвинутых функций, таких как fixtures и mocking. + +### Fixtures + +Fixtures — это функции, которые могут предоставлять данные или настраивать начальное состояние для тестов. Определяются с помощью декоратора `@pytest.fixture`. + +### Mocking + +Mocking используется для замены некоторых частей системы на mock-объекты. Это очень полезно для изоляции тестируемого кода. Обычно используется библиотека `unittest.mock`, часто в сочетании с функцией `patch`. + +Для примеров mocking смотрите `tests/test_hello_world.py`. diff --git a/content/ru/open_source/cookbook/chapter1/api.md b/content/ru/open_source/cookbook/chapter1/api.md new file mode 100644 index 00000000..3738d8ce --- /dev/null +++ b/content/ru/open_source/cookbook/chapter1/api.md @@ -0,0 +1,1135 @@ +--- +title: Linux API Версия +desc: MemCube является核心组件ом MemOS, он как "чип памяти" из Cyberpunk 2077, который позволяет агенту загружать различные "пакеты памяти" для получения различных знаний и способностей. В этой главе мы поможем вам освоить основные операции MemCube с помощью трех прогрессивных рецептов.
Обратите внимание, что система MemOS делится на два уровня: уровень ОС и уровень Cube, здесь мы сначала представляем более базовый уровень Cube. Многие операции ниже, такие как добавление и поиск, также доступны на уровне ОС, различие в том, что ОС управляет несколькими Cube и может выполнять общие поиски и операции по нескольким Cube, в то время как Cube отвечает только за собственную запись и запросы. +--- + +### Рецепт 1.1: Установка и настройка вашей среды разработки MemOS (API Версия) + +**🎯 Сценарий проблемы:** Вы разработчик AI приложений, хотите попробовать самый новый и популярный MemOS, но не знаете, как настроить среду MemOS. + +**🔧 Решение:** С помощью этого рецепта вы научитесь, как с нуля создать полную среду MemOS. + +#### Шаг 1: Проверьте системные требования + +```bash +# Проверка версии Python (требуется 3.10+) +python --version + +# 💡 Если версия ниже 3.10, пожалуйста, обновите Python +``` + +#### Шаг 2: Установите MemOS + +**Вариант A: Установка в производственной среде (рекомендуется)** + +```bash +# 🎯 Быстрая установка, подходит для производственного использования +pip install MemoryOS chonkie qdrant_client markitdown +``` + +**Вариант B: Установка в среде разработки (подходит для участников)** + +```bash +# 🎯 Клонирование исходного кода и установка среды разработки +git clone https://github.com/MemTensor/MemOS.git +cd MemOS + +# 🎯 Установка с помощью make (автоматически обработает зависимости и виртуальную среду) +make install + +# 🎯 Активировать виртуальную среду Poetry +poetry shell +# Или используйте: poetry run python your_script.py +``` + +#### Шаг 3: Настройка переменных окружения OpenAI API + +Создайте файл `.env`: + +```bash +# .env +# 🎯 Конфигурация OpenAI +OPENAI_API_KEY=your_openai_api_key_here +OPENAI_API_BASE=https://api.openai.com/v1 + +# 🎯 Специфическая конфигурация MemOS +MOS_TEXT_MEM_TYPE=general_text +MOS_USER_ID=default_user +MOS_TOP_K=5 +``` + +#### Шаг 4: Проверьте установку и полную среду + +Создайте файл проверки `test_memos_setup_api_mode.py`: + +```python +# test_memos_setup_api_mode.py +# 🎯 Скрипт проверки режима API - использование OpenAI API и MOS.simple() +import os +import sys +from dotenv import load_dotenv + +def check_openai_environment(): + """🎯 Проверка конфигурации переменных окружения OpenAI""" + print("🔍 Проверка конфигурации переменных окружения OpenAI...") + + # Загрузка файла .env + load_dotenv() + + # Проверка конфигурации OpenAI + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + print(f"📋 Статус переменных окружения OpenAI:") + + if openai_key: + masked_key = openai_key[:8] + "..." + openai_key[-4:] if len(openai_key) > 12 else "***" + print(f" ✅ OPENAI_API_KEY: {masked_key}") + print(f" ✅ OPENAI_API_BASE: {openai_base}") + return True + else: +print(f" ❌ OPENAI_API_KEY: не настроен") + print(f" ❌ OPENAI_API_BASE: {openai_base}") + return False + +def check_memos_installation(): +"""🎯 Проверка состояния установки MemOS""" +print("\n🔍 Проверка состояния установки MemOS...") + + try: + import memos +print(f"✅ Версия MemOS: {memos.__version__}") + +# Тестирование импорта основных компонентов + from memos.mem_cube.general import GeneralMemCube + from memos.mem_os.main import MOS + from memos.configs.mem_os import MOSConfig + +print("✅ Импорт основных компонентов прошел успешно") + return True + + except ImportError as e: +print(f"❌ Ошибка импорта: {e}") + return False + except Exception as e: +print(f"❌ Другие ошибки: {e}") + return False + +def test_api_functionality(): +"""🎯 Тестирование функциональности режима API""" +print("\n🔍 Тестирование функциональности режима API...") + + try: + from memos.mem_os.main import MOS + +# Используйте метод MOS.simple() по умолчанию +print("🚀 Создание экземпляра MOS (используя MOS.simple())...") + memory = MOS.simple() + +print("✅ MOS.simple() успешно создано!") +print(f" 📊 用户ID: {memory.user_id}") +print(f" 📊 Идентификатор сессии: {memory.session_id}") + + # Тестирование Добавления Памяти + print("\n🧠 Тестирование Добавления Памяти...") + memory.add(memory_content="Это Тестовая Память В Режиме API") + print("✅ Память Успешно Добавлена!") + + # Тестирование Чат-Функции + print("\n💬 Тестирование Чат-Функции...") + response = memory.chat("Что я только что добавил в память?") + print(f"✅ Ответ Чата: {response}") + + # Тестирование Поисковой Функции + print("\n🔍 Тестирование Поисковой Функции...") + search_results = memory.search("Тестовая Память", top_k=3) + if search_results and search_results.get("text_mem"): + print(f"✅ Поиск Успешен, Найдено {len(search_results['text_mem'])} Результатов") + else: + print("⚠️ Поиск Не Вернул Результатов") + + print("✅ Тестирование Функции Режима API Успешно!") + return True + + except Exception as e: + print(f"❌ Тестирование Функции Режима API Провалено: {e}") +print("💡 Подсказка: проверьте ключ API OpenAI и сетевое соединение.") + return False + +def main(): +"""🎯 Основной процесс верификации режима API""" +print("🚀 Начало проверки среды API MemOS...\n") + +# Шаг 1: Проверьте переменные окружения OpenAI + env_ok = check_openai_environment() + +# Шаг 2: Проверьте состояние установки + install_ok = check_memos_installation() + +# Шаг 3: Тестирование функции + if env_ok and install_ok: + func_ok = test_api_functionality() + else: + func_ok = False + if not env_ok: +print("\n⚠️ 由于 конфигурация переменных окружения OpenAI неполная, пропускаем тестирование функций") + elif not install_ok: +print("\n⚠️ Из-за неудачной установки MemOS пропускается функциональное тестирование") + +# Резюме + print("\n" + "="*50) +print("📊 Результаты проверки режима API:") +print(f" OpenAI переменные окружения: {'✅ 通过' if env_ok else '❌ 失败'}") +print(f" Установка MemOS: {'✅ Успешно' if install_ok else '❌ Не удалось'}") +print(f" Функциональное тестирование: {'✅ Пройдено' if func_ok else '❌ Провалено'}") + + if env_ok and install_ok and func_ok: +print(f"\n🎉 Поздравляем! MemOS API模式环境配置完全成功!") +print(f"💡 Теперь вы можете начать использовать режим API MemOS.") + elif install_ok and env_ok: + print(f"\n⚠️ MemOS установлен, OpenAI настроен, но тестирование функций не удалось.") + print(f"💡 Пожалуйста, проверьте, действителен ли ключ API OpenAI и нормально ли работает сетевое соединение.") + elif install_ok: + print("\n⚠️ MemOS установлен, но необходимо настроить переменные окружения OpenAI для нормальной работы.") + print("💡 Пожалуйста, настройте OPENAI_API_KEY в файле .env.") + else: + print("\n❌ Проблемы с конфигурацией окружения, пожалуйста, проверьте вышеуказанную информацию об ошибках.") + + return bool(env_ok and install_ok and func_ok) + +if __name__ == "__main__": + success = main() + sys.exit(0 if success else 1) +``` + +Запустите проверку режима API: + +```bash +python test_memos_setup_api_mode.py +``` + +#### Часто задаваемые вопросы и решения + +**Q1: Что делать, если установка на macOS не удалась?** + +```bash +# 🔧 macOS может потребовать дополнительной настройки +export SYSTEM_VERSION_COMPAT=1 +pip install MemoryOS +``` + +**Q2: Как решить конфликты зависимостей?** + +```bash +# 🔧 Используйте виртуальное окружение для изоляции +python -m venv memos_env +source memos_env/bin/activate # Linux/macOS +# или memos_env\Scripts\activate # Windows +pip install MemoryOS +``` + +### Рецепт 1.2: Построение простого MemCube из документа (API Версия) + +**🎯 Сценарий проблемы:** У вас есть PDF-документ, содержащий корпоративную базу знаний, и вы хотите создать "чип памяти", который может отвечать на соответствующие вопросы. + +**🔧 Решение:** С помощью этого рецепта вы научитесь, как использовать MemReader для преобразования документа в MemCube, который можно искать. MemReader является核心组件ом MemOS, который может интеллектуально анализировать документы и извлекать структурированную память. + +#### Шаг 1: Подготовьте пример документа + +Создайте пример документа знаний `company_handbook.txt`: + +```text +# Руководство для сотрудников компании + +## Рабочее Время +Стандартное рабочее время компании с понедельника по пятницу, с 9:00 до 18:00. +Гибкий график позволяет сотрудникам начинать работу с 8:00 до 10:00. + +## Политика Отпуска +- Годовой отпуск: 15 дней оплачиваемого годового отпуска +- Больничный: 7 дней оплачиваемого больничного в год +- Личный Отпуск: 3 Дня Личного Отпуска В Год + +## Льготы И Преимущества +Компания Предоставляет Полный Пакет Социальных Гарантий, Включая: +- Пенсионное Страхование +- Медицинское Страхование +- Страхование От Безработицы +- Страхование От Производственных Несчастий +- Страхование По Беременности +- Жилищный Сбережительный Фонд + +Дополнительные Преимущества Включают Годовой Медицинский Осмотр, Командные Мероприятия И Обучающие Дотации. + +## Офисное Оборудование +Каждый Сотрудник Получит: +- Один Ноутбук +- Один Монитор +- Эргономичное Кресло +- Офисный Стол + +## Контактная Информация +HR Отдел: hr@company.com +IT Поддержка: it@company.com +Финансовый Отдел: finance@company.com +``` + +#### Шаг 2: Используйте MemReader для создания MemCube + +```python +# create_memcube_with_memreader_api.py +# 🎯 Полный Процесс Создания MemCube С Использованием MemReader (Версия API) +import os +import uuid +from dotenv import load_dotenv +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.mem_cube.general import GeneralMemCube +from memos.configs.mem_reader import MemReaderConfigFactory +from memos.mem_reader.factory import MemReaderFactory + +def create_memcube_with_memreader(): + """ + 🎯 Полный Процесс Создания MemCube С Использованием MemReader (Версия API) + """ + + print("🔧 Создание Конфигурации MemCube...") + + # Загрузка Переменных Среды + load_dotenv() + + # Получение Конфигурации OpenAI + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + if not openai_key: + raise ValueError("❌ OPENAI_API_KEY Не Настроен. Пожалуйста, Настройте Ключ API OpenAI В Файле .env.") + + print("✅ Обнаружен Режим API OpenAI") + + # Получение Конфигурации MemOS + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + + # Конфигурация Режима OpenAI + cube_config = { + "user_id": user_id, + "cube_id": f"{user_id}_company_handbook_cube", + "text_mem": { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o-mini", + "temperature": 0.8, + "max_tokens": 8192, + "top_p": 0.9, + "top_k": 50, + "api_key": openai_key, + "api_base": openai_base + } + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": openai_base + } + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{user_id}_company_handbook", + "vector_dimension": 1536, + "distance_metric": "cosine" + } + } + } + }, + "act_mem": {"backend": "uninitialized"}, + "para_mem": {"backend": "uninitialized"} + } + + # Создание Экземпляра MemCube + config_obj = GeneralMemCubeConfig.model_validate(cube_config) + mem_cube = GeneralMemCube(config_obj) + + print("✅ MemCube создан успешно!") + print(f" 📊 Пользовательский ID: {mem_cube.config.user_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + print(f" 📊 Текстовый память бэкенд: {mem_cube.config.text_mem.backend}") + print(f" 🔍 Модель встраивания: text-embedding-ada-002 (OpenAI)") + print(f" 🎯 Конфигурационный режим: OPENAI API") + + return mem_cube + +def create_memreader_config(): + """ + 🎯 Создание конфигурации MemReader + """ + + # Загрузка Переменных Среды + load_dotenv() + + # Получение Конфигурации OpenAI + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + # Конфигурация MemReader + mem_reader_config = MemReaderConfigFactory( + backend="simple_struct", + config={ + "llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o-mini", + "temperature": 0.8, + "max_tokens": 8192, + "top_p": 0.9, + "top_k": 50, + "api_key": openai_key, + "api_base": openai_base + } + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": openai_base + } + }, + "chunker": { + "backend": "sentence", + "config": { + "chunk_size": 64, + "chunk_overlap": 20, + "min_sentences_per_chunk": 1 + } + }, + "remove_prompt_example": False + } + ) + + return mem_reader_config + +def load_document_to_memcube(mem_cube, doc_path): + """ + 🎯 Использование MemReader для загрузки документов в MemCube + """ + + print(f"\n📖 Использование MemReader для чтения документа: {doc_path}") + + # Создание MemReader + mem_reader_config = create_memreader_config() + mem_reader = MemReaderFactory.from_config(mem_reader_config) + + # Подготовка данных документа + print("📄 Подготовка данных документа...") + documents = [doc_path] # MemReader ожидает список путей к документам + + # Использование MemReader для обработки документов + print("🧠 Использование MemReader для извлечения памяти...") + memories = mem_reader.get_memory( + documents, + type="doc", + info={ + "user_id": mem_cube.config.user_id, + "session_id": str(uuid.uuid4()) + } + ) + + print(f"📚 MemReader сгенерировал {len(memories)} фрагментов памяти") + + # Добавить память в MemCube + print("💾 Добавление памяти в MemCube...") + for mem in memories: + mem_cube.text_mem.add(mem) + + print(f"✅ Успешно добавлено {len(memories)} фрагментов памяти в MemCube") + + # Вывод основных данных + print("\n📊 Основная информация о MemCube:") + print(f" 📁 Источник документа: {doc_path}") + print(f" 📝 Количество фрагментов памяти: {len(memories)}") + print(f" 🏷️ Тип документа: company_handbook") + print(f" 💾 Векторная база данных: Qdrant (режим памяти, освобождение памяти приводит к удалению)") + print(f" 🔍 Модель встраивания: text-embedding-ada-002 (OpenAI)") + print(f" 🎯 Конфигурационный режим: OPENAI API") + print(f" 🧠 Извлекатель памяти: MemReader (simple_struct)") + + return mem_cube + +if __name__ == "__main__": + print("🚀 Начинаем использовать MemReader для создания документа MemCube (API версия)...") + + # Создать MemCube + mem_cube = create_memcube_with_memreader() + + # Загрузить документ + import os + current_dir = os.path.dirname(os.path.abspath(__file__)) + doc_path = os.path.join(current_dir, "company_handbook.txt") + load_document_to_memcube(mem_cube, doc_path) + + print("\n🎉 MemCube создан успешно!") +``` + +#### Запустите пример + +```bash +# Шаг 2: Создание MemCube +python create_memcube_with_memreader_api.py +``` + +#### Шаг 3: Проверьте функции поиска и диалога + +> В текущей версии MemOS, при отключенном Scheduler, запуск chat может вызвать некоторые проблемы, необходимо вручную закомментировать один фрагмент кода, следуя приведенным ниже шагам, чтобы все последующие примеры кода работали нормально. В следующих версиях мы исправим эту проблему. +> ctrl+левый клик на функции chat() ниже, затем нажмите super.chat() для перехода в core.py, или в каталоге установки среды найдите lib/python3.12/site-packages/memos/mem_os/core.py и выполните поиск по def chat, чтобы найти соответствующую функцию +> Закомментируйте блок кода выше return в конце функции: + +``` +# submit message to scheduler +# for accessible_mem_cube in accessible_cubes: +# mem_cube_id = accessible_mem_cube.cube_id +# mem_cube = self.mem_cubes[mem_cube_id] +# if self.enable_mem_scheduler and self.mem_scheduler is not None: +# message_item = ScheduleMessageItem( +# user_id=target_user_id, +# mem_cube_id=mem_cube_id, +# mem_cube=mem_cube, +# label=ANSWER_LABEL, +# content=response, +# timestamp=datetime.now(), +# ) +# self.mem_scheduler.submit_messages(messages=[message_item]) +``` + + +```python +# test_memcube_search_and_chat_api.py +# 🎯 Тестирование функций поиска и диалога MemCube (API-версия) +import os +from dotenv import load_dotenv +from memos.configs.mem_os import MOSConfig +from memos.mem_os.main import MOS + +def create_mos_config(): + """ +🎯 Создание конфигурации MOS (версия API) + """ + load_dotenv() + + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + if not openai_key: + raise ValueError("❌ OPENAI_API_KEY Не Настроен. Пожалуйста, Настройте Ключ API OpenAI В Файле .env.") + + # Конфигурация Режима OpenAI + return MOSConfig( + user_id=user_id, + chat_model={ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-3.5-turbo", + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.1, + "max_tokens": 1024, + } + }, + mem_reader={ + "backend": "simple_struct", + "config": { + "llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-3.5-turbo", + "api_key": openai_key, + "api_base": openai_base, + } + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": openai_base, + } + }, + "chunker": { + "backend": "sentence", + "config": { + "tokenizer_or_token_counter": "gpt2", + "chunk_size": 512, + "chunk_overlap": 128, + "min_sentences_per_chunk": 1, + } + } + } + }, + enable_textual_memory=True, + top_k=top_k + ) + +def test_memcube_search_and_chat(): + """ +🎯 Тестирование функций поиска и диалога MemCube (версия API) + """ + +print("🚀 Начинаем тестирование функций поиска и диалога MemCube (API версия)...") + +# Импортируйте функции шага 2 + from create_memcube_with_memreader_api import create_memcube_with_memreader, load_document_to_memcube + +# Создание MemCube и загрузка документов +print("\n1️⃣ Создание MemCube и загрузка документов...") + mem_cube = create_memcube_with_memreader() + # Загрузить документ + import os + current_dir = os.path.dirname(os.path.abspath(__file__)) + doc_path = os.path.join(current_dir, "company_handbook.txt") + load_document_to_memcube(mem_cube, doc_path) + +# Создание конфигурации MOS +print("\n2️⃣ Создание конфигурации MOS...") + mos_config = create_mos_config() + +# Создание экземпляра MOS и регистрация MemCube +print("3️⃣ Создание экземпляра MOS и регистрация MemCube...") + mos = MOS(mos_config) + mos.register_mem_cube(mem_cube, mem_cube_id="handbook") + +print("✅ Создание экземпляра MOS прошло успешно!") +print(f" 📊 用户ID: {mos.user_id}") +print(f" 📊 Идентификатор сессии: {mos.session_id}") + print(f" 📊 Зарегистрированные MemCube: {list(mos.mem_cubes.keys())}") + print(f" 🎯 Конфигурационный режим: OPENAI API") + print(f" 🤖 Модель Чата: gpt-3.5-turbo (OpenAI)") + print(f" 🔍 Модель встраивания: text-embedding-ada-002 (OpenAI)") + + # Тестирование Функции Поиска + print("\n🔍 Тестирование Функции Поиска...") + test_queries = [ + "Какое рабочее время компании?", + "Сколько дней ежегодного отпуска?", + "Какие льготы и компенсации?", + "Как связаться с HR-отделом?" + ] + + for query in test_queries: + print(f"\n❓ Запрос: {query}") + + # Использование MOS для Поиска + search_results = mos.search(query, top_k=2) + + if search_results and search_results.get("text_mem"): + print(f"📋 Найдено {len(search_results['text_mem'])} связанных результатов:") + for cube_result in search_results['text_mem']: + cube_id = cube_result['cube_id'] + memories = cube_result['memories'] + print(f" 📦 MemCube: {cube_id}") + for i, memory in enumerate(memories[:2], 1): # Показывать только первые 2 результата + print(f" {i}. {memory.memory[:100]}...") + else: + print("😓 Не найдено связанных результатов") + + # Тестирование Функции Диалога + print("\n💬 Тестирование Функции Диалога...") + chat_questions = [ + "Каково расписание работы компании?" + "Какие льготы могут получать сотрудники?" + "Как связаться с IT-поддержкой?" + ] + + for question in chat_questions: + print(f"\n👤 Вопрос: {question}") + + try: + response = mos.chat(question) + print(f"🤖 Ответ: {response}") + except Exception as e: + print(f"❌ Ошибка диалога: {e}") + + print("\n🎉 Тест завершен!") + return mos + +if __name__ == "__main__": + test_memcube_search_and_chat() +``` + +#### Запустите пример + +```bash +# Шаг 3: Тестирование поиска и диалога +python test_memcube_search_and_chat_api.py +``` + +### Рецепт 1.3: Основные операции MemCube: создание, добавление памяти, сохранение, чтение, запрос, удаление (API Версия) + +**🎯 Сценарий проблемы:** Вы уже создали несколько MemCube: корпоративные правила, кадровые вопросы, корпоративная база знаний..., вам нужно научиться эффективно управлять полным жизненным циклом: создание, добавление памяти, сохранение на диск, загрузка с диска, запрос в памяти (базовый запрос и продвинутый запрос метаданных), а также очистка ненужных MemCube (удаление из памяти и удаление файлов). + +**🔧 Решение:** Освойте управление полным жизненным циклом MemCube, включая интеллектуальную настройку, базовые запросы, продвинутые операции с метаданными и детализированное управление памятью и файлами. + +#### Шаг 1: Управление полным жизненным циклом MemCube + +```python + # memcube_lifecycle_api.py +# 🎯 MemCube Управление Жизненным Циклом: Создание, Увеличение Памяти, Сохранение, Чтение, Запрос, Удаление (API версия) +import os +import shutil +import time +from pathlib import Path +from dotenv import load_dotenv +from memos.mem_cube.general import GeneralMemCube +from memos.configs.mem_cube import GeneralMemCubeConfig + +class MemCubeManager: + """ + 🎯 Менеджер Жизненного Цикла MemCube (API версия) + """ + + def __init__(self, storage_root="./memcube_storage"): + self.storage_root = Path(storage_root) + self.storage_root.mkdir(exist_ok=True) + self.loaded_cubes = {} # Кэш MemCube в памяти + + def create_empty_memcube(self, cube_id: str) -> GeneralMemCube: + """ + 🎯 Создать пустой MemCube (без примеров данных) + """ + + # Загрузить переменные окружения + load_dotenv() + + # Получить конфигурацию OpenAI + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + if not openai_key: + raise ValueError("❌ OPENAI_API_KEY не настроен. Пожалуйста, настройте ключ API OpenAI в файле .env.") + + # Получить Конфигурацию MemOS + user_id = os.getenv("MOS_USER_ID", "demo_user") + + # Конфигурация Режима OpenAI + cube_config = { + "user_id": user_id, + "cube_id": cube_id, + "text_mem": { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o-mini", + "temperature": 0.8, + "max_tokens": 8192, + "top_p": 0.9, + "top_k": 50, + "api_key": openai_key, + "api_base": openai_base + } + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": openai_base + } + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"collection_{cube_id}_{int(time.time())}", + "vector_dimension": 1536, + "distance_metric": "cosine" + } + } + } + }, + "act_mem": {"backend": "uninitialized"}, + "para_mem": {"backend": "uninitialized"} + } + + config_obj = GeneralMemCubeConfig.model_validate(cube_config) + mem_cube = GeneralMemCube(config_obj) + + print(f"✅ Создать Пустой MemCube: {cube_id}") + return mem_cube + + def save_memcube(self, mem_cube: GeneralMemCube, cube_id: str) -> str: + """ + 🎯 Сохранить MemCube На Диск + """ + + save_path = self.storage_root / cube_id + + print(f"💾 Сохранить MemCube В: {save_path}") + + try: + # ⚠️ Если Директория Существует, Сначала Очистить + if save_path.exists(): + shutil.rmtree(save_path) + + # Сохранить MemCube + mem_cube.dump(str(save_path)) + + print(f"✅ MemCube '{cube_id}' Успешно Сохранен") + return str(save_path) + + except Exception as e: + print(f"❌ Ошибка Сохранения: {e}") + raise + + def load_memcube(self, cube_id: str) -> GeneralMemCube: + """ + 🎯 Загрузить MemCube С Диска + """ + + load_path = self.storage_root / cube_id + + if not load_path.exists(): + raise FileNotFoundError(f"MemCube '{cube_id}' Не Существует В {load_path}") + + print(f"📂 Загрузить MemCube С Диска: {load_path}") + + try: + # Загрузить MemCube Из Директории + mem_cube = GeneralMemCube.init_from_dir(str(load_path)) + + # Кэшировать В Памяти + self.loaded_cubes[cube_id] = mem_cube + + print(f"✅ MemCube '{cube_id}' Успешно Загружен") + return mem_cube + + except Exception as e: + print(f"❌ Ошибка загрузки: {e}") + raise + + def list_saved_memcubes(self) -> list: + """ + 🎯 Перечислить все сохраненные MemCube + """ + + saved_cubes = [] + + for item in self.storage_root.iterdir(): + if item.is_dir(): + # Проверить, является ли это действительным каталогом MemCube + readme_path = item / "README.md" + if readme_path.exists(): + saved_cubes.append({ + "cube_id": item.name, + "path": str(item), + "size": self._get_dir_size(item) + }) + + return saved_cubes + + def unload_memcube(self, cube_id: str) -> bool: + """ + 🎯 Удалить MemCube из памяти (не удаляя файл) + """ + + if cube_id in self.loaded_cubes: + del self.loaded_cubes[cube_id] + print(f"♻️ MemCube '{cube_id}' был удален из памяти") + return True + else: + print(f"⚠️ MemCube '{cube_id}' не в памяти") + return False + + def delete_memcube(self, cube_id: str) -> bool: + """ + 🎯 Удалить локальные файлы MemCube + """ + + delete_path = self.storage_root / cube_id + + if not delete_path.exists(): + print(f"⚠️ MemCube '{cube_id}' не существует в {delete_path}") + return False + + print(f"🗑️ Удаление файла MemCube: {delete_path}") + + try: + # Удалить каталог + shutil.rmtree(delete_path) + + # Удалить из кэша памяти (если все еще в памяти) + if cube_id in self.loaded_cubes: + del self.loaded_cubes[cube_id] + + print(f"✅ Файл MemCube '{cube_id}' успешно удален") + return True + + except Exception as e: + print(f"❌ Ошибка удаления: {e}") + return False + + def _get_dir_size(self, path: Path) -> str: + """Вычислить размер каталога""" + total_size = sum(f.stat().st_size for f in path.rglob('*') if f.is_file()) + return f"{total_size / 1024:.1f} KB" + +def add_memories_to_cube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 Добавить память к MemCube + """ + + print(f"🧠 Добавление памяти к {cube_name}...") + + # Добавить несколько примеров памяти (с богатыми метаданными) + memories = [ + {"memory": f"Ажэнь влюбилась в Ацян", "metadata": {"type": "fact", "source": "conversation", "confidence": 0.9}}, + {"memory": f"Ажэнь ростом 1 метр 5 сантиметров", "metadata": {"type": "fact", "source": "file", "confidence": 0.8}}, + {"memory": f"Ажэнь - ассасин", "metadata": {"type": "fact", "source": "web", "confidence": 0.7}}, + {"memory": f"Ацян - программист", "metadata": {"type": "fact", "source": "conversation", "confidence": 0.9}}, + {"memory": f"Ацян любит писать код", "metadata": {"type": "fact", "source": "file", "confidence": 0.8}} + ] + + mem_cube.text_mem.add(memories) + + print(f"✅ Успешно добавлено {len(memories)} записей памяти в {cube_name}") + + # Показать текущее количество памяти + all_memories = mem_cube.text_mem.get_all() + print(f"📊 Текущее общее количество памяти в {cube_name}: {len(all_memories)}") + +def basic_query_memcube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 Базовый запрос MemCube + """ + + print(f"🔍 Базовый запрос к {cube_name}:") + + # Получить все записи памяти + all_memories = mem_cube.text_mem.get_all() + print(f" 📊 Общее количество памяти: {len(all_memories)}") + + # Поиск конкретного содержимого + search_results = mem_cube.text_mem.search("爱情", top_k=1) + print(f" 🎯 Результаты поиска '爱情': {len(search_results)}条") + + for i, result in enumerate(search_results, 1): + print(f" {i}. {result.memory}") + +def advanced_query_memcube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 Расширенный Запрос MemCube (Операции с Метаданными) + """ + + print(f"🔬 Расширенный Запрос {cube_name}:") + + # Получить все записи памяти + all_memories = mem_cube.text_mem.get_all() + + # 1. Показать Полную Структуру TextualMemoryItem + print(" 📋 Полная Структура Первой Памяти:") + first_memory = all_memories[0] + print(f" {first_memory}") + print(f" ID: {first_memory.id}") + print(f" Содержимое: {first_memory.memory}") + print(f" Метаданные: {first_memory.metadata}") + print(f" Тип: {first_memory.metadata.type}") + print(f" Источник: {first_memory.metadata.source}") + print(f" Уверенность: {first_memory.metadata.confidence}") + print() + + # 2. Фильтрация Метаданных + print(" 🔍 Фильтрация Метаданных:") + + # Фильтрация Памяти с Высокой Уверенностью + high_confidence = [m for m in all_memories if m.metadata.confidence and m.metadata.confidence >= 0.9] + print(f" Память с Высокой Уверенностью (>=0.9): {len(high_confidence)}条") + for i, memory in enumerate(high_confidence, 1): + print(f" {i}. {memory.memory} (Достоверность: {memory.metadata.confidence})") + + # Фильтрация памяти из определенных источников + conversation_memories = [m for m in all_memories if m.metadata.source == "conversation"] + print(f" Память из диалога: {len(conversation_memories)} записей") + for i, memory in enumerate(conversation_memories, 1): + print(f" {i}. {memory.memory} (Источник: {memory.metadata.source})") + + # Фильтрация памяти из файловых источников + file_memories = [m for m in all_memories if m.metadata.source == "file"] + print(f" Память из файлов: {len(file_memories)} записей") + for i, memory in enumerate(file_memories, 1): + print(f" {i}. {memory.memory} (Источник: {memory.metadata.source})") + + # 3. Комбинированная фильтрация + print(" 🔍 Комбинированная фильтрация:") + high_conf_file = [m for m in all_memories + if m.metadata.source == "file" and m.metadata.confidence and m.metadata.confidence >= 0.8] + print(f" Память из файлов с высокой достоверностью: {len(high_conf_file)} записей") + for i, memory in enumerate(high_conf_file, 1): + print(f" {i}. {memory.memory} (Источник: {memory.metadata.source}, Достоверность: {memory.metadata.confidence})") + + # 4. Статистическая информация + print(" 📊 Статистическая информация:") + sources = {} + confidences = [] + + for memory in all_memories: + # Статистика источников + source = memory.metadata.source + sources[source] = sources.get(source, 0) + 1 + + # Сбор достоверности + if memory.metadata.confidence: + confidences.append(memory.metadata.confidence) + + print(f" Распределение источников: {sources}") + if confidences: + avg_confidence = sum(confidences) / len(confidences) + print(f" Средняя Уверенность: {avg_confidence:.2f}") + +# 🎯 Демонстрация Полного Управления Жизненным Циклом +def demonstrate_lifecycle(): + """ + Демонстрация MemCube Полного Жизненного Цикла (API-версия) + """ + + manager = MemCubeManager() + + print("🚀 Начало Демонстрации Жизненного Цикла MemCube (API-версия)...\n") + + # Шаг 1: Создание MemCube + print("1️⃣ Создание MemCube") + cube1 = manager.create_empty_memcube("demo_cube_1") + + # Шаг 2: Добавление Памяти + print("\n2️⃣ Добавление Памяти") + add_memories_to_cube(cube1, "demo_cube_1") + + # Шаг 3: Сохранение на Диск + print("\n3️⃣ Сохранение MemCube на Диск") + manager.save_memcube(cube1, "demo_cube_1") + + # Шаг 4: Перечисление Сохраненных MemCube + print("\n4️⃣ Перечисление Сохраненных MemCube") + saved_cubes = manager.list_saved_memcubes() + for cube_info in saved_cubes: + print(f" 📦 {cube_info['cube_id']} - {cube_info['size']}") + + # Шаг 5: Чтение с Диска + print("\n5️⃣ Чтение MemCube с Диска") + del cube1 # 💡 Удаление Ссылки в Памяти + + reloaded_cube = manager.load_memcube("demo_cube_1") + + # Шаг 6: Базовый Запрос + print("\n6️⃣ Базовый Запрос") + basic_query_memcube(reloaded_cube, "перезагруженный_demo_cube_1") + + # Шаг 7: Продвинутый Запрос (Операции с Метаданными) + print("\n7️⃣ Продвинутый Запрос (Операции с Метаданными)") + advanced_query_memcube(reloaded_cube, "перезагруженный_demo_cube_1") + + # Шаг 8: Удаление MemCube из Памяти + print("\n8️⃣ Удаление MemCube из Памяти") + manager.unload_memcube("demo_cube_1") + + # Шаг 9: Удаление Локальных Файлов + print("\n9️⃣ Удаление Локальных Файлов") + manager.delete_memcube("demo_cube_1") + +if __name__ == "__main__": + """ + 🎯 Главная Функция - Запуск Демонстрации Жизненного Цикла MemCube (Версия API) + """ + try: + demonstrate_lifecycle() + print("\n🎉 Демонстрация Жизненного Цикла MemCube Завершена!") + except Exception as e: + print(f"\n❌ Произошла Ошибка Во Время Демонстрации: {e}") + import traceback + traceback.print_exc() +``` + +#### Запустите пример + +```bash +# Запуск Демонстрации Жизненного Цикла MemCube +python memcube_lifecycle_api.py +``` + +#### Часто задаваемые вопросы и лучшие практики + +**🔧 Лучшие практики:** + +1. **Управление Памятью** + + ```python + # ✅ Хорошая Практика: Ограничить Количество Одновременно Загружаемых MemCube + memory_manager = MemCubeMemoryManager() + memory_manager.max_active_cubes = 3 + + # ❌ Избегайте: Безлимитной Загрузки MemCube + # Это Может Привести К Переполнению Памяти + ``` + +2. **Стратегия Персистентности** + + ```python + # ✅ Регулярно Сохраняйте Важные Данные + if important_changes: + cube_manager.save_memcube(mem_cube, "important_data") + + # ✅ Используйте Версионированное Именование + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + cube_manager.save_memcube(mem_cube, f"data_backup_{timestamp}") + ``` + +3. **Оптимизация Запросов** + + ```python + # ✅ Разумно Установите top_k + results = mem_cube.text_mem.search(query, top_k=5) # Обычно 5-10 Достаточно + + # ✅ Используйте Метаданные Для Фильтрации И Сужения Поискового Диапазона + filtered_memories = advanced_ops.filter_by_metadata({"category": "important"}) + ``` + +**🐛 Часто задаваемые вопросы:** + +**Q1: Не удалось сохранить MemCube?** + +```python +# 🔧 Убедитесь, Что Достаточно Места На Диске И Права На Запись +import shutil +free_space = shutil.disk_usage(".").free / (1024**3) +print(f"Доступное Пространство: {free_space:.1f} GB") +``` + +**Q2: Результаты запроса неточные?** + +```python +# 🔧 Проверьте, Правильно Ли Настроена Модель Встраивания +print(f"Модель Встраивания: {mem_cube.text_mem.config.embedder}") + +# 🔧 Попробуйте Разные Поисковые Запросы +synonyms = ["重要", "ключевой", "основной", "главный"] +for synonym in synonyms: + results = mem_cube.text_mem.search(synonym) +``` + +**Q3: Использование памяти слишком высоко?** + +```python +# 🔧 Мониторинг И Оптимизация Использования Памяти +memory_manager.memory_health_check() +memory_manager.unload_cube("unused_cube_id") +gc.collect() +``` diff --git a/content/ru/open_source/cookbook/chapter1/ollama.md b/content/ru/open_source/cookbook/chapter1/ollama.md new file mode 100644 index 00000000..7ef789a1 --- /dev/null +++ b/content/ru/open_source/cookbook/chapter1/ollama.md @@ -0,0 +1,1275 @@ +--- +title: Linux Ollama版 +desc: MemCube является核心组件ом MemOS, он похож на "чип памяти" из Cyberpunk 2077, который позволяет агенту загружать различные "пакеты памяти" для получения различных знаний и возможностей. В этой главе мы с помощью трех прогрессивных рецептов поможем вам освоить основные операции MemCube.
Обратите внимание, что система MemOS делится на два уровня: уровень ОС и уровень Cube, здесь мы сначала представляем более базовый уровень Cube. Многие из следующих операций, такие как операции add и search, также присутствуют на уровне ОС, их отличие заключается в том, что ОС управляет несколькими Cube и может выполнять общие поисковые и операционные действия по нескольким Cube, в то время как Cube отвечает только за собственную запись и запрос. + +## Первая Глава: Введение: Ваш Первый MemCube (Linux Ollama版) + +MemCube является核心组件ом MemOS, он похож на "чип памяти" из Cyberpunk 2077, который позволяет агенту загружать различные "пакеты памяти" для получения различных знаний и возможностей. В этой главе мы с помощью трех прогрессивных рецептов поможем вам освоить основные операции MemCube. + +Обратите внимание, что система MemOS делится на два уровня: уровень ОС и уровень Cube, здесь мы сначала представляем более базовый уровень Cube. Многие из следующих операций, такие как операции add и search, также присутствуют на уровне ОС, их отличие заключается в том, что ОС управляет несколькими Cube и может выполнять общие поисковые и операционные действия по нескольким Cube, в то время как Cube отвечает только за собственную запись и запрос. + +### Рецепт 1.1: Установка и Настройка Вашей Разработческой Среды MemOS (Ollama版) + +**🎯 Сценарий Проблемы:** Вы разработчик AI-приложений, хотите попробовать самый новый и популярный MemOS, но не знаете, как настроить среду MemOS. + +**🔧 Решение:** С помощью этого рецепта вы научитесь, как с нуля создать полную среду MemOS. + +#### Шаг 1: Проверьте Системные Требования + +```bash +# Проверка Версии Python (Требуется 3.10+) +python --version + +# 💡 Если Версия Ниже 3.10, Пожалуйста, Сначала Обновите Python +``` + +#### Шаг 2: Установите MemOS + +**Вариант A: Установка в Производственной Среде (Рекомендуется)** + +```bash +# 🎯 Быстрая Установка, Подходит Для Производственного Использования +pip install MemoryOS chonkie qdrant_client markitdown +``` + +**Вариант B: Установка в Разработческой Среде (Подходит для Участников)** + +```bash +# 🎯 Клонирование Исходного Кода И Установка Развивающей Среды +git clone https://github.com/MemTensor/MemOS.git +cd MemOS + +# 🎯 Используйте make Для Установки (Автоматически Обработает Зависимости И Виртуальную Среду) +make install + +# 🎯 Активируйте Виртуальную Среду Poetry +poetry shell +# Или Используйте: poetry run python your_script.py +``` + +#### Шаг 3: Настройка Переменных Среды Модели Ollama + +Если вы еще не установили Ollama, сначала установите его: + +```bash +# 🎯 Установка Локального Модельного Сервиса Ollama +curl -fsSL https://ollama.com/install.sh | sh + +# Запуск Сервиса Ollama (Порт По Умолчанию) +ollama serve +# Запуск Сервиса Ollama (Указанный Порт) +# OLLAMA_HOST="localhost:11434" ollama serve + +# Загрузка Рекомендуемой Модели +ollama pull nomic-embed-text:latest # Модель Встраивания +ollama pull qwen2.5:0.5b # Модель Чата +``` + +Создайте файл `.env`: + +```bash +# .env +# 🎯 Конфигурация Локальной Модели Ollama +OLLAMA_BASE_URL=http://localhost:11434 +OLLAMA_CHAT_MODEL=qwen2.5:0.5b +OLLAMA_EMBED_MODEL=nomic-embed-text:latest + +# 🎯 Специфическая Конфигурация MemOS +MOS_TEXT_MEM_TYPE=general_text +MOS_USER_ID=default_user +MOS_TOP_K=5 +``` + +#### Шаг 4: Проверьте Установку и Полную Среду + +Создайте файл проверки `test_memos_setup_ollama_mode.py`: + +```python +# test_memos_setup_ollama_mode.py +# 🎯 Скрипт проверки режима Ollama - Используйте локальную модель Ollama и ручную настройку +import os +import sys +from dotenv import load_dotenv + +def check_ollama_environment(): + """🎯 Проверка конфигурации переменных окружения Ollama""" + print("🔍 Проверка конфигурации переменных окружения Ollama...") + + # Загрузите файл .env + load_dotenv() + + # Проверьте конфигурацию Ollama + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + print(f"📋 Состояние переменных окружения Ollama:") + + if ollama_base_url: + print(f" ✅ OLLAMA_BASE_URL: {ollama_base_url}") + print(f" ✅ OLLAMA_CHAT_MODEL: {ollama_chat_model or '❌ Не настроено'}") + print(f" ✅ OLLAMA_EMBED_MODEL: {ollama_embed_model or '❌ Не настроено'}") + ollama_configured = bool(ollama_base_url and ollama_chat_model and ollama_embed_model) + + if ollama_configured: + print("✅ Конфигурация Ollama полная") + else: + print("❌ Конфигурация Ollama неполная") + + return ollama_configured + else: + print(f" ❌ OLLAMA_BASE_URL: Не настроено") + print(f" ❌ OLLAMA_CHAT_MODEL: Не настроено") + print(f" ❌ OLLAMA_EMBED_MODEL: Не настроено") + return False + +def check_memos_installation(): + """🎯 Проверка состояния установки MemOS""" + print("\n🔍 Проверка состояния установки MemOS...") + + try: + import memos + print(f"✅ Версия MemOS: {memos.__version__}") + + # Тестирование импорта основных компонентов + from memos.mem_cube.general import GeneralMemCube + from memos.mem_os.main import MOS + from memos.configs.mem_os import MOSConfig + from memos.configs.mem_cube import GeneralMemCubeConfig + + print("✅ Импорт основных компонентов успешен") + return True + + except ImportError as e: + print(f"❌ Ошибка импорта: {e}") + return False + except Exception as e: + print(f"❌ Другие ошибки: {e}") + return False + +def test_ollama_functionality(): + """🎯 Тестирование функциональности режима Ollama""" + print("\n🔍 Тестирование функциональности режима Ollama...") + + try: + from memos.mem_os.main import MOS + from memos.configs.mem_os import MOSConfig + from memos.configs.mem_cube import GeneralMemCubeConfig + from memos.mem_cube.general import GeneralMemCube + + # Получение переменных окружения + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + print("🚀 Создание конфигурации Ollama...") + + # Создание конфигурации MOS + mos_config = MOSConfig( + user_id=os.getenv("MOS_USER_ID", "default_user"), + chat_model={ + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + "temperature": 0.7, + "max_tokens": 1024, + } + }, + mem_reader={ + "backend": "simple_struct", + "config": { + "llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url, + } + }, + "chunker": { + "backend": "sentence", + "config": { + "tokenizer_or_token_counter": "gpt2", + "chunk_size": 512, + "chunk_overlap": 128, + "min_sentences_per_chunk": 1, + } + } + } + }, + enable_textual_memory=True, + top_k=int(os.getenv("MOS_TOP_K", "5")) + ) + + # Создание конфигурации MemCube + cube_config = GeneralMemCubeConfig( + user_id=os.getenv("MOS_USER_ID", "default_user"), + cube_id=f"{os.getenv('MOS_USER_ID', 'default_user')}_cube", + text_mem={ + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url, + } + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{os.getenv('MOS_USER_ID', 'default_user')}_collection", + "vector_dimension": 768, # размерность nomic-embed-text + "distance_metric": "cosine", + } + } + } + }, + act_mem={"backend": "uninitialized"}, + para_mem={"backend": "uninitialized"} + ) + + print("✅ Конфигурация успешно создана!") + + # Создание экземпляра MOS и MemCube + print("🚀 Создание экземпляра MOS и MemCube...") + memory = MOS(mos_config) + mem_cube = GeneralMemCube(cube_config) + memory.register_mem_cube(mem_cube) + + print("✅ Экземпляр MOS и MemCube успешно созданы!") + print(f" 📊 Идентификатор пользователя: {memory.user_id}") + print(f" 📊 Идентификатор сессии: {memory.session_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + + # Тестирование добавления памяти + print("\n🧠 Тестирование добавления памяти...") + memory.add(memory_content="Это тестовая память в режиме Ollama") + print("✅ Память успешно добавлена!") + + # Тестирование функции чата + print("\n💬 Тестирование функции чата...") + response = memory.chat("Что я только что добавил в память?") + print(f"✅ Ответ чата: {response}") + + # Тестирование функции поиска + print("\n🔍 Тестирование функции поиска...") + search_results = memory.search("Тестовая память", top_k=3) + if search_results and search_results.get("text_mem"): + print(f"✅ Поиск успешен, найдено {len(search_results['text_mem'])} результатов") + else: + print("⚠️ Поиск не вернул результатов") + + # Тестирование MemCube прямого управления + print("\n🔧 Тестирование MemCube прямого управления...") + mem_cube.text_mem.add([{ + "memory": "Это память, добавленная напрямую через MemCube", + "metadata": { + "source": "conversation", + "type": "fact", + "confidence": 0.9 + } + }]) + print("✅ Прямое управление MemCube успешно!") + + print("✅ Тестирование функциональности режима Ollama успешно!") + return True + + except Exception as e: + print(f"❌ Тестирование функциональности режима Ollama не удалось: {e}") + print("💡 Подсказка: проверьте, работает ли служба Ollama, загружена ли модель.") + return False + +def main(): + """🎯 Основной процесс проверки режима Ollama""" + print("🚀 Начало проверки окружения MemOS режима Ollama...\n") + + # Шаг 1: Проверка переменных окружения Ollama + env_ok = check_ollama_environment() + + # Шаг 2: Проверка состояния установки + install_ok = check_memos_installation() + + # Шаг 3: Тестирование функциональности + if env_ok and install_ok: + func_ok = test_ollama_functionality() + else: + func_ok = False + if not env_ok: + print("\n⚠️ Из-за неполной конфигурации переменных окружения Ollama, пропускаем тестирование функциональности") + elif not install_ok: + print("\n⚠️ Из-за ошибки установки MemOS, пропускаем функциональное тестирование") + + # Резюме + print("\n" + "="*50) + print("📊 Результаты проверки режима Ollama:") + print(f" Переменные окружения Ollama: {'✅ Пройдено' if env_ok else '❌ Провалено'}") + print(f" Установка MemOS: {'✅ Пройдено' if install_ok else '❌ Провалено'}") + print(f" Функциональное тестирование: {'✅ Пройдено' if func_ok else '❌ Провалено'}") + + if env_ok and install_ok and func_ok: + print(f"\n🎉 Поздравляем! Конфигурация окружения MemOS Ollama полностью успешна!") + print(f"💡 Теперь вы можете начать использовать режим MemOS Ollama.") + print(f"💡 Способ использования: вручную настройте MOSConfig и GeneralMemCubeConfig") + elif install_ok and env_ok: + print(f"\n⚠️ MemOS установлен, Ollama настроен, но функциональное тестирование провалено.") + print(f"💡 Пожалуйста, проверьте, работает ли служба Ollama, и загружена ли модель.") + elif install_ok: + print("\n⚠️ MemOS установлен, но необходимо настроить переменные окружения Ollama для нормального использования.") + print("💡 Пожалуйста, настройте OLLAMA_BASE_URL, OLLAMA_CHAT_MODEL, OLLAMA_EMBED_MODEL в файле .env.") + else: + print("\n❌ Проблемы с конфигурацией окружения, пожалуйста, проверьте вышеуказанную информацию об ошибках.") + + return bool(env_ok and install_ok and func_ok) + +if __name__ == "__main__": + success = main() + sys.exit(0 if success else 1) +``` + +Запустите проверку режима Ollama: + +```bash +python test_memos_setup_ollama_mode.py +``` + +#### Часто Задаваемые Вопросы и Решения + +**Q1: Что делать, если установка на macOS не удалась?** + +```bash +# 🔧 Возможно, macOS требует дополнительной настройки +export SYSTEM_VERSION_COMPAT=1 +pip install MemoryOS +``` + +**Q2: Как решить конфликты зависимостей?** + +```bash +# 🔧 Использование Виртуальной Среды Для Изоляции +python -m venv memos_env +source memos_env/bin/activate # Linux/macOS +pip install MemoryOS +``` + +**Q3: Настройка GPU-ускорения? (в режиме Ollama)** + +```bash +# 🔧 GPU Ускорение Необходимо Только При Использовании Локальной Модели Ollama +pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 +``` + +### Рецепт 1.2: Создание Простого MemCube из Документного Файла (Ollama版) + +**🎯 Сценарий Проблемы:** У вас есть PDF-документ, содержащий корпоративную базу знаний, и вы хотите создать "чип памяти", который может отвечать на соответствующие вопросы. + +**🔧 Решение:** С помощью этого рецепта вы научитесь, как использовать MemReader для преобразования документа в MemCube, который можно искать. MemReader является核心组件ом MemOS, который может интеллектуально анализировать документы и извлекать структурированную память. + +#### Шаг 1: Подготовьте Пример Документа + +Создайте пример документа знаний `company_handbook.txt`: + +```text +# Справочник Сотрудника Компании + +## Рабочее Время +Стандартное рабочее время компании с понедельника по пятницу, с 9:00 до 18:00. +Гибкий график позволяет сотрудникам начинать работу с 8:00 до 10:00. + +## Политика Отпуска +- Годовой отпуск: 15 дней оплачиваемого годового отпуска +- Больничный: 7 дней оплачиваемого больничного в год +- Личный отпуск: 3 дня личного отпуска в год + +## Социальные Льготы +Компания предоставляет полный пакет социальных льгот, включая: +- Пенсионное Страхование +- Медицинское Страхование +- Страхование от Безработицы +- Страхование от несчастных случаев на производстве +- Страхование по беременности и родам +- Жилищный накопительный фонд + +Дополнительные льготы включают ежегодное медицинское обследование, командные мероприятия и обучение. + +## Офисное Оборудование +Каждый сотрудник получит: +- Один ноутбук +- Один монитор +- Эргономичное кресло +- Офисный стол + +## Контактная Информация +HR-отдел: hr@company.com +IT-поддержка: it@company.com +Финансовый отдел: finance@company.com +``` + +#### Шаг 2: Используйте MemReader для Создания MemCube + +**💡 Режим Ollama:** Этот скрипт использует локальную модель Ollama для обработки документа и векторизации. + +**🔧 Настройка Переменных Среды:** Перед запуском скрипта убедитесь, что вы настроили переменные среды Ollama в соответствии с рецептом 1.1. + +Для использования других парсеров можно обратиться к документации: TODO + + +```python +# create_memcube_with_memreader_ollama.py +# 🎯 Полный Процесс Создания MemCube с Использованием MemReader (Версия Ollama) +import os +import uuid +from dotenv import load_dotenv +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.mem_cube.general import GeneralMemCube +from memos.configs.mem_reader import MemReaderConfigFactory +from memos.mem_reader.factory import MemReaderFactory + +def create_memcube_with_memreader(): + """ + 🎯 Полный процесс создания MemCube с использованием MemReader (версия Ollama) + """ + + print("🔧 Создание конфигурации MemCube...") + + # Загрузка переменных окружения + load_dotenv() + + # Получение конфигурации Ollama + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError("❌ Переменные окружения Ollama не настроены. Пожалуйста, настройте OLLAMA_BASE_URL, OLLAMA_CHAT_MODEL, OLLAMA_EMBED_MODEL в файле .env.") + + print("✅ Обнаружен локальный режим модели Ollama") + + # Получение конфигурации MemOS + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + + # Конфигурация режима Ollama + cube_config = { + "user_id": user_id, + "cube_id": f"{user_id}_company_handbook_cube", + "text_mem": { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url + } + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{user_id}_company_handbook", + "vector_dimension": 768, + "distance_metric": "cosine" + } + } + } + }, + "act_mem": {"backend": "uninitialized"}, + "para_mem": {"backend": "uninitialized"} + } + + # Создание экземпляра MemCube + config_obj = GeneralMemCubeConfig.model_validate(cube_config) + mem_cube = GeneralMemCube(config_obj) + + print("✅ MemCube успешно создан!") + print(f" 📊 Идентификатор пользователя: {mem_cube.config.user_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + print(f" 📊 Бэкенд текстовой памяти: {mem_cube.config.text_mem.backend}") + print(f" 🔍 Модель встраивания: {ollama_embed_model} (Ollama)") + print(f" 🎯 Режим конфигурации: OLLAMA") + + return mem_cube + +def create_memreader_config(): + """ + 🎯 Создание конфигурации MemReader (версия Ollama) + """ + + # Загрузка переменных окружения + load_dotenv() + + # Получение конфигурации Ollama + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + # Настройка MemReader + mem_reader_config = MemReaderConfigFactory( + backend="simple_struct", + config={ + "llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url + } + }, + "chunker": { + "backend": "sentence", + "config": { + "chunk_size": 128, + "chunk_overlap": 32, + "min_sentences_per_chunk": 1 + } + }, + "remove_prompt_example": False + } + ) + + return mem_reader_config + +def load_document_to_memcube(mem_cube, doc_path): + """ + 🎯 Используйте MemReader для загрузки документов в MemCube (версия Ollama) + """ + + print(f"\n📖 Используйте MemReader для чтения документа: {doc_path}") + + # Создание MemReader + mem_reader_config = create_memreader_config() + mem_reader = MemReaderFactory.from_config(mem_reader_config) + + # Подготовка данных документа + print("📄 Подготовка данных документа...") + documents = [doc_path] # MemReader ожидает список путей к документам + + # Обработка документа с помощью MemReader + print("🧠 Используйте MemReader для извлечения памяти...") + memories = mem_reader.get_memory( + documents, + type="doc", + info={ + "user_id": mem_cube.config.user_id, + "session_id": str(uuid.uuid4()) + } + ) + + print(f"📚 MemReader сгенерировал {len(memories)} фрагментов памяти") + + # Добавление памяти в MemCube + print("💾 Добавление памяти в MemCube...") + for mem in memories: + mem_cube.text_mem.add(mem) + print(mem) + + print(f"✅ Успешно добавлено {len(memories)} фрагментов памяти в MemCube") + + # Вывод основной информации + print("\n📊 Основная информация о MemCube:") + print(f" 📁 Источник документа: {doc_path}") + print(f" 📝 Количество фрагментов памяти: {len(memories)}") + print(f" 🏷️ Тип документа: company_handbook") + print(f" 💾 Векторная база данных: Qdrant (режим памяти, освобождение памяти приводит к удалению)") + print(f" 🔍 Модель встраивания: {os.getenv('OLLAMA_EMBED_MODEL')} (Ollama)") + print(f" 🎯 Режим конфигурации: OLLAMA") + print(f" 🧠 Извлекатель памяти: MemReader (simple_struct)") + + return mem_cube + +if __name__ == "__main__": + print("🚀 Начинаем использовать MemReader для создания документа MemCube (версия Ollama)...") + + # Создание MemCube + mem_cube = create_memcube_with_memreader() + + # Загрузка документа + import os + current_dir = os.path.dirname(os.path.abspath(__file__)) + doc_path = os.path.join(current_dir, "company_handbook.txt") + load_document_to_memcube(mem_cube, doc_path) + + print("\n🎉 MemCube создан успешно!") +``` + +#### Пример Запуска + +```bash +# Шаг 2: Создание MemCube +python create_memcube_with_memreader_ollama.py +``` + + +#### Шаг 3: Проверьте Функции Поиска и Диалога + +**💡 Режим Ollama:** Этот скрипт использует локальную модель Ollama для поиска и диалога. + +> В текущей версии MemOS, при отключенном Scheduler, запуск chat может вызвать некоторые проблемы, необходимо вручную закомментировать один блок кода, следуя следующим шагам, вы сможете нормально запустить все последующие примеры кода. В следующих версиях мы исправим эту проблему. +> ctrl+левый клик на функции chat() ниже, затем нажмите super.chat() для перехода в core.py, или в каталоге установки среды найдите lib/python3.12/site-packages/memos/mem_os/core.py и выполните поиск по def chat для нахождения соответствующей функции. +> Закомментируйте блок кода выше return в конце функции: + +``` +# submit message to scheduler +# for accessible_mem_cube in accessible_cubes: +# mem_cube_id = accessible_mem_cube.cube_id +# mem_cube = self.mem_cubes[mem_cube_id] +# if self.enable_mem_scheduler and self.mem_scheduler is not None: +# message_item = ScheduleMessageItem( +# user_id=target_user_id, +# mem_cube_id=mem_cube_id, +# mem_cube=mem_cube, +# label=ANSWER_LABEL, +# content=response, +# timestamp=datetime.now(), +# ) +# self.mem_scheduler.submit_messages(messages=[message_item]) +``` + +```python +# test_memcube_search_and_chat_ollama.py +# 🎯 Тестирование функций поиска и диалога MemCube (версия Ollama) +import os +from dotenv import load_dotenv +from memos.configs.mem_os import MOSConfig +from memos.mem_os.main import MOS + +def create_mos_config(): + """ + 🎯 Создание конфигурации MOS (версия Ollama) + """ + load_dotenv() + + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError("❌ Переменные окружения Ollama не настроены. Пожалуйста, настройте OLLAMA_BASE_URL, OLLAMA_CHAT_MODEL, OLLAMA_EMBED_MODEL в файле .env.") + + # Конфигурация режима Ollama + return MOSConfig( + user_id=user_id, + chat_model={ + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + "temperature": 0.1, + "max_tokens": 1024, + } + }, + mem_reader={ + "backend": "simple_struct", + "config": { + "llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url, + } + }, + "chunker": { + "backend": "sentence", + "config": { + "tokenizer_or_token_counter": "gpt2", + "chunk_size": 512, + "chunk_overlap": 128, + "min_sentences_per_chunk": 1, + } + } + } + }, + enable_textual_memory=True, + top_k=top_k + ) + +def test_memcube_search_and_chat(): + """ + 🎯 Тестирование функций поиска и диалога MemCube (версия Ollama) + """ + + print("🚀 Начинаем тестирование функций поиска и диалога MemCube (версия Ollama)...") + + # Импортируйте функцию из шага 2 + from create_memcube_with_memreader_ollama import create_memcube_with_memreader, load_document_to_memcube + + # Создайте MemCube и загрузите документы + print("\n1️⃣ Создайте MemCube и загрузите документы...") + mem_cube = create_memcube_with_memreader() + # Загрузка документа + import os + current_dir = os.path.dirname(os.path.abspath(__file__)) + doc_path = os.path.join(current_dir, "company_handbook.txt") + load_document_to_memcube(mem_cube, doc_path) + + # Создайте конфигурацию MOS + print("\n2️⃣ Создайте конфигурацию MOS...") + mos_config = create_mos_config() + + # Создайте экземпляр MOS и зарегистрируйте MemCube + print("3️⃣ Создайте экземпляр MOS и зарегистрируйте MemCube...") + mos = MOS(mos_config) + mos.register_mem_cube(mem_cube, mem_cube_id="handbook") + + print("✅ Экземпляр MOS успешно создан!") + print(f" 📊 Идентификатор пользователя: {mos.user_id}") + print(f" 📊 Идентификатор сессии: {mos.session_id}") + print(f" 📊 Зарегистрированные MemCube: {list(mos.mem_cubes.keys())}") + print(f" 🎯 Режим конфигурации: OLLAMA") + print(f" 🤖 Модель чата: {os.getenv('OLLAMA_CHAT_MODEL')} (Ollama)") + print(f" 🔍 Модель встраивания: {os.getenv('OLLAMA_EMBED_MODEL')} (Ollama)") + + # Тестирование функции поиска + print("\n🔍 Тестирование функции поиска...") + test_queries = [ + "Какое рабочее время компании?" + "Сколько дней оплачиваемого отпуска?" + "Какие есть льготы и преимущества?" + "Как связаться с отделом HR?" + ] + + for query in test_queries: + print(f"\n❓ Запрос: {query}") + + # Использовать MOS для поиска + search_results = mos.search(query, top_k=2) + + if search_results and search_results.get("text_mem"): + print(f"📋 Найдено {len(search_results['text_mem'])} связанных результатов:") + for cube_result in search_results['text_mem']: + cube_id = cube_result['cube_id'] + memories = cube_result['memories'] + print(f" 📦 MemCube: {cube_id}") + for i, memory in enumerate(memories[:2], 1): # Показывать только первые 2 результата + print(f" {i}. {memory.memory[:100]}...") + else: + print("😓 Не найдено связанных результатов") + + # Тестирование функции диалога + print("\n💬 Тестирование функции диалога...") + chat_questions = [ + "Каково расписание рабочего времени компании?" + "Какие льготы могут получать сотрудники?" + "Как связаться с IT-поддержкой?" + ] + + for question in chat_questions: + print(f"\n👤 Вопрос: {question}") + + try: + response = mos.chat(question) + print(f"🤖 Ответ: {response}") + except Exception as e: + print(f"❌ Ошибка диалога: {e}") + + print("\n🎉 Тест завершен!") + return mos + +if __name__ == "__main__": + test_memcube_search_and_chat() +``` + +#### Пример Запуска + +```bash +# Шаг 3: Тестирование поиска и диалога +python test_memcube_search_and_chat_ollama.py +``` + + + + +### Рецепт 1.3: MemCube Базовые Операции: Создание, Добавление Памяти, Сохранение, Чтение, Запрос, Удаление (Версия Ollama) + +**🎯 Сценарий Проблемы:** Вы уже создали несколько MemCube: корпоративные правила, кадровые данные компании, корпоративная база знаний..., необходимо научиться эффективно управлять их полным жизненным циклом: создание, добавление памяти, сохранение на диск, загрузка с диска, запрос в памяти (базовый запрос и продвинутый запрос метаданных), а также очистка ненужных MemCube (удаление из памяти и удаление файлов). + +**🔧 Решение:** Овладение полным управлением жизненным циклом MemCube, включая проверку окружения, интеллектуальную настройку, базовые запросы, продвинутые операции с метаданными, а также детализированное управление памятью и файлами. + +#### Шаг 1: Полное Управление Жизненным Циклом MemCube + +```python + # memcube_lifecycle_ollama.py +# 🎯 Управление жизненным циклом MemCube: создание, добавление памяти, сохранение, чтение, запрос, удаление (версия Ollama) +import os +import shutil +import time +from pathlib import Path +from dotenv import load_dotenv +from memos.mem_cube.general import GeneralMemCube +from memos.configs.mem_cube import GeneralMemCubeConfig + +class MemCubeManager: + """ + 🎯 Менеджер жизненного цикла MemCube (версия Ollama) + """ + + def __init__(self, storage_root="./memcube_storage"): + self.storage_root = Path(storage_root) + self.storage_root.mkdir(exist_ok=True) + self.loaded_cubes = {} # Кэш MemCube в памяти + + def create_empty_memcube(self, cube_id: str) -> GeneralMemCube: + """ + 🎯 Создать пустой MemCube (без примеров данных) + """ + + # Загрузить переменные окружения + load_dotenv() + + # Получить конфигурацию Ollama + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError("❌ Переменные окружения Ollama не настроены. Пожалуйста, настройте OLLAMA_BASE_URL, OLLAMA_CHAT_MODEL, OLLAMA_EMBED_MODEL в файле .env.") + + print("✅ Обнаружен локальный режим модели Ollama") + + # Получить конфигурацию MemOS + user_id = os.getenv("MOS_USER_ID", "demo_user") + + # Конфигурация режима Ollama + cube_config = { + "user_id": user_id, + "cube_id": cube_id, + "text_mem": { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url + } + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"collection_{cube_id}_{int(time.time())}", + "vector_dimension": 768, + "distance_metric": "cosine" + } + } + } + }, + "act_mem": {"backend": "uninitialized"}, + "para_mem": {"backend": "uninitialized"} + } + + config_obj = GeneralMemCubeConfig.model_validate(cube_config) + mem_cube = GeneralMemCube(config_obj) + + print(f"✅ Создан пустой MemCube: {cube_id}") + return mem_cube + + def save_memcube(self, mem_cube: GeneralMemCube, cube_id: str) -> str: + """ + 🎯 Сохранить MemCube на диск + """ + + save_path = self.storage_root / cube_id + + print(f"💾 Сохранить MemCube в: {save_path}") + + try: + # ⚠️ Если каталог существует, сначала очистите + if save_path.exists(): + shutil.rmtree(save_path) + + # Сохранить MemCube + mem_cube.dump(str(save_path)) + + print(f"✅ MemCube '{cube_id}' успешно сохранен") + return str(save_path) + + except Exception as e: + print(f"❌ Ошибка сохранения: {e}") + raise + + def load_memcube(self, cube_id: str) -> GeneralMemCube: + """ + 🎯 Загрузить MemCube с диска + """ + + load_path = self.storage_root / cube_id + + if not load_path.exists(): + raise FileNotFoundError(f"MemCube '{cube_id}' не существует в {load_path}") + + print(f"📂 Загрузить MemCube с диска: {load_path}") + + try: + # Загрузить MemCube из каталога + mem_cube = GeneralMemCube.init_from_dir(str(load_path)) + + # Кэшировать в памяти + self.loaded_cubes[cube_id] = mem_cube + + print(f"✅ MemCube '{cube_id}' успешно загружен") + return mem_cube + + except Exception as e: + print(f"❌ Ошибка загрузки: {e}") + raise + + def list_saved_memcubes(self) -> list: + """ + 🎯 Перечислить все сохраненные MemCube + """ + + saved_cubes = [] + + for item in self.storage_root.iterdir(): + if item.is_dir(): + # Проверить, является ли это действительным каталогом MemCube + readme_path = item / "README.md" + if readme_path.exists(): + saved_cubes.append({ + "cube_id": item.name, + "path": str(item), + "size": self._get_dir_size(item) + }) + + return saved_cubes + + def unload_memcube(self, cube_id: str) -> bool: + """ + 🎯 Удалить MemCube из памяти (не удаляя файл) + """ + + if cube_id in self.loaded_cubes: + del self.loaded_cubes[cube_id] + print(f"♻️ MemCube '{cube_id}' был удален из памяти") + return True + else: + print(f"⚠️ MemCube '{cube_id}' не находится в памяти") + return False + + def delete_memcube(self, cube_id: str) -> bool: + """ + 🎯 Удалить локальные файлы MemCube + """ + + delete_path = self.storage_root / cube_id + + if not delete_path.exists(): + print(f"⚠️ MemCube '{cube_id}' не существует в {delete_path}") + return False + + print(f"🗑️ Удаление файла MemCube: {delete_path}") + + try: + # Удалить директорию + shutil.rmtree(delete_path) + + # Удалить из кэша памяти (если все еще в памяти) + if cube_id in self.loaded_cubes: + del self.loaded_cubes[cube_id] + + print(f"✅ Файл MemCube '{cube_id}' успешно удален") + return True + + except Exception as e: + print(f"❌ Ошибка удаления: {e}") + return False + + def _get_dir_size(self, path: Path) -> str: + """Вычислить размер директории""" + total_size = sum(f.stat().st_size for f in path.rglob('*') if f.is_file()) + return f"{total_size / 1024:.1f} KB" + +def add_memories_to_cube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 Добавить память в MemCube + """ + + print(f"🧠 Добавление памяти в {cube_name}...") + + # Добавить несколько примеров памяти (с богатыми метаданными) + memories = [ + {"memory": f"Ажэнь влюбилась в Ацянь", "metadata": {"type": "fact", "source": "conversation", "confidence": 0.9}}, + {"memory": f"Ажэнь ростом 1 метр 5 сантиметров", "metadata": {"type": "fact", "source": "file", "confidence": 0.8}}, + {"memory": f"阿珍是一个刺客", "metadata": {"type": "fact", "source": "web", "confidence": 0.7}}, + {"memory": f"阿强是一个程序员", "metadata": {"type": "fact", "source": "conversation", "confidence": 0.9}}, + {"memory": f"阿强喜欢写代码", "metadata": {"type": "fact", "source": "file", "confidence": 0.8}} + ] + + mem_cube.text_mem.add(memories) + + print(f"✅ Успешно добавлено {len(memories)} воспоминаний в {cube_name}") + + # Показать текущее количество воспоминаний + all_memories = mem_cube.text_mem.get_all() + print(f"📊 {cube_name} Текущее общее количество воспоминаний: {len(all_memories)}") + +def basic_query_memcube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 Базовый запрос MemCube + """ + + print(f"🔍 Базовый запрос {cube_name}:") + + # Получить все воспоминания + all_memories = mem_cube.text_mem.get_all() + print(f" 📊 Общее количество воспоминаний: {len(all_memories)}") + + # Поиск конкретного содержания + search_results = mem_cube.text_mem.search("爱情", top_k=1) + print(f" 🎯 Результат поиска '爱情': {len(search_results)}条") + + for i, result in enumerate(search_results, 1): + print(f" {i}. {result.memory}") + +def advanced_query_memcube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 Расширенный запрос MemCube (операции с метаданными) + """ + + print(f"🔬 Расширенный запрос {cube_name}:") + + # Получить все воспоминания + all_memories = mem_cube.text_mem.get_all() + + # 1. Показать Полную Структуру TextualMemoryItem + print(" 📋 Полная Структура Первой Памяти:") + first_memory = all_memories[0] + print(f" {first_memory}") + print(f" ID: {first_memory.id}") + print(f" Содержимое: {first_memory.memory}") + print(f" Метаданные: {first_memory.metadata}") + print(f" Тип: {first_memory.metadata.type}") + print(f" Источник: {first_memory.metadata.source}") + print(f" Уровень Достоверности: {first_memory.metadata.confidence}") + print() + + # 2. Фильтрация Метаданных + print(" 🔍 Фильтрация Метаданных:") + + # Фильтрация Памяти с Высоким Уровнем Достоверности + high_confidence = [m for m in all_memories if m.metadata.confidence and m.metadata.confidence >= 0.9] + print(f" Память с Высоким Уровнем Достоверности (>=0.9): {len(high_confidence)} записей") + for i, memory in enumerate(high_confidence, 1): + print(f" {i}. {memory.memory} (Уровень Достоверности: {memory.metadata.confidence})") + + # Фильтрация Памяти по Конкретному Источнику + conversation_memories = [m for m in all_memories if m.metadata.source == "conversation"] + print(f" Память из Диалога: {len(conversation_memories)} записей") + for i, memory in enumerate(conversation_memories, 1): + print(f" {i}. {memory.memory} (Источник: {memory.metadata.source})") + + # Фильтрация Источников Файловой Памяти + file_memories = [m for m in all_memories if m.metadata.source == "file"] + print(f" Источники Файловой Памяти: {len(file_memories)} записей") + for i, memory in enumerate(file_memories, 1): + print(f" {i}. {memory.memory} (Источник: {memory.metadata.source})") + + # 3. Комбинированная Фильтрация + print(" 🔍 Комбинированная Фильтрация:") + high_conf_file = [m for m in all_memories + if m.metadata.source == "file" and m.metadata.confidence and m.metadata.confidence >= 0.8] + print(f" Файловая Память С Высокой Уверенностью: {len(high_conf_file)} записей") + for i, memory in enumerate(high_conf_file, 1): + print(f" {i}. {memory.memory} (Источник: {memory.metadata.source}, Уверенность: {memory.metadata.confidence})") + + # 4. Статистическая Информация + print(" 📊 Статистическая Информация:") + sources = {} + confidences = [] + + for memory in all_memories: + # Статистика Источников + source = memory.metadata.source + sources[source] = sources.get(source, 0) + 1 + + # Сбор Уверенности + if memory.metadata.confidence: + confidences.append(memory.metadata.confidence) + + print(f" Распределение Источников: {sources}") + if confidences: + avg_confidence = sum(confidences) / len(confidences) + print(f" Средняя Уверенность: {avg_confidence:.2f}") + +# 🎯 Демонстрация Полного Управления Жизненным Циклом +def demonstrate_lifecycle(): + """ + Демонстрация Полного Жизненного Цикла MemCube + """ + + manager = MemCubeManager() + + print("🚀 Начало Демонстрации Жизненного Цикла MemCube...\n") + + # Шаг 1: Создание MemCube + print("1️⃣ Создание MemCube") + cube1 = manager.create_empty_memcube("demo_cube_1") + + # Шаг 2: Добавление памяти + print("\n2️⃣ Добавление памяти") + add_memories_to_cube(cube1, "demo_cube_1") + + # Шаг 3: Сохранение на диск + print("\n3️⃣ Сохранение MemCube на диск") + manager.save_memcube(cube1, "demo_cube_1") + + # Шаг 4: Список сохраненных MemCube + print("\n4️⃣ Список сохраненных MemCube") + saved_cubes = manager.list_saved_memcubes() + for cube_info in saved_cubes: + print(f" 📦 {cube_info['cube_id']} - {cube_info['size']}") + + # Шаг 5: Чтение с диска + print("\n5️⃣ Чтение MemCube с диска") + del cube1 # 💡 Удаление ссылки в памяти + + reloaded_cube = manager.load_memcube("demo_cube_1") + + # Шаг 6: Базовый запрос + print("\n6️⃣ Базовый запрос") + basic_query_memcube(reloaded_cube, "перезагруженный_demo_cube_1") + + # Шаг 7: Расширенный запрос (операции с метаданными) + print("\n7️⃣ Расширенный Запрос (Операции с Метаданными)") + advanced_query_memcube(reloaded_cube, "перезагруженный_demo_cube_1") + + # Шаг 8: Удалить MemCube из памяти + print("\n8️⃣ Удалить MemCube из памяти") + manager.unload_memcube("demo_cube_1") + + # Шаг 9: Удалить локальные файлы + print("\n9️⃣ Удалить локальные файлы") + manager.delete_memcube("demo_cube_1") + +if __name__ == "__main__": + """ + 🎯 Главная Функция - Запуск Демонстрации Жизненного Цикла MemCube + """ + try: + demonstrate_lifecycle() + print("\n🎉 Демонстрация Жизненного Цикла MemCube Завершена!") + except Exception as e: + print(f"\n❌ Произошла Ошибка Во Время Демонстрации: {e}") + import traceback + traceback.print_exc() +``` + + +#### Пример Запуска + +```bash +# Запуск Демонстрации Жизненного Цикла MemCube +python memcube_lifecycle_ollama.py +``` + +#### Часто Задаваемые Вопросы и Лучшие Практики + +**🔧 Лучшие Практики:** + +1. **Управление Памятью** + + ```python + # ✅ Хорошая Практика: Ограничить Количество Одновременно Загружаемых MemCube + memory_manager = MemCubeMemoryManager() + memory_manager.max_active_cubes = 3 + + # ❌ Избегать: Безлимитной Загрузки MemCube + # Это Может Привести К Переполнению Памяти + ``` + +2. **Стратегия Устойчивости** + + ```python + # ✅ Регулярно Сохраняйте Важные Данные + if important_changes: + cube_manager.save_memcube(mem_cube, "important_data") + + # ✅ Используйте Версионированное Именование + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + cube_manager.save_memcube(mem_cube, f"data_backup_{timestamp}") + ``` + +3. **Оптимизация Запросов** + + ```python + # ✅ Разумно Установите top_k + results = mem_cube.text_mem.search(query, top_k=5) # Обычно 5-10 Достаточно + + # ✅ Используйте Метаданные Для Фильтрации И Сужения Поискового Диапазона + filtered_memories = advanced_ops.filter_by_metadata({"category": "important"}) + ``` + +**🐛 Часто Задаваемые Вопросы:** + +**Q1: Не удалось сохранить MemCube?** + +```python +# 🔧 Убедитесь, Что Достаточно Места На Диске И Права На Запись +import shutil +free_space = shutil.disk_usage(".").free / (1024**3) +print(f"Доступное Пространство: {free_space:.1f} GB") +``` + +**Q2: Результаты запроса неточные?** + +```python +# 🔧 Проверьте, Правильно Ли Настроена Модель Встраивания +print(f"Модель Встраивания: {mem_cube.text_mem.config.embedder}") + +# 🔧 Попробуйте Разные Поисковые Слова +synonyms = ["важный", "ключевой", "основной", "главный"] +for synonym in synonyms: + results = mem_cube.text_mem.search(synonym) +``` + +**Q3: Использование памяти слишком высокое?** + +```python +# 🔧 Мониторинг И Оптимизация Использования Памяти +memory_manager.memory_health_check() +memory_manager.unload_cube("unused_cube_id") +gc.collect() +``` diff --git a/content/ru/open_source/cookbook/chapter2/api.md b/content/ru/open_source/cookbook/chapter2/api.md new file mode 100644 index 00000000..cf096b04 --- /dev/null +++ b/content/ru/open_source/cookbook/chapter2/api.md @@ -0,0 +1,491 @@ +--- +title: Linux API版 +--- + +## Дизайн Сценария + +**🎯 Сценарий Проблемы:** Вы разработчик AI-приложений, который уже освоил основные операции MemOS и теперь хочет создать более структурированную систему памяти. Вы обнаружили, что базовая функция `TextualMemoryMetadata` ограничена и не может удовлетворить потребности сложных сценариев, таких как необходимость различать рабочую память и долгосрочную память, необходимость отслеживать источник памяти, необходимость добавлять метки и информацию о сущностях к памяти. + +**🔧 Решение:** В этой главе вы научитесь использовать `TreeNodeTextualMemoryMetadata` для создания структурированной памяти, включая управление жизненным циклом памяти, многопоточность, метки сущностей и другие функции, чтобы ваше AI-приложение имело более интеллектуальную систему памяти. + +## Рецепт 2.1: Понимание Основных Концепций TreeNodeTextualMemoryMetadata + +**🎯 Сценарий Проблемы:** Вы хотите понять различия между `TreeNodeTextualMemoryMetadata` и базовыми метаданными, а также его основные функции. + +**🔧 Решение:** С помощью этого рецепта вы освоите основные концепции и базовую структуру `TreeNodeTextualMemoryMetadata`. + +### Основной Импорт + +```python +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata +``` + +### Основные Концепции + +#### 1. Тип Памяти (memory_type) + +- `WorkingMemory`: Рабочая Память, Временное Хранение +- `LongTermMemory`: Долгосрочная Память, Постоянное Хранение +- `UserMemory`: Память Пользователя, Персонализированное Хранение + +#### 2. Состояние Памяти (status) + +- `activated`: Активированное Состояние +- `archived`: Архивированное Состояние +- `deleted`: Удаленное Состояние + +#### 3. Тип Памяти (type) + +- `fact`: Факт +- `event`: Событие +- `opinion`: Мнение +- `topic`: Тема +- `reasoning`: Рассуждение +- `procedure`: Процедура + +## Рецепт 2.2: Создание Базовой Структурированной Памяти + +**🎯 Сценарий Проблемы:** Вы хотите создать различные типы памяти, такие как информация о персонажах, информация о проектах, рабочие задачи и т.д., и необходимо установить соответствующие метаданные для каждого типа памяти. + +**🔧 Решение:** С помощью этого рецепта вы научитесь создавать различные типы структурированной памяти. + +### Пример 1: Создание Простой Памяти о Персонаже + +Создание файла `create_person_memory_api.py`: + +```python +# create_person_memory_api.py +# 🎯 Пример создания памяти персонажа (API版) +import os +from dotenv import load_dotenv +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + +def create_person_memory_api(): + """ + 🎯 Пример создания памяти персонажа (API版) + """ + + print("🚀 Начинаем создание памяти персонажа (API版)...") + + # Загрузка переменных окружения + load_dotenv() + + # Проверка конфигурации API + openai_key = os.getenv("OPENAI_API_KEY") + if not openai_key: + raise ValueError("❌ Не настроен OPENAI_API_KEY. Пожалуйста, настройте ключ API OpenAI в файле .env.") + + print("✅ Обнаружен режим API OpenAI") + + # Получить ID пользователя + user_id = os.getenv("MOS_USER_ID", "default_user") + + # Создать метаданные для памяти персонажа + metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="conversation", + confidence=90.0, + memory_type="LongTermMemory", + key="张三_信息", + entities=["张三", "工程师"], + tags=["人员", "技术"] + ) + + # Создать элемент памяти + memory_item = TextualMemoryItem( + memory="张三是我们公司的资深工程师,擅长Python和机器学习", + metadata=metadata + ) + + print(f"Содержимое памяти: {memory_item.memory}") + print(f"Ключ памяти: {memory_item.metadata.key}") + print(f"Тип памяти: {memory_item.metadata.memory_type}") + print(f"Теги: {memory_item.metadata.tags}") + print(f"🎯 Режим конфигурации: OPENAI API") + + return memory_item + +if __name__ == "__main__": + create_person_memory_api() +``` + +Выполните команду: + +```bash +cd test_cookbook/chapter2/API/2 +python create_person_memory_api.py +``` + +### Пример 2: Создание Памяти о Проекте + +Создать файл `create_project_memory_api.py`: + +```python +# create_project_memory_api.py +# 🎯 Пример создания памяти проекта (API-версия) +import os +from dotenv import load_dotenv +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + +def create_project_memory_api(): + """ + 🎯 Пример создания памяти проекта (API-версия) + """ + + print("🚀 Начинаем создание проектной памяти (API версия)...") + + # Загрузка переменных окружения + load_dotenv() + + # Проверка конфигурации API + openai_key = os.getenv("OPENAI_API_KEY") + if not openai_key: + raise ValueError("❌ Не настроен OPENAI_API_KEY. Пожалуйста, настройте ключ API OpenAI в файле .env.") + + print("✅ Обнаружен режим API OpenAI") + + # Получить ID пользователя + user_id = os.getenv("MOS_USER_ID", "default_user") + + # Создание метаданных проектной памяти + project_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="file", + confidence=95.0, + memory_type="LongTermMemory", + key="AI项目_详情", + entities=["AI项目", "机器学习"], + tags=["项目", "AI", "重要"], + sources=["项目文档", "会议记录"] + ) + + # Создать элемент памяти + project_memory = TextualMemoryItem( + memory="AI项目 является интеллектуальной системой обслуживания клиентов, использующей новейшие технологии NLP, планируется завершение за 6 месяцев", + metadata=project_metadata + ) + + print(f"Проектная память: {project_memory.memory}") + print(f"Источник: {project_memory.metadata.sources}") + print(f"🎯 Режим конфигурации: OPENAI API") + + return project_memory + +if __name__ == "__main__": + create_project_memory_api() +``` + +Выполните команду: + +```bash +python create_project_memory_api.py +``` + +### Пример 3: Создание Рабочей Памяти + +Создание файла `create_work_memory_api.py`: + +```python +# create_work_memory_api.py +# 🎯 Пример создания рабочей памяти (API версия) +import os +from dotenv import load_dotenv +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + +def create_work_memory_api(): + """ + 🎯 Пример создания рабочей памяти (API версия) + """ + + print("🚀 Начинаем создание рабочей памяти (API версия)...") + + # Загрузка переменных окружения + load_dotenv() + + # Проверка конфигурации API + openai_key = os.getenv("OPENAI_API_KEY") + if not openai_key: + raise ValueError("❌ Не настроен OPENAI_API_KEY. Пожалуйста, настройте ключ API OpenAI в файле .env.") + + print("✅ Обнаружен режим API OpenAI") + + # Получить ID пользователя + user_id = os.getenv("MOS_USER_ID", "default_user") + + # Создание метаданных рабочей памяти + work_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="procedure", + source="conversation", + confidence=80.0, + memory_type="WorkingMemory", # Рабочая память + key="Сегодняшние Задачи", + tags=["Задача", "Сегодня"] + ) + + # Создать элемент памяти + work_memory = TextualMemoryItem( + memory="Сегодня необходимо завершить код-ревью, командное собрание и подготовить презентацию на завтра", + metadata=work_metadata + ) + + print(f"Рабочая Память: {work_memory.memory}") + print(f"Тип Памяти: {work_memory.metadata.memory_type}") + print(f"🎯 Режим конфигурации: OPENAI API") + + return work_memory + +if __name__ == "__main__": + create_work_memory_api() +``` + +Выполните команду: + +```bash +python create_work_memory_api.py +``` + +## Рецепт 2.3: Описание и Конфигурация Часто Используемых Полей + +**🎯 Сценарий Проблемы:** Вам нужно узнать о всех доступных полях `TreeNodeTextualMemoryMetadata` и о том, как правильно их настроить. + +**🔧 Решение:** С помощью этого рецепта вы освоите значения и методы настройки всех полей. + +### Описание Часто Используемых Полей + +| Поле | Тип | Описание | Пример | +| ------------- | ----- | ---------------- | ---------------------- | +| `user_id` | str | Идентификатор Пользователя | "user123" | +| `type` | str | Тип Памяти | "факт", "событие" | +| `source` | str | Источник | "разговор", "файл" | +| `confidence` | float | Уверенность (0-100) | 90.0 | +| `memory_type` | str | Тип Жизненного Цикла Памяти | "ДолгосрочнаяПамять" | +| `key` | str | Ключ/Заголовок Памяти | "Важная Информация" | +| `entities` | list | Список Сущностей | ["Чжан Сан", "Проект"] | +| `tags` | list | Список Меток | ["Важный", "Технический"] | +| `sources` | list | Мульти-Источник | ["Документ", "Собрание"] | + +## Рецепт 2.4: Практическое Применение - Создание Памяти и Добавление в MemCube + +**🎯 Сценарий Проблемы:** Вы уже научились создавать структурированную память и теперь хотите добавить эту память в MemCube и управлять ею. + +**🔧 Решение:** С помощью этого рецепта вы научитесь интегрировать структурированную память в MemCube и реализовать полный процесс управления памятью. + +Создайте файл `memcube_with_structured_memories_api.py`: + +```python +# memcube_with_structured_memories_api.py +# 🎯 Полный пример добавления структурированной памяти в MemCube (API-версия) +import os +from dotenv import load_dotenv +from memos.mem_cube.general import GeneralMemCube +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + +def create_memcube_config_api(): + """ + 🎯 Создайте конфигурацию MemCube (API-версия) + """ + + print("🔧 Создание конфигурации MemCube (API-версия)...") + + # Загрузка переменных окружения + load_dotenv() + + # Проверка конфигурации API + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + if not openai_key: + raise ValueError("❌ Не настроен OPENAI_API_KEY. Пожалуйста, настройте ключ API OpenAI в файле .env.") + + print("✅ Обнаружен режим API OpenAI") + + # Получить конфигурацию + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + + # Конфигурация режима OpenAI + config = GeneralMemCubeConfig( + user_id=user_id, + cube_id=f"{user_id}_structured_memories_cube", + text_mem={ + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-3.5-turbo", + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.1, + "max_tokens": 1024, + } + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": openai_base, + } + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{user_id}_structured_memories", + "vector_dimension": 1536, + "distance_metric": "cosine" + } + } + } + }, + act_mem={"backend": "uninitialized"}, + para_mem={"backend": "uninitialized"} + ) + + return config + +def create_structured_memories_api(): + """ + 🎯 Полный пример добавления структурированной памяти в MemCube (API-версия) + """ + + print("🚀 Начинаем создание структурированной памяти MemCube (API-версия)...") + + # Создание конфигурации MemCube + config = create_memcube_config_api() + + # Создание MemCube + mem_cube = GeneralMemCube(config) + + print("✅ MemCube успешно создан!") + print(f" 📊 Идентификатор пользователя: {mem_cube.config.user_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + print(f" 📊 Бэкенд текстовой памяти: {mem_cube.config.text_mem.backend}") + print(f" 🔍 Модель встраивания: text-embedding-ada-002 (OpenAI)") + print(f" 🎯 Режим конфигурации: OPENAI API") + + # Создание Нескольких Элементов Памяти + memories = [] + + # Память 1: Информация о Персоне + person_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="fact", + source="conversation", + confidence=90.0, + memory_type="LongTermMemory", + key="李四_信息", + entities=["李四", "设计师"], + tags=["人员", "设计"] + ) + + memories.append({ + "memory": "李四是我们的UI设计师,有5年经验,擅长用户界面设计", + "metadata": person_metadata + }) + + # Память 2: Информация о Проекте + project_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="fact", + source="file", + confidence=95.0, + memory_type="LongTermMemory", + key="移动应用项目", + entities=["移动应用", "开发"], + tags=["项目", "移动端", "重要"] + ) + + memories.append({ + "memory": "移动应用项目正在进行中,预计3个月完成,团队有8个人", + "metadata": project_metadata + }) + + # Память 3: Рабочая Память + work_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="procedure", + source="conversation", + confidence=85.0, + memory_type="WorkingMemory", + key="本周任务", + tags=["任务", "本周"] + ) + + memories.append({ + "memory": "本周需要完成需求分析、原型设计、以及技术选型", + "metadata": work_metadata + }) + + # Добавить в MemCube + mem_cube.text_mem.add(memories) + + print("✅ Успешно добавлено 3 элемента памяти в MemCube") + + # Запрос памяти + print("\n🔍 Запрос всех воспоминаний:") + all_memories = mem_cube.text_mem.get_all() + for i, memory in enumerate(all_memories, 1): + print(f"{i}. {memory.memory}") + print(f" Ключ: {memory.metadata.key}") + print(f" Тип: {memory.metadata.memory_type}") + print(f" Метки: {memory.metadata.tags}") + print() + + # Поиск конкретной памяти + print("🔍 Поиск памяти, содержащей '李四':") + search_results = mem_cube.text_mem.search("李四", top_k=2) + for result in search_results: + print(f"- {result.memory}") + + return mem_cube + +if __name__ == "__main__": + create_structured_memories_api() +``` + +Выполните команду: + +```bash +cd test_cookbook/chapter2/API/4 +python memcube_with_structured_memories_api.py +``` + +## Часто Задаваемые Вопросы и Решения + +**Q1: Как выбрать подходящий memory_type?** + +```python +# 🔧 Выбор в зависимости от важности памяти +if is_important: + memory_type = "LongTermMemory" # Долгосрочное хранение +elif is_temporary: + memory_type = "WorkingMemory" # Временное хранение +else: + memory_type = "UserMemory" # Персонализированное хранение +``` + +**Q2: Как установить подходящее значение confidence?** + +```python +# 🔧 Установка в зависимости от надежности источника информации +if source == "verified_document": + confidence = 95.0 +elif source == "conversation": + confidence = 80.0 +elif source == "web_search": + confidence = 70.0 +``` + +**Q3: Как эффективно использовать tags и entities?** + +```python +# 🔧 Используйте Значимые Метки и Сущности +tags = ["Проект", "Технология", "Важно"] # Удобно для Классификации и Поиска +entities = ["Чжан Сан", "AI项目"] # Удобно для Распознавания и Связывания Сущностей +``` diff --git a/content/ru/open_source/cookbook/chapter2/ollama.md b/content/ru/open_source/cookbook/chapter2/ollama.md new file mode 100644 index 00000000..f283b828 --- /dev/null +++ b/content/ru/open_source/cookbook/chapter2/ollama.md @@ -0,0 +1,511 @@ +--- +title: Linux Ollama版 +--- + +## Дизайн Сценария + +**🎯 Сценарий Проблемы:** Вы разработчик AI-приложений, который уже освоил основные операции MemOS и теперь хочет создать более структурированную систему памяти. Вы обнаружили, что базовая функция `TextualMemoryMetadata` ограничена и не может удовлетворить потребности сложных сценариев, таких как необходимость различать рабочую память и долгосрочную память, необходимость отслеживать источник памяти, необходимость добавлять теги и информацию об объектах к памяти. + +**🔧 Решение:** В этой главе вы научитесь использовать `TreeNodeTextualMemoryMetadata` для создания структурированной памяти, включая управление жизненным циклом памяти, многопоточность, теги объектов и другие функции, чтобы ваше AI-приложение имело более интеллектуальную систему памяти. + +## Рецепт 2.1: Понимание Основных Концепций TreeNodeTextualMemoryMetadata + +**🎯 Сценарий Проблемы:** Вы хотите понять различия между `TreeNodeTextualMemoryMetadata` и базовыми метаданными, а также его основные функции. + +**🔧 Решение:** С помощью этого рецепта вы освоите основные концепции и базовую структуру `TreeNodeTextualMemoryMetadata`. + +### Основной Импорт + +```python +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata +``` + +### Основные Концепции + +#### 1. Тип Памяти (memory_type) + +- `WorkingMemory`: Рабочая Память, Временное Хранение +- `LongTermMemory`: Долгосрочная Память, Постоянное Хранение +- `UserMemory`: Память Пользователя, Персонализированное Хранение + +#### 2. Состояние Памяти (status) + +- `activated`: Активированное Состояние +- `archived`: Архивированное Состояние +- `deleted`: Удаленное Состояние + +#### 3. Тип (type) + +- `fact`: Факт +- `event`: Событие +- `opinion`: Мнение +- `topic`: Тема +- `reasoning`: Рассуждение +- `procedure`: Процедура + +## Рецепт 2.2: Создание Базовой Структурированной Памяти + +**🎯 Сценарий Проблемы:** Вы хотите создать различные типы памяти, такие как информация о персонажах, информация о проектах, рабочие задачи и т.д., и вам нужно установить подходящие метаданные для каждого типа памяти. + +**🔧 Решение:** С помощью этого рецепта вы научитесь создавать различные типы структурированной памяти. + +### Пример 1: Создание Простой Памяти о Персонаже + +Создание файла `create_person_memory_ollama.py`: + +```python +# create_person_memory_ollama.py +# 🎯 Пример создания памяти персонажа (Ollama版) +import os +from dotenv import load_dotenv +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + +def create_person_memory_ollama(): + """ + 🎯 Пример создания памяти персонажа (Ollama版) + """ + + print("🚀 Начинаем создание памяти персонажа (Ollama版)...") + + # Загрузка переменных окружения + load_dotenv() + + # Проверка конфигурации Ollama + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError("❌ Не настроены переменные окружения Ollama. Пожалуйста, настройте OLLAMA_BASE_URL, OLLAMA_CHAT_MODEL, OLLAMA_EMBED_MODEL в файле .env.") + + print("✅ Обнаружен локальный режим модели Ollama") + + # Получить ID пользователя + user_id = os.getenv("MOS_USER_ID", "default_user") + + # Создать метаданные для памяти персонажа + metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="conversation", + confidence=90.0, + memory_type="LongTermMemory", + key="张三_信息", + entities=["张三", "工程师"], + tags=["人员", "技术"] + ) + + # Создать элемент памяти + memory_item = TextualMemoryItem( + memory="张三是我们公司的资深工程师,擅长Python和机器学习", + metadata=metadata + ) + + print(f"Содержимое памяти: {memory_item.memory}") + print(f"Ключ памяти: {memory_item.metadata.key}") + print(f"Тип памяти: {memory_item.metadata.memory_type}") + print(f"Теги: {memory_item.metadata.tags}") + print(f"🎯 Режим конфигурации: OLLAMA") + print(f"🤖 Модель чата: {ollama_chat_model}") + print(f"🔍 Модель встраивания: {ollama_embed_model}") + + return memory_item + +if __name__ == "__main__": + create_person_memory_ollama() +``` + +Выполните команду: + +```bash +cd test_cookbook/chapter2/Ollama/2 +python create_person_memory_ollama.py +``` + +### Пример 2: Создание Памяти о Проекте + +Создать файл `create_project_memory_ollama.py`: + +```python +# create_project_memory_ollama.py +# 🎯 Пример Создания Проектной Памяти (Версия Ollama) +import os +from dotenv import load_dotenv +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + +def create_project_memory_ollama(): + """ + 🎯 Пример Создания Проектной Памяти (Версия Ollama) + """ + + print("🚀 Начинаем Создание Проектной Памяти (Версия Ollama)...") + + # Загрузка переменных окружения + load_dotenv() + + # Проверка конфигурации Ollama + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError("❌ Не настроены переменные окружения Ollama. Пожалуйста, настройте OLLAMA_BASE_URL, OLLAMA_CHAT_MODEL, OLLAMA_EMBED_MODEL в файле .env.") + + print("✅ Обнаружен локальный режим модели Ollama") + + # Получить ID пользователя + user_id = os.getenv("MOS_USER_ID", "default_user") + + # Метаданные Проектной Памяти + project_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="file", + confidence=95.0, + memory_type="LongTermMemory", + key="AI项目_详情", + entities=["AI项目", "机器学习"], + tags=["项目", "AI", "重要"], + sources=["项目文档", "会议记录"] + ) + + # Создать элемент памяти + project_memory = TextualMemoryItem( + memory="AI项目是一个智能客服系统,使用最新的NLP技术,预计6个月完成", + metadata=project_metadata + ) + + print(f"Проектная Память: {project_memory.memory}") + print(f"Источники: {project_memory.metadata.sources}") + print(f"🎯 Режим конфигурации: OLLAMA") + print(f"🤖 Модель чата: {ollama_chat_model}") + print(f"🔍 Модель встраивания: {ollama_embed_model}") + + return project_memory + +if __name__ == "__main__": + create_project_memory_ollama() +``` + +Выполните команду: + +```bash +python create_project_memory_ollama.py +``` + +### Пример 3: Создание Рабочей Памяти + +Создайте файл `create_work_memory_ollama.py`: + +```python +# create_work_memory_ollama.py +# 🎯 Пример Создания Рабочей Памяти (Версия Ollama) +import os +from dotenv import load_dotenv +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + +def create_work_memory_ollama(): + """ + 🎯 Пример Создания Рабочей Памяти (Версия Ollama) + """ + + print("🚀 Начинаем Создание Рабочей Памяти (Версия Ollama)...") + + # Загрузка переменных окружения + load_dotenv() + + # Проверка конфигурации Ollama + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError("❌ Не настроены переменные окружения Ollama. Пожалуйста, настройте OLLAMA_BASE_URL, OLLAMA_CHAT_MODEL, OLLAMA_EMBED_MODEL в файле .env.") + + print("✅ Обнаружен локальный режим модели Ollama") + + # Получить ID пользователя + user_id = os.getenv("MOS_USER_ID", "default_user") + + # Создание Метаданных Рабочей Памяти + work_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="procedure", + source="conversation", + confidence=80.0, + memory_type="WorkingMemory", # Рабочая Память + key="Сегодняшние Задачи", + tags=["Задача", "Сегодня"] + ) + + # Создать элемент памяти + work_memory = TextualMemoryItem( + memory="Сегодня необходимо завершить код-ревью, командное собрание и подготовить презентацию на завтра", + metadata=work_metadata + ) + + print(f"Рабочая Память: {work_memory.memory}") + print(f"Тип Памяти: {work_memory.metadata.memory_type}") + print(f"🎯 Режим конфигурации: OLLAMA") + print(f"🤖 Модель чата: {ollama_chat_model}") + print(f"🔍 Модель встраивания: {ollama_embed_model}") + + return work_memory + +if __name__ == "__main__": + create_work_memory_ollama() +``` + +Выполните команду: + +```bash +python create_work_memory_ollama.py +``` + +## Рецепт 2.3: Описание и Конфигурация Часто Используемых Полей + +**🎯 Сценарий Проблемы:** Вам нужно понять все доступные поля `TreeNodeTextualMemoryMetadata` и как правильно их настроить. + +**🔧 Решение:** С помощью этого рецепта вы освоите значения и методы настройки всех полей. + +### Описание Часто Используемых Полей + +| Поле | Тип | Описание | Пример | +| ------------- | ----- | ---------------- | ---------------------- | +| `user_id` | str | ID Пользователя | "user123" | +| `type` | str | Тип Памяти | "факт", "событие" | +| `source` | str | Источник | "разговор", "файл" | +| `confidence` | float | Уверенность (0-100) | 90.0 | +| `memory_type` | str | Тип Жизненного Цикла Памяти | "ДолгосрочнаяПамять" | +| `key` | str | Ключ/Заголовок Памяти | "Важная Информация" | +| `entities` | list | Список Сущностей | ["Чжан Сан", "Проект"] | +| `tags` | list | Список тегов | ["重要", "技术"] | +| `sources` | list | Список источников | ["文档", "会议"] | + +## Рецепт 2.4: Практическое Применение - Создание Памяти и Добавление в MemCube + +**🎯 Сценарий Проблемы:** Вы уже научились создавать структурированную память и теперь хотите добавить эту память в MemCube и управлять ею. + +**🔧 Решение:** С помощью этого рецепта вы научитесь интегрировать структурированную память в MemCube и реализовать полный процесс управления памятью. + +Создание файла `memcube_with_structured_memories_ollama.py`: + +```python +# memcube_with_structured_memories_ollama.py +# 🎯 Полный пример добавления структурированной памяти в MemCube (версия Ollama) +import os +from dotenv import load_dotenv +from memos.mem_cube.general import GeneralMemCube +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + +def create_memcube_config_ollama(): + """ + 🎯 Создание конфигурации MemCube (версия Ollama) + """ + + print("🔧 Создание конфигурации MemCube (версия Ollama)...") + + # Загрузка переменных окружения + load_dotenv() + + # Проверка конфигурации Ollama + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError("❌ Не настроены переменные окружения Ollama. Пожалуйста, настройте OLLAMA_BASE_URL, OLLAMA_CHAT_MODEL, OLLAMA_EMBED_MODEL в файле .env.") + + print("✅ Обнаружен локальный режим модели Ollama") + + # Получение конфигурации + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + + # Конфигурация режима Ollama + cube_config = { + "user_id": user_id, + "cube_id": f"{user_id}_structured_memories_cube", + "text_mem": { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url + } + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{user_id}_structured_memories", + "vector_dimension": 768, + "distance_metric": "cosine" + } + } + } + }, + "act_mem": {"backend": "uninitialized"}, + "para_mem": {"backend": "uninitialized"} + } + + # Создание экземпляра MemCube + config_obj = GeneralMemCubeConfig.model_validate(cube_config) + + return config_obj + +def create_structured_memories_ollama(): + """ + 🎯 Полный пример добавления структурированной памяти в MemCube (версия Ollama) + """ + + print("🚀 Начало создания структурированной памяти MemCube (версия Ollama)...") + + # Создание конфигурации MemCube + config = create_memcube_config_ollama() + + # Создание MemCube + mem_cube = GeneralMemCube(config) + + print("✅ MemCube успешно создан!") + print(f" 📊 Идентификатор пользователя: {mem_cube.config.user_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + print(f" 📊 Текстовая Память Бэкенд: {mem_cube.config.text_mem.backend}") + + # Получить Конфигурацию Ollama Для Отображения + load_dotenv() + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + print(f" 🔍 Встраиваемая Модель: {ollama_embed_model} (Ollama)") + print(f" 🤖 Чат Модель: {ollama_chat_model} (Ollama)") + print(f" 🎯 Конфигурационный Режим: OLLAMA") + + # Создать Несколько Элементов Памяти + memories = [] + + # Память 1: Информация о Персоне + person_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="fact", + source="conversation", + confidence=90.0, + memory_type="LongTermMemory", + key="李四_信息", + entities=["李四", "设计师"], + tags=["人员", "设计"] + ) + + memories.append({ + "memory": "李四是我们的UI设计师,有5年经验,擅长用户界面设计", + "metadata": person_metadata + }) + + # Память 2: Информация о Проекте + project_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="fact", + source="file", + confidence=95.0, + memory_type="LongTermMemory", + key="移动应用项目", + entities=["移动应用", "开发"], + tags=["项目", "移动端", "重要"] + ) + + memories.append({ + "memory": "Проект мобильного приложения в процессе, ожидается завершение через 3 месяца, команда состоит из 8 человек" + "metadata": project_metadata + }) + + # Память 3: Рабочая Память + work_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="procedure", + source="conversation", + confidence=85.0, + memory_type="WorkingMemory", + key="Задачи На Эту Неделю" + tags=["Задача", "На Эту Неделю"] + ) + + memories.append({ + "memory": "На этой неделе необходимо завершить анализ требований, проектирование прототипа и выбор технологий" + "metadata": work_metadata + }) + + # Добавить в MemCube + mem_cube.text_mem.add(memories) + + print("✅ Успешно добавлено 3 элемента памяти в MemCube") + + # Запрос памяти + print("\n🔍 Запрос всех записей памяти:") + all_memories = mem_cube.text_mem.get_all() + for i, memory in enumerate(all_memories, 1): + print(f"{i}. {memory.memory}") + print(f" Ключ: {memory.metadata.key}") + print(f" Тип: {memory.metadata.memory_type}") + print(f" Теги: {memory.metadata.tags}") + print() + + # Поиск конкретной памяти + print("🔍 Поиск памяти, содержащей 'Ли Сы':") + search_results = mem_cube.text_mem.search("Ли Сы", top_k=2) + for result in search_results: + print(f"- {result.memory}") + + return mem_cube + +if __name__ == "__main__": + create_structured_memories_ollama() +``` + +Выполните команду: + +```bash +cd test_cookbook/chapter2/Ollama/4 +python memcube_with_structured_memories_ollama.py +``` + +## Часто Задаваемые Вопросы и Решения + +**Q1: Как выбрать подходящий memory_type?** + +```python +# 🔧 Выбор В Соответствии С Важностью Памяти +if is_important: + memory_type = "LongTermMemory" # Долгосрочное Хранение +elif is_temporary: + memory_type = "WorkingMemory" # Временное Хранение +else: + memory_type = "UserMemory" # Персонализированное Хранение +``` + +**Q2: Как установить подходящее значение confidence?** + +```python +# 🔧 Настройка В Соответствии С Надежностью Источника Информации +if source == "verified_document": + confidence = 95.0 +elif source == "conversation": + confidence = 80.0 +elif source == "web_search": + confidence = 70.0 +``` + +**Q3: Как эффективно использовать tags и entities?** + +```python +# 🔧 Использование Значимых Меток И Сущностей +tags = ["项目", "技术", "重要"] # Удобно Для Классификации И Поиска +entities = ["张三", "AI项目"] # Удобно Для Распознавания И Связывания Сущностей +``` diff --git a/content/ru/open_source/cookbook/chapter3/overview.md b/content/ru/open_source/cookbook/chapter3/overview.md new file mode 100644 index 00000000..fdfb8f9a --- /dev/null +++ b/content/ru/open_source/cookbook/chapter3/overview.md @@ -0,0 +1,1106 @@ +--- +title: Использование MemOS для построения системы интеллектуального анализа романов +--- + +### 🆚 Почему выбрать MemOS? Сравнение традиционных методов и MemOS + +Перед тем как начать кодирование, давайте посмотрим, какие проблемы решает MemOS: + +![Cookbook-Chapter3-Chart](https://statics.memtensor.com.cn/memos/cookbook-chapter3-chart.png) + +**Примеры сравнительного эффекта:** + +**Пользователь спрашивает: "Как развивались отношения Сяо Фэна и Дуань Юя?"** + +| Традиционный Метод | MemOS Метод | +| --------------------------- | ----------------------- | +| 🐌 Переискать Связанные Фрагменты В Тексте | ⚡ Прямой Поиск На Уровне Связей | +| 😵 Возможны Пропуски Ключевых Событий | 🎯 Полная Хронология Развития Связей | +| 📄 Ответ Только На Основе Часть Текста | 🧠 Анализ На Основе Полного Образа Персонажа | + +### 💡 Почему использовать встроенные компоненты MemOS? + +Представьте, что вы хотите приготовить блюдо, вы можете выбрать: + +- 🔧 **Сделать все приправы самостоятельно** - требует много времени и усилий, качество трудно гарантировать +- 🏪 **Использовать профессиональные бренды приправ** - экономит время и эффективно, качество стабильно + +MemOS как профессиональный "бренд приправ", он уже подготовил для нас: + +- 🤖 **Интеллектуальный клиент для диалога** - автоматически решает сетевые проблемы, поддерживает различные AI модели +- 🧠 **Служба векторизации** - специально оптимизированная способность понимания китайского текста +- ⚙️ **Управление конфигурацией** - простая и удобная настройка параметров + +**Полученные знания:** +В этой главе вы научитесь, как, как профессиональный разработчик, приоритизировать использование зрелых библиотек компонентов, а не писать сложный низкоуровневый код с нуля. + +--- + +### Введение в главу + +Эта глава проведет вас через создание интеллектуальной системы анализа памяти на основе романа "Тяньлунь Ба Бу", реализуя полный процесс преобразования от исходного текста к структурированной памяти. + +**Основная архитектура технологии:** + +![Cookbook-Chapter3-Core](https://statics.memtensor.com.cn/memos/cookbook-chapter3-core.png) + +**Конвейер обработки данных:** + +1. **Предобработка текста** → Разделение на главы → **Структурированный ввод** +2. **Извлечение на основе AI** → Моделирование персонажей → **Генерация MemCube** +3. **Преобразование формата** → Построение графовой структуры → **База памяти MemOS** + +**Идеология проектирования системы:** + +- Эта глава предоставляет полное решение от неструктурированного текста до интеллектуальной системы памяти +- Каждый рецепт решает ключевые технические проблемы в конвейере данных +- Поддержка параллельной обработки и инкрементного обновления больших объемов текста +- Построение запрашиваемой и выводимой интеллектуальной сети памяти + +--- + +### Конфигурация окружения + +```python +import requests +import json +import os +import pickle +import time +from datetime import datetime +from concurrent.futures import ThreadPoolExecutor, as_completed +from requests.adapters import HTTPAdapter +from urllib3.util.retry import Retry +import re +from typing import Dict, List, Optional, Any, Set, Tuple +from dataclasses import dataclass, field +from enum import Enum +``` + +## Рецепт 3.0: Предобработка текста и конфигурация окружения API + +### 🎯 Цель + +Создание основы для структурированной обработки текста романа, включая разделение глав и подключение AI-сервисов. + +### 📖 Алгоритм разделения глав + +Использование регулярных выражений для распознавания заголовков глав, разделяя длинные романы на обрабатываемые фрагменты: + +```python +def extract_all_chapters(text: str, output_dir: str = "chapters"): + # Найти Все Позиции Заголовков "Глава X" + pattern = r"(第[一二三四五六七八九十百千零〇两\d]+章)" + matches = list(re.finditer(pattern, text)) + + if not matches: + raise ValueError("Не Найдено Ни Одного Заголовка Главы") + + os.makedirs(output_dir, exist_ok=True) + + for i in range(len(matches)): + start_idx = matches[i].start() + end_idx = matches[i+1].start() if i+1 < len(matches) else len(text) + chapter_title = matches[i].group() + chapter_number = i + 1 # Нумерация Натуральными Числами + + chapter_text = text[start_idx:end_idx].strip() + filename = os.path.join(output_dir, f"chapter{chapter_number}.txt") + with open(filename, "w", encoding="utf-8") as f: + f.write(chapter_text) + print(f"✅ Сохранено: {filename}({chapter_title})") + +# Чтение Целой Книги +with open("天龙八部.txt", "r", encoding="utf-8") as f: + full_text = f.read() + +# Извлечение И Сохранение Всех Глав +extract_all_chapters(full_text) +``` + +### 🔧 Конфигурация клиента API + +Создание стабильного соединения с AI-сервисом, поддерживающего вызовы моделей для различных типов задач: + +```python +# Конфигурация Функции Ремонт JSON +try: + from json_repair import repair_json + HAS_JSONREPAIR = True + print("✓ Библиотека jsonrepair Загружена, Функция Ремонта JSON Включена") +except ImportError: + HAS_JSONREPAIR = False + print("⚠ Библиотека jsonrepair Не Установлена, Будет Использована Базовая Стратегия Ремонта") + def repair_json(text): + return text + +class TaskType(Enum): + EVENT_EXTRACTION = "event_extraction" + +class MemOSLLMClient: + """Клиент для диалога - Используйте MemOS, чтобы сделать вызовы AI простыми и надежными""" + + def __init__(self, api_key: str, api_base: str = "https://api.openai.com/v1", model: str = "gpt-4o"): + # 🔧 Шаг Первый: Импортируйте Умные Компоненты MemOS + from memos.llms.factory import LLMFactory + from memos.configs.llm import LLMConfigFactory + + # 🎯 Шаг Второй: Скажите MemOS, какую AI Модель мы будем использовать + llm_config_factory = LLMConfigFactory( + backend="openai", # Используйте OpenAI (также поддерживаются другие поставщики) + config={ + "model_name_or_path": model, # Выбранная вами AI модель + "api_key": api_key, # Ваш API ключ + "api_base": api_base, # Адрес API сервиса + "temperature": 0.8, # Уровень креативности + "max_tokens": 8192, # Максимальная длина ответа + "top_p": 0.9, # Контроль качества ответа + } + ) + + # 🚀 Шаг Третий: Позвольте MemOS помочь нам создать клиент для диалога + # MemOS автоматически обработает сложные проблемы, такие как повторные попытки сети и пул соединений + self.llm = LLMFactory.from_config(llm_config_factory) + print(f"✅ Клиент для диалога готов! Используемая модель: {model}") + + def call_api(self, messages: List[Dict], task_type: TaskType, timeout: int = 1800) -> Dict: + """Методы общения с AI - Это так просто!""" + try: + response = self.llm.generate(messages) + return { + "status": "success", # Успех! + "content": response, # Ответ ИИ + "model_used": self.llm.config.model_name_or_path # Какую модель использовали + } + except Exception as e: + # 😅 Если произошла ошибка, MemOS сообщит нам, в чем конкретно проблема + return { + "status": "error", + "error": str(e), + "model_used": self.llm.config.model_name_or_path + } +``` + +### 🚀 Инициализация пакетной обработки + +Создание механизма обхода глав для подготовки к последующей параллельной обработке: + +```python +# 🎯 Настройте своего AI помощника (используйте MemOS, чтобы все упростить) +API_KEY = "YOUR_API_KEY" # 🔑 Введите ваш OpenAI API ключ +API_BASE = "https://api.openai.com/v1" # 🌐 Адрес API сервиса (обычно не нужно изменять) +MODEL_NAME = "gpt-4o" # 🤖 Выберите понравившуюся модель AI + +# 🚀 Создайте своего персонального AI помощника +api_client = MemOSLLMClient( + api_key=API_KEY, + api_base=API_BASE, + model=MODEL_NAME +) +# Теперь у вас есть умный, стабильный и удобный AI помощник! + +memcubes = {} # Глобальная память о персонажах +alias_to_name = {} # Отображение псевдонимов на стандартные имена +chapter_folder = "chapters" + +# Обработка по порядку глав +chapter_files = sorted( + [os.path.join(chapter_folder, f) for f in os.listdir(chapter_folder) + if f.startswith("chapter") and f.endswith(".txt")], + key=lambda x: int(re.search(r'chapter(\d+)', x).group(1)) +) + +for chapter_file in chapter_files: + chapter_id = chapter_file.replace(".txt", "") + print(f"\n📖 Обрабатывается: {chapter_id}") + + with open(chapter_file, "r", encoding="utf-8") as f: + content = f.read() + # Логика последующей обработки... +``` + +--- + +## Рецепт 3.1: Автоматическое распознавание персонажей и унификация псевдонимов на основе AI + +### 🎯 Цель + +Использование AI для автоматического распознавания персонажей в романе, создание сопоставления псевдонимов, и инициализация контейнеров памяти персонажей. + +### 🧠 Интеллектуальное распознавание персонажей + +Достижение точного извлечения персонажей и объединения псевдонимов с помощью тщательно разработанных подсказок: + +```python +@staticmethod +def extract_character_names_prompt(paragraph: str, alias_to_name: dict = None): + system_msg = ( + "Вы эксперт по распознаванию персонажей в романах, пожалуйста, извлеките всех явно упомянутых персонажей из следующего фрагмента романа.\n" + "Для каждого персонажа укажите стандартное имя этого персонажа (например, "乔峰") и все обращения, псевдонимы, заменители, которые появляются в этом фрагменте (например, "丐帮帮主", "乔帮主", "那大汉").\n\n" + "Пожалуйста, верните JSON в следующем формате: \n" + "[\n" + " {\n" + " \"name\": \"乔峰\",\n" + " \"aliases\": [\"丐帮帮主\", \"乔帮主\", \"那大汉\"]\n" + " }\n" + "]\n\n" + "⚠️ Внимание: \n" + "1. Включайте только персонажей, не включая места или организации.\n" + "2. Разные обращения одного и того же персонажа должны быть объединены в одну запись.\n" + "3. Все поля должны использовать стандартный формат JSON. Не включайте символы markdown или комментарии.\n" + "4. Если невозможно определить, является ли данное обращение новым персонажем, можно временно оставить его как отдельный элемент." + ) + + if alias_to_name: + system_msg += "\n\nВот известные псевдонимы и соответствующие стандартные имена персонажей, пожалуйста, постарайтесь отнести новые распознанные обращения к уже существующим персонажам: \n" + alias_map_str = json.dumps(alias_to_name, ensure_ascii=False, indent=2) + system_msg += alias_map_str + + return [ + {"role": "system", "content": system_msg}, + {"role": "user", "content": f"Фрагмент романа следующий: \n{paragraph}"} + ] +``` + +### 💾 Инициализация MemCube и управление псевдонимами + +Создание структурированных контейнеров памяти для каждого распознанного персонажа: + +```python +def init_memcube(character_name: str, chunk_id: str): + """Инициализация памяти персонажа MemCube - включает все основные поля""" + return { + "name": character_name, + "first_appearance": chunk_id, + "aliases": [character_name], + "events": [], + "utterances": [], + "speech_style": "", + "personality_traits": [], + "emotion_state": "", + "relations": [] + } + +# Выполнение распознавания персонажей и инициализация +name_prompt = Prompt.extract_character_names_prompt(content, alias_to_name) +name_result = api_client.call_api(name_prompt, TaskType.EVENT_EXTRACTION, timeout=1800) + +try: + extracted = json.loads(name_result.get("content", "").strip("```json").strip("```").strip()) +except: + extracted = [] + +# Обновление базы данных персонажей и отображение псевдонимов +for item in extracted: + std_name = item["name"] + aliases = item.get("aliases", []) + + # Инициализация или обновление MemCube + if std_name not in memcubes: + print(f"🆕 Новый Персонаж Распознавания:{std_name}") + memcubes[std_name] = init_memcube(std_name, chapter_id) + memcubes[std_name]["aliases"] = [] + + # Объединить Список Псевдонимов + all_aliases = list(set(memcubes[std_name].get("aliases", []) + aliases)) + memcubes[std_name]["aliases"] = all_aliases + + # Построить Глобальную Карта Псевдонимов + for alias in [std_name] + aliases: + alias_to_name[alias] = std_name +``` + +--- + +## Рецепт 3.2: Извлечение структурированного содержания памяти + +### 🎯 Цель + +Использование AI для извлечения структурированной информации о персонажах из текста романа, включая события, цитаты, характер, эмоции и сеть отношений. + +### 🎭 Подсказка для многомерного извлечения информации + +Проектирование точных шаблонов подсказок, чтобы гарантировать, что AI возвращает стандартизированные данные в формате JSON: + +```python +@staticmethod +def update_character_prompt(character_name: str, unfinished_events: list, paragraph: str): + return [ + { + "role": "system", + "content": ( + "Вы являетесь экспертом по моделированию персонажей романов и будете анализировать незавершенные события определенного персонажа и последние фрагменты романа.\n" + "Ваша задача — обновить следующие поля:\n" + "- events:Список Событий(обновить статус, добавить новые события, включая подполе event_id、action、motivation、impact、involved_entities、time、location、event、if_completed)\n" + "- Каждое событие должно содержать уникальный \"event_id\", например \"event_001\", \"event_002\" и т.д.\n" + "- utterances:Сказанные Слова(включая время или номер события)\n" + "- speech_style:Стиль Речи(например, Классический, Прямой, Ироничный и т.д.)\n" + "- personality_traits:Черты Личности(например, Спокойный, Импульсивный)\n" + "- emotion_state:Текущее Эмоциональное Состояние\n" + "- relations:Список Отношений с Другими\n\n" + "Пожалуйста, обратите особое внимание на следующие требования:\n" + "1. Пожалуйста, внимательно оцените, завершены ли существующие незавершенные события в новом фрагменте.\n" + "2. Если у какого-либо события есть завершение или результат, обязательно отметьте его поле `if_completed` как true.\n" + "3. Если в фрагменте романа появляются новые события, связанные с этим персонажем, пожалуйста, добавьте новую запись о событии.\n" + "В конечном итоге, пожалуйста, выведите следующую структуру JSON: \n" + "{\n" + " \"events\": [...],\n" + " \"utterances\": [...],\n" + " \"speech_style\": \"...\",\n" + " \"personality_traits\": [...],\n" + " \"emotion_state\": \"...\",\n" + " \"relations\": [...]\n" + "}\n\n" + "⚠️ Пожалуйста, обратите внимание: \n" + "1. Все имена полей должны быть заключены в двойные кавычки (стандартный формат JSON).\n" + "2. Не добавляйте символы комментариев, дополнительные пояснения или символы markdown.\n" + "3. Возвращайте только полный объект JSON, не массив и не другой формат.\n" + "4. Если нет содержимого для заполнения, используйте пустой массив [] или пустую строку \"\".\n" + ) + }, + { + "role": "user", + "content": ( + f"Имя персонажа: {character_name}\n" + f"Текущие незавершенные события следующие (JSON):\n{json.dumps(unfinished_events, ensure_ascii=False, indent=2)}\n\n" + f"Фрагмент романа следующий: \n{paragraph}\n\n" + "Пожалуйста, верните обновленную информацию о персонаже в указанном формате." + ) + } + ] +``` + +### 🔄 Алгоритм интеллектуального объединения данных + +Реализация отслеживания состояния событий и механизма инкрементного обновления: + +```python +def get_unfinished_events(memcube: dict): + """Получить список незавершенных событий - для контекстной непрерывности""" + return [event for event in memcube.get("events", []) if not event.get("if_completed", False)] + +def merge_events(old_events: list, new_events: list): + """Интеллектуальное объединение событий - обработка обновлений состояния и новых событий""" + event_dict = {e["event_id"]: e for e in old_events} + + for new_event in new_events: + eid = new_event["event_id"] + if eid in event_dict: + # Стратегия объединения: новые поля имеют приоритет, сохраняем историческую информацию + merged = event_dict[eid].copy() + for key, value in new_event.items(): + if value not in [None, "", []]: + merged[key] = value + event_dict[eid] = merged + else: + event_dict[eid] = new_event # Новое событие добавляется напрямую + + return list(event_dict.values()) + +def merge_unique_list(old: list, new: list): + """Список Удаления Дубликатов - Сохранение Исходного Порядка""" + combined = old + new + seen = set() + result = [] + for item in combined: + if isinstance(item, dict): + key = json.dumps(item, sort_keys=True, ensure_ascii=False) + else: + key = str(item) + if key not in seen: + seen.add(key) + result.append(item) + return result +``` + +### ⚡ Двигатель параллельной обработки + +Использование пула потоков для эффективного пакетного обновления персонажей: + +```python +# Параллельное Обновление Всех Статусов Персонажей +with ThreadPoolExecutor(max_workers=8) as executor: + futures = { + executor.submit(update_memcube_for_character, name, memcube, content, chapter_id): name + for name, memcube in memcubes.items() + } + + for future in as_completed(futures): + name = futures[future] + try: + name, updated, error = future.result() + if error or not updated: + print(f"⚠️ Обновление Неудачно: {name} в {chapter_id} -> {error}") + continue + + # Умное Объединение Результатов Обновления + memcube = memcubes[name] + memcube["events"] = merge_events(memcube["events"], updated.get("events", [])) + memcube["utterances"].extend(updated.get("utterances", [])) + if updated.get("speech_style"): + memcube["speech_style"] = updated["speech_style"] + memcube["personality_traits"] = merge_unique_list( + memcube["personality_traits"], updated.get("personality_traits", []) + ) + if updated.get("emotion_state"): + memcube["emotion_state"] = updated["emotion_state"] + memcube["relations"].extend(updated.get("relations", [])) + + except Exception as e: + print(f"⚠️ Исключение Параллельного Выполнения: {name} -> {e}") +``` + +--- + +## Рецепт 3.3: Интеллектуальная система вывода на основе памяти + +### 🎯 Цель + +Реализация продвинутых функций, таких как вывод сюжета, оценка разумности и анализ эмоций на основе построенного MemCube. + +### 🔮 Двигатель вывода сюжета + +Использование полной информации о памяти персонажей для прогнозирования развития истории: + +```python +@staticmethod +def speculate_event_outcome(character_name: str, memcube: dict, user_input: str): + """На Основе Памяти Персонажей - Генерация Наративов В Стиле Романа""" + return [ + { + "role": "system", + "content": ( + "Вы Эксперт По Генерации Сценариев Романов.\n" + "Вы Получите Полную JSON Информацию О Всех Персонажах (Включая Цепочки Событий, Характер, Эмоции, Отношения И Т.Д.) И Гипотетический Сюжет, Предложенный Пользователем.\n" + "Ваша Задача - На Основе Фона Персонажей, Невыполненных Событий, Сетей Отношений, Характера И Мотивации, Обоснованно Предсказать Возможное Развитие Сюжета.\n" + "Пожалуйста, Сгенерируйте Полный Наратив В Стиле Романа (Не Список, Не JSON), Описывающий Как Развивается История.\n" + "Обратите Внимание, Что Языковой Стиль Должен Соответствовать Исходному Роману (Например, Классический Ушу Стиль)." + ) + }, + { + "role": "user", + "content": ( + f"Имя Персонажа: {character_name}\n\n" + f"Информация О Персонаже Ниже (Формат JSON):\n{json.dumps(memcube, ensure_ascii=False, indent=2)}\n\n" + f"Гипотетический Сюжет Пользователя Ниже: \n{user_input}\n\n" + "Пожалуйста, На Основе Вышеуказанной Информации Предскажите Развитие Сюжета, Верните Наратив В Романном Стиле, Не Включая Никакого Объяснительного Языка Или JSON." + ) + } + ] + +@staticmethod +def evaluate_plot_reasonableness(character_name: str, memcube: dict, user_input: str): + """Анализ Обоснованности Сюжета - На Основе Логического Оценивания Персонажей""" + return [ + { + "role": "system", + "content": ( + "Вы являетесь экспертом по анализу обоснованности поведения персонажей романа.\n" + "Вы получите полную информацию о всех персонажах в формате JSON (включая цепочки событий, характер, эмоции, отношения и т.д.) и гипотетический сюжет, предложенный пользователем.\n" + "Ваша задача: \n" + "1. Оценить, соответствует ли данный сюжет логике поведения данного персонажа, его характеристикам, эмоциональному состоянию и текущему контексту.\n" + "2. Если не соответствует, укажите конкретные несоответствия и объясните причины.\n" + "3. Если соответствует, объясните его обоснованность и кратко опишите, как этот сюжет логично разворачивается.\n\n" + "Формат ответа: \n" + "- Оценка обоснованности: Обоснованно / Необоснованно / Условно обоснованно\n" + "- Объяснение анализа: Подробное объяснение, соответствует ли это мотивации персонажа, отношениям и контексту\n" + "- Рекомендации: При необходимости предложите изменения или более обоснованные альтернативные выражения\n\n" + "Пожалуйста, отвечайте кратко на китайском языке, не генерируйте текст романа или структуру JSON." + ) + }, + { + "role": "user", + "content": ( + f"Имя Персонажа: {character_name}\n\n" + f"Полная информация о всех персонажах представлена ниже (формат JSON):\n{json.dumps(memcube, ensure_ascii=False, indent=2)}\n\n" + f"Гипотетический сюжет, предложенный пользователем, выглядит следующим образом: \n{user_input}\n\n" + "Пожалуйста, оцените, соответствует ли этот сюжет текущему состоянию и логике данного персонажа, и объясните причины." + ) + } + ] +``` + +### 🎭 Многомерная аналитическая структура + +Предоставление профессиональных аналитических инструментов, таких как отслеживание эмоций, прогресс конфликтов, оценка позиций и т.д.: + +```python +@staticmethod +def emotion_trajectory_prompt(character_name: str, memcube: dict, user_input: str): + """Анализ Эмоциональной Траектории - Прогноз Изменения Эмоций Персонажа""" + return [ + { + "role": "system", + "content": ( + "Ты - эксперт по анализу эмоциональной траектории персонажей.\n" + "Ты получишь полную информацию о персонаже (включая события, характер, эмоции, отношения и т.д.) и предполагаемый пользователем сюжет.\n" + "Пожалуйста, оцени, произойдут ли изменения в эмоциях персонажа в данном сюжете.\n\n" + "Ваша задача: \n" + "1. Определи, содержит ли предполагаемый сюжет изменения эмоций.\n" + "2. Если да, укажи тип эмоции и объясни, как это изменение было вызвано.\n" + "3. Если нет, объясни, почему эмоции остаются стабильными.\n\n" + "Формат ответа: \n" + "- Изменение эмоций: есть / нет\n" + "- Текущие эмоции: xxx\n" + "- Причина изменения: xxx\n" + "Пожалуйста, отвечай кратко на китайском языке." + ) + }, + { + "role": "user", + "content": ( + f"Имя Персонажа: {character_name}\n\n" + f"Полная информация о персонаже следующая (JSON):\n{json.dumps(memcube, ensure_ascii=False, indent=2)}\n\n" + f"Предполагаемый пользователем сюжет следующий: \n{user_input}" + ) + } + ] + +@staticmethod +def conflict_progression_prompt(character_name: str, memcube: dict, user_input: str): + """Анализ Эволюции Конфликта - Отслеживание Развития Противоречий Между Персонажами""" + return [ + { + "role": "system", + "content": ( + "Ты - эксперт по анализу эволюции противоречий между персонажами.\n" + "Вы получите полную информацию о персонаже (в формате JSON) и предложенный пользователем сюжет.\n" + "Пожалуйста, определите, включает ли этот сюжет развитие конфликта с другими.\n\n" + "Ваша задача: \n" + "1. Определите, включает ли предложенный сюжет существующие или потенциальные объекты конфликта.\n" + "2. Если да, пожалуйста, определите, изменились ли эти отношения (например, обострились, смягчились или разрешились).\n" + "3. Кратко опишите причины изменения конфликта.\n\n" + "Формат ответа: \n" + "- Противник: xxx\n" + "- Текущая стадия: xxx (например: потенциальный → обострение → смягчение → разрешение)\n" + "- Причина изменения: xxx\n" + "Пожалуйста, отвечай кратко на китайском языке." + ) + }, + { + "role": "user", + "content": ( + f"Имя Персонажа: {character_name}\n\n" + f"Полная информация о персонаже следующая (JSON):\n{json.dumps(memcube, ensure_ascii=False, indent=2)}\n\n" + f"Предполагаемый пользователем сюжет следующий: \n{user_input}" + ) + } + ] +``` + +### 💡 Примеры Практического Применения + +```python +# Загрузка уже построенной базы данных персонажей +with open("memcubes1.json", "r", encoding="utf-8") as f: + memcubes = json.load(f) + +character_name = "段誉" +user_input = "Что произойдет, если段誉 не появится на турнире в剑湖宫?" + +# Выполнение сюжетной симуляции +prompt = Prompt.speculate_event_outcome(character_name, memcubes[character_name], user_input) +response = api_client.call_api(prompt, TaskType.EVENT_EXTRACTION) +print(response.get("content", "❌ Нет ответа")) +``` + +--- + +## Рецепт 3.4: Оптимизация Конфигурации Модели Embedding + +### 🔄 Переключение Модели Embedding для Поиска Текстов на Китайском Языке + +**Объяснение Причин Переключения:** + +Исходный код использует модель nomic-embed для векторизации текста, но эта модель в основном оптимизирована для английского текста и имеет следующие проблемы при обработке китайских романов: + +1. **Ограниченные возможности понимания китайской семантики**: модель nomic-embed-text в основном обучена на английском корпусе, что делает её слабой в понимании семантики китайского языка и захвате текстовых отношений +2. **Недостаточная точность поиска**: при поиске персонажей, событий и отношений в китайских романах, таких как «Тяньлунь Бадэ», вычисление семантической схожести недостаточно точно +3. **Отсутствие культурного контекста**: не может хорошо понимать специфические контексты, такие как боевые искусства, история и культура в китайских литературных произведениях + +**Рекомендуемая Замена:** + +Согласно [Mem0 официальной документации](https://docs.mem0.ai/components/embedders/models/openai) и [оценке моделей встраивания на китайском языке](https://github.com/wangyuxinwhy/uniem), рекомендуется следующая конфигурация: + +#### Вариант 1: OpenAI Embedding (Рекомендуется) + +```python +config = { + "embedder": { + "provider": "openai", + "config": { + "model": "text-embedding-3-large", # Поддерживает несколько языков, отличный результат на китайском + "embedding_dims": 3072, + "api_key": "YOUR_OPENAI_API_KEY" + } + } +} +``` + +**Преимущества:** + +- Поддержка двуязычного поиска, выдающиеся результаты в задачах поиска текстов на китайском языке +- Более высокая размерность векторов (3072), более богатое семантическое представление +- Хорошие результаты в оценке MTEB-zh + +#### Вариант 2: Модель M3E (Открытая Альтернатива) + +```python +config = { + "embedder": { + "provider": "huggingface", + "config": { + "model": "moka-ai/m3e-base", # Открытая модель, оптимизированная для китайского языка + "embedding_dims": 768 + } + } +} +``` + +**Преимущества:** + +- Специально обучена для китайского языка, превосходит OpenAI ada-002 в задачах классификации и поиска текстов на китайском языке +- Поддержка гетерогенного поиска текстов, подходит для поиска отношений между персонажами и событий +- Полностью открытый исходный код, без затрат на вызовы API + +#### Вариант 3: Локальное Развертывание + +```python +config = { + "embedder": { + "provider": "ollama", + "config": { + "model": "moka-ai/m3e-base", + "ollama_base_url": "http://localhost:11434" + } + } +} +``` + +**Данные Сравнения Производительности:** + +Согласно [MTEB-zh评测](https://github.com/wangyuxinwhy/uniem) результатам: + +| Модель | Точность Классификации Китайского Текста | Китайский Поиск ndcg@10 | Преимущество | +| ----------------------------- | ------------------ | ---------------- | ---------- | +| nomic-embed | Не Тестировалось | Не Тестировалось | Оптимизация Для Английского | +| OpenAI text-embedding-3-large | 0.6231 | 0.7786+ | Поддержка Многоязычности | +| M3E-base | 0.6157 | 0.8004 | Специализация На Китайском | + +--- + +## Рецепт 3.5: Преобразователь Структуры Memory Графа + +### 🎯 Цель + +Преобразовать данные MemCube в формат узлов Memory, совместимый с MemOS, для построения запрашиваемой базы знаний. + +### 🏗️ Генерация Узлов Memory + +Преобразовать события и отношения персонажей в стандартизированные объекты Memory: + +```python +def create_memory_node(content: str, entities: list, key: str, memory_type: str = "fact") -> dict: + """Создание Стандартизированного Узла Памяти""" + node_id = str(uuid.uuid4()) + now = datetime.now().isoformat() + + # Симуляция встраивания (в реальном применении следует использовать настоящие сервисы встраивания) + embedding = [0.1] * 768 # Пример Размерности + + return { + "id": node_id, + "memory": content, + "metadata": { + "user_id": "", + "session_id": "", + "status": "activated", + "type": "fact", + "confidence": 0.99, + "entities": entities, + "tags": ["событие"] if "событие" in key else ["отношение"], + "updated_at": now, + "memory_type": memory_type, + "key": key, + "sources": [], + "embedding": embedding, + "created_at": now, + "usage": [], + "background": "" + } + } +``` + +### 🔄 Пакетная Обработка Преобразования + +Реализовать эффективный конвейер преобразования от MemCube к Memory: + +```python +INPUT_FILE = "memcube_all.json" +OUTPUT_FILE = "memory_graph.json" + +with open(INPUT_FILE, "r", encoding="utf-8") as f: + memcube_data = json.load(f) + +nodes = [] +edges = [] + +for character, data in memcube_data.items(): + previous_event_id = None + + # === Преобразование Последовательности Событий === + for event in data.get("events", []): + memory_text = f"{character} в {event.get('time')} в {event.get('location')},потому что {event.get('motivation')},выполнил {event.get('action')},результат: {event.get('impact')}。" + entities = [character] + event.get("involved_entities", []) + node = create_memory_node( + content=memory_text, + entities=entities, + key=f"Событие {character}: {event.get('action')}" + ) + nodes.append(node) + + # Установление Хронологической Связи Событий + if previous_event_id: + edges.append({ + "source": previous_event_id, + "target": node["id"], + "type": "FOLLOWS" + }) + previous_event_id = node["id"] + + # === Агрегация Сетей Отношений === + relations_texts = [] + seen = set() + for relation in data.get("relations", []): + name = relation.get("name") or relation.get("人物") or relation.get("character") + relation_text = relation.get("relation") or relation.get("relationship") or relation.get("отношение") + if not name or not relation_text: + continue + dedup_key = (str(name), str(relation_text)) + if dedup_key in seen: + continue + seen.add(dedup_key) + relations_texts.append(f"С{name} является {relation_text}") + + if relations_texts: + memory_text = f"{character}" + ",".join(relations_texts) + "。" + entities = [character] + node = create_memory_node( + content=memory_text, + entities=entities, + key=f"Сводка отношений {character}", + ) + nodes.append(node) + +# Сохранить результаты преобразования +with open(OUTPUT_FILE, "w", encoding="utf-8") as f: + json.dump({ + "nodes": nodes, + "edges": edges + }, f, ensure_ascii=False, indent=2) + +print(f"✅ Преобразование завершено, всего сгенерировано {len(nodes)} узлов памяти, {len(edges)} ребер") +print(f"📁 Выходной файл: {OUTPUT_FILE}") +``` + +--- + +## Рецепт 3.5: Интеграция MemOS и Проверка Запросов + +### 🎯 Цель + +Интегрировать преобразованные данные Memory в систему MemOS для реализации семантического интеллектуального поиска. + +### 🔗 Коннектор MemOS + +Установить стабильное соединение с сервисом MemOS: + +```python +import memos +from memos.configs.embedder import EmbedderConfigFactory +from memos.configs.memory import TreeTextMemoryConfig +from memos.configs.mem_reader import SimpleStructMemReaderConfig +from memos.embedders.factory import EmbedderFactory +from memos.mem_reader.simple_struct import SimpleStructMemReader +from memos.memories.textual.tree import TreeTextMemory +from memos.configs.mem_os import MOSConfig + +# Загрузить MemOS конфигурацию +config = TreeTextMemoryConfig.from_json_file("/root/Test/memos_config.json") +tree_memory = TreeTextMemory(config) + +# Загрузить данные памяти +tree_memory.load("/root/Test") + +# Выполнить семантический поиск +results = tree_memory.search("段誉初遇神仙姐姐", top_k=5) + +for result in results: + relativity = result.metadata.relativity if hasattr(result.metadata, 'relativity') else 0.0 + print(f"Степень сходства: {relativity:.3f}") + print(f"Содержимое: {result.memory}") + print("---") +``` + +### 🔍 Проверка Интеллектуального Поиска + +Проверить производительность системы через многомерные запросы: + +```python +# Тестирование запросов нескольких типов +test_queries = [ + "段誉初遇神仙姐姐", + "乔峰的身世之谜", + "Приключения Сюй Чжу" + "Вражда Динь Чуньцю и У Яцзы" +] + +for query in test_queries: + print(f"\n🔍 Запрос: {query}") + results = tree_memory.search(query, top_k=3) + + for i, result in enumerate(results, 1): + relativity = result.metadata.relativity if hasattr(result.metadata, 'relativity') else 0.0 + print(f" {i}. Степень Соответствия: {relativity:.3f}") + print(f" Содержимое: {result.memory[:100]}...") +``` + +--- + +## 🎯 Креативные Расширения на Основе MemOS + +Поздравляем! Вы уже освоили основные технологии MemOS. Теперь давайте посмотрим, какие захватывающие приложения можно создать: + +### 🕰️ Идея 1: Интеллектуальная Система Хронологии Мира + +Создание динамической хронологии мира боевых искусств на основе MemOS, позволяя ИИ понимать причинно-следственные связи событий: + +```python +# Пример: Умное Управление Временной Линией +timeline_memory = { + "1094 год": { + "события": ["Разгадка Тайны Происхождения Сяо Фэна", "Битва в Юй Сянь Чжуан"], + "последствия": ["Сотрясение Рынка", "Раскол Братства"], + "затронутые_персонажи": ["Сяо Фэн", "А Чжу", "Дуан Чжэнчунь"] + }, + "1095 год": { + "события": ["Истина Инцидента у Врат Ганмэнь", "Смерть А Чжу"], + "последствия": ["Изменение Духовного Состояния Сяо Фэна", "Напряженные Отношения между Сун и Ляо"] + } +} + +# ИИ может ответить: Что произойдет, если Сяо Фэн не пойдет к Вратам Ганмэнь? +``` + +### 🧠 Идея 2: Динамический Фон Рабочей Памяти + +Использование функции рабочей памяти MemCube для обновления фона мира в реальном времени по мере развития сюжета: + +```python +# Пример: Управление Динамическим Состоянием Мира +from memos.memories.textual.base import TextualMemoryItem + +# Создание Элемента Памяти Мирового Состояния +world_state_memories = [ + TextualMemoryItem( + memory="Степень политической напряженности между Сун и Ляо достигла 0.8, частые пограничные конфликты", + metadata={"type": "world_state", "category": "politics"} + ), + TextualMemoryItem( + memory="Текущие легендарные боевые искусства в мире: Цзюянь Шэньгун, Ицзин Цзин", + metadata={"type": "world_state", "category": "martial_arts"} + ), + TextualMemoryItem( + memory="Шаолинь и Удань сохраняют нейтралитет, внутри Братства Бедняков происходят расколы", + metadata={"type": "world_state", "category": "sect_relations"} + ) +] + +# Использование Управления Памятью Текста MemCube для Мирового Состояния +mem_cube.text_mem.replace_working_memory(world_state_memories) + +# Автоматическое обновление рабочей памяти, когда Сяо Фэн принимает важные решения +current_working_memory = mem_cube.text_mem.get_working_memory() +``` + +### 🎮 Идея 3: Интерактивная Текстовая Игра на Основе MemOS + +**Конечная Идея**: Создание поистине интеллектуальной одиночной текстовой приключенческой игры на основе MemOS + MemCube + GPT-4o! + +```python +# Пример Основной Архитектуры Игры +class WuxiaTextGame: + def __init__(self, mos_config): + from memos.mem_os.main import MOS + + self.world_memory = MOS(mos_config) # Система Памяти Мира + self.character_cubes = {} # MemCube для каждого NPC + self.timeline_memories = [] # Список Воспоминаний Временной Линии + + # Создание Основного Пользователя Игры + self.world_memory.create_user("game_master") + + def start_adventure(self, player_choice): + """ + Выбор Игрока: + - Персонаж: Сяо Фэн/Дуань Юй/Сюй Чжу/Созданный Персонаж + - Временной Пункт: Детство/Юность/Средний Возраст + - Место: Центральная Равнина/Дали/Ляо + """ + return f"Добро пожаловать в {player_choice.location}..." + + def process_action(self, player_input): + """ + Обработка естественного языка игрока: + "Я хочу пойти в Шаолинь учиться боевым искусствам" + "Я хочу стать братом с Сяо Фэнем" + "Я хочу остановить резню у Яньмэньгуань" + """ + # 1. Понять намерения игрока (используя функции LLM MemOS) + intent_analysis = self.world_memory.chat( + query=f"Анализировать намерения игрока: {player_input}", + user_id="game_master" + ) + + # 2. Извлечь соответствующую память + context = self.world_memory.search( + query=player_input, + user_id="game_master" + ) + + # 3. Рассчитать последствия действий (на основе извлеченного контекста) + consequences = self.predict_consequences(player_input, context) + + # 4. Обновить состояние мира (добавить новую память) + self.update_world_state(player_input, consequences) + + # 5. Сгенерировать развитие сюжета + return self.generate_story(player_input, context, consequences) + + def predict_consequences(self, player_input, context): + """Предсказать последствия действий игрока""" + query = f"На основе следующего контекста: {context}, предсказать возможные последствия действия игрока '{player_input}'" + result = self.world_memory.chat( + query=query, + user_id="game_master" + ) + return result + + def update_world_state(self, player_input, consequences): + """Обновить состояние мира в памяти MemOS""" + memory_content = f"Действие игрока: {player_input}, Последствия: {consequences}" + self.world_memory.add( + memory_content=memory_content, + user_id="game_master" + ) + + def generate_story(self, player_input, context, consequences): + """Генерация Развития Истории""" + query = f"На основе фона {context} и последствий {consequences}, сгенерировать интересное развитие истории для действия игрока '{player_input}'" + return self.world_memory.chat( + query=query, + user_id="game_master" + ) + +# Полный Пример Использования +def create_wuxia_game(): + """Создание Полного Примера Ролевой Игры В Стиле Уся""" + from memos.configs.mem_os import MOSConfig + + # Создание Конфигурации MemOS + mos_config = MOSConfig( + user_id="game_system", + chat_model={ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o", + "api_key": "YOUR_API_KEY", + "api_base": "https://api.openai.com/v1" + } + }, + mem_reader={ + "backend": "simple_struct", + "config": { + "llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o", + "api_key": "YOUR_API_KEY", + "api_base": "https://api.openai.com/v1" + } + } + } + }, + enable_textual_memory=True + ) + + # Создание Экземпляра Игры + game = WuxiaTextGame(mos_config) + + # Пример Диалога + response = game.process_action("Я хочу найти Сяо Фэна в гостинице Лояна") + print(response) + + return game +``` + +**Примеры Игрового Процесса:** + +``` +Игрок: Я юный новичок, хочу навестить Сяо Фэна +ИИ: В то время Сяо Фэн расследовал тайну своего происхождения в районе Лояна, и вы случайно встретили его в гостинице... + Сяо Фэн, увидев вас молодым, спросил: "Младший брат, почему ты еще бродишь на улице так поздно?" + +Игрок: Я сказал ему, что хочу изучить боевые искусства и прошу его взять меня в ученики +ИИ: Сяо Фэн громко засмеялся: "Моя собственная судьба - это сплошная загадка, как я могу быть учителем? + Но раз уж мы встретились, это судьба, я могу научить тебя несколько приемов для самозащиты..." + [Ваш Уровень Боевых Искусств +1, Отношение Со Сяо Фэном +5] + +Игрок: Я хочу рассказать Сяо Фэну правду о его происхождении +ИИ: Это опасный выбор! Раннее раскрытие происхождения может изменить весь ход истории... +Вы уверены, что хотите это сделать? Это откроет совершенно новую сюжетную ветвь. +``` + +### 🌟 Ваше Воображение — Это Граница! + +На основе MemOS вы можете создать: + +- 📚 **Интеллектуальный Генератор Романов** - ИИ автоматически создает на основе ваших установок +- 🎭 **Виртуальные Персонажи Компаньоны** - Ведите реальные диалоги с Сяо Фэнем, Дуань Юем +- 🎨 **Интерактивное Создание Сюжета** - Динамически генерируемый мир истории +- 🎯 **Образовательная Игровая Платформа** - Учитесь истории и литературе в игре +- 🔮 **Прогностическое Развлечение** - ИИ предсказывает, как ваши выборы повлияют на сюжет + +**Ключевое Внимание:** MemOS дает ИИ настоящую "память", позволяя: + +- 🧠 Запоминать все исторические события и отношения между персонажами +- 🔄 Динамически обновлять состояние мира в зависимости от действий игрока +- 🎯 Генерировать логически последовательное развитие сюжета +- 🌟 Создавать бесконечные возможности для ветвления истории + +--- + +## 🎮 Испытайте Прямо Сейчас: Демонстрация Интерактивной Текстовой Игры + +Хотите лично испытать текстовую игру, созданную на основе MemOS? Мы предоставили полный демонстрационный проект, показывающий, как применить технологии, представленные в этой главе, к реальному интерактивному текстовому генератору. + +### 📦 Особенности Демонстрации + +- **🎯 На Основе "Тяньлунь Ба Бу"**: Используйте тот же контент романа, обработанный в этой главе, в качестве базы знаний +- **🔍 Умное Определение Намерений**: Автоматически определяет тип операции, которую хочет выполнить пользователь +- **💬 Разнообразные Режимы Взаимодействия**: Поддержка продолжения истории, анализа персонажей, гипотетических сюжетов, диалогов персонажей и т.д. +- **🧠 Управление MemOS**: Демонстрация реального поиска MemCube и генерации контекста + +### 🚀 Попробуйте Прямо Сейчас + +**👉 [MemCube Interactive Text Game Demo - Hugging Face](https://huggingface.co/datasets/MemCube/interactive-text-game-demo)** + +Этот демонстрационный проект включает в себя: +- ✅ **Полный Исходный Код**: Демонстрация реального использования различных компонентов MemOS +- ✅ **Руководство по Запуску**: Пошаговое руководство по развертыванию и запуску +- ✅ **Техническое Описание**: Подробное объяснение принципов реализации и проектирования +- ✅ **Настраиваемый**: Можно заменить на ваш собственный текстовый контент + +Работая с этим демо, вы глубже поймете, как технологии MemOS, представленные в этой главе, работают в реальных приложениях! + +**Теперь освободите свою креативность и создайте свой умный мир с MemOS!** 🚀 diff --git a/content/ru/open_source/cookbook/chapter4/overview.md b/content/ru/open_source/cookbook/chapter4/overview.md new file mode 100644 index 00000000..12ca40b8 --- /dev/null +++ b/content/ru/open_source/cookbook/chapter4/overview.md @@ -0,0 +1,3576 @@ +--- +title: Использование MemOS для построения производственной системы вопросов и ответов на основе знаний +--- +## **Введение** + +При построении системы вопросов и ответов (QA) в определенной области отрасль сталкивается с общей проблемой: хотя большие языковые модели (LLM) обладают обширными знаниями, их точность и надежность в специализированных областях все еще недостаточны; традиционные методы генерации с улучшением поиска (RAG), хотя и могут вводить внешние знания, ограничены дискретностью документов и отсутствием глубокой логической связи, что затрудняет решение сложных вопросов и ответов. + +Цель этой главы — показать, как решить эту проблему на основе MemOS и предложить и реализовать полный демонстрационный проект по улучшению знаний для производства. Наша основная цель — доказать и реализовать ключевое утверждение: с помощью структурированной системы знаний маленькая модель, тщательно улучшенная, может превзойти неулучшенную большую модель в своей профессиональной способности. + +Для достижения этой цели мы разработали и построили динамическую систему знаний под названием MemCube. Процесс его создания следует строгой инженерной методологии: + +**Извлечение и структурирование скрытых знаний**: Сначала мы систематически извлекаем скрытые знания о конкретной области из больших языковых моделей (LLM) и с помощью метода "итеративного расширения концептуальной карты" преобразуем их в масштабную, высокопокрывающую явную карту концептуальных отношений. + +**Генерация структурированных пар знаний**: Затем мы используем эту концептуальную карту в качестве руководства и снова применяем LLM для генерации большого количества высококачественных пар вопросов и ответов (QA) с сложной клинической логикой, которые станут основным содержанием базы знаний. + +**Создание и развертывание базы знаний**: В конечном итоге мы организуем эти пары QA и загружаем их в графовую базу данных (Neo4j), создавая динамическую базу знаний (MemCube), которая может эффективно извлекаться системой MemOS для улучшения возможностей маленькой модели в данной области. + +Эта глава полностью продемонстрирует процесс создания MemCube с нуля на примере области кардиологии и с помощью количественной оценки подтвердит значительный эффект этой системы в повышении профессиональных способностей модели в вопросах и ответах, предоставляя повторяемый стандартный процесс для реализации недорогих, высокоточных и объяснимых AI-сервисов знаний в реальном бизнесе. + +--- + +## **Введение в главу: План построения динамической системы знаний** + +Основная исследовательская цель этой главы — подтвердить, что путем систематического построения базы знаний MemOS (то есть MemCube) модель с относительно небольшим количеством параметров (например, уровня 7B) может достичь или даже превзойти уровень производительности больших моделей (например, уровня 32B+). + +Эта глава проведет вас через полный практический процесс знаний. Наша конечная цель — создать интеллектуальную систему вопросов и ответов, специально предназначенную для области кардиологии. Для достижения этой цели мы будем следовать четкому, поэтапному пути, где каждый шаг будет основываться на результатах предыдущего. + +Общая структура этой главы выглядит следующим образом: + +### **Первый этап: Построение базовой структуры знаний в области — Расширение концептуальной карты** + +Это основа всей работы. Высококачественная база знаний начинается с всеобъемлющей и структурированной сети концепций в области, которая является явным выражением скрытых знаний этой области. + +**Цель**: Создать масштабную карту, которая будет широко охватывать основные концепции кардиологии и их взаимосвязи. + +**Получение начальных концепций**: Мы отбираем материалы из специализированных медицинских наборов данных в области кардиологии и с помощью LLM предварительно извлекаем набор высококачественных "начальных концепций", которые станут отправной точкой для карты. + +**Итеративное расширение**: На основе начальных концепций мы с помощью многократных автоматизированных процессов позволяем LLM ассоциировать новые связанные концепции на основе уже существующих в карте и устанавливать связи. + +**Схлопывание и оценка**: Мы вводим строгие механизмы контроля схлопывания (например, объединение схожих узлов, мониторинг темпов роста новых концепций), чтобы гарантировать, что карта прекращает расти, когда достигает достаточного уровня охвата знаний. В конечном итоге мы количественно оцениваем целостность нашей карты, сравнивая ее с ключевыми словами из внешних источников знаний. + +### **Второй этап: Генерация применимого содержимого знаний — Генерация пар QA на основе карты** + +С концептуальной картой как базовой структурой, нам необходимо заполнить ее конкретными знаниями, которые могут быть непосредственно поняты и использованы ИИ, а именно вопросами и ответами. + +**Цель**: Преобразовать абстрактные концепции и отношения в графе в большое количество конкретных QA пар, содержащих клиническую логику. + +**Генерация знаний по отдельным концепциям**: Обойти каждый узел ключевой концепции в графе и использовать LLM для генерации независимых, глубоких клинических вопросов и ответов для каждой концепции. + +**Генерация связанных знаний**: Для "пар концепций", которые связаны в графе, мы позволяем LLM генерировать более сложные вопросы о взаимосвязи, которые отражают внутреннюю логику обеих. + +### **Третий Этап: Сборка и Развертывание Базы Знаний — Построение и Монтирование MemCube** + +Дискретные данные QA необходимо организовать в эффективную систему. + +**Цель**: Структурировать все сгенерированные данные QA и загрузить их в графовую базу данных, чтобы сформировать базу знаний, которая может быть вызвана MemOS в любое время. + +**Процесс**: + +**Форматирование данных**: Мы унифицируем все QA пары в стандартный формат JSON и генерируем векторные встраивания (Embedding) для текстов вопросов, используемых для поиска. + +**Импорт в графовую базу данных**: Написать скрипт для пакетного и эффективного импорта отформатированных узлов (концепции, QA) и ребер (отношения) в базу данных Neo4j. + +**Монтаж MemOS**: Наконец, с помощью простой конфигурации мы укажем систему MemOS на эту базу данных Neo4j, официально активируя наш кардиологический MemCube. + +### **Четвертый Этап: Проверка Итоговых Результатов — Оценка Системы** + +После завершения сборки нам необходимо использовать объективные данные, чтобы доказать ее ценность. + +**Цель**: Качественно оценить меньшую модель, оснащенную MemCube, по сравнению с неусиленной моделью, чтобы определить, достигла ли она превосходства в профессиональных вопросах и ответах. + +**Процесс**: Мы создадим независимый набор для оценки, с помощью автоматизированных скриптов проведем "соревнование по одинаковым вопросам" между моделями с различными конфигурациями, а более мощная модель будет выступать в роли судьи для оценки, в конечном итоге используя процент побед и баллы для демонстрации фактической эффективности нашей системы. + +С помощью вышеуказанных четырех этапов вы четко увидите, как абстрактная бизнес-задача шаг за шагом с помощью строгих инженерных методов в конечном итоге превращается в мощную, оценимую AI систему знаний. +------------------------------------------------------------------------------------------------------------------------------ + +## **Построение и Расширение Концептуальной Карты Области** + +### **Цель** + +Преобразовать неструктурированные знания в определенной области в высококачественный, структурированный набор начальных концепций, что является основой для построения интеллектуального MemCube. + +### **Основная Идея** + +В профессиональных сценариях вопросов и ответов данные для обучения крупных языковых моделей (LLM) уже содержат огромное количество знаний в области. Проблема заключается в том, как систематически "извлечь" и "организовать" эти знания, чтобы специализированный, малый MemCube в данной области обладал знаниями, сопоставимыми с большими моделями. + +Прямо спрашивать LLM "Пожалуйста, предоставьте все знания в области кардиологии" неэффективно и непрактично. Поэтому мы должны установить ряд точных **"концептуальных якорей"**, на основе которых систематически очертить карту знаний LLM о данной области. Хотя охват знаний в области трудно количественно оценить, мы можем косвенно измерить его полноту через ключевые концепции и ключевые слова в области. Конечная цель этого этапа — максимально полно захватить концепции области, чтобы предоставить структурированную поддержку для последующего извлечения знаний. + +--- + +### **Шаг 1: Получение Начальных Концепций** + +Построение графа начинается с получения группы высококачественных "начальных концепций". Эти начальные концепции являются отправной точкой для итеративного расширения графа, и их качество напрямую влияет на скорость и эффективность построения модели знаний в области. + +Чтобы обеспечить профессионализм и охват начальных концепций, в этом эксперименте используется открытый набор данных тестовых вопросов медицинских экспертов `medxpert` в качестве начального источника данных. Этот набор данных содержит четкие классификации в области медицины, что позволяет нам точно отбирать соответствующие знания в области кардиологии. + +Искренне благодарим: MedXpert открытый Benchmark + +Ссылка для загрузки данных: https://raw.githubusercontent.com/TsinghuaC3I/MedXpertQA/refs/heads/main/eval/data/medxpertqa/input/medxpertqa_text_input.jsonl + +Следующий код демонстрирует процесс загрузки и фильтрации данных. + +```python +import os +os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' +os.environ['HUGGINGFACE_HUB_URL'] = 'https://hf-mirror.com' +os.environ['HF_HUB_BASE_URL'] = 'https://hf-mirror.com' + +import glob +import pickle +import requests +import json +import time +from datetime import datetime +from concurrent.futures import ThreadPoolExecutor, as_completed +import torch +import uuid +import sys +import ijson +from decimal import Decimal +from neo4j import GraphDatabase +from collections import defaultdict +import numpy as np +from requests.adapters import HTTPAdapter +from urllib3.util.retry import Retry +from typing import Dict, List, Optional, Any +from dataclasses import dataclass +import re +from collections import Counter +import random +from sentence_transformers import SentenceTransformer +from json_repair import repair_json +``` + +Мы согласуем следующие переменные окружения: + +```python +# api url; api key является вашим личным настроением +# Для конкретного используемого llm модели: +# 1. На этапе обобщения seed concepts мы используем мощную модель MEDXPERT_THINKER=o3 для расширения более чем 100 вопросов в области сердечно-сосудистой медицины, извлекая процесс анализа вопросов. Наша цель не в том, чтобы o3 правильно отвечал на каждый вопрос, а в том, чтобы после анализа каждого сердечно-сосудистого вопроса, его процесс мышления обобщал seed концепции в области сердечно-сосудистой медицины. +# 2. После извлечения мыслительного процесса o3 мы используем MEDXPERT_THINK_EXTRACTOR=gpt-4o для извлечения названий сердечно-сосудистых концепций в качестве seed концепций +# Для вышеуказанных двух этапов наша цель состоит в создании библиотеки seed концепций; если у вас есть ваша собственная библиотека документов в вашей области, вы можете пропустить этот этап и напрямую извлечь интересующие вас seed концепции из ваших документов. +# 3. После завершения создания библиотеки seed концепций мы проведем расширение концептуальной карты области. На этом этапе мы рекомендуем выбирать вашу модель в зависимости от наших экспериментальных результатов и вашего бюджета. На этапе наших испытаний мы использовали CONCEPT_GRAPH_EXTENDER=gpt-4omini в качестве ориентира. +# 4. После завершения построения концептуальной карты области мы проведем (a) индивидуальную генерацию qa для каждого концепта (b) генерацию qa для каждой значимой пары концептов. Поскольку генерация qa зависит от возможностей модели, мы рекомендуем использовать мощную модель. На этапе наших экспериментов мы использовали QA_SYNTHESIZER=gpt-4o в качестве ориентира. +# Мы применяем английскую embedding модель EMBEDDING_MODEL=nomic-ai/nomic-embed-text-v1.5 ко всем используемым embedding моделям +api_url="your api url" +api_key="your api key" + +# Различные возможные модели: +MEDXPERT_THINKER = 'o3' +MEDXPERT_THINK_EXTRACTOR = 'gpt-4o' +CONCEPT_GRAPH_EXTENDER = 'gpt-4o-mini' +QA_SYNTHESIZER = 'gpt-4o' +EMBEDDING_MODEL = 'nomic-ai/nomic-embed-text-v1.5' +``` + +```python +# Извлечение seed концепций из последнего набора данных medxpert, его преимущество заключается в наличии соответствующего разделения по областям +import json +from collections import Counter + +data = [] +with open("medxpertqa_text_input.jsonl", "r", encoding="utf-8") as f: + for line in f: + data.append(json.loads(line.strip())) + +# Извлечение вопросов в области сердечно-сосудистой медицины +body_system_counts = Counter(entry["body_system"] for entry in data) +heart_data = [] +for i in range(len(data)): + if data[i]['body_system']=='Cardiovascular': + heart_data.append(data[i]) +``` + +Чтобы обеспечить стабильное и эффективное взаимодействие с API крупных языковых моделей, мы разработали модульный клиент API. Этот клиент интегрирует пул соединений, механизм автоматической повторной попытки на основе экспоненциальной задержки и контроль времени ожидания запросов, что обеспечивает надежность при высоком уровне параллельных вызовов. В то же время мы определили стандартизированную структуру данных (`AnalysisResult`), чтобы унифицировать хранение результатов запросов, что упрощает последующую обработку. + +```python + +@dataclass +class AnalysisResult: + """Анализ результатов данных""" + status: str # success, api_error + question_id: str + input_data: Dict + response: Optional[str] = None + error_details: Optional[str] = None + processing_time: Optional[float] = None + +class APIClient: + """Клиент API вызова""" + + def __init__(self, api_url: str, api_key: str, model_name: str): + self.api_url = api_url + self.api_key = api_key + self.model_name = model_name + + # Создание сессии и настройка пула соединений и стратегии повторных попыток + self.session = requests.Session() + + retry_strategy = Retry( + total=3, + backoff_factor=1, + status_forcelist=[500, 502, 503, 504], + ) + + adapter = HTTPAdapter(pool_connections=10, pool_maxsize=20, max_retries=retry_strategy) + self.session.mount('http://', adapter) + self.session.mount('https://', adapter) + + self.session.headers.update({ + "Content-Type": "application/json", + "Authorization": f"Bearer {self.api_key}" + }) + + def call_api(self, messages: List[Dict], timeout: int = 120) -> Dict: + """Вызов API""" + data = { + "model": self.model_name, + "messages": messages, + "stream": False + } + + try: + response = self.session.post(url=self.api_url, json=data, timeout=timeout) + response.raise_for_status() + result = response.json() + return { + "status": "success", + "content": result['choices'][0]['message']['content'] + } + except requests.exceptions.RequestException as e: + return { + "status": "error", + "error": str(e) + } + +``` + +Мы используем тщательно разработанный класс `PromptTemplate` для упаковки и генерации инструкций для взаимодействия с LLM. Этот шаблон задает роль LLM как опытного профессора клинической медицины и требует от него структурированного, систематического разбора и анализа медицинских вопросов. Такой структурированный вывод является ключом к последующему точному извлечению информации. + +```python + +class PromptTemplate: + """Класс шаблона подсказок""" + + @staticmethod + def get_system_prompt() -> str: + return """You are a world-renowned clinical professor at a top teaching hospital with over 20 years of experience. Your thinking is grounded in evidence-based medicine, characterized by rigorous logic and clear reasoning. + +Your core mission extends beyond solving clinical problems—you must **teach young doctors and medical students your decision-making process**. Therefore, when analyzing any case, you must: + +1. **Systematic Deconstruction**: Begin by breaking down the problem from a macro perspective, identifying core clinical contradictions and key information. +2. **Comprehensive Evaluation**: Provide independent and thorough analysis of all possibilities (including every option), without skipping any. +3. **Clear Reasoning**: Explicitly articulate the "because-therefore" logic behind each judgment, clearly stating which specific clinical indicators, guideline consensus, or pathophysiological principles your decisions are based on. +4. **Principle Extraction**: After analysis, skillfully distill complex individual case decision processes into reusable, instructive core principles. + +Your language should combine authority with clarity, enabling listeners to fully replicate your thought process.""" + + @staticmethod + def get_analysis_prompt(question_data: Dict) -> str: + question = question_data['question'] + options = question_data['options'] + + options_text = "" + for opt in options: + options_text += f"({opt['letter']}) {opt['content']}\n" + return f"""Analyze this cardiovascular medicine multiple-choice question systematically and select the SINGLE CORRECT ANSWER. Provide a comprehensive analysis that demonstrates expert clinical reasoning. + + **[Clinical Problem]** + --- + {question} + + Answer Choices: + {options_text} + --- + + + **[Analysis Structure]** + + **Part 1: Clinical Context Analysis** + + Begin by establishing the clinical foundation for this question: + + * **Clinical Scenario Identification**: What is the primary clinical situation being presented? (e.g., diagnostic workup, treatment decision, risk stratification, pathophysiology question, etc.) + + * **Key Clinical Elements**: What are the most important clinical details, patient characteristics, findings, or parameters mentioned in the question stem? Why are these details clinically significant? + + * **Question Focus**: What specific aspect of clinical medicine is this question testing? What clinical knowledge or decision-making skill is being assessed? + + * **Relevant Clinical Framework**: What established clinical guidelines, diagnostic criteria, or treatment algorithms are relevant to answering this question? + + **Part 2: Systematic Option Analysis** + + Now analyze each answer choice methodically: + + **Option (A): ** + * **Clinical Evaluation**: How does this option relate to the clinical scenario? What would be the clinical implications if this were the correct choice? + * **Evidence-Based Assessment**: Based on current guidelines, evidence, and pathophysiology, is this option clinically appropriate? Why or why not? + + **Option (B): ** + * **Clinical Evaluation**: [Same analysis format] + * **Evidence-Based Assessment**: [Same analysis format] + + [Continue this systematic analysis for each option through the last one] + + **Part 3: Final Answer and Clinical Synthesis** + + * **Clinical Summary**: Briefly synthesize the key clinical scenario from the question stem and the critical findings from my analysis of each option. + + * **Selected Answer**: Based on my systematic analysis, the correct answer is: **(Letter) [Brief restatement of the correct option]** + + * **Answer Justification**: Concisely explain why this is the best answer, focusing on the most compelling clinical evidence and reasoning. + + * **Option Comparison Summary**: Provide a brief comparative overview of why the chosen option is superior to the other alternatives, highlighting the key clinical distinctions. + + * **Clinical Teaching Point**: Detailedly summarize the essential clinical medicine principle demonstrated by this question as a practical clinical pearl. + + **CRITICAL REQUIREMENT**: End with a clear statement: "**FINAL ANSWER: (a [single] Letter, DO NOT GIVE DETAILED CONTENT IN OPTION)**" + + Begin your analysis now.""" +``` + +Чтобы связать вышеупомянутые компоненты, мы разработали два процессора. `CardioAnalysisProcessor` отвечает за обработку одного вопроса, он комбинирует Prompt, вызывает API и возвращает структурированные результаты. В то время как `BatchProcessor` использует пул потоков (`ThreadPoolExecutor`) для реализации высокопараллельной обработки, позволяя передавать все отобранные вопросы партиями и параллельно обрабатывать их с помощью `CardioAnalysisProcessor`, автоматически сохраняя результаты каждой партии. Этот дизайн является необходимой гарантией достижения производственной эффективности обработки данных. + +```python +# Извлечение процесса мышления llm для подготовки семенных концепций +class CardioAnalysisProcessor: + """Анализатор и обработчик сердечно-сосудистых проблем""" + + def __init__(self, api_client: APIClient): + self.api_client = api_client + self.template = PromptTemplate() + + def process_single_question(self, question_data: Dict, question_id: str) -> AnalysisResult: + """Обработка одной сердечно-сосудистой проблемы""" + start_time = time.time() + + # Формирование сообщения + system_prompt = self.template.get_system_prompt() + user_prompt = self.template.get_analysis_prompt(question_data) + + messages = [ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": user_prompt} + ] + + # Вызов API + api_result = self.api_client.call_api(messages, timeout=120) + processing_time = time.time() - start_time + + if api_result["status"] != "success": + return AnalysisResult( + status="api_error", + question_id=question_id, + input_data=question_data, + error_details=api_result["error"], + processing_time=processing_time + ) + + return AnalysisResult( + status="success", + question_id=question_id, + input_data=question_data, + response=api_result["content"], + processing_time=processing_time + ) + +class BatchProcessor: + """Пакетный обработчик""" + + def __init__(self, processor: CardioAnalysisProcessor, output_dir: str = "cardio_analysis"): + self.processor = processor + self.output_dir = output_dir + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + def process_questions_list(self, heart_data: List[Dict], max_workers: int = 10, + batch_size: int = 50, batch_delay: int = 1) -> Dict: + """Пакетная обработка сердечно-сосудистых проблем""" + total_questions = len(heart_data) + print(f"Начало пакетной обработки {total_questions} сердечно-сосудистых клинических проблем") + print(f"Размер партии: {batch_size}, Максимальное количество параллельных задач: {max_workers}") + + all_results = {} + batch_num = 1 + + # Обработка по пакетам + for i in range(0, total_questions, batch_size): + batch_data = heart_data[i:i + batch_size] + print(f"\nОбработка партии {batch_num}: Проблема {i+1}-{min(i+batch_size, total_questions)} ({len(batch_data)} штук)") + + batch_start_time = time.time() + batch_results = self._process_batch(batch_data, max_workers, i) + batch_end_time = time.time() + + # Сохранение результатов партии + self._save_batch_results(batch_results, batch_num, batch_start_time) + + all_results.update(batch_results) + + print(f"Пакет {batch_num} завершен, время затрачено: {batch_end_time - batch_start_time:.2f} секунд") + + batch_num += 1 + + # Перерыв между пакетами + if i + batch_size < total_questions: + print(f"Перерыв между пакетами {batch_delay} секунд...") + time.sleep(batch_delay) + + print(f"\nВсе пакеты обработаны! Всего обработано {total_questions} вопросов") + return all_results + + def _process_batch(self, batch_data: List[Dict], max_workers: int, start_index: int) -> Dict: + """Обработка одного пакета""" + batch_results = {} + + with ThreadPoolExecutor(max_workers=max_workers) as executor: + # Отправка задания + future_to_question = {} + for idx, question_data in enumerate(batch_data): + # Использовать оригинальный ID или сгенерировать новый ID + question_id = question_data.get('id', f"cardio_{start_index + idx:06d}") + future = executor.submit(self.processor.process_single_question, question_data, question_id) + future_to_question[future] = (question_id, question_data) + + # Сбор результатов + completed = 0 + for future in as_completed(future_to_question): + question_id, question_data = future_to_question[future] + #try: + result = future.result() + batch_results[question_id] = result + + # Простое отображение статуса + status_symbol = "✓" if result.status == "success" else "✗" + completed += 1 + + if completed % 5 == 0 or completed == len(batch_data): + success_count = sum(1 for r in batch_results.values() if r.status == "success") + print(f" Завершено: {completed}/{len(batch_data)} (Успешно: {success_count}) {status_symbol}") + + return batch_results + + def _save_batch_results(self, batch_results: Dict, batch_num: int, start_time: float): + """Сохранение результатов пакета""" + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + filename = f"cardio_analysis_batch_{batch_num:03d}_{timestamp}.pkl" + filepath = os.path.join(self.output_dir, filename) + + # Статистическая информация + total_count = len(batch_results) + success_count = sum(1 for r in batch_results.values() if r.status == "success") + error_count = total_count - success_count + + # Построение данных для сохранения + save_data = { + "metadata": { + "batch_num": batch_num, + "timestamp": timestamp, + "start_time": start_time, + "total_questions": total_count, + "successful_analyses": success_count, + "failed_analyses": error_count, + "success_rate": success_count / total_count if total_count > 0 else 0 + }, + "results": batch_results + } + + # Сохранение в файл + with open(filepath, 'wb') as f: + pickle.dump(save_data, f) + + print(f" Результаты пакета сохранены: {filename}") + print(f" Успех: {success_count}/{total_count} ({success_count/total_count*100:.1f}%)") + + return filepath +``` + +Запустив вышеупомянутый процесс пакетной обработки, мы отправили все вопросы в области кардиологии LLM для глубокого анализа и собрали возвращенные подробные тексты анализа (включая анализ клинической ситуации, различение вариантов, резюме основных принципов и т.д.), чтобы подготовить данные для следующего этапа извлечения концепций. + +**Примечание**: Пожалуйста, заполните свои собственные `api_url`, `api_key` и `model_name` в функции `process_heart_data`. + +```python +def process_heart_data(heart_data: List[Dict], api_url: str, api_key: str, model_name: str, max_workers: int = 10, + batch_size: int = 50, output_dir: str = "cardio_analysis"): + """Удобная функция для обработки heart_data""" + print(f"Готовлюсь обработать {len(heart_data)} сердечно-сосудистых клинических вопросов") + + # Инициализация API клиента + api_client = APIClient( + api_url=api_url, + api_key=api_key, + model_name=model_name + ) + + # Инициализация обработчика + processor = CardioAnalysisProcessor(api_client) + batch_processor = BatchProcessor(processor, output_dir=output_dir) + + # Пакетная обработка + results = batch_processor.process_questions_list( + heart_data=heart_data, + max_workers=max_workers, + batch_size=batch_size, + batch_delay=1 + ) + + return results +``` + +```python +# Пакетное извлечение мыслительного процесса каждого qa +# max_workers: количество параллельных запросов к API +# batch_size: сколько раз нужно выполнить запрос к API перед сохранением результатов + +results = process_heart_data(heart_data, max_workers=100, batch_size=400, output_dir="cookbooktest", + api_url = api_url, + api_key = api_key, + model_name = MEDXPERT_THINKER) +textlist = [results[i].response for i in results.keys()] +``` + +Теперь у нас есть большое количество текстов глубокого анализа, сгенерированных LLM, по вопросам кардиологии. Следующая задача заключается в том, чтобы извлечь все ключевые медицинские концепции из этих неструктурированных текстов. Мы снова используем LLM для выполнения этой задачи, и ключ к успеху по-прежнему заключается в хорошо спроектированном Prompt. `PromptTemplate` был переработан, чтобы направить LLM на роль кардиологического эксперта, следуя ряду строгих принципов извлечения (таких как извлечение ключевых терминов, избегание описательных комбинаций, вывод в стандартном формате JSON и т.д.), чтобы гарантировать, что конечный список концепций будет чистым и стандартизированным. + +```python +class PromptTemplate: + + @staticmethod + def get_system_prompt() -> str: + + return """You are an experienced cardiovascular specialist, skilled in identifying and extracting medical concept terms from clinical texts. + +Your task is to extract all relevant concept terms from cardiovascular clinical texts. + +Extraction principles: +- Only extract cardiovascular-related medical concepts, terms, and nouns +- Only concept terms, not complete definitions or explanations +- Prefer single core terms (e.g., "myocardial infarction", "hypertension", "echocardiography") +- Use phrases only when they represent standard medical terminology that cannot be meaningfully separated (e.g., "atrial fibrillation", "coronary artery disease") +- Avoid descriptive combinations (e.g., "severe hypertension" → "hypertension") +- Avoid overly vague terms (e.g., "heart problem") +- Include but not limited to disease names, examination methods, drug treatments, anatomical structures, physiological indicators, clinical manifestations, assessment tools, and all other related concepts +- Remove duplicate concepts +- Sort by importance + +Please ensure the output format strictly follows JSON format requirements.""" + + @staticmethod + def get_extraction_prompt(text_content: str) -> str: + + return f"""**Task: Extract concept terms from cardiovascular clinical text** + +**Please extract all relevant cardiovascular concept terms from the following text:** + +--- +{text_content} +--- + +**Output format (strictly follow JSON format):** +```json +{{ +"concepts": [ + "concept1", + "concept2", + "concept3", + "..." +] +}}""" +``` + +После выполнения вышеуказанных шагов мы успешно извлекли предварительный список семенных концепций в области кардиологии из огромного количества текстов анализа. Этот список закладывает прочную основу для последующего итеративного расширения концептуальной карты. + +**Пример результата:** + +```python +seed_concepts = [ + 'blood pressure', 'step-up', 'glucagon', 'therapeutic anticoagulation'... +] +``` + +### **Метод Итеративного Расширения Концептуальной Карты** + +#### **Основная Цель** + +Достичь полного охвата целевой области с помощью итеративного расширения концептуальной карты. Мы используем стратегию поэтапного расширения на основе LLM, начиная с набора семенных концепций и постепенно расширяя его, в конечном итоге создавая полную концептуальную карту области. + +#### **Итеративный Процесс** + +Основной процесс итерации выглядит следующим образом: + +- **Вход**: Концептуальная карта, созданная на предыдущем этапе итерации. +- **Обработка**: Для каждого узла концепции в карте предоставляются его собственные и известные соседние концепции в качестве контекстной информации для LLM, и запрашивается у LLM генерация дополнительных концепций, непосредственно связанных с этой центральной концепцией. +- **Выход**: Новые концепции, возвращенные LLM, проходят постобработку (например, удаление дубликатов) и добавляются в концептуальную карту в качестве входных данных для следующего этапа итерации. + +#### **Механизм Сходимости и Контрольные Параметры** + +С течением итераций новые сгенерированные концепции все больше перекрываются с уже существующими концепциями в карте, что приводит к естественной сходимости процесса итерации. Мы разработали три ключевых параметра для точного контроля этого процесса: + +1. **Порог Слияния Похожих Узлов (`similarity_threshold`)** + + * **Механизм**: Использует модель встраивания для вычисления векторного представления концепций, определяя семантическое сходство двух концепций с помощью косинусного сходства. + * **Действие**: Когда сходство двух концепций превышает установленный порог, они будут объединены в один узел в графе. + * **Влияние**: Этот параметр напрямую контролирует "гранулярность" концептуальной карты и скорость расширения, что является ключом к балансировке целостности графа и вычислительных затрат. +2. **Темп Растущих Новых Концепций (`new_concept_rate_threshold`)** + + * **Механизм**: Вычисляет долю новых концепций, созданных в текущем раунде, которые отсутствуют в существующей карте (т.е. "совершенно новые"). + * **Действие**: Когда эта доля ниже установленного порога, можно считать, что карта достигает насыщенности по охвату концепций, и итерации могут быть остановлены. +3. **Темп Растущих Новых Ребер (`new_edge_rate_threshold`)** + + * **Механизм**: Вычисляет темп роста количества новых соединений (ребер), созданных в текущем раунде между уже существующими старыми концепциями в графе. + * **Действие**: Когда сеть отношений между концепциями становится более совершенной, и рост новых соединений значительно замедляется, итерации могут быть остановлены. + * **Значение**: Этот показатель в основном отражает целостность внутренней структуры концептуальной карты. + +#### **Стратегия Выбора Параметров и Анализ Сходимости** + +В условиях отсутствия внешних оценочных наборов данных, выбор гиперпараметров и оценка сходимости являются ключевыми вопросами на практике. + +1. **Порог Слияния Похожих Узлов (`similarity_threshold`)**: **Ключевой Показатель, Контролирующий Скорость Итерации.** + Теоретически, можно не проводить слияние похожих узлов, чтобы построить наиболее полную концептуальную карту, но это приведет к огромным вычислительным затратам. Поэтому установка разумного порога имеет решающее значение. Каждый основной узел, который в конечном итоге оказывается в графе, можно понимать как **представительную концепцию** в семантическом пространстве, определенном этим порогом. Этот параметр является основным регулятором для балансировки целостности графа и вычислительной эффективности. Для академических исследований, требующих максимального охвата, можно установить высокий порог (например, 0.95); для практических приложений, ориентированных на соотношение затрат и выгод, можно установить более низкий порог (например, 0.80). +2. **Темп Растущих Новых Концепций**: **Первый Показатель, Сходящийся, Но Могущий Остановиться.** + По мере итерации темп роста новых концепций будет первым показывать тенденцию к сходимости. Однако на практике было обнаружено, что после достижения определенного уровня этот показатель может остановиться на низком уровне, не приближаясь полностью к нулю. Основная причина этого заключается в том, что LLM, проводя ассоциации концепций, может постепенно "сдвигаться" за строгие границы области. Поэтому нельзя полагаться только на этот показатель для определения завершенности итерации. +3. **Темп Растущих Новых Ребер**: **Итоговый Показатель Стабильной Сходимости.** + Когда большинство основных концепций целевой области (например, области сердечно-сосудистых заболеваний) уже захвачены, и основные отношения между ними установлены, последующие новые узлы в основном будут находиться на "краю" области. Эти крайние узлы трудно установить новые, значимые связи с старыми узлами в основной зоне графа. Это приводит к стабильному снижению темпа роста новых ребер между старыми концепциями и в конечном итоге к сходимости. В отличие от темпа роста новых концепций, этот показатель меньше подвержен влиянию характеристики "сверхобласти" LLM и является надежным показателем **целостности структуры** концептуальной карты. + +**Рекомендации по Практической Стратегии**: При ограниченных затратах использовать сбалансированный `similarity_threshold` (например, 0.80) и наблюдать за кривой сходимости с помощью метода локтя (Elbow Method). Когда темп роста новых концепций и темп роста новых ребер в течение 1-2 раундов не показывают значительных изменений и достигают плато, итерацию можно остановить. + +--- + +### **Основная Реализация Кода** + +Мы преобразуем вышеизложенную теорию в систему концептуальной карты, способную к саморазвитию. + +#### **1. Основная Структура Данных: Класс `ConceptGraph`** + +Основой системы является класс `ConceptGraph`, который представляет собой "умную карту", интегрирующую семантическое понимание и динамические возможности обновления. + +* **Инициализация (`__init__`)**: Начинается с группы предварительно обработанных семенных концепций, вычисляются их векторные вложения (embedding), строится начальное состояние графа. +* **Умное удаление дубликатов (`_is_similar_to_existing`)**: Это ключ к контролю качества и масштаба графа. Он использует косинусное сходство семантических векторов, чтобы определить, является ли новая концепция семантически "близкой" к уже существующим концепциям в графе. Концепция будет объединена только в том случае, если сходство превышает установленный `similarity_threshold`. +* **Динамическое обновление (`update_graph`)**: Это основной движущий механизм "роста" графа. Этот метод принимает новые концепции, расширенные LLM, и через механизм умного удаления дубликатов добавляет действительно "новые" концепции в качестве новых узлов в граф, устанавливая связи с исходными концепциями. +* **Мониторинг состояния (`calculate_metrics`, `get_graph_stats`)**: Эти методы отвечают за вычисление определенных нами показателей сходимости (таких как темп роста новых концепций, темп роста новых рёбер) и статистики графа (количество узлов, количество рёбер), что позволяет количественно контролировать эффективность каждой итерации. + +```python +class ConceptGraph: + + @classmethod + def from_graph_dict(cls, graph_dict: Dict[str, List[str]], concept_mapping, model, similarity_threshold): + """ + Восстановление ConceptGraph из сохраненного графа слов + Args: + graph_dict: сохраненный словарь смежности + model: экземпляр модели SentenceTransformer + similarity_threshold: порог для определения схожих концепций + concept_mapping: сохраненное отображение всех известных схожих концепций, например, {'hearts':'heart'} + Returns: + Экземпляр ConceptGraph + """ + if model is None: + raise ValueError("Параметры модели не могут быть None, пожалуйста, сначала используйте load_embedding_model() для загрузки модели") + + # Создать экземпляр, но не инициализировать + instance = cls.__new__(cls) + instance.model = model + instance.graph = graph_dict.copy() + instance.concept_embeddings = {} + instance.concept_mapping = concept_mapping + instance.similarity_threshold = similarity_threshold + + # Пересчитать embedding для всех концепций и создать самосопоставление + all_concepts = list(graph_dict.keys()) + if all_concepts: + print(f"Пересчитываем embedding для {len(all_concepts)} концепций...") + all_embeddings = model.encode(all_concepts) + + for concept, embedding in zip(all_concepts, all_embeddings): + instance.concept_embeddings[concept] = embedding + #instance.concept_mapping[concept] = concept # Создать самосопоставление + + print("ConceptGraph перестроен") + + return instance + + def __init__(self, seed_concepts: List[str], model, similarity_threshold): + """ + Инициализировать граф из семенных концепций и создать библиотеку embedding + Args: + seed_concepts: Список семенных концепций, уже прошедших внешнее удаление дубликатов + model: Экземпляр модели SentenceTransformer (обязательно) + similarity_threshold: порог для определения схожих концепций + """ + if model is None: + raise ValueError("Параметры модели не могут быть None, пожалуйста, сначала используйте load_embedding_model() для загрузки модели") + + self.model = model + self.graph = {} + self.concept_embeddings = {} # Поддерживать отображение concept -> embedding + self.concept_mapping = {} # Добавить таблицу сопоставления концепций + self.similarity_threshold = similarity_threshold # Порог сходства embedding + + # Очистить семенные концепции + cleaned_seeds = [concept.strip() for concept in seed_concepts if concept.strip()] + + print(f"Вычисляем embedding для {len(cleaned_seeds)} семенных концепций...") + + # Пакетное вычисление embedding + if cleaned_seeds: + seed_embeddings = self.model.encode(cleaned_seeds) + + # Создание Начальной Графа, Библиотеки Встраиваний и Таблицы Соответствий + for concept, embedding in zip(cleaned_seeds, seed_embeddings): + self.graph[concept] = [] + self.concept_embeddings[concept] = embedding + self.concept_mapping[concept] = concept # Создание Самосоответствия + + print(f"Инициализация Концептуальной Карты Завершена, Количество Семенных Концепций: {len(cleaned_seeds)}") + + def _get_target_concept(self, concept: str) -> Optional[str]: + """Единый Поиск Концептуального Соответствия""" + return self.concept_mapping.get(concept) + + def _is_similar_to_existing(self, new_concept: str, new_embedding: np.ndarray) -> Optional[str]: + """ + Проверка, Похожи Ли Новые Концепции На Существующие + Returns: + Если Похожи, Вернуть Похожие Существующие Концепции; Иначе Вернуть None + """ + if not self.concept_embeddings: + return None + + # Вычисление Сходства Со Всеми Существующими Концепциями + existing_concepts = list(self.concept_embeddings.keys()) + existing_embeddings = np.array([self.concept_embeddings[concept] for concept in existing_concepts]) + + # Вычисление Косинусного Сходства + similarities = self.model.similarity([new_embedding], existing_embeddings)[0] + + # Нахождение Самой Похожей Концепции + max_similarity_idx = np.argmax(similarities) + max_similarity = similarities[max_similarity_idx] + + if max_similarity >= self.similarity_threshold: + return existing_concepts[max_similarity_idx] + + return None + + def get_current_adjacency(self) -> Dict[str, List[str]]: + """Получение Текущего Словаря Смежности""" + return self.graph.copy() + + def calculate_metrics(self, expansion_results: Dict) -> Dict[str, float]: + """Вычисление Показателя Увеличения""" + # Сбор Всех Новых Концепций + all_new_concepts = [] + for result in expansion_results.values(): + if result.status == "success" and result.new_concepts: + all_new_concepts.extend(result.new_concepts) + + if not all_new_concepts: + return {"connectivity_rate": 0.0} + + existing_concepts = set(self.graph.keys()) + + # Связность: Новосозданные Ребра (Оба Являются Существующими Узлами) / Общее Количество Ребер На Предыдущем Этапе + old_total_edges = sum(len(neighbors) for neighbors in self.graph.values()) // 2 + + # Подсчет Новосозданных Ребер (Оба Являются Существующими Узлами) + new_edges_between_old_nodes = 0 + for result in expansion_results.values(): + if result.status == "success" and result.new_concepts: + center_concept = result.center_concept + for new_concept in result.new_concepts: + if (new_concept in existing_concepts and + center_concept != new_concept and + new_concept not in self.graph.get(center_concept, [])): + new_edges_between_old_nodes += 1 + + connectivity_rate = new_edges_between_old_nodes / old_total_edges if old_total_edges > 0 else float('inf') + + return { + "connectivity_rate": connectivity_rate + } + + + def update_graph(self, expansion_results: Dict): + """ + Обновление Структуры Графа - Использование Механизма Соответствия Для Удаления Дубликатов + """ + nodes_added = 0 + edges_added = 0 + embedding_duplicates = 0 + + # Сбор Всех Новых Концепций + all_new_concepts = [] + concept_to_centers = {} # Записывает соответствие каждого нового концепта с центральным концептом + + for result in expansion_results.values(): + if result.status == "success" and result.new_concepts: + center_concept = result.center_concept + for new_concept in result.new_concepts: + if new_concept.strip(): + cleaned_concept = new_concept.strip() + all_new_concepts.append(cleaned_concept) + if cleaned_concept not in concept_to_centers: + concept_to_centers[cleaned_concept] = [] + concept_to_centers[cleaned_concept].append(center_concept) + + if not all_new_concepts: + return nodes_added, edges_added, embedding_duplicates + + num_all_new_concepts = len(all_new_concepts) + print(f"Получено {num_all_new_concepts} новых концептов (без удаления дубликатов)") + + # Используйте отображение для быстрого фильтрации известных концептов + concepts_need_embedding = [] + concept_targets = {} # концепт -> целевой_концепт отображение + + for concept in all_new_concepts: + target = self._get_target_concept(concept) + if target is not None: + # Известные концепты, используйте отображение напрямую + concept_targets[concept] = target + if target != concept: + embedding_duplicates += 1 + else: + # Новые концепты, для которых необходимо вычислить встраивание + concepts_need_embedding.append(concept) + + # Вычисляйте встраивание только для неизвестных концептов + if concepts_need_embedding: + unique_concepts = list(set(concepts_need_embedding)) + print(f"В настоящее время выполняется встраивание и удаление дубликатов для {len(unique_concepts)} новых концептов...") + new_embeddings = self.model.encode(unique_concepts) + + # Обрабатывайте концепты, для которых необходимо встраивание, по одному + total_concepts = len(unique_concepts) + for idx, (new_concept, new_embedding) in enumerate(zip(unique_concepts, new_embeddings), 1): + # Выводите прогресс каждые 500 + if idx % 500 == 0 or idx == total_concepts: + print(f" Прогресс обработки: {idx}/{total_concepts} ({idx/total_concepts*100:.1f}%)") + # Проверьте, похожи ли они на существующие концепты + similar_concept = self._is_similar_to_existing(new_concept, new_embedding) + + if similar_concept: + # Обнаружены похожие концепты, создайте отображение + self.concept_mapping[new_concept] = similar_concept + concept_targets[new_concept] = similar_concept + embedding_duplicates += 1 + else: + # Совершенно новый концепт, добавьте в граф и создайте самоотображение + self.graph[new_concept] = [] + self.concept_embeddings[new_concept] = new_embedding + self.concept_mapping[new_concept] = new_concept + concept_targets[new_concept] = new_concept + nodes_added += 1 + + # Добавьте ребра (соедините со всеми связанными центральными концептами) + for concept in all_new_concepts: + target_concept = concept_targets[concept] + + for center_concept in concept_to_centers[concept]: + # Убедитесь, что центральная концепция присутствует в графе + if center_concept in self.graph: + # Двунаправленное соединение + if target_concept not in self.graph[center_concept]: + self.graph[center_concept].append(target_concept) + edges_added += 1 + + if center_concept not in self.graph[target_concept]: + self.graph[target_concept].append(center_concept) + edges_added += 1 + + print(f"Дедупликация завершена: добавленные узлы {nodes_added}, добавленные ребра {edges_added//2}, дедуплицированные концепции {embedding_duplicates}") + + return nodes_added, edges_added // 2, embedding_duplicates, nodes_added / num_all_new_concepts # Ненаправленный граф, количество ребер делится на 2 + + def get_graph_stats(self) -> Dict[str, int]: + """Получить статистическую информацию о графе""" + node_count = len(self.graph) + edge_count = sum(len(neighbors) for neighbors in self.graph.values()) // 2 + return {"nodes": node_count, "edges": edge_count} +``` + +#### **2. Полный код процесса расширения** + +Полный итерационный процесс состоит из исполняемого "одиночного цикла концептуального расширения", который объединяет несколько компонентов: + +* **Утилиты (`ResponseValidator`, `load_embedding_model`)**: Используются для решения распространенных проблем в инженерной практике, таких как исправление некорректного JSON, возвращаемого LLM, загрузка и управление моделями глубокого обучения. +* **Модуль взаимодействия с LLM (`APIClient`, `PromptTemplate`)**: Специально разработанный `PromptTemplate` используется для направления LLM на "ассоциации" и "расширения" на основе существующих концепций в графе. +* **Параллельный процессор (`ConceptExpander`, `BatchConceptExpander`)**: Отвечает за то, чтобы каждый узел концепции в графе рассматривался как отдельная задача, параллельно запрашивая расширение у LLM для обеспечения эффективности обработки. +* **Общий контроль итераций (`run_concept_expansion_iteration`)**: Это верхний уровень функции, отвечающей за координацию всех вышеупомянутых компонентов, полностью выполняя цикл "получить текущий граф -\> параллельное расширение -\> обновить граф -\> вычислить показатели". + +```python + +# Импорт библиотеки JSON Repair +try: + from json_repair import repair_json + HAS_JSONREPAIR = True + print("✓ Библиотека jsonrepair загружена, функция восстановления JSON включена") +except ImportError: + HAS_JSONREPAIR = False + print("⚠ Библиотека jsonrepair не установлена, будет использована базовая стратегия восстановления. Запустите 'pip install jsonrepair' для включения расширенного восстановления JSON") + def repair_json(text): + return text + +class ResponseValidator: + """Валидатор ответа""" + + @staticmethod + def validate_json_response(response_text: str, expected_keys: List[str]) -> Dict: + """ + Проверяет, является ли содержимое ответа API действительным JSON, включая предварительную обработку для устойчивости к ошибкам + + Returns: + dict: { + "is_valid_json": bool, + "parsed_json": dict or None, + "error_type": str, + "raw_response": str + } + """ + if not response_text or not response_text.strip(): + return { + "is_valid_json": False, + "parsed_json": None, + "error_type": "empty_response", + "raw_response": response_text + } + + repair_attempts = [] + + try: + # Предварительная обработка очистки + text = response_text.strip() + + # 1. Обработка блоков кода markdown ```json...``` или ```...``` + code_block_match = re.search(r'```(?:json)?\s*\n?(.*?)\n?```', text, re.DOTALL) + if code_block_match: + text = code_block_match.group(1).strip() + + # 2. Обработка обертки кавычками '...' или "..." + if (text.startswith("'") and text.endswith("'")) or (text.startswith('"') and text.endswith('"')): + text = text[1:-1] + + # 3. Удаление начальных и конечных обратных кавычек + text = text.strip('`').strip() + + # 4. Поиск части JSON - от первого { до последнего } + json_match = re.search(r'(\{.*\})', text, re.DOTALL) + if json_match: + text = json_match.group(1) + + # Первая Попытка: Прямой Парсинг + try: + parsed = json.loads(text) + repair_attempts.append("direct_parse_success") + except json.JSONDecodeError as e: + repair_attempts.append(f"direct_parse_failed: {str(e)}") + + # Вторая Попытка: Парсинг После Исправления С Помощью jsonrepair + if HAS_JSONREPAIR: + try: + repaired_text = repair_json(text) + parsed = json.loads(repaired_text) + repair_attempts.append("jsonrepair_success") + except Exception as e: + repair_attempts.append(f"jsonrepair_failed: {str(e)}") + raise + else: + repair_attempts.append("jsonrepair_not_available") + raise + + # Проверка Соответствия Ожидаемой Структуре + if isinstance(parsed, dict) and all(key in parsed for key in expected_keys): + return { + "is_valid_json": True, + "parsed_json": parsed, + "error_type": None, + "raw_response": response_text, + "repair_attempts": repair_attempts + } + else: + missing_keys = [key for key in expected_keys if key not in parsed] if isinstance(parsed, dict) else expected_keys + return { + "is_valid_json": False, + "parsed_json": parsed, + "error_type": f"missing_keys: expected {expected_keys}, missing {missing_keys}", + "raw_response": response_text, + "repair_attempts": repair_attempts + } + + except json.JSONDecodeError as e: + return { + "is_valid_json": False, + "parsed_json": None, + "error_type": f"json_decode_error: {str(e)}", + "raw_response": response_text, + "repair_attempts": repair_attempts + } + except Exception as e: + return { + "is_valid_json": False, + "parsed_json": None, + "error_type": f"unexpected_error: {str(e)}", + "raw_response": response_text, + "repair_attempts": repair_attempts + } + +# Код Итерации Расширения Графа На Основе Концепции Семени + +@dataclass +class ConceptExpansionResult: + """Класс Данных Результатов Расширения Концепции""" + status: str # success, api_error, json_error + concept_id: str + center_concept: str + neighbors: List[str] + response: Optional[str] = None + error_details: Optional[str] = None + processing_time: Optional[float] = None + json_validation: Optional[Dict] = None + new_concepts: Optional[List[str]] = None + returned_center: Optional[str] = None # LLM Возвращенный center_concept + +class PromptTemplate: + """Класс шаблона подсказок""" + + @staticmethod + def get_system_prompt() -> str: + """Получить Системные Подсказки""" + return """You are an experienced cardiovascular specialist, skilled in building comprehensive concept graphs for the cardiovascular domain. + +Your task is to expand a cardiovascular concept graph by generating new related concepts based on a given center concept and its existing connections.""" + + @staticmethod + def get_expansion_prompt(center_concept: str, neighbors: List[str]) -> str: + """Сгенерировать Подсказки Для Расширения Концепции""" + neighbors_text = ", ".join(neighbors) if neighbors else "None" + + return f"""**Task: Generate new cardiovascular concepts related to the center concept** + +**Domain**: Cardiovascular medicine +**Relationship requirement**: New concepts should be directly related to the center concept through strong clinical medical associations + +**Center concept**: {center_concept} +**Existing neighbor concepts of the center concept**: {neighbors_text} + +**Output format (strictly follow JSON format):** + +{{ + "center_concept": "{center_concept}", + "new_concepts": [ + "concept1", + "concept2", + "concept3", + "..." + ] +}} + + +If no new concepts can be generated: + +{{ + "center_concept": "{center_concept}", + "new_concepts": ["NO NEW CONCEPTS"] +}} + +**Instructions**: + +1. Instead of generate general medical concept, focus on generating new cardiovascular-domain concepts that are directly relevant in clinical scenarios to "{center_concept}" with strong clinical medical relation +2. Do not repeat any existing connected concepts listed above +3. Prefer single core terms (e.g., "myocardial infarction", "hypertension", "echocardiography") +4. Use phrases only when they represent standard medical terminology that cannot be meaningfully separated (e.g., "atrial fibrillation", "coronary artery disease") +5. Avoid descriptive combinations (e.g., "severe hypertension" → "hypertension") +6. Avoid overly vague terms (e.g., "heart problem") +7. Generate concepts that are directly related to the center concept +8. Do not repeat any existing connected concepts listed above; Avoid duplicate concepts""" + +class ConceptExpander: + """Обработчик Расширения Концепции""" + + def __init__(self, api_client: APIClient): + self.api_client = api_client + self.template = PromptTemplate() + + def expand_single_concept(self, center_concept: str, neighbors: List[str], concept_id: str) -> ConceptExpansionResult: + """Расширить Одну Концепцию""" + start_time = time.time() + + # Формирование сообщения + system_prompt = self.template.get_system_prompt() + user_prompt = self.template.get_expansion_prompt(center_concept, neighbors) + + messages = [ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": user_prompt} + ] + + # Вызов API + api_result = self.api_client.call_api(messages, timeout=120) + processing_time = time.time() - start_time + + if api_result["status"] != "success": + return ConceptExpansionResult( + status="api_error", + concept_id=concept_id, + center_concept=center_concept, + neighbors=neighbors, + error_details=api_result["error"], + processing_time=processing_time + ) + + # Проверка JSON Ответа + expected_keys = ["center_concept", "new_concepts"] + json_validation = ResponseValidator.validate_json_response( + api_result["content"], expected_keys + ) + + if json_validation["is_valid_json"]: + returned_center = json_validation["parsed_json"]["center_concept"] + new_concepts = json_validation["parsed_json"]["new_concepts"] + + # Проверка На Случай "Нет Новых Концепций" + if len(new_concepts) == 1 and new_concepts[0].strip() == "NO NEW CONCEPTS": + return ConceptExpansionResult( + status="success", + concept_id=concept_id, + center_concept=center_concept, + neighbors=neighbors, + response=api_result["content"], + processing_time=processing_time, + json_validation=json_validation, + new_concepts=[], # Пустой Список, Указывающий На Отсутствие Новых Концепций + returned_center=returned_center + ) + + # Обычная Обработка Новых Концепций - Удаление Предыдущей Логики Фильтрации, Передача На Embedding Для Удаления Дубликатов + new_concepts = [concept.strip() for concept in new_concepts if concept.strip()] + + return ConceptExpansionResult( + status="success", + concept_id=concept_id, + center_concept=center_concept, + neighbors=neighbors, + response=api_result["content"], + processing_time=processing_time, + json_validation=json_validation, + new_concepts=new_concepts, + returned_center=returned_center + ) + else: + return ConceptExpansionResult( + status="json_error", + concept_id=concept_id, + center_concept=center_concept, + neighbors=neighbors, + response=api_result["content"], + error_details=f"JSON validation failed: {json_validation['error_type']}", + processing_time=processing_time, + json_validation=json_validation + ) + +class BatchConceptExpander: + """Обработчик Массового Расширения Концепций""" + def __init__(self, expander: ConceptExpander, output_dir: str = "concept_expansion"): + self.expander = expander + self.output_dir = output_dir + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + def expand_concepts_batch(self, adjacency_dict: Dict[str, List[str]], max_workers: int = 10) -> Dict: + """Концепция Масштабного Увеличения""" + concepts_to_expand = list(adjacency_dict.keys()) + total_concepts = len(concepts_to_expand) + print(f"Начало Масштабного Увеличения Концепций {total_concepts} Концепций") + print(f"Максимальная Параллельность: {max_workers}") + + batch_start_time = time.time() + batch_results = self._process_batch(concepts_to_expand, adjacency_dict, max_workers) + batch_end_time = time.time() + + print(f"Обработка Завершена, Время: {batch_end_time - batch_start_time:.2f} Секунд") + return batch_results + + def _process_batch(self, batch_concepts: List[str], adjacency_dict: Dict[str, List[str]], + max_workers: int) -> Dict: + """Обработка Партии""" + batch_results = {} + + with ThreadPoolExecutor(max_workers=max_workers) as executor: + # Отправка задания + future_to_concept = {} + for idx, concept in enumerate(batch_concepts): + concept_id = f"concept_{idx:06d}" + neighbors = adjacency_dict.get(concept, []) + future = executor.submit(self.expander.expand_single_concept, concept, neighbors, concept_id) + future_to_concept[future] = (concept_id, concept) + + # Сбор результатов + completed = 0 + for future in as_completed(future_to_concept): + concept_id, concept = future_to_concept[future] + try: + result = future.result() + batch_results[concept_id] = result + + # Простое Отображение Состояния + status_symbol = "✓" if result.status == "success" else "✗" + completed += 1 + + if completed % 1000 == 0 or completed == len(batch_concepts): + success_count = sum(1 for r in batch_results.values() if r.status == "success") + print(f" Завершено: {completed}/{len(batch_concepts)} (Успешно: {success_count}) {status_symbol}") + + except Exception as e: + batch_results[concept_id] = ConceptExpansionResult( + status="exception", + concept_id=concept_id, + center_concept=concept, + neighbors=adjacency_dict.get(concept, []), + error_details=str(e) + ) + print(f" Исключение: {concept_id} - {str(e)}") + + return batch_results + + def _save_results(self, batch_results: Dict, start_time: float): + """Сохранение Результатов""" + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + filename = f"concept_expansion_results_{timestamp}.pkl" + filepath = os.path.join(self.output_dir, filename) + + # Статистическая информация + total_count = len(batch_results) + success_count = sum(1 for r in batch_results.values() if r.status == "success") + error_count = total_count - success_count + + # Подсчет Сгенерированных Концепций + total_new_concepts = sum(len(r.new_concepts) for r in batch_results.values() + if r.status == "success" and r.new_concepts) + + # Подсчет Пропущенных Концепций (без Новых Концепций) + skipped_concepts = sum(1 for r in batch_results.values() + if r.status == "success" and r.new_concepts is not None and len(r.new_concepts) == 0) + + # Построение данных для сохранения + save_data = { + "metadata": { + "timestamp": timestamp, + "start_time": start_time, + "total_concepts": total_count, + "successful_expansions": success_count, + "failed_expansions": error_count, + "success_rate": success_count / total_count if total_count > 0 else 0, + "total_new_concepts": total_new_concepts, + "skipped_concepts": skipped_concepts + }, + "results": batch_results + } + + # Сохранение в файл + with open(filepath, 'wb') as f: + pickle.dump(save_data, f) + + print(f" Результаты Сохранены: {filename}") + print(f" Успех: {success_count}/{total_count} ({success_count/total_count*100:.1f}%)") + print(f" Общее Количество Новых Концепций: {total_new_concepts}") + print(f" Пропущенные Концепции: {skipped_concepts}") + + return filepath + +class ConceptGraph: + + @classmethod + def from_graph_dict(cls, graph_dict: Dict[str, List[str]], concept_mapping, model, similarity_threshold): + """ + Восстановление ConceptGraph из сохраненного графа слов + Args: + graph_dict: сохраненный словарь смежности + model: экземпляр модели SentenceTransformer + similarity_threshold: порог для определения схожих концепций + concept_mapping: сохраненное отображение всех известных схожих концепций, например, {'hearts':'heart'} + Returns: + Экземпляр ConceptGraph + """ + if model is None: + raise ValueError("Параметры модели не могут быть None, пожалуйста, сначала используйте load_embedding_model() для загрузки модели") + + # Создать экземпляр, но не инициализировать + instance = cls.__new__(cls) + instance.model = model + instance.graph = graph_dict.copy() + instance.concept_embeddings = {} + instance.concept_mapping = concept_mapping + instance.similarity_threshold = similarity_threshold + + # Пересчитать embedding для всех концепций и создать самосопоставление + all_concepts = list(graph_dict.keys()) + if all_concepts: + print(f"Пересчитываем embedding для {len(all_concepts)} концепций...") + all_embeddings = model.encode(all_concepts) + + for concept, embedding in zip(all_concepts, all_embeddings): + instance.concept_embeddings[concept] = embedding + #instance.concept_mapping[concept] = concept # Создать самосопоставление + + print("ConceptGraph перестроен") + + return instance + + def __init__(self, seed_concepts: List[str], model, similarity_threshold): + """ + Инициализировать граф из семенных концепций и создать библиотеку embedding + Args: + seed_concepts: Список семенных концепций, уже прошедших внешнее удаление дубликатов + model: Экземпляр модели SentenceTransformer (обязательно) + similarity_threshold: порог для определения схожих концепций + """ + if model is None: + raise ValueError("Параметры модели не могут быть None, пожалуйста, сначала используйте load_embedding_model() для загрузки модели") + + self.model = model + self.graph = {} + self.concept_embeddings = {} # Поддерживать отображение concept -> embedding + self.concept_mapping = {} # Добавить таблицу сопоставления концепций + self.similarity_threshold = similarity_threshold # Порог сходства embedding + + # Очистить семенные концепции + cleaned_seeds = [concept.strip() for concept in seed_concepts if concept.strip()] + + print(f"Вычисляем embedding для {len(cleaned_seeds)} семенных концепций...") + + # Пакетное вычисление embedding + if cleaned_seeds: + seed_embeddings = self.model.encode(cleaned_seeds) + + # Создание Начальной Графа, Библиотеки Встраиваний и Таблицы Соответствий + for concept, embedding in zip(cleaned_seeds, seed_embeddings): + self.graph[concept] = [] + self.concept_embeddings[concept] = embedding + self.concept_mapping[concept] = concept # Создание Самосоответствия + + print(f"Инициализация Концептуальной Карты Завершена, Количество Семенных Концепций: {len(cleaned_seeds)}") + + def _get_target_concept(self, concept: str) -> Optional[str]: + """Единый Поиск Концептуального Соответствия""" + return self.concept_mapping.get(concept) + + def _is_similar_to_existing(self, new_concept: str, new_embedding: np.ndarray) -> Optional[str]: + """ + Проверка, Похожи Ли Новые Концепции На Существующие + Returns: + Если Похожи, Вернуть Похожие Существующие Концепции; Иначе Вернуть None + """ + if not self.concept_embeddings: + return None + + # Вычисление Сходства Со Всеми Существующими Концепциями + existing_concepts = list(self.concept_embeddings.keys()) + existing_embeddings = np.array([self.concept_embeddings[concept] for concept in existing_concepts]) + + # Вычисление Косинусного Сходства + similarities = self.model.similarity([new_embedding], existing_embeddings)[0] + + # Нахождение Самой Похожей Концепции + max_similarity_idx = np.argmax(similarities) + max_similarity = similarities[max_similarity_idx] + + if max_similarity >= self.similarity_threshold: + return existing_concepts[max_similarity_idx] + + return None + + def get_current_adjacency(self) -> Dict[str, List[str]]: + """Получение Текущего Словаря Смежности""" + return self.graph.copy() + + def calculate_metrics(self, expansion_results: Dict) -> Dict[str, float]: + """Вычисление Показателя Увеличения""" + # Сбор Всех Новых Концепций + all_new_concepts = [] + for result in expansion_results.values(): + if result.status == "success" and result.new_concepts: + all_new_concepts.extend(result.new_concepts) + + if not all_new_concepts: + return {"connectivity_rate": 0.0} + + existing_concepts = set(self.graph.keys()) + + # Связность: Новосозданные Ребра (Оба Являются Существующими Узлами) / Общее Количество Ребер На Предыдущем Этапе + old_total_edges = sum(len(neighbors) for neighbors in self.graph.values()) // 2 + + # Подсчет Новосозданных Ребер (Оба Являются Существующими Узлами) + new_edges_between_old_nodes = 0 + for result in expansion_results.values(): + if result.status == "success" and result.new_concepts: + center_concept = result.center_concept + for new_concept in result.new_concepts: + if (new_concept in existing_concepts and + center_concept != new_concept and + new_concept not in self.graph.get(center_concept, [])): + new_edges_between_old_nodes += 1 + + connectivity_rate = new_edges_between_old_nodes / old_total_edges if old_total_edges > 0 else float('inf') + + return { + "connectivity_rate": connectivity_rate + } + + + def update_graph(self, expansion_results: Dict): + """ + Обновление Структуры Графа - Использование Механизма Соответствия Для Удаления Дубликатов + """ + nodes_added = 0 + edges_added = 0 + embedding_duplicates = 0 + + # Сбор Всех Новых Концепций + all_new_concepts = [] + concept_to_centers = {} # Записывает соответствие каждого нового концепта с центральным концептом + + for result in expansion_results.values(): + if result.status == "success" and result.new_concepts: + center_concept = result.center_concept + for new_concept in result.new_concepts: + if new_concept.strip(): + cleaned_concept = new_concept.strip() + all_new_concepts.append(cleaned_concept) + if cleaned_concept not in concept_to_centers: + concept_to_centers[cleaned_concept] = [] + concept_to_centers[cleaned_concept].append(center_concept) + + if not all_new_concepts: + return nodes_added, edges_added, embedding_duplicates + + num_all_new_concepts = len(all_new_concepts) + print(f"Получено {num_all_new_concepts} новых концептов (без удаления дубликатов)") + + # Используйте отображение для быстрого фильтрации известных концептов + concepts_need_embedding = [] + concept_targets = {} # концепт -> целевой_концепт отображение + + for concept in all_new_concepts: + target = self._get_target_concept(concept) + if target is not None: + # Известные концепты, используйте отображение напрямую + concept_targets[concept] = target + if target != concept: + embedding_duplicates += 1 + else: + # Новые концепты, для которых необходимо вычислить встраивание + concepts_need_embedding.append(concept) + + # Вычисляйте встраивание только для неизвестных концептов + if concepts_need_embedding: + unique_concepts = list(set(concepts_need_embedding)) + print(f"В настоящее время выполняется встраивание и удаление дубликатов для {len(unique_concepts)} новых концептов...") + new_embeddings = self.model.encode(unique_concepts) + + # Обрабатывайте концепты, для которых необходимо встраивание, по одному + total_concepts = len(unique_concepts) + for idx, (new_concept, new_embedding) in enumerate(zip(unique_concepts, new_embeddings), 1): + # Выводите прогресс каждые 500 + if idx % 500 == 0 or idx == total_concepts: + print(f" Прогресс обработки: {idx}/{total_concepts} ({idx/total_concepts*100:.1f}%)") + # Проверьте, похожи ли они на существующие концепты + similar_concept = self._is_similar_to_existing(new_concept, new_embedding) + + if similar_concept: + # Обнаружены похожие концепты, создайте отображение + self.concept_mapping[new_concept] = similar_concept + concept_targets[new_concept] = similar_concept + embedding_duplicates += 1 + else: + # Совершенно новый концепт, добавьте в граф и создайте самоотображение + self.graph[new_concept] = [] + self.concept_embeddings[new_concept] = new_embedding + self.concept_mapping[new_concept] = new_concept + concept_targets[new_concept] = new_concept + nodes_added += 1 + + # Добавьте ребра (соедините со всеми связанными центральными концептами) + for concept in all_new_concepts: + target_concept = concept_targets[concept] + + for center_concept in concept_to_centers[concept]: + # Убедитесь, что центральная концепция присутствует в графе + if center_concept in self.graph: + # Двунаправленное соединение + if target_concept not in self.graph[center_concept]: + self.graph[center_concept].append(target_concept) + edges_added += 1 + + if center_concept not in self.graph[target_concept]: + self.graph[target_concept].append(center_concept) + edges_added += 1 + + print(f"Дедупликация завершена: добавленные узлы {nodes_added}, добавленные ребра {edges_added//2}, дедуплицированные концепции {embedding_duplicates}") + + return nodes_added, edges_added // 2, embedding_duplicates, nodes_added / num_all_new_concepts # Ненаправленный граф, количество ребер делится на 2 + + def get_graph_stats(self) -> Dict[str, int]: + """Получить статистическую информацию о графе""" + node_count = len(self.graph) + edge_count = sum(len(neighbors) for neighbors in self.graph.values()) // 2 + return {"nodes": node_count, "edges": edge_count} + +def load_embedding_model(model_name: str = "nomic-ai/nomic-embed-text-v1.5"): + """ + Загрузка Модели Встраивания + Args: + model_name: Название Модели + Returns: + Экземпляр Модели SentenceTransformer + """ + print(f"Загрузка embedding модели: {model_name}") + model = SentenceTransformer(model_name, trust_remote_code=True) + print("Модель загружена") + return model + +def extract_seed_concepts(results): + """Извлечение начальных концепций из результатов пакетной обработки""" + all_concepts = [] + + for result in results.values(): + if result.status == "success" and result.extracted_concepts: + all_concepts.extend(result.extracted_concepts) + + # Удаление пробелов и дубликатов + seed_concepts = list(set(concept.strip() for concept in all_concepts if concept.strip())) + + return seed_concepts + +def run_concept_expansion_iteration(api_url: str, api_key: str, model_name: str, concept_graph: ConceptGraph, max_workers: int = 10): + """Запуск итерации расширения концепций один раз""" + # Инициализация API клиента и обработчика + api_client = APIClient( + api_url=api_url, + api_key=api_key, + model_name=model_name + ) + + expander = ConceptExpander(api_client) + batch_expander = BatchConceptExpander(expander) + + # Получение текущего словаря смежности + current_adjacency = concept_graph.get_current_adjacency() + + # Пакетное расширение концепций + expansion_results = batch_expander.expand_concepts_batch( + adjacency_dict=current_adjacency, + max_workers=max_workers + ) + + # Расчет метрик + metrics = concept_graph.calculate_metrics(expansion_results) + + # Обновление графа - удаление дубликатов с использованием embedding + nodes_added, edges_added, embedding_duplicates, concept_add_rate = concept_graph.update_graph(expansion_results) + + # Получение статистики обновленного графа + graph_stats = concept_graph.get_graph_stats() + + # Подсчет количества пропущенных концепций + skipped_count = sum(1 for r in expansion_results.values() + if r.status == "success" and r.new_concepts is not None and len(r.new_concepts) == 0) + + # Печать результатов + print(f"\n=== Итерация Завершена ===") + print(f"Обновление Концепции: {concept_add_rate:.3f}") + print(f"Связность Концепции: {metrics['connectivity_rate']:.3f}") + print(f"Количество Узлов В Конце Итерации: {graph_stats['nodes']}") + print(f"Количество Ребер В Конце Итерации: {graph_stats['edges']}") + print(f"Добавленные Узлы В Этот Раунд: {nodes_added}") + print(f"Количество Добавленных Ребер В Этот Раунд: {edges_added}") + print(f"Пропущенные Концепции: {skipped_count}") + + return { + "concept_add_rate": concept_add_rate, + "connectivity_rate": metrics['connectivity_rate'], + "graph_stats": graph_stats, + "nodes_added": nodes_added, + "edges_added": edges_added, + "embedding_duplicates": embedding_duplicates, + "skipped_count": skipped_count, + "expansion_results": expansion_results + } +``` + +### **Запуск расширения: Подготовка и выполнение** + +Перед запуском масштабной итерации мы проводим внутреннее семантическое удаление дубликатов для начального списка `seed_concepts`. Функция `deduplicate_seed_concepts` сравнивает семантическое сходство всех семенных концепций попарно и отбрасывает дублирующие концепции с слишком высоким сходством, чтобы обеспечить чистоту начального графа. + +После очистки мы используем этот качественный набор семян для официального создания экземпляра `ConceptGraph`, готовясь к первому раунду расширения. + +Загрузка embedding model для фильтрации схожих семенных концепций: + +```python +import json +import pickle +import time +import torch +import numpy as np +from sentence_transformers import SentenceTransformer +from datetime import datetime + +device = 'cuda' if torch.cuda.is_available() else 'cpu' +print(f"Инициализация Модели, Используя Устройство: {device}") +model = SentenceTransformer(EMBEDDING_MODEL, trust_remote_code=True, device=device) +print("Инициализация Модели Завершена") +``` + +Инициализация concept_graph на основе семенных концепций: + +```python + +import random +import numpy as np + +def deduplicate_seed_concepts(seed_concepts, model, similarity_threshold=0.95): + """Удаление Дубликатов Из Начальных Концепций, Сходство > Пороговое Значение, Случайно Сохраняем Одну""" + + embeddings = model.encode(seed_concepts) + similarities = model.similarity(embeddings, embeddings) + similarities = similarities.cpu().numpy() + + to_remove = set() + n = len(seed_concepts) + + for i in range(n): + for j in range(i+1, n): + if similarities[i][j] > similarity_threshold: + # Сходство Превышает Порог, Случайно Выбираем Одну Для Удаления + remove_idx = random.choice([i, j]) + to_remove.add(remove_idx) + print(f"Сходные Концепции: '{seed_concepts[i]}' vs '{seed_concepts[j]}' (Сходство: {similarities[i][j]:.4f})") + print(f" -> Удалить: '{seed_concepts[remove_idx]}'") + + filtered_concepts = [concept for i, concept in enumerate(seed_concepts) if i not in to_remove] + + print(f"\nРезультаты Удаления Дубликатов: {len(seed_concepts)} -> {len(filtered_concepts)} Концепций") + print(f"Удалено {len(to_remove)} схожих концепций") + + return filtered_concepts + +# Пример Использования +filtered_seed_concepts = deduplicate_seed_concepts(seed_concepts, model, similarity_threshold=0.8) +concept_graph = ConceptGraph(filtered_seed_concepts, model, similarity_threshold=0.8) +``` + +Повторно выполняя функцию `run_concept_expansion_iteration`, мы можем завершить несколько раундов расширения. После завершения каждого раунда расширения мы рекомендуем сохранять обновленную структуру графа (`graph_dict`) и таблицу сопоставления концепций (`concept_mapping`) в постоянное хранилище в виде файлов `.pkl`, чтобы предотвратить потерю результатов длительной работы из-за неожиданных прерываний. Этот процесс будет продолжаться до тех пор, пока предустановленные показатели сходимости не достигнут порогового значения. + +## Конкретный процесс одиночного расширения графа + +```python +# Пример Кода Для Одной Итерации + +domain = 'Cardio' + +# Убедитесь, что каталог для сохранения существует +save_dir = f'cookbooktest/{domain}' +os.makedirs(save_dir, exist_ok=True) + +iter_n = 1 + +results = run_concept_expansion_iteration(model_name=CONCEPT_GRAPH_EXTENDER, concept_graph=concept_graph, max_workers = 100, + api_url=api_url, + api_key=api_key) + + + +# Получите смежный список графа +graph_dict = concept_graph.graph + +# Сохранить в формате pickle +with open(f'{save_dir}/concept_graph_4omini_{iter_n}_iter.pkl', 'wb') as f: + pickle.dump(graph_dict, f) + +# Получите смежный список графа +concept_mapping = concept_graph.concept_mapping +# Сохранить в формате pickle +with open(f'{save_dir}/concept_graph_4omini_{iter_n}_iter_concept_mapping.pkl', 'wb') as f: + pickle.dump(concept_mapping, f) + + +# Повторите для большего количества итераций··· Практический опыт показывает, что до 10 раз граф уже должен быть достаточно большим, чтобы сойтись. +# Цикл кода, только для справки +# Поскольку стоимость расширения графа увеличивается с увеличением числа итераций, мы настоятельно рекомендуем вам вручную выполнять итерации по кругам и после каждой итерации проверять покрытие текущего графа концепций на основе вашей собственной библиотеки концепций для валидации, чтобы определить количество итераций для завершения +# В отсутствие библиотеки концепций для валидации вы можете обратиться к (a) покрытие новых концепций = количество новых узлов в этом раунде / количество новых концепций, полученных в этом раунде (b) связность концепций как индикатор завершения сходимости +''' +MAX_ITER = 10 # Максимальное количество итераций +CONCEPT_ADD_THRESHOLD = 0.05 # Нижний предел добавления концепций +CONNECTIVITY_THRESHOLD = 0.2 # Нижний предел связности + +domain = 'Cardio' +save_dir = f'cookbooktest/{domain}' + +for iter_n in range(1, MAX_ITER + 1): + print(f"\n===== Iteration {iter_n} =====") + + # Выполните одну итерацию расширения концепций + results = run_concept_expansion_iteration( + model_name=CONCEPT_GRAPH_EXTENDER, + concept_graph=concept_graph, + max_workers=100, + api_url=api_url, + api_key=api_key + ) + + # Извлечение метрик + concept_add_rate = results["concept_add_rate"] + connectivity_rate = results["connectivity_rate"] + + # Сохранить граф смежности + graph_dict = concept_graph.graph + with open(f'{save_dir}/concept_graph_4omini_{iter_n}_iter.pkl', 'wb') as f: + pickle.dump(graph_dict, f) + + # Сохранить концептуальную карту + concept_mapping = concept_graph.concept_mapping + with open(f'{save_dir}/concept_graph_4omini_{iter_n}_iter_concept_mapping.pkl', 'wb') as f: + pickle.dump(concept_mapping, f) + + # Условие OR для досрочного завершения + if (concept_add_rate < CONCEPT_ADD_THRESHOLD) or (connectivity_rate < CONNECTIVITY_THRESHOLD): + print(f"Остановить итерацию: удовлетворяет условию остановки (concept_add_rate<{CONCEPT_ADD_THRESHOLD} или connectivity_rate<{CONNECTIVITY_THRESHOLD})") + break +''' +``` + +### **Экспериментальные данные и оценка** + +Мы провели всестороннюю экспериментальную проверку в двух медицинских областях: кардиологии (cardio) и респираторной системе (respiratory), используя модели GPT-4o-mini и GPT-4o, проводя многократные итерации расширения при различных порогах сходства (0.8, 0.85, 0.9). Метод проверки заключался в извлечении ключевых слов из медицинских статей соответствующей области на Википедии и вычислении охвата концептуальной графики. + +#### **Настройки эксперимента** + +- **Набор данных**: Область кардиологии (cardio), область респираторной системы (respiratory) +- **Модели**: GPT-4o-mini, GPT-4o +- **Порог сходства**: 0.8, 0.85, 0.9 +- **Показатели оценки**: Охват ключевых слов Википедии (при порогах 0.8, 0.85, 0.9) +- **Базовая стоимость**: Завершение 8 раундов итераций моделью GPT-4o-mini обошлось примерно в $20 + +#### **Описание показателей** + +- **Количество Узлов**: Общее количество концепций, которые были рассмотрены (включая концепции, признанные схожими + концепции, оставленные в графе) +- **Количество Ребер**: Общее количество ребер в концептуальной карте +- **Коэффициент Новых Концепций**: Количество новых узлов в концептуальной карте / Общее количество концепций, созданных в текущем раунде +- **Коэффициент Новых Ребер**: Количество новых ребер между старыми узлами / Количество ребер между старыми узлами до появления новых ребер +- **Оценка Стоимости**: Расчет общего количества концепций, созданных в текущем и предыдущих раундах, с использованием тарифов gpt-4o-mini за 8 раундов итерации + +#### **Результаты Экспериментов в Области Сердечно-Сосудистых Заболеваний** + +| Модель | Порог | Эпохи | Количество Узлов | Количество Ребер | Покрытие@0.8 | Покрытие@0.85 | Покрытие@0.9 | Уровень Новых Концепций | Уровень Новых Ребер | Оценка Стоимости | +| ----------- | ---- | ---- | ------ | ------- | ---------- | ----------- | ---------- | -------- | ------ | -------- | +| GPT-4o-mini | 0.8 | 1 | 7,797 | 23,284 | 89.67% | 79.73% | 66.12% | 10.05% | 0.00% | $0.83 | +| GPT-4o-mini | 0.8 | 2 | 16,066 | 63,712 | 93.79% | 86.13% | 76.00% | 7.20% | 49.50% | $2.37 | +| GPT-4o-mini | 0.8 | 3 | 28,737 | 132,451 | 95.49% | 89.67% | 80.58% | 5.50% | 33.40% | $5.06 | +| GPT-4o-mini | 0.8 | 4 | 47,255 | 239,751 | 96.21% | 92.09% | 83.52% | 4.56% | 25.60% | $9.32 | +| GPT-4o-mini | 0.8 | 5 | 73,359 | 397,872 | 96.73% | 93.79% | 86.46% | 3.79% | 21.10% | $15.68 | +| GPT-4o | 0.8 | 1 | 7,232 | 20,577 | 90.91% | 80.97% | 68.61% | 9.68% | 0.00% | $7.34 | +| GPT-4o | 0.8 | 2 | 14,574 | 55,559 | 94.57% | 88.82% | 78.68% | 7.51% | 46.20% | $20.41 | +| GPT-4o | 0.8 | 3 | 23,488 | 102,429 | 95.95% | 91.50% | 82.01% | 6.15% | 23.80% | $37.94 | +| GPT-4o | 0.8 | 4 | 40,030 | 188,292 | 97.32% | 94.31% | 86.20% | 5.30% | 23.50% | $70.82 | +| GPT-4o | 0.8 | 5 | 64,807 | 317,772 | 97.97% | 95.36% | 88.82% | 4.45% | 18.80% | $120.80 | +| GPT-4o | 0.85 | 1 | 8,750 | 29,200 | 92.22% | 84.43% | 72.73% | 9.96% | 0.00% | $10.34 | +| GPT-4o | 0.85 | 2 | 17,570 | 79,784 | 95.88% | 90.97% | 81.56% | 9.11% | 70.90% | $28.58 | +| GPT-4o | 0.85 | 3 | 32,217 | 172,894 | 96.99% | 93.66% | 86.46% | 7.36% | 49.40% | $62.47 | +| GPT-4o | 0.85 | 4 | 55,586 | 328,126 | 97.78% | 95.29% | 89.60% | 6.31% | 37.90% | $119.19 | + +#### **Результаты Экспериментов в Области Дыхательной Системы** + +| Модель | Порог | Эпохи | Количество Узлов | Количество Ребер | Покрытие@0.8 | Покрытие@0.85 | Покрытие@0.9 | Уровень Новых Концепций | Уровень Новых Ребер | Оценка Стоимости | +| ----------- | ---- | ---- | ------- | ------- | ---------- | ----------- | ---------- | -------- | ------- | -------- | +| GPT-4o-mini | 0.8 | 1 | 4,683 | 13,569 | 84.07% | 74.32% | 61.11% | 11.27% | 0.00% | $0.49 | +| GPT-4o-mini | 0.8 | 2 | 9,736 | 38,374 | 89.20% | 82.08% | 69.71% | 7.92% | 56.00% | $1.42 | +| GPT-4o-mini | 0.8 | 3 | 17,893 | 81,567 | 92.56% | 87.21% | 76.10% | 6.10% | 36.70% | $3.11 | +| GPT-4o-mini | 0.8 | 4 | 30,231 | 150,979 | 94.55% | 89.62% | 79.98% | 4.96% | 28.30% | $2.76 | +| GPT-4o-mini | 0.8 | 5 | 48,032 | 255,740 | 96.23% | 91.40% | 82.08% | 4.08% | 23.20% | $6.96 | +| GPT-4o-mini | 0.8 | 6 | 73,308 | 405,320 | 96.96% | 92.87% | 84.38% | 3.69% | 19.20% | $13.02 | +| GPT-4o-mini | 0.8 | 7 | 108,026 | 613,808 | 97.27% | 93.92% | 87.42% | 3.23% | 16.60% | $8.49 | +| GPT-4o-mini | 0.8 | 8 | 153,963 | 894,902 | 97.80% | 94.76% | 89.10% | 2.88% | 14.50% | $20.00 | +| GPT-4o-mini | 0.85 | 1 | 5,334 | 17,158 | 86.79% | 77.36% | 64.47% | 12.35% | 0.00% | $0.61 | +| GPT-4o-mini | 0.85 | 2 | 11,312 | 50,003 | 90.99% | 84.07% | 72.54% | 9.56% | 71.00% | $1.75 | +| GPT-4o-mini | 0.85 | 3 | 20,800 | 105,945 | 94.76% | 88.78% | 78.41% | 8.14% | 44.40% | $3.69 | +| GPT-4o-mini | 0.85 | 4 | 36,552 | 213,214 | 96.65% | 92.24% | 83.23% | 6.24% | 41.60% | $3.99 | +| GPT-4o-mini | 0.85 | 5 | 61,575 | 388,639 | 97.59% | 94.03% | 85.32% | 5.56% | 34.00% | $10.08 | +| GPT-4o-mini | 0.9 | 1 | 5,646 | 19,742 | 86.06% | 75.89% | 65.30% | 13.36% | 0.00% | $0.70 | +| GPT-4o-mini | 0.9 | 2 | 12,437 | 60,868 | 91.30% | 84.38% | 73.79% | 12.05% | 124.10% | $2.15 | +| GPT-4o-mini | 0.9 | 3 | 25,008 | 150,025 | 94.23% | 89.83% | 81.13% | 9.63% | 91.30% | $5.31 | + +#### **Ключевые Находки и Анализ** + +##### **1. Проверка Сходимости: Все Настройки Стремятся к Сходимости** + +Все экспериментальные настройки продемонстрировали четкую тенденцию к сходимости: + +- **Коэффициент Растущих Новых Концепций**: С начальных 10-13% стабильно снижается до 3-5%, что подтверждает насыщение графа в покрытии концепций +- **Коэффициент Растущих Новых Ребер**: С пика второго раунда (46-71%) постепенно сходит к 15-20%, что подтверждает совершенствование сети отношений между концепциями +- **Плато Покрытия**: После 4-5 раундов рост покрытия значительно замедляется, переходя в состояние сходимости + +##### **2. Анализ Различий Моделей: Баланс Качества и Стоимости** + +**Преимущества GPT-4o**: + +- **Более Высокое Покрытие**: На тех же раундах GPT-4o обычно на 2-4 процентных пункта выше, чем GPT-4o-mini +- **Быстрая Сходимость**: Для достижения того же уровня покрытия требуется меньше раундов +- **Лучшее Качество Концепций**: Проявляется в более высоком уровне соответствия ключевым словам Википедии + +**Анализ Стоимости**: + +- **Стоимость GPT-4o**: Абсолютная стоимость составляет примерно 8-15 раз больше, чем у GPT-4o-mini +- **Увеличение Производительности**: Повышение покрытия обычно составляет **2-4%** +- **Соотношение Стоимости и Эффективности**: GPT-4o-mini предлагает лучшее соотношение стоимости и эффективности в большинстве практических сценариев + +##### **3. Влияние Порога Сходства: Баланс Точности и Эффективности** + +- **Порог 0.8**: Быстрое расширение, но может включать больше схожих концепций +- **Порог 0.85**: Сбалансированный выбор, подходящий для большинства приложений +- **Порог 0.9**: Высокая точность, но медленная скорость расширения, подходит для сценариев с очень высокими требованиями к чистоте концепций + +##### **4. Кросс-Дисциплинарная Согласованность: Универсальность Метода** + +Результаты экспериментов в области сердечно-сосудистых и дыхательных систем высоко согласованы, что подтверждает надежность метода: + +- Схемы сходимости схожи +- Тенденции покрытия一致 +- Соотношение стоимости и эффективности аналогично + +#### **Практические Рекомендации** + +**Сценарии с Приоритетом Стоимости (Рекомендуется)**: + +- Используйте GPT-4o-mini + порог 0.8 +- Проведите 4-5 раундов итерации для достижения покрытия более 95% +- Контроль затрат в диапазоне $3-10 + +**Сценарии с Приоритетом Качества**: + +- Используйте GPT-4o + порог 0.85 +- Можно достичь покрытия более 97% +- Необходимо принять значительное увеличение затрат + +**Сбалансированные Сценарии**: + +- Используйте GPT-4o-mini + порог 0.85 +- Достигните покрытия 94-97% +- Умеренные затраты, приемлемое качество + +## **Генерация Памяти QA на Основе Концептуальной Карты и Дистилляция Знаний** + +После нескольких раундов итерации мы построили обширную и структурированную сеть концептуальных отношений. Однако эта сеть в настоящее время является лишь "скелетом". Чтобы превратить ее в базу знаний, которую AI может использовать напрямую, нам нужно заполнить ее конкретным содержанием — то есть высококачественными вопросами и ответами (QA). Этот процесс мы называем \*\*"Дистилляция Знаний"\*\*. + +Наша стратегия делится на два этапа: + +1. Генерация независимых пар вопросов и ответов для каждого **отдельного узла концепции** в графе, чтобы создать базовые знания. +2. Генерация связанных пар вопросов и ответов для каждой **связанной пары концепций с клиническим значением** (ребер) в графе, чтобы построить глубокие знания. + +Для достижения этой цели мы разработали `ConceptDistiller` (дистиллятор концепций) и соответствующий ему Prompt. Этот Prompt предназначен для того, чтобы направить мощную модель "учителя" (например, GPT-4o) в преобразовании изолированной медицинской концепции в учебный вопрос и ответ, насыщенный клиническим контекстом и проверяющий способности к комплексному рассуждению. Эти пары QA станут содержанием памяти "ученической" модели (малой модели, которую мы в конечном итоге хотим улучшить). + +```python + +@dataclass +class ConceptDistillationResult: + """Класс данных для результатов генерации концептуального QA""" + status: str # success, api_error, json_error + concept_id: str + concept_name: str + response: Optional[str] = None + error_details: Optional[str] = None + processing_time: Optional[float] = None + json_validation: Optional[Dict] = None + generated_questions: Optional[List[Dict]] = None + +class ConceptDistiller: + """Генератор концептуального QA - генерирует пары вопросов и ответов для каждого концепта""" + + def __init__(self, api_client: APIClient): + self.api_client = api_client + + def distill_concept(self, concept: str, concept_id: str) -> ConceptDistillationResult: + """Генерировать пары вопросов и ответов для одного концепта""" + start_time = time.time() + + # Построить подсказку + system_prompt = self.get_distillation_system_prompt() + user_prompt = self.get_distillation_prompt(concept) + + messages = [ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": user_prompt} + ] + + # Вызов API + api_result = self.api_client.call_api(messages, timeout=300) + processing_time = time.time() - start_time + + if api_result["status"] != "success": + return ConceptDistillationResult( + status="api_error", + concept_id=concept_id, + concept_name=concept, + error_details=api_result["error"], + processing_time=processing_time + ) + + # Проверка JSON Ответа + expected_keys = ["concept", "questions"] + json_validation = ResponseValidator.validate_json_response( + api_result["content"], expected_keys + ) + + if json_validation["is_valid_json"]: + questions = json_validation["parsed_json"]["questions"] + return ConceptDistillationResult( + status="success", + concept_id=concept_id, + concept_name=concept, + response=api_result["content"], + processing_time=processing_time, + json_validation=json_validation, + generated_questions=questions + ) + else: + return ConceptDistillationResult( + status="json_error", + concept_id=concept_id, + concept_name=concept, + response=api_result["content"], + error_details=f"JSON validation failed: {json_validation['error_type']}", + processing_time=processing_time, + json_validation=json_validation + ) + + @staticmethod + def get_distillation_system_prompt() -> str: + """Получить Системные Подсказки""" + return """You are a world-renowned cardiovascular specialist with 20+ years of clinical experience. Your task is to create high-quality educational content for training junior cardiovascular doctors based on the given cardiovascular concept. + +Your generated questions must require clinical reasoning and integration - avoid simple memorization questions.""" + + @staticmethod + def get_distillation_prompt(concept: str) -> str: + """Генерировать подсказку для концептуального QA""" + return f"""**TARGET CONCEPT: {concept}** + +Generate exactly 3 diverse cardiovascular clinical questions about this concept, each with complete learning materials. Follow these requirements: + +**QUESTION DESIGN PRINCIPLES:** +1. Realistic cardiovascular clinical scenarios requiring clinical reasoning +2. Every condition mentioned must be CRITICAL to the clinical decision - avoid redundant details +3. Use general descriptors (elderly patient, young adult) rather than specific ages +4. Focus on decision-making situations where this concept is central +5. **AVOID simple factual questions** - require clinical integration and reasoning + +**KNOWLEDGE FACTS REQUIREMENTS:** +- Each fact must start with the concept name as the subject +- Focus on core medical properties, mechanisms, clinical significance + +**OUTPUT FORMAT (strict JSON):** +{{ + "concept": "{concept}", + "questions": [ + {{ + "question_id": 1, + "question": "Clinical scenario question 1...", + "reasoning_guidance": "Step-by-step clinical thinking process 1...", + "knowledge_facts": [ + "{concept} fact 1...", + "{concept} fact 2...", + "{concept} fact 3..." + ], + "final_answer": "Comprehensive clinical answer..." + }}, + {{ + "question_id": 2, + "question": "Clinical scenario question 2...", + "reasoning_guidance": "Step-by-step clinical thinking process 2...", + "knowledge_facts": [ + "{concept} fact 1...", + "{concept} fact 2..." + ], + "final_answer": "Comprehensive clinical answer..." + }}, + {{ + "question_id": 3, + "question": "Clinical scenario question 3...", + "reasoning_guidance": "Step-by-step clinical thinking process 3...", + "knowledge_facts": [ + "{concept} fact 1...", + "{concept} fact 2..." + ], + "final_answer": "Comprehensive clinical answer..." + }} + ] +}} + +Generate the educational content now.""" + +class BatchConceptDistiller: + """Обработчик пакетной генерации концептуального QA""" + + def __init__(self, distiller: ConceptDistiller, output_dir: str = "concept_distillation"): + self.distiller = distiller + self.output_dir = output_dir + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + def distill_concept_graph(self, concept_graph_dict: Dict, max_workers: int = 10, + batch_size: int = 20, batch_delay: int = 0) -> Dict: + """Пакетная генерация""" + concept_list = list(concept_graph_dict.keys()) # Предполагается, что ключи dict - это названия концептов + total_concepts = len(concept_list) + print(f"Начать пакетную обработку: генерация QA для {total_concepts} концептов") + print(f"Размер партии: {batch_size}, Максимальное количество параллельных задач: {max_workers}") + + all_results = {} + batch_num = 1 + + # Обработка по пакетам + for i in range(0, total_concepts, batch_size): + batch_concepts = concept_list[i:i + batch_size] + print(f"\nОбработка партии {batch_num}: Концепция {i+1}-{min(i+batch_size, total_concepts)} ({len(batch_concepts)} штук)") + + batch_start_time = time.time() + batch_results = self._process_batch(batch_concepts, max_workers, i) + batch_end_time = time.time() + + # Сохранение результатов партии + self._save_batch_results(batch_results, batch_num, batch_start_time) + + all_results.update(batch_results) + + print(f"Пакет {batch_num} завершен, время затрачено: {batch_end_time - batch_start_time:.2f} секунд") + + batch_num += 1 + + # Перерыв между пакетами + if i + batch_size < total_concepts: + #print(f"Перерыв между партиями {batch_delay} секунд...") + time.sleep(batch_delay) + + print(f"\nВсе партии обработаны! Всего обработано {total_concepts} концепций") + return all_results + + def _process_batch(self, batch_concepts: List[str], max_workers: int, start_index: int) -> Dict: + """Обработка одного пакета""" + batch_results = {} + + with ThreadPoolExecutor(max_workers=max_workers) as executor: + # Отправка задания + future_to_concept = {} + for idx, concept in enumerate(batch_concepts): + concept_id = f"concept_{start_index + idx:06d}" + future = executor.submit(self.distiller.distill_concept, concept, concept_id) + future_to_concept[future] = (concept_id, concept) + + # Сбор результатов + completed = 0 + for future in as_completed(future_to_concept): + concept_id, concept = future_to_concept[future] + try: + result = future.result() + batch_results[concept_id] = result + + # Простое Отображение Состояния + status_symbol = "✓" if result.status == "success" else "✗" + completed += 1 + + if completed % 1000 == 0 or completed == len(batch_concepts): + success_count = sum(1 for r in batch_results.values() if r.status == "success") + print(f" Завершено: {completed}/{len(batch_concepts)} (Успешно: {success_count}) {status_symbol}") + + except Exception as e: + batch_results[concept_id] = ConceptDistillationResult( + status="exception", + concept_id=concept_id, + concept_name=concept, + error_details=str(e) + ) + print(f" Исключение: {concept_id} - {str(e)}") + + return batch_results + + def _save_batch_results(self, batch_results: Dict, batch_num: int, start_time: float): + """Сохранение результатов пакета""" + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + filename = f"concept_distillation_batch_{batch_num:03d}_{timestamp}.pkl" + filepath = os.path.join(self.output_dir, filename) + + # Статистическая информация + total_count = len(batch_results) + success_count = sum(1 for r in batch_results.values() if r.status == "success") + total_questions = sum(len(r.generated_questions) for r in batch_results.values() + if r.status == "success" and r.generated_questions) + + save_data = { + "metadata": { + "batch_num": batch_num, + "timestamp": timestamp, + "start_time": start_time, + "total_concepts": total_count, + "successful_distillations": success_count, + "total_questions_generated": total_questions + }, + "results": batch_results + } + + with open(filepath, 'wb') as f: + pickle.dump(save_data, f) + + print(f" Результаты пакета сохранены: {filename}") + print(f" Успех: {success_count}/{total_count} ({success_count/total_count*100:.1f}%)") + print(f" Общее количество сгенерированных вопросов: {total_questions}") + + return filepath + +# ==================== Удобные функции ==================== + +def distill_concept_graph(concept_graph_dict: Dict, api_url: str, api_key: str, model_name: str, max_workers: int = 10, + batch_size: int = 20, output_dir: str = "concept_distillation"): + """Удобная функция для дистилляции концептуальной карты""" + print(f"Подготовка дистилляции концептуальной карты: {len(concept_graph_dict)} концепций") + + # Инициализация API клиента + api_client = APIClient( + api_url=api_url, + api_key=api_key, + model_name=model_name + ) + + # Инициализация дистиллятора + distiller = ConceptDistiller(api_client) + batch_distiller = BatchConceptDistiller(distiller, output_dir=output_dir) + + # Пакетная дистилляция + results = batch_distiller.distill_concept_graph( + concept_graph_dict=concept_graph_dict, + max_workers=max_workers, + batch_size=batch_size, + batch_delay=1 + ) + + return results + +def test_single_concept_distillation(concept: str, api_url: str, api_key: str, model_name: str, verbose: bool = True): + """Тестирование дистилляции одной концепции""" + print("=" * 80) + print("Тест дистилляции одной концепции") + print("=" * 80) + + # Инициализация API клиента + api_client = APIClient( + api_url=api_url, + api_key=api_key, + model_name=model_name + ) + + distiller = ConceptDistiller(api_client) + + print(f"Концепция: {concept}") + print() + + # Обработка концепции + result = distiller.distill_concept(concept, "test_concept") + + print(f"Статус обработки: {result.status}") + print(f"Время обработки: {result.processing_time:.2f} секунд") + + if result.status == "success": + print(f"Количество сгенерированных вопросов: {len(result.generated_questions)}") + print("=" * 80) + print("Сгенерированные данные:") + print("=" * 80) + for i, question in enumerate(result.generated_questions, 1): + print(f"\nВопрос {i}:") + print(f"Сцена: {question['question']}") + print(f"Вывод: {question['reasoning_guidance'][:100]}...") + print(f"Факты знаний: {len(question['knowledge_facts'])} штук") + print(f"Ответ: {question['final_answer'][:100]}...") + print("=" * 80) + if verbose: + print("Исходный ответ LLM:") + print("=" * 80) + print(result.response) + print("=" * 80) + return {"success": True, "result": result} + else: + print(f"Ошибка обработки: {result.error_details}") + return {"success": False, "result": result} + +def load_and_analyze_distillation_results(results_dir: str = "concept_distillation"): + """Загрузка и анализ результатов""" + result_files = [f for f in os.listdir(results_dir) + if f.startswith('concept_distillation_batch_') and f.endswith('.pkl')] + result_files.sort() + + if not result_files: + print("Файл с результатами не найден") + return {} + + all_training_data = [] + total_concepts = 0 + total_successful = 0 + total_questions = 0 + + print("Анализ результатов:") + print("=" * 80) + + for file in result_files: + filepath = os.path.join(results_dir, file) + with open(filepath, 'rb') as f: + data = pickle.load(f) + + metadata = data['metadata'] + results = data['results'] + + total_concepts += metadata['total_concepts'] + total_successful += metadata['successful_distillations'] + total_questions += metadata['total_questions_generated'] + + print(f"Пакет {metadata['batch_num']:3d}: " + f"Всего концепций {metadata['total_concepts']:3d}, " + f"Успешно {metadata['successful_distillations']:3d} " + f"({metadata['successful_distillations']/metadata['total_concepts']*100:.1f}%), " + f"Количество вопросов {metadata['total_questions_generated']:4d}") + + # Сбор данных + for concept_id, result in results.items(): + if result.status == "success" and result.generated_questions: + for question in result.generated_questions: + training_sample = { + "concept": result.concept_name, + "concept_id": concept_id, + "question_id": question["question_id"], + "question": question["question"], + "reasoning_guidance": question["reasoning_guidance"], + "knowledge_facts": question["knowledge_facts"], + "final_answer": question["final_answer"] + } + all_training_data.append(training_sample) + + print("=" * 80) + print(f"Всего: {total_concepts} концептов, Успешно: {total_successful} ({total_successful/total_concepts*100:.1f}%)") + print(f"Сгенерировано QA: {len(all_training_data)} (в среднем по {len(all_training_data)/total_successful:.1f} на концепт)") + + return { + "training_data": all_training_data, + "statistics": { + "total_concepts": total_concepts, + "successful_distillations": total_successful, + "total_questions": total_questions, + "training_samples": len(all_training_data) + } + } + +if __name__ == "__main__": + print("=" * 80) + print("Система генерации концепт QA") + print("=" * 80) + + # Пример использования + print("Метод использования:") + print("1. test_single_concept_distillation('atrial_fibrillation') - Тестирование одного концепта") + print("2. distill_concept_graph(concept_graph_dict) - Пакетная генерация концепт QA") + print("3. load_and_analyze_distillation_results() - Анализ результатов") + print("\nПример:") + print("# Пакетное выполнение") + print("# distillation_results = distill_concept_graph(your_concept_graph_dict, max_workers=10, batch_size=20)") +``` + +Перед запуском крупномасштабной пакетной обработки хорошей практикой является проверка того, работает ли Prompt и логика кода так, как ожидается. Ниже приведен код, который представляет собой такой модульный тест, который на примере "мерцательной аритмии (atrial_fibrillation)" вызывает функцию `test_single_concept_distillation` для тестирования эффекта генерации QA для одного концепта. + +```python +# Тестирование увеличения одного концепта +test_single_concept_distillation('atrial_fibrillation') +``` + +На практике нам может не понадобиться генерировать QA для всех концептов в графе. В зависимости от целей проекта мы можем выбрать подходящий подмножество. Как упоминалось в начале этого раздела, наша стратегия заключается в том, чтобы выбрать подграф среднего размера (узлы после 3 итераций), но с более зрелыми связями (ребра после 5 итераций) в качестве области для знания дистилляции. + +Ниже приведен код, который предназначен для достижения этой цели. Он сначала загружает два различных файла графа на разных этапах итерации, а затем с помощью функций `extract_subgraph` и `extract_unique_edges` точно строит целевой граф `filtered_graph`, который мы используем для генерации QA. + +```python +# Фильтрация для получения текущей целевой концепт-графа + +import pickle +with open('cookbooktest/Cardio/concept_graph_4omini_5_iter.pkl', 'rb') as f: + concept_dict = pickle.load(f) + +import pickle +with open('cookbooktest/Cardio/concept_graph_4omini_3_iter.pkl', 'rb') as f: + sub_concept_dict = pickle.load(f) + +def extract_subgraph(full_graph_dict, sub_concept_set): + """Извлечение подграфа, оставляя только указанные концепты и их связи""" + + # Если sub_concept_set является dict, возьмите его keys; если это list/set, используйте напрямую + if isinstance(sub_concept_set, dict): + valid_concepts = set(sub_concept_set.keys()) + else: + valid_concepts = set(sub_concept_set) + + subgraph = {} + + for concept, neighbors in full_graph_dict.items(): + # Обрабатывайте только концепции в подмножестве + if concept in valid_concepts: + # Сохраняйте только концепции среди соседей, которые также находятся в подмножестве + filtered_neighbors = [n for n in neighbors if n in valid_concepts] + if filtered_neighbors: # Сохраняйте только узлы с соседями + subgraph[concept] = filtered_neighbors + + print(f"Исходный граф: {len(full_graph_dict)} узлов") + print(f"Подграф: {len(subgraph)} узлов") + + # Подсчет количества ребер + total_edges = sum(len(neighbors) for neighbors in subgraph.values()) + print(f"Количество ребер подграфа: {total_edges}") + + return subgraph + +filtered_graph = extract_subgraph(concept_dict, sub_concept_dict) + +# Удаление дублирующихся ребер +def extract_unique_edges(graph_dict): + """Извлечение уникальных пар ребер из графа, двусторонние ребра сохраняются только одно""" + + processed_pairs = set() + unique_edges = [] + + for concept_a, neighbors in graph_dict.items(): + for concept_b in neighbors: + # Сортировка для обеспечения того, чтобы (A,B) и (B,A) рассматривались как одна и та же пара + edge = tuple(sorted([concept_a, concept_b])) + + if edge not in processed_pairs: + processed_pairs.add(edge) + unique_edges.append(edge) + + print(f"Общее количество ребер: {sum(len(neighbors) for neighbors in graph_dict.values())}") + print(f"Количество ребер после удаления дубликатов: {len(unique_edges)}") + + return unique_edges + +# Использование +unique_edges = extract_unique_edges(filtered_graph) + +# Просмотр первых нескольких ребер +print("Передние 5 ребер:") +for i, (a, b) in enumerate(unique_edges[:5]): + print(f"{i+1}. {a} <-> {b}") +``` + +```python +# Пакетное извлечение qa для одного концепта +results = distill_concept_graph( + concept_graph_dict=example_concept_dict, + max_workers=100, # Число параллельных потоков + batch_size=1000, # Размер пакета + output_dir="cookbooktest/Cardio", # Место сохранения + api_url=api_url, + api_key=api_key, + model_name=QA_SYNTHESIZER +) +``` + +На практике мы выбрали подграф среднего размера (узлы после 3 итераций), но с более зрелыми связями (ребра после 5 итераций) в качестве области для знания дистилляции, чтобы сбалансировать широту и глубину знаний. Для дистилляции знаний пар концептов мы разработали более сложный "оценка-генерация" двухступенчатый Prompt. LLM сначала играет роль "фильтра", строго оценивая клиническую связь и образовательную ценность пар концептов, только "золотые комбинации", прошедшие оценку, перейдут на второй этап, чтобы сгенерировать QA-пару, которая одновременно охватывает два концепта и имеет более сложную логику. + +```python +# Для генерации извлечений вопросов концептной пары, не будем углубляться, мы предоставим подсказку в качестве вдохновения: + @staticmethod + def get_pair_system_prompt() -> str: + """Получить подсказки для оценки концептной пары""" + return """You are a world-renowned cardiovascular specialist with 20+ years of clinical experience. Your task is to rigorously evaluate concept pairs and generate high-quality educational content. You must act as a **strict filter**, approving only pairs with a **direct, critical, and undeniable link** in clinical practice and training.""" + + @staticmethod + def get_pair_prompt(concept_pairs: List[tuple]) -> str: + """Сгенерировать подсказки для оценки концептной пары""" + pairs_text = "" + for i, (concept_a, concept_b) in enumerate(concept_pairs, 1): + pairs_text += f"{i}. {concept_a} <-> {concept_b}\n" + + return f"""**CONCEPT PAIRS TO EVALUATE:** +{pairs_text} + +For each pair, you must strictly evaluate the following two criteria. **BOTH must be strongly true** to proceed. + +1. **Direct Clinical Relevance**: Is there a **direct causal, pathophysiological, diagnostic, or therapeutic link** between the two concepts? The connection should not just a weak, coincidental, or indirect association. One concept must frequently and directly influence the consideration of the other in **critical clinical decision-making**. + +2. **Essential Educational Value**: Does understanding this specific link teach a **crucial, non-obvious clinical reasoning skill**? The relationship should highlight a common point of confusion to be clarified, a key differential diagnosis, or a pivotal management decision. It must be more than a simple factual association. + +**EXAMPLE OF A PAIR TO REJECT:** +- `"Hypertension" <-> "Stethoscope"`: While a stethoscope is used in the diagnosis of hypertension, this is a basic procedural fact. + +For each pair that meet the stringent criteria: +1. Generate 1 clinical question covering BOTH concepts. +2. Every condition mentioned must be CRITICAL to the clinical decision - avoid redundant details +3. Use general descriptors (elderly patient, young adult) rather than specific ages +4. Focus on decision-making situations where simultaneously considering the concept pairs is central +5. **AVOID simple factual questions** - require clinical integration and reasoning + +**OUTPUT FORMAT (strict JSON):** +{{ + "evaluated_pairs": [ + {{ + "concept_pair": ["concept_a", "concept_b"], + "is_clinically_relevant": true, + "is_instructionally_meaningful": true, + "question": {{ + "question": "Clinical scenario covering both concepts...", + "reasoning_guidance": "Step-by-step clinical thinking...", + "knowledge_facts": [ + "Concept_a fact 1...", + "Concept_b fact 1...", + "Concept_a fact 2..." + ], + "final_answer": "Comprehensive answer..." + }} + }}, + {{ + "concept_pair": ["concept_x", "concept_y"], + "is_clinically_relevant": false, + "is_instructionally_meaningful": false, + "question": null + }} + ] +}} + +Generate the evaluation and content now.""" +``` + +--- + +## **Пример структуры данных QA** + +Все QA-данные, сгенерированные в процессе дистилляции знаний, будут организованы в единый, стандартный формат JSON-объекта для удобства последующего чтения и обработки программами. Эта структура содержит следующие ключевые поля: + +- `concept`: источник знаний, может быть одним концептом (строка) или парой концептов (список). +- `question`: основной клинический вопрос. +- `reasoning_guidance`: клинический путь мышления для решения этого вопроса. +- `knowledge_facts`: ключевые знания, необходимые для ответа на этот вопрос. +- `final_answer`: комплексный, авторитетный ответ на вопрос. + +Мы назвали все отформатированные QA-данные `qa_collection`. + +1. **Пример QA для одного концепта** + +```python +{'concept': 'ankylosing spondylitis', + 'question': 'A young adult patient with a 5-year history of ankylosing spondylitis presents with unexplained fatigue and palpitations. Laboratory tests reveal anemia and elevated acute phase reactants. In the context of ankylosing spondylitis, what cardiovascular complication should be explored, and what is the likely mechanism of the heart condition related to this systemic inflammatory disease?', + 'reasoning_guidance': 'Identify the common systemic manifestations of ankylosing spondylitis including inflammation and anemia. Consider the cardiovascular implications of chronic inflammation and anemia on cardiac function. Explore the mechanism by which systemic diseases like ankylosing spondylitis can result in heart conditions such as myocardial fibrosis or dysfunction.', + 'knowledge_facts': ['ankylosing spondylitis can cause systemic inflammation, contributing to cardiovascular complications like myocardial fibrosis.', + 'ankylosing spondylitis-associated inflammation can lead to chronic anemia, affecting cardiovascular health.', + 'ankylosing spondylitis may lead to cardiac conduction system involvement, resulting in palpitations.'], + 'final_answer': "Given the patient's symptoms and laboratory findings, myocardial fibrosis due to systemic inflammation related to ankylosing spondylitis should be explored. The fatigue and palpitations may be due, in part, to anemia exacerbating cardiac stress, and inflammation leading to fibrosis, altering cardiac conduction and function."} + +``` + +2. **Пример QA для пары концептов** + +```python +{'concept': ['apical hypertrophy of the lv', 'myocardial ischaemia'], + 'question': 'A middle-aged adult with a history of hypertension presents with exertional chest pain. Echocardiography reveals apical hypertrophy of the left ventricle. How would you differentiate between hypertrophic cardiomyopathy and myocardial ischaemia as the cause of the symptoms?', + 'reasoning_guidance': 'Consider the role of diagnostic imaging and stress testing in distinguishing between structural heart changes and ischemic heart conditions. Evaluate the characteristic findings of apical hypertrophy and myocardial ischemia.', + 'knowledge_facts': ['Apical hypertrophy can mimic signs of myocardial ischaemia.', + 'Myocardial ischaemia is often indicated by ST-segment changes during stress.', + 'Hypertrophic cardiomyopathy may present with specific echocardiographic patterns of ventricular thickening.'], + 'final_answer': 'To differentiate hypertrophic cardiomyopathy from myocardial ischaemia, perform a stress test to assess for changes indicative of ischemia and use advanced imaging modalities like cardiac MRI, which can provide detailed myocardial characterization.'} + +``` + +--- + +## **Последний шаг: построение и экспорт MemCube** + +На этом все подготовительные работы завершены. Теперь мы собираемся собрать эти независимые "единицы знаний" (`qa_collection`) в мощную, взаимосвязанную сеть знаний — **MemCube**. + +Процесс построения следующий: + +1. **Концепты как скелет**: каждый "концепт" в графе концептов станет независимым **узлом** в MemCube. +2. **QA как плоть**: каждая "QA-пара" также станет независимым **узлом** и будет связана с одним или двумя узлами концептов, откуда она произошла. +3. **Вопрос как индекс**: мы векторизуем **текст вопроса (question)** в каждом узле QA, чтобы использовать его в качестве семантического "адреса" в сети памяти для быстрого поиска. + +Ниже приведен Python-скрипт, который в одном шаге завершает этот процесс преобразования. Он загружает `qa_collection`, извлекает и создает все узлы концептов и узлы QA, а затем устанавливает связи между узлами на основе заданной логики, в конечном итоге собирая все узлы и ребра в полный JSON-объект, соответствующий формату MemOS, и экспортируя его в файл. + +```python +import os +from sentence_transformers import SentenceTransformer +import torch +model = SentenceTransformer( + EMBEDDING_MODEL, + trust_remote_code=True +) +# ============================================================================= +# Ячейка 1: Импорт библиотек и вспомогательных функций +# ============================================================================= +import pickle +import uuid +import json +from datetime import datetime +from collections import defaultdict +import numpy as np + +# Загрузка данных +with open("cookbooktest/Cardio/qa_collection.pkl", 'rb') as f: + qa_collection = pickle.load(f) + +print(f"✅ Загружено {len(qa_collection)} QA данных") + +def generate_real_embedding_batch(texts, batch_size=50): + """Пакетная генерация векторов embedding""" + if isinstance(texts, str): + # Один текст, обрабатываем напрямую + embedding = model.encode(texts, convert_to_tensor=False) + return embedding.tolist() + + # Пакетная обработка + all_embeddings = [] + total = len(texts) + + for i in range(0, total, batch_size): + batch_end = min(i + batch_size, total) + batch_texts = texts[i:batch_end] + + print(f" Пакет embedding {i//batch_size + 1}/{(total-1)//batch_size + 1} ({len(batch_texts)} текстов)") + + # Пакетное кодирование + batch_embeddings = model.encode(batch_texts, convert_to_tensor=False, show_progress_bar=False) + + # Преобразовать в список и добавить в результат + for emb in batch_embeddings: + all_embeddings.append(emb.tolist()) + + return all_embeddings + +# ============================================================================= +# Ячейка 2: Проверка данных и извлечение концепций +# ============================================================================= +def extract_unique_concepts(qa_collection): + """Извлечь все уникальные концепции из данных QA и проверить формат данных""" + unique_concepts = set() + invalid_data = [] + valid_concept_qa = 0 + valid_relation_qa = 0 + + for i, qa_data in enumerate(qa_collection): + if isinstance(qa_data['concept'], str): + # Concept QA - Одна концепция + unique_concepts.add(qa_data['concept']) + valid_concept_qa += 1 + elif isinstance(qa_data['concept'], list): + # Relation QA - Должно быть парой из 2 концепций + if len(qa_data['concept']) == 2: + unique_concepts.update(qa_data['concept']) + valid_relation_qa += 1 + else: + # Аномалия данных: не 2 концепции + invalid_data.append({ + 'index': i, + 'concept': qa_data['concept'], + 'length': len(qa_data['concept']), + 'question': qa_data['question'][:100] + "..." + }) + else: + # Аномалия данных: концепция не является ни str, ни list + invalid_data.append({ + 'index': i, + 'concept': qa_data['concept'], + 'type': type(qa_data['concept']), + 'question': qa_data['question'][:100] + "..." + }) + + # Сообщить результаты проверки данных + print(f"📊 Результаты проверки данных:") + print(f" - Действительные Concept QA: {valid_concept_qa}") + print(f" - Действительные Relation QA: {valid_relation_qa}") + print(f" - Аномальные данные: {len(invalid_data)}") + print(f" - Извлеченные уникальные концепции: {len(unique_concepts)}") + + if invalid_data: + print(f"\n⚠️ Подробности аномальных данных:") + for item in invalid_data[:3]: # Показать только первые 3 + print(f" 索引{item['index']}: concept={item['concept']}") + print(f" Вопрос: {item['question']}") + if len(invalid_data) > 3: + print(f" ... Осталось {len(invalid_data) - 3} исключительных данных") + + return list(unique_concepts), invalid_data, valid_concept_qa, valid_relation_qa + +# Выполнение проверки данных +print("🔍 Начало проверки данных...") +unique_concepts, invalid_data, valid_concept_qa, valid_relation_qa = extract_unique_concepts(qa_collection) + +print(f"\n✅ Пример списка концепций: {list(unique_concepts)[:5]}...") + +# ============================================================================= +# Ячейка 3: Создание узлов концепций +# ============================================================================= +def create_concept_nodes(unique_concepts): + """Создание всех узлов концепций - использование названия концепции в качестве memory и embedding""" + concept_nodes = {} + + print(f"Начинаем генерировать embedding для {len(unique_concepts)} концепций...") + + # Пакетная генерация embedding концепций + concept_embeddings = generate_real_embedding_batch(unique_concepts, batch_size=100) + + for i, (concept, embedding) in enumerate(zip(unique_concepts, concept_embeddings)): + concept_id = str(uuid.uuid4()) + + node = { + "id": concept_id, + "memory": concept, # Название концепции в качестве memory + "metadata": { + "type": "fact", + "memory_type": "UserMemory", + "status": "activated", + "entities": [concept], + "tags": [concept], + "embedding": embedding, # embedding названия концепции + "created_at": datetime.now().isoformat(), + "usage": [], + "background": "" + } + } + + concept_nodes[concept] = { + "id": concept_id, + "node": node + } + + if (i + 1) % 20 == 0: + print(f" Завершено {i + 1}/{len(unique_concepts)} концепций") + + print(f"✅ Создано {len(concept_nodes)} узлов концепций") + return concept_nodes + +# Выполнение создания узлов концепций +print("🏗️ Создание концептуального узла...") +concept_nodes = create_concept_nodes(unique_concepts) +print("Идентификатор примера концептуального узла:", list(concept_nodes.keys())[0], "->", concept_nodes[list(concept_nodes.keys())[0]]["id"]) + +# ============================================================================= +# Ячейка 4: Создание QA узлов +# ============================================================================= +def create_qa_nodes(qa_collection, concept_nodes): + """Создание всех QA узлов - Оптимизация эмбеддингов批量""" + + # 1. Сначала соберите все текстовые вопросы и метаданные + all_questions = [] + all_metadata = [] + skipped_count = 0 + + for qa_data in qa_collection: + question = qa_data['question'] + + # Построение полного содержимого памяти + memory_content = f"""Question: {qa_data['question']} + +Reasoning Guidance: {qa_data['reasoning_guidance']} + +Knowledge Facts: {'; '.join(qa_data['knowledge_facts'])} + +Answer: {qa_data['final_answer']}""" + + # Определение типа QA и подготовка метаданных + if isinstance(qa_data['concept'], str): + # Concept QA + concept_name = qa_data['concept'] + if concept_name not in concept_nodes: + print(f" Предупреждение: Концепция '{concept_name}' не существует, пропускаем этот QA") + skipped_count += 1 + continue + + qa_type = "concept_qa" + entities = [concept_name] + tags = [concept_name] + related_concept_ids = [concept_nodes[concept_name]["id"]] + + elif isinstance(qa_data['concept'], list) and len(qa_data['concept']) == 2: + # Relation QA + concept_names = qa_data['concept'] + + # Проверка существования всех концепций + missing_concepts = [name for name in concept_names if name not in concept_nodes] + if missing_concepts: + print(f" Предупреждение: Концепции {missing_concepts} не существуют, пропускаем этот QA") + skipped_count += 1 + continue + + qa_type = "relation_qa" + entities = concept_names + tags = concept_names + related_concept_ids = [concept_nodes[name]["id"] for name in concept_names] + + else: + # Пропуск аномальных данных + skipped_count += 1 + continue + + all_questions.append(question) + all_metadata.append({ + 'memory_content': memory_content, + 'qa_type': qa_type, + 'entities': entities, + 'tags': tags, + 'related_concept_ids': related_concept_ids + }) + + print(f"Собрано {len(all_questions)} действительных вопросов (пропущено {skipped_count}), начинаем массовую генерацию эмбеддингов...") + + # 2. Массовая генерация эмбеддингов для всех вопросов + all_embeddings = generate_real_embedding_batch(all_questions, batch_size=100) + + # 3. Создание QA узлов + qa_nodes = [] + concept_qa_count = 0 + relation_qa_count = 0 + + for i, (question, metadata, embedding) in enumerate(zip(all_questions, all_metadata, all_embeddings)): + qa_id = str(uuid.uuid4()) + + node = { + "id": qa_id, + "memory": metadata['memory_content'], + "metadata": { + "type": "fact", + "memory_type": "UserMemory", + "status": "activated", + "entities": metadata['entities'], + "tags": metadata['tags'], + "embedding": embedding, # Эмбеддинг вопроса + "created_at": datetime.now().isoformat(), + "usage": [], + "background": "", + # Временное Поле, Используемое Для Создания Ребер Связи + "qa_type": metadata['qa_type'], + "related_concept_ids": metadata['related_concept_ids'] + } + } + + qa_nodes.append(node) + + if metadata['qa_type'] == "concept_qa": + concept_qa_count += 1 + else: + relation_qa_count += 1 + + if (i + 1) % 50 == 0: + print(f" Создано {i + 1}/{len(all_questions)} Узлов QA") + + print(f"✅ Создано {len(qa_nodes)} Узлов QA") + print(f" - Concept QA: {concept_qa_count}") + print(f" - Relation QA: {relation_qa_count}") + + return qa_nodes + +# Выполнение Создания Узлов QA +print("🏗️ Создание Узлов QA...") +qa_nodes = create_qa_nodes(qa_collection, concept_nodes) +if qa_nodes: + print(f"Пример Узла QA: {qa_nodes[0]['metadata']['qa_type']}") +``` + +```python + +# ============================================================================= +# Ячейка 5: Создание Ребер Связи +# ============================================================================= +def create_edges(concept_nodes, qa_nodes, qa_collection): + """Создание Ребер Связи Между Узлами""" + edges = [] + edge_set = set() # Используется Для Удаления Дубликатов Ребер + + # 1. Концепция↔Концепция RELATE_TO Связь (Выводится Из Relation QA) + concept_relations = set() + for qa_data in qa_collection: + if isinstance(qa_data['concept'], list) and len(qa_data['concept']) == 2: + # Relation QA Указывает На Наличие Клинической Связи Между Двумя Концепциями + concept_A, concept_B = qa_data['concept'] + if concept_A in concept_nodes and concept_B in concept_nodes: + relation_key = tuple(sorted([concept_A, concept_B])) + concept_relations.add(relation_key) + + relate_count = 0 + for concept_A, concept_B in concept_relations: + concept_A_id = concept_nodes[concept_A]["id"] + concept_B_id = concept_nodes[concept_B]["id"] + + edge_key = tuple(sorted([concept_A_id, concept_B_id])) + if edge_key not in edge_set: + edges.append({ + "source": concept_A_id, + "target": concept_B_id, + "type": "RELATE_TO" + }) + edge_set.add(edge_key) + relate_count += 1 + + print(f"✅ Создано {relate_count} Связей RELATE_TO Между Концепциями") + + # 2. Концепция PARENT QA Связь (Concept QA) + parent_count = 0 + for qa_node in qa_nodes: + if qa_node['metadata']['qa_type'] == "concept_qa": + concept_id = qa_node['metadata']['related_concept_ids'][0] + + edges.append({ + "source": concept_id, + "target": qa_node['id'], + "type": "PARENT" + }) + parent_count += 1 + + print(f"✅ Создано {parent_count} Связей Концепция→QA PARENT") + + # 3. Концепция PARENT QA Связь (Relation QA - Мостовые Вопросы) + relation_parent_count = 0 + for qa_node in qa_nodes: + if qa_node['metadata']['qa_type'] == "relation_qa": + qa_id = qa_node['id'] + + # Убедитесь, что related_concept_ids действительны + if 'related_concept_ids' in qa_node['metadata']: + for concept_id in qa_node['metadata']['related_concept_ids']: + edges.append({ + "source": concept_id, # Концепция как родительский узел + "target": qa_id, # Вопрос-бридж как дочерний узел + "type": "PARENT" + }) + relation_parent_count += 1 + + print(f"✅ Создано {relation_parent_count} отношений концепция→бридж QA PARENT") + print(f"📊 Общее количество отношений: {len(edges)}") + + return edges + +# Выполнение создания отношений рёбер +print("🔗 Создание рёбер отношений...") +edges = create_edges(concept_nodes, qa_nodes, qa_collection) + +# ============================================================================= +# Ячейка 6: Сборка и сохранение окончательного JSON +# ============================================================================= +def assemble_final_json(concept_nodes, qa_nodes, edges): + """Сборка окончательного формата JSON TextualMemoryItem""" + + # Объединение всех узлов + all_nodes = [] + + # Добавление узлов концепции + for concept_data in concept_nodes.values(): + all_nodes.append(concept_data["node"]) + + # Добавление узлов QA, очистка временных полей + for qa_node in qa_nodes: + # Глубокое копирование узлов, чтобы избежать изменения оригинальных данных + clean_node = { + "id": qa_node["id"], + "memory": qa_node["memory"], + "metadata": qa_node["metadata"].copy() + } + + # Удаление временных полей + if "qa_type" in clean_node["metadata"]: + del clean_node["metadata"]["qa_type"] + if "related_concept_ids" in clean_node["metadata"]: + del clean_node["metadata"]["related_concept_ids"] + + all_nodes.append(clean_node) + + # Построение окончательной структуры + result = { + "nodes": all_nodes, + "edges": edges + } + + print(f"✅ Итоговый JSON содержит:") + print(f" - Количество узлов: {len(all_nodes)}") + print(f" - Количество рёбер: {len(edges)}") + print(f" - Узлы концепции: {len(concept_nodes)}") + print(f" - Узлы QA: {len(qa_nodes)}") + print(f"✅ Временные поля очищены") + + return result + +# Выполнение окончательной сборки +print("📦 Сборка итогового JSON...") +final_json = assemble_final_json(concept_nodes, qa_nodes, edges) +``` + +```python +def save_final_json(result, filename="cardio_textual_memory_graph.json"): + """Сохранить итоговый JSON в файл""" + with open(filename, 'w', encoding='utf-8') as f: + json.dump(result, f, ensure_ascii=False, indent=2) + + print(f"✅ Сохранено в файл: {filename}") + return filename + + +# Сохранение результата +filename = save_final_json(final_json, "cookbooktest/Cardio/cardio_textual_memory_graph.json") + +print("\n🎉 Конвертация завершена!") +print(f"📄 Выходной файл: {filename}") +print(f"📋 Итоговая статистика:") +print(f" - Всего узлов: {len(final_json['nodes'])}") +print(f" - Общее количество рёбер: {len(final_json['edges'])}") + +# Показать некоторые примеры данных для проверки +if final_json['nodes']: + sample_node = final_json['nodes'][0] + print(f"\n📝 Пример узлов:") + print(f" ID: {sample_node['id']}") + print(f" Memory: {sample_node['memory'][:50]}...") + print(f" Type: {sample_node['metadata']['type']}") + print(f" Entities: {sample_node['metadata']['entities']}") + +if final_json['edges']: + sample_edge = final_json['edges'][0] + print(f"\n🔗 Пример рёбер:") + print(f" {sample_edge['source']} --{sample_edge['type']}--> {sample_edge['target']}") +``` + +### **Загрузка MemCube** + +Теперь пришло время внедрить этот "цифровой чертеж" в высокопроизводительное постоянное хранилище, чтобы он стал MemCube, доступным для MemOS в реальном времени. + +Мы предоставили скрипт для пакетного импорта, оптимизированного для производительности, который может обойти узкие места по добавлению по одному, эффективно загружая весь MemCube, при этом гарантируя, что его структура данных полностью совместима с MemOS. Основные задачи этого скрипта включают: создание ограничений базы данных, пакетный импорт узлов и ребер, создание векторного индекса (что является ключом к реализации семантического поиска на уровне миллисекунд) и проверка совместимости. + +```python +# Загрузка memcube в neo4j + +#!/usr/bin/env python3 +import sys +import os +import ijson +import json +import time +from datetime import datetime +from decimal import Decimal +from neo4j import GraphDatabase + +# ===================== Информация о конфигурации - Пожалуйста, измените следующую информацию ===================== +NEO4J_URI = 'bolt://localhost:7687' +NEO4J_USERNAME = 'your neo4j username' +NEO4J_PASSWORD = 'your neo4j password' +NEO4J_DATABASE = 'neo4j' +JSON_FILE_PATH = 'cookbooktest/Cardio/cardio_textual_memory_graph.json' +# =================================================================== + +# Глобальный экземпляр драйвера +driver = None + +def get_driver(): + """Получить экземпляр драйвера Neo4j""" + global driver + if not driver: + try: + driver = GraphDatabase.driver( + NEO4J_URI, + auth=(NEO4J_USERNAME, NEO4J_PASSWORD) + ) + except Exception as e: + print(f"❌ Ошибка создания драйвера: {e}") + sys.exit(1) + return driver + +def close_driver(): + """Закрыть соединение драйвера""" + global driver + if driver: + driver.close() + driver = None + +def test_neo4j_connection(): + """Проверка соединения с Neo4j""" + try: + driver = get_driver() + with driver.session() as session: + result = session.run("RETURN 'Connection OK' AS message") + print(f"✅ Соединение с Neo4j успешно: {result.single()['message']}") + return True + except Exception as e: + print(f"❌ Ошибка соединения с Neo4j: {e}") + return False + +def create_memos_compatible_schema(): + """Создать схему и индексы, совместимые с MemOS""" + print("Создание структуры данных, совместимой с MemOS...") + + try: + driver = get_driver() + with driver.session() as session: + # Создание ограничений, совместимых с MemOS + session.run(""" + CREATE CONSTRAINT memory_id_unique IF NOT EXISTS + FOR (n:Memory) REQUIRE n.id IS UNIQUE + """) + print("✅ Создание уникального ограничения ID узла Memory") + return True + + except Exception as e: + print(f"❌ Ошибка создания схемы: {e}") + return False + +def bulk_import_nodes(): + """Пакетный импорт узлов - Нативный способ Neo4j""" + print("\n" + "=" * 50) + print("Начало пакетного импорта узлов в Neo4j") + print("=" * 50) + + driver = config.get_driver() + start_time = time.time() + success_count = 0 + batch_size = 5000 # Большие партии для достижения наилучшей производительности + batch = [] + + try: + with open(config.json_file_path, 'rb') as f: + nodes = ijson.items(f, 'nodes.item') + + for node in nodes: + # Подготовка данных узлов, совместимых с MemOS + node_data = prepare_memos_node(node) + batch.append(node_data) + + # Выполнение пакетного импорта + if len(batch) >= batch_size: + batch_success = execute_node_batch(driver, batch) + success_count += batch_success + batch = [] + + # Отображение прогресса + elapsed = time.time() - start_time + rate = success_count / elapsed + eta_minutes = (200000 - success_count) / rate / 60 + + print(f" Импортировано: {success_count:,}/200,000 ({success_count/200000*100:.1f}%) | " + f"Скорость: {rate:.1f} узлов/сек | " + f"Ожидаемое время: {eta_minutes:.1f} минут") + + # Обработка оставшихся партий + if batch: + batch_success = execute_node_batch(driver, batch) + success_count += batch_success + + total_time = time.time() - start_time + print(f"\n✅ Пакетный импорт узлов завершен:") + print(f" Импортируемое количество: {success_count:,}") + print(f" Общее время: {total_time/60:.1f} минут") + print(f" Средняя скорость: {success_count/total_time:.1f} узлов/сек") + return success_count + + except Exception as e: + print(f"❌ Ошибка массового импорта: {e}") + return success_count + + +def clean_data_types(obj): + """Очистка типов данных, чтобы обеспечить совместимость с Neo4j""" + if isinstance(obj, dict): + return {k: clean_data_types(v) for k, v in obj.items()} + elif isinstance(obj, list): + return [clean_data_types(item) for item in obj] + elif isinstance(obj, Decimal): + return float(obj) + elif obj is None: + return None + else: + return obj + +def prepare_memos_node(node): + """Подготовка данных узлов, совместимых с MemOS""" + # Сначала очистим типы данных + node = clean_data_types(node) + metadata = node.get('metadata', {}).copy() + + # Убедимся в наличии необходимых полей + if 'created_at' not in metadata: + metadata['created_at'] = datetime.now().isoformat() + if 'updated_at' not in metadata: + metadata['updated_at'] = datetime.now().isoformat() + + return { + 'id': node.get('id'), + 'memory': node.get('memory', ''), + 'metadata': clean_data_types(metadata) + } + +def execute_node_batch(driver, batch): + """Выполнение массового импорта узлов""" + cypher_query = """ + UNWIND $batch AS nodeData + MERGE (n:Memory {id: nodeData.id}) + SET n.memory = nodeData.memory, + n.created_at = datetime(nodeData.metadata.created_at), + n.updated_at = datetime(nodeData.metadata.updated_at), + n += nodeData.metadata + RETURN count(n) as imported + """ + + try: + with driver.session() as session: + result = session.run(cypher_query, batch=batch) + return result.single()['imported'] + except Exception as e: + print(f" Ошибка импорта пакета: {e}") + return 0 + +def bulk_import_edges(): + """Массовый импорт рёбер""" + print("\n" + "=" * 50) + print("Начало массового импорта рёбер в Neo4j") + print("=" * 50) + + driver = config.get_driver() + start_time = time.time() + success_count = 0 + batch_size = 10000 # Рёбра могут использовать большие пакеты + batch = [] + + try: + with open(config.json_file_path, 'rb') as f: + edges = ijson.items(f, 'edges.item') + + for edge in edges: + # Очистка типов данных рёбер + edge_clean = clean_data_types(edge) + batch.append({ + 'source': edge_clean.get('source'), + 'target': edge_clean.get('target'), + 'type': edge_clean.get('type') + }) + + if len(batch) >= batch_size: + batch_success = execute_edge_batch(driver, batch) + success_count += batch_success + batch = [] + + elapsed = time.time() - start_time + rate = success_count / elapsed + eta_minutes = (500000 - success_count) / rate / 60 + + if success_count % 50000 == 0: # Показать каждые 50000 записей + print(f" Импортировано: {success_count:,}/500,000 ({success_count/500000*100:.1f}%) | " + f"Скорость: {rate:.1f} ребер/сек | " + f"Ожидаемое время: {eta_minutes:.1f} минут") + + # Обработка оставшихся партий + if batch: + batch_success = execute_edge_batch(driver, batch) + success_count += batch_success + + total_time = time.time() - start_time + print(f"\n✅ Импорт ребер завершен:") + print(f" Импортируемое количество: {success_count:,}") + print(f" Общее время: {total_time/60:.1f} минут") + print(f" Средняя скорость: {success_count/total_time:.1f} ребер/сек") + return success_count + + except Exception as e: + print(f"❌ Ошибка импорта ребер: {e}") + return success_count + +def execute_edge_batch(driver, batch): + """Выполнение импорта партии ребер""" + cypher_query = """ + UNWIND $batch AS edgeData + MATCH (source:Memory {id: edgeData.source}) + MATCH (target:Memory {id: edgeData.target}) + MERGE (source)-[r:PARENT]->(target) + RETURN count(r) as imported + """ + + try: + with driver.session() as session: + result = session.run(cypher_query, batch=batch) + return result.single()['imported'] + except Exception as e: + print(f" Ошибка импорта партии ребер: {e}") + return 0 + +def create_memos_indexes(): + """Создание индекса, необходимого для MemOS""" + print("\n" + "=" * 50) + print("Создание индекса, совместимого с MemOS") + print("=" * 50) + + try: + driver = config.get_driver() + with driver.session() as session: + # Общие индексы MemOS + indexes = [ + "CREATE INDEX memory_type_idx IF NOT EXISTS FOR (n:Memory) ON (n.memory_type)", + "CREATE INDEX memory_status_idx IF NOT EXISTS FOR (n:Memory) ON (n.status)", + "CREATE INDEX memory_created_at_idx IF NOT EXISTS FOR (n:Memory) ON (n.created_at)", + "CREATE INDEX memory_updated_at_idx IF NOT EXISTS FOR (n:Memory) ON (n.updated_at)", + "CREATE INDEX memory_user_name_index IF NOT EXISTS FOR (n:Memory) ON (n.user_name)" + ] + + for index_query in indexes: + session.run(index_query) + print(f"✅ Индекс создан: {index_query.split()[-7]}") # Извлечение имени индекса + + # Создание векторного индекса - необходимо для векторного поиска MemOS + try: + session.run(""" + CREATE VECTOR INDEX memory_vector_index IF NOT EXISTS + FOR (n:Memory) ON (n.embedding) + OPTIONS {indexConfig: { + `vector.dimensions`: 768, + `vector.similarity_function`: 'cosine' + }} + """) + print("✅ Векторный индекс создан: memory_vector_index (768 измерений)") + except Exception as ve: + print(f"⚠️ Ошибка создания векторного индекса: {ve}") + print(" Функция векторного поиска будет недоступна") + print("✅ Все индексы, совместимые с MemOS, созданы") + + except Exception as e: + print(f"❌ Ошибка создания индекса: {e}") + +def verify_memos_compatibility(): + """Проверка совместимости MemOS""" + print("\n" + "=" * 50) + print("Проверка совместимости MemOS") + print("=" * 50) + + try: + # Добавить путь MemOS + sys.path.append('./MemOS/src') + from memos.configs.graph_db import GraphDBConfigFactory + from memos.graph_dbs.factory import GraphStoreFactory + + # Создать конфигурацию MemOS + graph_config = GraphDBConfigFactory( + backend="neo4j", + config={ + "uri": config.uri, + "user": config.username, + "password": config.password, + "db_name": config.database, + "auto_create": False, + "embedding_dimension": 768, + } + ) + + graph_store = GraphStoreFactory.from_config(graph_config) + + # Тестирование основных функций + try: + node_count = graph_store.count_nodes("UserMemory") + print(f"✅ Статистика узлов MemOS: {node_count:,} узлов UserMemory") + except: + print("⚠️ Функция статистики узлов требует доработки") + + # Тестирование функции экспорта + try: + exported = graph_store.export_graph() + print(f"✅ Экспорт графа MemOS: {len(exported.get('nodes', []))} узлов, {len(exported.get('edges', []))} ребер") + except Exception as e: + print(f"⚠️ Функция экспорта графа: {e}") + + print("✅ Проверка совместимости MemOS завершена") + return True + + except Exception as e: + print(f"❌ Проверка совместимости MemOS не удалась: {e}") + return False + +def main(): + """Главная Функция""" + print("🚀 Neo4j Инструмент Пакетного Импорта") + print("=" * 50) + + try: + # 1. Получить Конфигурацию Пользователя - Ввод Все Информации Один Раз + config.get_user_input() + + # 2. Протестировать Соединение + if not test_neo4j_connection(): + return + + # 3. Создать Совместимую Схему + if not create_memos_compatible_schema(): + return + + # 4. Показать Оценку + print(f"\nПрямой Neo4j Пакетный Импорт Оценка:") + print(f" Количество Узлов: 200,000") + print(f" Количество Ребер: 500,000") + print(f" Размер Пакета: 5,000 Узлов/Пакет, 10,000 Ребер/Пакет") + print(f" Ожидаемая Скорость: 1000+ Узлов/Секунда, 5000+ Ребер/Секунда") + print(f" Ожидаемое Время: 15-25 Минут") + + confirm = input("\nНачать Прямой Пакетный Импорт? (y/N): ").strip().lower() + if confirm != 'y': + print("❌ Пользователь Отменил Импорт") + return + + # 5. Выполнить Импорт + total_start = time.time() + + # Импорт Узлов + node_count = bulk_import_nodes() + + # Импорт Ребер + edge_count = bulk_import_edges() + + # Создание Индекса + create_memos_indexes() + + # Проверка Совместимости + compatible = verify_memos_compatibility() + + # Резюме + total_time = time.time() - total_start + print("\n" + "=" * 50) + print("Прямой Пакетный Импорт Завершен") + print("=" * 50) + print(f"✅ Общее Время: {total_time/60:.1f} Минут") + print(f"📊 Статистика Импорта:") + print(f" Узлов: {node_count:,}") + print(f" Ребер: {edge_count:,}") + print(f" Совместимость MemOS: {'✅ Полная Совместимость' if compatible else '⚠️ Требуется Настройка'}") + + if node_count > 0: + print("\n💡 Теперь Доступны Все Функции MemOS:") + print(" - Семантический Поиск") + print(" - Графовый Запрос") + print(" - Память Вывод") + print(" - Визуализация") + + except KeyboardInterrupt: + print("\n❌ Пользователь прервал операцию") + except Exception as e: + print(f"\n❌ Ошибка выполнения программы: {e}") + finally: + # Убедитесь, что соединение с базой данных закрыто + config.close_driver() + print("🔒 Соединение с базой данных закрыто") + +if __name__ == "__main__": + main() +``` + +#### **Монтирование MemCube в MemOS** + +Когда данные успешно импортированы, наша кардиологическая MemCube официально "запущена". В приложении достаточно инициализировать `TreeTextMemory` MemOS с помощью конфигурационного файла, указывающего на базу данных. После этого мы можем взаимодействовать с огромной базой знаний через этот объект `tree_memory`, наделяя ИИ профессиональной памятью в области. + +```python +# Монтирование MemCube +from memos.configs.memory import TreeTextMemoryConfig +from memos.memories.textual.tree import TreeTextMemory + +# 1. Пример конфигурационного файла, необходимого для монтирования MemCube +config_data = { + "extractor_llm": { + "backend": "huggingface", + "config": { + "model_name_or_path": "/mnt/public/model/huggingface/Qwen2.5-14B", + "temperature": 0.1, + "remove_think_prefix": True, + "max_tokens": 8192 + } + }, + "dispatcher_llm": { + "backend": "huggingface", + "config": { + "model_name_or_path": "/mnt/public/model/huggingface/Qwen3-0.6B", + "temperature": 0.1, + "remove_think_prefix": True, + "max_tokens": 8192 + } + }, + "embedder": { + "backend": "sentence_transformer", + "config": { + "model_name_or_path": "your embedding model path" + } + }, + "graph_db": { + "backend": "neo4j", + "config": { + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "yourpassword", + "db_name": "neo4j", + "auto_create": False, + "embedding_dimension": 768 + } + } +} + +# 2. Запись в JSON файл +json_path = "cookbooktest/tree_config.json" +with open(json_path, "w", encoding="utf-8") as f: + json.dump(config_data, f, indent=2, ensure_ascii=False) + +print(f"Конфигурационный файл сгенерирован: {json_path}") + +# 3. Чтение конфигурации и инициализация TreeTextMemory +config = TreeTextMemoryConfig.from_json_file(json_path) +tree_memory = TreeTextMemory(config) + +``` + +--- + +## **Отчет По Оценке Эффективности: Проверка Производительности Рамки Укрепления Памяти MemCube** + +### **Методы Оценки** + +Чтобы количественно оценить повышение производительности, обеспечиваемое кардиологической MemCube, мы разработали автоматизированный процесс оценки. В его основе лежит использование мощной сторонней модели (например, Gemini-2.5-Pro) в качестве нейтрального "экзаменатора", чтобы проверить, как модели, оснащенные MemCube, улучшают свои способности к решению профессиональных задач. + +#### Примеры Оценочных Заданий + +```python +# questions (partial in 200 questions) + 'A 65-year-old male patient presents to the emergency department with severe lower abdominal pain, inability to urinate, and is complaining of lightheadedness and palpitations. His past medical history includes hypertension controlled with lisinopril, benign prostatic hyperplasia for which he has been taking tamsulosin, and moderate alcohol use. On examination, his heart rate is elevated at 105 beats per minute, blood pressure is 140/90 mmHg, and he appears uncomfortable. Palpation reveals a distended bladder. An ECG shows sinus tachycardia without ischemic changes. You suspect bladder distension might be causing autonomic reflex changes affecting cardiac function. Considering this scenario, explain the physiological mechanism by which bladder distension might result in cardiac symptoms, and outline your approach to managing this patient to resolve both the urinary and cardiovascular concerns.', + 'In an elderly patient with poorly controlled diabetes, how do advanced glycation end products (AGEs) contribute to the pathophysiology of endothelial injury, and what implications does this have for the management of cardiovascular risks?', + 'A middle-aged patient with venous insufficiency is monitored using transcutaneous oxygen measurements to assess tissue perfusion. How does venous insufficiency affect transcutaneous oxygen levels, and how should these results influence treatment decisions for skin ulcers?', + 'A young adult with confirmed tubular acidosis is presenting with significant metabolic acidosis. How would sodium bicarbonate therapy be utilized in this case, and what are the considerations for its dosages and effects?' +``` + +```python + +#### Реализация Основного Процесса Поиска +# Скрипт ниже демонстрирует шаги поиска на основе MemCube: с помощью метода `tree_memory.search()`. Точно находите наиболее схожие фрагменты знаний из нашего обширного MemCube, соответствующие семантике текущего вопроса. Вы также можете настроить модель chat для реализации функции диалога напрямую. +# question_list: Список схожих вопросов, предоставленных пользователем для поиска. Например: ['Каковы признаки инфаркта миокарда?', 'Каковы потенциальные опасности высокого кровяного давления?'] +question_list = ['What are the signs of a myocardial infarction?', 'What are the potential dangers of high blood pressure?'] +search_results_dict = {} + +for i, question in enumerate(question_list): + print(i) + results = tree_memory.search(question, top_k=15) + # Исключить короткие чисто концептуальные узлы + filtered_results = [node.memory for node in results if len(node.memory) > 100] + search_results_dict[i] = { + 'question': question, + 'results': filtered_results + } +``` + +--- + +# 🧠 Отчет По Оценке Эффективности Медицинского ИИ MemCube + +## 📋 Исполнительное Резюме + +На основе объективной оценки 200 медицинских случаев, данный отчет всесторонне оценивает эффективность MemCube в медицинских приложениях ИИ. MemCube, построенный на базе знаний через MemOS, значительно улучшил способности медицинского рассуждения модели ИИ. + +### **Ключевые Результаты Сравнения И Анализ** + +#### **Статистика Прямых Побед И Поражений** + +| Сравнение Конфигураций | MemCube Улучшенная Версия Побеждает | Baseline Базовая Версия Побеждает | Ничья | +| ------------------------------------ | :-------------: | :--------------: | :--: | +| **Сравнение Внутри Модели 7B** | **47** | **3** | 150 | +| **Сравнение Внутри Модели 32B** | **92** | **0** | 108 | +| **7B+MemCube vs 32B Baseline** | **57** | **3** | 140 | + +#### **Ключевой Анализ Инсайтов** + +1. **Для больших моделей точные знания в области по-прежнему имеют решающее значение**: Результаты показывают, что модель с 32B параметрами, оснащенная MemCube, демонстрирует подавляющее преимущество (92 победы и 0 поражений). Это подтверждает, что даже для моделей с уже сильными базовыми способностями структурированная внешняя база знаний может обеспечить решающий скачок в производительности, особенно в профессиональных областях, где требуется точность знаний. +2. **Система памяти реализует "малое против большого"**: В сравнении между 7B моделью и 32B базовой моделью, 7B модель с MemCube достигла значительного преимущества с 57 победами и 3 поражениями. Это ясно демонстрирует, что хорошо спроектированная система памяти может эффективно компенсировать недостаток знаний у малой модели, позволяя ей превосходить универсальные модели, которые в несколько раз больше. +3. **Система памяти имеет универсальную эффективность**: Независимо от того, 7B или 32B модель, после оснащения MemCube их профессионализм и точность ответов значительно возросли. Это указывает на то, что предложенная в этой главе структура "концептуальная карта - дистилляция знаний - усиление памяти" является универсальным и эффективным решением для повышения возможностей ИИ. + +### **Глубокий Анализ Представительных Случаев** + +Чтобы более наглядно понять механизм действия MemCube, мы провели глубокий анализ некоторых оценочных случаев. + +#### **Анализ Случая 1 (Модель 7B, ID: 9): Ретинопатия Недоношенных (ROP) Случай** + +**Клиническая Проблема**: Вопрос касается 6-летнего ребенка с ретинопатией недоношенных (ROP), который был направлен в кардиологическое отделение для системной оценки из-за изменений в микроциркуляции сетчатки. Вопрос требует оценки, какие кардиологические исследования следует провести, и как находки в глазном дне могут повлиять на стратегию кардиологической оценки. + +**Клиническая Проблема:** + +``` +A 6-year-old child is referred to your cardiovascular clinic for evaluation after being diagnosed with retinopathy of prematurity (ROP). The ophthalmologist has noted significant retinal vessel changes and has expressed concerns regarding the child's cardiovascular health given the potential systemic implications of microvascular changes observed in ROP. As you assess the child, you consider possible cardiovascular complications that may arise. What cardiovascular assessments would be pertinent in this case, and how might the existing retinal findings influence your cardiovascular evaluation strategy, particularly concerning microvascular health and its potential systemic effects? +``` + +**Улучшенный Ответ MemCube**: + +``` +{'model': 'qwen2.5-7b-instruct', 'version': 'v2', 'question_id': 9, 'prompt': "As an experienced medical expert, provide comprehensive analysis using evidence-based medicine principles.\n\n**CLINICAL CASE:**\nA 6-year-old child is referred to your cardiovascular clinic for evaluation after being diagnosed with retinopathy of prematurity (ROP). The ophthalmologist has noted significant retinal vessel changes and has expressed concerns regarding the child's cardiovascular health given the potential systemic implications of microvascular changes observed in ROP. As you assess the child, you consider possible cardiovascular complications that may arise. What cardiovascular assessments would be pertinent in this case, and how might the existing retinal findings influence your cardiovascular evaluation strategy, particularly concerning microvascular health and its potential systemic effects?\n\n**KEY EVIDENCE:**\n• Question: A young child presents with suspected retinopathy of prematurity, potentially linked to a congenital heart defect that has led to inconsistent oxygen delivery. As a cardiovascular specialist, how would you approach the management of this child's systemic condition to optimize retinal health?\n\nReasoning Guidance: Evaluate the impact of the congenital heart defect on systemic oxygenation. Consider the role of oxygen supplementation and monitoring. Integrate cardiovascular management strategies with ophthalmologic treatment to optimize retinal health.\n\nKnowledge Facts: Pediatric retinal disorders often involve insufficient retinal vascular development.; Pediatric retinal disorders can be exacerbated by systemic oxygen imbalances, common in congenital heart defects.; Effective management of pediatric retinal disorder requires collaboration with ophthalmology and cardiology.\n\nAnswer: The management involves stabilizing systemic oxygen levels through correction of the heart defect, if feasible, and careful use of supplemental oxygen. Coordination with an ophthalmologist to monitor retinal changes and implement laser therapy or surgical interventions may be required.\n• Question: During a cardiovascular examination, a pediatric patient with coexisting retinal and cardiovascular disorders seems to have poor growth despite appropriate medical interventions. What could be the systemic implications of these concurrent conditions, and how should clinical decision-making address these concerns?\n\nReasoning Guidance: Integrate understanding of pediatric retinal disorder with the potential cardiovascular inefficiencies causing poor systemic circulation and growth delays. Consider multidisciplinary approaches for these intertwined issues, promoting comprehensive care strategies.\n\nKnowledge Facts: Pediatric retinal disorders and cardiac anomalies can have overlapping pathogenic mechanisms affecting systemic development.; A comprehensive clinical approach involves assessing the interplay between circulatory efficiency and ocular vascular health.; Addressing underlying cardiovascular inefficiencies may relieve secondary complications impacting systemic development.\n\nAnswer: The clinical approach should prioritize optimization of cardiovascular function to improve circulation efficiencies, potentially benefiting retinal health and promoting growth. Collaboration across specialties, including cardiology, ophthalmology, and pediatrics, is crucial for comprehensive systemic management.\n• Question: A young adult with a history of pediatric retinal disorder secondary to Kawasaki disease is undergoing cardiovascular follow-up for potential coronary artery complications. How can ongoing retinal issues influence cardiovascular management?\n\nReasoning Guidance: Assess how retinal issues, such as impaired visual acuity or peripheral vision loss, might affect compliance or understanding of cardiovascular treatment plans. Consider unique strategies in communication or monitoring to enhance treatment adherence.\n\nKnowledge Facts: Pediatric retinal disorders can result from inflammatory conditions like Kawasaki disease impacting vasculature.; In patients with persistent retinal disorder consequences, visual limitations could obstruct understanding of complex medical instructions.; Cardiovascular management must adapt to individual patient's sensory and learning capabilities, ensuring thorough education about treatment and prevention strategies.\n\nAnswer: Management may require tailored communication strategies, ensuring the patient fully understands and is capable of following the prescribed cardiovascular treatment. Regular check-ups should integrate assessments of retinal status to anticipate any complications affecting routine cardiovascular care.\n• Question: A premature infant is undergoing ophthalmic screening for retinopathy of prematurity (ROP). What complications, if untreated, might arise related to the retina?\n\nReasoning Guidance: Understand how untreated ROP can lead to tractional retinal detachment in premature infants.\n\nKnowledge Facts: Retinopathy of prematurity involves abnormal retinal vessel development.; Advanced ROP can result in retinal traction and detachment.; Screening and early treatment are critical in preventing detachment.\n\nAnswer: Regular screening and timely intervention, such as laser photocoagulation, are essential to prevent retinal detachment.\n\nPlease provide evidence-based medical analysis and management recommendations.", 'response': "### Comprehensive Analysis and Management Recommendations for a Child with Retinopathy of Prematurity (ROP) and Potential Cardiovascular Complications\n\n#### Clinical Case Overview\nA 6-year-old child has been referred to a cardiovascular clinic for evaluation due to a diagnosis of retinopathy of prematurity (ROP). The ophthalmologist has noted significant retinal vessel changes and expressed concerns about potential systemic implications, particularly regarding microvascular health and its potential systemic effects.\n\n#### Key Evidence and Reasoning\n\n1. **Impact of Congenital Heart Defect on Systemic Oxygenation:**\n - **Congenital Heart Defects and ROP:** Congenital heart defects can lead to inconsistent oxygen delivery, which can affect retinal vascular development. The retina is highly sensitive to oxygen levels, and inadequate oxygenation can result in ROP.\n - **Management Strategy:**\n - **Correcting the Heart Defect:** If the congenital heart defect is correctable, surgical intervention should be considered to improve systemic oxygenation.\n - **Supplemental Oxygen:** In the interim, supplemental oxygen can be used to optimize oxygen levels, but it should be carefully monitored to avoid hyperoxia, which can also be detrimental.\n - **Collaboration with Ophthalmology:** Regular ophthalmologic follow-up is essential to monitor retinal changes and intervene with laser therapy or surgical interventions if necessary.\n\n2. **Systemic Implications of Concurrent Conditions:**\n - **Poor Growth and Circulatory Efficiency:** Poor growth in a child with both retinal and cardiovascular disorders may be due to systemic circulatory inefficiencies. This can be exacerbated by underlying cardiovascular anomalies.\n - **Multidisciplinary Approach:**\n - **Cardiovascular Optimization:** Focus on optimizing cardiovascular function to improve circulation efficiency. This may include pharmacological interventions, lifestyle modifications, and, if necessary, surgical interventions.\n - **Comprehensive Care:** Collaboration between cardiology, ophthalmology, and pediatrics is essential to address the interplay between circulatory efficiency and ocular vascular health.\n\n3. **Ongoing Retinal Issues and Cardiovascular Management:**\n - **Visual Limitations and Treatment Adherence:** Retinal issues, such as impaired visual acuity or peripheral vision loss, can affect a patient's ability to understand and adhere to complex medical instructions.\n - **Tailored Communication Strategies:**\n - **Simplified Instructions:** Use clear and simple language to ensure the patient or caregiver fully understands the treatment plan.\n - **Visual Aids and Educational Materials:** Provide visual aids and educational materials to enhance understanding and compliance.\n - **Regular Follow-ups:** Schedule regular check-ups to monitor both cardiovascular and retinal health, ensuring timely intervention if any complications arise.\n\n4. **Complications of Untreated ROP:**\n - **Tractional Retinal Detachment:** Advanced ROP can lead to retinal traction and detachment, which can result in severe visual impairment or blindness.\n - **Screening and Early Intervention:**\n - **Regular Ophthalmic Screening:** Implement regular ophthalmic screening for premature infants to detect ROP early.\n - **Timely Intervention:** Promptly intervene with laser photocoagulation or other treatments to prevent retinal detachment.\n\n### Evidence-Based Medical Analysis and Management Recommendations\n\n1. **Initial Assessment:**\n - **Cardiovascular Examination:** Perform a thorough cardiovascular examination, including echocardiography, to assess the presence and severity of any congenital heart defects.\n - **Ophthalmologic Evaluation:** Conduct a comprehensive ophthalmologic examination to assess the extent of retinal changes and determine the stage of ROP.\n\n2. **Management Plan:**\n - **Correct Congenital Heart Defects:** If the heart defect is correctable, arrange for surgical intervention to improve systemic oxygenation.\n - **Supplemental Oxygen Therapy:** Use supplemental oxygen cautiously to optimize oxygen levels, but monitor for hyperoxia.\n - **Collaborative Care:** Establish a multidisciplinary care team including cardiology, ophthalmology, and pediatrics to coordinate treatment and monitoring.\n - **Growth Monitoring:** Regularly monitor the child's growth and development to address any systemic circulatory inefficiencies.\n - **Communication Strategies:** Use simplified instructions and visual aids to enhance treatment adherence, especially if the child has visual limitations.\n - **Ophthalmic Screening:** Implement regular ophthalmic screening for premature infants to detect ROP early and intervene promptly.\n\n3. **Monitoring and Follow-ups:**\n - **Regular Follow-ups:** Schedule regular follow-ups with both the cardiologist and ophthalmologist to monitor the child's cardiovascular and retinal health.\n - **Adjustments to Treatment:** Be prepared to adjust the treatment plan based on the child's response to interventions and any new findings.\n\nBy following these evidence-based recommendations, the healthcare team can optimize the child's cardiovascular and retinal health, ensuring the best possible outcomes for the patient.", 'length': 5313, 'api_time': 89.44595098495483, 'timestamp': 1753351860.232497, 'error': False} +``` + +**Ответ Baseline**: + +``` +{'model': 'qwen2.5-7b-instruct', 'version': 'baseline', 'question_id': 9, 'prompt': "Analyze this clinical case as a senior medical expert:\n\nA 6-year-old child is referred to your cardiovascular clinic for evaluation after being diagnosed with retinopathy of prematurity (ROP). The ophthalmologist has noted significant retinal vessel changes and has expressed concerns regarding the child's cardiovascular health given the potential systemic implications of microvascular changes observed in ROP. As you assess the child, you consider possible cardiovascular complications that may arise. What cardiovascular assessments would be pertinent in this case, and how might the existing retinal findings influence your cardiovascular evaluation strategy, particularly concerning microvascular health and its potential systemic effects?\n\nPlease provide detailed medical analysis and recommendations.", 'response': "In this clinical case, a 6-year-old child with retinopathy of prematurity (ROP) presents with significant retinal vessel changes, raising concerns about potential systemic implications. As a senior medical expert, I would recommend a comprehensive cardiovascular evaluation to assess for any underlying cardiovascular complications that may be related to the microvascular changes observed in the retina. Here is a detailed analysis and a recommended evaluation strategy:\n\n### 1. **Medical History and Physical Examination**\n- **Medical History:**\n - **Perinatal History:** Obtain detailed information about the child's birth, including gestational age, birth weight, and any complications during delivery.\n - **Family History:** Inquire about any cardiovascular or ocular diseases in the family.\n - **Past Medical History:** Review any previous medical conditions, surgeries, or treatments.\n - **Current Medications:** Document any medications the child is currently taking.\n- **Physical Examination:**\n - **General Appearance:** Assess for signs of prematurity or other systemic conditions.\n - **Cardiovascular Examination:**\n - **Heart Sounds:** Auscultate for any murmurs, gallops, or rubs.\n - **Peripheral Vascular Signs:** Check for signs of hypertension, such as brachial artery blood pressure differences, or signs of coarctation of the aorta.\n - **Capillary Refill Time:** Evaluate for any signs of poor perfusion.\n\n### 2. **Cardiovascular Assessments**\nGiven the potential systemic implications of microvascular changes observed in ROP, the following cardiovascular assessments are pertinent:\n\n#### **A. Blood Pressure Measurement**\n- **Non-Invasive Measurement:** Measure blood pressure in both arms to detect any differences that might suggest coarctation of the aorta.\n- **Ambulatory Blood Pressure Monitoring (ABPM):** Consider this if there are any signs of hypertension or if the child is symptomatic.\n\n#### **B. Echocardiography**\n- **Echocardiogram:** This is the gold standard for evaluating cardiac structure and function. It can help identify any congenital heart defects, valvular abnormalities, or other structural heart issues that might be related to the microvascular changes.\n- **Fetal Echocardiography:** If the child was born prematurely, a fetal echocardiogram might have been performed, which could provide additional information.\n\n#### **C. Cardiac MRI or CT**\n- **Imaging Studies:** If there are specific concerns about complex cardiac anatomy or if echocardiography is inconclusive, cardiac MRI or CT can provide detailed images of the heart and great vessels.\n\n#### **D. Cardiovascular Risk Factors**\n- **Fasting Lipid Profile:** Assess for dyslipidemia, which can be a risk factor for cardiovascular disease.\n- **Fasting Blood Glucose:** Evaluate for diabetes or impaired glucose tolerance, which can also contribute to cardiovascular risk.\n- **Anthropometric Measurements:** Measure height, weight, and body mass index (BMI) to assess for obesity, which is a significant risk factor for cardiovascular disease.\n\n### 3. **Ophthalmologic and Microvascular Health Considerations**\n- **Retinal Changes:** The significant retinal vessel changes in ROP suggest microvascular abnormalities. These changes are often associated with systemic conditions such as hypertension, diabetes, and other vascular disorders.\n- **Systemic Evaluation:** Given the systemic implications, a thorough evaluation for other microvascular diseases should be considered, including:\n - **Fundoscopy:** Regular follow-up fundoscopy to monitor for progression of ROP.\n - **Retinal Vessel Fluorescein Angiography:** To assess the integrity of the retinal vasculature and identify any areas of leakage or ischemia.\n - **Systemic Blood Pressure Monitoring:** Regular monitoring of blood pressure to detect any hypertension.\n - **Glucose Tolerance Testing:** To screen for diabetes or impaired glucose tolerance.\n\n### 4. **Recommendations**\n- **Referral to a Pediatric Cardiologist:** Given the potential systemic implications, it is crucial to refer the child to a pediatric cardiologist for a comprehensive cardiovascular evaluation.\n- **Regular Follow-Up:** Schedule regular follow-up visits to monitor the child's cardiovascular health and retinal status.\n- **Lifestyle Modifications:** If any risk factors are identified, implement lifestyle modifications such as a healthy diet, regular exercise, and weight management.\n- **Genetic Counseling:** Consider genetic counseling if there is a family history of cardiovascular or ocular diseases.\n\n### Conclusion\nThe microvascular changes observed in ROP suggest a potential systemic vascular disease. A comprehensive cardiovascular evaluation, including echocardiography, blood pressure monitoring, and other relevant tests, is essential to identify any underlying cardiovascular complications. Regular follow-up and monitoring are crucial to ensure early detection and management of any potential issues.", 'length': 4977, 'api_time': 92.66847014427185, 'timestamp': 1753351863.4531698, 'error': False} +``` + +**Анализ Случая**: +В этом случае базовая модель (Ответ B) предоставила стандартный клинический процесс оценки, охватывающий сбор анамнеза, физикальное обследование и различные кардиологические исследования. Однако ее ответ не углубился в исследование внутренней патофизиологической связи между ROP и сердечно-сосудистой системой. + +В отличие от этого, модель, усиленная MemCube (Ответ A), продемонстрировала более высокий уровень клинического рассуждения. Она смогла вызвать и интегрировать несколько связанных фрагментов знаний (эти знания были дистиллированы из нашей QA-памяти для концепций "ROP", "врожденные пороки сердца", "системная оксигенация"), например: + +* Четко указала, что "врожденные пороки сердца могут привести к нестабильной доставке кислорода, что, в свою очередь, влияет на развитие сосудов сетчатки". +* Подчеркнула потенциальные преимущества оптимизации "эффективности системного кровообращения" для улучшения здоровья сосудов глаз и общего развития. + +Это иллюстрирует ключевое преимущество MemCube: он не просто осуществляет простую выборку информации, а эффективно связывает разрозненные точки знаний во время рассуждения, формируя многоаспектную и более глубокую аналитическую структуру. Это позволяет усиленной модели действовать как опытный эксперт, исследуя проблему с точки зрения причин и предлагая междисциплинарные стратегии комплексного управления, а не просто перечисляя пункты обследования. + +--- + +### Оценка Эффективности MemCube Для Модели 32B + +#### Пример 1: Сравнение Вопросов и Ответов в Медицине (ID: 146) + +**Клинический Вопрос**: Для взрослого пациента, у которого диагностирована идиопатическая дилатационная кардиомиопатия (DCM) и наблюдаются симптомы сердцебиения и головокружения, спрашивается, как наличие аритмии влияет на его диагностику и стратегию лечения. +**Клинический Вопрос**: + +``` +An adult patient with known idiopathic dilated cardiomyopathy presents with palpitations and dizziness. How does the presence of arrhythmias influence your diagnostic and therapeutic approach, especially in the context of managing dilated cardiomyopathy? +``` + +**Улучшенный Ответ MemCube**: + +``` +{'model': 'qwen2.5-32b-instruct', 'version': 'v2', 'question_id': 146, 'prompt': 'As an experienced medical expert, provide comprehensive analysis using evidence-based medicine principles.\n\n**CLINICAL CASE:**\nAn adult patient with known idiopathic dilated cardiomyopathy presents with palpitations and dizziness. How does the presence of arrhythmias influence your diagnostic and therapeutic approach, especially in the context of managing dilated cardiomyopathy?\n\n**KEY EVIDENCE:**\n• Question: A middle-aged patient diagnosed with idiopathic dilated cardiomyopathy presents with palpitations and dizziness. Considering the risk of proarrhythmia, what diagnostic strategies and management plans should be considered?\n\nReasoning Guidance: Evaluate the role of idiopathic dilated cardiomyopathy in altering cardiac electrophysiology, leading to arrhythmic complications. Discuss the impact of heart failure medications on arrhythmia risk and selection of antiarrhythmic drugs fostering minimal proarrhythmic potential.\n\nKnowledge Facts: Idiopathic dilated cardiomyopathy can lead to heart chamber enlargement affecting electrical conduction.; Proarrhythmia refers to the increased risk of arrhythmias caused by medications or cardiac conditions.; Monitoring with ECG and considering beta-blocker or anticoagulant therapy are key in management.\n\nAnswer: Given the history of idiopathic dilated cardiomyopathy, the patient should be monitored closely with ECG for arrhythmic patterns. Opt for rhythm-stabilizing medications like beta-blockers while avoiding drugs with high proarrhythmic potential.\n• Question: An adult presents with palpitations and a recent diagnosis of idiopathic dilated cardiomyopathy. How should the presence of frequent atrial premature beats influence the clinical management of this patient?\n\nReasoning Guidance: Evaluate how atrial arrhythmias can exacerbate heart failure symptoms and potential management strategies to mitigate this risk.\n\nKnowledge Facts: Idiopathic dilated cardiomyopathy can lead to heart failure symptoms.; Frequent atrial premature beats can worsen cardiac function.; Managing arrhythmias may improve heart failure control.\n\nAnswer: Focus on optimizing heart failure management and consider treatment options for arrhythmias, such as beta-blockers or antiarrhythmic drugs.\n• Question: A young adult has been diagnosed with idiopathic dilated cardiomyopathy and is experiencing palpitations. Analyze how idiopathic dilated cardiomyopathy can cause palpitations and determine an appropriate treatment strategy.\n\nReasoning Guidance: Palpitations in dilated cardiomyopathy could indicate arrhythmias. Evaluate cardiac function and rhythm, using diagnostics to determine arrhythmia presence and guide treatment such as antiarrhythmics or device therapy.\n\nKnowledge Facts: Idiopathic dilated cardiomyopathy can lead to arrhythmias causing palpitations.; Palpitations may reflect arrhythmic risks in cardiomyopathy due to ventricular dysfunction.; Evaluating arrhythmia type and severity is essential in managing palpitations and potential heart failure exacerbations.\n\nAnswer: Investigate arrhythmia presence using ECG, consider beta-blockers or anti-arrhythmic medication, and evaluate need for device therapy like ICD.\n• Question: A young adult with idiopathic dilated cardiomyopathy presents with arrhythmias. How might disruptions in cardiac action potentials contribute to this presentation, and what treatment options should be considered?\n\nReasoning Guidance: Understand the mechanics of cardiac action potentials and how disruptions can lead to arrhythmias in dilated cardiomyopathy. Analyze therapeutic strategies targeting electrophysiological abnormalities.\n\nKnowledge Facts: Action potentials are crucial for coordinated cardiac contraction.; Idiopathic dilated cardiomyopathy can alter cardiac electrical activity.; Arrhythmias in cardiomyopathy may result from ion channel dysfunction or structural changes.\n\nAnswer: Altered cardiac action potentials due to cardiomyopathy can cause electrical instability, resulting in arrhythmias. Management includes antiarrhythmic drugs, device therapy, and addressing underlying structural heart issues.\n\nPlease provide evidence-based medical analysis and management recommendations.', 'response': '### Clinical Case Analysis: Idiopathic Dilated Cardiomyopathy with Palpitations and Dizziness\n\n#### Background\nIdiopathic dilated cardiomyopathy (IDC) is characterized by ventricular dilation and impaired systolic function, often leading to heart failure. The presence of arrhythmias in IDC is common and can exacerbate symptoms such as palpitations and dizziness, potentially leading to more severe complications like syncope or sudden cardiac death.\n\n#### Diagnostic Approach\n1. **Electrocardiogram (ECG) Monitoring:**\n - **Initial ECG:** To identify any immediate arrhythmias, such as atrial fibrillation, ventricular tachycardia, or frequent premature beats.\n - **Holter Monitoring:** For 24-48 hours to capture intermittent arrhythmias.\n - **Event Monitor:** For patients with infrequent symptoms, to record arrhythmias as they occur.\n - **Implantable Loop Recorder:** For patients with recurrent symptoms and negative initial monitoring.\n\n2. **Echocardiography:**\n - To assess ventricular function, chamber dimensions, and wall motion abnormalities.\n - To evaluate for any thrombus formation, which could be a source of embolic events.\n\n3. **Blood Tests:**\n - Cardiac biomarkers (e.g., BNP, NT-proBNP) to assess heart failure severity.\n - Thyroid function tests, as hyperthyroidism can cause palpitations.\n - Electrolyte levels, particularly potassium and magnesium, which can affect cardiac rhythm.\n\n#### Therapeutic Approach\n1. **Optimization of Heart Failure Therapy:**\n - **Beta-Blockers:** Proven to reduce mortality and hospitalization in IDC. They also stabilize the heart rhythm, reducing the risk of arrhythmias.\n - **ACE Inhibitors/ARBs:** To reduce afterload and improve ventricular function.\n - **Diuretics:** To manage fluid overload and alleviate symptoms of heart failure.\n - **SGLT2 Inhibitors:** Emerging evidence supports their use in reducing cardiovascular events in heart failure patients.\n\n2. **Antiarrhythmic Therapy:**\n - **Class I Antiarrhythmics (e.g., flecainide, propafenone):** Used cautiously due to potential proarrhythmic effects.\n - **Class III Antiarrhythmics (e.g., amiodarone, sotalol):** Amiodarone is effective but has significant side effects; sotalol is a beta-blocker with antiarrhythmic properties.\n - **Calcium Channel Blockers (e.g., verapamil, diltiazem):** Useful for certain arrhythmias like atrial fibrillation, but use with caution due to negative inotropic effects.\n\n3. **Device Therapy:**\n - **Implantable Cardioverter Defibrillator (ICD):** Indicated in patients with IDC and reduced ejection fraction (EF <35%) to prevent sudden cardiac death.\n - **Pacemakers:** Considered in patients with bradyarrhythmias or those requiring resynchronization therapy (CRT).\n\n4. **Lifestyle Modifications:**\n - Smoking cessation, alcohol moderation, and a low-sodium diet.\n - Regular, moderate-intensity exercise as tolerated.\n - Stress management techniques to reduce arrhythmia triggers.\n\n#### Proarrhythmic Risk and Management\n- **Proarrhythmic Potential:** Antiarrhythmic drugs can paradoxically increase the risk of arrhythmias, particularly in patients with structural heart disease. Careful selection and monitoring are essential.\n- **Risk Stratification:** Use risk stratification tools like the CHA2DS2-VASc score for thromboembolic risk and the European Society of Cardiology guidelines for ICD implantation.\n\n#### Conclusion\nIn managing a patient with IDC and arrhythmias, a comprehensive approach is necessary, combining optimal heart failure therapy with targeted antiarrhythmic treatment and device therapy as indicated. Close monitoring and patient education are crucial to prevent complications and improve quality of life.', 'length': 3725, 'api_time': 18.48910903930664, 'timestamp': 1753352210.820965, 'error': False} +``` + +**Ответ Baseline**: + +``` +{'model': 'qwen2.5-32b-instruct', 'version': 'baseline', 'question_id': 146, 'prompt': 'Analyze this clinical case as a senior medical expert:\n\nAn adult patient with known idiopathic dilated cardiomyopathy presents with palpitations and dizziness. How does the presence of arrhythmias influence your diagnostic and therapeutic approach, especially in the context of managing dilated cardiomyopathy?\n\nPlease provide detailed medical analysis and recommendations.', 'response': "In the context of an adult patient with known idiopathic dilated cardiomyopathy (DCM) presenting with palpitations and dizziness, the presence of arrhythmias significantly influences the diagnostic and therapeutic approach. Here is a detailed analysis and recommendations based on current medical practices:\n\n### Clinical Context and Initial Assessment\n- **Idiopathic Dilated Cardiomyopathy**: DCM is characterized by ventricular dilation and impaired systolic function, often leading to heart failure and arrhythmias.\n- **Symptoms**: Palpitations and dizziness are common symptoms that can be indicative of arrhythmias, which are frequent complications in DCM.\n- **Risk Factors**: The patient's history of DCM places them at higher risk for arrhythmias, particularly atrial fibrillation (AF), ventricular tachycardia (VT), and bradyarrhythmias.\n\n### Diagnostic Approach\n1. **History and Physical Examination**: Detailed history to understand the onset, duration, and triggers of palpitations and dizziness. Physical examination should focus on signs of heart failure, such as jugular venous distension, rales, and peripheral edema.\n2. **Electrocardiogram (ECG)**: Essential for detecting arrhythmias. Can identify AF, VT, or other conduction abnormalities.\n3. **Holter Monitoring**: Useful for patients with intermittent symptoms to capture arrhythmias that may not be evident on a standard ECG.\n4. **Echocardiography**: To assess ventricular function, size, and potential thrombus formation, especially if AF is suspected.\n5. **Cardiac MRI**: Provides detailed images of the heart structure and function, which can be crucial in assessing the extent of DCM and ruling out other causes of cardiomyopathy.\n6. **Blood Tests**: Including electrolytes, thyroid function tests, and markers of heart failure (BNP/NT-proBNP).\n\n### Therapeutic Approach\n1. **Management of Arrhythmias**:\n - **Atrial Fibrillation**: If diagnosed, rate control or rhythm control strategies should be considered. Rate control can be achieved with beta-blockers or non-dihydropyridine calcium channel blockers. Rhythm control might involve antiarrhythmic drugs or catheter ablation.\n - **Ventricular Tachycardia**: If VT is suspected or confirmed, antiarrhythmic drugs (e.g., amiodarone) or implantable cardioverter-defibrillator (ICD) may be necessary. Catheter ablation can also be considered.\n - **Bradyarrhythmias**: If bradyarrhythmias are present, a pacemaker may be indicated.\n\n2. **Management of Dilated Cardiomyopathy**:\n - **Heart Failure Medications**: Continue or initiate medications such as ACE inhibitors/ARBs, beta-blockers, aldosterone antagonists, and diuretics as needed.\n - **Lifestyle Modifications**: Encourage a heart-healthy diet, regular physical activity, and smoking cessation.\n - **Monitoring**: Regular follow-up with echocardiography and clinical assessment to monitor disease progression and response to therapy.\n\n3. **Anticoagulation**:\n - If AF is present, anticoagulation therapy is necessary to prevent thromboembolic events. The choice of anticoagulant (e.g., warfarin, direct oral anticoagulants) should be based on the patient's risk factors and comorbidities.\n\n### Prognosis and Long-Term Management\n- **Prognosis**: The presence of arrhythmias in DCM can worsen prognosis. Regular monitoring and timely intervention are crucial.\n- **Long-Term Management**: Focus on preventing arrhythmias and heart failure exacerbations. Consider multidisciplinary care involving cardiologists, electrophysiologists, and heart failure specialists.\n\n### Conclusion\nThe presence of arrhythmias in a patient with idiopathic dilated cardiomyopathy requires a comprehensive approach, including thorough diagnostic evaluation and tailored therapeutic interventions. The goal is to manage both the underlying cardiomyopathy and the arrhythmias to improve the patient's quality of life and prognosis.", 'length': 3902, 'api_time': 13.865102052688599, 'timestamp': 1753352205.427208, 'error': False} +``` + +**Анализ Случая**: +Базовая модель 32B уже может дать довольно полные и точные ответы, охватывающие процесс диагностики, схемы лечения и управление прогнозом. + +Тем не менее, модель, улучшенная MemCube, превосходит в **структурности, логичности и глубине деталей**. Путем поиска и интеграции QA-памяти MemCube по концепциям "DCM", "аритмия", "риск аритмии" и т.д., Ответ A демонстрирует следующие характеристики: + +* **Более Четкая Логическая Структура**: Ответ A классифицирует методы диагностики и лечения, например, объясняет антиаритмические препараты по категориям (Class I, Class III и т.д.) и четко указывает на меры предосторожности при их использовании в контексте DCM (например, риск аритмии). +* **Выделение Ключевых Знаний**: Ответ A явно указывает на "оптимизацию лечения сердечной недостаточности" как основу для управления аритмией и перечисляет двойное действие таких препаратов, как β-блокаторы, в стабилизации сердечного ритма. Все это основано на QA-памяти MemCube, подчеркивающей ключевые моменты клинической практики. +* **Увеличенная Осведомленность о Рисках**: Ответ A специально включает раздел "Риск и Управление Аритмией", что показывает, что модель не просто излагает знания, но и имитирует мышление эксперта по оценке рисков. + +Этот случай показывает, что даже для мощной модели 32B, MemCube все еще может выполнять роль "коуча знаний", помогая модели организовывать и выражать обширные внутренние знания более структурированным и соответствующим клинической логике образом, предоставляя более ценные профессиональные рекомендации. + +--- + +## 🚀 Практический Опыт: Демонстрация MemCube в Кардиологии + +Система вопросов и ответов по кардиологическим знаниям, представленная в этой главе, уже построена и предлагает полную демонстрационную версию MemCube, содержащую **211,315 записей памяти** и **522,368 семантических связей**. + +### 📦 Характеристики Демонстрационной Системы + +- **🫀 Профессиональная Область**: Система знаний по кардиологии +- **📊 Масштаб Данных**: 211,315 высококачественных записей памяти +- **🔗 Сеть Связей**: 522,368 семантических соединений между концепциями +- **💾 Размер Данных**: около 5.0GB структурированных медицинских знаний +- **🤖 Поддержка ИИ**: поддержка различных моделей LLM (GPT-4o, Claude, локальные модели и т.д.) +- **🌐 Готовность к Развертыванию**: производственная архитектура на основе Neo4j + MemOS + +### 🔍 Испытайте Прямо Сейчас + +Хотите самостоятельно испытать полный процесс построения и конечный результат, описанные в этой главе? Вы можете посетить наш демонстрационный проект: + +**👉 [Cardio MemCube Demo - Hugging Face](https://huggingface.co/datasets/MemCube/cardio-memcube-demo)** + +Этот демонстрационный проект предлагает: +- ✅ **Полное Руководство по Установке**: однонажатийное развертывание системы MemCube в кардиологии +- ✅ **Работающие Примеры Кода**: непосредственное испытание функций вопросов и ответов +- ✅ **Подробная Техническая Документация**: понимание методологии построения и лучших практик +- ✅ **Поддержка Многоязычных Моделей**: гибкая настройка различных бэкендов AI моделей + +### ⚠️ Важное Примечание + +- **🏥 Медицинский Отказ от Ответственности**: эта демонстрация предназначена только для технической демонстрации и образовательных целей и не должна использоваться в качестве основы для медицинской диагностики или лечения +- **🌐 Поддержка Языков**: текущая версия использует оптимизированную для английского языка модель встраивания, запросы на китайском языке требуют перевода или замены на многоязычную модель встраивания +- **🔧 Техническая Архитектура**: это техническая реализация, применимая к любой профессиональной области + +Путем практического опыта с этой демонстрационной системой вы лучше поймете, как преобразовать теоретические методы из этой главы в реальные производственные приложения и накопите ценный опыт для построения вашей собственной системы MemCube в вашей области. diff --git a/content/ru/open_source/cookbook/chapter5/chat_api.md b/content/ru/open_source/cookbook/chapter5/chat_api.md new file mode 100644 index 00000000..300eaeb5 --- /dev/null +++ b/content/ru/open_source/cookbook/chapter5/chat_api.md @@ -0,0 +1,55 @@ +--- +title: Единый Чат Интерфейс (Chat API) — Семантический Поиск, Вопросы и Ответы и Управление Памятью +desc: В этом разделе представлен единый чат интерфейс, который помогает разработчикам ИИ через один интерфейс выполнять семантический поиск, вопросы и ответы в диалоге и добавление памяти. Интерфейс следует простому процессу: сначала извлечение памяти, затем диалог с LLM, и наконец, запись текущего раунда диалога в память. Предоставлены примеры потокового и непотокового вызова, что упрощает быструю интеграцию и использование. +--- + +## Глава Пятая: Chat API + +**🎯 Сценарий Проблемы: ** Вы разработчик AI приложений, но не хотите разрабатывать собственный процесс поиска памяти, вопросов и ответов, добавления памяти. + +**🔧 Решение: ** Мы предоставили единый чат интерфейс, через который пользователи могут выполнять семантический поиск, вопросы и ответы в диалоге, добавление памяти, не вызывая несколько отдельных интерфейсов. + +**🔧 Процесс Выполнения: ** Процесс выполнения следующий: +```markdown +A[Пользовательский Запрос] --> B[Поиск Памяти] --> C[LLM Чат] --> D[Добавить Память] +``` + +### Конкретные Шаги +#### Шаг 1: Запустите MemOS API Сервис +Сначала вам нужно настроить ваш Список Моделей Чата в .env +```dotenv +CHAT_MODEL_LIST=[{"backend": "qwen", "api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1", "api_key": "xxx", "model_name_or_path": "qwen2.5-72b-instruct", "support_models": ["qwen2.5-72b-instruct"]}, {"backend": "deepseek", "api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1", "api_key": "xxx", "model_name_or_path": "deepseek-r1", "support_models": ["deepseek-r1"]}] +``` +```bash +uvicorn memos.api.server_api:app --host 0.0.0.0 --port 8001 --workers 8 +``` + +#### Шаг 2: Вызовите интерфейс chat api + +**Непотоковый** +```bash +curl -X POST "http://0.0.0.0:8001/product/chat/complete" \ + -H "Content-Type: application/json" \ + -d '{ + "user_id": "memos_user_123", + "readable_cube_ids": ["xxx"], + "writable_cube_ids": ["xxx"], + "query": "Я запланировал поездку в Гуанчжоу на летние каникулы, какие сетевые отели доступны для проживания?" + "model_name_or_path": "deepseek-r1", + "add_message_on_answer": true + }' +``` + +**Потоковый** +```bash +curl -N -X POST "http://0.0.0.0:8001/product/chat/stream" \ + -H "Content-Type: application/json" \ + -d '{ + "user_id": "memos_user_123", + "readable_cube_ids": ["xxx"], + "writable_cube_ids": ["xxx"], + "query": "Я запланировал поездку в Гуанчжоу на летние каникулы, какие сетевые отели доступны для проживания?" + "model_name_or_path": "deepseek-r1", + "add_message_on_answer": true + }' +``` diff --git a/content/ru/open_source/cookbook/overview.md b/content/ru/open_source/cookbook/overview.md new file mode 100644 index 00000000..18f88b8e --- /dev/null +++ b/content/ru/open_source/cookbook/overview.md @@ -0,0 +1,215 @@ +--- +title: MemOS Сценарные Примеры +--- + +## Введение + +### Философия Cookbook: Ориентированность на Решение Проблем + +Добро пожаловать в MemOS Cookbook! Это не традиционная техническая документация, а практическое руководство, сосредоточенное на **решении реальных проблем**. + +**Почему нужна эта Cookbook?** + +В разработке AI-приложений мы часто сталкиваемся с такими вызовами: + +- 🤔 "Как заставить мое AI-приложение запомнить предпочтения пользователя?" +- 🔍 "Как быстро извлекать релевантную информацию из большого объема документов?" +- 💡 "Как построить интеллектуального помощника с долгосрочной памятью?" + +Традиционная документация говорит вам **что это**, справочник API говорит вам **как вызывать**, а эта Cookbook сосредоточена на том, чтобы сказать вам **как решить конкретные проблемы**. + +**Основная концепция этой Cookbook:** + +1. **Ориентированность на проблемы**: каждый рецепт начинается с реального сценария использования +2. **Ориентированность на практику**: предоставление полностью работающих примеров кода +3. **Постепенное обучение**: от простого к сложному, шаг за шагом +4. **Лучшие практики**: интеграция опыта и рекомендаций из производственной среды + +--- + +## 📚 Полное Навигационное Указание + +### [Глава 1: Введение: Ваш Первый MemCube](/open_source/cookbook/chapter1/api) + +**Ключевые навыки**: Настройка окружения, Основные операции с MemCube, Импорт и управление данными + +- **Версия API** + - **Рецепт 1.1**: Настройка окружения разработки MemOS (версия API) + - **Рецепт 1.2**: Создание простого MemCube из документации (версия API) + - **Рецепт 1.3**: Основные операции с MemCube (версия API) +- **Версия Ollama** + - **Рецепт 1.1**: Настройка окружения разработки MemOS (версия Ollama) + - **Рецепт 1.2**: Создание простого MemCube из документации (версия Ollama) + - **Рецепт 1.3**: Основные операции с MemCube (версия Ollama) + +### [Глава 2: Структурированная Память: TreeNodeTextualMemoryMetadata](/open_source/cookbook/chapter2/api) + +**Ключевые навыки**: Структурированная память, Управление метаданными, Многоисточниковый трекинг + +- **Версия API** + - **Рецепт 2.1**: Понимание основных концепций `TreeNodeTextualMemoryMetadata` + - **Рецепт 2.2**: Создание базовой структурированной памяти (версия API) + - **Рецепт 2.3**: Описание и настройка часто используемых полей +- **Версия Ollama** + - **Рецепт 2.1**: Понимание основных концепций `TreeNodeTextualMemoryMetadata` + - **Рецепт 2.2**: Создание базовой структурированной памяти (версия Ollama) + - **Рецепт 2.3**: Описание и настройка часто используемых полей + +### [Глава 3: Использование MemOS для Построения Интеллектуальной Системы Анализа Романтики](/open_source/cookbook/chapter3/overview) + +**Ключевые навыки**: Предобработка текста, Извлечение памяти на основе AI, Интеллектуальная система вывода, Разработка креативных приложений + +- **Рецепт 3.0**: Предобработка текста и настройка окружения API +- **Рецепт 3.1**: Определение персонажей и унификация псевдонимов на основе AI +- **Рецепт 3.2**: Извлечение содержимого структурированной памяти +- **Рецепт 3.3**: Интеллектуальная система вывода на основе памяти +- **Рецепт 3.4**: Оптимизация конфигурации модели Embedding +- **Рецепт 3.5**: Преобразователь структуры Memory графа +- **Рецепт 3.6**: Интеграция MemOS и проверка запросов +- **Креативные демонстрации**: + - Интеллектуальная система временной линии мира + - Динамический фон мира Рабочей Памяти + - Интерактивная текстовая игра на основе MemOS + +### [Глава 4: Использование MemOS для Построения Производственной Системы Вопросов и Ответов](/open_source/cookbook/chapter4/overview) + +**Ключевые навыки**: Построение концептуальной карты, Знаниевая инженерия, Производственное развертывание, Увеличение малых моделей + +- **Первый Этап: Построение Базовой Структуры Области Знаний — Расширение Концептуальной Карты** + - Получение Семенных Концепций: Извлечение Основных Концепций Области из Профессиональных Датасетов + - Итеративное Расширение: Автоматическое Расширение Концептуальной Карты на Основе LLM + - Сходимость и Оценка: Качественная Оценка Целостности Карты +- **Второй Этап: Генерация Применимого Знания — Генерация QA Пары на Основе Карты** + - Генерация Знаний по Одной Концепции: Генерация Глубоких Вопросов и Ответов для Каждого Узла Концепции + - Генерация Связанных Знаний: Построение Сложных Логических Связей Между Концепциями +- **Третий Этап: Построение Динамической Базы Знаний — Развертывание Системы MemCube** + - Интеграция Базы Данных Neo4j + - Конфигурация и Оптимизация Системы MemOS + - Лучшие Практики Развертывания в Производственной Среде +- **Практический Кейс**: Система Вопросов и Ответов в Области Кардиологии +- **Проверка Производительности**: Сравнение Профессиональных Возможностей Малых и Больших Моделей + +--- + +## 🎯 Рекомендации по Обучающему Пути + +### 🟢 Путь Начинающего (Всего 4-6 Часов) + +``` +Глава 1 (Версия API или Версия Ollama) → Глава 2 (Соответствующая версия) +``` + +**Подходит**: Разработчикам, только что ознакомившимся с MemOS +**Цель**: Овладеть Основными Операциями и Структурированной Памятью + +### 🟡 Продвинутый Путь (Всего 8-12 Часов) + +``` +Глава 1 → Глава 2 → Глава 3 (Система Анализа Умных Романах) +``` + +**Подходит**: Разработчикам с Определенным Опытам в AI +**Цель**: Овладеть Сложной Обработкой Текста, Извлечением Памяти на Основе AI и Интеллектуальными Системами Вывода + +### 🔴 Продвинутый Путь (Всего 15-25 Часов) + +``` +Глава 1 → Глава 2 → Глава 3 → Глава 4 (Система Вопросов и Ответов Уровня Производства) +``` + +**Подходит**: Разработчикам, желающим Создать Продуктовые Приложения +**Цель**: Овладеть Инженерией Знаний, Построением Концептуальных Карт и Продуктовым Развертыванием + +### 🚀 Экспертный Путь (Всего 20-30 Часов) + +``` +Полное Изучение Всех Глав + Практика Творческого Расширения + Применение в Пользовательских Областях +``` + +**Подходит**: AI Архитекторам и Продвинутым Разработчикам +**Цель**: Овладеть Всею Функциональностью MemOS и Способностью Проектировать Инновационные AI Системы Памяти + +--- + +## Как Эффективно Использовать Этот Cookbook + +**📖 Рекомендации по Чтению:** + +- **Начинающим**: Рекомендуется Чтение в Порядке Глав, Практиковать Каждую Рецептуру +- **Опытным Разработчикам**: Можно Прямо Перейти к Интересующим Рецептам +- **Решателям Проблем**: Быстро Находить Соответствующие Рецепты по Указанному Указателю +- **Обучающимся по Путям**: Систематическое Обучение в Соответствии с Указанными Путями + +**🛠️ Рекомендации по Практике:** + +1. **Подготовка Окружения**: Убедитесь, что Установлен Python 3.10+ и Соответствующие Зависимости +2. **Практика**: Каждая Рецептура Содержит Полный Исполняемый Код +3. **Экспериментирование с Вариантами**: Попробуйте Изменить Параметры, Наблюдая за Разными Эффектами +4. **Решение Проблем**: При Возникновении Проблем Обратитесь к Разделу Часто Задаваемых Вопросов или Попросите Помощи в Сообществе + +**🔧 Кодовые Конвенции:** + +```python +# 💡 Подсказка: Важные Концепции или Лучшие Практики +# ⚠️ Внимание: Важные Моменты, На Которые Нужно Обратить Особое Внимание +# 🎯 Цель: Цель Текущего Шага +``` + +--- + +## 🔧 Подготовка Окружения + +### Системные Требования + +- Python 3.10+ +- 8GB+ ОЗУ (рекомендуется 16GB) +- 50GB+ Свободного Места на Диске + +### Установка Зависимостей + +```bash +pip install MemoryOS +# Необязательно: Neo4j, Ollama, OpenAI API +``` + +### Проверка Установки + +```python +import memos +print(f"MemOS версия: {memos.__version__}") +``` + +--- + +### Связь с Учебниками, API Справочниками и Другими Документами + +**Экосистема Документации:** + +- **🏁 Учебник по Быстрому Началу**: Поможет Вам За 5 Минут Ознакомиться с Основными Функциями MemOS +- **📚 Этот Cookbook**: Глубокие Практические Рецепты для Решения Конкретных Проблем +- **📖 API Справочник**: Подробные Технические Спецификации Функций и Классов +- **🏗️ Документация по Архитектуре**: Руководство по Проектированию и Расширению Системы + +**Когда Использовать Какую Документацию:** + +| Сцена | Рекомендуемая Документация | Описание | +| ------------ | -------------------- | ------------------------ | +| Только Начинаю с MemOS | Быстрый Начальный Учебник | Понять Основные Концепции и Ключевые Функции | +| Решение Конкретной Проблемы | **Этот Кулинарный Справочник** | Найти Соответствующий Рецепт и Решение | +| Поиск Использования Функций | Справочник API | Посмотреть Подробности Параметров и Возвращаемых Значений | +| Проектирование Системы | Документация Архитектуры | Понять Внутренние Механизмы и Способы Расширения | + +--- + +## 📞 Получить Помощь + +- **GitHub Issues**: Подайте технические вопросы и отчеты об ошибках в [MemOS Issues](https://github.com/MemTensor/MemOS/issues) +- **GitHub Discussions**: Обменяйтесь опытом использования и задавайте вопросы в [MemOS Discussions](https://github.com/MemTensor/MemOS/discussions) +- **Discord社区**: Присоединяйтесь к [MemOS Discord服务器](https://discord.gg/Txbx3gebZR) для общения в реальном времени +- **官方文档**: Ознакомьтесь с [MemOS官方文档](https://memos-docs.openmem.net/open_source/home/overview/) для получения подробных инструкций по использованию +- **API参考**: Посмотрите [MemOS API文档](https://memos-docs.openmem.net/api-reference/search-memories/) для получения информации об интерфейсах +- **微信群**: Сканируйте [二维码](https://statics.memtensor.com.cn/memos/qr-code.png), чтобы присоединиться к технической группе WeChat + +--- + +*Давайте Начнем Это Увлекательное Путешествие по Обучению MemOS!* diff --git a/content/ru/open_source/getting_started/examples.md b/content/ru/open_source/getting_started/examples.md new file mode 100644 index 00000000..9762d8ed --- /dev/null +++ b/content/ru/open_source/getting_started/examples.md @@ -0,0 +1,681 @@ +--- +title: MemOS Пример +desc: "Поздравляем! Вы уже освоили быстрый старт и построили свою первую рабочую память! Теперь пришло время объединить различные типы памяти и функции, чтобы увидеть, какие возможности может реализовать MemOS. Используйте эти отобранные примеры, чтобы вдохновить своих собственных агентов, чат-ботов или системы знаний." +--- + +::card-group + + :::card + --- + icon: ri:play-line + title: Самый Простой Pipeline + to: /cn/open_source/getting_started/examples#示例-1СамыйПростойPipeline + --- + Минимальный рабочий Pipeline — добавление и поиск открытой памяти. + ::: + + :::card + --- + icon: ri:tree-line + title: Добавление и извлечение из нескольких источников информации + to: /cn/open_source/getting_started/examples#示例-2多信息源记忆的添加与检索 + --- + Добавление текстовых, изображений, файлов и вызовов инструментов из нескольких источников в память и возможность их извлечения. + ::: + + :::card + --- + icon: ri:apps-line + title: Добавление И Извлечение Нескольких Cube + to: /cn/open_source/getting_started/examples#示例-3ДобавлениеИИзвлечениеНесколькихCube + --- + Добавление различных воспоминаний в разные Cube и одновременное их извлечение. + ::: + + :::card + --- + icon: ri:database-2-line + title: Только KVCacheMemory + to: /cn/open_source/getting_started/examples#示例-4Только-KVCacheMemory + --- + Использование краткосрочного KV cache для ускорения сессий и быстрого внедрения контекста. + ::: + + :::card + --- + icon: ri:calendar-check-line + title: Планирование Памяти + to: /cn/open_source/getting_started/examples#示例-5ПланированиеНесколькихПамятей + --- + Запуск динамических вызовов памяти для многопользовательских и многосессионных агентов. + ::: + +:: + +## Пример 1: Минимальный Pipeline + +### Когда использовать: +- Вы хотите минимальный рабочий пример. +- Вам нужно просто сохранить простую открытую память в базе данных и иметь возможность ее извлекать. + +### Ключевые моменты: +- Поддержка базового добавления и поиска личной пользовательской памяти. + +### Полный пример кода +```python +import json +from memos.api.routers.server_router import add_memories, search_memories +from memos.api.product_models import APIADDRequest, APISearchRequest + +user_id = "test_user_1" +add_req = APIADDRequest( + user_id=user_id, + writable_cube_ids=["cube_test_user_1"], + messages = [ + {"role": "user", "content": "I’ve planned to travel to Guangzhou during the summer vacation. What chain hotels are available for accommodation?"}, + {"role": "assistant", "content": "You can consider [7 Days Inn, Ji Hotel, Hilton], etc."}, + {"role": "user", "content": "I’ll choose 7 Days Inn."}, + {"role": "assistant", "content": "Okay, feel free to ask me if you have any other questions."} + ], + async_mode="sync", + mode="fine", +) + +add_rsp = add_memories(add_req) +print("add_memories rsp: \n\n", add_rsp) + +search_req = APISearchRequest( + user_id=user_id, + readable_cube_ids=["cube_test_user_1"], + query="Please recommend a hotel that I haven’t stayed at before.", + include_preference=True, +) + +search_rsp = search_memories(search_req).data +print("\n\nsearch_rsp: \n\n", json.dumps(search_rsp, indent=2, ensure_ascii=False)) +```` + +## Пример 2: Добавление и извлечение памяти из нескольких источников + +### Когда использовать: + +- Вам нужно добавить файлы, изображения или историю вызовов инструментов в память, помимо простого текстового диалога. +- При этом вы хотите извлекать память из этих многопоточных источников. + +### Ключевые моменты: + +- Добавление памяти из различных источников информации. +- Необходимы загружаемые файлы и URL изображений. +- Добавленная информация должна строго соответствовать формату OpenAI Messages. +- Схема инструмента в системном запросе должна быть обернута в . + +### Полный пример кода +Добавление текста + файлов в память. +```python +import json +from memos.api.routers.server_router import add_memories, search_memories +from memos.api.product_models import APIADDRequest, APISearchRequest + +user_id = "test_user_2" +add_req = APIADDRequest( + user_id=user_id, + writable_cube_ids=["cube_test_user_2"], + messages = [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "Please read this file, summarize the key points, and provide a final conclusion." + }, + { + "type": "file", + "file": { + "file_id": "file_123", + "filename": "report.md", + "file_data": "@http://139.196.232.20:9090/graph-test/algorithm/2025_11_13/1763043889_1763043782_PM1%E8%BD%A6%E9%97%B4PMT%E9%9D%B4%E5%8E%8B%E8%BE%B9%E5%8E%8B%E5%8E%8B%E5%8A%9B%E6%97%A0%E6%B3%95%E5%BB%BA%E7%AB%8B%E6%95%85%E9%9A%9C%E6%8A%A5%E5%91%8A20240720.md" + } + }, + ] + }, + { + "role": "assistant", + "content": [ + { + "type": "text", + "text": "Final Summary: During the PMT boot-pressure startup test of the PM1 workshop on July 20, 2024, the drive could not run because the edge pressures on both sides failed to reach the 2.5-bar interlock requirement. After troubleshooting, the PLC output signals, hydraulic pipelines, and valves were all found to be normal. The root cause was ultimately identified as poor contact at the negative terminal of the proportional valve’s DC 24V power supply inside the PLC cabinet, caused by a short-jumpered terminal block. After re-connecting the negative incoming lines in parallel, the equipment returned to normal operation. It is recommended to replace terminal blocks in batches, inspect instruments with uncertain service life, and optimize the troubleshooting process by tracing common-mode issues from shared buses and power supply sources." + } + ] + } + ], + async_mode="sync", + mode="fine", +) + +add_rsp = add_memories(add_req) +print("add_memories rsp: \n\n", add_rsp) + +search_req = APISearchRequest( + user_id=user_id, + readable_cube_ids=["cube_test_user_2"], + query="Workshop PMT boot pressure startup test", + include_preference=False, +) +search_rsp = search_memories(search_req).data +print("\n\nsearch_rsp: \n\n", json.dumps(search_rsp, indent=2, ensure_ascii=False)) +``` +Добавление сообщений из нескольких смешанных источников в память. +```python +import json +from memos.api.routers.server_router import add_memories, search_memories +from memos.api.product_models import APIADDRequest, APISearchRequest + +user_id = "test_user_2" +add_req = APIADDRequest( + user_id=user_id, + writable_cube_ids=["cube_test_user_2"], + messages = [ + { + "role": "system", + "content": [ + { + "type": "text", + "text": "You are a professional industrial fault analysis assistant. Please read the PDF, images, and instructions provided by the user and provide a professional technical summary.\n\n\n[\n {\n \"name\": \"file_reader\",\n \"description\": \"Used to read the content of files uploaded by the user and return the text data (in JSON string format).\",\n \"parameters\": [\n {\"name\": \"file_id\", \"type\": \"string\", \"required\": true, \"description\": \"The file ID to be read\"}\n ],\n \"returns\": {\"type\": \"text\", \"description\": \"Returns the extracted text content of the file\"}\n }\n]\n" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "text", + "text": "Please read this file and image, summarize the key points, and provide a final conclusion." + }, + { + "type": "file", + "file": { + "file_id": "file_123", + "filename": "report.pdf", + "file_data": "@http://139.196.232.20:9090/graph-test/algorithm/2025_11_13/1763043889_1763043782_PM1%E8%BD%A6%E9%97%B4PMT%E9%9D%B4%E5%8E%8B%E8%BE%B9%E5%8E%8B%E5%8E%8B%E5%8A%9B%E6%97%A0%E6%B3%95%E5%BB%BA%E7%AB%8B%E6%95%85%E9%9A%9C%E6%8A%A5%E5%91%8A20240720.md" + } + }, + { + "type": "image_url", + "image_url": { + "url": "https://play-groud-test-1.oss-cn-shanghai.aliyuncs.com/%E5%9B%BE%E7%89%871.jpeg" + } + } + ] + }, + { + "role": "assistant", + "tool_calls": [ + { + "id": "call_file_reader_001", + "type": "function", + "function": { + "name": "file_reader", + "arguments": "{\"file_id\": \"file_123\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_file_reader_001", + "content": [ + { + "type": "text", + "text": "{\"file_id\":\"file_123\",\"extracted_text\":\"PM1 workshop PMT boot pressure startup test record… Final fault cause: poor contact at the negative terminal of the DC 24V power supply circuit due to a short-jumped terminal block.\"}" + } + ] + }, + { + "role": "assistant", + "content": [ + { + "type": "text", + "text": "Final Summary: During the PMT boot-pressure startup test of the PM1 workshop on July 20, 2024, the drive could not run because the edge pressures on both sides failed to reach the 2.5-bar interlock requirement. After troubleshooting, the PLC output signals, hydraulic pipelines, and valves were all found to be normal. The root cause was ultimately identified as poor contact at the negative terminal of the proportional valve’s DC 24V power supply inside the PLC cabinet, caused by a short-jumpered terminal block. After re-connecting the negative incoming lines in parallel, the equipment returned to normal operation. It is recommended to replace terminal blocks in batches, inspect instruments with uncertain service life, and optimize the troubleshooting process by tracing common-mode issues from shared buses and power supply sources." + } + ] + } +], + async_mode="sync", + mode="fine", +) + +add_rsp = add_memories(add_req) + +print("add_memories rsp: \n\n", add_rsp) + + + +search_req = APISearchRequest( + user_id=user_id, + readable_cube_ids=["cube_test_user_2"], + query="Workshop PMT boot pressure startup test", + include_preference=False, +) + +search_rsp = search_memories(search_req).data +print("\n\nsearch_rsp: \n\n", json.dumps(search_rsp, indent=2, ensure_ascii=False)) +``` + +## Пример 3: Добавление и извлечение из нескольких Cube + +### Когда использовать: + +- Добавление памяти в разные изолированные пространства Cube. +- Вы хотите одновременно извлекать память из разных пространств Cube. + +### Ключевые моменты: + +- Ввод списка readable_cube_ids, содержащего несколько идентификаторов cube, при извлечении. + +### Полный пример кода +```python +import json +from memos.api.routers.server_router import add_memories, search_memories +from memos.api.product_models import APIADDRequest, APISearchRequest + +user_id = "test_user_3" +add_req = APIADDRequest( + user_id=user_id, + writable_cube_ids=["cube_test_user_3_1"] , + messages = [ + {"role": "user", "content": "I’ve planned to travel to Guangzhou during the summer vacation. What chain hotels are available for accommodation?"}, + {"role": "assistant", "content": "You can consider [7 Days Inn, Ji Hotel, Hilton], etc."}, + {"role": "user", "content": "I’ll choose 7 Days Inn."}, + {"role": "assistant", "content": "Okay, feel free to ask me if you have any other questions."} + ], + async_mode="sync", + mode="fine", +) + +add_rsp = add_memories(add_req) +print("add_memories rsp: \n\n", add_rsp) + +add_req = APIADDRequest( + user_id=user_id, + writable_cube_ids=["cube_test_user_3_2"] , + messages = [ + {"role": "user", "content": "I love you, I need you."}, + {"role": "assistant", "content": "Wow, I love you too"}, + ], + async_mode="sync", + mode="fine", +) + +add_rsp = add_memories(add_req) +print("add_memories rsp: \n\n", add_rsp) + +search_req = APISearchRequest( + user_id=user_id, + readable_cube_ids=["cube_test_user_3_1", "cube_test_user_3_2"], + query="Please recommend a hotel, Love u u", + include_preference=True, +) + +search_rsp = search_memories(search_req).data +print("\n\nsearch_rsp: \n\n", json.dumps(search_rsp, indent=2, ensure_ascii=False)) +``` + +## 示例 4:Только KVCacheMemory + +### Когда использовать: + +- Вы хотите краткосрочную рабочую память для ускорения многократных диалогов. +- Подходит для ускорения сессий чат-ботов или повторного использования подсказок. +- Лучше всего подходит для кэширования скрытых состояний / пар KV. + +### Ключевые моменты: + +- Использование KVCacheMemory без явной открытой памяти. +- Демонстрация извлечения → добавления → объединения → получения → удаления. +- Показано, как экспортировать/загружать KV cache. + +### Полный пример кода + + +```python +import json +from transformers import DynamicCache + +from memos.memories.activation.item import KVCacheItem +from memos.configs.memory import MemoryConfigFactory +from memos.memories.factory import MemoryFactory + +def get_cache_info(cache): + if not cache: + return None + + num_layers = 0 + total_size_bytes = 0 + + if hasattr(cache, "layers"): + num_layers = len(cache.layers) + for layer in cache.layers: + if hasattr(layer, "key_cache") and layer.key_cache is not None: + total_size_bytes += layer.key_cache.nelement() * layer.key_cache.element_size() + if hasattr(layer, "value_cache") and layer.value_cache is not None: + total_size_bytes += layer.value_cache.nelement() * layer.value_cache.element_size() + + if hasattr(layer, "keys") and layer.keys is not None: + total_size_bytes += layer.keys.nelement() * layer.keys.element_size() + if hasattr(layer, "values") and layer.values is not None: + total_size_bytes += layer.values.nelement() * layer.values.element_size() + + elif hasattr(cache, "key_cache") and hasattr(cache, "value_cache"): + num_layers = len(cache.key_cache) + for k, v in zip(cache.key_cache, cache.value_cache, strict=False): + if k is not None: + total_size_bytes += k.nelement() * k.element_size() + if v is not None: + total_size_bytes += v.nelement() * v.element_size() + + return { + "num_layers": num_layers, + "size_bytes": total_size_bytes, + "size_mb": f"{total_size_bytes / (1024 * 1024):.2f} MB", + } + + +def serialize_item(obj): + if isinstance(obj, list): + return [serialize_item(x) for x in obj] + + if isinstance(obj, KVCacheItem): + return { + "id": obj.id, + "metadata": obj.metadata, + "records": obj.records.model_dump() + if hasattr(obj.records, "model_dump") + else obj.records, + "memory": get_cache_info(obj.memory), + } + + if isinstance(obj, DynamicCache): + return get_cache_info(obj) + + return str(obj) + + +# Создание Конфигурации Для KVCacheMemory (HuggingFace Backend) +config = MemoryConfigFactory( + backend="kv_cache", + config={ + "extractor_llm": { + "backend": "huggingface", + "config": { + "model_name_or_path": "Qwen/Qwen3-0.6B", + "max_tokens": 32, + "add_generation_prompt": True, + "remove_think_prefix": True, + }, + }, + }, +) + +# Инстанцирование KVCacheMemory +kv_mem = MemoryFactory.from_config(config) + +# Извлечение Одного KVCacheItem (DynamicCache) +prompt = [ + {"role": "user", "content": "What is MemOS?"}, + {"role": "assistant", "content": "MemOS is a memory operating system for LLMs."}, +] +print("===== Extract KVCacheItem =====") +cache_item = kv_mem.extract(prompt) +print(json.dumps(serialize_item(cache_item), indent=2, default=str)) + +# Добавление Кэша В Память +kv_mem.add([cache_item]) +print("All caches:") +print(json.dumps(serialize_item(kv_mem.get_all()), indent=2, default=str)) + +# Получение По ID +retrieved = kv_mem.get(cache_item.id) +print("Retrieved:") +print(json.dumps(serialize_item(retrieved), indent=2, default=str)) + +# Объединение Кэша +item2 = kv_mem.extract([{"role": "user", "content": "Tell me a joke."}]) +kv_mem.add([item2]) +merged = kv_mem.get_cache([cache_item.id, item2.id]) +print("Merged cache:") +print(json.dumps(serialize_item(merged), indent=2, default=str)) + +# Удалить Один Из Них +kv_mem.delete([cache_item.id]) +print("After delete:") +print(json.dumps(serialize_item(kv_mem.get_all()), indent=2, default=str)) + +# Экспорт И Загрузка Кэша +kv_mem.dump("tmp/kv_mem") +print("Dumped to tmp/kv_mem") +kv_mem.delete_all() +kv_mem.load("tmp/kv_mem") +print("Loaded caches:") +print(json.dumps(serialize_item(kv_mem.get_all()), indent=2, default=str)) +``` + +## Пример 5: Планирование памяти + +### Когда использовать: + +- Вы хотите настроить логику планирования памяти или расширить фоновые задачи для постоянного управления и оптимизации памяти с помощью асинхронных триггеров. +- Подходит для SaaS агентов или задач LLM с многократными диалогами. +- Демонстрация настройки и запуска задач управления памятью MemScheduler. + +### Ключевые моменты: + +- Регистрация пользовательских обратных вызовов через `mem_scheduler.register_handlers`. +- Использование `add_handler` и `chat_stream_playground` для взаимодействия. +- Показано, как получить и использовать экземпляр MemScheduler, инициализированный из переменных окружения. + +### Полный пример кода + +```python +import asyncio +import json +import os +import sys +import time + +from pathlib import Path + + +# Установить Путь Перед Импортом В Зависимостях +FILE_PATH = Path(__file__).absolute() +BASE_DIR = FILE_PATH.parent.parent.parent +sys.path.insert(0, str(BASE_DIR)) # Включить Выполнение Из Любой Рабочей Директории + +# Установить Переменные Среды Перед Импортом server_router, Чтобы Убедиться, Что Компоненты Правильно Инициализированы +os.environ["ENABLE_CHAT_API"] = "true" + +from memos.api.product_models import APIADDRequest, ChatPlaygroundRequest # noqa: E402 + +# Импортировать Из server_router Для Инициализации +from memos.api.routers.server_router import ( # noqa: E402 + add_handler, + chat_stream_playground, + mem_scheduler, +) +from memos.log import get_logger # noqa: E402 +from memos.mem_scheduler.schemas.message_schemas import ScheduleMessageItem # noqa: E402 +from memos.mem_scheduler.schemas.task_schemas import ( # noqa: E402 + MEM_UPDATE_TASK_LABEL, + QUERY_TASK_LABEL, +) + + +logger = get_logger(__name__) + + +def init_task(): + conversations = [ + {"role": "user", "content": "I just adopted a golden retriever puppy yesterday."}, + {"role": "assistant", "content": "Congratulations! What did you name your new puppy?"}, + { + "role": "user", + "content": "His name is Max. I live near Central Park in New York where we'll walk daily.", + }, + {"role": "assistant", "content": "Max will love those walks! Any favorite treats for him?"}, + { + "role": "user", + "content": "He loves peanut butter biscuits. Personally, I'm allergic to nuts though.", + }, + {"role": "assistant", "content": "Good to know about your allergy. I'll note that."}, + # Вопрос 1 (Питомец) - Имя + {"role": "user", "content": "What's my dog's name again?"}, + {"role": "assistant", "content": "Your dog is named Max."}, + # Вопрос 2 (Питомец) - Порода + {"role": "user", "content": "Can you remind me what breed Max is?"}, + {"role": "assistant", "content": "Max is a golden retriever."}, + # Вопрос 3 (Питомец) - Лакомства + {"role": "user", "content": "What treats does Max like?"}, + {"role": "assistant", "content": "He loves peanut butter biscuits."}, + # Вопрос 4 (Адрес) + {"role": "user", "content": "Where did I say I live?"}, + {"role": "assistant", "content": "You live near Central Park in New York."}, + # Вопрос 5 (Аллергия) + {"role": "user", "content": "What food should I avoid due to allergy?"}, + {"role": "assistant", "content": "You're allergic to nuts."}, + {"role": "user", "content": "Perfect, just wanted to check what you remembered."}, + {"role": "assistant", "content": "Happy to help! Let me know if you need anything else."}, + ] + + questions = [ + {"question": "What's my dog's name again?", "category": "Pet"}, + {"question": "Can you remind me what breed Max is?", "category": "Pet"}, + {"question": "What treats does Max like?", "category": "Pet"}, + {"question": "Where did I say I live?", "category": "Address"}, + {"question": "What food should I avoid due to allergy?", "category": "Allergy"}, + ] + return conversations, questions + + +working_memories = [] + + +# Определить Пользовательскую Функцию Обработки Запросов +def custom_query_handler(messages: list[ScheduleMessageItem]): + for msg in messages: + # Печать Введенного Пользователем Содержимого + print(f"\n[scheduler] User input query: {msg.content}") + # Вручную Сформировать Новое Сообщение С Меткой MEM_UPDATE Для Запуска Обновления Памяти + new_msg = msg.model_copy(update={"label": MEM_UPDATE_TASK_LABEL}) + # Отправить Сообщение На Обработку Диспетчеру + mem_scheduler.submit_messages([new_msg]) + + +# Определение Пользовательской Функции Обработки Обновления Памяти +def custom_mem_update_handler(messages: list[ScheduleMessageItem]): + global working_memories + search_args = {} + top_k = 2 + for msg in messages: + # Поиск связанных с текущим содержимым воспоминаний в текстовой памяти (возвращает top_k=2) + results = mem_scheduler.retriever.search( + query=msg.content, + user_id=msg.user_id, + mem_cube_id=msg.mem_cube_id, + mem_cube=mem_scheduler.current_mem_cube, + top_k=top_k, + method=mem_scheduler.search_method, + search_args=search_args, + ) + working_memories.extend(results) + working_memories = working_memories[-5:] + for mem in results: + print(f"\n[scheduler] Retrieved memory: {mem.memory}") + + +async def run_with_scheduler(): + print("==== run_with_automatic_scheduler_init ====") + conversations, questions = init_task() + + # Инициализация с использованием компонента server_router + # Конфигурация загрузки через переменные окружения в init_server() + + user_id = "user_1" + mem_cube_id = "mem_cube_5" + + print(f"Adding conversations for user {user_id}...") + + # Добавление памяти с помощью add_handler + add_req = APIADDRequest( + user_id=user_id, + writable_cube_ids=[mem_cube_id], + messages=conversations, + async_mode="sync", # Использование синхронного режима в этом примере для немедленного добавления + ) + add_handler.handle_add_memories(add_req) + + for item in questions: + print("===== Chat Start =====") + query = item["question"] + print(f"Query:\n {query}\n") + + # Использование chat_handler для общения + chat_req = ChatPlaygroundRequest( + user_id=user_id, + query=query, + readable_cube_ids=[mem_cube_id], + writable_cube_ids=[mem_cube_id], + ) + response = chat_stream_playground(chat_req) + + answer = "" + buffer = "" + async for chunk in response.body_iterator: + if isinstance(chunk, bytes): + chunk = chunk.decode("utf-8") + buffer += chunk + while "\n\n" in buffer: + msg, buffer = buffer.split("\n\n", 1) + for line in msg.split("\n"): + if line.startswith("data: "): + json_str = line[6:] + try: + data = json.loads(json_str) + if data.get("type") == "text": + answer += data["data"] + except json.JSONDecodeError: + pass + print(f"\nAnswer: {answer}") + + +if __name__ == "__main__": + mem_scheduler.register_handlers( + { + QUERY_TASK_LABEL: custom_query_handler, # Задача запроса + MEM_UPDATE_TASK_LABEL: custom_mem_update_handler, # Задача обновления памяти + } + ) + + asyncio.run(run_with_scheduler()) + + time.sleep(20) + mem_scheduler.stop() +``` + +::note +**Обратите внимание**
+Используйте dump() и load() для постоянного хранения вашего куба памяти. + +Обязательно убедитесь, что размерность вашей векторной базы данных соответствует вашему эмбеддеру. + +Если вы используете функции открытой памяти на основе графов, вам необходимо установить Neo4j Desktop. +:: + +## Следующий шаг + +Вы только начали! Теперь вы можете попробовать: + +- Выбрать пример, соответствующий вашему сценарию использования. +- Комбинировать модули для создания более умных и долговечных агентов! + +Нужна дополнительная помощь? +Посмотрите документацию API или внесите свой собственный пример! + diff --git a/content/ru/open_source/getting_started/installation.md b/content/ru/open_source/getting_started/installation.md new file mode 100644 index 00000000..53eb9318 --- /dev/null +++ b/content/ru/open_source/getting_started/installation.md @@ -0,0 +1,646 @@ +--- +title: "Руководство по Установке" +desc: "Полное руководство по установке MemOS." +--- + + +::card-group + + :::card + --- + icon: ri:database-2-line + title: Установка Через Docker + to: /cn/open_source/getting_started/installation#УстановкаЧерезDocker + --- + Подходит для быстрой развертки: одно нажатие для запуска сервиса и зависимых компонентов. + ::: + + :::card + --- + icon: ri:play-line + title: Установка Из Исходного Кода + to: /cn/open_source/getting_started/installation#УстановкаИзИсходногоКода + --- + Подходит для вторичной разработки и вклада: редактируемая установка, возможность тестирования, локальная отладка. + ::: + + :::card + --- + icon: ri:tree-line + title: Установка Через pip + to: /cn/open_source/getting_started/installation#УстановкаЧерезpip + --- + Самый простой способ установки: быстрое начало работы с MemOS. + ::: + + +:: + + + +## Установка через Docker +```bash +git clone https://github.com/MemTensor/MemOS.git +cd MemOS +``` + +#### Создание файла конфигурации .env +::note +**Пожалуйста, обратите внимание**
+Конфигурация файла .env должна находиться в корневом каталоге проекта MemOS +:: + +::steps{level="4"} + +#### 1. Создать .env +```bash +cd MemOS +touch .env +``` + +#### 2. Содержимое .env + +.env быстрая конфигурация выглядит следующим образом +```bash + +# Ключ API OpenAI (необходимо настроить) +OPENAI_API_KEY=sk-xxx +# Базовый URL API OpenAI +OPENAI_API_BASE=http://xxx:3000/v1 +# Имя модели по умолчанию +MOS_CHAT_MODEL=qwen3-max + +# Модель Memory Reader LLM +MEMRADER_MODEL=qwen3-max +# Ключ API Memory Reader +MEMRADER_API_KEY=sk-xxx +# Базовый URL API Memory Reader +MEMRADER_API_BASE=http://xxx:3000/v1 + +# Имя модели Embedder +MOS_EMBEDDER_MODEL=text-embedding-v4 +# Конфигурация Embedding Backend Два Выбора ollama | universal_api +MOS_EMBEDDER_BACKEND=universal_api +# Embedder API Базовый URL +MOS_EMBEDDER_API_BASE=http://xxx:8081/v1 +# Embedder API Ключ +MOS_EMBEDDER_API_KEY=xxx +# Размерность Векторов Embedding +EMBEDDING_DIMENSION=1024 +# Reranker Backend (http_bge | и т.д.) +MOS_RERANKER_BACKEND=cosine_local + +# Neo4j Подключение URI +# Допустимые Значения: neo4j-community | neo4j | nebular | polardb +NEO4J_BACKEND=neo4j-community +# Обязательно, Когда backend=neo4j* +NEO4J_URI=bolt://localhost:7687 +NEO4J_USER=neo4j +NEO4J_PASSWORD=12345678 +NEO4J_DB_NAME=neo4j +MOS_NEO4J_SHARED_DB=false + +# Использовать Ли Redis Диспетчер +DEFAULT_USE_REDIS_QUEUE=false + +# Включить Чат API +ENABLE_CHAT_API=true +# Список Моделей Чата Можно Запросить Через 百炼. Модели Можно Выбрать +CHAT_MODEL_LIST=[{"backend": "qwen", "api_base": "https://xxx/v1", "api_key": "sk-xxx", "model_name_or_path": "qwen3-max", "extra_body": {"enable_thinking": true} ,"support_models": ["qwen3-max"]}] +``` +#### Пример конфигурации .env на основе BaiLian +```bash +# Можно Запросить Через Платформу 百炼 +# https://bailian.console.aliyun.com/?spm=a2c4g.11186623.0.0.2f2165b08fRk4l&tab=api#/api +# После Успешной Заявки Получите API_KEY и BASE_URL, Пример Конфигурации Ниже + +# OpenAI API Ключ (Используйте API_KEY 百炼) +OPENAI_API_KEY=you_bailian_api_key +# Базовый URL API OpenAI +OPENAI_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1 +# Имя модели по умолчанию +MOS_CHAT_MODEL=qwen3-max + +# Модель Memory Reader LLM +MEMRADER_MODEL=qwen3-max +# Memory Reader API Ключ (Используйте API_KEY 百炼) +MEMRADER_API_KEY=you_bailian_api_key +# Базовый URL API Memory Reader +MEMRADER_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1 + +# Название модели Embedder можно найти по следующей ссылке +# https://bailian.console.aliyun.com/?spm=a2c4g.11186623.0.0.2f2165b08fRk4l&tab=api#/api/?type=model&url=2846066 +MOS_EMBEDDER_MODEL=text-embedding-v4 +# Конфигурация Embedding Backend Два Выбора ollama | universal_api +MOS_EMBEDDER_BACKEND=universal_api +# Embedder API Базовый URL +MOS_EMBEDDER_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1 +# API-ключ Embedder (используйте API_KEY от 百炼) +MOS_EMBEDDER_API_KEY=you_bailian_api_key +# Размерность Векторов Embedding +EMBEDDING_DIMENSION=1024 +# Reranker Backend (http_bge | и т.д.) +MOS_RERANKER_BACKEND=cosine_local + +# Neo4j Подключение URI +# Допустимые Значения: neo4j-community | neo4j | nebular | polardb +NEO4J_BACKEND=neo4j-community +# Обязательно, Когда backend=neo4j* +NEO4J_URI=bolt://localhost:7687 +NEO4J_USER=neo4j +NEO4J_PASSWORD=12345678 +NEO4J_DB_NAME=neo4j +MOS_NEO4J_SHARED_DB=false + +# Использовать Ли Redis Диспетчер +DEFAULT_USE_REDIS_QUEUE=false + +# Включить Чат API +ENABLE_CHAT_API=true + +CHAT_MODEL_LIST=[{"backend": "qwen", "api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1", "api_key": "you_bailian_api_key", "model_name_or_path": "qwen3-max-preview", "extra_body": {"enable_thinking": true} ,"support_models": ["qwen3-max-preview"]}] +``` +![MemOS bailian](https://cdn.memtensor.com.cn/img/get_key_url_by_bailian_compressed.png) +
Пример запроса API_KEY и BASE_URL от 百炼
+ +:: + + +#### Конфигурация файла Dockerfile +::note +**Пожалуйста, обратите внимание**
+Файл Dockerfile находится в каталоге docker +:: + +```bash +# Перейдите в каталог docker +cd docker +``` +Содержит быстрый режим и полный режим, можно различать использование облегченного пакета (различие arm и x86) и полного пакета (различие arm и x86) + +```bash + +● Упрощенный пакет: упрощает зависимости, такие как nvidia, которые имеют слишком большой объем, для достижения легковесности образа, что делает локальное развертывание более легким и быстрым. +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-base:v1.0 +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-base-arm:v1.0 + +● Полный пакет: включает все зависимости MemOS в образ, чтобы вы могли испытать полный функционал, можно напрямую построить и запустить, настроив Dockerfile. +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-full-base:v1.0.0 +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-full-base-arm:v1.0.0 +``` + +```bash +# Текущий пример использует упрощенный пакет url +FROM registry.cn-shanghai.aliyuncs.com/memtensor/memos-base-arm:v1.0 + +WORKDIR /app + +ENV HF_ENDPOINT=https://hf-mirror.com + +ENV PYTHONPATH=/app/src + +COPY src/ ./src/ + +EXPOSE 8000 + +CMD ["uvicorn", "memos.api.server_api:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] + +``` + +#### Запуск клиента docker +```bash + # Если docker не установлен, пожалуйста, установите соответствующую версию, ссылка для загрузки ниже: + https://www.docker.com/ + + # После установки вы можете запустить docker через клиент или через командную строку + # Запустите docker через командную строку + sudo systemctl start docker + +# После установки проверьте состояние docker +docker ps + +# Просмотрите образы docker (необязательно) +docker images + +``` + +#### Построение и запуск сервиса : +::note +**Пожалуйста, обратите внимание**
+Команда сборки также находится в каталоге docker +:: +```bash +# В каталоге docker +docker compose up +``` +![MemOS buildComposeupSuccess](https://cdn.memtensor.com.cn/img/memos_build_composeup_success_compressed.png) +
Пример изображения, порт согласно пользовательской конфигурации docker
+ +#### Доступ к API через [http://localhost:8000/docs](http://localhost:8000/docs). + +![MemOS Architecture](https://cdn.memtensor.com.cn/img/memos_run_server_success_compressed.png) + +#### ADD Memory +```bash +curl --location --request POST 'http://127.0.0.1:8000/product/add' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + + "messages": [{ + "role": "user", + "content": "Мне нравится есть клубнику" + }], + "user_id": "8736b16e-1d20-4163-980b-a5063c3facdc", + "writable_cube_ids":["b32d0977-435d-4828-a86f-4f47f8b55bca"] +}' + +# Ответ +{ + "code": 200, + "message": "Memory created successfully", + "data": null +} +``` + +#### Search Memory +```bash +curl --location --request POST 'http://127.0.0.1:8000/product/search' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "query": "Что мне нравится есть", + "user_id": "8736b16e-1d20-4163-980b-a5063c3facdc", + "readable_cube_ids": ["b32d0977-435d-4828-a86f-4f47f8b55bca"], + "top_k":20 + }' +# Ответ +{ + "code": 200, + "message": "Search completed successfully", + "data": { + "text_mem": [ + { + "cube_id": "7231eda8-6c57-4f6e-97ce-98b699eebb98", + "memories": [ + { + "id": "2f40be8f-736c-4a5f-aada-9489037769e0", + "memory": "[user观点]Пользователь любит клубнику.", + "metadata": { + "user_id": "de8215e3-3beb-4afc-9b64-ae594d62f1ea", + "session_id": "root_session", + "status": "activated", + "type": "fact", + "key": "Предпочтение пользователя к клубнике", + "confidence": 0.99, + "source": null, + "tags": [ + "предпочтение", + "клубника" + ], + "visibility": null, + "updated_at": "2025-09-18T08:23:44.625479000+00:00", + "memory_type": "UserMemory", + "sources": [], + "embedding": [], + "created_at": "2025-09-18T08:23:44.625511000+00:00", + "usage": [ + "{ + "time": "2025-09-18T08:24:17.759748", + "info": { + "user_id": "de8215e3-3beb-4afc-9b64-ae594d62f1ea", + "session_id": "root_session" + } + }" + ], + "background": "Пользователь выразил предпочтение к клубнике, что показывает их склонность в диетических предпочтениях.", + "relativity": 0.6349761312470591, + "vector_sync": "success", + "ref_id": "[2f40be8f]", + "id": "2f40be8f-736c-4a5f-aada-9489037769e0", + "memory": "[user观点]Пользователь любит клубнику." + }, + "ref_id": "[2f40be8f]" + }, + ... + } + } + ], + "act_mem": [], + "para_mem": [] + } +} +``` + + +## Установка из исходного кода +```bash +git clone https://github.com/MemTensor/MemOS.git +cd MemOS +``` + +#### Создание файла конфигурации .env +Серверный API MemOS зависит от переменных окружения для запуска, поэтому необходимо создать файл .env в каталоге запуска. +1. Создайте .env +```bash +cd MemOS +touch .env +``` + +2. Содержимое .env, быстрая конфигурация см. в разделе установки docker [конфигурация env](/open_source/getting_started/installation#2.-.env-内容) +Подробная конфигурация .env см. в [конфигурации env](/open_source/getting_started/rest_api_server/#本地运行) + +::note +**Пожалуйста, обратите внимание**
+Конфигурация файла .env должна находиться в корневом каталоге проекта MemOS +:: + + +#### Установка зависимостей +```bash +# Выполнить команду установки +pip install -e . +pip install --no-cache-dir -r ./docker/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ +# Настроить PYTHONPATH в абсолютном каталоге текущего проекта src +export PYTHONPATH=/******/MemOS/src +``` + +#### Установка графовой базы данных +Основой памяти Memos является хранение через графовую базу данных, в открытом проекте рекомендуется использовать Neo4j для запуска вашего первого проекта. Сообщество также поддерживает версии Neo4j Enterprise/Community и PolarDB. + +::note +**Самый быстрый выбор для разработчиков ПК: Neo4j Desktop**
Если вы планируете использовать Neo4j в качестве графовой памяти, Neo4j Desktop может быть самым удобным способом установки.
+Кроме того, вам нужно установить в файле .env **NEO4J_BACKEND=neo4j** +:: + + +#### Запустить MemOS Server. +```bash +# В корневом каталоге проекта +uvicorn memos.api.server_api:app --host 0.0.0.0 --port 8000 --workers 1 +``` + +#### ADD Memory +```bash +curl --location --request POST 'http://127.0.0.1:8000/product/add' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + + "messages": [{ + "role": "user", + "content": "Мне нравится есть клубнику" + }], + "user_id": "8736b16e-1d20-4163-980b-a5063c3facdc", + "writable_cube_ids":["b32d0977-435d-4828-a86f-4f47f8b55bca"] +}' + +# Ответ +{ + "code": 200, + "message": "Memory created successfully", + "data": null +} +``` + +#### Search Memory +```bash +curl --location --request POST 'http://127.0.0.1:8000/product/search' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "query": "Что мне нравится есть", + "user_id": "8736b16e-1d20-4163-980b-a5063c3facdc", + "readable_cube_ids": ["b32d0977-435d-4828-a86f-4f47f8b55bca"], + "top_k":20 + }' +# Ответ +{ + "code": 200, + "message": "Search completed successfully", + "data": { + "text_mem": [ + { + "cube_id": "7231eda8-6c57-4f6e-97ce-98b699eebb98", + "memories": [ + { + "id": "2f40be8f-736c-4a5f-aada-9489037769e0", + "memory": "[user观点]Пользователь любит клубнику.", + "metadata": { + "user_id": "de8215e3-3beb-4afc-9b64-ae594d62f1ea", + "session_id": "root_session", + "status": "activated", + "type": "fact", + "key": "Предпочтение пользователя к клубнике", + "confidence": 0.99, + "source": null, + "tags": [ + "предпочтение", + "клубника" + ], + "visibility": null, + "updated_at": "2025-09-18T08:23:44.625479000+00:00", + "memory_type": "UserMemory", + "sources": [], + "embedding": [], + "created_at": "2025-09-18T08:23:44.625511000+00:00", + "usage": [ + "{ + "time": "2025-09-18T08:24:17.759748", + "info": { + "user_id": "de8215e3-3beb-4afc-9b64-ae594d62f1ea", + "session_id": "root_session" + } + }" + ], + "background": "Пользователь выразил предпочтение к клубнике, что показывает их склонность в диетических предпочтениях.", + "relativity": 0.6349761312470591, + "vector_sync": "success", + "ref_id": "[2f40be8f]", + "id": "2f40be8f-736c-4a5f-aada-9489037769e0", + "memory": "[user观点]Пользователь любит клубнику." + }, + "ref_id": "[2f40be8f]" + }, + ... + } + } + ], + "act_mem": [], + "para_mem": [] + } +} +``` + + +## Установка через pip +Самый простой способ установить MemOS — использовать pip. + +::steps{level="4"} + +#### Создание и активация окружения Conda (рекомендуется) + +Чтобы избежать конфликтов зависимостей, настоятельно рекомендуется использовать отдельное окружение Conda. + +```bash +conda create -n memos python=3.11 +conda activate memos +``` + +#### Установка MemOS из PyPI +Установка MemOS и всех его дополнительных компонентов: + +```bash +pip install -U "MemoryOS[all]" +``` + +#### Установка графовой базы данных +Основой памяти Memos является хранение через графовую базу данных, в открытом проекте рекомендуется использовать Neo4j для запуска вашего первого проекта. Сообщество также поддерживает версии Neo4j Enterprise/Community и PolarDB. + +::note +**Самый быстрый выбор для разработчиков ПК: Neo4j Desktop**
Если вы планируете использовать Neo4j в качестве графовой памяти, Neo4j Desktop может быть самым удобным способом установки. +:: + + +#### Создание файла конфигурации .env +Серверный API MemOS зависит от переменных окружения для запуска, поэтому необходимо создать файл .env в каталоге запуска. +1. Создайте .env +```bash +touch .env +``` + +2. Пример содержимого .env +Подробная конфигурация .env см. в [конфигурации env](/open_source/getting_started/rest_api_server) + +Для получения подробной информации о настройке среды разработки, руководствах по рабочим процессам и лучших практиках вклада, пожалуйста, обратитесь к нашему [руководству по вкладу](/open_source/contribution/overview). + +#### Запустить MemOS Server +MemOS не будет автоматически загружать файл .env, пожалуйста, используйте способ python-dotenv для запуска. +```bash +python -m dotenv run -- \ + uvicorn memos.api.server_api:app \ + --host 0.0.0.0 \ + --port 8000 +``` +После успешного запуска вы увидите аналогичный вывод: +```text +INFO: Uvicorn running on http://0.0.0.0:8000 +INFO: Application startup complete. +``` + +#### Начните свои операции памяти +Добавление памяти (способы вызова совпадают с развертыванием из исходного кода, на этот раз мы попробуем **синхронный** способ добавления памяти): +```text +curl --location --request POST 'http://127.0.0.1:8000/product/add' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "messages": [{ + "role": "user", + "content": "Мне нравится есть клубнику" + }], + "user_id": "8736b16e-1d20-4163-980b-a5063c3facdc", + "writable_cube_ids":["b32d0977-435d-4828-a86f-4f47f8b55bca"], + "async_mode": "sync", + "mode": "fine" +}' +``` + +::note +**Ожидаемый вывод**
+```json +{ + "code": 200, + "message": "Memory added successfully", + "data": [ + { + "memory": "Пользователь любит есть клубнику.", + "memory_id": "d01a354e-e5f6-4e2a-bd89-c57ae", + "memory_type": "UserMemory", + "cube_id": "b32d0977-435d-4828-a86f-4f47f8b55bca" + } + ] +} +``` +:: + +Извлечение памяти (способы вызова совпадают с развертыванием из исходного кода): +```text +curl --location --request POST 'http://127.0.0.1:8000/product/search' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "query": "Что мне нравится есть", + "user_id": "8736b16e-1d20-4163-980b-a5063c3facdc", + "readable_cube_ids": ["b32d0977-435d-4828-a86f-4f47f8b55bca"], + "top_k":20 + }' +``` + +::note +**Ожидаемый вывод**
+```json +{ + "code": 200, + "message": "Search completed successfully", + "data": { + "text_mem": [ + { + "cube_id": "b32d0977-435d-4828-a86f-4f47f8b55bca", + "memories": [ + { + "id": "f18cbe36-4cd9-456f-9b9f-6be89c35b2bf", + "memory": "Пользователь любит есть клубнику.", + "metadata": { + "user_id": "8736b16e-1d20-4163-980b-a5dc", + "session_id": "default_session", + "status": "activated", + "type": "fact", + "key": "Предпочтение Клубники", + "confidence": 0.99, + "source": null, + "tags": ["Предпочтение Напитков", "Клубника"], + "visibility": null, + "updated_at": "2025-12-26T20:35:08.178564000+00:00", + "info": null, + "covered_history": null, + "memory_type": "WorkingMemory", + "sources": [], + "embedding": [], + "created_at": "2025-12-26T20:35:08.177484000+00:00", + "usage": [], + "background": "Пользователь выразил положительное мнение, что указывает на то, что они любят этот фрукт и, возможно, склонны включать клубнику в свои пищевые предпочтения.", + "file_ids": [], + "relativity": 0.0, + "ref_id": "[f18cbe36]" + }, + "ref_id": "[f18cbe36]" + } + ] + } + ], + "act_mem": [], + "para_mem": [], + "pref_mem": [ + { + "cube_id": "b32d0977-435d-4828-a86f-4f47f8b55bca", + "memories": [] + } + ], + "pref_note": "", + "tool_mem": [ + { + "cube_id": "b32d0977-435d-4828-a86f-4f47f8b55bca", + "memories": [] + } + ], + "pref_string": "" + } +} +``` +:: + +:: + +::note +**Скачать пример кода**
Поздравляем вас 🎉 с успешной установкой MemOS через pip и прохождением минимального тестового случая! Вы также можете скачать пример кода на основе следующих команд, чтобы понять, как вызываются каждый внутренний модуль memos: +```bash +memos download_examples +``` +:: + + diff --git a/content/ru/open_source/getting_started/rest_api_server.md b/content/ru/open_source/getting_started/rest_api_server.md new file mode 100644 index 00000000..bca38fa5 --- /dev/null +++ b/content/ru/open_source/getting_started/rest_api_server.md @@ -0,0 +1,501 @@ +--- +title: REST API Сервис +desc: MemOS предоставляет REST API сервис, написанный с использованием FastAPI. Пользователи могут выполнять все операции через REST интерфейс. +--- + +![MemOS Architecture](https://cdn.memtensor.com.cn/img/memos_run_server_success_compressed.png) +
MemOS REST API Служба Поддержки API
+ +### Функциональные Особенности + +- Добавить Новую Память: создать новую память для указанного пользователя. +- Поиск Памяти: искать содержимое памяти для указанного пользователя. +- Получить Все Памяти Пользователя: получить все содержимое памяти для определенного пользователя. +- Обратная Связь по Памяти: предоставить обратную связь по содержимому памяти для указанного пользователя. +- Общение с MemOS: вести диалог с MemOS, возвращая SSE потоковый ответ. + + +## Локальный Запуск + +### 1. Локальная Загрузка +```bash +# Скачайте Код В Локальную Папку +git clone https://github.com/MemTensor/MemOS +``` + +### 2. Настройка Переменных Среды +```bash +# Перейдите В Директорию Папки +cd MemOS +``` + +#### Создайте файл `.env` в корневом каталоге и настройте ваши переменные среды. +##### Быстрая Конфигурация .env выглядит следующим образом, полная версия доступна по ссылке .env.example. + +```bash + +# Ключ API OpenAI (необходимо настроить) +OPENAI_API_KEY=sk-xxx +# Базовый URL API OpenAI +OPENAI_API_BASE=http://xxx:3000/v1 +# Имя Модели По Умолчанию +MOS_CHAT_MODEL=qwen3-max + +# Модель Memory Reader LLM +MEMRADER_MODEL=qwen3-max +# Ключ API Memory Reader +MEMRADER_API_KEY=sk-xxx +# Базовый URL API Memory Reader +MEMRADER_API_BASE=http://xxx:3000/v1 + +# Имя Модели Embedder +MOS_EMBEDDER_MODEL=text-embedding-v4 +# Настройка embedding backend два варианта: ollama | universal_api +MOS_EMBEDDER_BACKEND=universal_api +# Базовый URL API Embedder +MOS_EMBEDDER_API_BASE=http://xxx:8081/v1 +# Ключ API Embedder +MOS_EMBEDDER_API_KEY=xxx +# Размерность Векторов Embedding +EMBEDDING_DIMENSION=1024 +# Reranker Backend (http_bge | etc.) +MOS_RERANKER_BACKEND=cosine_local + +# Neo4j Connection URI +# Допустимые значения: neo4j-community | neo4j | nebular | polardb +NEO4J_BACKEND=neo4j-community +# Обязательно, когда backend=neo4j* +NEO4J_URI=bolt://localhost:7687 +NEO4J_USER=neo4j +NEO4J_PASSWORD=12345678 +NEO4J_DB_NAME=neo4j +MOS_NEO4J_SHARED_DB=false + +# Использовать ли планировщик Redis +DEFAULT_USE_REDIS_QUEUE=false + +# Включить Chat API +ENABLE_CHAT_API=true +# Список моделей чата можно запросить через 百炼. Модели можно выбирать самостоятельно +CHAT_MODEL_LIST=[{"backend": "qwen", "api_base": "https://xxx/v1", "api_key": "sk-xxx", "model_name_or_path": "qwen3-max", "extra_body": {"enable_thinking": true} ,"support_models": ["qwen3-max"]}] +``` + +### 3. Настройка Конфигурации на Примере BaiLian + +```bash +# Можно запросить через платформу 百炼 +# https://bailian.console.aliyun.com/?spm=a2c4g.11186623.0.0.2f2165b08fRk4l&tab=api#/api +# После успешного запроса получите API_KEY и BASE_URL, пример конфигурации ниже + +# OpenAI API Ключ (используйте API_KEY от 百炼) +OPENAI_API_KEY=you_bailian_api_key +# Базовый URL API OpenAI +OPENAI_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1 +# Имя Модели По Умолчанию +MOS_CHAT_MODEL=qwen3-max + +# Модель Memory Reader LLM +MEMRADER_MODEL=qwen3-max +# Memory Reader API Ключ (используйте API_KEY от 百炼) +MEMRADER_API_KEY=you_bailian_api_key +# Базовый URL API Memory Reader +MEMRADER_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1 + +# Название модели Embedder можно найти по следующей ссылке +# https://bailian.console.aliyun.com/?spm=a2c4g.11186623.0.0.2f2165b08fRk4l&tab=api#/api/?type=model&url=2846066 +MOS_EMBEDDER_MODEL=text-embedding-v4 +# Настройка embedding backend два варианта: ollama | universal_api +MOS_EMBEDDER_BACKEND=universal_api +# Базовый URL API Embedder +MOS_EMBEDDER_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1 +# Embedder API Ключ (используйте API_KEY от 百炼) +MOS_EMBEDDER_API_KEY=you_bailian_api_key +# Размерность Векторов Embedding +EMBEDDING_DIMENSION=1024 +# Reranker Backend (http_bge | etc.) +MOS_RERANKER_BACKEND=cosine_local + +# Neo4j Connection URI +# Допустимые значения: neo4j-community | neo4j | nebular | polardb +NEO4J_BACKEND=neo4j-community +# Обязательно, когда backend=neo4j* +NEO4J_URI=bolt://localhost:7687 +NEO4J_USER=neo4j +NEO4J_PASSWORD=12345678 +NEO4J_DB_NAME=neo4j +MOS_NEO4J_SHARED_DB=false + +# Использовать ли планировщик Redis +DEFAULT_USE_REDIS_QUEUE=false + +# Включить Chat API +ENABLE_CHAT_API=true + +CHAT_MODEL_LIST=[{"backend": "qwen", "api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1", "api_key": "you_bailian_api_key", "model_name_or_path": "qwen3-max-preview", "extra_body": {"enable_thinking": true} ,"support_models": ["qwen3-max-preview"]}] +``` +![MemOS bailian](https://cdn.memtensor.com.cn/img/get_key_url_by_bailian_compressed.png) +
Пример запроса API_KEY и BASE_URL через 百炼
+ +Настройте версии зависимостей в docker/requirement.txt и т.д. (можно игнорировать). Полную версию можно найти по requirements.txt. + +### 4、Запуск Docker +```bash + # Если Docker не установлен, пожалуйста, установите соответствующую версию, адрес для загрузки ниже: + https://www.docker.com/ + +# После установки можно запустить Docker через клиент или через командную строку +# Запуск Docker через командную строку +sudo systemctl start docker + +# После установки проверьте состояние Docker +docker ps + +# Просмотр образов Docker (необязательно) +docker images + +``` + + +### Способ 1: Запуск с Использованием Образа Зависимостей Docker (Рекомендуется) +::steps{level="4"} + +```bash +# Войдите в каталог Docker +cd docker +``` + +#### Подтверждение Использования Образа +Включает быстрый режим и полный режим, можно различать использование облегченного пакета (различие arm и x86) и полного пакета (различие arm и x86) + +```bash + +● Упрощенный пакет: Упрощение зависимостей, таких как nvidia, которые имеют слишком большой объем, для достижения легкости образа, что делает локальное развертывание более легким и быстрым. +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-base:v1.0 +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-base-arm:v1.0 + +● Полный пакет: Все зависимости MemOS упакованы в образ, можно испытать полный функционал, можно напрямую построить и запустить через конфигурацию Dockerfile. +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-full-base:v1.0.0 +url: registry.cn-shanghai.aliyuncs.com/memtensor/memos-full-base-arm:v1.0.0 +``` +#### Настройка Файла Dockerfile + +```bash +# Текущий пример использует упрощенный пакет url +FROM registry.cn-shanghai.aliyuncs.com/memtensor/memos-base-arm:v1.0 + +WORKDIR /app + +ENV HF_ENDPOINT=https://hf-mirror.com + +ENV PYTHONPATH=/app/src + +COPY src/ ./src/ + +EXPOSE 8000 + +CMD ["uvicorn", "memos.api.server_api:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] + +``` + +#### Построить и Запустить Сервис : +```bash +# В каталоге Docker +docker compose up +``` +![MemOS buildComposeupSuccess](https://cdn.memtensor.com.cn/img/memos_build_composeup_success_compressed.png) +
Пример изображения, порт по настройкам docker
+ +#### Доступ к API через [http://localhost:8000/docs](http://localhost:8000/docs). + +![MemOS Architecture](https://cdn.memtensor.com.cn/img/memos_run_server_success_compressed.png) + + +#### Тестовые Случаи (Добавить Память Пользователя -> Запросить Память Пользователя) Ссылка на Тестовые Случаи Docker Compose up + +:: + + + +### Способ 2: Установить Клиент Docker Compose up +::steps{level="4"} +Docker Compose up для среды разработки уже предварительно настроен с qdrant, neo4j. +Для работы сервера требуется переменная среды `OPENAI_API_KEY`. + + +#### Перейдите в папку docker +```bash +# Перейдите в папку Docker в текущем каталоге +cd docker +``` + +#### Установите соответствующие модули зависимостей +```bash + +pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt +# Установка зависимостей с использованием источника Alibaba Cloud +pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ + +# команда не найдена: pip используйте pip3 + + + +``` + + +#### Запустите контейнер с помощью Docker Compose Up в каталоге docker (убедитесь, что vpn подключен): + +```bash + +# Первый Запуск Требует Сборки +docker compose up --build +# Повторный Запуск Не Требует +docker compose up + +``` + +#### Доступ к API через [http://localhost:8000/docs](http://localhost:8000/docs). + +#### Пример Процесса + +##### (Запросить Память Пользователя (если нет, продолжайте дальше) -> Добавить Память Пользователя -> Запросить Память Пользователя) + +##### Добавить Пользовательскую Память http://localhost:8000/product/add (POST) +```bash +# Параметры Запроса +{ + "user_id": "8736b16e-1d20-4163-980b-a5063c3facdc", + "mem_cube_id": "b32d0977-435d-4828-a86f-4f47f8b55bca", + "async_mode": "async", + "messages": [ + { + "role": "user", + "content": "Мне Нравятся Клубника" + } + ] +} +# Ответ +{ + "code": 200, + "message": "Memory created successfully", + "data": null +} +``` + +##### Запросить Пользовательскую Память http://localhost:8000/product/search (POST) +```bash +# Параметры Запроса +{ + "query": "Что Мне Нравится", + "user_id": "8736b16e-1d20-4163-980b-a5063c3facdc", + "mem_cube_id": "b32d0977-435d-4828-a86f-4f47f8b55bca" +} +# Ответ +{ + "code": 200, + "message": "Search completed successfully", + "data": { + "text_mem": [ + { + "cube_id": "7231eda8-6c57-4f6e-97ce-98b699eebb98", + "memories": [ + { + "id": "2f40be8f-736c-4a5f-aada-9489037769e0", + "memory": "[user观点]Пользователь Нравится Клубника。", + "metadata": { + "user_id": "de8215e3-3beb-4afc-9b64-ae594d62f1ea", + "session_id": "root_session", + "status": "activated", + "type": "fact", + "key": "Предпочтение Пользователя К Клубнике", + "confidence": 0.99, + "source": null, + "tags": [ + "предпочтение", + "клубника" + ], + "visibility": null, + "updated_at": "2025-09-18T08:23:44.625479000+00:00", + "memory_type": "UserMemory", + "sources": [], + "embedding": [], + "created_at": "2025-09-18T08:23:44.625511000+00:00", + "usage": [ + "{ + "time": "2025-09-18T08:24:17.759748", + "info": { + "user_id": "de8215e3-3beb-4afc-9b64-ae594d62f1ea", + "session_id": "root_session" + } + }" + ], + "background": "Пользователь Выразил Предпочтение К Клубнике, Показывая Их Склонности В Питании。", + "relativity": 0.6349761312470591, + "vector_sync": "success", + "ref_id": "[2f40be8f]", + "id": "2f40be8f-736c-4a5f-aada-9489037769e0", + "memory": "[user观点]Пользователь Нравится Клубника。" + }, + "ref_id": "[2f40be8f]" + }, + ... + } + } + ], + "act_mem": [], + "para_mem": [] + } +} + + + +# Ошибка Ответа, Причина Проверки +# src/memos/api/config.py +# Проверьте "neo4j_vec_db" и "EMBEDDING_DIMENSION", указанные в методе get_neo4j_community_config. +``` + + +#### Изменения в коде сервера или библиотеке автоматически перезагрузят сервер. + + +:: + +### Способ 3: Установить Клиент с Использованием CLI Команды + +::steps{level="4"} + +#### Установить Зависимости + +```bash +# pip install --upgrade pip && pip install --no-cache-dir -r ./docker/requirements.txt +# Установка зависимостей с использованием источника Alibaba Cloud +pip install --no-cache-dir -r ./docker/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ + + +``` + +#### Откройте терминал и выполните следующую команду для установки: + +```bash + +# В настоящее время может потребоваться ручная установка пакетов. Эти два пакета нужно найти. +# neo4j.5.26.4.tar qdrant.v1.15.3.tar +docker load -i neo4j.5.26.4.tar +docker load -i qdrant.v1.15.3.tar +# Проверьте, установлены ли они успешно. +docker images +# Проверьте, запустились ли они. +docker ps -a + +# Если при запуске возникает ошибка ModuleNotFoundError: No module named 'memos', это связано с проблемой соответствия пути, выполните. +export PYTHONPATH=/you-file-absolute-path/MemOS/src + +# Корневая директория. + uvicorn memos.api.server_api:app --host 0.0.0.0 --port 8000 --workers 1 + + + +``` + +#### Доступ к API + +После завершения запуска, получите доступ к API по адресу [http://localhost:8000/docs](http://localhost:8000/docs). + + +:: + +### Способ 4: Не Использовать Docker +::steps{level="4"} +#### Ссылка на настройку переменных среды выше, уже настроен файл .env + +#### Установите Poetry для управления зависимостями: + +```bash +curl -sSL https://install.python-poetry.org | python3 - +``` + +#### Настройка Переменных Среды Poetry: + +```bash + +# Чтобы начать использовать, вам нужно найти каталог bin Poetry в "PATH" (/Users/jinyunyuan/.local/bin) `переменная окружения. +# Современная система macOS по умолчанию использует оболочку zsh. Вы можете подтвердить это с помощью следующей команды. +1. Убедитесь, какую оболочку вы используете. + +echo $SHELL +# Если выводится /bin/zsh или /usr/bin/env zsh, значит, вы используете zsh. +# (Если ваша версия системы старая, возможно, вы все еще используете bash, вывод будет /bin/bash) +2. Откройте соответствующий файл конфигурации оболочки. +# Если вы используете zsh (в большинстве случаев): +# Используйте редактор nano (рекомендуется для новичков). +nano ~/.zshrc + +# Или Используйте Редактор Vim +# vim ~/.zshrc +# Если Вы Используете Bash: +nano ~/.bash_profile +# Или +nano ~/.bashrc + +3. Добавьте Переменную Среды PATH + +# В самом конце открытого файла, начните новую строку и вставьте команду, которую вам дала установка: +export PATH="/you-path/.local/bin:$PATH" + +4. Сохраните и Выйдите из Редактора + +# Если Вы Используете Nano: +# Нажмите Ctrl + O, чтобы записать (сохранить), нажмите Enter, чтобы подтвердить имя файла. +# Затем нажмите Ctrl + X, чтобы выйти из редактора. + +# Если Вы Используете Vim: +# Нажмите i, чтобы войти в режим вставки, вставьте код, затем нажмите ESC, чтобы выйти из режима вставки. +# Введите :wq, затем нажмите Enter, чтобы сохранить и выйти. + +5. Сделайте Конфигурацию Немедленно Действующей +# Только что измененный файл конфигурации не будет автоматически действовать в текущем открытом терминальном окне, вам нужно выполнить одну из следующих команд, чтобы перезагрузить его: + +# Для Zsh: +source ~/.zshrc + +# Для Bash: +source ~/.bash_profile + +6. Проверьте, Успешна Ли Установка +# Теперь вы можете выполнить тестовую команду, указанную в подсказке, чтобы проверить, все ли готово: +poetry --version +# После успешного выполнения будет отображен номер версии Poetry (version 2.2.0) + +``` + +#### Установите все зависимости проекта и инструменты разработки: + +```bash +make install +``` + +#### Сначала запустите neo4j и qdrant в docker + +#### Запустите сервер FastAPI (в каталоге MomOS): + +```bash +uvicorn memos.api.product_api:app --host 0.0.0.0 --port 8000 --reload +``` + +#### После запуска сервера вы можете протестировать API с помощью документации OpenAPI по адресу [http://localhost:8000/docs](http://localhost:8000/docs) или [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) + +#### Тестовые Случаи (Регистрация Пользователя -> Добавить Память Пользователя -> Запросить Память Пользователя) Ссылка на Тестовые Случаи Docker Compose up + +:: + + +### Способ 5: Запуск через PyCharm + +#### Запустите server_api +```bash +1. Перейдите в файл MemOS/docker/Dockerfile и измените конфигурацию запуска +# Start the docker +CMD ["uvicorn", "memos.api.server_api:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] + +2. Перейдите в каталог MemOS/src/memos/api и запустите server_api.py напрямую + +``` diff --git a/content/ru/open_source/getting_started/your_first_memory.md b/content/ru/open_source/getting_started/your_first_memory.md new file mode 100644 index 00000000..3620cb5b --- /dev/null +++ b/content/ru/open_source/getting_started/your_first_memory.md @@ -0,0 +1,322 @@ +--- +title: Создайте Вашу Первую Память +desc: "Практическое занятие! Мы покажем вам, как использовать **SimpleStructMemReader** для извлечения памяти из диалога и сохранения ее в **TreeTextMemory** для управления и поиска." +--- + +## Цели Обучения + +Этот учебник проведет вас через основной рабочий процесс MemOS, освоив следующие навыки: + +1. **Чтение (Read)**: Как использовать `SimpleStructMemReader`, чтобы превратить беспорядочные записи чата в структурированную память. +2. **Сохранение (Add)**: Как сохранить извлеченную память в `TreeTextMemory` (графовая база данных). +3. **Поиск (Search)**: Как использовать естественный язык для поиска сохраненной памяти. + +--- + +## Введение в Основные Компоненты + +Перед тем как начать практическое занятие, давайте познакомимся с двумя ключевыми компонентами, которые мы будем использовать: + +### SimpleStructMemReader (Извлекатель Структурированной Памяти) + +Это интеллектуальный модуль извлечения информации на основе LLM, который может: + - Автоматически анализировать диалоги, документы и другие неструктурированные данные + - Выявлять предпочтения пользователей, фактические утверждения, модели поведения и другую ключевую информацию + - Выводить стандартизированные структурированные единицы памяти + +### TreeTextMemory (Деревовидная Текстовая База Памяти) + +Это система управления памятью на основе графовой базы данных, которая может: + - Организовывать память в древовидной структуре, поддерживая иерархические отношения + - Устанавливать семантические связи между памятью + - Поддерживать эффективный семантический поиск и обход графа + - Совместима с графовыми базами данных, такими как Neo4j + +## Попробуйте Сами + +Мы продемонстрируем на конкретном примере: как извлечь ключевую информацию из диалога пользователя о "плохом состоянии в теннисе" и создать систему памяти, которую можно искать. + +### 1. Импорт Модуля + +```python +from memos import log +from memos.configs.mem_reader import SimpleStructMemReaderConfig +from memos.configs.memory import TreeTextMemoryConfig +from memos.mem_reader.simple_struct import SimpleStructMemReader +from memos.memories.textual.tree import TreeTextMemory + +logger = log.get_logger(__name__) +``` + +### 2. Инициализация Основных Компонентов + +```python + +# 1. Инициализация TreeTextMemory (Склад Памяти) +tree_config = TreeTextMemoryConfig.from_json_file( + "examples/data/config/tree_config_shared_database.json" +) +my_tree_textual_memory = TreeTextMemory(tree_config) + +# ⚠️ Внимание: Здесь для удобства демонстрации очищены старые данные. В производственной среде ни в коем случае не делайте этого! +my_tree_textual_memory.delete_all() + +# 2. Инициализация SimpleStructMemReader (Извлекатель Информации) +reader_config = SimpleStructMemReaderConfig.from_json_file( + "examples/data/config/simple_struct_reader_config.json" +) +reader = SimpleStructMemReader(reader_config) +``` + +### 3. Подготовка Диалога + +Вот диалог между пользователем и ИИ, в котором пользователь выражает проблему состояния во время игры в теннис: + +```python +scene_data = [ + [ + { + "role": "user", + "chat_time": "3 May 2025", + "content": "This week I’ve been feeling a bit off, especially when playing tennis. My body just doesn’t feel right.", + }, + { + "role": "assistant", + "chat_time": "3 May 2025", + "content": "It sounds like you've been having some physical discomfort lately...", + }, + # ... (пропущено несколько раундов обсуждений) ... + { + "role": "user", + "chat_time": "3 May 2025", + "content": "I think it might be due to stress and lack of sleep recently...", + }, + ] +] +``` + +### 4. Извлечение и Сохранение + +**SimpleStructMemReader** автоматически проанализирует диалог, извлечет ключевые точки памяти, такие как "пользователь испытывает стресс", "недостаток сна", "падение результатов в теннисе", и затем сохранит их в базе данных. + +```python +# 1. Извлечение (Extract) +# Reader будет вызывать LLM для анализа диалога и возвращать список памяти +memory = reader.get_memory( + scene_data, + type="chat", + info={"user_id": "1234", "session_id": "2222"} +) + +# 2. Хранение (Add) +for m_list in memory: + added_ids = my_tree_textual_memory.add(m_list) + + # Посмотрим, что было сохранено + for i, id in enumerate(added_ids): + print(f"Сохранена {i}-я запись памяти: " + my_tree_textual_memory.get(id).memory) + + # Ждем завершения обработки на фоне (создание индекса требует немного времени) + my_tree_textual_memory.memory_manager.wait_reorganizer() +``` + +### 5. Поиск Памяти + +**Базовый Поиск (Search):** + +Просто задайте вопрос, как в поисковой системе. + +```python +# Немного подождите, пока строится индекс +import time +time.sleep(2) + +init_time = time.time() + +# Попробуйте поискать что-то о "детстве" (предполагая, что в предыдущем диалоге содержится соответствующий контент) +# Или попробуйте поискать "Why is the user feeling bad?" +results = my_tree_textual_memory.search( + "Talk about the user's childhood story?", + top_k=10, + info={ + "query": "Talk about the user's childhood story?", + "user_id": "111", + "session_id": "2234", + }, +) + +for i, r in enumerate(results): + print(f"Найдено {i}-е совпадение: {r.memory}") + +print(f"Время поиска: {round(time.time() - init_time)}s") +``` + +**Расширенный Поиск (Fine Mode):** + +Если вы хотите более умные результаты поиска (например, чтобы LLM помог вам подвести итоги найденного), вы можете включить `mode="fine"`. + +```python +# Включить Fine Режим +results_fine_search = my_tree_textual_memory.search( + "Recent news in the first city you've mentioned.", + top_k=10, + mode="fine", # Ключевое здесь + info={ + "query": "Recent news in NewYork", + "user_id": "111", + "session_id": "2234", + "chat_history": [ + {"role": "user", "content": "I want to know three beautiful cities"}, + {"role": "assistant", "content": "New York, London, and Shanghai"}, + ], + }, +) + +for i, r in enumerate(results_fine_search): + print(f"Результат Fine Поиска: {r.memory}") +``` + +### 6. Продвинутый: Мультимодальность и Инструменты (Modality & Tools) + +Возможности MemOS не ограничиваются обработкой текстовых диалогов, она также поддерживает мультимодальный ввод и расширенные функции. + +#### 1. Чтение Документов (Documents) + +Можно напрямую читать локальные документы и преобразовывать их в память: + +```python +# Построить Документные Данные +doc_data = [ + { + "type": "file", + "file": { + "filename": "tennis_rule.txt", + "path": "./tennis_rule.txt", # Убедитесь, что файл существует + # Или предоставьте контент напрямую: "file_data": "..." + } + } +] + +# Сообщить Reader, что это тип "doc" +doc_memories = reader.get_memory( + doc_data, + type="doc", + info={"user_id": "1234", "session_id": "docs_import"} +) + +# Сохранить В Памяти +for m in doc_memories: + my_tree_textual_memory.add(m) +``` + +#### 2. Вызов Инструментов (Tools) + +Когда Агент использует инструменты (например, поиск, калькулятор), MemOS может анализировать ввод и вывод инструментов, фиксируя факты, такие как "пользователь запросил погоду", "результат вычисления 50". + +```python +tool_scene = [ + [ + {"role": "user", "content": "What's the weather in Beijing?"}, + { + "role": "assistant", + "content": "", + "tool_calls": [{"id": "call_1", "function": {"name": "get_weather", "arguments": "{'city': 'Beijing'}"}}] + }, + { + "role": "tool", + "tool_call_id": "call_1", + "content": "Sunny, 25°C" + } + ] +] + +# Reader Автоматически Поймет, Что Это Взаимодействие С Инструментом +tool_memories = reader.get_memory(tool_scene, type="chat", info={"user_id": "1234"}) +``` + +### 7. Предпочтения Пользователя (Preferences) + +Помимо фактической памяти (TreeTextMemory), MemOS имеет специальную **PreferenceTextMemory** для управления предпочтениями пользователей (например, "нравится острое", "не нравится дождь"). Она использует векторные базы данных (например, Milvus/Qdrant) для хранения, что позволяет быстро находить персонализированные настройки пользователя. + +```python +from memos.memories.textual.simple_preference import SimplePreferenceTextMemory +# Внимание: Инициализация Требует Настройки VectorDB, Embedder И Т.Д., Здесь Только Для Примера +# pref_memory = SimplePreferenceTextMemory(...) + +# Автоматически Извлечь Предпочтения Из Диалога +pref_memories = pref_memory.get_memory(chat_data, type="chat", info=...) + +# Сохранить Предпочтения +pref_memory.add(pref_memories) + +# Поиск Предпочтений +prefs = pref_memory.search("What is the user's UI preference?", top_k=1) +print(prefs[0].memory) # Вывод: "Пользователь предпочитает темный режим" +``` + +### 8. Обратная Связь по Памяти (Feedback) + +Память не является статичной. Пользователь может исправить ИИ: "Мне не нравится красный, я передумал, мне нравится синий". Модуль **MemFeedback** предназначен для обработки таких "коррекций". + +Он может: +1. **Изменять** ошибочную память. +2. **Удалять** устаревшую память. +3. **Объединять** конфликтующие воспоминания. + +```python +from memos.mem_feedback.simple_feedback import SimpleMemFeedback + +# Инициализировать Модуль Обратной Связи +# feedback_module = SimpleMemFeedback(...) + +# Обработка Отзывов Пользователей +# Предположим, пользователь говорит: "Actually, I started playing tennis in 2020, not 2018." +feedback_module.process_feedback({ + "user_id": "1234", + "feedback_content": "Actually, I started playing tennis in 2020, not 2018.", + "chat_history": [...], # Предоставить Контекст + "feedback_time": "Now" +}) + +# Модуль Отзывов будет автоматически обновлять узлы и отношения в базе данных Graph в фоновом режиме +``` + +### Резюме + +С помощью этого учебника вы освоили основной рабочий процесс MemOS: +1. **Извлечение Информации**: Используйте Reader для извлечения структурированной информации из различных источников данных +2. **Хранение Памяти**: Используйте TreeTextMemory для управления фактической памятью, PreferenceMemory для управления предпочтениями пользователей +3. **Умный Поиск**: Получайте соответствующую память через запросы на естественном языке +4. **Постоянная Оптимизация**: Поддерживайте точность и актуальность памяти через механизмы обратной связи + +На следующем этапе вы можете попробовать запустить `examples/mem_os/simple_memos.py`, чтобы испытать полноценного Агента, который объединяет все эти функции! + +### 7. Завершение + +После завершения тестирования рекомендуется выполнить следующие операции по очистке: + +```python +# Остановить Фоновый Поток +my_tree_textual_memory.memory_manager.close() + +# Сделать Резервную Копию Памяти +my_tree_textual_memory.dump("tmp/my_tree_textual_memory") + +# Удалить Базу Данных и Убежать (только для тестовой среды!) +my_tree_textual_memory.drop() +``` + +--- + +## Что Дальше? + +- **Попробуйте свой собственный LLM бэкенд:** Переключитесь на OpenAI, HuggingFace или Ollama. +- **Изучите [TreeTextMemory](/open_source/modules/memories/tree_textual_memory):** Построение иерархической памяти на основе графов. +- **Добавьте [Activation Memory](/open_source/modules/memories/kv_cache_memory):** Кэширование состояния ключей и значений для ускорения вывода. +- **Углубленное Обучение:** Ознакомьтесь с [API Reference](/api-reference/search-memories) и [Examples](/open_source/getting_started/examples) для понимания сложных рабочих процессов. + + +Далее вы можете ознакомиться с более продвинутыми функциями: +- **[MemReader](/open_source/modules/mem_reader)**: на самом деле он также может читать изображения и PDF. +- **[MemFeedback](/open_source/modules/mem_feedback)**: если память ошиблась, как заставить ИИ автоматически исправить это? +- **[MemCube](/open_source/modules/mem_cube)**: как объединить различные способности памяти, чтобы создать настоящий универсальный мозг. diff --git a/content/ru/open_source/home/architecture.md b/content/ru/open_source/home/architecture.md new file mode 100644 index 00000000..d30d40a8 --- /dev/null +++ b/content/ru/open_source/home/architecture.md @@ -0,0 +1,139 @@ +--- +title: Архитектурный Дизайн +desc: MemOS использует модульный дизайн, где все основные компоненты работают совместно, превращая традиционный LLM в систему улучшенной памяти с полной способностью управления жизненным циклом памяти. +--- +## Основные Модули + +### MOS (Memory Operating System, Операционная Система Памяти) + +MemOS является уровнем оркестрации — управляет предсказательной, асинхронной планировкой через различные типы памяти (чистый текст, активация, параметризация) и организует **многопользовательские, многосессионные** рабочие процессы памяти. + +**Основные Функции** + - **Единый API Шлюз**: предоставляет единый интерфейс для всех операций с памятью (добавление, поиск, обновление, передача, откат) + - **Оркестрация Рабочих Процессов**: координирует выполнение компонентов, таких как MemCube, MemReader, MemScheduler + - **Поддержка Взаимодействия**: реализует перенос памяти между моделями и устройствами через протокол обмена памятью (MIP) + - **Планирование Ресурсов**: интеллектуально распределяет вычислительные ресурсы, балансируя требования к оперативному отклику и фоновым обработкам + + +### MemCube (Контейнер Памяти) + +MemCube является **модульным хранилищем памяти** MemOS, которое можно рассматривать как независимую и переносимую "карточку памяти". Каждый MemCube может обслуживать конкретного пользователя, агента или сессию, вмещая один или несколько типов памяти. + +**Много Cube Поддержка (Multi-Cube):** + +MemOS поддерживает одновременную работу с несколькими MemCube через **композитный вид (Composite View)**, обеспечивая гибкую изоляцию и совместное использование памяти: + +| Тип Операции | Стратегия | Сценарий Применения | +|---------|------|---------| +| **Запись** | Распределенная Запись (Fan-out Write) | Запись памяти одновременно в личный Cube пользователя и общий Cube проекта | +| **Чтение** | Параллельный Поиск (Parallel Search) | Одновременный запрос нескольких Cube, агрегация результатов для предоставления глобального вида | + +**Динамические Управляющие Возможности:** + + - **Поддержка Горячей Замены**: возможность динамической регистрации, обновления или удаления MemCube во время выполнения + - **Контейнеризированное Хранилище**: поддерживает безопасную передачу памяти между сессиями, моделями и устройствами + - **Гарантия Изоляции**: обеспечивает изоляцию данных памяти между различными пользователями или приложениями + +### Асинхронный Механизм Добавления (Asynchronous Addition) + +Чтобы поддерживать низкую задержку в условиях высокой конкуренции, MemOS предоставляет асинхронный режим добавления памяти (`async_mode`), используя **MemScheduler** для фонового планирования: + +| Тип Памяти | Стратегия Обработки | Преимущества | +|---------|---------|------| +| **Текстовая Память** | Быстрое Извлечение + Асинхронная Обработка | API немедленно возвращает базовые результаты, сложная обработка выполняется в фоновом режиме | +| **Предпочтительная Память** | Полностью Асинхронная Обработка | Максимальное снижение задержки ответа API | + +**Роль MemScheduler:** +В качестве асинхронного планировщика задач отвечает за: + - управление очередью приоритетов фоновых задач + - координацию вычислительно интенсивных операций, таких как переиндексация и графовое вывод + - мониторинг состояния задач, обеспечивая согласованность обработки + +### Система Типов Памяти + +MemOS поддерживает несколько специализированных типов памяти для удовлетворения различных потребностей: + +#### 1. Параметризованная Память (**Скоро Будет Доступна**) + + - **Характеристики**: знания закреплены в весах модели, нулевая задержка вывода + - **Сценарии Применения**: стабильные предметные знания, ключевые навыки + - **Жизненный Цикл**: долгосрочный, высокая стоимость обновления + +#### 2. Активационная Память + + - **Характеристики**: KV кэш и скрытое состояние во время выполнения, быстрая повторная использование + - **Сценарии Применения**: контекст многократных диалогов, часто запрашиваемая фоновая информация + - **Жизненный Цикл**: краткосрочный, поддержка на уровне сессии + +#### 3. Открытая Память + +Структурированные или неструктурированные блоки знаний; редактируемые, отслеживаемые, подходят для быстрого обновления, персонализации и совместного использования между несколькими агентами. + +| Подкласс Памяти | Структура Хранения | Основные Преимущества | Типичное Применение | +|---------|---------|---------|---------| +| **GeneralTextMemory** | Хранение Векторов | Гибкий семантический поиск, поддержка фильтрации метаданных | Неструктурированные документы, записи чата | +| **TreeTextMemory** | Хранение Графовой Структуры | Иерархическая организация, поддержка многопроходного вывода | Структурированные базы знаний, профили пользователей | + + +::note{title="Рекомендации по Выбору Архитектуры"} +**Рекомендации по Началу**
: начните с `GeneralTextMemory` для быстрой проверки концепции +**Путь Эволюции**
: по мере увеличения сложности бизнеса постепенно вводите `TreeTextMemory` для обработки структурированных знаний +:: + +#### Базовые Поддерживающие Компоненты + +Базовые модули MemOS обеспечивают стандартизированные возможности, гарантируя масштабируемость и согласованность системы: + +| Категория Компонентов | Основная Функция | Примеры Реализации | +|---------|---------|---------| +| **Обработка Текста** | Умное Разбиение, Извлечение Памяти | Chunkers, MemReaders | +| **Векторизация** | Генерация Встраиваний Текста | Embedders (bge-m3, text-embedding-3-large) | +| **Интерфейс Хранения** | Поддержка Многих Баз Данных | GraphDBs (Neo4j, Qdrant, PolarDB) | +| **Соединение Моделей** | Унифицированный Интерфейс LLM | LLMs (OpenAI, Ollama) | +| **Оптимизация Качества** | Перепорядок Результатов Поиска | Rerankers (bge-reranker-v2-m3) | + +## Архитектура Организации Кода + +Проект MemOS организован четко, поддерживает принцип "включай и работай": + +``` +src/memos/ + api/ # Определение API + chunkers/ # Инструменты Разбиения Текста + configs/ # Конфигурационные Шаблоны + context/ # Контекст Логов + embedders/ # Модели Встраивания + graph_dbs/ # Бэкенды Графовых Баз Данных (например, Neo4j) + vec_dbs/ # Бэкенды Векторных Баз Данных (например, Qdrant) + llms/ # Соединители LLM + mem_agent/ # Глубокий Поиск + mem_chat/ # Логика Чата с Укрепленной Памятью + mem_cube/ # Управление MemCube + mem_feedback # Обратная Связь по Памяти + mem_os/ # Оркестрация MOS + mem_reader/ # Читатель Памяти + mem_scheduler/ # Модуль Планировщика Памяти + memories/ # Реализация Типов Памяти + multi_mem_cube/# Многоуровневый Cube + parsers/ # Инструменты Парсинга + reranker/ # Модуль Перепорядочивания + templates/ # Шаблоны Подсказок + types/ # Определения Типов +``` + +::note{title="Руководство по Разработке"} +**Профессиональные Советы**
+ - **Быстрая Экспертиза**: используйте примеры из каталога `examples/` для быстрой проверки функциональности + - **Глубокая Настройка**: обращайтесь к реализации модулей в `src/` для вторичной разработки + - **Управление Конфигурацией**: все компоненты поддерживают гибкую настройку через `configs/` +:: + +## Масштабируемость + +MemOS имеет **модульный дизайн**. +Добавляйте свои собственные типы памяти, хранилища или соединители LLM с минимальными изменениями — благодаря **единой конфигурации и фабричному шаблону**. + +::note +**Профессиональные Советы**
+[Вклад](/open_source/contribution/overview) нового бэкенда или делитесь своим пользовательским типом памяти — это легко интегрировать. +:: diff --git a/content/ru/open_source/home/core_concepts.md b/content/ru/open_source/home/core_concepts.md new file mode 100644 index 00000000..b1edfa1c --- /dev/null +++ b/content/ru/open_source/home/core_concepts.md @@ -0,0 +1,105 @@ +--- +title: Основные Понятия +desc: MemOS рассматривает память как первоочередный ресурс. Его основная концепция сосредоточена на том, как организовать, хранить, извлекать и управлять памятью для ваших LLM приложений. +--- + +## Обзор + +* [MOS (Операционная Система Памяти)](#mos-операционная-система-памяти) +* [MemCube](#memcube) +* [Типы Памяти](#типы-памяти) +* [Сквозные Понятия](#сквозные-понятия) + + +## MOS (Операционная Система Памяти) + +**Определение** +MOS является слоем оркестрации и планирования MemOS, отвечающим за координацию нескольких MemCube и различных операций с памятью. Он служит промежуточным ПО, соединяющим LLM с структурированной и интерпретируемой системой памяти для поддержки сложных задач вывода и планирования. + +**Сценарии Использования** +Когда вам необходимо установить согласованный, проверяемый и отслеживаемый рабочий процесс памяти между пользователями, сессиями или агентами, используйте MOS для унифицированного планирования. + +## MemCube + +**Определение** +MemCube — это вставляемый и расширяемый контейнер памяти в MemOS. Каждый пользователь, сессия или задача может быть назначена отдельному MemCube, который может содержать один или несколько типов памяти. + +**Сценарии Использования** +С увеличением масштаба системы можно достичь изоляции, повторного использования и горизонтального масштабирования памяти путем настройки различных MemCube. + +## Типы Памяти + +MemOS рассматривает память как динамически развивающуюся систему знаний, а не как статическое хранилище данных. Основные типы памяти следующие: + +| Тип Памяти | Описание | Когда Использовать | +|----------------|----------------------------------------------|---------------------------------------------| +| **Параметрическая Память** | Знания, интегрированные в веса модели | Вечнозеленые навыки, стабильные профессиональные знания | +| **Активная Память** | Повторно используемый KV Cache и скрытое состояние | Быстрое повторное использование в диалогах, многократные сессии | +| **Открытая Память** | Текст, документы, узлы графа, инструменты или предпочтения и т.д. | Можно искать, проверять, эволюционные знания | + +### Параметрическая Память + +**Определение** +Параметрическая память относится к знаниям, закрепленным в весах модели, и может рассматриваться как "долговременная память" модели. Она всегда доступна онлайн, обеспечивая поддержку знаний с нулевой задержкой для задач вывода. + +**Сценарии Использования** +Подходит для стабильных областей знаний, отобранных универсальных решений для проблем и навыков, которые не подвержены изменениям. + +### Активная Память + +**Определение** +Активная память — это "рабочая память" модели, которую можно повторно использовать, включая заранее рассчитанный кэш ключей и значений (KV Cache) и скрытые состояния, которые можно напрямую внедрить в механизм внимания, избегая повторного кодирования повторяющегося контента. + +**Почему Это Важно:** +Хранение стабильной контекстной информации (например, описаний продуктов, руководств) в виде KV Cache может значительно снизить задержку первого токена (TTFT) и повысить эффективность многократных диалогов и генерации с улучшением поиска (RAG). + +**Когда Использовать:** +- Повторное использование фоновых знаний в последовательных запросах +- Ускорение диалоговых систем на основе фиксированного контекста +- В сочетании с MemScheduler автоматическое преобразование высокочастотной открытой памяти в KV кэш + +### Открытая Память + +**Определение** +Структурированные или неструктурированные единицы знаний, обладающие видимостью и интерпретируемостью для пользователей. Кроме традиционных документов, журналов чата, графовых узлов и векторных вложений, MemOS также рассматривает следующее как открытую память: +- **Память Инструментов (Tool Memory)**: включает определения инструментов (Schema) и траектории использования (Trajectory), используемые для повышения способности агентов (Agent) к вызову инструментов. +- **Память Предпочтений (Preference Memory)**: явные или неявные предпочтения пользователей, используемые для персонализированных рекомендаций и ответов. + +**Сценарии Использования** +Подходит для семантического поиска, создания персонализированного опыта, усиления инструментов для сложных задач и отслеживаемых фактов, развивающихся со временем. Поддерживает метки, отслеживание источников и полное управление жизненным циклом. + + +## Как Они Работают В Месте + +MemOS позволяет вам планировать все три типа памяти в цикле жизненного цикла: + +- Процесс дистилляции: часто используемая открытая память может быть дистиллирована в параметрическую память, повышая эффективность вывода. +- Оптимизация кэша: распространенные пути вывода могут быть закреплены в повторно используемых шаблонах KV, уменьшая повторные вычисления. +- Архивирование понижения: параметрическая или активная память, использующаяся реже, может быть понижена до открытого хранения, что упрощает аудит и повторное обучение. + +С помощью MemOS ваша AI система может не только хранить информацию, но и обеспечивать непрерывную **память**, **глубокое понимание** и **автономную эволюцию**. + +::note +**Инсайты Системы**
+ - Со временем часто используемая открытая память может быть дистиллирована в параметрическую память. + - Низкочастотные параметры или кэш могут быть архивированы в открытом виде, создавая проверяемый и повторно обучаемый замкнутый цикл знаний. +:: + +## Сквозные Понятия + +### Гибридный Поиск + +Сочетание поиска по векторной схожести и алгоритмов обхода графов для достижения надежного и контекстно осведомленного гибридного поиска. + +### Управление и Жизненный Цикл + +Каждый элемент памяти имеет полный жизненный цикл состояния (активация, слияние, архивирование) и поддерживает отслеживание источников и детализированный контроль доступа, что крайне важно для соблюдения требований аудита и соответствия данным. + +::note +**Совет по соблюдению**
+Пожалуйста, убедитесь, что вы полностью документируете источники и изменения состояния каждого элемента памяти, чтобы соответствовать нормам управления данными и аудита. +:: + +## Ключевые моменты + +MemOS предоставляет вашей LLM-приложению структурированную, эволюционную и управляемую систему памяти, позволяя агентам осуществлять долгосрочное планирование, сложное рассуждение и постоянную адаптацию, раскрывая истинный потенциал приложений следующего поколения AI. diff --git a/content/ru/open_source/home/memos_intro.md b/content/ru/open_source/home/memos_intro.md new file mode 100644 index 00000000..58a0884c --- /dev/null +++ b/content/ru/open_source/home/memos_intro.md @@ -0,0 +1,113 @@ +--- +title: Что Такое MemOS? +desc: "**MemOS** — это **операционная система памяти**, созданная для больших языковых моделей (LLMs) и агентов. Она рассматривает память как **управляемый, планируемый и интерпретируемый первичный ресурс**, а не как непрозрачный слой, скрытый внутри весов модели." +--- + +![MemOS Architecture](https://statics.memtensor.com.cn/memos/memos-architecture.png) + + +С развитием LLMs они должны справляться со сложными задачами — такими как многократные диалоги, долгосрочное планирование, принятие решений и персонализированный пользовательский опыт — **предоставление им возможности структурировать, управлять и развивать память** становится критически важным для достижения истинного долгосрочного интеллекта и адаптивности. + +Тем не менее, большинство основных LLMs по-прежнему сильно зависят от статической параметризованной памяти (весов модели). Это затрудняет обновление знаний, отслеживание использования памяти или накопление эволюционных пользовательских предпочтений. Каков результат? Высокая стоимость обновления знаний, хрупкое поведение и ограниченная персонализация. + +**MemOS** решает эти проблемы, переопределяя память как **основной модульный системный ресурс** с унифицированной структурой, управлением жизненным циклом и логикой планирования. Он предоставляет уровень на основе Python, который находится между вашим LLM и внешними источниками знаний, реализуя **постоянные, структурированные и эффективные операции с памятью**. + +С помощью MemOS ваш LLM может сохранять знания с течением времени, более надежно управлять контекстом и использовать интерпретируемую и проверяемую память для вывода — открывая более умное, надежное и адаптивное поведение ИИ. + + +::note +**Подсказка**
MemOS помогает преодолеть разрыв между статическими параметризованными весами и динамической, специфической для пользователя памятью. + Рассматривайте это как "мозг" вашего агента с модульными компонентами для открытого текста и активной памяти, которые можно подключать и использовать. +:: + +## Почему Нам Нужен MemOS? + +LLMs мощные, но сильно зависят от параметризованной памяти (весов), которые трудно проверять, обновлять или делиться ими. +Типичный векторный поиск (RAG) помогает извлекать внешние факты, но не имеет единого управления, контроля жизненного цикла или совместного использования между агентами. + +**MemOS** меняет это. +Рассматривайте это как операционную систему для памяти: +как операционная система управляет CPU, RAM и файлами, MemOS **управляет, преобразует и регулирует** различные типы памяти — от параметризованных весов до временных кэшей и открытых, отслеживаемых знаний. + +::note +**Глубокое Понимание**
MemOS помогает вашему LLM эволюционировать, интегрируя параметризованную, активированную и открытое текстовое воспоминание в жизненный цикл. +:: + + +## Основные Строительные Модули +### MemCubes + +**Гибкие контейнеры**, вмещающие один или несколько типов памяти. +Каждый пользователь, сессия или агент могут иметь свой собственный MemCube — взаимозаменяемый, многоразовый и отслеживаемый. + +### Жизненный Цикл Памяти + +Каждый элемент памяти может проходить через следующие состояния: + +- **Генерация** → **Активация** → **Объединение** → **Архивирование** → **Заморозка** + +Каждый шаг контролируется версионностью через **отслеживание источников** и журналы аудита. Старая память может быть восстановлена или смоделирована с помощью "машины времени". + + +### Операции и Управление + +Модули включают: + +- **MemScheduler** — динамическое преобразование типов памяти для оптимального повторного использования. +- **MemLifecycle** — управление переходами состояния, объединением и архивированием. +- **MemGovernance** — обработка контроля доступа, редактирования, соблюдения и отслеживания аудита. + + +::note +**Напоминание о Соблюдении**
Каждый элемент памяти несет полные метаданные источника, поэтому вы можете проверить, кто создал, изменил или запрашивал его. +:: + + +## Многогранная Память + +MemOS интегрирует **три формы памяти** в жизненный цикл: + +| Тип | Описание | Примеры | +|----------------| ---------------------------------------------------- | ---------------------------------------------- | +| **Параметрическая Память** | Извлечение знаний в веса модели | Вечнозеленые навыки, стабильные факты области | +| **Активная Память** | KV caches и скрытые состояния для повторного использования в выводе | Быстрые многократные беседы, низкая задержка генерации | +| **Явная Память** | Тексты, документы, графики, векторные блоки, факты, видимые пользователю | Семантический поиск, эволюция, интерпретируемая память | + +С течением времени: + +- Часто используемая открытая память может быть преобразована в параметризованные веса. +- Стабильный контекст поднимается в KV Cache для быстрого внедрения. +- Малоиспользуемые или устаревшие знания могут быть понижены. + + +## Чем MemOS Отличается? + +- Гибридный поиск — смешанный символический и семантический поиск, смешанный векторный и графовый поиск. +- Многопользовательская и многопользовательская графика — частная и общая. +- Отслеживание источников и аудита — каждый элемент памяти управляется и интерпретируем. + + +- Автоматическое повышение KV Cache для повторного использования стабильного контекста. +- Планирование жизненного цикла памяти — уменьшение вызовов устаревших фактов или громоздких весов. + +- Необходимы **многоразовые, эволюционные воспоминания** для диалогового агента +- Обработка **соответствия, обновлений области и персонализации** для корпоративного Copilot +- Многопользовательская система, работающая на **общем графе знаний** +- Строители ИИ, желающие модульные, проверяемые воспоминания, а не черные ящики подсказок + +## Ключевые моменты + +**MemOS** превращает ваш LLM из "просто предсказания токенов" +в интеллектуальную эволюционную систему, которая может **запоминать**, **делать выводы** и **адаптироваться** — +как операционная система вашего агентского мышления. + +**С MemOS ваш ИИ не просто хранит факты — он растет.** + +## Основные характеристики + +- **Модульная архитектура памяти**: поддержка открытого текста, активации (KV cache) и параметрической (adapters/LoRA) памяти. +- **MemCube**: единый контейнер для всех типов памяти с простым загрузкой/сохранением и доступом к API. +- **MOS**: система улучшения памяти для LLMs с модульной памятью, которую можно подключать. +- **Графовая база данных**: нативная поддержка Neo4j и других графовых баз данных для структурированной, интерпретируемой памяти. +- **Легкость интеграции**: может использоваться с HuggingFace, Ollama и пользовательскими LLMs. +- **Масштабируемость**: добавляйте свои собственные модули памяти или базы данных. diff --git a/content/ru/open_source/home/overview.md b/content/ru/open_source/home/overview.md new file mode 100644 index 00000000..15586ae2 --- /dev/null +++ b/content/ru/open_source/home/overview.md @@ -0,0 +1,47 @@ +--- +title: MemOS Документация + desc: Добро пожаловать в официальную документацию MemOS – пакет Python, специально разработанный для предоставления расширенных модульных функций памяти для крупных языковых моделей (LLMs). + banner: https://statics.memtensor.com.cn/memos/memos-banner.gif + links: + - label: 'PyPI' + to: https://pypi.org/project/MemoryOS/ + target: _blank + avatar: + src: https://statics.memtensor.com.cn/icon/pypi.svg + alt: PyPI logo + - label: 'Open Source' + to: https://github.com/MemTensor/MemOS + target: _blank + icon: i-simple-icons-github +--- + +## Что такое MemOS? + +С развитием крупных языковых моделей (LLMs) их задачи становятся все более сложными, включая многократные диалоги, планирование, принятие решений и персонализированные агенты. В этом контексте эффективное управление и использование памяти становится ключевым фактором для достижения долгосрочного интеллекта и адаптивных способностей. + Однако, основные архитектуры LLM часто имеют недостатки в структурировании, управлении и интеграции памяти, что приводит к высоким затратам на обновление знаний, несоответствующим состояниям поведения и трудностям в накоплении пользовательских предпочтений. + +**MemOS** решает эти проблемы, переопределяя память как основной ресурс первого уровня с единой структурой, управлением жизненным циклом и стратегиями планирования. Он предоставляет пакет Python, который предлагает единый уровень памяти для приложений на основе LLM, обеспечивая постоянные, структурированные и эффективные операции с памятью. Это позволяет LLM сохранять долгосрочные знания, управлять контекстом и улучшать способности к рассуждению, поддерживая более умное и адаптивное поведение. + +![MemOS Architecture](https://statics.memtensor.com.cn/memos/memos-architecture.png) + +## Основные характеристики + +- **Модульная архитектура памяти**: поддержка открытого текста, активации (KV cache) и параметров (адаптеры/LoRA). +- **MemCube**: единый контейнер для всех типов памяти, легкий в загрузке/сохранении и доступе через API. +- **MOS**: система улучшенной памяти для LLM, с модульной памятью, готовой к подключению. +- **Графовая база данных**: нативная поддержка Neo4j и других графовых баз данных для структурированной и интерпретируемой памяти. +- **Легкость интеграции**: совместимость с HuggingFace, Ollama и пользовательскими LLM. +- **Масштабируемость**: добавление собственных модулей памяти или баз данных. + + +## Установка + +Пожалуйста, обратитесь к нашему [руководству по установке](/open_source/getting_started/installation) для получения полных инструкций по установке, включая базовую установку, необязательные зависимости и внешние зависимости. + +## Вклад + +Мы приветствуем вклад! Пожалуйста, ознакомьтесь с [руководством по вкладу](/open_source/contribution/overview) для получения подробной информации о настройке окружения и отправке pull request. + +## Лицензия + +MemOS выпущен под лицензией Apache 2.0. diff --git a/content/ru/open_source/modules/mem_chat.md b/content/ru/open_source/modules/mem_chat.md new file mode 100644 index 00000000..2e1ecc40 --- /dev/null +++ b/content/ru/open_source/modules/mem_chat.md @@ -0,0 +1,180 @@ +--- +title: MemChat +desc: "MemChat является вашим "дипломатом памяти", который координирует ввод пользователя, извлечение памяти и генерацию LLM, создавая связный и обладающий долгосрочной памятью диалоговый опыт." + +## 1. Введение + +**MemChat** является центром управления диалогом MemOS. + +Это не просто интерфейс чата, а мост между "мгновенным диалогом" и "долговременной памятью". В процессе общения с пользователем MemChat отвечает за实时ное извлечение соответствующей фоновой информации из MemCube (куб памяти), построение контекста и осаждение нового диалогового содержания в новую память. С его помощью ваш агент больше не будет "рыбой с памятью", а станет действительно понимающим прошлое и постоянно развивающимся интеллектуальным партнером. + +--- + +## 2. Основные возможности + +### Увеличенный Диалог Памятью (Memory-Augmented Chat) +Перед тем как ответить на вопросы пользователя, MemChat автоматически извлекает соответствующую Textual Memory (текстовую память) из MemCube и внедряет её в Prompt. Это позволяет агенту отвечать на вопросы на основе предыдущей истории взаимодействия или базы знаний, а не полагаться только на предобученные знания LLM. + +### Автоматическое Осаждение Памяти (Auto-Memorization) +После диалога MemChat использует Extractor LLM для автоматического извлечения ценной информации (например, предпочтений пользователя, фактических знаний) из потока диалога и сохраняет её в MemCube. Пользователю не нужно вручную вмешиваться, весь процесс полностью автоматизирован. + +### Управление Контекстом +Автоматическое управление историей диалога (`max_turns_window`). Когда диалог становится слишком длинным, он умно обрезает старый контекст, полагаясь на извлечённую долговременную память для поддержания связности диалога, эффективно решая проблему ограничения контекстного окна LLM. + +### Гибкая Конфигурация +Поддержка конфигурационных переключателей для различных типов памяти (текстовая память, активированная память и т.д.), адаптируясь к различным сценариям применения. + +--- + +## 3. Структура Кода + +Основная логика находится в `memos/src/memos/mem_chat/`. + +* **`simple.py`**: **Стандартная Реализация (SimpleMemChat)**. Это готовая к использованию реализация REPL (Read-Eval-Print Loop), содержащая полную логику "извлечение -> генерация -> хранение". +* **`base.py`**: **Определение Интерфейса (BaseMemChat)**. Определяет основные действия MemChat, такие как `run()` и атрибут `mem_cube`. +* **`factory.py`**: **Фабричный Класс**. Отвечает за создание конкретного объекта MemChat на основе конфигурации (`MemChatConfig`). + +--- + +## 4. Ключевые Интерфейсы + +Основная точка взаимодействия — это класс `MemChat` (обычно создаётся `MemChatFactory`). + +### 4.1 Инициализация +Сначала вам нужно создать объект конфигурации, а затем создать экземпляр с помощью фабричного метода. После создания необходимо смонтировать экземпляр `MemCube` на `mem_chat.mem_cube`. + +### 4.2 `run()` +Запустите интерактивный цикл командного диалога. Подходит для разработки и отладки, он будет обрабатывать ввод пользователя, вызывать извлечение памяти, генерировать ответы и выводить их. + +### 4.3 Атрибуты +* **`mem_cube`**: Связанный объект куба памяти. MemChat использует его для чтения и записи памяти. +* **`chat_llm`**: Экземпляр LLM, используемый для генерации ответов. + +--- + +## 5. Рабочий Процесс + +Один цикл диалога MemChat обычно включает следующие шаги: + +1. **Получение Ввода (Input)**: Получение текстового ввода от пользователя. +2. **Извлечение Памяти (Recall)**: (если включена `enable_textual_memory`) использовать ввод пользователя в качестве запроса, извлекая Top-K соответствующих воспоминаний из `mem_cube.text_mem`. +3. **Построение Подсказки (Prompt Construction)**: Объединение системной подсказки, извлечённой памяти и недавней истории диалога (History) в полную подсказку. +4. **Генерация Ответа (Generation)**: Вызов `chat_llm` для генерации ответа. +5. **Извлечение и Хранение Памяти (Memorization)**: (если включена `enable_textual_memory`) отправка текущего диалога (Пользователь + Ассистент) в извлекатель `mem_cube`, извлечение новой памяти и сохранение в базе данных. + +--- + +## 6. Примеры Разработки + +Ниже приведён полный пример кода, демонстрирующий, как настроить MemChat и смонтировать MemCube на основе Qdrant и OpenAI. + +### 6.1 Реализация Кода + +```python +import os +import sys + +# Убедитесь, что модуль src может быть импортирован +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../src"))) + +from memos.configs.mem_chat import MemChatConfigFactory +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.mem_chat.factory import MemChatFactory +from memos.mem_cube.general import GeneralMemCube + +def get_mem_chat_config() -> MemChatConfigFactory: + """Генерация конфигурации MemChat""" + return MemChatConfigFactory.model_validate( + { + "backend": "simple", + "config": { + "user_id": "user_123", + "chat_llm": { + "backend": "openai", + "config": { + "model_name_or_path": os.getenv("MOS_CHAT_MODEL", "gpt-4o"), + "temperature": 0.8, + "max_tokens": 1024, + "api_key": os.getenv("OPENAI_API_KEY"), + "api_base": os.getenv("OPENAI_API_BASE"), + }, + }, + "max_turns_window": 20, + "top_k": 5, + "enable_textual_memory": True, # Включить явную память + }, + } + ) + +def get_mem_cube_config() -> GeneralMemCubeConfig: + """Генерация конфигурации MemCube""" + return GeneralMemCubeConfig.model_validate( + { + "user_id": "user03alice", + "cube_id": "user03alice/mem_cube_tree", + "text_mem": { + "backend": "general_text", + "config": { + "cube_id": "user03alice/mem_cube_general", + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": os.getenv("MOS_CHAT_MODEL", "gpt-4o"), + "api_key": os.getenv("OPENAI_API_KEY"), + "api_base": os.getenv("OPENAI_API_BASE"), + }, + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": "user03alice_mem_cube_general", + "vector_dimension": 1024, + }, + }, + "embedder": { + "backend": os.getenv("MOS_EMBEDDER_BACKEND", "universal_api"), + "config": { + "provider": "openai", + "api_key": os.getenv("MOS_EMBEDDER_API_KEY", "EMPTY"), + "model_name_or_path": os.getenv("MOS_EMBEDDER_MODEL", "bge-m3"), + "base_url": os.getenv("MOS_EMBEDDER_API_BASE"), + }, + }, + }, + }, + } + ) + +def main(): + print("Initializing MemChat...") + mem_chat = MemChatFactory.from_config(get_mem_chat_config()) + + print("Initializing MemCube...") + mem_cube = GeneralMemCube(get_mem_cube_config()) + + # Ключевой шаг: монтирование памяти куба + mem_chat.mem_cube = mem_cube + + print("Starting Chat Session...") + try: + mem_chat.run() + finally: + print("Saving memory cube...") + mem_chat.mem_cube.dump("new_cube_path") + +if __name__ == "__main__": + main() +``` + +--- + +## 7. Описание Конфигурации + +При настройке `MemChatConfigFactory` следующие параметры имеют решающее значение: + +* **`user_id`**: Обязательный. Используется для идентификации текущего пользователя в разговоре, чтобы обеспечить изоляцию памяти. +* **`chat_llm`**: Конфигурация модели разговора. Рекомендуется использовать более мощную модель (например, GPT-4o) для получения лучшего качества ответов и соблюдения инструкций. +* **`enable_textual_memory`**: `True` / `False`. Включить ли текстовую память. Если включено, система будет выполнять поиск перед разговором и сохранять данные после разговора. +* **`max_turns_window`**: Целое число. Количество раундов, сохраняемых в истории разговора. Исторические записи, превышающие этот лимит, будут обрезаны, полагаясь на долгосрочную память для дополнения контекста. +* **`top_k`**: Целое число. Сколько наиболее релевантных фрагментов памяти извлекать из хранилища и внедрять в Prompt каждый раз. + diff --git a/content/ru/open_source/modules/mem_cube.md b/content/ru/open_source/modules/mem_cube.md new file mode 100644 index 00000000..62fed2f3 --- /dev/null +++ b/content/ru/open_source/modules/mem_cube.md @@ -0,0 +1,290 @@ +--- +title: MemCube +desc: "MemCube — это ваш "ящик для памяти", который управляет тремя типами памяти: открытой памятью, активной памятью и параметрической памятью. Он предоставляет простой интерфейс для загрузки, сохранения и работы с несколькими модулями памяти, позволяя разработчикам легко создавать, сохранять и делиться приложениями для улучшения памяти." +--- +## Что такое MemCube? + +**MemCube** — это контейнер, который включает три основных типа памяти: + +- **Открытая память** (например, `GeneralTextMemory`, `TreeTextMemory`): используется для хранения и извлечения неструктурированных или структурированных текстовых знаний. +- **Активная память** (например, `KVCacheMemory`): используется для хранения кэшированных значений для ускорения вывода LLM и повторного использования контекста. +- **Параметрическая память** (например, `LoRAMemory`): используется для хранения параметров адаптации модели (например, весов LoRA). + +Каждый тип памяти можно настраивать независимо и гибко комбинировать в зависимости от потребностей приложения. + +## Структура + +MemCube определяется конфигурацией (см. `GeneralMemCubeConfig`), которая указывает бэкенд и настройки для каждого типа памяти. Типичная структура выглядит так: + +``` +MemCube + ├── user_id + ├── cube_id + ├── text_mem: TextualMemory + ├── act_mem: ActivationMemory + └── para_mem: ParametricMemory +``` + +Все модули памяти доступны через интерфейс MemCube: + +- `mem_cube.text_mem` +- `mem_cube.act_mem` +- `mem_cube.para_mem` + +## Архитектура View + +Начиная с MemOS 2.0, операции во время выполнения (добавление/поиск) должны выполняться через **архитектуру View**: + +### SingleCubeView + +Используется для управления одним MemCube. Применяется, когда системе требуется только одно пространство памяти. + +```python +from memos.multi_mem_cube.single_cube import SingleCubeView + +view = SingleCubeView( + cube_id="my_cube", + naive_mem_cube=naive_mem_cube, + mem_reader=mem_reader, + mem_scheduler=mem_scheduler, + logger=logger, + searcher=searcher, + feedback_server=feedback_server, # Необязательно +) + +# Добавить Память +view.add_memories(add_request) + +# Поиск Памяти +view.search_memories(search_request) +``` + +### CompositeCubeView + +Используется для управления несколькими MemCube. Применяется, когда необходимо выполнять единые операции через несколько пространств памяти. + +```python +from memos.multi_mem_cube.composite_cube import CompositeCubeView + +# Создать Несколько SingleCubeView +view1 = SingleCubeView(cube_id="cube_1", ...) +view2 = SingleCubeView(cube_id="cube_2", ...) + +# Комбинированный Вид для Множественных Операций с Cube +composite = CompositeCubeView(cube_views=[view1, view2], logger=logger) + +# Поиск по Всем Cube +results = composite.search_memories(search_request) +# Результаты Включают Поле cube_id для Идентификации Источника +``` + +### Поля запроса API + +#### Добавление памяти (режим add) + +| Поле | Описание | +| --------------------- | ---------------------------------------------------------------- | +| `writable_cube_ids` | Целевой cube для операции add | +| `async_mode` | `"async"` (включает фоновую обработку scheduler) или `"sync"` (отключает синхронную обработку scheduler) | + +#### Поиск памяти (режим search) + +| Поле | Описание | +| --------------------- | ---------------------------------------------------------------- | +| `readable_cube_ids` | Целевой cube для операции search | +| `async_mode` | `"async"` (включает фоновую обработку scheduler) или `"sync"` (отключает синхронную обработку scheduler) | + +## Основные методы (GeneralMemCube) + +GeneralMemCube — это стандартная реализация MemCube, которая управляет всеми памятью системы через единый интерфейс. GeneralMemCube предоставляет следующие основные методы для управления жизненным циклом данных памяти. + +### Инициализация + +```python +from memos.mem_cube.general import GeneralMemCube +mem_cube = GeneralMemCube(config) +``` + +### Операции со статическими данными + +| Метод | Описание | +| ----------------------------------------- | ----------------------------------------- | +| `init_from_dir(dir)` | Загружает MemCube из локального каталога | +| `init_from_remote_repo(repo, base_url)` | Загружает MemCube из удаленного репозитория (например, Hugging Face) | +| `load(dir)` | Загружает все воспоминания в существующий экземпляр из каталога | +| `dump(dir)` | Сохранить все воспоминания в директорию для постоянного хранения | + +## Хранение файлов + +Каталог после сохранения MemCube содержит следующие файлы, каждый из которых соответствует одному типу памяти: + +- `config.json` (Конфигурация MemCube) +- `textual_memory.json` (Открытая память) +- `activation_memory.pickle` (Активная память) +- `parametric_memory.adapter` (Параметрическая память) + +## Примеры использования + +### Пример экспорта (dump_cube.py) + +```python +import json +import os +import shutil + +from memos.api.handlers import init_server +from memos.api.product_models import APIADDRequest +from memos.log import get_logger +from memos.multi_mem_cube.single_cube import SingleCubeView + +logger = get_logger(__name__) +EXAMPLE_CUBE_ID = "example_dump_cube" +EXAMPLE_USER_ID = "example_user" + +# 1. Инициализация сервиса +components = init_server() +naive = components["naive_mem_cube"] + +# 2. Создание SingleCubeView +view = SingleCubeView( + cube_id=EXAMPLE_CUBE_ID, + naive_mem_cube=naive, + mem_reader=components["mem_reader"], + mem_scheduler=components["mem_scheduler"], + logger=logger, + searcher=components["searcher"], + feedback_server=components["feedback_server"], +) + +# 3. Добавление воспоминаний через View +result = view.add_memories(APIADDRequest( + user_id=EXAMPLE_USER_ID, + writable_cube_ids=[EXAMPLE_CUBE_ID], + messages=[ + {"role": "user", "content": "This is a test memory"}, + {"role": "user", "content": "Another memory to persist"}, + ], + async_mode="sync", # Использовать синхронный режим для немедленного завершения +)) +print(f"✓ Added {len(result)} memories") + +# 4. Экспорт данных для конкретного cube_id +output_dir = "tmp/mem_cube_dump" +if os.path.exists(output_dir): + shutil.rmtree(output_dir) +os.makedirs(output_dir, exist_ok=True) + +# Экспорт графовых данных (экспортировать только данные текущего cube_id) +json_data = naive.text_mem.graph_store.export_graph( + include_embedding=True, # Включить embedding для поддержки семантического поиска + user_name=EXAMPLE_CUBE_ID, # Фильтрация по cube_id +) + +# Исправление формата embedding: разобрать строку в список для совместимости с импортом +import contextlib +for node in json_data.get("nodes", []): + metadata = node.get("metadata", {}) + if "embedding" in metadata and isinstance(metadata["embedding"], str): + with contextlib.suppress(json.JSONDecodeError): + metadata["embedding"] = json.loads(metadata["embedding"]) + +print(f"✓ Exported {len(json_data.get('nodes', []))} nodes") + +# Сохранить в файл +memory_file = os.path.join(output_dir, "textual_memory.json") +with open(memory_file, "w", encoding="utf-8") as f: + json.dump(json_data, f, indent=2, ensure_ascii=False) +print(f"✓ Saved to: {memory_file}") +``` + +### Пример импорта и поиска (load_cube.py) + +> **Примечание о совместимости встраивания**: Примерные данные используют модель **bge-m3** с размерностью **1024**. Если ваша среда использует другую модель встраивания или размерность, семантический поиск после импорта может быть неточным или неудачным. Пожалуйста, убедитесь, что ваша конфигурация `.env` соответствует конфигурации встраивания во время экспорта. + +```python +import json +import os + +from memos.api.handlers import init_server +from memos.api.product_models import APISearchRequest +from memos.log import get_logger +from memos.multi_mem_cube.single_cube import SingleCubeView + +logger = get_logger(__name__) +EXAMPLE_CUBE_ID = "example_dump_cube" +EXAMPLE_USER_ID = "example_user" + +# 1. Инициализация сервиса +components = init_server() +naive = components["naive_mem_cube"] + +# 2. Создание SingleCubeView +view = SingleCubeView( + cube_id=EXAMPLE_CUBE_ID, + naive_mem_cube=naive, + mem_reader=components["mem_reader"], + mem_scheduler=components["mem_scheduler"], + logger=logger, + searcher=components["searcher"], + feedback_server=components["feedback_server"], +) + +# 3. Загрузка Данных Из Файла В graph_store +load_dir = "examples/data/mem_cube_tree" +memory_file = os.path.join(load_dir, "textual_memory.json") + +with open(memory_file, encoding="utf-8") as f: + json_data = json.load(f) + +naive.text_mem.graph_store.import_graph(json_data, user_name=EXAMPLE_CUBE_ID) + +nodes = json_data.get("nodes", []) +print(f"✓ Imported {len(nodes)} nodes") + +# 4. Отображение Загруженных Данных +print(f"\nLoaded {len(nodes)} memories:") +for i, node in enumerate(nodes[:3], 1): # Отображение Первых 3 Записей + metadata = node.get("metadata", {}) + memory_text = node.get("memory", "N/A") + mem_type = metadata.get("memory_type", "unknown") + print(f" [{i}] Type: {mem_type}") + print(f" Content: {memory_text[:60]}...") + +# 5. Проверка Семантического Поиска +query = "test memory dump persistence demonstration" +print(f'\nSearching: "{query}"') + +search_result = view.search_memories( + APISearchRequest( + user_id=EXAMPLE_USER_ID, + readable_cube_ids=[EXAMPLE_CUBE_ID], + query=query, + ) +) + +text_mem_results = search_result.get("text_mem", []) +memories = [] +for group in text_mem_results: + memories.extend(group.get("memories", [])) + +print(f"✓ Found {len(memories)} relevant memories") +for i, mem in enumerate(memories[:2], 1): # Отображение Первых 2 Записей + print(f" [{i}] {mem.get('memory', 'N/A')[:60]}...") +``` + +### Полный пример + +Смотрите примеры в репозитории кода: + +- `MemOS/examples/mem_cube/dump_cube.py` - Экспорт Данных MemCube (add + export) +- `MemOS/examples/mem_cube/load_cube.py` - Импорт Данных MemCube И Проведение Семантического Поиска (import + search) + +### Примечание о старом API + +Способ прямого вызова `mem_cube.text_mem.get_all()` в ранних версиях устарел, пожалуйста, используйте архитектуру View. Старые примеры перемещены в `MemOS/examples/mem_cube/_deprecated/`. + +## Примечания для разработчиков + +* MemCube обеспечивает согласованность режима, гарантируя безопасную загрузку/выгрузку +* Каждый тип памяти является заменяемым и поддерживает независимое тестирование +* См. `/tests/mem_cube/` для получения информации о интеграционном тестировании и режимах использования diff --git a/content/ru/open_source/modules/mem_feedback.md b/content/ru/open_source/modules/mem_feedback.md new file mode 100644 index 00000000..f50e1aa9 --- /dev/null +++ b/content/ru/open_source/modules/mem_feedback.md @@ -0,0 +1,156 @@ +--- +title: MemFeedback +desc: "MemFeedback — это твой "тетрадь с ошибками памяти", позволяющая твоему Agent понимать "ты ошибся" и автоматически исправлять память. Это ключевой компонент для реализации самоэволюции памяти." +--- + +## 1. Введение + +**MemFeedback** — это "лекарство от сожалений" в MemOS. + +В системе долговременной памяти наиболее проблематично часто не "не запомнить", а "неправильно запомнить и не исправить". Когда пользователь говорит "Нет, мой день рождения завтра" или "Переименуй этот проект в X", простая система RAG обычно оказывается бессильной. + +MemFeedback может понимать эти команды на естественном языке, автоматически точно находить конфликтующие воспоминания в базе данных и выполнять атомарные операции исправления (например, архивировать старые воспоминания, записывать новые воспоминания). С его помощью твой Agent может, как человек, постоянно исправлять ошибки и учиться в процессе общения. + +--- + +## 2. Основные Возможности + +Он может обрабатывать четыре распространенных сценария обратной связи: + +### Исправление (Correction) +Пользователь указывает на фактическую ошибку. Система не будет грубо удалять старые данные, а архивирует их (**Archive**) и записывает новые данные. Таким образом, ошибка исправляется, и сохраняется история версий (Traceability). Если это текущий диалог (WorkingMemory), то обновление происходит на месте, обеспечивая согласованность контекста. + +### Дополнение (Addition) +Если пользователь просто добавил новую информацию, которая не конфликтует со старыми воспоминаниями, то все просто — она просто сохраняется как новый узел в памяти. + +### Глобальная Замена (Keyword Replacement) +Похоже на "глобальную рефакторизацию" в IDE. Например, если пользователь говорит "замени 'Чжан Сан' на 'Ли Сы' во всех документах", система автоматически определит диапазон затронутых документов с помощью Reranker и массово обновит все связанные воспоминания. + +### Эволюция Предпочтений (Preference Evolution) +Специально обрабатывает предпочтения, такие как "я не ем кинзу" или "мне нравится Python". Система будет записывать сценарии, в которых возникают эти предпочтения, постоянно обогащая профиль пользователя, чтобы Agent становился все более удобным в использовании. + +--- + +## 3. Структура Кода + +Основная логика находится в `memos/src/memos/mem_feedback/`. + +* **`simple_feedback.py`**: **рекомендуется смотреть это**. Это официальная упакованная версия, которая объединяет LLM, векторную базу данных и поисковик, готовую к использованию. +* **`feedback.py`**: основной класс реализации `MemFeedback`. Здесь выполняются все грязные и трудоемкие задачи: распознавание намерений, сравнение конфликтов, безопасность. +* **`base.py`**: определение интерфейса. +* **`utils.py`**: инструменты. + +--- + +## 4. Ключевые Интерфейсы + +Главный входной интерфейс один: `process_feedback()`. Обычно вызывается асинхронно после завершения процесса RAG и получения обратной связи от пользователя. + +### 4.1 Входные Параметры + +| Параметр | Описание | +| :--- | :--- | +| `user_id` / `user_name` | Идентификатор пользователя и Cube ID. | +| `chat_history` | История диалога, чтобы LLM знала, о чем вы только что говорили. | +| `feedback_content` | Отзыв пользователя (например, "Нет, это пять часов"). | +| **`retrieved_memory_ids`** | **Обязательный параметр (рекомендуется)**. Передайте сюда ID памяти, полученные в предыдущем RAG, это как бы дает системе "мишень", указывая, какую память нужно исправить. Если не передать, системе придется заново искать в огромной памяти, что не только медленно, но и легко приводит к ошибкам. | +| `corrected_answer` | Нужно ли одновременно сгенерировать исправленный ответ. | + +### 4.2 Результаты Выхода + +Возвращает словарь, который сообщает, что было изменено в этой операции: +* **`record`**: детали изменений в базе данных (например, `{ "add": [...], "update": [...] }`). +* **`answer`**: ответ на естественном языке для пользователя. + +--- + +## 5. Рабочий Процесс + +Рабочий процесс MemFeedback похож на строгую редакцию: + +1. **Рецензирование (распознавание намерений)**: сначала смотрим, исправляет ли пользователь ошибку, добавляет информацию или меняет имя. +2. **Локализация (вызов)**: находим воспоминание, которое нужно изменить (если вы передали ID, этот шаг пропускается). +3. **Корректура (сравнение)**: даем LLM внимательно сравнить новую и старую информацию, чтобы определить, является ли это полностью новым (ADD) или требует обновления (UPDATE). +4. **Контроль безопасности (проверка безопасности)**: предотвращаем случайные изменения LLM. Например, правильный ли ID? Не нужно ли удалить целый длинный документ? (будет установлен порог для блокировки). +5. **Публикация (запись)**: в конце выполняем операции с графовой базой данных, архивируя старые и записывая новые. + +--- + +## 6. Примеры Разработки + +Здесь есть исполняемый код, демонстрирующий, как инициализировать сервис, установить "ошибочное воспоминание", а затем исправить его с помощью обратной связи от пользователя. + +### 6.1 Подготовительные Работы + +Сначала нам нужно инициализировать сервис `SimpleMemFeedback`. + +```python +# Предполагается, что компоненты llm, embedder, graph_db и т.д. были инициализированы через Factory. +# Полный код инициализации смотрите в examples/mem_feedback/example_feedback.py + +from memos.mem_feedback.simple_feedback import SimpleMemFeedback + +feedback_server = SimpleMemFeedback( + llm=llm, + embedder=embedder, + graph_store=graph_db, + memory_manager=memory_manager, + mem_reader=mem_reader, + searcher=searcher, + reranker=mem_reranker, + pref_mem=None, +) +``` + +### 6.2 Симуляция Сценария и Выполнение Обратной Связи + +Сценарий: система ошибочно запомнила "ты любишь яблоки, не любишь бананы", теперь мы должны это исправить. + +```python +import json +from memos.mem_feedback.utils import make_mem_item + +# 1. Симуляция истории диалога +# Пользователь спрашивает о предпочтениях, помощник ошибается. +history = [ + {"role": "user", "content": "Что мне нравится из фруктов, а что не нравится"}, + {"role": "assistant", "content": "Ты любишь яблоки, не любишь бананы"}, +] + +# 2. Предустановка "Ошибочной Памяти" +# Мы вручную добавляем в хранилище ошибочный факт +mem_text = "Ты любишь яблоки, не любишь бананы" +# ... (опущены подробные параметры make_mem_item, см. исходный код) ... +memory_manager.add([make_mem_item(mem_text, ...)], ...) + +# 3. Обратная связь пользователя +feedback_content = "Неправильно, на самом деле я люблю мангостин" +print(f"Feedback Input: {feedback_content}") + +# 4. Исполнение исправления +# MemFeedback обнаружит конфликт, архивирует старую память и записывает новую память "люблю мангостин" +res = feedback_server.process_feedback( + ..., + chat_history=history, + feedback_content=feedback_content, + ... +) + +# 5. Просмотр результатов +print(json.dumps(res, indent=4)) +``` + +--- + +## 7. Описание Конфигурации + +Чтобы запустить MemFeedback, вам нужно подготовить конфигурацию следующих компонентов (обычно в `.env` или YAML): + +* **LLM (`extractor_llm`)**: Ум должен работать хорошо, рекомендуется использовать модель уровня GPT-4o. Установите низкую температуру (например, 0), потому что она должна заниматься логическим анализом, не требуется слишком много рассеяния. +* **Embedder (`embedder`)**: Используется для преобразования новой памяти в векторы. +* **GraphDB (`graph_db`)**: Эти два брата отвечают за то, где и как хранится память. +* **MemReader (`mem_reader`)**: Если это чисто новая память, используйте его для анализа. + + +--- + diff --git a/content/ru/open_source/modules/mem_reader.md b/content/ru/open_source/modules/mem_reader.md new file mode 100644 index 00000000..67e62cf6 --- /dev/null +++ b/content/ru/open_source/modules/mem_reader.md @@ -0,0 +1,183 @@ +--- +title: "MemReader" +desc: "MemReader — это ваш 'переводчик памяти'. Он отвечает за преобразование беспорядочного ввода (чаты, документы, изображения) в структурированные фрагменты памяти, которые система может понять." + +## 1. Введение + +При создании AI приложений мы часто сталкиваемся с такой проблемой: пользователи присылают самые разные вещи — это могут быть случайные чаты, PDF документы или изображения. **MemReader** предназначен для того, чтобы 'переварить' эти исходные данные (Raw Data) и преобразовать их в стандартные блоки памяти (Memory Item) с Embedding и метаданными. + +Проще говоря, он выполняет три задачи: +1. **Нормализация**: независимо от того, отправили ли вы строку или JSON, сначала преобразуйте в стандартный формат. +2. **Разбиение (Chunking)**: разбейте длинные диалоги или документы на подходящие небольшие части для удобства последующей обработки. +3. **Извлечение (Extraction)**: вызов LLM для извлечения неструктурированной информации в структурированные знания (Fine режим) или для прямого создания снимка (Fast режим). + +--- + +## 2. Основные Режимы + +MemReader разработал два рабочих режима, соответствующих требованиям 'быстроты' и 'точности': + +### ⚡ Fast Режим (Только Быстро) +* **Особенности**: **не вызывает LLM**, только выполняет разбиение и Embedding. +* **Сценарии использования**: + * Пользователь отправляет сообщения очень быстро, системе требуется ответ в миллисекундах. + * Нужно только сохранить 'снимок' диалога, без глубокого понимания. +* **Результат**: исходные текстовые фрагменты + векторный индекс + отслеживание источников (Sources). + +### 🧠 Fine Режим (Тщательная Обработка) +* **Особенности**: **вызывает LLM** для глубокого анализа. +* **Сценарии использования**: + * Запись долгосрочной памяти (необходимо извлечение ключевых фактов). + * Анализ документов (необходимо обобщение основных идей). + * Мультимодальное понимание (необходимо понять содержание изображений). +* **Результат**: структурированные факты + извлечение ключевой информации (Key) + контекст (Background) + векторный индекс + отслеживание источников (Sources) + мультимодальные детали. + +--- + +## 3. Структура Кода + +Структура кода MemReader очень ясна и состоит из следующих частей: + +* **`base.py`**: определяет все интерфейсы, которые должны соблюдать Reader. +* **`simple_struct.py`**: **самая распространенная реализация**. Специализируется на чисто текстовых диалогах и локальных документах, легкая и эффективная. +* **`multi_modal_struct.py`**: **универсальный игрок**. Может обрабатывать изображения, URL файлов, вызовы Tool и другие сложные входные данные. +* **`read_multi_modal/`**: содержит различные конкретные парсеры (Parser), такие как `ImageParser`, специально для разбора изображений, `FileParser` для разбора файлов и т.д. + +--- + +## 4. Как Выбрать? + +| Ваши Требования | Рекомендуемый Выбор | Причина | +| :--- | :--- | :--- | +| **Обработка Только Текстовых Диалогов** | `SimpleStructMemReader` | Простой, прямой, хорошая производительность. | +| **Необходимо Обрабатывать Изображения, Ссылки на Файлы** | `MultiModalStructMemReader` | Встроенные возможности мультимодальной обработки. | +| **Необходимо Обновление с Fast до Fine** | Метод `fine_transfer` любого Reader | Поддерживает прогрессивную стратегию «сначала сохранить, потом улучшить». | + +--- + +## 5. Обзор API + +### Унифицированная Фабрика: `MemReaderFactory` + +Не создавайте объекты самостоятельно с помощью `new`, использование фабричного метода — это лучший подход: + +```python +from memos.configs.mem_reader import MemReaderConfigFactory +from memos.mem_reader.factory import MemReaderFactory + +# Создание Reader из Конфигурации +cfg = MemReaderConfigFactory.model_validate({...}) +reader = MemReaderFactory.from_config(cfg) +``` + +### Основной Метод: `get_memory()` + +Это метод, который вы вызываете чаще всего. + +```python +memories = reader.get_memory( + scene_data, # Ваши входные данные + type="chat", # Тип: chat или doc + info=user_info, # Информация о пользователе (user_id, session_id) + mode="fine" # Режим: fast или fine (настойчиво рекомендуется явно указывать!) +) +``` + +**Результат**: `list[list[TextualMemoryItem]]` + +::note{icon="ri:bnb-fill"} +Почему двойной список? +Потому что длинный диалог может быть разбит на несколько окон (Window), внешний список представляет окна, а внутренний список представляет извлеченные из этого окна элементы памяти. +:: + +--- + +## 6. Практика Разработки + +### Сценарий 1: Обработка Простых Чат-Записей + +Это самый базовый способ использования, с использованием `SimpleStructMemReader`. + +```python +# 1. Подготовка Входных Данных: Стандартный Формат Диалога OpenAI +conversation = [ + [ + {"role": "user", "content": "У меня завтра в 3 часа дня встреча"}, + {"role": "assistant", "content": "Какова тема встречи?"}, + {"role": "user", "content": "Обсуждение крайнего срока проекта Q4"}, + ] +] + +# 2. Извлечение Памяти (Fine Мод) +memories = reader.get_memory( + conversation, + type="chat", + mode="fine", + info={"user_id": "u1", "session_id": "s1"} +) + +# 3. Результаты +# memories будет содержать извлеченные факты, например: "Пользователь завтра в 15:00 имеет встречу по проекту Q4" +``` + +### Сценарий 2: Обработка Мультимодальных Входных Данных + +Когда пользователь отправляет изображения или ссылки на файлы, переключитесь на `MultiModalStructMemReader`. + +```python +# 1. Подготовка Входных Данных: Сложное Сообщение, Содержащее Файлы и Изображения +scene_data = [ + [ + { + "role": "user", + "content": [ + {"type": "text", "text": "Посмотрите на этот файл и изображение"}, + # Файлы поддерживают автоматическую загрузку и анализ по URL + {"type": "file", "file": {"file_data": "https://example.com/readme.md"}}, + # Изображения поддерживают URL + {"type": "image_url", "image_url": {"url": "https://example.com/chart.png"}}, + ] + } + ] +] + +# 2. Извлечение Памяти +memories = multimodal_reader.get_memory( + scene_data, + type="chat", + mode="fine", # Только Fine Мод вызывает визуальную модель для анализа изображений + info={"user_id": "u1", "session_id": "s1"} +) +``` + +### Сценарий 3: Пошаговая Оптимизация (Fine Transfer) + +Для улучшения пользовательского опыта вы можете сначала использовать Fast режим для быстрого сохранения диалога, а затем, когда система будет свободна, 'отшлифовать' его в Fine память. + +```python +# 1. Сначала Быстро Сохранить (в миллисекундах) +fast_memories = reader.get_memory(conversation, mode="fast", ...) + +# ... Сохранить в Базу Данных ... + +# 2. Фоновая Асинхронная Уточнение +refined_memories = reader.fine_transfer_simple_mem( + fast_memories_flat_list, # Обратите внимание, что здесь передается плоский список элементов + type="chat" +) + +# 3. Заменить оригинальные fast_memories на refined_memories +``` + +--- + +## 7. Описание Параметров Конфигурации + +В `.env` или конфигурационном файле вы можете настроить следующие ключевые параметры: + +* **`chat_window_max_tokens`**: **Размер Скользящего Окна**. По умолчанию 1024. Определяет, сколько контекста будет упаковано для обработки. Установка слишком маленького значения может привести к потере контекста, установка слишком большого значения может превысить лимит токенов LLM. +* **`remove_prompt_example`**: **Удалить Пример Из Prompt**. True = экономия токенов, но может снизить качество извлечения; False = сохранить пример для повышения точности, но потребует больше токенов (сохранить примеры Few-shot). +* **`direct_markdown_hostnames`** (только мультимодальный): **Белый Список Доменов**. Доменные имена в списке (например, `raw.githubusercontent.com`) будут обрабатываться напрямую как Markdown текст, пропуская этапы OCR/форматирования, что ускоряет обработку. + + + diff --git a/content/ru/open_source/modules/mem_scheduler.md b/content/ru/open_source/modules/mem_scheduler.md new file mode 100644 index 00000000..832c38ed --- /dev/null +++ b/content/ru/open_source/modules/mem_scheduler.md @@ -0,0 +1,494 @@ +--- +title: "MemScheduler" +desc: "MemScheduler является вашим "организатором памяти", который асинхронно управляет потоками и обновлениями памяти в фоновом режиме, координируя взаимодействие между рабочей памятью, долгосрочной памятью и активной памятью, позволяя диалоговым системам динамически организовывать и использовать память." + +## Основные Характеристики + +- 🚀 **Параллельная Работа с MemOS Системой**: Запуск в независимом потоке/процессе, не блокируя основную бизнес-логику. +- 🧠 **Координация Множественной Памяти**: Умное управление потоками рабочей памяти, долгосрочной памяти и персонализированной памяти пользователя. +- ⚡ **Событийно-Ориентированное Планирование**: Асинхронный механизм распределения задач на основе очереди сообщений (Redis/Local). +- 🔍 **Эффективный Поиск**: Интеграция векторного поиска и графового поиска для быстрого нахождения соответствующей памяти. +- 📊 **Полный Мониторинг**: Реальный мониторинг использования памяти, состояния очереди задач и задержки планирования. +- 📝 **Подробная Запись Логов**: Полное отслеживание операций с памятью для удобства отладки и анализа системы. + +## MemScheduler Архитектура + +`MemScheduler` использует модульную архитектуру, разделенную на три уровня: + +### Уровень Планирования (Ядро) +1. **Планировщик (Маршрутизатор)**: Умный маршрутизатор сообщений, который распределяет задачи к соответствующим обработчикам в зависимости от типа сообщения (`QUERY`, `ANSWER`, `MEM_UPDATE` и т.д.). +2. **Обработка Сообщений**: Управляет бизнес-логикой через сообщения с определенными метками (Label), определяя формат сообщений и правила обработки. + +### Уровень Исполнения (Гарантия) +3. **Очередь Задач**: Поддерживает два режима: Redis Stream (в производственной среде) и Local Queue (для разработки и тестирования), обеспечивая асинхронное буферизование задач и их сохранение. +4. **Управление Памятью**: Выполняет операции чтения и записи, сжатия, забвения и преобразования типов для трех уровней памяти (Рабочая/Долгосрочная/Пользовательская). +5. **Система Поиска**: Модуль смешанного поиска, который сочетает намерения пользователя, управление сценами и соответствие ключевым словам для быстрого нахождения соответствующей памяти. + +### Уровень Поддержки (Помощь) +6. **Мониторинг**: Отслеживание накопления задач, времени обработки и состояния хранилища памяти. +7. **Запись Логов**: Поддержка логов операций с памятью по всему пути, что облегчает отладку и анализ. + +## Инициализация MemScheduler + +В архитектуре MemOS `MemScheduler` инициализируется как часть серверного компонента при запуске. + +### Инициализация в Server Router + +В `src/memos/api/routers/server_router.py` планировщик автоматически загружается через функцию `init_server()`: + +```python +from memos.api import handlers +from memos.api.handlers.base_handler import HandlerDependencies +from memos.mem_scheduler.base_scheduler import BaseScheduler +from memos.mem_scheduler.utils.status_tracker import TaskStatusTracker + +# ... Другие импорты ... + +# 1. Инициализация всех серверных компонентов (включая DB, LLM, Memory, Scheduler) +# init_server() будет считывать переменные окружения и инициализировать глобальные одиночные компоненты +components = handlers.init_server() + +# Create dependency container for handlers +dependencies = HandlerDependencies.from_init_server(components) + +# Initialize handlers... +# search_handler = SearchHandler(dependencies) +# ... + +# 2. Получение экземпляра планировщика из словаря компонентов +# Планировщик уже был инициализирован и запущен внутри init_server (если это было включено) +mem_scheduler: BaseScheduler = components["mem_scheduler"] + +# 3. Пользователь также может получить другие компоненты, связанные с планированием, в components (необязательно, для настройки обработки задач) +# redis_client используется для прямого взаимодействия с Redis или мониторинга состояния задач +redis_client = components["redis_client"] +# ... +``` + + +## Планирование Задач и Модель Данных + +Планировщик распределяет и выполняет задачи на основе сообщений. В этом разделе описаны поддерживаемые типы задач, структура сообщений и журналы выполнения. + +### Типы Сообщений и Обработчики + +Планировщик распределяет и выполняет задачи, регистрируя определенные метки задач (Label) и обработчики (Handler). Ниже приведены задачи планирования, которые поддерживаются по умолчанию в текущей версии (на основе `GeneralScheduler` и `OptimizedScheduler`): + +| Метка Сообщения (Label) | Соответствующая Константа | Метод Обработчика | Описание | +| :--- | :--- | :--- | :--- | +| `query` | `QUERY_TASK_LABEL` | `_query_message_consumer` | Обработка пользовательских запросов, инициирование распознавания намерений, извлечение памяти и преобразование в задачи обновления памяти. | +| `answer` | `ANSWER_TASK_LABEL` | `_answer_message_consumer` | Обработка ответов AI, запись журналов диалогов. | +| `mem_update` | `MEM_UPDATE_TASK_LABEL` | `_memory_update_consumer` | Основная задача. Выполнение процесса обновления долгосрочной памяти, включая извлечение Query Keyword, обновление Monitor, извлечение соответствующей памяти и замена рабочей памяти (Working Memory). | +| `add` | `ADD_TASK_LABEL` | `_add_message_consumer` | Обработка записи журналов добавления новой памяти (поддержка локальных и облачных журналов). | +| `mem_read` | `MEM_READ_TASK_LABEL` | `_mem_read_message_consumer` | Использование `MemReader` для глубокой обработки и импорта внешнего содержимого памяти. | +| `mem_organize` | `MEM_ORGANIZE_TASK_LABEL` | `_mem_reorganize_message_consumer` | Инициирование операций реорганизации и объединения (Merge) памяти. | +| `pref_add` | `PREF_ADD_TASK_LABEL` | `_pref_add_message_consumer` | Обработка извлечения и добавления пользовательских предпочтений (Preference Memory). | +| `mem_feedback` | `MEM_FEEDBACK_TASK_LABEL` | `_mem_feedback_message_consumer` | Обработка пользовательской обратной связи для исправления памяти или усиления предпочтений. | +| `api_mix_search` | `API_MIX_SEARCH_TASK_LABEL` | `_api_mix_search_message_consumer` | (Специфично для OptimizedScheduler) Выполнение асинхронной смешанной поисковой задачи, сочетая быстрый поиск и детализированный поиск. | + +### Структура Сообщений (ScheduleMessageItem) + +Планировщик использует единую структуру `ScheduleMessageItem` для передачи сообщений в очереди. + +> **Примечание**: Объект `mem_cube` сам по себе не содержится в модели сообщений, а интерпретируется планировщиком во время выполнения через `mem_cube_id`. + +| Поле | Тип | Описание | Значение по умолчанию/Примечания | +| :--- | :--- | :--- | :--- | +| `item_id` | `str` | Уникальный идентификатор сообщения (UUID) | Автоматически генерируется | +| `user_id` | `str` | Связанный идентификатор пользователя | (Обязательно) | +| `mem_cube_id` | `str` | Связанный идентификатор Memory Cube | (Обязательно) | +| `label` | `str` | Метка задачи (например, `query`, `mem_update`) | (Обязательно) | +| `content` | `str` | Нагрузка сообщения (обычно JSON-строка или текст) | (Обязательно) | +| `timestamp` | `datetime` | Время отправки сообщения | Автоматически генерируется (UTC сейчас) | +| `session_id` | `str` | Идентификатор сессии, используемый для изоляции контекста | `""` | +| `trace_id` | `str` | Идентификатор трассировки, используемый для связи логов по всей цепочке | Автоматически генерируется | +| `user_name` | `str` | Отображаемое имя пользователя | `""` | +| `task_id` | `str` | Идентификатор задачи на уровне бизнеса (для связи нескольких сообщений) | `None` | +| `info` | `dict` | Дополнительная пользовательская информация контекста | `None` | +| `stream_key` | `str` | (Для Внутреннего Использования) Ключ Redis Stream | `""` | + +### Структура Журнала Выполнения (ScheduleLogForWebItem) + +Планировщик генерирует структурированные журналы сообщений для отображения на фронтенде или для постоянного хранения. + +| Поле | Тип | Описание | Примечание | +| :--- | :--- | :--- | :--- | +| `item_id` | `str` | Уникальный Идентификатор Записи Лога | Автоматически Генерируется | +| `task_id` | `str` | Связанный Идентификатор Родительской Задачи | Необязательно | +| `user_id` | `str` | Идентификатор Пользователя | (Обязательно) | +| `mem_cube_id` | `str` | Идентификатор Memory Cube | (Обязательно) | +| `label` | `str` | Категория Лога (например, `addMessage`, `addMemory`) | (Обязательно) | +| `log_content` | `str` | Краткое Описание Текста Лога | (Обязательно) | +| `from_memory_type` | `str` | Исходная Область Памяти | Например, `UserInput`, `LongTermMemory` | +| `to_memory_type` | `str` | Целевая Область Памяти | Например, `WorkingMemory` | +| `memcube_log_content` | `list[dict]` | Структурированное Подробное Содержимое | Содержит Конкретный Текст Памяти, Идентификаторы Ссылок и Т. Д. | +| `metadata` | `list[dict]` | Метаданные Элемента Памяти | Содержит Уровень Доверия, Статус, Метки и Т. Д. | +| `status` | `str` | Статус Задачи | Например, `completed`, `failed` | +| `timestamp` | `datetime` | Время Создания Лога | Автоматически Генерируется | +| `current_memory_sizes` | `MemorySizes` | Снимок Текущего Количества Памяти в Каждой Области | Используется для Отображения на Мониторинговой Панели | +| `memory_capacities` | `MemoryCapacities` | Ограничение памяти для каждого региона | Используется для отображения на панели мониторинга | + +## Примеры Функций Планирования + +### 1. Обработка Сообщений и Пользовательский Handler + +Самая мощная функция планировщика — это поддержка регистрации пользовательских обработчиков сообщений (Handler). Вы можете определить определенные типы сообщений (например, `MY_CUSTOM_TASK`) и написать функции для их обработки. + +```python +import uuid +from datetime import datetime + +# 1. Импортируйте необходимые определения типов и экземпляр планировщика +# Примечание: mem_scheduler необходимо импортировать из server_router, так как это глобальный синглтон +from memos.api.routers.server_router import mem_scheduler +from memos.mem_scheduler.schemas.message_schemas import ScheduleMessageItem + +# Определите пользовательский ярлык задачи +MY_TASK_LABEL = "MY_CUSTOM_TASK" + + +# Определите функцию обработчика +def my_task_handler(messages: list[ScheduleMessageItem]): + """ + Функция для обработки пользовательских задач + """ + for msg in messages: + print(f"⚡️ [Handler] Получена задача: {msg.item_id}") + print(f"📦 Содержимое: {msg.content}") + # Здесь выполните вашу бизнес-логику, например: вызов LLM, запись в базу данных, запуск других задач и т.д. + + +# 2. Зарегистрируйте обработчик в планировщике +# Этот шаг подключает вашу пользовательскую логику к системе планирования +mem_scheduler.register_handlers({ + MY_TASK_LABEL: my_task_handler +}) + +# 3. Отправьте задачу +task = ScheduleMessageItem( + item_id=str(uuid.uuid4()), + user_id="user_123", + mem_cube_id="cube_001", + label=MY_TASK_LABEL, + content="Это тестовое сообщение", + timestamp=datetime.now() +) + +# Если планировщик не запущен, здесь задача будет помещена в очередь ожидания (если это очередь Redis) +# Или в локальном режиме очереди может потребоваться сначала вызвать mem_scheduler.start() +mem_scheduler.submit_messages([task]) + +print(f"Task submitted: {task.item_id}") + +# Предотвращение Досрочного Выхода Главного Процесса Планировщика +time.sleep(10) +``` + +### 2. Redis Очередь против Локальной Очереди + +- **Локальная Очередь (Local Queue)**: + - **Подходящие Сценарии**:Модульное Тестирование, Простые Скрипты На Одном Компьютере. + - **Особенности**:Высокая Скорость, Но Данные Утрачаются После Перезапуска Процесса, Не Поддерживает Совместное Использование Многопроцессорных/Многоэкземплярных. + - **Конфигурация**:`MOS_SCHEDULER_USE_REDIS_QUEUE=false` + +- **Очередь Redis (Redis Stream)**: + - **Подходящие Сценарии**:Производственная Среда, Распределенное Развертывание. + - **Особенности**:Постоянное Хранение Данных, Поддержка Групп Потребителей (Consumer Group), Позволяет Нескольким Экземплярам Планировщика Совместно Обрабатывать Задачи (Балансировка Нагрузки). + - **Конфигурация**:`MOS_SCHEDULER_USE_REDIS_QUEUE=true` + - **Отладка**:Можно Использовать Скрипт `show_redis_status.py` Для Просмотра Состояния Очереди. + +## Комплексные Сценарии Применения + +### Сценарий 1: Основной Диалоговый Поток И Обновление Памяти + +Ниже представлен полный пример, демонстрирующий, как инициализировать окружение, зарегистрировать пользовательскую логику, смоделировать диалоговый поток и инициировать обновление памяти. + +```python +import asyncio +import json +import os +import sys +import time +from pathlib import Path + +# --- Подготовка Окружения --- +# 1. Установите Корневую Директорию Проекта в sys.path, чтобы Убедиться, что Можно Импортировать MemOS Модуль +FILE_PATH = Path(__file__).absolute() +BASE_DIR = FILE_PATH.parent.parent.parent +sys.path.insert(0, str(BASE_DIR)) + +# 2. Установите Необходимые Переменные Окружения (Эмуляция .env Конфигурации) +os.environ["ENABLE_CHAT_API"] = "true" +os.environ["MOS_ENABLE_SCHEDULER"] = "true" +# Определите, Использовать ли Redis или Локальную Очередь +os.environ["MOS_SCHEDULER_USE_REDIS_QUEUE"] = "false" + +# --- Импорт Компонентов --- +# Внимание: Импорт server_router Запустит Инициализацию Компонентов, Убедитесь, что Переменные Окружения Установлены Перед Этим +from memos.api.product_models import APIADDRequest, ChatPlaygroundRequest +from memos.api.routers.server_router import ( + add_handler, + chat_stream_playground, + mem_scheduler, # Здесь mem_scheduler Уже Является Инициализированным Синглтоном +) +from memos.log import get_logger +from memos.mem_scheduler.schemas.message_schemas import ScheduleMessageItem +from memos.mem_scheduler.schemas.task_schemas import ( + MEM_UPDATE_TASK_LABEL, + QUERY_TASK_LABEL, +) + +logger = get_logger(__name__) + +# Глобальная Переменная Для Демонстрации Результатов Поиска Памяти +working_memories = [] + +# --- Пользовательские Обработчики --- + +def custom_query_handler(messages: list[ScheduleMessageItem]): + """ + Обработка Сообщений Запроса Пользователя: + 1. Печать Содержимого Запроса + 2. Преобразование Сообщения В Задачу MEM_UPDATE, Запуск Процесса Поиска/Обновления Памяти + """ + for msg in messages: + print(f"\n[Scheduler 🟢] Получен Запрос Пользователя: {msg.content}") + + # Копирование Сообщения и Изменение Метки На MEM_UPDATE, Это Распространенная Модель "Цепочки Задач" + new_msg = msg.model_copy(update={"label": MEM_UPDATE_TASK_LABEL}) + + # Отправить Новый Задачу Обработчику + mem_scheduler.submit_messages([new_msg]) + + +def custom_mem_update_handler(messages: list[ScheduleMessageItem]): + """ + Обработка Задачи Обновления Памяти: + 1. Использовать Извлекатель (Retriever) Для Поиска Связанных Памятей + 2. Обновить Глобальный Список Рабочей Памяти + """ + global working_memories + search_args = {} + top_k = 2 + + for msg in messages: + print(f"[Scheduler 🔵] Идет Поиск Памяти Для Запроса...") + # Вызов Основной Функции Извлечения + results = mem_scheduler.retriever.search( + query=msg.content, + user_id=msg.user_id, + mem_cube_id=msg.mem_cube_id, + mem_cube=mem_scheduler.current_mem_cube, + top_k=top_k, + method=mem_scheduler.search_method, + search_args=search_args, + ) + + # Симуляция Обновления Рабочей Памяти + working_memories.extend(results) + working_memories = working_memories[-5:] # Сохранять Последние 5 Записей + + for mem in results: + # Печать Извлеченных Фрагментов Памяти + print(f" ↳ [Memory Found]: {mem.memory[:50]}...") + +# --- Симуляция Бизнес Данных --- + +def get_mock_data(): + """Генерация Симулированных Данных Диалога""" + conversations = [ + {"role": "user", "content": "I just adopted a golden retriever puppy named Max."}, + {"role": "assistant", "content": "That's exciting! Max is a great name."}, + {"role": "user", "content": "He loves peanut butter treats but I am allergic to nuts."}, + {"role": "assistant", "content": "Noted. Peanut butter for Max, no nuts for you."}, + ] + + questions = [ + {"question": "What is my dog's name?", "category": "Pet"}, + {"question": "What am I allergic to?", "category": "Allergy"}, + ] + return conversations, questions + +# --- Основной Процесс --- + +async def run_demo(): + print("==== MemScheduler Demo Start ====") + conversations, questions = get_mock_data() + + user_id = "demo_user_001" + mem_cube_id = "cube_demo_001" + + print(f"1. Инициализация Базы Памяти Пользователя ({user_id})...") + # Использовать API Handler Для Добавления Начальной Памяти (Синхронный Режим) + add_req = APIADDRequest( + user_id=user_id, + writable_cube_ids=[mem_cube_id], + messages=conversations, + async_mode="sync", + ) + add_handler.handle_add_memories(add_req) + print(" Память Добавлена Успешно.") + + print("\n2. Начать тестирование диалога (и запустить задачу планировщика в фоновом режиме)...") + for item in questions: + query = item["question"] + print(f"\n>> User: {query}") + + # Инициировать запрос на чат + chat_req = ChatPlaygroundRequest( + user_id=user_id, + query=query, + readable_cube_ids=[mem_cube_id], + writable_cube_ids=[mem_cube_id], + ) + + # Получить потоковый ответ + response = chat_stream_playground(chat_req) + + # Обработать потоковый вывод (упрощенная версия) + full_answer = "" + buffer = "" + async for chunk in response.body_iterator: + if isinstance(chunk, bytes): + chunk = chunk.decode("utf-8") + buffer += chunk + while "\n\n" in buffer: + msg, buffer = buffer.split("\n\n", 1) + for line in msg.split("\n"): + if line.startswith("data: "): + try: + data = json.loads(line[6:]) + if data.get("type") == "text": + full_answer += data["data"] + except: pass + + print(f">> AI: {full_answer}") + + # Подождите немного, чтобы планировщик в фоновом режиме обработал задачу и напечатал журнал + await asyncio.sleep(1) + +if __name__ == "__main__": + # 1. Зарегистрируйте наш пользовательский обработчик + # Это заменит или добавит к логике планирования по умолчанию + mem_scheduler.register_handlers( + { + QUERY_TASK_LABEL: custom_query_handler, + MEM_UPDATE_TASK_LABEL: custom_mem_update_handler, + } + ) + + # 2. Убедитесь, что планировщик запущен + if not mem_scheduler._running: + mem_scheduler.start() + + try: + asyncio.run(run_demo()) + except KeyboardInterrupt: + pass + finally: + # Предотвратить преждевременный выход основного процесса планировщика + time.sleep(10) + + print("\n==== Остановить планировщик ====") + mem_scheduler.stop() +``` + +### Сценарий 2: Асинхронные Задачи, Параллелизм И Перезапуск С Точки Остановки (Redis) + +Этот пример демонстрирует, как использовать очередь Redis для реализации параллельной обработки асинхронных задач и функции перезапуска с точки остановки. Для запуска этого примера необходимо настроить окружение Redis. + +```python +from pathlib import Path +from time import sleep + +from memos.api.routers.server_router import mem_scheduler +from memos.mem_scheduler.schemas.message_schemas import ScheduleMessageItem + + +# Отладка: напечатать конфигурацию планировщика +print("=== Scheduler Configuration Debug ===") +print(f"Scheduler type: {type(mem_scheduler).__name__}") +print(f"Config: {mem_scheduler.config}") +print(f"use_redis_queue: {mem_scheduler.use_redis_queue}") +print(f"Queue type: {type(mem_scheduler.memos_message_queue).__name__}") +print(f"Queue maxsize: {getattr(mem_scheduler.memos_message_queue, 'maxsize', 'N/A')}") +print("=====================================\n") + +queue = mem_scheduler.memos_message_queue + + +# Определить функцию обработки +def my_test_handler(messages: list[ScheduleMessageItem]): + print(f"My test handler received {len(messages)} messages: {[one.item_id for one in messages]}") + for msg in messages: + # Создать файл по task_id (используя item_id в качестве числового ID 0..99) + task_id = str(msg.item_id) + file_path = tmp_dir / f"{task_id}.txt" + try: + sleep(5) + file_path.write_text(f"Task {task_id} processed.\n") + print(f"writing {file_path} done") + except Exception as e: + print(f"Failed to write {file_path}: {e}") + + +def submit_tasks(): + mem_scheduler.memos_message_queue.clear() + + # Создать 100 сообщений (task_id 0..99) + users = ["user_A", "user_B"] + messages_to_send = [ + ScheduleMessageItem( + item_id=str(i), + user_id=users[i % 2], + mem_cube_id="test_mem_cube", + label=TEST_HANDLER_LABEL, + content=f"Create file for task {i}", + ) + for i in range(100) + ] + # Пакетная отправка сообщений и печать информации о завершении + print(f"Submitting {len(messages_to_send)} messages to the scheduler...") + mem_scheduler.memos_message_queue.submit_messages(messages_to_send) + print(f"Task submission done! tasks in queue: {mem_scheduler.get_tasks_status()}") + + +# Регистрация Обработчика Функций +TEST_HANDLER_LABEL = "test_handler" +mem_scheduler.register_handlers({TEST_HANDLER_LABEL: my_test_handler}) + +# Перезагрузка Через 5 Секунд +mem_scheduler.orchestrator.tasks_min_idle_ms[TEST_HANDLER_LABEL] = 5_000 + +tmp_dir = Path("./tmp") +tmp_dir.mkdir(exist_ok=True) + +# Тест Остановки И Перезагрузки: Если В tmp Уже Есть >1 Файл, Пропустить Отправку И Напечатать Информацию +existing_count = len(list(Path("tmp").glob("*.txt"))) if Path("tmp").exists() else 0 +if existing_count > 1: + print(f"Skip submission: found {existing_count} files in tmp (>1), continue processing") +else: + submit_tasks() + +# 6. Ждать, Пока В tmp Будет 100 Файлов Или Время Иссякнет +poll_interval = 1 +expected = 100 +tmp_dir = Path("tmp") +tasks_status = mem_scheduler.get_tasks_status() +mem_scheduler.print_tasks_status(tasks_status=tasks_status) +while ( + mem_scheduler.get_tasks_status()["remaining"] != 0 + or mem_scheduler.get_tasks_status()["running"] != 0 +): + count = len(list(tmp_dir.glob("*.txt"))) if tmp_dir.exists() else 0 + tasks_status = mem_scheduler.get_tasks_status() + mem_scheduler.print_tasks_status(tasks_status=tasks_status) + print(f"[Monitor] Files in tmp: {count}/{expected}") + sleep(poll_interval) +print(f"[Result] Final files in tmp: {len(list(tmp_dir.glob('*.txt')))})") + +# 7. Остановить Планировщик +sleep(20) +print("Stopping the scheduler...") +mem_scheduler.stop() +``` diff --git a/content/ru/open_source/modules/memories/general_textual_memory.md b/content/ru/open_source/modules/memories/general_textual_memory.md new file mode 100644 index 00000000..28c9a61b --- /dev/null +++ b/content/ru/open_source/modules/memories/general_textual_memory.md @@ -0,0 +1,156 @@ +--- +title: "GeneralTextMemory: Универсальная Память Текста" +desc: "`GeneralTextMemory` является гибким, векторным модулем памяти текста в MemOS, предназначенным для хранения, поиска и управления неструктурированными знаниями. Если модуль Naive — это 'совпадение ключевых слов', то GeneralTextMemory — это 'умный индекс, понимающий смысл', который подходит для систем, таких как разговорные агенты, персональные помощники и любые системы, требующие семантического поиска памяти." +## Содержание + +- [Структура Памяти](#структура-памяти) + - [Метаданные (`TextualMemoryMetadata`)](#метаданные-textualmemorymetadata) +- [Резюме API (`GeneralTextMemory`)](#резюме-api-generaltextmemory) + - [Инициализация](#инициализация) + - [Основные Методы](#основные-методы) +- [Хранение Файлов](#хранение-файлов) +- [Примеры Использования](#примеры-использования) +- [Расширения и Продвинутые Темы](#расширения-и-продвинутые-темы) + - [Поиск в Интернете](#поиск-в-интернете) + - [MultiModal Reader](#multimodal-reader) +- [Замечания для Разработчиков](#замечания-для-разработчиков) + + +## Структура Памяти + +Каждая память представлена как `TextualMemoryItem`: + +| Поле | Тип | Описание | +| ---------- | --------------------------- | ---------------------------------- | +| `id` | `str` | UUID (если пропущен, будет сгенерирован автоматически) | +| `memory` | `str` | Содержимое памяти (обязательно) | +| `metadata` | `TextualMemoryMetadata` | Метаданные (для поиска/фильтрации) | + +### Метаданные (`TextualMemoryMetadata`) + +| Поле | Тип | Описание | +| ------------- | -------------------------------------------------- | ----------------------------------- | +| `type` | `"procedure"`, `"fact"`, `"event"`, `"opinion"` | Тип памяти | +| `memory_time` | `str (YYYY-MM-DD)` | Дата/время, на которое ссылается память | +| `source` | `"conversation"`, `"retrieved"`, `"web"`, `"file"` | Источник памяти | +| `confidence` | `float (0-100)` | Оценка уверенности/достоверности | +| `entities` | `list[str]` | Основные сущности/концепции | +| `tags` | `list[str]` | Тематические теги | +| `visibility` | `"private"`, `"public"`, `"session"` | Область доступа | +| `updated_at` | `str` | Последняя метка времени обновления (ISO 8601) | + +Все значения проверяются, недопустимые значения вызовут ошибку. + +## Механизм Поиска + +В отличие от упомянутого ранее `NaiveTextMemory`, использующего **алгоритм совпадения ключевых слов**, `GeneralNaiveTextMemory` использует **векторный семантический поиск**. + +**Сравнение Характеристик Алгоритма с NaiveTextMemory** + +| Особенности | Совпадение ключевых слов | Векторный семантический поиск | +| -------------- | ---------------------------- | -------------------------------- | +| **Понимание Семантики** | ❌ Не Понимает Синонимы | ✅ Понимает Похожие Концепции | +| **Использование Ресурсов** | ✅ Очень Низкое | ⚠️ Требуется Встраивание Модели и Векторной Базы Данных | +| **Скорость Выполнения** | ✅ Быстро (O(n)) | ⚠️ Медленно (Построение Индекса + Запрос) | +| **Подходящий Масштаб** | < 1K Записей | 10K - 100K Записей | +| **Предсказуемость** | ✅ Результаты Интуитивно Понятны | ⚠️ Черный Ящик Модели | + +## API Резюме (`GeneralTextMemory`) + +### Инициализация +```python +GeneralTextMemory(config: GeneralTextMemoryConfig) +``` + +### Основные Методы +| Метод | Описание | +| ------------------------ | --------------------------------------------------- | +| `extract(messages)` | Извлечение Памяти Из Списка Сообщений (На Основе LLM) | +| `add(memories)` | Добавление Одной Или Нескольких Записей (Элементы Или Словари) | +| `search(query, top_k)` | Поиск Top-K Записей С Использованием Векторной Схожести | +| `get(memory_id)` | Получение Одной Записи По ID | +| `get_by_ids(ids)` | Получение Нескольких Записей По ID | +| `get_all()` | Возврат Всех Записей | +| `update(memory_id, new)` | Обновление Одной Записи По ID | +| `delete(ids)` | Удаление Записей По ID | +| `delete_all()` | Удалить Все Память | +| `dump(dir)` | Сериализовать Все Память В JSON Файл В Каталоге | +| `load(dir)` | Загрузить Память Из Сохраненного Файла | + +## Хранение Файлов + +При вызове `dump(dir)`, система сохранит память в: + +``` +/ +``` + +Этот файл содержит список JSON всех записей памяти, который можно перезагрузить с помощью `load(dir)`. + +## Примеры Использования + +```python +import os +from memos.configs.memory import MemoryConfigFactory +from memos.memories.factory import MemoryFactory + +config = MemoryConfigFactory( + backend="general_text", + config={ + "extractor_llm": { ... }, + "vector_db": { ... }, + "embedder": { ... }, + }, +) +m = MemoryFactory.from_config(config) + +# Извлечение И Добавление Памяти +memories = m.extract([ + {"role": "user", "content": "I love tomatoes."}, + {"role": "assistant", "content": "Great! Tomatoes are delicious."}, +]) +m.add(memories) + +# Создать И Добавить Память Вручную По ID +memory_id = "xxx" +m.add( + [ + { + "id": memory_id, + "memory": "User is Chinese.", + ... + } + ] +) + +# Поиск Памяти +results = m.search("Tell me more about the user", top_k=2) + +# Обновление Памяти +m.update(memory_id, {"memory": "User is Canadian.", ...}) + +# Удаление Памяти +m.delete([memory_id]) + +# Сериализовать Все Память В JSON Файл В Каталоге/Загрузить Память Из Сохраненного Файла +m.dump("tmp/mem") +m.load("tmp/mem") +``` + +::note +**Расширение: Поиск в Интернете**
+GeneralTextMemory может использоваться в сочетании с поиском в Интернете для извлечения контента с веб-страниц и добавления его в библиотеку памяти.
+Смотрите пример: [Извлечение Памяти из Интернета](./tree_textual_memory#извлечение-памяти-из-интернета-опционально) +:: + +::note +**Продвинутое: Использование MultiModal Reader**
+Если необходимо обрабатывать многомодальный контент, такой как изображения, URL, файлы и т.д., можно использовать `MultiModalStructMemReader`.
+Смотрите полный пример: [Использование MultiModalStructMemReader](./tree_textual_memory#использование-multimodalstructmemreader-продвинутый) +:: + +## Замечания для Разработчиков + +* Используйте Qdrant (или совместимую) векторную БД для быстрого поиска по сходству +* Модели встраивания и извлечения настраиваемы (поддержка olama/OpenAI) +* Интеграционные тесты в `/tests` охватывают все методы. diff --git a/content/ru/open_source/modules/memories/kv_cache_memory.md b/content/ru/open_source/modules/memories/kv_cache_memory.md new file mode 100644 index 00000000..f9c2b3f9 --- /dev/null +++ b/content/ru/open_source/modules/memories/kv_cache_memory.md @@ -0,0 +1,518 @@ +--- +title: "KVCacheMemory: Активная Память" +desc: "`KVCacheMemory` является специализированным модулем памяти в MemOS, предназначенным для хранения и управления KV cache, в основном используемым для ускорения вывода больших языковых моделей (LLMs) и поддержки эффективного повторного использования контекста. В качестве активной памяти он помогает улучшить производительность систем искусственного интеллекта для диалогов и генерации." + +## Примеры Использования KV Cache Памяти + +В MemOS KV Cache лучше всего подходит для хранения **семантически стабильной и часто повторно используемой фоновой информации**, например: +- Часто задаваемые вопросы (FAQs) или специализированные знания +- Предыдущая история диалогов + +Эти стабильные **открытые элементы памяти** автоматически распознаются и управляются модулем `MemScheduler`. Как только они выбраны, они заранее преобразуются в представление в формате KV (`KVCacheItem`). Этот шаг предварительного вычисления хранит активное состояние памяти в формате, пригодном для повторного использования (тензор пар ключ-значение), что позволяет им быть внедренными в кэш внимания модели во время вывода. + +Как только преобразование выполнено, эта KV память может **повторно использоваться между запросами**, без необходимости повторного кодирования оригинального содержимого. Это снижает вычислительные затраты на обработку и хранение большого объема текста, что делает его идеальным выбором для приложений, требующих **быстрого времени отклика** и **высокой пропускной способности**. + +## Почему KV Cache Память +Интеграция `MemScheduler` с KV Cache памятью может привести к значительной оптимизации производительности, особенно на этапе **предварительного заполнения** вывода LLM. + +### Без KV Cache Памяти + +- Каждый новый запрос добавляется в полный шаблон подсказки, включая фоновое знание. +- Модель должна **пересчитывать встраивания токенов и внимание** на всей последовательности — даже для неизмененной памяти. + +### С KV Cache Памятью + +- Фоновое знание **кэшируется один раз** в виде тензора пар ключ-значение. +- Для каждого запроса кодируется только новый ввод пользователя (токен запроса). +- Ранее кэшированные KV напрямую внедряются в механизм внимания. + +### Преимущества + +Это разделение уменьшает избыточные вычисления на этапе предварительного заполнения, что приводит к: + +- Пропуску повторного кодирования фонового знания +- Более быстрому вычислению внимания между токенами запроса и кэшированной памятью +- **Снижению времени до первого токена (Time To First Token, TTFT)** в процессе генерации + +Эта оптимизация особенно ценна в следующих аспектах: + +- Многораундные взаимодействия с чат-ботами +- Генерация с улучшением поиска или контекстная генерация (RAG, CAG) +- Ассистенты, работающие с фиксированными документами или памятью в стиле FAQ + + +### Оценка Ускорения KV Cache Памяти + +Чтобы проверить влияние инъекции памяти на основе KV на производительность, мы провели серию контрольных экспериментов, имитирующих реальное повторное использование памяти в MemOS. + +#### Установка Эксперимента + +В типичном использовании модуль `MemScheduler` постоянно отслеживает модели взаимодействия и поднимает высокочастотную, стабильную открытую память до формата KV. Эта KV память загружается в кэш активов GPU и повторно используется в процессе вывода. + +Оценка сравнивает две стратегии памяти: + +1. **Инъекция на основе подсказки**: Фоновое знание добавляется в виде оригинального текста +2. **Инъекция KV Cache**: Память напрямую внедряется в кэш внимания модели + +Мы протестировали эти стратегии: + +- **Три длины текста**: Короткий текст, текст средней длины и длинный текст +- **Три типа запросов**: Короткие запросы, средние запросы и длинные запросы + +Основным показателем является **время до первого токена (TTFT)**, что является ключевым показателем задержки для реактивной генерации. + +#### Результаты Эксперимента + +В таблице ниже представлены результаты для трех моделей (Qwen3-8B, Qwen3-32B, Qwen2.5-72B). TTFT при инъекции KV Cache всегда ниже, чем при инъекции на основе подсказки, в то время как выходные токены для обеих стратегий остаются согласованными. + +::note{icon="ri:bnb-fill"} +`Build (s)` относится к одноразовым затратам на предварительную обработку памяти в формат KV, распределенным на несколько запросов. +:: + +| Model | Ctx | CtxTok | Qry | QryTok | Build (s) | KV TTFT (s) | Dir TTFT (s) | Speedup (%) | +| ----------- | ------ | ------ | ------ | ------ | --------- | ----------- | ------------ | ----------- | +| Qwen3-8B | long | 6064 | long | 952.7 | 0.92 | 0.50 | 2.37 | 79.1 | +| | | | medium | 302.7 | 0.93 | 0.19 | 2.16 | 91.1 | +| | | | short | 167 | 0.93 | 0.12 | 2.04 | 94.2 | +| | medium | 2773 | long | 952.7 | 0.41 | 0.43 | 1.22 | 64.6 | +| | | | medium | 302.7 | 0.41 | 0.16 | 1.08 | 85.1 | +| | | | short | 167 | 0.43 | 0.10 | 0.95 | 89.7 | +| | short | 583 | long | 952.7 | 0.12 | 0.39 | 0.51 | 23.0 | +| | | | medium | 302.7 | 0.12 | 0.14 | 0.32 | 55.6 | +| | | | short | 167 | 0.12 | 0.08 | 0.29 | 71.3 | +| Qwen3-32B | long | 6064 | long | 952.7 | 0.71 | 0.31 | 1.09 | 71.4 | +| | | | medium | 302.7 | 0.71 | 0.15 | 0.98 | 84.3 | +| | | | short | 167 | 0.71 | 0.11 | 0.96 | 88.8 | +| | medium | 2773 | long | 952.7 | 0.31 | 0.24 | 0.56 | 56.9 | +| | | | medium | 302.7 | 0.31 | 0.12 | 0.47 | 75.1 | +| | | | short | 167 | 0.31 | 0.08 | 0.44 | 81.2 | +| | short | 583 | long | 952.7 | 0.09 | 0.20 | 0.24 | 18.6 | +| | | | medium | 302.7 | 0.09 | 0.09 | 0.15 | 39.6 | +| | | | short | 167 | 0.09 | 0.07 | 0.14 | 53.5 | +| Qwen2.5-72B | long | 6064 | long | 952.7 | 1.26 | 0.48 | 2.04 | 76.4 | +| | | | medium | 302.7 | 1.26 | 0.23 | 1.82 | 87.2 | +| | | | short | 167 | 1.27 | 0.15 | 1.79 | 91.4 | +| | medium | 2773 | long | 952.7 | 0.58 | 0.39 | 1.05 | 62.7 | +| | | | medium | 302.7 | 0.58 | 0.18 | 0.89 | 79.2 | +| | | | short | 167 | 0.71 | 0.23 | 0.82 | 71.6 | +| | short | 583 | long | 952.7 | 0.16 | 0.33 | 0.43 | 23.8 | +| | | | medium | 302.7 | 0.16 | 0.15 | 0.27 | 43.2 | +| | | | short | 167 | 0.16 | 0.10 | 0.25 | 60.5 | + + +#### Производительность на основе vLLM + +MemOS теперь поддерживает управление активной памятью с помощью vLLM. Чтобы оценить влияние предзагрузки различных длин префиксного текста в KV Cache, мы провели тестирование производительности на системе с 8 `H800 80GB GPU (112 vCPU, 1920 GiB памяти)` и на системе с 8 `RTX4090-24G-PCIe (112 vCPU, 960 GiB памяти)`. Оценка охватывала две текущие основные модели: Qwen3-32B и Qwen2.5-72B. + +Бенчмаркинг проводился в сочетаниях различных длин памяти и контекста, чтобы смоделировать различные сценарии активной памяти: +- **Длина текстовой памяти (токены)**: 500, 1000, 2000 +- **Длина контекстного текста (токены)**: 500, 1000, 2000, 4000 + +В следующей таблице подведены итоги результатов бенчмаркинга. + +**Qwen2.5-72B** +- On 4090(2 Nodes 16 GPUs) + +| mem tks | prompt tks | TTFT (without cache, ms) | TTFT (With cache, ms) | TTFT Speedup (%) | Abs Dis(ms) | +| ------- | ---------- | ------------------------ | --------------------- | ---------------- | ----------- | +| 0.5k | 0.5k | 1787.21 | 851.47 | 52.358% | 935.74 | +| 0.5k | 1k | 2506.26 | 1290.68 | 48.502% | 1215.58 | +| 0.5k | 2k | 3843.48 | 2897.97 | 24.600% | 945.51 | +| 0.5k | 4k | 6078.01 | 5200.86 | 14.432% | 877.15 | +| 1k | 0.5k | 2274.61 | 920.16 | 59.546% | 1354.45 | +| 1k | 1k | 2907.17 | 1407.65 | 51.580% | 1499.52 | +| 1k | 2k | 4278.53 | 2916.47 | 31.835% | 1362.06 | +| 1k | 4k | 6897.99 | 5218.94 | 24.341% | 1679.05 | +| 2k | 0.5k | 3460.12 | 782.73 | 77.379% | 2677.39 | +| 2k | 1k | 4443.34 | 1491.24 | 66.439% | 2952.10 | +| 2k | 2k | 5733.14 | 2758.48 | 51.885% | 2974.66 | +| 2k | 4k | 8152.76 | 5627.41 | 30.975% | 2525.35 | + + +- On H800(4 GPUs) + +| mem tks | prompt tks | TTFT (without cache, ms) | TTFT (With cache, ms) | TTFT Speedup (%) | Abs Dis(ms) | +| ------- | ---------- | ------------------------ | --------------------- | ---------------- | ----------- | +| 0.5k | 0.5k | 51.65 | 52.17 | -1.007% | -0.52 | +| 0.5k | 1k | 55.70 | 57.03 | -2.388% | -1.33 | +| 0.5k | 2k | 74.23 | 78.56 | -5.833% | -4.33 | +| 0.5k | 4k | 77.56 | 77.45 | 0.142% | 0.11 | +| 1k | 0.5k | 55.90 | 55.73 | 0.304% | 0.17 | +| 1k | 1k | 55.35 | 52.89 | 4.444% | 2.46 | +| 1k | 2k | 80.14 | 73.82 | 7.886% | 6.32 | +| 1k | 4k | 82.83 | 73.51 | 11.252% | 9.32 | +| 2k | 0.5k | 75.82 | 71.31 | 5.948% | 4.51 | +| 2k | 1k | 80.60 | 78.71 | 2.345% | 1.89 | +| 2k | 2k | 83.91 | 78.60 | 6.328% | 5.31 | +| 2k | 4k | 99.15 | 80.12 | 19.193% | 19.03 | + +**Qwen3-32B** + +- On 4090(1 Nodes 8 GPUs) + +| mem tks | prompt tks | TTFT (without cache, ms) | TTFT (With cache, ms) | TTFT Speedup (%) | Abs Dis(ms) | +| ------- | ---------- | ------------------------ | --------------------- | ---------------- | ----------- | +| 0.5k | 0.5k | 288.72 | 139.29 | 51.756% | 149.43 | +| 0.5k | 1k | 428.72 | 245.85 | 42.655% | 182.87 | +| 0.5k | 2k | 683.65 | 538.59 | 21.218% | 145.06 | +| 0.5k | 4k | 1170.48 | 986.94 | 15.681% | 183.54 | +| 1k | 0.5k | 409.83 | 137.96 | 66.337% | 271.87 | +| 1k | 1k | 507.95 | 262.21 | 48.379% | 245.74 | +| 1k | 2k | 743.48 | 539.71 | 27.408% | 203.77 | +| 1k | 4k | 1325.34 | 1038.59 | 21.636% | 286.75 | +| 2k | 0.5k | 686.01 | 147.34 | 78.522% | 538.67 | +| 2k | 1k | 762.96 | 246.22 | 67.728% | 516.74 | +| 2k | 2k | 1083.93 | 498.05 | 54.051% | 585.88 | +| 2k | 4k | 1435.39 | 1053.31 | 26.619% | 382.08 | + + +- On H800(2 GPUs) + +| mem tks | prompt tks | TTFT (without cache, ms) | TTFT (With cache, ms) | TTFT Speedup (%) | Abs Dis(ms) | +| ------- | ---------- | ------------------------ | --------------------- | ---------------- | ----------- | +| 0.5k | 0.5k | 161.18 | 97.61 | 39.440% | 63.57 | +| 0.5k | 1k | 164.00 | 121.39 | 25.982% | 42.61 | +| 0.5k | 2k | 257.34 | 215.20 | 16.375% | 42.14 | +| 0.5k | 4k | 365.14 | 317.95 | 12.924% | 47.19 | +| 1k | 0.5k | 169.45 | 100.52 | 40.679% | 68.93 | +| 1k | 1k | 180.91 | 128.25 | 29.108% | 52.66 | +| 1k | 2k | 271.69 | 210.00 | 22.706% | 61.69 | +| 1k | 4k | 389.30 | 314.64 | 19.178% | 74.66 | +| 2k | 0.5k | 251.43 | 130.92 | 47.930% | 120.51 | +| 2k | 1k | 275.81 | 159.60 | 42.134% | 116.21 | +| 2k | 2k | 331.11 | 218.17 | 34.110% | 112.94 | +| 2k | 4k | 451.06 | 334.80 | 25.775% | 116.26 | + + +Результаты ясно показывают, что интеграция функции повторного использования KV Cache с vLLM принесла революционное улучшение производительности для MemOS. + +## Структура памяти KV Cache + +Реализовано повторное использование памяти на основе KV с помощью `KVCacheMemory`, что значительно уменьшает размер модели и задержку между типами запросов, сохраняя при этом одинаковый вывод. Перемещая повторно используемую память из открытых подсказок в заранее вычисленный KV Cache, MemOS устраняет избыточное кодирование контекста и обеспечивает более быстрое время отклика, особенно в реальных приложениях LLM с улучшенной памятью. + +Каждый кэш хранится как `KVCacheItem`: + +| Поле | Тип | Описание | +| ------------- | -------------- | ------------------------------------------- | +| `kv_cache_id` | `str` | Уникальный ID в кэше (UUID) | +| `kv_cache` | `DynamicCache` | Фактический KV Cache (transformers) | +| `metadata` | `dict` | Метаданные (источник, время извлечения и т.д.) | + + +## API Резюме (`KVCacheMemory`) + +### Инициализация +```python +KVCacheMemory(config: KVCacheMemoryConfig) +``` + +### Основные методы +| Метод | Описание | +| ------------------------ | -------------------------------------------------------- | +| `extract(text)` | Извлечение KV Cache из входного текста с использованием LLM | +| `add(memories)` | Добавление одного или нескольких `KVCacheItem` в память | +| `get(memory_id)` | Получение одного кэша по ID | +| `get_by_ids(ids)` | Получение нескольких кэшей по IDs | +| `get_all()` | Возвращает все сохраненные кэши | +| `get_cache(cache_ids)` | Объединение и возврат комбинированного кэша из нескольких IDs | +| `delete(ids)` | Удаление кэша по IDs | +| `delete_all()` | Удаление всех кэшей | +| `dump(dir)` | Сериализация всех кэшей в файлы pickle в директории | +| `load(dir)` | Загружает кэш из файла pickle в каталоге | +| `from_textual_memory(mem)` | Преобразует `TextualMemoryItem` в `KVCacheItem` | + + +При вызове `dump(dir)`, система записывает в: + +``` +/ +``` + +Этот файл содержит словарь pickle для всех KV Cache, который можно перезагрузить с помощью `load(dir)`. + + +## Как использовать + +### HF KVCache Memory + +```python +import json + +from transformers import DynamicCache + +from memos.configs.memory import MemoryConfigFactory +from memos.memories.activation.item import KVCacheItem +from memos.memories.factory import MemoryFactory + + +def get_cache_info(cache): + if not cache: + return None + + num_layers = 0 + total_size_bytes = 0 + + if hasattr(cache, "layers"): + num_layers = len(cache.layers) + for layer in cache.layers: + if hasattr(layer, "key_cache") and layer.key_cache is not None: + total_size_bytes += layer.key_cache.nelement() * layer.key_cache.element_size() + if hasattr(layer, "value_cache") and layer.value_cache is not None: + total_size_bytes += layer.value_cache.nelement() * layer.value_cache.element_size() + + if hasattr(layer, "keys") and layer.keys is not None: + total_size_bytes += layer.keys.nelement() * layer.keys.element_size() + if hasattr(layer, "values") and layer.values is not None: + total_size_bytes += layer.values.nelement() * layer.values.element_size() + + elif hasattr(cache, "key_cache") and hasattr(cache, "value_cache"): + num_layers = len(cache.key_cache) + for k, v in zip(cache.key_cache, cache.value_cache, strict=False): + if k is not None: + total_size_bytes += k.nelement() * k.element_size() + if v is not None: + total_size_bytes += v.nelement() * v.element_size() + + return { + "num_layers": num_layers, + "size_bytes": total_size_bytes, + "size_mb": f"{total_size_bytes / (1024 * 1024):.2f} MB", + } + + +def serialize_item(obj): + if isinstance(obj, list): + return [serialize_item(x) for x in obj] + + if isinstance(obj, KVCacheItem): + return { + "id": obj.id, + "metadata": obj.metadata, + "records": obj.records.model_dump() + if hasattr(obj.records, "model_dump") + else obj.records, + "memory": get_cache_info(obj.memory), + } + + if isinstance(obj, DynamicCache): + return get_cache_info(obj) + + return str(obj) + + +if __name__ == "__main__": + # ===== Пример: Использование фабрики и HFLLM для создания и управления KVCacheMemory ===== + + # 1. Создание конфигурации KVCacheMemory (с использованием бэкенда HuggingFace) + config = MemoryConfigFactory( + backend="kv_cache", + config={ + "extractor_llm": { + "backend": "huggingface", + "config": { + "model_name_or_path": "Qwen/Qwen3-0.6B", # Используйте действительное имя модели HuggingFace + "max_tokens": 32, + "add_generation_prompt": True, + "remove_think_prefix": True, + }, + }, + }, + ) + + # 2. Использование фабрики для инстанцирования KVCacheMemory + kv_mem = MemoryFactory.from_config(config) + + # 3. Извлечение KVCacheItem (DynamicCache) из подсказки (внутреннее использование HFLLM.build_kv_cache) + prompt = [ + {"role": "user", "content": "What is MemOS?"}, + {"role": "assistant", "content": "MemOS is a memory operating system for LLMs."}, + ] + print("===== Extract KVCacheItem =====") + cache_item = kv_mem.extract(prompt) + print(json.dumps(serialize_item(cache_item), indent=2, default=str)) + print() + + # 4. Добавление извлеченного KVCacheItem + print("===== Add KVCacheItem =====") + kv_mem.add([cache_item]) + print(json.dumps(serialize_item(kv_mem.get_all()), indent=2, default=str)) + print() + + # 5. Получение по ID + print("===== Get KVCacheItem by id =====") + retrieved = kv_mem.get(cache_item.id) + print(json.dumps(serialize_item(retrieved), indent=2, default=str)) + print() + + # 6. Слияние кэшей (используя два элемента для имитации) + print("===== Merge DynamicCache =====") + item2 = kv_mem.extract([{"role": "user", "content": "Tell me a joke."}]) + kv_mem.add([item2]) + merged_cache = kv_mem.get_cache([cache_item.id, item2.id]) + print(json.dumps(serialize_item(merged_cache), indent=2, default=str)) + print() + + # 7. Удаление одного + print("===== Delete one KVCacheItem =====") + kv_mem.delete([cache_item.id]) + print(json.dumps(serialize_item(kv_mem.get_all()), indent=2, default=str)) + print() + + # 8. Сброс и загрузка + print("===== Dump and Load KVCacheMemory =====") + kv_mem.dump("tmp/kv_mem") + print("Memory dumped to 'tmp/kv_mem'.") + kv_mem.delete_all() + kv_mem.load("tmp/kv_mem") + print( + "Memory loaded from 'tmp/kv_mem':", + json.dumps(serialize_item(kv_mem.get_all()), indent=2, default=str), + ) +``` + +### VLLM KVCache Memory + +```python +#!/usr/bin/env python3 +""" +Демонстрация примера использования VLLMKVCacheMemory с бэкендом vLLM. +Этот пример демонстрирует, как использовать новую совместимую с vLLM память кэша KV. +""" + +from memos.configs.memory import MemoryConfigFactory +from memos.memories.factory import MemoryFactory + + +def main(): + """Главная функция, демонстрирующая использование VLLMKVCacheMemory.""" + + print("=== VLLM KV Cache Memory Example ===\n") + + # 1. Создание VLLMKVCacheMemory Конфигурации (Используя vLLM Бэкенд) + config = MemoryConfigFactory( + backend="vllm_kv_cache", # Используя Новый vLLM KV Cache Бэкенд + config={ + "extractor_llm": { + "backend": "vllm", + "config": { + "model_name_or_path": "Qwen/Qwen3-0.6B", + "api_base": "http://localhost:8088/v1", + "temperature": 0.7, + "max_tokens": 1024, + "model_schema": "memos.configs.llm.VLLMLLMConfig", + }, + }, + }, + ) + + # 2. Использование Фабрики Для Инстанцирования VLLMKVCacheMemory + print("Initializing VLLM KV Cache Memory...") + vllm_kv_mem = MemoryFactory.from_config(config) + print("✓ VLLM KV Cache Memory initialized successfully.\n") + + # 3. Извлечение VLLMKVCacheItem Из Подсказки + print("===== Extract VLLMKVCacheItem =====") + system_prompt = [ + {"role": "system", "content": "You are a helpful AI assistant."}, + {"role": "user", "content": "What is MemOS?"}, + {"role": "assistant", "content": "MemOS is a memory operating system for LLMs."}, + ] + + try: + cache_item = vllm_kv_mem.extract(system_prompt) + print("✓ KV cache item extracted successfully") + print(f" ID: {cache_item.id}") + print(f" Memory (prompt): {cache_item.memory[:100]}...") + print(f" Metadata: {cache_item.metadata}") + print() + except Exception as e: + print(f"✗ Failed to extract KV cache item: {e}") + return + + # 4. Добавление Извлеченного VLLMKVCacheItem + print("===== Add VLLMKVCacheItem =====") + vllm_kv_mem.add([cache_item]) + all_items = vllm_kv_mem.get_all() + print(f"✓ Added cache item. Total items: {len(all_items)}") + print() + + # 5. Получение по ID + print("===== Get VLLMKVCacheItem by id =====") + retrieved = vllm_kv_mem.get(cache_item.id) + if retrieved: + print(f"✓ Retrieved cache item: {retrieved.id}") + print(f" Memory (prompt): {retrieved.memory[:100]}...") + else: + print("✗ Failed to retrieve cache item") + print() + + # 6. Получение Кэша (Возвращает Подсказку Строку vLLM) + print("===== Get Cache (Prompt String) =====") + prompt_string = vllm_kv_mem.get_cache([cache_item.id]) + if prompt_string: + print(f"✓ Retrieved prompt string: {prompt_string[:100]}...") + print(" This prompt can be used for vLLM generation with preloaded KV cache") + else: + print("✗ Failed to retrieve prompt string") + print() + + # 7. Извлечение Другого Кэш-Элемента Для Демонстрации + print("===== Extract Another VLLMKVCacheItem =====") + another_prompt = [ + {"role": "system", "content": "You are a coding assistant."}, + {"role": "user", "content": "Write a Python function to calculate fibonacci numbers."}, + ] + + try: + cache_item2 = vllm_kv_mem.extract(another_prompt) + vllm_kv_mem.add([cache_item2]) + print(f"✓ Added second cache item. Total items: {len(vllm_kv_mem.get_all())}") + print() + except Exception as e: + print(f"✗ Failed to extract second KV cache item: {e}") + print() + + # 8. Предварительная Загрузка KV Cache На Сервере vLLM + print("===== Preload KV Cache on vLLM Server =====") + try: + vllm_kv_mem.preload_kv_cache([cache_item.id, cache_item2.id]) + print("✓ KV cache preloaded on vLLM server successfully") + print(" The server now has the KV cache ready for fast generation") + except Exception as e: + print(f"✗ Failed to preload KV cache: {e}") + print() + + # 9. Удаление Одного Элемента + print("===== Delete One VLLMKVCacheItem =====") + vllm_kv_mem.delete([cache_item.id]) + remaining_items = vllm_kv_mem.get_all() + print(f"✓ Deleted cache item. Remaining items: {len(remaining_items)}") + print() + + # 10. Дамп И Загрузка + print("===== Dump and Load VLLMKVCacheMemory =====") + try: + vllm_kv_mem.dump("tmp/vllm_kv_mem") + print("✓ Memory dumped to 'tmp/vllm_kv_mem'") + + # Очистка Памяти И Повторная Загрузка + vllm_kv_mem.delete_all() + vllm_kv_mem.load("tmp/vllm_kv_mem") + reloaded_items = vllm_kv_mem.get_all() + print(f"✓ Memory loaded from 'tmp/vllm_kv_mem': {len(reloaded_items)} items") + except Exception as e: + print(f"✗ Failed to dump/load memory: {e}") + print() + + print("=== Example completed successfully ===") + + +if __name__ == "__main__": + main() +``` + +## Важные замечания для разработчиков + +* Используйте HuggingFace `DynamicCache` для эффективного хранения ключей и значений +* Сериализация на основе pickle для быстрой загрузки/сохранения +* Интеграционные тесты в `/tests` охватывают все методы. diff --git a/content/ru/open_source/modules/memories/naive_textual_memory.md b/content/ru/open_source/modules/memories/naive_textual_memory.md new file mode 100644 index 00000000..1a44e371 --- /dev/null +++ b/content/ru/open_source/modules/memories/naive_textual_memory.md @@ -0,0 +1,508 @@ +--- +title: "NaiveTextMemory: Простой Текстовый Запоминающий Модуль" +desc: "Наиболее легковесный модуль памяти в MemOS, специально разработанный для быстрого прототипирования и простых сценариев. Не требует векторной базы данных, быстрое извлечение с использованием сопоставления ключевых слов. Давайте начнем использовать систему памяти MemOS самым простым способом! +`NaiveTextMemory` — это текстовый запоминающий модуль, основанный на памяти, который хранит память в списке в памяти и использует сопоставление ключевых слов для извлечения. Это лучшая отправная точка для изучения MemOS и подходит для демонстраций, тестирования и небольших приложений. + +--- + +## Содержание + +- [Что Вы Узнаете](#что-вы-узнаете) +- [Почему Выбирают NaiveTextMemory](#почему-выбирают-naivetextmemory) +- [Основные Концепции](#основные-концепции) + - [Структура Памяти](#структура-памяти) + - [Поля Метаданных](#поля-метаданных-textualmemorymetadata) + - [Механизм Поиска](#механизм-поиска) +- [Справочник API](#справочник-api) + - [Инициализация](#инициализация) + - [Основные Методы](#основные-методы) + - [Параметры Конфигурации](#параметры-конфигурации) +- [Практическое Занятие](#практическое-занятие) + - [Быстрый Старт](#быстрый-старт) + - [Полный Пример](#полный-пример) + - [Хранение Файлов](#хранение-файлов) +- [Руководство по Сценариям Использования](#руководство-по-сценариям-использования) +- [Сравнение с Другими Модулями Памяти](#сравнение-с-другими-модулями-памяти) +- [Лучшие Практики](#лучшие-практики) +- [Следующий Шаг](#следующий-шаг) + +## Что Вы Узнаете + +В конце этого руководства вы сможете: +- Использовать LLM для автоматического извлечения структурированной памяти из диалогов +- Хранить и управлять памятью в памяти (без базы данных) +- Искать память с использованием сопоставления ключевых слов +- Сохранять и восстанавливать данные памяти +- Понять, когда использовать NaiveTextMemory и когда переходить на другие модули + +## Почему Выбирают NaiveTextMemory + +### Преимущества + +::list{icon="ph:check-circle-duotone"} +- **Нулевая Зависимость**: Не требует векторной базы данных или моделей встраивания +- **Быстрый Запуск**: Несколько строк кода для запуска +- **Легковесный и Эффективный**: Низкое потребление ресурсов, высокая скорость выполнения +- **Простой и Интуитивный**: Сопоставление ключевых слов, предсказуемые результаты +- **Легко Отлаживать**: Вся память хранится в памяти, удобно просматривать +- **Идеальная Отправная Точка**: Лучший выбор для изучения MemOS +:: + +### Подходящие Сценарии + +::list{icon="ph:lightbulb-duotone"} +- Быстрое прототипирование и проверка концепции +- Простые диалоговые агенты (количество памяти < 1000 записей) +- Тестовые и демонстрационные сценарии +- Ограниченные ресурсы (нельзя запускать модели встраивания) +- Сценарии поиска по ключевым словам (запросы совпадают с памятью) +:: + +::note +**Совет по Производительности**
+Когда количество памяти превышает 1000 записей, рекомендуется перейти на [GeneralTextMemory](/open_source/modules/memories/general_textual_memory), который использует векторный поиск и обеспечивает лучшую производительность. +:: + + +## Основные Концепции + +### Структура Памяти + +Каждая память представлена как объект `TextualMemoryItem`, содержащий следующие поля: + +| Поле | Тип | Обязательное | Описание | +| ---------- | --------------------------- | ---- | ----------------------------- | +| `id` | `str` | ✗ | Уникальный Идентификатор (Автоматически Генерируемый UUID) | +| `memory` | `str` | ✓ | Основное Текстовое Содержимое Памяти | +| `metadata` | `TextualMemoryMetadata` | ✗ | Метаданные (Для Классификации, Фильтрации и Поиска) | + +### Метаданные Поля (`TextualMemoryMetadata`) + +Метаданные предоставляют богатую контекстную информацию для классификации, фильтрации и организации памяти: + +| Поле | Тип | Значение По Умолчанию | Описание | +| ------------- | -------------------------------------------------- | ---------- | ------------------------------ | +| `type` | `"procedure"` / `"fact"` / `"event"` / `"opinion"` | `"fact"` | Классификация Типа Памяти | +| `memory_time` | `str (YYYY-MM-DD)` | Текущая Дата | Время, Связанное с Памятью | +| `source` | `"conversation"` / `"retrieved"` / `"web"` / `"file"` | - | Источник Памяти | +| `confidence` | `float (0-100)` | 80.0 | Оценка Уверенности/Достоверности | +| `entities` | `list[str]` | `[]` | Упомянутые Сущности или Концепции | +| `tags` | `list[str]` | `[]` | Тематические Теги | +| `visibility` | `"private"` / `"public"` / `"session"` | `"private"` | Область Контроля Доступа | +| `updated_at` | `str` | Автоматически | Последняя Метка Времени Обновления (ISO 8601) | + +## Справочник API + +### Инициализация + +```python +from memos.memories.textual.naive import NaiveTextMemory +from memos.configs.memory import NaiveTextMemoryConfig + +memory = NaiveTextMemory(config: NaiveTextMemoryConfig) +``` + +### Основные Методы + +| Метод | Параметр | Возвращаемое Значение | Описание | +| ------------------------ | ------------------------------------- | ----------------------------- | -------------------------------------- | +| `extract(messages)` | `messages: list[dict]` | `list[TextualMemoryItem]` | Использует LLM для извлечения структурированной памяти из диалога | +| `add(memories)` | `memories: list / dict / Item` | `None` | Добавляет одну или несколько записей памяти | +| `search(query, top_k)` | `query: str, top_k: int` | `list[TextualMemoryItem]` | Поиск по ключевым словам, возвращает top-k записей памяти | +| `get(memory_id)` | `memory_id: str` | `TextualMemoryItem` | Получает одну запись памяти по ID | +| `get_by_ids(ids)` | `ids: list[str]` | `list[TextualMemoryItem]` | Пакетное получение записей памяти по списку ID | +| `get_all()` | - | `list[TextualMemoryItem]` | Возвращает все записи памяти | +| `update(memory_id, new)` | `memory_id: str, new: dict` | `None` | Обновляет содержимое или метаданные указанной записи памяти | +| `delete(ids)` | `ids: list[str]` | `None` | Удаляет одну или несколько записей памяти | +| `delete_all()` | - | `None` | Очищает все записи памяти | +| `dump(dir)` | `dir: str` | `None` | Сериализует память в файл JSON для сохранения | +| `load(dir)` | `dir: str` | `None` | Загружает память из файла JSON | + +### Механизм Поиска + +`NaiveTextMemory` использует **алгоритм сопоставления ключевых слов**: + +::steps{} + +#### Шаг 1: Токенизация +Разделите запрос и каждое содержимое памяти на списки слов + +#### Шаг 2: Вычисление Степени Совпадения +Подсчитайте количество пересечений между запросом и словами памяти + +#### Шаг 3: Сортировка +Отсортируйте всю память по убыванию количества совпадающих слов + +#### Шаг 4: Возврат Результатов +Возьмите первые top-k записей памяти в качестве результатов поиска + +:: + + + +::note +**Сравнение Примеров**
+Запрос: "котенок"
+- **Сопоставление Ключевых Слов**: Совпадает только с памятью, содержащей "кот" и "котенок"
+- **Семантический Поиск**: Также может совпадать с памятью, связанной с "домашними животными", "маленькими котами", "мяуками" и т.д. (позже мы изучим это в статье о "Общей Текстовой Памяти") +:: + +### Параметры Конфигурации + +**NaiveTextMemoryConfig** + +| Параметр | Тип | Обязательный | Значение по умолчанию | Описание | +| ------------------ | ---------------------- | ---- | ---------------------- | ------------------------------------------ | +| `extractor_llm` | `LLMConfigFactory` | ✓ | - | Конфигурация LLM для извлечения памяти из диалога | +| `memory_filename` | `str` | ✗ | `textual_memory.json` | Имя файла для постоянного хранения | + +**Пример Конфигурации** + +```json +{ + "backend": "naive_text", + "config": { + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o-mini", + "temperature": 0.8, + "max_tokens": 1024, + "api_base": "xxx", + "api_key": "sk-xxx" + } + }, + "memory_filename": "my_memories.json" + } +} +``` + +## Практическое Занятие + +### Быстрый Старт + +Всего 3 шага, чтобы начать использовать NaiveTextMemory: + +::steps{} + +#### Шаг 1: Создание Конфигурации + +```python +from memos.configs.memory import MemoryConfigFactory + +config = MemoryConfigFactory( + backend="naive_text", + config={ + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o-mini", + "api_key": "your-api-key", + "api_base": "your-api-base" + }, + }, + }, +) +``` + +#### Шаг 2: Инициализация Модуля Памяти + +```python +from memos.memories.factory import MemoryFactory + +memory = MemoryFactory.from_config(config) +``` + +#### Шаг 3: Извлечение и Добавление Памяти + +```python +# Автоматическое извлечение памяти из диалога +memories = memory.extract([ + {"role": "user", "content": "I love tomatoes."}, + {"role": "assistant", "content": "Great! Tomatoes are delicious."}, +]) + +# Добавить в хранилище памяти +memory.add(memories) +print(f"✓ Добавлено {len(memories)} записей памяти") +``` + +::alert{type="info"} +**Продвинутый: Использование MultiModal Reader**
+Если необходимо обрабатывать изображения, URL, файлы и другие мультимодальные содержимое, можно использовать `MultiModalStructMemReader`.
+Смотрите полный пример: [Использование MultiModalStructMemReader](./tree_textual_memory#使用-multimodalstructmemreader高级) +:: + +:: + +### Полный пример + +Ниже приведен полный пример от начала до конца, демонстрирующий все основные функции: + +```python +from memos.configs.memory import MemoryConfigFactory +from memos.memories.factory import MemoryFactory + +# ======================================== +# 1. Инициализация +# ======================================== +config = MemoryConfigFactory( + backend="naive_text", + config={ + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o-mini", + "api_key": "your-api-key", + }, + }, + }, +) +memory = MemoryFactory.from_config(config) + +# ======================================== +# 2. Извлечение и добавление памяти +# ======================================== +memories = memory.extract([ + {"role": "user", "content": "I love tomatoes."}, + {"role": "assistant", "content": "Great! Tomatoes are delicious."}, +]) +memory.add(memories) +print(f"✓ Добавлено {len(memories)} записей памяти") + +# ======================================== +# 3. Поиск памяти +# ======================================== +results = memory.search("tomatoes", top_k=2) +print(f"\n🔍 Найдено {len(results)} связанных записей памяти:") +for i, item in enumerate(results, 1): + print(f" {i}. {item.memory}") + +# ======================================== +# 4. Получить все записи памяти +# ======================================== +all_memories = memory.get_all() +print(f"\n📊 Всего {len(all_memories)} записей памяти") + +# ======================================== +# 5. Обновить память +# ======================================== +if memories: + memory_id = memories[0].id + memory.update( + memory_id, + { + "memory": "User loves tomatoes.", + "metadata": {"type": "opinion", "confidence": 95.0} + } + ) + print(f"\n✓ Память обновлена: {memory_id}") + +# ======================================== +# 6. Персистентное Хранение +# ======================================== +memory.dump("tmp/mem") +print("\n💾 Память сохранена в tmp/mem/textual_memory.json") + +# ======================================== +# 7. Загрузка Памяти +# ======================================== +memory.load("tmp/mem") +print("✓ Память загружена из файла") + +# ======================================== +# 8. Удаление Памяти +# ======================================== +if memories: + memory.delete([memories[0].id]) + print(f"\n🗑️ Удалено 1 запись памяти") + +# Удалить Все Памяти +# memory.delete_all() +``` + +::note +**Расширение: Поиск в Интернете**
+NaiveTextMemory сосредоточен на управлении локальной памятью. Если вам нужно извлекать информацию из Интернета и добавлять в память, смотрите:
+[Извлечение памяти из Интернета](./tree_textual_memory#从互联网检索记忆可选) +:: + +### Хранение файлов + +При вызове `dump(dir)` система сохранит память в: + +``` +/ +``` + +Этот файл содержит список всех записей памяти в формате JSON, который можно использовать для повторной загрузки с помощью `load(dir)`. + +**Структура файла по умолчанию** + +```json +[ + { + "id": "550e8400-e29b-41d4-a716-446655440000", + "memory": "User loves tomatoes.", + "metadata": { + "type": "opinion", + "confidence": 95.0, + "entities": ["user", "tomatoes"], + "tags": ["food", "preference"], + "updated_at": "2026-01-14T10:30:00Z" + } + }, + ... +] +``` + +Используя `load(dir)`, можно полностью восстановить все данные памяти. + +::note +**Важное замечание**
+Память хранится в оперативной памяти и будет потеряна после перезапуска процесса. Пожалуйста, регулярно вызывайте `dump()`, чтобы сохранить данные! +:: +## Руководство по сценариям использования + +### Наилучшие сценарии + +::list{icon="ph:check-circle-duotone"} +- **Быстрая разработка прототипов**: не требует настройки векторной базы данных, можно запустить за несколько минут +- **Простой диалоговый агент**: небольшие приложения с количеством записей памяти < 1000 +- **Тестирование и демонстрация**: быстрая проверка логики извлечения и поиска памяти +- **Ограниченные ресурсы**: сценарии, в которых невозможно запустить модели встраивания или векторные базы данных +- **Поиск по ключевым словам**: сценарии, в которых содержимое запроса напрямую соответствует тексту памяти +- **Обучение и преподавание**: лучший старт для понимания системы памяти MemOS +:: + +### Не рекомендуемые сценарии + +::list{icon="ph:x-circle-duotone"} +- **Масштабные приложения**: более 10,000 записей памяти (производительность поиска ухудшается) +- **Требования к семантическому поиску**: необходимо понимать синонимы (например, "кот" и "домашнее животное") +- **Производственная среда**: строгие требования к производительности и точности +- **Многоязычные сценарии**: требуется понимание семантики между языками +- **Сложное логическое рассуждение**: необходимо понимать взаимосвязи между записями памяти +:: + +::alert{type="info"} +**Путь к обновлению**
+Для вышеупомянутых не рекомендуемых сценариев рекомендуется обновиться до: +- [GeneralTextMemory](/open_source/modules/memories/general_textual_memory) - Векторный Семантический Поиск, Подходит для 10K-100K Записей Памяти +- [TreeTextMemory](/open_source/modules/memories/tree_textual_memory) - Хранение в Структуре Дерева, Поддерживает Реляционное Выведение и Многошаговые Запросы +:: + +## Сравнение с другими модулями памяти + +Выбор подходящего модуля памяти имеет решающее значение для успеха проекта. Следующее сравнение поможет вам принять решение: + +| Характеристика | **NaiveTextMemory** | **GeneralTextMemory** | **TreeTextMemory** | +| -------------- | --------------------- | -------------------------- | --------------------------- | +| **Способ Поиска** | Совпадение Ключевых Слов | Векторный Семантический Поиск | Структура Дерева + Векторный Поиск | +| **Зависимые Компоненты** | Только LLM | LLM + Встраиватель + Векторная База Данных | LLM + Встраиватель + База Данных Дерева | +| **Подходящий Масштаб** | < 1K Записей | 1K - 100K Записей | 10K - 1M Записей | +| **Сложность Запроса** | O(n) Линейный Сканирование | O(log n) Приблизительный Ближайший Сосед | O(log n) + Обход Дерева | +| **Семантическое Понимание** | ❌ | ✅ | ✅ | +| **Отношенческое Вывод** | ❌ | ❌ | ✅ | +| **Многоступенчатый Запрос** | ❌ | ❌ | ✅ | +| **Хранилище** | Список Памяти | Векторная База Данных (Qdrant и др.) | Графовая База Данных (Neo4j/PolarDB) | +| **Сложность Настройки** | Низкая ⭐ | Средняя ⭐⭐ | Высокая ⭐⭐⭐ | +| **Кривая Обучения** | Очень Простая | Умеренная | Довольно Крутая | +| **Готовность К Производству** | ❌ Только Прототип/Демонстрация | ✅ Подходит Для Большинства Сценариев | ✅ Подходит Для Сложных Приложений | + +::alert{type="success"} +**Рекомендации По Выбору**
+- **Только начинаете учиться?** → Начните с NaiveTextMemory
+- **Нужен семантический поиск?** → Используйте GeneralTextMemory
+- **Нужны логические выводы?** → Выберите TreeTextMemory +:: + +## Лучшие практики + +Следуйте этим рекомендациям, чтобы максимально использовать преимущества NaiveTextMemory: + +::steps{} + +### 1. Регулярно сохраняйте данные + +```python +# Сохраняйте Немедленно После Ключевых Операций +memory.add(new_memories) +memory.dump("tmp/mem") # ✓ Немедленная Персистенция + +# Регулярное Автоматическое Резервное Копирование +import schedule +schedule.every(10).minutes.do(lambda: memory.dump("tmp/mem")) +``` + +### 2. Контролируйте объем памяти + +```python +# Регулярная Очистка Старой Памяти +if len(memory.get_all()) > 1000: + old_memories = sorted( + memory.get_all(), + key=lambda m: m.metadata.updated_at + )[:100] # Самые Старые 100 Записей + + memory.delete([m.id for m in old_memories]) + print("✓ Очистили 100 Старых Записей") +``` + +### 3. Оптимизируйте поисковые запросы + +```python +# ❌ Плохо: Неопределенный Запрос +results = memory.search("东西", top_k=5) + +# ✅ Хорошо: Используйте Конкретные Ключевые Слова +results = memory.search("番茄 西红柿", top_k=5) +``` + +### 4. Разумно используйте метаданные + +```python +# Установите Четкие Метаданные При Добавлении Памяти +memory.add({ + "memory": "User prefers dark mode", + "metadata": { + "type": "opinion", # ✓ Ясная Категоризация + "tags": ["UI", "preference"], # ✓ Удобно Для Фильтрации + "confidence": 90.0, # ✓ Уровень Достоверности + "entities": ["user", "dark mode"] # ✓ Обозначение Сущностей + } +}) +``` + +### 5. Планируйте путь к обновлению + +```python +# Мониторинг Количества Памяти, Своевременное Обновление +memory_count = len(memory.get_all()) +if memory_count > 800: + print("⚠️ Количество Памяти Близко К Пределу, Рекомендуется Обновиться До GeneralTextMemory") + # Пример Кода Для Миграции: + # 1. Экспортируйте Существующую Память: memory.dump("backup") + # 2. Создайте Конфигурацию GeneralTextMemory + # 3. Импортируйте Память В Новый Модуль +``` + +:: + + +## Следующий шаг + +Поздравляем! Вы уже освоили основные способы использования NaiveTextMemory. Далее вы можете: + +::list{icon="ph:arrow-right-duotone"} +- **Обновиться до векторного поиска**: изучите семантические возможности [GeneralTextMemory](/open_source/modules/memories/general_textual_memory) +- **Изучить графовую структуру**: узнайте о функциях логического вывода [TreeTextMemory](/open_source/modules/memories/tree_textual_memory) +- **Интегрировать в приложение**: смотрите [Полную документацию API](/api-reference/search-memories) для создания приложений уровня производства +- **Запустить пример кода**: просмотрите каталог `/examples/` для получения дополнительных практических примеров +- **Узнать о графовых базах данных**: если вам нужны расширенные функции, изучите [Neo4j](/open_source/modules/memories/neo4j_graph_db) или [PolarDB](/open_source/modules/memories/polardb_graph_db) +:: + +::alert{type="success"} +**Совет**
+NaiveTextMemory является идеальной отправной точкой для изучения MemOS. Когда вашему приложению понадобятся более мощные функции, вы сможете без проблем перейти на другие модули памяти! +:: diff --git a/content/ru/open_source/modules/memories/nebula_graph_db.md b/content/ru/open_source/modules/memories/nebula_graph_db.md new file mode 100644 index 00000000..dfc38515 --- /dev/null +++ b/content/ru/open_source/modules/memories/nebula_graph_db.md @@ -0,0 +1,126 @@ +--- +title: Основанный На NebulaGraph Явный Мемориальный Бэкенд +desc: "Этот модуль предоставляет возможности хранения и запроса мемориальной графовой базы данных на основе NebulaGraph для систем усиления памяти (таких как RAG, когнитивные агенты или персональные помощники). Унаследованный от `BaseGraphDB`, поддерживает многопользовательскую изоляцию, структурированный поиск, внешние векторные индексы и другие возможности, подходит для построения и вывода больших графов." +--- + +## Почему Выбирают NebulaGraph? + +* Подходит для масштабируемого распределенного развертывания +* Поддерживает гибкое определение меток и атрибутов для вершин и рёбер +* Поддерживает векторные индексы (начиная с Nebula 5) + + +## Рекомендуемая Конфигурация Шаблона + +Подходит для производственных сценариев, совместим с логической изоляцией многопользовательской среды: + +```json +"graph_db": { + "backend": "nebular", + "config": { + "uri": ["localhost:9669"], + "user": "root", + "password": "your_password", + "space": "database_name", + "user_name": "user_name", + "use_multi_db": false, + "auto_create": true, + "embedding_dimension": 1024 + } +} +``` + +* `space`: Название графового пространства Nebula, эквивалентно базе данных +* `user_name`: Для логической изоляции многопользователей (автоматически внедряет условия фильтрации) +* `embedding_dimension`: Настройте в соответствии с вашей моделью встраивания (например, text-embedding-3-large равен 3072) +* `auto_create`: Автоматически создавать графовое пространство и схему (рекомендуется для тестовой среды) + + +## Модель Использования Многопользовательской Среды + +Бэкенд NebulaGraph поддерживает две архитектуры многопользовательской среды: + +### Много пользователей в одной базе данных (Shared DB + `user_name`) + +Подходит для нескольких пользователей/агентов, использующих одно графовое пространство, каждый пользователь использует логическую изоляцию: + +```python +GraphDBConfigFactory( + backend="nebular", + config={ + "space": "shared_graph", + "user_name": "alice", + "use_multi_db": False, + ... + }, +) +``` + +### Много Баз Данных (Multi DB, по одному пространству на пользователя) + +Подходит для сценариев с более сильной изоляцией ресурсов, каждый пользователь занимает одно графовое пространство (space): + +```python +GraphDBConfigFactory( + backend="nebular", + config={ + "space": "user_alice_graph", + "use_multi_db": True, + "auto_create": True, + ... + }, +) +``` + +## Пример Быстрого Использования + +```python +import os +import json +from memos.graph_dbs.factory import GraphStoreFactory +from memos.configs.graph_db import GraphDBConfigFactory + +config = GraphDBConfigFactory( + backend="nebular", + config={ + "uri": json.loads(os.getenv("NEBULAR_HOSTS", "localhost")), + "user": os.getenv("NEBULAR_USER", "root"), + "password": os.getenv("NEBULAR_PASSWORD", "xxxxxx"), + "space": os.getenv("space"), + "use_multi_db": True, + "auto_create": True, + "embedding_dimension": os.getenv("embedding_dimension", 1024), + }, + ) + +graph = GraphStoreFactory.from_config(config) + +topic = TextualMemoryItem( + memory="This research addresses long-term multi-UAV navigation for energy-efficient communication coverage.", + metadata=TreeNodeTextualMemoryMetadata( + memory_type="LongTermMemory", + key="Multi-UAV Long-Term Coverage", + hierarchy_level="topic", + type="fact", + memory_time="2024-01-01", + source="file", + sources=["paper://multi-uav-coverage/intro"], + status="activated", + confidence=95.0, + tags=["UAV", "coverage", "multi-agent"], + entities=["UAV", "coverage", "navigation"], + visibility="public", + updated_at=datetime.now().isoformat(), + embedding=embed_memory_item( + "This research addresses long-term " + "multi-UAV navigation for " + "energy-efficient communication " + "coverage." + ), + ), + ) + +graph.add_node( + id=topic.id, memory=topic.memory, metadata=topic.metadata.model_dump(exclude_none=True) +) +``` diff --git a/content/ru/open_source/modules/memories/neo4j_graph_db.md b/content/ru/open_source/modules/memories/neo4j_graph_db.md new file mode 100644 index 00000000..0b904671 --- /dev/null +++ b/content/ru/open_source/modules/memories/neo4j_graph_db.md @@ -0,0 +1,189 @@ +--- +title: Neo4j Графовая База Данных +desc: "Этот модуль предоставляет графовую структуру для хранения и запроса памяти для систем улучшения памяти (таких как RAG, когнитивные агенты или персональные помощники по памяти).
Он определяет чистый абстрактный класс(`BaseGraphDB`) и использует **Neo4j** для реализации, которая может быть использована в производственной среде." +--- + +## Почему Память Нуждается в Графовом Хранилище? + +В отличие от векторного хранилища, графовая база данных позволяет: + +- Организовывать память в **цепочки, иерархии и причинно-следственные связи** +- Выполнять **многошаговое рассуждение** и **обход подграфов** +- Поддерживать **удаление дубликатов, обнаружение конфликтов и планирование** памяти +- Динамически развивать графовую память со временем + +Это составляет основу для долгосрочного, объяснимого и составного рассуждения о памяти. + +## Особенности + +- Единый интерфейс для различных графовых баз данных +- Встроенная поддержка Neo4j +- Поддержка векторного улучшенного поиска(`search_by_embedding`) +- Модульный, заменяемый и тестируемый +- [v0.2.1 Новая Функция] Поддержка **многоарендной графовой архитектуры** (одна база данных для нескольких пользователей) +- [v0.2.1 Новая Функция] Совместимость с **Neo4j** Community Edition + +## Структура Каталога + +``` + +src/memos/graph_dbs/ +├── base.py # Абстрактный интерфейс BaseGraphDB +├── factory.py # Фабрика инстанцирует GraphDB из конфигурации +├── neo4j.py # Продуктовая реализация Neo4jGraphDB + +```` + +## Как Использовать + +```python +from memos.graph_dbs.factory import GraphStoreFactory +from memos.configs.graph_db import GraphDBConfigFactory + +# Шаг 1: Построение конфигурации фабрики +config = GraphDBConfigFactory( + backend="neo4j", + config={ + "uri": "bolt://localhost:7687", + "user": "your_neo4j_user_name", + "password": "your_password", + "db_name": "memory_user1", + "auto_create": True, + "embedding_dimension": 768 + } +) + +# Шаг 2: Инстанцирование графового хранилища +graph = GraphStoreFactory.from_config(config) + +# Шаг 3: Добавление памяти +graph.add_node( + id="node-001", + memory="Today I learned about retrieval-augmented generation.", + metadata={"type": "WorkingMemory", "tags": ["RAG", "AI"], "timestamp": "2025-06-05", "sources": []} +) + +```` + +## Заменяемый Дизайн + +### Интерфейс: `BaseGraphDB` + +```` +Описание функций: +1. Операции с узлами: +Вставка: add_node(Добавить один узел) + add_nodes_batch(Пакетное добавление узлов) +Запрос: get_node(Запрос одного узла) + get_nodes(Запрос нескольких узлов) + get_memory_count(Запрос количества узлов) + node_not_exist(Существует ли узел) + search_by_embedding(Поиск по вектору может добавлять условия фильтрации, для получения полного документации по методу см. функцию neo4j_example.example_complex_shared_db_search_filter) +Обновление: update_node(Обновление одного узла) +Удаление: delete_node(Удаление одного узла) + clear (Удалить все связанные узлы по user_name) + См. функцию neo4j_example.example_complex_shared_db_delete_memory для получения полного документации по методу + +2. Операции с ребрами +Вставка: add_edge(Добавление тройки памяти) +Запрос: get_edges(Запрос нескольких отношений) + edge_exists(Существует ли отношение) + get_children_with_embeddings(Запрос списка узлов типа PARENT) + get_subgraph(Запрос многошаговых узлов) +Удаление: delete_edge(Удаление отношения) + +3. Операции импорта и экспорта: + import_graph(Импортировать весь граф из сериализованного словаря, параметры включают словарь всех узлов и ребер для загрузки: {'nodes':[],'edges':[]}) + export_graph(Экспортировать все узлы и ребра графа в структурированном виде, поддерживает постраничный вывод) + +Смотрите src/memos/graph_dbs/base.py для получения полной документации по методам. +```` +### Текущий Бэкенд: + +| Бэкенд | Статус | Файл | +| ------- | ------ | ---------- | +| Neo4j | Stable | `neo4j.py` | + +## Одна База Данных для Многоарендности (Shared DB, Multi-Tenant) + +С помощью настройки поля `user_name`, MemOS поддерживает изоляцию графов памяти для нескольких пользователей в одной базе данных Neo4j, что подходит для совместных систем и сценариев с несколькими ролями: + +```python +config = GraphDBConfigFactory( + backend="neo4j", + config={ + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "your_password", + "db_name": "shared-graph", + "user_name": "alice", + "use_multi_db": false, + "embedding_dimension": 768, + }, +) +``` + +Данные каждого пользователя логически изолированы в чтении, записи, поиске и экспорте через поле `user_name`, система автоматически выполняет фильтрацию. + +::note +**Пример Ссылки**
+Не будем много говорить, все в коде `examples/basic_modules +/neo4j_example.example_complex_shared_db(db_name="shared-traval-group-complex-new")` +:: + +## Поддержка Neo4j Community Edition + +Новый идентификатор бэкенда: `neo4j-community` + +Способ использования аналогичен стандартному Neo4j, но автоматически отключает функции для предприятий: + +- ❌ Не поддерживает `auto_create` базу данных +- ❌ Не поддерживает нативные векторные индексы (необходимо использовать внешнюю векторную библиотеку, в настоящее время поддерживается только Qdrant) +- ✅ Принудительное включение логической изоляции `user_name` (Community Edition или `user_name` относится к одному бизнесу и не требует строгой изоляции) + +Пример конфигурации: + +```python +config = GraphDBConfigFactory( + backend="neo4j-community", + config={ + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "12345678", + "db_name": "paper", + "user_name": "bob", + "auto_create": False, + "embedding_dimension": 768, + "use_multi_db": False, + "vec_config": { + "backend": "qdrant", + "config": { + "host": "localhost", + "port": 6333, + "collection_name": "neo4j_vec_db", + "vector_dimension": 768, + "distance_metric": "cosine" + }, + }, + }, +) +``` + +::note +**Пример Ссылки**
`examples/basic_modules +/neo4j_example.example_complex_shared_db(db_name="paper", +community=True)` +:: + +## Расширение + +Вы можете добавить поддержку любых других графовых движков (например, **TigerGraph**, **DGraph**, **Weaviate hybrid**): + +1. Подкласс `BaseGraphDB` +2. Создайте класс данных конфигурации (например, `DgraphConfig`) +3. Зарегистрируйте его в: + + * `GraphDBConfigFactory.backend_to_class` + * `GraphStoreFactory.backend_to_class` + +Смотрите `src/memos/graph_dbs/neo4j.py` в качестве справочной реализации. diff --git a/content/ru/open_source/modules/memories/overview.md b/content/ru/open_source/modules/memories/overview.md new file mode 100644 index 00000000..8747fe7f --- /dev/null +++ b/content/ru/open_source/modules/memories/overview.md @@ -0,0 +1,243 @@ +--- +title: "Обзор Модулей Памяти" +desc: "Полное руководство по системе памяти MemOS - MemOS предлагает богатый выбор модулей памяти, удовлетворяющих различные потребности от легковесной текстовой памяти до сложных графовых структур. Это руководство поможет вам быстро найти наиболее подходящее решение для памяти." + +# Почему Нужны Разные Модули Памяти + +Модули памяти являются основными компонентами, которые наделяют Agent способностью "долговременной памяти". Они не просто жестко хранят и извлекают данные, как база данных, но могут автоматически извлекать, классифицировать, связывать и динамически обновлять информацию, как это делает человек. Выбор различных модулей памяти позволяет Agent обладать различными способностями. + +## 🎯 Быстрый Выбор Модуля + +::alert{type="info"} +**Не Уверены, Какой Выбрать?** Следуйте этому дереву решений: +- 🚀 **Быстрое Тестирование/Демонстрация: Легкий старт, не требуется дополнительное ПО** → [NaiveTextMemory](#naivetextmemory-简单明文记忆) +- 📝 **Универсальная Текстовая Память: Запоминание содержимого чата или большого количества документов с возможностью семантического поиска** → [GeneralTextMemory](#generaltextmemory-通用文本记忆) +- 👤 **Управление Предпочтениями Пользователя: Специально разработано для создания профиля пользователя** → [PreferenceTextMemory](#preferencetextmemory-偏好记忆) +- 🌳 **Структурированная Знаниевая Графика: Сложные логические связи между данными** → [TreeTextMemory](#treetextmemory-分层结构记忆) +- ⚡ **Ускорение Выводов: Высокая нагрузка, желаемая более плавная и быстрая реакция** → [KVCacheMemory](#kvcachememory-激活记忆) +:: + +--- + +## 📚 Классификация Модулей Памяти + +### I. Серия Текстовой Памяти + +Сосредоточена на хранении и извлечении памяти в текстовом формате, подходит для большинства сценариев применения. + +#### NaiveTextMemory: Простая Текстовая Память +::card +**Подходящие Сценарии:** Быстрая прототипизация, демонстрация, обучение, небольшие приложения + +**Ключевые Особенности:** +- ✅ Никаких зависимостей, чистое хранилище в памяти +- ✅ Поиск по ключевым словам +- ✅ Минимальный API, 5 минут на освоение +- ✅ Поддержка постоянного хранения файлов + +**Ограничения:** +- ❌ Нет векторного семантического поиска +- ❌ Не подходит для больших объемов данных +- ❌ Ограниченная точность поиска + +📖 [Посмотреть Документацию](./naive_textual_memory) +:: + +#### GeneralTextMemory: Универсальная Текстовая Память +::card +**Подходящие Сценарии:** Агент для общения, персональный помощник, система управления знаниями + +**Ключевые Особенности:** +- ✅ Семантический поиск на основе векторов +- ✅ Поддержка богатых метаданных (тип, время, источник и т.д.) +- ✅ Гибкая фильтрация и запросы +- ✅ Подходит для средних и крупных приложений + +**Технические Требования:** +- Требуется векторная база данных (например, Qdrant) +- Требуется модель встраивания + +📖 [Посмотреть Документацию](./general_textual_memory) +:: + +#### PreferenceTextMemory: Предпочтительная Память +::card +**Подходящие Сценарии:** Персонализированные рекомендации, профили пользователей, интеллектуальные помощники + +**Ключевые Особенности:** +- ✅ Автоматическое распознавание явных и неявных предпочтений +- ✅ Удаление дубликатов предпочтений и обнаружение конфликтов +- ✅ Фильтрация по типу и интенсивности предпочтений +- ✅ Семантический поиск по вектору + +**Специальные Функции:** +- Двойное извлечение предпочтений (явное/неявное) +- Оценка интенсивности предпочтений +- Поддержка временного затухания + +📖 [Посмотреть Документацию](./preference_textual_memory) +:: + +#### TreeTextMemory: Иерархическая Структурированная Память +::card +**Подходящие Сценарии:** Знаниевая графика, сложные логические выводы, многоуровневые запросы + +**Ключевые Особенности:** +- ✅ Структурированное хранилище на основе графовой базы данных +- ✅ Поддержка иерархических отношений и причинно-следственных цепей +- ✅ Возможности многоуровневого вывода +- ✅ Удаление дубликатов, обнаружение конфликтов, планирование памяти + +**Расширенные Функции:** +- Поддержка MultiModal Reader (изображения, URL, файлы) +- Поддержка интернет-поиска (BochaAI, Google, Bing) +- Механизм замены рабочей памяти + +**Технические Требования:** +- Требуется графовая база данных (например, Neo4j) +- Требуется векторная база данных и модель встраивания + +📖 [Посмотреть Документацию](./tree_textual_memory) +:: + +--- + +### II. Специальные Модули Памяти + +Системы памяти, оптимизированные для конкретных сценариев. + +#### KVCacheMemory: Активированная Память +::card +**Подходящие Сценарии:** Ускорение вывода LLM, повторное использование фоновых знаний с высокой частотой + +**Ключевые Особенности:** +- ⚡ Предварительно рассчитанный KV Cache, пропуск повторного кодирования +- ⚡ Значительное сокращение вычислений на этапе предварительного заполнения +- ⚡ Подходит для сценариев с высокой пропускной способностью + +**Типичные Примеры Использования:** +- Кэширование часто задаваемых вопросов (FAQ) +- Повторное использование истории диалогов +- Предварительная загрузка предметных знаний + +**Принцип Работы:** +Стабильная текстовая память → Предварительное преобразование в KV Cache → Прямое внедрение во время вывода + +📖 [Посмотреть Документацию](./kv_cache_memory) +:: + +#### ParametricMemory: Параметрическая Память +::card +**Статус:** 🚧 В разработке + +**Цели Проектирования:** +- Кодирование знаний в веса модели (LoRA, экспертные модули) +- Динамическая загрузка/выгрузка модулей возможностей +- Поддержка многозадачной и многопользовательской архитектуры + +**Будущие Функции:** +- Генерация и сжатие параметров модулей +- Контроль версий и откат +- Горячая замена модулей возможностей + +📖 [Посмотреть Документацию](./parametric_memory) +:: + +--- + +### Три, Бэкенд Графовой Базы Данных + +Обеспечивает графовое хранилище для TreeTextMemory. + +#### Neo4j Graph DB +::card +**Рейтинг:** ⭐⭐⭐⭐⭐ + +**Особенности:** +- Полный функционал графовой базы данных +- Поддержка векторного улучшенного поиска +- Многопользовательская архитектура (v0.2.1+) +- Совместимость с сообществом + +📖 [Посмотреть Документацию](./neo4j_graph_db) +:: + +#### Nebula Graph DB +::card +**Характеристики:** +- Распределенная графовая база данных +- Высокая доступность +- Подходит для масштабируемого развертывания + +📖 [Посмотреть Документацию](./nebula_graph_db) +:: + +#### PolarDB Graph DB +::card +**Характеристики:** +- Alibaba Cloud PolarDB графовые вычисления +- Облачная нативная архитектура +- Корпоративная надежность + +📖 [Посмотреть Документацию](./polardb_graph_db) +:: + +--- + +## 🛠️ Рекомендации по Сценариям Использования + +### Сценарий 1: Быстрая Прототипизация +**Рекомендуется:** [NaiveTextMemory](./naive_textual_memory) +```python +from memos.memories import NaiveTextMemory +memory = NaiveTextMemory() +memory.add("Пользователь любит пить кофе") +results = memory.search("кофе") +``` + +### Сценарий 2: Память Чат-бота +**Рекомендуется:** [GeneralTextMemory](./general_textual_memory) +- Поддержка семантического поиска +- Фильтрация по времени, типу, источнику +- Подходит для управления историей диалогов + +### Сценарий 3: Система Персонализированных Рекомендаций +**Рекомендуется:** [PreferenceTextMemory](./preference_textual_memory) +- Автоматическое извлечение предпочтений пользователей +- Обнаружение конфликтов предпочтений +- Оценка интенсивности и фильтрация + +### Сценарий 4: Применение Знаний Графов +**Рекомендуется:** [TreeTextMemory](./tree_textual_memory) +- Запросы многослойных отношений +- Управление иерархией +- Сложные сценарии вывода + +### Сценарий 5: Высокопроизводительные Услуги LLM +**Рекомендуется:** [KVCacheMemory](./kv_cache_memory) +- Система FAQ +- Чат-бот для обслуживания клиентов +- Обработка большого объема запросов + +--- + +## 🔗 Расширенные Функции + +### MultiModal Reader (Мультимодальное Чтение) +Поддержка обработки в TreeTextMemory: +- Изображения в диалогах +- URL веб-страниц +- Локальные файлы (PDF, DOCX, TXT, Markdown) +- Смешанный режим (текст + изображение + URL) + +👉 [Посмотреть пример](./tree_textual_memory#使用-multimodalstructmemreader高级) + +### Internet Retrieval (Интернет Поиск) +Получение актуальной информации из сети и добавление в память: +- Поиск BochaAI +- Поиск Google +- Поиск Bing + +👉 [Посмотреть Пример](./tree_textual_memory#из-интернета-поиск-памяти-опционально) + +--- diff --git a/content/ru/open_source/modules/memories/parametric_memory.md b/content/ru/open_source/modules/memories/parametric_memory.md new file mode 100644 index 00000000..55ca5804 --- /dev/null +++ b/content/ru/open_source/modules/memories/parametric_memory.md @@ -0,0 +1,44 @@ +--- +title: Параметрическая Память (В Разработке) +--- + +::note +**В Разработке** +Эта функция все еще активно разрабатывается, ожидайте обновлений! +:: + +`Параметрическая Память (Parametric Memory)` является核心ом **долгосрочных знаний и способностей** в архитектуре MemOS. В отличие от явной памяти или активной памяти, параметрическая память кодирует глубокое представление языковых структур, мировых знаний и общих способностей рассуждения, непосредственно встраивая их в веса модели. + +В дизайне архитектуры MemOS параметрическая память не ограничивается статическими предобученными весами; она также включает в себя **LoRA адаптеры** и модули экспертных плагинов, что позволяет вам постепенно расширять или настраивать способности LLM без необходимости повторной тренировки всей модели. + +Например, вы можете извлекать структурированные или фиксированные знания в параметрической форме, сохранять их как независимые **модули способностей (Capability Blocks)** и динамически загружать или выгружать их в процессе вывода. Это упрощает создание "экспертных подмоделей" для задач, таких как юридическое рассуждение, финансовый анализ или резюме в определенной области — и все это управляется MemOS. + +## Цели Дизайна + +::list{icon="ph:check-circle-duotone"} +- **Контролируемость** — поддержка генерации, загрузки, переключения или комбинирования параметрических модулей по мере необходимости. +- **Пластичность** — совместная эволюция с явной памятью и активной памятью; поддержка извлечения и отката знаний. +- **Прослеживаемость** *(в разработке)* — предоставление функций контроля версий и управления параметрическими модулями. +:: + +## Текущий Статус + +`Параметрическая Память (Parametric Memory)` в настоящее время все еще находится на стадии проектирования и верификации прототипа. Мы планируем выпустить API для генерации, сжатия и горячей замены параметрических модулей в будущих версиях, чтобы лучше поддерживать многозадачные, многопрофильные и многопользовательские архитектуры. + +Пожалуйста, следите за нашими обновлениями! + +## Связанные Модули + +Хотя параметрическая память находится в разработке, вы уже можете попробовать следующее: +- **[GeneralTextMemory](/open_source/modules/memories/general_textual_memory)**: Гибкое семантическое хранилище на основе векторов +- **[TreeTextMemory](/open_source/modules/memories/tree_textual_memory)**: Структурированное, иерархическое и графовое знание +- **[Activation Memory](/open_source/modules/memories/kv_cache_memory)**: Эффективный кэш состояния во время выполнения + +## Замечания для Разработчиков + +Параметрическая память дополнит видение MemOS о единой архитектуре **Memory³**: +- **Параметрическая Память**: внутренние и встроенные неявные знания +- **Активная Память**: кратковременное состояние во время выполнения +- **Явная Память**: структурированная, прослеживаемая явная внешняя память + +Органическое сочетание трех элементов создаст адаптивную, устойчиво эволюционирующую и объяснимую интеллектуальную систему. diff --git a/content/ru/open_source/modules/memories/polardb_graph_db.md b/content/ru/open_source/modules/memories/polardb_graph_db.md new file mode 100644 index 00000000..8874e49c --- /dev/null +++ b/content/ru/open_source/modules/memories/polardb_graph_db.md @@ -0,0 +1,461 @@ +--- +title: "PolarDB Графовая База Данных" +desc: "MemOS поддерживает использование **PolarDB** (основанной на расширении Apache AGE) в качестве графовой базы данных для хранения и извлечения данных о памяти в виде графов знаний. PolarDB сочетает в себе мощные возможности PostgreSQL и гибкость графовых баз данных, что делает его особенно подходящим для сценариев, требующих одновременного выполнения запросов к реляционным и графовым данным." +--- + +## Функциональные Особенности + +::list{icon="ph:check-circle-duotone"} +- Полные операции графовой базы данных: добавление, удаление, изменение и поиск узлов, управление ребрами +- Поиск векторных вложений: поддержка семантического поиска с индексом IVFFlat +- Управление пулом соединений: автоматическое управление соединениями с базой данных, поддержка высокой нагрузки +- Изоляция многопользовательского режима: поддержка физических и логических режимов изоляции +- Хранение атрибутов JSONB: гибкое хранение метаданных +- Пакетные операции: поддержка пакетной вставки узлов и ребер +- Автоматическая метка времени: автоматическое поддержание `created_at` и `updated_at` +- Защита от SQL-инъекций: встроенные параметризованные запросы и экранирование строк +:: + +## Структура Каталога + +``` +MemOS/ +└── src/ + └── memos/ + ├── configs/ + │ └── graph_db.py # PolarDBGraphDBConfig Конфигурационный Класс + └── graph_dbs/ + ├── base.py # BaseGraphDB Абстрактный Базовый Класс + ├── factory.py # GraphDBFactory Фабричный Класс + └── polardb.py # PolarDBGraphDB Реализация +``` + +## Быстрый Старт + +### 1. Установка Зависимостей + +```bash +# Установка psycopg2 Драйвера (выберите один из двух) +pip install psycopg2-binary # Рекомендуется: Предварительно Скомпилированная Версия +# Или +pip install psycopg2 # Требуется Библиотека Разработки PostgreSQL + +# Установка MemOS +pip install MemoryOS -U +``` + +### 2. Конфигурация PolarDB + +#### Способ 1: Использование Конфигурационного Файла (Рекомендуется) + +```json +{ + "graph_db_store": { + "backend": "polardb", + "config": { + "host": "localhost", + "port": 5432, + "user": "postgres", + "password": "your_password", + "db_name": "memos_db", + "user_name": "alice", + "use_multi_db": true, + "auto_create": false, + "embedding_dimension": 1024, + "maxconn": 100 + } + } +} +``` + +#### Способ 2: Инициализация Кода + +```python +from memos.configs.graph_db import PolarDBGraphDBConfig +from memos.graph_dbs.polardb import PolarDBGraphDB + +# Создание Конфигурации +config = PolarDBGraphDBConfig( + host="localhost", + port=5432, + user="postgres", + password="your_password", + db_name="memos_db", + user_name="alice", + use_multi_db=True, + embedding_dimension=1024, + maxconn=100 +) + +# Инициализация Базы Данных +graph_db = PolarDBGraphDB(config) +``` + +### 3. Примеры Основных Операций + +```python +# ======================================== +# Шаг 1: Добавление Узла +# ======================================== +node_id = graph_db.add_node( + label="Memory", + properties={ + "content": "Python является высокоуровневым языком программирования", + "memory_type": "Knowledge", + "tags": ["programming", "python"] + }, + embedding=[0.1, 0.2, 0.3, ...], # 1024-мерный Вектор + user_name="alice" +) +print(f"✓ Узел создан: {node_id}") + +# ======================================== +# Шаг 2: Обновление узла +# ======================================== +graph_db.update_node( + id=node_id, + fields={ + "content": "Python является интерпретируемым, объектно-ориентированным языком высокого уровня", + "updated": True + }, + user_name="alice" +) +print("✓ Узел обновлен") + +# ======================================== +# Шаг 3: Создание отношений +# ======================================== +# Сначала создайте второй узел +node_id_2 = graph_db.add_node( + label="Memory", + properties={ + "content": "Django является веб-фреймворком для Python", + "memory_type": "Knowledge" + }, + embedding=[0.15, 0.25, 0.35, ...], + user_name="alice" +) + +# Создание ребра +edge_id = graph_db.add_edge( + source_id=node_id, + target_id=node_id_2, + edge_type="RELATED_TO", + properties={ + "relationship": "Фреймворк и язык", + "confidence": 0.95 + }, + user_name="alice" +) +print(f"✓ Отношение создано: {edge_id}") + +# ======================================== +# Шаг 4: Поиск векторов +# ======================================== +query_embedding = [0.12, 0.22, 0.32, ...] # Вектор запроса + +results = graph_db.search_by_embedding( + embedding=query_embedding, + top_k=5, + memory_type="Knowledge", + user_name="alice" +) + +print(f"\n🔍 Найдено {len(results)} похожих узлов:") +for node in results: + print(f" - {node.get('content')} (Сходство: {node.get('score', 'N/A')})") + +# ======================================== +# Шаг 5: Удаление узла +# ======================================== +graph_db.delete_node(id=node_id, user_name="alice") +print(f"✓ Узел {node_id} Удален") +``` + +## Подробности Конфигурации + +### PolarDBGraphDBConfig Параметры Описание + +| Параметр | Тип | Значение По Умолчанию | Обязательный | Описание | +|------|------|--------|------|------| +| `host` | str | - | ✓ | Адрес хоста базы данных | +| `port` | int | 5432 | ✗ | Порт базы данных | +| `user` | str | - | ✓ | Имя пользователя базы данных | +| `password` | str | - | ✓ | Пароль базы данных | +| `db_name` | str | - | ✓ | Название целевой базы данных | +| `user_name` | str | None | ✗ | Идентификатор арендатора (для логической изоляции) | +| `use_multi_db` | bool | True | ✗ | Использовать ли физическую изоляцию нескольких баз данных | +| `auto_create` | bool | False | ✗ | Автоматически создавать базу данных | +| `embedding_dimension` | int | 1024 | ✗ | Размерность векторного встраивания | +| `maxconn` | int | 100 | ✗ | Максимальное количество соединений в пуле соединений | + +### Сравнение Режимов Многопользовательского Использования + +| Особенности | Физическая Изоляция
(`use_multi_db=True`) | Логическая Изоляция
(`use_multi_db=False`) | +|------|-----------------------------------|-------------------------------------| +| **Уровень Изоляции** | Уровень Базы Данных | Фильтрация По Меткам Уровня Приложения | +| **Требования К Конфигурации** | `db_name` Обычно Равно `user_name` | Необходимо Указать `user_name` | +| **Производительность** | Лучше (Независимые Ресурсы) | Удовлетворительно (Общие Ресурсы) | +| **Стоимость** | Высокая (Отдельная БД Для Каждого Арендатора) | Низкая (Общая База Данных) | +| **Сценарии Использования** | Корпоративные Клиенты, Высокие Требования К Безопасности | SaaS Мультиаренда, Разработка И Тестирование | +| **Миграция Данных** | Удобно (Экспорт Весь БД) | Необходимо Фильтровать По Меткам | + +### Примеры Конфигурации + +#### Пример 1: Физическая Изоляция (Рекомендуется для Корпоративной Версии) + +```json +{ + "graph_db_store": { + "backend": "polardb", + "config": { + "host": "prod-polardb.example.com", + "port": 5432, + "user": "admin", + "password": "secure_password", + "db_name": "customer_001", + "user_name": null, + "use_multi_db": true, + "auto_create": false, + "embedding_dimension": 1536, + "maxconn": 200 + } + } +} +``` + +#### Пример 2: Логическая Изоляция (Рекомендуется для SaaS) + +```json +{ + "graph_db_store": { + "backend": "polardb", + "config": { + "host": "shared-polardb.example.com", + "port": 5432, + "user": "app_user", + "password": "app_password", + "db_name": "shared_memos", + "user_name": "tenant_alice", + "use_multi_db": false, + "auto_create": false, + "embedding_dimension": 768, + "maxconn": 50 + } + } +} +``` + +## Расширенные Особенности + +### 1. Пакетная Вставка Узлов + +```python +# Пакетное Добавление Узлов (Высокая Производительность) +nodes_data = [ + { + "label": "Memory", + "properties": {"content": f"Узел {i}", "memory_type": "Test"}, + "embedding": [0.1 * i] * 1024, + } + for i in range(100) +] + +node_ids = graph_db.add_nodes_batch( + nodes=nodes_data, + user_name="alice" +) +print(f"✓ Пакетно Создано {len(node_ids)} Узлов") +``` + +### 2. Примеры Сложных Запросов + +```python +# Поиск Определенного Типа Памяти И Сортировка По Времени +def get_recent_memories(graph_db, memory_type, limit=10): + """Получить Недавние Узлы Памяти""" + query = f""" + SELECT * FROM "{graph_db.db_name}_graph"."Memory" + WHERE properties->>'memory_type' = %s + AND properties->>'user_name' = %s + ORDER BY updated_at DESC + LIMIT %s + """ + + conn = graph_db._get_connection() + try: + with conn.cursor() as cursor: + cursor.execute(query, [memory_type, "alice", limit]) + results = cursor.fetchall() + return results + finally: + graph_db._return_connection(conn) + +# Пример Использования +recent = get_recent_memories(graph_db, "WorkingMemory", limit=5) +print(f"Недавние 5 Рабочих Узлов Памяти: {len(recent)} Узлов") +``` + +### 3. Оптимизация Векторных Индексов + +```python +# Создание Или Обновление Векторного Индекса +graph_db.create_index( + label="Memory", + vector_property="embedding", + dimensions=1024, + index_name="memory_vector_index" +) +print("✓ Векторный Индекс Оптимизирован") +``` + +### 4. Мониторинг Пула Соединений + +```python +# Просмотр Состояния Пула Соединений (Только Для Отладки) +import logging +logging.basicConfig(level=logging.DEBUG) + +# Получение соединения будет выводить подробные логи +conn = graph_db._get_connection() +# [DEBUG] [_get_connection] Successfully acquired connection from pool +graph_db._return_connection(conn) +# [DEBUG] [_return_connection] Successfully returned connection to pool +``` + +## Интерфейс BaseGraphDB + +PolarDB реализует все методы абстрактного класса `BaseGraphDB`, обеспечивая совместимость с другими графовыми базами данных. + +### Основные Методы + +| Метод | Описание | Параметры | +|------|------|------| +| `add_node()` | Добавить один узел | label, properties, embedding, user_name | +| `add_nodes_batch()` | Пакетное добавление узлов | nodes, user_name | +| `update_node()` | Обновить свойства узла | id, fields, user_name | +| `delete_node()` | Удалить узел | id, user_name | +| `delete_node_by_params()` | Удалить узел по условиям | params, user_name | +| `add_edge()` | Создать связь | source_id, target_id, edge_type, properties, user_name | +| `update_edge()` | Обновить свойства связи | edge_id, properties, user_name | +| `delete_edge()` | Удалить связь | edge_id, user_name | +| `search_by_embedding()` | Поиск по векторному сходству | embedding, top_k, memory_type, user_name | +| `get_node()` | Получить один узел | id, user_name | +| `get_memory_count()` | Подсчет количества узлов | memory_type, user_name | +| `remove_oldest_memory()` | Очистить старую память | memory_type, keep_latest, user_name | + +### Примеры Полных Подписей Методов + +```python +from typing import Any + +# Добавить Узел +def add_node( + self, + label: str = "Memory", + properties: dict[str, Any] | None = None, + embedding: list[float] | None = None, + user_name: str | None = None +) -> str: + """Добавить новый узел в графовую базу данных""" + pass + +# Векторный Поиск +def search_by_embedding( + self, + embedding: list[float], + top_k: int = 10, + memory_type: str | None = None, + user_name: str | None = None, + filters: dict[str, Any] | None = None +) -> list[dict[str, Any]]: + """Поиск по сходству на основе векторных вложений""" + pass + +# Пакетные Операции +def add_nodes_batch( + self, + nodes: list[dict[str, Any]], + user_name: str | None = None +) -> list[str]: + """Пакетное добавление нескольких узлов""" + pass +``` + +## Руководство по Расширенной Разработке + +Если необходимо реализовать пользовательские функции на основе PolarDB, можно унаследовать класс `PolarDBGraphDB`: + +```python +from memos.graph_dbs.polardb import PolarDBGraphDB +from memos.configs.graph_db import PolarDBGraphDBConfig + +class CustomPolarDBGraphDB(PolarDBGraphDB): + """Пользовательская реализация PolarDB графовой базы данных""" + + def __init__(self, config: PolarDBGraphDBConfig): + super().__init__(config) + # Пользовательская Логика Инициализации + self.custom_index_created = False + + def create_custom_index(self): + """Создать пользовательский индекс""" + conn = self._get_connection() + try: + with conn.cursor() as cursor: + cursor.execute(f""" + CREATE INDEX IF NOT EXISTS idx_custom_field + ON "{self.db_name}_graph"."Memory" + ((properties->>'custom_field')); + """) + conn.commit() + self.custom_index_created = True + print("✓ Пользовательский индекс создан") + except Exception as e: + print(f"❌ Ошибка создания индекса: {e}") + conn.rollback() + finally: + self._return_connection(conn) + + def search_by_custom_field(self, field_value: str): + """Поиск по пользовательским полям""" + query = f""" + SELECT * FROM "{self.db_name}_graph"."Memory" + WHERE properties->>'custom_field' = %s + """ + + conn = self._get_connection() + try: + with conn.cursor() as cursor: + cursor.execute(query, [field_value]) + results = cursor.fetchall() + return results + finally: + self._return_connection(conn) + +# Использовать Пользовательскую Реализацию +config = PolarDBGraphDBConfig( + host="localhost", + port=5432, + user="postgres", + password="password", + db_name="custom_db" +) + +custom_db = CustomPolarDBGraphDB(config) +custom_db.create_custom_index() +results = custom_db.search_by_custom_field("special_value") +``` + +## Ресурсы для Справки + +- [Документация Apache AGE](https://age.apache.org/) +- [Документация по пулу соединений PostgreSQL](https://www.psycopg.org/docs/pool.html) +- [Документация PolarDB](https://www.alibabacloud.com/product/polardb) +- [Репозиторий MemOS на GitHub](https://github.com/MemOS-AI/MemOS) + +## Следующий Шаг + +- Узнать о использовании [Neo4j Графовой Базы Данных](./neo4j_graph_db.md) +- Посмотреть конфигурацию [Общей Текстовой Памяти](./general_textual_memory.md) +- Изучить расширенные особенности [Деревовидной Текстовой Памяти](./tree_textual_memory.md) diff --git a/content/ru/open_source/modules/memories/preference_textual_memory.md b/content/ru/open_source/modules/memories/preference_textual_memory.md new file mode 100644 index 00000000..24123cf1 --- /dev/null +++ b/content/ru/open_source/modules/memories/preference_textual_memory.md @@ -0,0 +1,226 @@ +--- +title: "PreferenceTextMemory: Хранение и Управление Явными Памятью Пользователя" +desc: "`PreferenceTextMemory` является модулем для хранения и управления явной памятью пользователя в MemOS. Он подходит для сценариев, где необходимо извлечение памяти на основе предпочтений пользователя." + +## Содержание + +- [Почему Нужна Память Предпочтений](#почему-нужна-память-предпочтений) + - [Преимущества и Характеристики](#преимущества-и-характеристики) + - [Сценарии Применения](#сценарии-применения) +- [Основные Концепции и Рабочий Процесс](#основные-концепции-и-рабочий-процесс) + - [Структура Памяти](#структура-памяти) + - [Поля Метаданных](#поля-метаданных) + - [Основной Рабочий Процесс](#основной-рабочий-процесс) +- [API Справка](#api-справка) + - [Инициализация](#инициализация) + - [Основные Методы](#основные-методы) + - [Хранение Файлов](#хранение-файлов) +- [Практическое Задание: С 0 до 1](#практическое-задание-с-0-до-1) + - [Создание Конфигурации PreferenceTextMemory](#создание-конфигурации-preferencetextmemory) + - [Инициализация PreferenceTextMemory](#инициализация-preferencetextmemory) + - [Извлечение Структурированной Памяти](#извлечение-структурированной-памяти) + - [Поиск Памяти](#поиск-памяти) + - [Резервное Копирование и Восстановление](#резервное-копирование-и-восстановление) + - [Полный Пример Кода](#полный-пример-кода) + + +## Почему Нужна Память Предпочтений + +### Преимущества и Характеристики + +::list{icon="ph:check-circle-duotone"} +- **Двойное Извлечение Предпочтений**: Автоматическое распознавание явных и неявных предпочтений +- **Семантическое Понимание**: Использование векторных вложений для понимания глубокого смысла предпочтений +- **Умное Удаление Дубликатов**: Автоматическое обнаружение и объединение повторяющихся или конфликтующих предпочтений +- **Точный Поиск**: Семантический поиск на основе векторной схожести +- **Постоянное Хранение**: Поддержка векторных баз данных (Qdrant/Milvus) +- **Масштабируемость**: Поддержка управления большими объемами данных предпочтений +- **Персонализированное Увеличение**: Поддержка независимых профилей предпочтений для каждого пользователя +:: + +### Сценарии Применения + +::list{icon="ph:lightbulb-duotone"} +- Персонализированные диалоговые агенты (запоминание предпочтений пользователя) +- Умные рекомендательные системы (рекомендации на основе предпочтений) +- Системы обслуживания клиентов (предоставление индивидуализированных услуг) +- Системы фильтрации контента (отбор контента на основе предпочтений) +- Системы помощи в обучении (адаптация к стилю обучения) +:: + +::alert{type="info"} + +В заключение, когда вам нужно создать систему, способную "запоминать" предпочтения пользователя и предоставлять персонализированные услуги на их основе, `PreferenceTextMemory` является лучшим выбором. +:: + +## Основные Концепции и Рабочий Процесс +### Структура Памяти + +В MemOS память предпочтений представлена как `PreferenceTextMemory`, каждый элемент памяти является `TextualMemoryItem`, хранящимся в базе данных Milvus. +- `id`: Уникальный ID памяти (если опущен, генерируется автоматически) +- `memory`: Основной текст +- `metadata`: Включает информацию о иерархии, вложениях, тегах, сущностях, источниках и состоянии + +Память предпочтений может быть разделена на явную и неявную память предпочтений: +- **Явная Память Предпочтений**: Предпочтения или антипатии, явно выраженные пользователем. **Примеры**: + - "Мне нравится темный режим" + - "Я не ем острое" + - "Пожалуйста, отвечайте кратко" + - "Я предпочитаю техническую документацию, а не видеоуроки" + +- **Неявная Память Предпочтений**: Предпочтения, выведенные из поведения пользователя и моделей диалога. **Примеры**: + - Пользователь всегда запрашивает примеры кода → Предпочтение практико-ориентированного обучения + - Пользователь часто запрашивает подробные объяснения → Предпочтение глубокого понимания + - Пользователь многократно упоминает экологические темы → Забота о устойчивом развитии + +::alert{type="success"} +**Умное Извлечение**
+`PreferenceTextMemory` использует LLM для автоматического извлечения явных и неявных предпочтений из диалога без необходимости ручной разметки! +:: + +### Метаданные Поля (`PreferenceTextualMemoryMetadata`) + +| Поле | Тип | Описание | +| ------------- | -------------------------------------------------- | ----------------------------------- | +| `preference_type` | `"explicit_preference"`, `"implicit_preference"` | Тип предпочтительной памяти, делится на явную и неявную предпочтительную память | +| `dialog_id` | `str` | Идентификатор диалога, используется для связи предпочтительной памяти с конкретным диалогом | +| `original_text` | `str` | Исходный текст, содержащий информацию о предпочтениях пользователя | +| `embedding` | `str` | Вектор встраивания, используемый для семантического поиска и извлечения | +| `preference` | `str` | Информация о предпочтениях пользователя | +| `create_at` | `str` | Временная метка создания (ISO 8601) | +| `mem_cube_id` | `str` | Идентификатор куба памяти, используется для связи предпочтительной памяти с конкретным кубом памяти | +| `score` | `float ` | Оценка схожести между предпочтительной памятью и запросом в результатах поиска | + +### Основной Рабочий Процесс + +Когда вы запускаете этот пример, ваш рабочий процесс будет: + +1. **Извлечение:** Использование LLM для извлечения структурированной памяти из исходного текста. + + +2. **Вложение:** Генерация векторных вложений для поиска по схожести. + + +3. **Хранение:** Сохранение памяти предпочтений в базе данных Milvus, одновременно обновляя поля метаданных. + + +4. **Поиск:** Запрос по векторной схожести, возвращающий наиболее релевантную память предпочтений. + +## API Справка + +### Инициализация + +```python +PreferenceTextMemory(config: PreferenceTextMemoryConfig) +``` + +### Основные Методы + +| Метод | Описание | +| --------------------------- | ----------------------------------------------------- | +| `get_memory(messages)` | Извлечение предпочтительной памяти из исходного диалога. | +| `search(query, top_k)` | Поиск top-k предпочтительной памяти с использованием схожести векторов. | +| `load(dir)` | Загрузка предпочтительной памяти из сохраненных файлов. | +| `dump(dir)` | Сериализация всех предпочтительных памяти в JSON-файлы в каталоге. | +| `add(memories)` | Пакетное добавление предпочтительных воспоминаний в базу данных Milvus. | +| `get_with_collection_name(collection_name, memory_id)` | Получение конкретного типа предпочтительных воспоминаний по имени коллекции и ID воспоминания. | +| `get_by_ids_with_collection_name(collection_name, memory_ids)` | Пакетное получение конкретного типа предпочтительных воспоминаний по имени коллекции и ID воспоминаний. | +| `get_all()` | Получение всех предпочтительных воспоминаний. | +| `get_memory_by_filter(filter)` | Получение предпочтительных воспоминаний по условиям фильтрации. | +| `delete(memory_ids)` | Удаление предпочтительных воспоминаний с указанными ID. | +| `delete_by_filter(filter)` | Удаление предпочтительных воспоминаний по условиям фильтрации. | +| `delete_with_collection_name(collection_name, memory_ids)` | Удаление всех предпочтительных воспоминаний с указанным именем коллекции и ID. | +| `delete_all()` | Удаление всех предпочтительных воспоминаний. | + + +### Хранение Файлов + +Когда вызывается `dump(dir)`, MemOS сериализует всю память предпочтений в JSON-файлы в указанной директории: +``` +/ +``` + +--- + +## Практическое Занятие: С 0 До 1 + +::steps{} + +### Создание Конфигурации PreferenceTextMemory +Определение: +- Ваша модель embedding (например, nomic-embed-text:latest), +- Ваш бэкенд базы данных Milvus, +- Извлекатель памяти (на основе LLM) (по желанию). + +```python +from memos.configs.memory import PreferenceTextMemoryConfig + +config = PreferenceTextMemoryConfig.from_json_file("examples/data/config/preference_config.json") +``` + +### Инициализация PreferenceTextMemory + +```python +from memos.memories.textual.preference import PreferenceTextMemory + +preference_memory = PreferenceTextMemory(config) +``` + +### Извлечение Структурированной Памяти + +Используйте извлекатель памяти для разбора диалогов, файлов или документов на несколько `TextualMemoryItem`. + +```python +scene_data = [[ + {"role": "user", "content": "Tell me about your childhood."}, + {"role": "assistant", "content": "I loved playing in the garden with my dog."} +]] + +memories = preference_memory.get_memory(scene_data, type="chat", info={"user_id": "1234"}) +preference_memory.add(memories) +``` + +### Поиск Памяти + +```python +results = preference_memory.search("Tell me more about the user", top_k=2) +``` + +### Резервное Копирование И Восстановление +Поддержка постоянного хранения предпочтительной памяти и возможность перезагрузки в любое время: +```python +preference_memory.dump("tmp/pref_memories") +preference_memory.load("tmp/pref_memories") +``` + +:: + +### Полный Пример Кода + +Этот пример объединяет все вышеперечисленные шаги, предоставляя полный процесс от начала до конца на примере Milvus — просто скопируйте и запустите! + +```python +from memos.configs.memory import PreferenceTextMemoryConfig +from memos.memories.textual.preference import PreferenceTextMemory + +# Создание PreferenceTextMemory +config = PreferenceTextMemoryConfig.from_json_file("examples/data/config/preference_config.json") + +preference_memory = PreferenceTextMemory(config) +preference_memory.delete_all() + +scene_data = [[ + {"role": "user", "content": "Tell me about your childhood."}, + {"role": "assistant", "content": "I loved playing in the garden with my dog."} +]] + +# Извлечение предпочтительных воспоминаний из исходного диалога и добавление в базу данных Milvus +memories = preference_memory.get_memory(scene_data, type="chat", info={"user_id": "1234"}) +preference_memory.add(memories) + +# Поиск воспоминаний +results = preference_memory.search("Tell me more about the user", top_k=2) + +# Персистентное хранение предпочтительных воспоминаний +preference_memory.dump("tmp/pref_memories") +``` diff --git a/content/ru/open_source/modules/memories/tree_textual_memory.md b/content/ru/open_source/modules/memories/tree_textual_memory.md new file mode 100644 index 00000000..b690d1b0 --- /dev/null +++ b/content/ru/open_source/modules/memories/tree_textual_memory.md @@ -0,0 +1,509 @@ +--- +title: "TreeTextMemory: Деревовидная Память" +desc: > + Давайте создадим вашу первую **графовую, деревовидную память** в MemOS! +
+ **TreeTextMemory** поддерживает структурированное организацию, связывание и извлечение памяти, сохраняя при этом богатую контекстную информацию и хорошую интерпретируемость. +
+ MemOS в настоящее время использует [Neo4j](/open_source/modules/memories/neo4j_graph_db) в качестве бэкенда и планирует поддерживать больше графовых баз данных в будущем. +--- + + + +## Содержание + +- [Что Вы Узнаете](#что-вы-узнаете) +- [Основные Концепции и Рабочий Процесс](#основные-концепции-и-рабочий-процесс) + - [Структура Памяти](#структура-памяти) + - [Поля Метаданных](#поля-метаданных-treenodetextualmemorymetadata) + - [Основной Рабочий Процесс](#основной-рабочий-процесс) +- [API Справка](#api-справка) +- [Практическое Задание: От 0 до 1](#практическое-задание-от-0-до-1) + - [Создание Конфигурации TreeTextMemory](#создание-конфигурации-treetextmemory) + - [Инициализация TreeTextMemory](#инициализация-treetextmemory) + - [Извлечение Структурированной Памяти](#извлечение-структурированной-памяти) + - [Поиск Памяти](#поиск-памяти) + - [Извлечение Памяти из Интернета (по желанию)](#извлечение-памяти-из-интернета-по-желанию) + - [Замена Рабочей Памяти](#замена-рабочей-памяти) + - [Резервное Копирование и Восстановление](#резервное-копирование-и-восстановление) + - [Полный Пример Кода](#полный-пример-кода) +- [Почему Выбирают TreeTextMemory](#почему-выбирают-treetextmemory) +- [Следующий Шаг](#следующий-шаг) + +## Что Вы Узнаете + +В конце этого руководства вы будете: +- Извлекать структурированную память из исходного текста или диалога +- Хранить их в графовой базе данных как **узлы** +- Связывать память в **иерархии** и семантические графы +- Использовать **векторное сходство + графовый обход** для поиска + +## Основные Концепции и Рабочий Процесс + +### Структура Памяти + +Каждый узел в `TreeTextMemory` является `TextualMemoryItem`: +- `id`: Уникальный ID памяти (если опущен, будет сгенерирован автоматически) +- `memory`: Основной текст +- `metadata`: Включает информацию о структуре, встраивания, метки, сущности, источник и состояние + +### Метаданные Поля (`TreeNodeTextualMemoryMetadata`) + +| Поле | Тип | Описание | +| --------------- |-------------------------------------------------------| ------------------------------------------ | +| `memory_type` | `"WorkingMemory"`, `"LongTermMemory"`, `"UserMemory"` | Классификация Жизненного Цикла | +| `status` | `"activated"`, `"archived"`, `"deleted"` | Статус Узла | +| `visibility` | `"private"`, `"public"`, `"session"` | Область Доступа | +| `sources` | `list[str]` | Список Источников (например: файлы, URL) | +| `source` | `"conversation"`, `"retrieved"`, `"web"`, `"file"` | Тип Исходного Источника | +| `confidence` | `float (0-100)` | Оценка Уверенности | +| `entities` | `list[str]` | Упомянутые Сущности или Концепции | +| `tags` | `list[str]` | Тематические Теги | +| `embedding` | `list[float]` | Поиск По Сходству На Основе Векторных Встраиваний | +| `created_at` | `str` | Временная Метка Создания (ISO 8601) | +| `updated_at` | `str` | Временная Метка Последнего Обновления (ISO 8601) | +| `usage` | `list[str]` | История Использования | +| `background` | `str` | Дополнительный Контекст | + + +::note +**Лучшие Практики**
+ Используйте значимые метки и контекст — они помогают организовать ваш граф для многопроходного вывода. +:: + +### Основной Рабочий Процесс + +Когда вы запускаете этот пример, ваш рабочий процесс будет: + +1. **Извлечение:** Используйте LLM для извлечения структурированной памяти из исходного текста. + + +2. **Встраивание:** Генерируйте векторные встраивания для поиска сходства. + + +3. **Хранение и Связывание:** Добавьте связанные узлы в графовую базу данных (Neo4j). + + +4. **Поиск:** Запросите по векторному сходству, затем разверните результаты по количеству переходов в графе. + + +::note +**Подсказка**
Связи в графе помогают извлекать контекст, который может быть упущен при чистом векторном поиске! +:: + +## API Справка + +### Инициализация + +```python +TreeTextMemory(config: TreeTextMemoryConfig) +``` + +### Основные Методы + +| Метод | Описание | +| --------------------------- | ----------------------------------------------------- | +| `add(memories)` | Добавить одну или несколько память (элементов или словарей) | +| `replace_working_memory()` | Заменить все узлы WorkingMemory | +| `get_working_memory()` | Получить все узлы WorkingMemory | +| `search(query, top_k)` | Использовать вектор + граф для поиска top-k памяти | +| `get(memory_id)` | Получить отдельную память по ID | +| `get_by_ids(ids)` | Получить несколько памяти по IDs | +| `get_all()` | Экспортировать всю память в виде словаря | +| `update(memory_id, new)` | Обновить память по ID | +| `delete(ids)` | Удалить память по IDs | +| `delete_all()` | Удалить всю память и отношения | +| `dump(dir)` | Сериализовать граф в JSON в каталоге | +| `load(dir)` | Загрузить граф из сохраненного JSON файла | +| `drop(keep_last_n)` | Резервное копирование графа и удаление базы данных, сохранить N резервных копий | + +### Хранение Файлов + +Когда вызывается `dump(dir)`, MemOS экспортирует деревовидную память в формате JSON: + +``` +/ +``` + +Этот файл содержит структуру JSON с `nodes` и `edges`. Его можно повторно загрузить с помощью `load(dir)`. + +--- + +## Практическое Задание: От 0 до 1 + +::steps{} + +### Создание Конфигурации TreeTextMemory +Определите: +- Вашу модель встраивания (например, nomic-embed-text:latest), +- Ваш бэкенд графовой базы данных (Neo4j), +- Извлекатель памяти (на основе LLM) (по желанию). + +```python +from memos.configs.memory import TreeTextMemoryConfig + +config = TreeTextMemoryConfig.from_json_file("examples/data/config/tree_config.json") +``` + + +### Инициализация TreeTextMemory + +```python +from memos.memories.textual.tree import TreeTextMemory + +tree_memory = TreeTextMemory(config) +``` + +### Извлечение Структурированной Памяти + +Используйте извлекатель памяти для разбора диалогов, файлов или документов на несколько `TextualMemoryItem`. + +#### ИспользованиеSimpleStructMemReader(базовый) + +```python +from memos.mem_reader.simple_struct import SimpleStructMemReader + +reader = SimpleStructMemReader.from_json_file("examples/data/config/simple_struct_reader_config.json") + +scene_data = [[ + {"role": "user", "content": "Tell me about your childhood."}, + {"role": "assistant", "content": "I loved playing in the garden with my dog."} +]] + +memories = reader.get_memory(scene_data, type="chat", info={"user_id": "1234"}) +for m_list in memories: + tree_memory.add(m_list) +``` + +#### ИспользованиеMultiModalStructMemReader(расширенный) + +`MultiModalStructMemReader` поддерживает обработку мультимодального контента (текст, изображения, URL, файлы и т.д.), способный автоматически определять (умная маршрутизация) различные анализаторы: + +```python +from memos.configs.mem_reader import MultiModalStructMemReaderConfig +from memos.mem_reader.multi_modal_struct import MultiModalStructMemReader + +# Создание конфигурацииMultiModal Reader +multimodal_config = MultiModalStructMemReaderConfig( + llm={ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o-mini", + "api_key": "your-api-key" + } + }, + embedder={ + "backend": "openai", + "config": { + "model_name_or_path": "text-embedding-3-small", + "api_key": "your-api-key" + } + }, + chunker={ + "backend": "text_splitter", + "config": { + "chunk_size": 1000, + "chunk_overlap": 200 + } + }, + extractor_llm={ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o-mini", + "api_key": "your-api-key" + } + }, + # Необязательно: указать, какие домены напрямую возвращаютMarkdown + direct_markdown_hostnames=["github.com", "docs.python.org"] +) + +# ИнициализацияMultiModal Reader +multimodal_reader = MultiModalStructMemReader(multimodal_config) + +# ======================================== +# Пример 1: Обработка диалога с изображениями +# ======================================== +scene_with_image = [[ + { + "role": "user", + "content": [ + {"type": "text", "text": "Это сад моего дома"}, + {"type": "image_url", "image_url": {"url": "https://example.com/garden.jpg"}} + ] + }, + { + "role": "assistant", + "content": "Ваш сад очень красивый!" + } +]] + +memories = multimodal_reader.get_memory( + scene_with_image, + type="chat", + info={"user_id": "1234", "session_id": "session_001"} +) +for m_list in memories: + tree_memory.add(m_list) +print(f"✓ Добавлено {len(memories)} многомодальных воспоминаний") + +# ======================================== +# Пример 2: Обработка URL веб-страницы +# ======================================== +scene_with_url = [[ + { + "role": "user", + "content": "Пожалуйста, проанализируйте эту статью: https://example.com/article.html" + }, + { + "role": "assistant", + "content": "Я помогу вам проанализировать эту статью" + } +]] + +url_memories = multimodal_reader.get_memory( + scene_with_url, + type="chat", + info={"user_id": "1234", "session_id": "session_002"} +) +for m_list in url_memories: + tree_memory.add(m_list) +print(f"✓ Извлечено и добавлено {len(url_memories)} воспоминаний из URL") + +# ======================================== +# Пример 3: Обработка локальных файлов +# ======================================== +# Поддерживаемые Форматы Файлов: PDF, DOCX, TXT, Markdown, HTML и др. +file_paths = [ + "./documents/report.pdf", + "./documents/notes.md", + "./documents/data.txt" +] + +file_memories = multimodal_reader.get_memory( + file_paths, + type="doc", + info={"user_id": "1234", "session_id": "session_003"} +) +for m_list in file_memories: + tree_memory.add(m_list) +print(f"✓ Из файла извлечено и добавлено {len(file_memories)} записей") + +# ======================================== +# Пример 4: Смешанный Режим (Текст + Изображения + URL) +# ======================================== +mixed_scene = [[ + { + "role": "user", + "content": [ + {"type": "text", "text": "Это мой проектный документ:"}, + {"type": "text", "text": "https://github.com/user/project/README.md"}, + {"type": "image_url", "image_url": {"url": "https://example.com/diagram.png"}} + ] + } +]] + +mixed_memories = multimodal_reader.get_memory( + mixed_scene, + type="chat", + info={"user_id": "1234", "session_id": "session_004"} +) +for m_list in mixed_memories: + tree_memory.add(m_list) +print(f"✓ Из смешанного содержимого извлечено и добавлено {len(mixed_memories)} записей") +``` + +::alert{type="info"} +**Преимущества MultiModal Reader**
+- **Умный Маршрутизатор**: Автоматически распознает тип контента (изображение/URL/файл) и выбирает подходящий парсер
+- **Поддержка Форматов**: Поддерживает множество форматов, включая PDF, DOCX, Markdown, HTML, изображения и т.д.
+- **Парсинг URL**: Автоматически извлекает содержимое веб-страниц (включая GitHub, документационные сайты и т.д.)
+- **Обработка Больших Файлов**: Автоматически разбивает на части очень большие файлы, чтобы избежать превышения лимита токенов
+- **Сохранение Контекста**: Использует скользящее окно для поддержания непрерывности контекста между частями +:: + +::note +**Подсказки по Конфигурации**
+- Используйте параметр `direct_markdown_hostnames`, чтобы указать, какие домены должны возвращать Markdown формат напрямую
+- Поддерживает два режима извлечения: `mode="fast"` и `mode="fine"`, режим fine извлекает более детально
+- Посмотреть полный пример: `/examples/mem_reader/multimodal_struct_reader.py` +:: + +### Поиск Памяти + +Попробуйте векторный поиск + графический поиск: +```python +results = tree_memory.search("Talk about the garden", top_k=5) +for i, node in enumerate(results): + print(f"{i}: {node.memory}") +``` + +### Извлечение Памяти из Интернета (по желанию) +Вы также можете в реальном времени получать содержимое веб-страниц из поисковых систем, таких как Google / Bing / Bocha (博查), и автоматически разбивать его на узлы памяти. MemOS предоставляет единый интерфейс. + +Следующий пример демонстрирует, как извлечь веб-страницы, связанные с "Alibaba 2024 ESG report", и автоматически извлечь их в структурированную память. + +```python + +# Создание Embedder +embedder = EmbedderFactory.from_config( + EmbedderConfigFactory.model_validate({ + "backend": "ollama", + "config": {"model_name_or_path": "nomic-embed-text:latest"}, + }) +) + +# Настройка Ретривера (на примере BochaAI) +retriever_config = InternetRetrieverConfigFactory.model_validate({ + "backend": "bocha", + "config": { + "api_key": "sk-xxx", # Замените на ваш BochaAI API Key + "max_results": 5, + "reader": { # Конфигурация Reader с автоматическим разбиением + "backend": "simple_struct", + "config": ..., # Ваша конфигурация mem-reader + }, + } +}) + +# Инстанцирование Ретривера +retriever = InternetRetrieverFactory.from_config(retriever_config, embedder) + +# Выполнение Веб-Поиска +results = retriever.retrieve_from_internet("Alibaba 2024 ESG report") + +# Добавление в Граф Памяти +for m in results: + tree_memory.add(m) + +``` +Вы также можете напрямую настроить поле internet_retriever в TreeTextMemoryConfig, например: + + +```json +{ + "internet_retriever": { + "backend": "bocha", + "config": { + "api_key": "sk-xxx", + "max_results": 5, + "reader": { + "backend": "simple_struct", + "config": ... + } + } + } +} +``` + +Таким образом, при вызове tree_memory.search(query) система автоматически вызовет интернет-извлечение (например, BochaAI / Google / Bing), а затем отсортирует результаты вместе с узлами локальной карты, без необходимости вручную вызывать retriever.retrieve_from_internet + +### Замена Рабочей Памяти + +Замените вашу текущую `WorkingMemory` новым узлом: +```python +tree_memory.replace_working_memory( + [{ + "memory": "User is discussing gardening tips.", + "metadata": {"memory_type": "WorkingMemory"} + }] +) +``` + +### Резервное Копирование и Восстановление +Поддерживает постоянное хранилище для древовидной структуры и возможность перезагрузки в любое время: +```python +tree_memory.dump("tmp/tree_memories") +tree_memory.load("tmp/tree_memories") +``` + +:: + + +### Полный Пример Кода + +Этот пример объединяет все вышеперечисленные шаги и предоставляет полный процесс от начала до конца — просто скопируйте и запустите! + +```python +from memos.configs.embedder import EmbedderConfigFactory +from memos.configs.memory import TreeTextMemoryConfig +from memos.configs.mem_reader import SimpleStructMemReaderConfig +from memos.embedders.factory import EmbedderFactory +from memos.mem_reader.simple_struct import SimpleStructMemReader +from memos.memories.textual.tree import TreeTextMemory + +# Настройки Встраивания +embedder_config = EmbedderConfigFactory.model_validate({ + "backend": "ollama", + "config": {"model_name_or_path": "nomic-embed-text:latest"} +}) +embedder = EmbedderFactory.from_config(embedder_config) + +# Создание TreeTextMemory +tree_config = TreeTextMemoryConfig.from_json_file("examples/data/config/tree_config.json") +my_tree_textual_memory = TreeTextMemory(tree_config) +my_tree_textual_memory.delete_all() + +# Настройки Читателя +reader_config = SimpleStructMemReaderConfig.from_json_file( + "examples/data/config/simple_struct_reader_config.json" +) +reader = SimpleStructMemReader(reader_config) + +# Извлечение Из Диалога +scene_data = [[ + { + "role": "user", + "content": "Tell me about your childhood." + }, + { + "role": "assistant", + "content": "I loved playing in the garden with my dog." + }, +]] +memory = reader.get_memory(scene_data, type="chat", info={"user_id": "1234", "session_id": "2222"}) +for m_list in memory: + my_tree_textual_memory.add(m_list) + +# Поиск +results = my_tree_textual_memory.search( + "Talk about the user's childhood story?", + top_k=10 +) +for i, r in enumerate(results): + print(f"{i}'th result: {r.memory}") + +# Добавление Из Документа [Опционально] +doc_paths = ["./text1.txt", "./text2.txt"] +doc_memory = reader.get_memory( + doc_paths, "doc", info={ + "user_id": "your_user_id", + "session_id": "your_session_id", + } +) +for m_list in doc_memory: + my_tree_textual_memory.add(m_list) + +# Сброс И Удаление [Опционально] +my_tree_textual_memory.dump("tmp/my_tree_textual_memory") +my_tree_textual_memory.drop() +``` + +## Почему Выбирают TreeTextMemory + +- **Структурная Иерархия:** Организуйте память как ментальную карту — узлы могут иметь родителей, детей и перекрестные ссылки. +- **Графовые Связи:** Превосходите чистую иерархию — создавайте многопроходные цепочки вывода. +- **Семантический Поиск + Графовое Расширение:** Объединяйте преимущества векторов и графиков. +- **Объяснимость:** Отслеживайте, как память соединяется, объединяется или эволюционирует со временем. + +::note +**Попробуйте Это**
Добавьте узлы памяти из документов или веб-контента. Связывайте их вручную или автоматически объединяйте похожие узлы! +:: + +## Следующий Шаг + +- **Узнайте Больше [Neo4j](/open_source/modules/memories/neo4j_graph_db):** treeTextMemory поддерживается графовой базой данных. Узнайте, как Neo4j обрабатывает узлы, ребра и обходы, чтобы помочь вам спроектировать более эффективную иерархию памяти, многопроходные выводы и стратегии связи контекста. +- **Добавьте [Activation Memory](/open_source/modules/memories/kv_cache_memory):** Используйте KV-кэш во время выполнения для тестирования состояния сессии. +- **Изучите Графовые Выводы:** Создайте рабочие процессы для многопроходного извлечения и синтеза ответов. +- **Идите Дальше:** Проверьте [API Reference](/api-reference/search-memories) для продвинутых приложений или запустите больше примеров в `examples/`. + +Теперь ваш агент может не только запоминать факты, но и запоминать связи между ними! diff --git a/content/ru/open_source/modules/mos/overview.md b/content/ru/open_source/modules/mos/overview.md new file mode 100644 index 00000000..bc18d18d --- /dev/null +++ b/content/ru/open_source/modules/mos/overview.md @@ -0,0 +1,106 @@ +--- +title: Руководство по Разработке API (Архитектура Компонентов и Обработчиков) +desc: MemOS v2.0 использует более модульную и разъединённую архитектуру. Устаревший класс MOS был исключён, теперь рекомендуется использовать модель Components (Компоненты) + Handlers (Обработчики) для разработки. +--- + + +Эта архитектура разделяет "элементы системы" (Components) и "выполнение бизнес-логики" (Handlers), что делает систему более удобной для расширения, тестирования и обслуживания. + +## 1. Основные Понятия + +### 1.1 Components (Основные Компоненты) + +Components являются "органами" MemOS, они инициализируются при запуске сервера (через `init_server()`), и повторно используются на протяжении всего жизненного цикла. + +Основные компоненты включают: + +#### Основные Компоненты Памяти + +1. **MemCube**: Контейнер памяти, используемый для изоляции памяти различных пользователей/различных сценариев применения и единого управления несколькими модулями памяти. +2. **MemReader**: Обработчик памяти, который преобразует различные материалы, вводимые пользователем (чаты, документы, изображения), в фрагменты памяти, которые могут быть записаны в систему. +3. **MemScheduler**: Фоновый планировщик, отвечающий за управление очередью фоновых задач, асинхронно обрабатывающий времязатратные операции хранения, индексации, организации памяти и поддерживающий параллельное выполнение нескольких задач. +4. **MemChat**: Контроллер диалогов, отвечающий за автоматическое выполнение "поиска памяти -> управления контекстом -> планирования LLM -> обновления памяти" в процессе диалога. +5. **MemFeedback**: Корректор памяти, автоматически понимающий естественные языковые отзывы пользователей, точно определяющий конфликтующие воспоминания и выполняющий атомарные исправления (коррекция/дополнение/замена). + +### 1.2 Handlers (Обработчики Бизнес-Логики) + +Handlers являются "мозгом" MemOS, они инкапсулируют конкретную бизнес-логику (например, добавление, поиск, диалог), выполняя конкретные пользовательские задачи через вызов и координацию возможностей Components (органов). + +#### Обзор Основных Обработчиков + +| Handler | Действие | Основной Метод | +| :--- | :--- | :--- | +| **AddHandler** | Добавить Память (Диалог/Документ/Текст) | `handle_add_memories` | +| **SearchHandler** | Поиск Памяти (Семантический Поиск) | `handle_search_memories` | +| **ChatHandler** | Диалог (С Укреплением Памяти) | `handle_chat_complete`, `handle_chat_stream` | +| **FeedbackHandler** | Обратная Связь (Коррекция Памяти/Ручное Вмешательство) | `handle_feedback_memories` | +| **MemoryHandler** | Управление (Получить Подробности/Удалить) | `handle_get_memory`, `handle_delete_memories` | +| **SchedulerHandler** | Планировщик (Запрос Статуса Асинхронных Задач) | `handle_scheduler_status`, `handle_scheduler_wait` | +| **SuggestionHandler** | Предложения (Генерация Рекомендованных Вопросов) | `handle_get_suggestion_queries` | + +## 2. Подробное Описание API + +### 2.1 Инициализация (Initialization) +Инициализация является основой запуска системы. Все обработчики зависят от единой механики регистрации компонентов и внедрения зависимостей. + +- Загрузка компонентов (init_server): при запуске системы инициализируются все основные компоненты, включая LLM (большую языковую модель), уровень хранения (векторная база данных, графовая база данных), планировщик (Scheduler) и различные Memory Cube. +- Внедрение зависимостей (HandlerDependencies): для обеспечения разъединённости кода и тестируемости все компоненты объединяются в единый контейнер зависимостей (`HandlerDependencies`). Когда обработчик запускается, ему нужно только получить этот контейнер, чтобы получить необходимые ресурсы, такие как `naive_mem_cube`, `mem_reader`, `feedback_server` и т.д., без необходимости повторного создания этих компонентов. + +### 2.2 Добавление Памяти (AddHandler) +AddHandler является "инструкцией по приему памяти" мозга, отвечающей за преобразование внешней информации и запись её в память системы. Он не только отвечает за прием и преобразование различных видов информации, но также может автоматически распознавать отзывы и перенаправлять их в специализированный процесс обработки отзывов. + +- Основные функции: + - Поддержка мультимодальности: возможность обрабатывать пользовательские диалоги, документы, изображения и другие формы ввода, единообразно преобразуя их в объекты памяти внутри системы. + - Синхронный и асинхронный режимы: управление способом обработки через параметр `async_mode`. **Синхронный режим** ("sync"): немедленная обработка, вызывающий блокируется в ожидании результата, подходит для отладки; **Асинхронный режим** ("async"): задача помещается в фоновую очередь для параллельной обработки MemScheduler, API немедленно возвращает идентификатор задачи, подходит для производственной среды для повышения скорости отклика. + - Автоматическая маршрутизация отзывов: если в запросе отмечено `is_feedback=True`, обработчик автоматически извлекает последнее сообщение пользователя из диалога в качестве содержимого отзыва и перенаправляет его на обработку MemFeedback, а не добавляет как обычную новую память. + - Многозадачная запись: поддержка одновременной записи памяти в несколько MemCube. При указании нескольких целевых кубов система будет параллельно обрабатывать все задачи записи; при наличии только одной цели будет использоваться легковесный способ обработки. + +### 2.3 Поиск Памяти (SearchHandler) +SearchHandler является "инструкцией по поиску памяти" мозга, предоставляющей интеллектуальные возможности запроса памяти на основе семантики, являющейся ключевым компонентом для реализации RAG (поиск, улучшенный генерацией). + +- Основные функции : + - Семантический поиск : Используя технологию векторного встраивания (Embedding), возвращает связанные воспоминания на основе семантической схожести запроса, что позволяет более точно понять намерения пользователя по сравнению с простым сопоставлением ключевых слов. + - Гибкий диапазон поиска : Поддерживает указание целевого диапазона данных для поиска. Например, можно искать только в памяти конкретного пользователя или искать общие публичные воспоминания среди нескольких пользователей, удовлетворяя различные требования к конфиденциальности и бизнесу. + - Разнообразные режимы поиска : В зависимости от сценария применения можно гибко выбирать между скоростью и точностью. **Быстрый режим** подходит для сценариев с высокими требованиями к времени отклика, **Точный режим** подходит для сценариев, стремящихся к высокой точности воспоминаний, **Смешанный режим** учитывает оба аспекта. + - Многошаговый поисковый вывод : Для сложных вопросов поддерживает внедрение глубокой логики вывода, постепенно приближаясь к наиболее релевантным воспоминаниям через многократное понимание и поиск. + +### 2.4 Диалог (ChatHandler) +ChatHandler является "инструкцией по координации диалога" мозга, отвечающей за преобразование потребностей пользователя в диалоге в полный бизнес-процесс. Он не хранит данные напрямую, а координирует другие обработчики для выполнения задач диалога от начала до конца. + +- Основные функции : + - Оркестрация процессов : Автоматически выполняет полный цикл диалога "поиск воспоминаний → LLM генерация → сохранение воспоминаний". Каждый раз, когда пользователь задает вопрос, он получает более интеллектуальный ответ на основе исторических воспоминаний, при этом каждый диалог фиксируется как новое воспоминание, реализуя обучение через диалог. + - Управление контекстом : Отвечает за обработку соединения history (исторический диалог) и query (текущий вопрос), обеспечивая понимание LLM полного контекста диалога и предотвращая потерю информации. + - Разнообразные режимы взаимодействия : Поддерживает стандартный режим запрос-ответ (APIChatCompleteRequest) и потоковый ответ (Stream) режим, стандартный режим подходит для простых вопросов, потоковый режим подходит для длинных текстовых ответов, удовлетворяя различные требования к взаимодействию на фронтенде. + - Уведомление сообщений (по желанию) : Поддерживает автоматическую отправку результатов на сторонние платформы (например, DingTalk) после генерации ответа, реализуя многоканальную интеграцию. + +### 2.5 Обратная Связь и Коррекция (FeedbackHandler) +FeedbackHandler является "инструкцией по обратной связи и коррекции" мозга, отвечающей за понимание естественноязычной обратной связи пользователя о работе ИИ, автоматически точно определяя и исправляя соответствующее содержание воспоминаний. + +- Основные функции : + - Коррекция воспоминаний : Когда пользователь указывает на ошибку ИИ (например, "место встречи не Пекин, а Шанхай"), обработчик автоматически обновляет или помечает соответствующие старые воспоминания. Система использует управление версиями, а не прямое удаление, сохраняя возможность отслеживания истории изменений. + - Положительная и отрицательная обратная связь : Поддерживает возможность для пользователей отмечать качество конкретных воспоминаний с помощью лайков или дизлайков. Система соответственно корректирует вес и достоверность этого воспоминания, делая последующий поиск более точным. + - Точное определение : Поддерживает два способа обратной связи. Один основан на автоматическом определении конфликтной информации на основе истории диалога, другой позволяет пользователю напрямую указывать конкретные воспоминания для коррекции, повышая эффективность и точность обратной связи. + +### 2.6 Управление Памятью (MemoryHandler) +MemoryHandler является "инструкцией по управлению воспоминаниями" мозга, предоставляющей базовые возможности CRUD (создание, чтение, обновление, удаление) для данных воспоминаний, в основном используемые в системном управлении или для очистки данных в операционных сценариях. + +- Основные функции : + - Тщательное управление : В отличие от бизнес-уровневой записи AddHandler, этот обработчик позволяет напрямую получать подробную информацию о конкретном воспоминании по ID воспоминания или выполнять физическое удаление. Этот способ прямого взаимодействия обходит упаковку бизнес-логики, в основном используется для отладки, аудита или очистки системы. + - Прямой доступ к низкому уровню : Некоторые операции управления требуют прямого взаимодействия с низкоуровневыми органами памяти (naive_mem_cube), чтобы обеспечить наиболее эффективные и минимально задерживающие возможности обработки данных, удовлетворяя потребности в обслуживании системы. + +### 2.7 Состояние Планировщика Задач (SchedulerHandler) +SchedulerHandler является "инструкцией по мониторингу задач" мозга, отвечающей за отслеживание реального состояния выполнения всех асинхронных задач в системе, позволяя пользователям понимать прогресс и результаты фоновых задач. + +- Основные Функции : + - Отслеживание Состояния : В сочетании с бэкендом Redis, отслеживание реального состояния задач (Queued В Очереди, Running Выполняется, Completed Завершено, Failed Неудачно). + - Получение Результатов : Предоставление интерфейса для запроса результатов задач. Когда асинхронная задача завершена, пользователь может получить окончательный результат выполнения или информацию об ошибках через этот интерфейс, чтобы понять, была ли операция успешной и причины неудачи. + - Синхронное Ожидание (Инструмент Отладки) : В процессе тестирования и интеграционного тестирования предоставляется инструмент для принудительного преобразования асинхронных задач в синхронное ожидание, что позволяет разработчикам отлаживать асинхронные процессы так же, как и синхронный код, повышая эффективность разработки. + +### 2.8 Предполагаемые Вопросы (SuggestionHandler) +SuggestionHandler является "инструкцией по генерации предложений" мозга, которая активно рекомендует связанные вопросы, предсказывая потенциальные потребности пользователя, помогая пользователю исследовать возможности системы и находить интересные темы. + +- Основные Функции : + - Двухрежимная Генерация : + - Предложения на Основе Диалога : Когда пользователь предоставляет недавнюю историю диалога, система анализирует контекст диалога, предполагает возможные интересные для пользователя последующие темы и генерирует 3 связанных рекомендованных вопроса. + - Предложения на Основе Профиля Пользователя : Когда контекст диалога отсутствует, система предполагает интересы и состояние пользователя на основе его недавней памяти, генерируя рекомендованные вопросы, связанные с недавней жизнью или работой пользователя. Это подходит для начала диалога или смены темы. + - Многоязычная Поддержка : Рекомендованные вопросы автоматически адаптируются к языковым настройкам пользователя, поддерживая множество языков, включая китайский и английский, улучшая опыт различных пользователей. diff --git a/content/ru/open_source/modules/mos/users.md b/content/ru/open_source/modules/mos/users.md new file mode 100644 index 00000000..5e12f4c2 --- /dev/null +++ b/content/ru/open_source/modules/mos/users.md @@ -0,0 +1,305 @@ +--- +title: Управление Пользователями +desc: "**MOS** предоставляет полные функции управления пользователями для поддержки многопользовательских и многосессионных операций памяти. Этот документ подробно описывает методы управления пользователями в **MOS**." + +## Роли Пользователей + +**MOS** поддерживает 4 различных уровня прав доступа для ролей пользователей: + +| Роль | Описание | Права | +|------|-------------|-------------| +| `ROOT` | Системный Администратор | Доступ ко всем кубам и пользователям, не может быть удален | +| `ADMIN` | Администратор Пользователь | Может управлять пользователями и кубами, доступ ко всем кубам | +| `USER` | Обычный Пользователь | Может создавать и управлять своими кубами, доступ к общим кубам | +| `GUEST` | Ограниченный Пользователь | Может только получать доступ к общим кубам, не может создавать кубы | + +## Методы Управления Пользователями + +### 1. `create_user` + +Создание нового пользователя в системе **MOS** + +**Параметры:** +- `user_id` (str): Уникальный идентификатор пользователя +- `role` (UserRole, optional): Роль пользователя. По умолчанию `UserRole.USER` +- `user_name` (str, optional): Имя пользователя для отображения. Если не указано, используется `user_id` + +**Возвращаемое значение:** +- `str`: Созданный ID пользователя + +**Пример:** +```python +import uuid +from memos.mem_user.user_manager import UserRole + +# Создать Стандартного Пользователя +user_id = str(uuid.uuid4()) +memory.create_user(user_id=user_id, role=UserRole.USER, user_name="John Doe") + +# Создать Администратора Пользователя +admin_id = str(uuid.uuid4()) +memory.create_user(user_id=admin_id, role=UserRole.ADMIN, user_name="Admin User") + +# Создать Пользователя Гостя +guest_id = str(uuid.uuid4()) +memory.create_user(user_id=guest_id, role=UserRole.GUEST, user_name="Guest User") +``` + +**Примечание:** +- Если пользователь с тем же `user_name` уже существует, метод возвращает ID существующего пользователя +- В процессе инициализации система автоматически создаст пользователя root +- ID пользователя должен быть уникальным в системе + +### 2. `list_users` + +Получение информации о всех активных пользователях в системе + +**Параметры:** +- Нет + +**Возвращаемое значение:** +- `list`: Список словарей с информацией о пользователях: + - `user_id` (str): Уникальный идентификатор пользователя + - `user_name` (str): Имя пользователя для отображения + - `role` (str): Роль пользователя (root, администратор, обычный пользователь, гость) + - `created_at` (str): Временная метка ISO создания пользователя + - `is_active` (bool): Активен ли аккаунт пользователя + +**Пример:** +```python +# Список Всех Пользователей +users = memory.list_users() +for user in users: + print(f"User: {user['user_name']} (ID: {user['user_id']})") + print(f"Role: {user['role']}") + print(f"Active: {user['is_active']}") + print(f"Created: {user['created_at']}") + print("---") +``` + +**Пример вывода:** +``` +User: root (ID: root) +Role: root +Active: True +Created: 2024-01-15T10:30:00 +--- +User: John Doe (ID: 550e8400-e29b-41d4-a716-446655440000) +Role: user +Active: True +Created: 2024-01-15T11:00:00 +--- +``` + +### 3. `create_cube_for_user` + +Создание нового куба памяти и назначение указанного пользователя его владельцем + +**Параметры:** +- `cube_name` (str): Название куба +- `owner_id` (str): ID пользователя-владельца куба +- `cube_path` (str, optional): Локальный путь к файлу куба или URL удаленного репозитория +- `cube_id` (str, optional): Индикатор пользовательского куба, если не предоставлен, используется сгенерированный UUID + +**Возвращаемое значение:** +- `str`: Созданный ID куба + +**Пример:** +```python +import uuid + +# Первый Раз Создать Пользователя +user_id = str(uuid.uuid4()) +memory.create_user(user_id=user_id, user_name="Alice") + +# Создать Куб Для Пользователя +cube_id = memory.create_cube_for_user( + cube_name="Alice's Personal Memory", + owner_id=user_id, + cube_path="/path/to/alice/memory", + cube_id="alice_personal_cube" +) + +print(f"Created cube: {cube_id}") +``` + +**Примечание:** +- Владельцы автоматически получают доступ ко всем созданным кубам +- Владельцы кубов могут делиться ими с другими пользователями +- Если указан `cube_path`, он может быть локальным путем к директории или URL удаленного репозитория +- Пользовательский `cube_id` должен быть уникальным в системе + +### 4. `get_user_info` + +Получение подробной информации о текущем пользователе и доступных ему кубах + +**Параметры:** +- Нет + +**Возвращаемое значение:** +- `dict`: Словарь с информацией о пользователе и доступных кубах: + - `user_id` (str): ID текущего пользователя + - `user_name` (str): Имя текущего пользователя + - `role` (str): Роль текущего пользователя + - `created_at` (str): Временная метка ISO создания пользователя + - `accessible_cubes` (list): Список словарей для каждого доступного куба: + - `cube_id` (str): Индикатор куба + - `cube_name` (str): Название куба + - `cube_path` (str): Путь к файлу куба или URL репозитория + - `owner_id` (str): ID владельца куба + - `is_loaded` (bool): Загружен ли куб в память в данный момент + +**Пример:** +```python +# Получить Информацию О Текущем Пользователе +user_info = memory.get_user_info() + +print(f"Current User: {user_info['user_name']} ({user_info['user_id']})") +print(f"Role: {user_info['role']}") +print(f"Created: {user_info['created_at']}") +print("\nAccessible Cubes:") +for cube in user_info['accessible_cubes']: + print(f"- {cube['cube_name']} (ID: {cube['cube_id']})") + print(f" Owner: {cube['owner_id']}") + print(f" Loaded: {cube['is_loaded']}") + print(f" Path: {cube['cube_path']}") +``` + +**Пример вывода:** +``` +Current User: Alice (550e8400-e29b-41d4-a716-446655440000) +Role: user +Created: 2024-01-15T11:00:00 + +Accessible Cubes: +- Alice's Personal Memory (ID: alice_personal_cube) + Owner: 550e8400-e29b-41d4-a716-446655440000 + Loaded: True + Path: /path/to/alice/memory +- Shared Project Memory (ID: project_cube) + Owner: bob_user_id + Loaded: False + Path: /path/to/project/memory +``` + +### 5. `share_cube_with_user` + +Поделиться кубом памяти с другими пользователями, предоставив им доступ к содержимому куба + +**Параметры:** +- `cube_id` (str): ID куба для совместного использования +- `target_user_id` (str): ID пользователя, с которым делится куб + +**Возвращаемое значение:** +- `bool`: Если успешно поделено, возвращает `True`, иначе возвращает `False` + +**Пример:** +```python +# Поделиться Кубом С Другими Пользователями +success = memory.share_cube_with_user( + cube_id="alice_personal_cube", + target_user_id="bob_user_id" +) + +if success: + print("Cube shared successfully") +else: + print("Failed to share cube") +``` + +**Примечание:** +- Текущий пользователь должен иметь право доступа к кубу, который делится +- Целевой пользователь должен существовать и быть активным +- Совместное использование куба предоставляет целевому пользователю права на чтение и запись для этого куба +- Владельцы кубов всегда могут делиться своими кубами +- Пользователи, имеющие доступ к кубу, могут делиться кубом с другими пользователями (если у них есть соответствующие права) + +## Полный Рабочий Процесс Управления Пользователями + +Ниже приведен полный пример демонстрации операций управления пользователями: + +```python +import uuid +from memos.configs.mem_os import MOSConfig +from memos.mem_os.main import MOS +from memos.mem_user.user_manager import UserRole + +# Инициализация MOS +mos_config = MOSConfig.from_json_file("examples/data/config/simple_memos_config.json") +memory = MOS(mos_config) + +# 1. Создать Пользователя +alice_id = str(uuid.uuid4()) +bob_id = str(uuid.uuid4()) + +memory.create_user(user_id=alice_id, user_name="Alice", role=UserRole.USER) +memory.create_user(user_id=bob_id, user_name="Bob", role=UserRole.USER) + +# 2. Все Пользователи +print("All users:") +users = memory.list_users() +for user in users: + print(f"- {user['user_name']} ({user['role']})") + +# 3. Создать Куб Для Пользователя +alice_cube_id = memory.create_cube_for_user( + cube_name="Alice's Personal Memory", + owner_id=alice_id, + cube_path="/path/to/alice/memory" +) + +bob_cube_id = memory.create_cube_for_user( + cube_name="Bob's Work Memory", + owner_id=bob_id, + cube_path="/path/to/bob/work" +) + +# 4. Поделиться Кубом С Другими Пользователями +memory.share_cube_with_user(alice_cube_id, bob_id) +memory.share_cube_with_user(bob_cube_id, alice_id) + +# 5. Получить Информацию О Пользователе +alice_info = memory.get_user_info() +print(f"\nAlice's accessible cubes: {len(alice_info['accessible_cubes'])}") + +# 6. Добавить Память В Куб +memory.add( + messages=[ + {"role": "user", "content": "I like playing football."}, + {"role": "assistant", "content": "That's great! Football is a wonderful sport."} + ], + user_id=alice_id, + mem_cube_id=alice_cube_id +) + +# 7. Искать Память +retrieved = memory.search( + query="What does Alice like?", + user_id=alice_id +) +print(f"Retrieved memories: {retrieved['text_mem']}") +``` + +## Обработка Ошибок + +Методы управления пользователями включают полную обработку ошибок: + +- **Проверка Пользователя**: Метод проверяет, существует ли пользователь и активен ли он перед выполнением операции +- **Проверка Доступа к Кубу**: Убедитесь, что у пользователя есть соответствующие права доступа к кубу перед выполнением операции +- **Предотвращение Дубликатов**: Элегантная обработка дублирующихся имен пользователей и ID кубов +- **Проверка Прав**: Проверка ролей и прав пользователей для чувствительных операций + +## Устойчивость Базы Данных + +Управление данными пользователей сохраняется в базе данных SQLite: +- **Местоположение**: По умолчанию `~/.memos/memos_users.db` +- **Таблицы**: `users`, `cubes`, `user_cube_association` +- **Связи**: Между пользователями и кубами существует отношение многие ко многим +- **Мягкое Удаление**: Пользователи и кубы мягко удаляются (отмечаются как неактивные), а не удаляются навсегда + +## Вопросы Безопасности + +- **Контроль Доступа на Основе Ролей**: Разные роли пользователей имеют разные права +- **Право Собственности на Куб**: Владельцы кубов могут полностью контролировать свои кубы +- **Проверка Доступа**: Все операции должны проверять права доступа пользователя перед выполнением +- **Защита Корневого Пользователя**: Корневой пользователь не может быть удален и имеет полный доступ к системе diff --git a/content/ru/open_source/modules/mos/users_configurations.md b/content/ru/open_source/modules/mos/users_configurations.md new file mode 100644 index 00000000..3728a5d5 --- /dev/null +++ b/content/ru/open_source/modules/mos/users_configurations.md @@ -0,0 +1,719 @@ +--- +title: MemOS Настройка Руководство + desc: Этот документ полностью описывает все поля конфигурации и методы инициализации различных компонентов в системе MemOS. + --- + +1. [Обзор Конфигурации](#configuration-overview) +2. [Конфигурация MOS](#mos-configuration) +3. [Конфигурация LLM](#llm-configuration) +4. [Конфигурация MemReader](#memreader-configuration) +5. [Конфигурация MemCube](#memcube-configuration) +6. [Конфигурация Памяти](#memory-configuration) +7. [Конфигурация Встраивателя](#embedder-configuration) +8. [Конфигурация Векторной Базы Данных](#vector-database-configuration) +9. [Конфигурация Графовой Базы Данных](#graph-database-configuration) +10. [Конфигурация Планировщика](#scheduler-configuration) +11. [Методы Инициализации](#initialization-methods) +12. [Примеры Конфигурации](#configuration-examples) + +## Обзор Конфигурации + +MemOS использует иерархическую систему конфигурации с различными фабричными моделями для бэкенда. Каждый компонент имеет: +- Основной класс конфигурации +- Класс конфигурации, специфичный для бэкенда +- Фабричный класс для создания соответствующей конфигурации на основе бэкенда + +## Конфигурация MOS + +Основная конфигурация MOS для координации всех компонентов + +### Поля MOSConfig + +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `user_id` | str | "root" | Идентификатор пользователя MOS, этот идентификатор пользователя будет использоваться как значение по умолчанию | +| `session_id` | str | Автоматически Сгенерированный UUID | Идентификатор Сессии MOS | +| `chat_model` | LLMConfigFactory | Обязательный | Чат для Конфигурации LLM | +| `mem_reader` | MemReaderConfigFactory | Обязательный | Конфигурация MemReader | +| `mem_scheduler` | SchedulerFactory | Необязательный | Конфигурация Планировщика | +| `max_turns_window` | int | 15 | Максимальное Количество Сохраненных Диалогов | +| `top_k` | int | 5 | Максимальная Память для Поиска по Каждому Запросу | +| `enable_textual_memory` | bool | True | Включить Текстовую Память | +| `enable_activation_memory` | bool | False | Включить Память Активации | +| `enable_parametric_memory` | bool | False | Включить Параметрическую Память | +| `enable_mem_scheduler` | bool | False | Включить Память Планировщика | + + +### Пример Конфигурации MOS + +```json +{ + "user_id": "root", + "chat_model": { + "backend": "huggingface", + "config": { + "model_name_or_path": "Qwen/Qwen3-1.7B", + "temperature": 0.1, + "remove_think_prefix": true, + "max_tokens": 4096 + } + }, + "mem_reader": { + "backend": "simple_struct", + "config": { + "llm": { + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b", + "temperature": 0.8, + "max_tokens": 1024, + "top_p": 0.9, + "top_k": 50 + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": "nomic-embed-text:latest" + } + }, + "chunker": { + "backend": "sentence", + "config": { + "tokenizer_or_token_counter": "gpt2", + "chunk_size": 512, + "chunk_overlap": 128, + "min_sentences_per_chunk": 1 + } + } + } + }, + "max_turns_window": 20, + "top_k": 5, + "enable_textual_memory": true, + "enable_activation_memory": false, + "enable_parametric_memory": false +} +``` + +## Конфигурация LLM + +Конфигурация для различных бэкендов LLM + +### Основные Поля LLM + +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `model_name_or_path` | str | Обязательный | Название или Путь Модели | +| `temperature` | float | 0.8 | Температура Выборки | +| `max_tokens` | int | 1024 | Максимальное Количество Генерируемых Токенов | +| `top_p` | float | 0.9 | Параметр Top-p Выборки | +| `top_k` | int | 50 | Параметр Top-k Выборки | +| `remove_think_prefix` | bool | False | Удалить тег think из вывода | + +### Поля, Специфичные для Бэкенда + +#### OpenAI LLM +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `api_key` | str | Обязательное | OpenAI API key | +| `api_base` | str | "https://api.openai.com/v1" | OpenAI API base URL | + +#### Ollama LLM +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `api_base` | str | "http://localhost:11434" | Ollama API base URL | + +#### HuggingFace LLM +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `do_sample` | bool | False | Использовать выборку VS жадное кодирование | +| `add_generation_prompt` | bool | True | Применить шаблон генерации | + +### Пример Конфигурации LLM + +```json +// OpenAI +{ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o", + "temperature": 0.8, + "max_tokens": 1024, + "top_p": 0.9, + "top_k": 50, + "api_key": "sk-...", + "api_base": "https://api.openai.com/v1" + } +} + +// Ollama +{ + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b", + "temperature": 0.8, + "max_tokens": 1024, + "top_p": 0.9, + "top_k": 50, + "api_base": "http://localhost:11434" + } +} + +// HuggingFace +{ + "backend": "huggingface", + "config": { + "model_name_or_path": "Qwen/Qwen3-1.7B", + "temperature": 0.1, + "remove_think_prefix": true, + "max_tokens": 4096, + "do_sample": false, + "add_generation_prompt": true + } +} +``` + +## MemReader Конфигурация + +Конфигурация компонента чтения памяти + +### Основные Поля MemReader + +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `created_at` | datetime | Автоматически сгенерировано | Время создания метки | +| `llm` | LLMConfigFactory | Обязательное | Конфигурация LLM | +| `embedder` | EmbedderConfigFactory | Обязательное | Конфигурация встраивателя | +| `chunker` | chunkerConfigFactory | Обязательное | Конфигурация блока | + +### Типы Бэкенда + +- `simple_struct`: Структурированный читатель памяти + +### Пример Конфигурации MemReader + +```json +{ + "backend": "simple_struct", + "config": { + "llm": { + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b", + "temperature": 0.0, + "remove_think_prefix": true, + "max_tokens": 8192 + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": "nomic-embed-text:latest" + } + }, + "chunker": { + "backend": "sentence", + "config": { + "tokenizer_or_token_counter": "gpt2", + "chunk_size": 512, + "chunk_overlap": 128, + "min_sentences_per_chunk": 1 + } + } + } +} +``` + +## Конфигурация MemCube + +Конфигурация компонента памяти куба + +### GeneralMemCubeConfig Поля + +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `user_id` | str | "default_user" | ID пользователя MemCube | +| `cube_id` | str | Автоматически сгенерированный UUID | ID куба MemCube | +| `text_mem` | MemoryConfigFactory | Обязательное | Конфигурация памяти в открытом виде | +| `act_mem` | MemoryConfigFactory | Обязательное | Конфигурация активной памяти | +| `para_mem` | MemoryConfigFactory | Обязательное | Конфигурация параметрической памяти | + +### Разрешенные Бэкенды + +- **Явная Память**: `naive_text`, `general_text`, `tree_text`, `uninitialized` +- **Активная Память**: `kv_cache`, `uninitialized` +- **Параметрическая Память**: `lora`, `uninitialized` + +### Пример Конфигурации MemCube + +```json +{ + "user_id": "root", + "cube_id": "root/mem_cube_kv_cache", + "text_mem": {}, + "act_mem": { + "backend": "kv_cache", + "config": { + "memory_filename": "activation_memory.pickle", + "extractor_llm": { + "backend": "huggingface", + "config": { + "model_name_or_path": "Qwen/Qwen3-1.7B", + "temperature": 0.8, + "max_tokens": 1024, + "top_p": 0.9, + "top_k": 50, + "add_generation_prompt": true, + "remove_think_prefix": false + } + } + } + }, + "para_mem": { + "backend": "lora", + "config": { + "memory_filename": "parametric_memory.adapter", + "extractor_llm": { + "backend": "huggingface", + "config": { + "model_name_or_path": "Qwen/Qwen3-1.7B", + "temperature": 0.8, + "max_tokens": 1024, + "top_p": 0.9, + "top_k": 50, + "add_generation_prompt": true, + "remove_think_prefix": false + } + } + } + } +} +``` + +## Конфигурация Памяти + +Конфигурация различных типов систем памяти + +### Основные Поля Памяти + +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `cube_id` | str | None | Уникальный MemCube идентификатор, по умолчанию может быть cube_name или path| + +### Конфигурация Открытой Памяти + +#### Основная Открытая Память +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `memory_filename` | str | "textual_memory.json" | Имя файла для хранения памяти | + +#### Чистая Открытая Память (только текст) +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `extractor_llm` | LLMConfigFactory | Обязательно | LLM для извлечения памяти | + +#### Универсальная Открытая Память (с векторным индексом) +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `extractor_llm` | LLMConfigFactory | Обязательно | LLM для извлечения памяти | +| `vector_db` | VectorDBConfigFactory | Обязательно | Конфигурация векторной базы данных | +| `embedder` | EmbedderConfigFactory | Обязательное | Конфигурация встраивателя | + +#### Деревовидная Открытая Память +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `extractor_llm` | LLMConfigFactory | Обязательно | LLM для извлечения памяти | +| `dispatcher_llm` | LLMConfigFactory | Обязательно | LLM для распределения памяти | +| `embedder` | EmbedderConfigFactory | Обязательное | Конфигурация встраивателя | +| `graph_db` | GraphDBConfigFactory | Обязательно | Конфигурация графовой базы данных | + +### Конфигурация Активной Памяти + +#### Основная Активная Память +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `memory_filename` | str | "activation_memory.pickle" | Имя файла для хранения памяти | + +#### Память KV Cache +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `extractor_llm` | LLMConfigFactory | Обязательно | LLM для извлечения памяти (должен быть huggingface) | + +### Конфигурация Параметрической Памяти + +#### Основная Параметрическая Память +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `memory_filename` | str | "parametric_memory.adapter" | Имя файла для хранения памяти | + +#### LoRA Память +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `extractor_llm` | LLMConfigFactory | Обязательно | LLM для извлечения памяти (должен быть huggingface) | + +### Пример Конфигурации Памяти + +```json +// Деревовидная Явная Память +{ + "backend": "tree_text", + "config": { + "memory_filename": "tree_memory.json", + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b", + "temperature": 0.0, + "remove_think_prefix": true, + "max_tokens": 8192 + } + }, + "dispatcher_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b", + "temperature": 0.0, + "remove_think_prefix": true, + "max_tokens": 8192 + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": "nomic-embed-text:latest" + } + }, + "graph_db": { + "backend": "neo4j", + "config": { + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "12345678", + "db_name": "user08alice", + "auto_create": true, + "embedding_dimension": 768 + } + } + } +} +``` + +## Конфигурация Встраивателя + +Конфигурация модели встраивания + +### Основные Поля Встраивателя + +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `model_name_or_path` | str | Обязательный | Название или Путь Модели | +| `embedding_dims` | int | None | Количество размерностей встраивания | + +### Поля, Специфичные для Бэкенда + +#### Встраиватель Ollama +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `api_base` | str | "http://localhost:11434" | Ollama API base URL | + +#### Sentence Transformer Встраиватель +Нет других полей, кроме основных конфигураций. + +### Пример Конфигурации Встраивателя + +```json +// Ollama Встраиватель +{ + "backend": "ollama", + "config": { + "model_name_or_path": "nomic-embed-text:latest", + "api_base": "http://localhost:11434" + } +} + +// Sentence Transformer Встраиватель +{ + "backend": "sentence_transformer", + "config": { + "model_name_or_path": "all-MiniLM-L6-v2", + "embedding_dims": 384 + } +} +``` + +## Конфигурация Векторной Базы Данных + +Конфигурация векторной базы данных + +### Основные Поля Векторной Базы Данных + +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `collection_name` | str | Обязательное | Название коллекции | +| `vector_dimension` | int | None | Размерность вектора | +| `distance_metric` | str | None | Метрика расстояния (косинусное, евклидово, скалярное произведение) | + +### Поля Векторной Базы Данных Qdrant + +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `host` | str | None | Хост Qdrant | +| `port` | int | None | Порт Qdrant | +| `path` | str | None | Локальный путь Qdrant | + +### Пример Конфигурации Векторной Базы Данных + +```json +{ + "backend": "qdrant", + "config": { + "collection_name": "memories", + "vector_dimension": 768, + "distance_metric": "cosine", + "path": "/path/to/qdrant" + } +} +``` + +## Конфигурация Графовой Базы Данных + +Конфигурация графовой базы данных + +### Основные Поля Графовой Базы Данных + +| Поле | Тип | Значение по умолчанию | Описание | +|-------|------|---------|-------------| +| `uri` | str | Обязательное | URI базы данных | +| `user` | str | Обязательное | Имя пользователя базы данных | +| `password` | str | Обязательное | Пароль базы данных | + +### Neo4j Графовая База Данных Поля + +| Поле | Тип | Значение по умолчанию | Описание | +|-------|------|---------|-------------| +| `db_name` | str | Обязательное | Название целевой базы данных | +| `auto_create` | bool | False | Создать базу данных, если она не существует | +| `embedding_dimension` | int | 768 | Размерность векторного встраивания | + +### Пример Конфигурации Графовой Базы Данных + +```json +{ + "backend": "neo4j", + "config": { + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "12345678", + "db_name": "user08alice", + "auto_create": true, + "embedding_dimension": 768 + } +} +``` + +## Конфигурация Планировщика + +Конфигурация системы планирования памяти для управления извлечением и активацией памяти + +### Основные Поля Планировщика + +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `top_k` | int | 10 | Количество кандидатов для рассмотрения в начальном поиске | +| `top_n` | int | 5 | Количество окончательных результатов, возвращаемых после обработки | +| `enable_parallel_dispatch` | bool | True | Использовать ли пул потоков для включения параллельной обработки сообщений | +| `thread_pool_max_workers` | int | 5 | Максимальное количество потоков в пуле потоков (1-20) | +| `consume_interval_seconds` | int | 3 | Интервал потребления сообщений из очереди (в секундах) (0-60) | + +### Общие Поля Планировщика + +| Поле | Тип | Значение По Умолчанию | Описание | +|-------|------|---------|-------------| +| `act_mem_update_interval` | int | 300 | Интервал обновления активной памяти (в секундах) | +| `context_window_size` | int | 5 | Размер контекстного окна для истории диалога | +| `activation_mem_size` | int | 5 | Размер активной памяти | +| `act_mem_dump_path` | str | 自动生成 | Путь к файлу для хранения активной памяти | + +### Типы Бэкенда + +- `general_scheduler`: Расширенный планировщик с управлением активацией памяти + +### Пример Конфигурации Планировщика + +```json +{ + "backend": "general_scheduler", + "config": { + "top_k": 10, + "top_n": 5, + "act_mem_update_interval": 300, + "context_window_size": 5, + "activation_mem_size": 1000, + "thread_pool_max_workers": 10, + "consume_interval_seconds": 3, + "enable_parallel_dispatch": true + } +} +``` + +## Метод Инициализации + +### Из JSON Файла + +```python +from memos.configs.mem_os import MOSConfig + +# Загрузка конфигурации из файла JSON +mos_config = MOSConfig.from_json_file("path/to/config.json") +``` + +### Из Словаря + +```python +from memos.configs.mem_os import MOSConfig + +# Создание конфигурации из словаря +config_dict = { + "user_id": "root", + "chat_model": { + "backend": "huggingface", + "config": { + "model_name_or_path": "Qwen/Qwen3-1.7B", + "temperature": 0.1 + } + } + # ... other fields +} + +mos_config = MOSConfig(**config_dict) +``` + +### Использование Фабричного Шаблона + +```python +from memos.configs.llm import LLMConfigFactory + +# Создание конфигурации LLM с использованием фабричного метода +llm_config = LLMConfigFactory( + backend="huggingface", + config={ + "model_name_or_path": "Qwen/Qwen3-1.7B", + "temperature": 0.1 + } +) +``` + +## Примеры Конфигурации + +### Создание Полного MOS + +```python +from memos.configs.mem_os import MOSConfig +from memos.mem_os.main import MOS + +# Загрузка конфигурации +mos_config = MOSConfig.from_json_file("examples/data/config/simple_memos_config.json") + +# Инициализация MOS +mos = MOS(mos_config) + +# Создание Пользователя И Регистрация Куба +user_id = "user_123" +mos.create_user(user_id=user_id) +mos.register_mem_cube("path/to/mem_cube", user_id=user_id) + +# Использование MOS +response = mos.chat("Hello, how are you?", user_id=user_id) +``` + +### Деревовидная Конфигурация Памяти + +```python +from memos.configs.memory import MemoryConfigFactory + +# Создание Деревовидной Конфигурации Памяти +tree_memory_config = MemoryConfigFactory( + backend="tree_text", + config={ + "memory_filename": "tree_memory.json", + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b", + "temperature": 0.0, + "max_tokens": 8192 + } + }, + "dispatcher_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": "qwen3:0.6b", + "temperature": 0.0, + "max_tokens": 8192 + } + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": "nomic-embed-text:latest" + } + }, + "graph_db": { + "backend": "neo4j", + "config": { + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "password", + "db_name": "memories", + "auto_create": True, + "embedding_dimension": 768 + } + } + } +) +``` + +### Конфигурация Много Бэкендового LLM + +```python +from memos.configs.llm import LLMConfigFactory + +# Конфигурация OpenAI +openai_config = LLMConfigFactory( + backend="openai", + config={ + "model_name_or_path": "gpt-4o", + "temperature": 0.8, + "max_tokens": 1024, + "api_key": "sk-...", + "api_base": "https://api.openai.com/v1" + } +) + +# Конфигурация Ollama +ollama_config = LLMConfigFactory( + backend="ollama", + config={ + "model_name_or_path": "qwen3:0.6b", + "temperature": 0.8, + "max_tokens": 1024, + "api_base": "http://localhost:11434" + } +) + +# Конфигурация HuggingFace +hf_config = LLMConfigFactory( + backend="huggingface", + config={ + "model_name_or_path": "Qwen/Qwen3-1.7B", + "temperature": 0.1, + "remove_think_prefix": True, + "max_tokens": 4096, + "do_sample": False, + "add_generation_prompt": True + } +) +``` + +Эта всеобъемлющая система конфигурации позволяет гибкую и масштабируемую настройку MemOS с различными бэкендами и компонентами diff --git a/content/ru/open_source/open_source_api/chat/chat.md b/content/ru/open_source/open_source_api/chat/chat.md new file mode 100644 index 00000000..29a42f13 --- /dev/null +++ b/content/ru/open_source/open_source_api/chat/chat.md @@ -0,0 +1,86 @@ +--- +title: Диалог +desc: Интеграция полного цикла "поиск, генерация, хранение" RAG замкнутого интерфейса, поддерживающего персонализированные ответы и автоматическое накопление памяти на основе MemCube. +--- + +::: +Об полный список полей API, форматов и другой информации см. в [Документации интерфейса Chat](/api_docs/chat/chat). +::: + +**Путь интерфейса**: +* **Полный Ответ**:`POST /product/chat/complete` +* **Потоковый Ответ (SSE)**:`POST /product/chat/stream` + +**Описание функции**:Данный интерфейс является основным входом для оркестрации бизнес-процессов MemOS. Он может автоматически извлекать соответствующую память из указанных `readable_cube_ids`, генерировать ответ в сочетании с текущим контекстом и, при необходимости, автоматически записывать результаты диалога в `writable_cube_ids`, обеспечивая саморазвитие AI-приложений. + + +## 1. Основная архитектура: Процесс Оркестрации ChatHandler + +1. **Извлечение памяти (Retrieval)**:Вызывая **SearchHandler** на основе `readable_cube_ids`, извлекаются соответствующие факты, предпочтения и контекст инструментов из изолированного Cube. +2. **Усиленная генерация контекста (Generation)**:Извлеченные фрагменты памяти внедряются в Prompt, вызывая указанный LLM (через `model_name_or_path`) для генерации целевых ответов. +3. **Автоматическая замкнутая память (Storage)**:Если включен `add_message_on_answer=true`, система вызовет **AddHandler**, чтобы асинхронно сохранить текущий диалог в указанный Cube, без необходимости ручного вызова интерфейса добавления разработчиком. +## 2. Ключевые параметры интерфейса + +### 2.1 Идентичность и контекст +| Имя Параметра | Тип | Обязательный | Описание | +| :--- | :--- | :--- | :--- | +| **`query`** | `str` | Да | Текущий вопрос пользователя. | +| **`user_id`** | `str` | Да | Уникальный идентификатор пользователя, используемый для аутентификации и изоляции данных. | +| `history` | `list` | Нет | Краткосрочная история диалогов, используемая для поддержания связности текущей сессии. | +| `session_id` | `str` | Нет | Идентификатор сессии. Используется как "мягкий сигнал" для повышения веса вызова связанных воспоминаний в этой сессии. | + +### 2.2 Контроль чтения и записи MemCube +| Имя Параметра | Тип | Значение По Умолчанию | Описание | +| :--- | :--- | :--- | :--- | +| **`readable_cube_ids`** | `list` | - | **Чтение:** Список идентификаторов памяти Cube, разрешенных для извлечения (может пересекаться с личными и общими библиотеками). | +| **`writable_cube_ids`** | `list` | - | **Запись:** Список целевых идентификаторов Cube, в которые должны сохраняться автоматически сгенерированные воспоминания после завершения диалога. | +| **`add_message_on_answer`** | `bool` | `true` | Включить ли автоматическую запись. Рекомендуется включить для поддержания постоянного обновления воспоминаний. | + +### 2.3 Конфигурация алгоритмов и моделей +| Имя Параметра | Тип | Значение По Умолчанию | Описание | +| :--- | :--- | :--- | :--- | +| `mode` | `str` | `fast` | Режим извлечения: `fast` (быстрый), `fine` (тонкий), `mixture` (смешанный). | +| `model_name_or_path` | `str` | - | Укажите название или путь к используемой модели LLM. | +| `system_prompt` | `str` | - | Переопределить стандартный системный подсказ. | +| `temperature` | `float` | - | Температура выборки, контролирующая креативность генерируемого текста. | +| `threshold` | `float` | `0.5` | Порог релевантности для вызова памяти, память ниже этого значения будет исключена. | + +## 3. Принцип работы + +MemOS предлагает два режима ответа на выбор: +### 3.1 Полный ответ (`/complete`) +* **Особенности**:Ожидание генерации всего содержимого моделью и одновременный возврат JSON. +* **Сценарий**:Неинтерактивные задачи, обработка логики в фоновом режиме или простые приложения с низкими требованиями к времени отклика. + +### 3.2 Потоковый ответ (`/stream`) +* **Особенности**:Использует протокол **Server-Sent Events (SSE)** для реального времени передачи токенов. +* **Сценарий**:Чат-боты, интеллектуальные помощники и другие UI-взаимодействия, требующие мгновенной обратной связи в стиле печатной машинки. + +## 4. Быстрый старт + +Рекомендуется использовать встроенный в открытой версии `MemOSClient` для вызова. Следующий пример демонстрирует, как запросить советы по изучению языка R и использовать функции памяти: + +```python +from memos.api.client import MemOSClient + +client = MemOSClient(api_key="...", base_url="...") + +# Инициация Запроса Диалога +res = client.chat( + user_id="dev_user_01", + query="Рекомендуйте набор решений для очистки данных на языке R в соответствии с моими предыдущими предпочтениями", + readable_cube_ids=["private_cube_01", "public_kb_r_lang"], # Чтение: Личные предпочтения + Общественная библиотека + writable_cube_ids=["private_cube_01"], # Запись: Сохранение в личное пространство + add_message_on_answer=True, # Включить автоматическую запись памяти + mode="fine" # Использовать режим точного поиска +) + +if res: + print(f"AI Ответ: {res.data}") +``` + + +::: +**Совет разработчика:** +Если необходимо отладить в среде `Playground`, пожалуйста, посетите специальный интерфейс потока отладки /product/chat/stream/playground. +::: diff --git a/content/ru/open_source/open_source_api/core/add_memory.md b/content/ru/open_source/open_source_api/core/add_memory.md new file mode 100644 index 00000000..682c3de7 --- /dev/null +++ b/content/ru/open_source/open_source_api/core/add_memory.md @@ -0,0 +1,70 @@ +--- +title: Добавить Память (Add Memory) +desc: Основной производственный интерфейс MemOS. Через механизм изоляции MemCube реализуется асинхронное производство личной памяти, базы знаний и многопользовательских сценариев. + +**Путь интерфейса**: `POST /product/add` +**Описание функции**: Это основной вход для хранения неструктурированных данных в системе. Он поддерживает преобразование исходных данных в структурированные фрагменты памяти через списки диалогов, чистый текст или метаданные. В открытой версии система реализует физическую изоляцию и динамическую организацию памяти через **MemCube**. + +## 1. Основной Механизм: MemCube и Изоляция + +В открытой архитектуре понимание MemCube является ключом к эффективному использованию интерфейса: + +* **Изоляционная Единица**: MemCube является атомной единицей генерации памяти, Кубы полностью независимы друг от друга, система выполняет дедупликацию и разрешение конфликтов только внутри одного Куба. +* **Гибкое Отображение**: + * **Личный Режим**: Передайте `user_id` как `writable_cube_ids`, чтобы создать личную частную память. + * **Режим Базы Знаний**: Передайте уникальный идентификатор базы знаний (QID) как `writable_cube_ids`, содержимое будет сохранено в этой базе знаний. +* **Многозадачная Запись**: Интерфейс поддерживает одновременную запись памяти в несколько Кубов, реализуя междоменную синхронизацию. + + +## 2. Ключевые Параметры Интерфейса + +Основные параметры определены следующим образом: + +| Параметр | Тип | Обязательный | Значение по умолчанию | Описание | +| :--- | :--- | :--- | :--- | :--- | +| **`user_id`** | `str` | Да | - | Уникальный идентификатор пользователя, используемый для проверки прав доступа. | +| **`messages`** | `list/str`| Да | - | Список сообщений для хранения или чистый текст. | +| **`writable_cube_ids`** | `list[str]`| Да | - | **Ключевой параметр**: список идентификаторов целевых кубов для записи. | +| **`async_mode`** | `str` | Нет | `async` | Режим обработки: `async` (обработка в фоновом режиме) или `sync` (блокировка текущего запроса). | +| **`is_feedback`** | `bool` | Нет | `false` | Если `true`, система автоматически перенаправит на обработчик обратной связи для выполнения коррекции памяти. | +| `session_id` | `str` | Нет | `default` | Идентификатор сессии, используемый для отслеживания контекста диалога. | +| `custom_tags` | `list[str]`| Нет | - | Пользовательские теги, которые могут использоваться в качестве условий фильтрации при последующем поиске. | +| `info` | `dict` | Нет | - | Расширенные метаданные. Все пары ключ-значение поддерживают последующую фильтрацию и поиск. | +| `mode` | `str` | Нет | - | Действует только при `async_mode='sync'`, возможные значения `fast` (быстрый) или `fine` (точный). | + +## 3. Принцип Работы (Component & Handler) + +Когда запрос достигает бэкенда, система с помощью **AddHandler** вызывает основные компоненты для выполнения следующей логики: + +1. **Мультимодальный Анализ**: Компонент `MemReader` преобразует `messages` в внутренние объекты памяти. +2. **Маршрутизация Обратной Связи**: Если `is_feedback=True`, Handler извлекает конец диалога как обратную связь, напрямую исправляя существующую память, не создавая новых фактов. +3. **Асинхронное Распределение**: Если режим `async`, `MemScheduler` помещает задачу в очередь задач, интерфейс немедленно возвращает `task_id`. +4. **Внутренняя Организация**: Алгоритм выполняет организационную логику в целевом Кубе, оптимизируя качество памяти через дедупликацию и слияние. + +## 4. Пример Быстрого Начала + +Рекомендуется использовать SDK `MemOSClient` для стандартизированных вызовов: + +```python +from memos.api.client import MemOSClient + +# Инициализация Клиента +client = MemOSClient(api_key="...", base_url="...") + +# Сценарий 1: Добавление Памяти для Личного Пользователя +client.add_message( + user_id="sde_dev_01", + writable_cube_ids=["user_01_private"], + messages=[{"role": "user", "content": "Я изучаю ggplot2 в языке R."}], + async_mode="async", + custom_tags=["Programming", "R"] +) +# Сценарий 2: Импорт Содержимого в Базу Знаний и Включение Обратной Связи +client.add_message( + user_id="admin_01", + writable_cube_ids=["kb_finance_2026"], + messages="Процесс финансового аудита на 2026 год обновлен, пожалуйста, смотрите приложение." + is_feedback=True, # Пометить как отзыв для исправления старой версии процесса + info={"source": "Internal_Portal"} +) +``` diff --git a/content/ru/open_source/open_source_api/core/delete_memory.md b/content/ru/open_source/open_source_api/core/delete_memory.md new file mode 100644 index 00000000..d866903b --- /dev/null +++ b/content/ru/open_source/open_source_api/core/delete_memory.md @@ -0,0 +1,62 @@ +--- +title: Удаление Памяти (Delete Memory) +desc: Постоянно удалить записи памяти, связанные файлы или наборы памяти, соответствующие определенным условиям фильтрации, из указанного MemCube. +--- + +**Путь интерфейса**:`POST /product/delete_memory` +**Описание функции**:Этот интерфейс используется для поддержания точности и соответствия базы памяти. Когда пользователь запрашивает забыть определенную информацию, данные устарели или необходимо очистить определенные загруженные файлы, можно использовать этот интерфейс для синхронного выполнения физического удаления в векторной базе данных и графовой базе данных. + +## 1. Основной Механизм: Физическая Очистка Уровня Cube + +В открытой версии операция удаления следует строгой логике изоляции **MemCube**: + +* **Ограничение Области**:С помощью параметра `writable_cube_ids` операция удаления строго ограничена в указанной памяти и никогда не удалит содержимое других Cube по ошибке. +* **Многомерное Удаление**:Поддерживает одновременное выполнение очистки по трем измерениям: **ID памяти** (точное), **ID файла** (сопутствующее удаление) и **Фильтр** (логика условий). +* **Атомарная Синхронизация**:Операция удаления инициируется **MemoryHandler**, что обеспечивает синхронное удаление сущностных узлов в нижележащем векторном индексе и графовой базе данных, предотвращая вызов "иллюзий". + + + +## 2. Ключевые Параметры Интерфейса +Основные параметры определены следующим образом: + +| Параметр | Тип | Обязательный | Описание | +| :--- | :--- | :--- | :--- | +| **`writable_cube_ids`** | `list[str]` | Да | Укажите список целевых Кубов для выполнения операции удаления. | +| **`memory_ids`** | `list[str]` | Нет | Список уникальных идентификаторов памяти для удаления. | +| **`file_ids`** | `list[str]` | Нет | Список идентификаторов исходных файлов для удаления, все связанные с ними воспоминания будут очищены. | +| **`filter`** | `object` | Нет | Логический фильтр. Поддерживает массовое удаление воспоминаний, соответствующих условиям по меткам, метаданным или временным меткам. | + +## 3. Принцип Работы (MemoryHandler) + +1. **Права и Маршрутизация**:Система проверяет права на выполнение операции через `user_id` и маршрутизирует запрос к **MemoryHandler**. +2. **Локализация Хранения**:На основе `writable_cube_ids` локализует нижележащий компонент **naive_mem_cube**. +3. **Распределение Задач Очистки**: + * **Очистка по ID**:Непосредственно выполняет стирание записей в основной базе данных и векторной базе по UUID. + * **Очистка по Фильтру**:Сначала извлекает наборы ID памяти, соответствующие условиям, затем выполняет массовое физическое удаление. +4. **Обратная Связь по Статусу**:После завершения операции возвращает статус успеха, соответствующее содержимое немедленно исчезнет из диапазона вызова [**Интерфейса Поиска**](./search_memory.md). + +## 4. Пример Быстрого Начала + +Используйте `MemOSClient` для выполнения операций удаления по различным измерениям: + +```python +# Инициализация клиента +client = MemOSClient(api_key="...", base_url="...") + +# Сценарий 1: Точное удаление одной известной ошибочной памяти +client.delete_memory( + writable_cube_ids=["user_01_private"], + memory_ids=["2f40be8f-736c-4a5f-aada-9489037769e0"] +) + +# Сценарий 2: Массовая очистка всех устаревших воспоминаний под одной конкретной меткой +client.delete_memory( + writable_cube_ids=["kb_finance_2026"], + filter={"tags": {"contains": "deprecated_policy"}} +) +``` +## 5. Важные Замечания + +Необратимость: Операция удаления является физическим удалением. После успешного выполнения эта память не может быть вызвана снова через интерфейс поиска. + +Связь с Файлом: При удалении через `file_ids` система автоматически отслеживает и очищает фактическую память и резюме, извлеченные из этого файла. diff --git a/content/ru/open_source/open_source_api/core/get_memory.md b/content/ru/open_source/open_source_api/core/get_memory.md new file mode 100644 index 00000000..6898dfa9 --- /dev/null +++ b/content/ru/open_source/open_source_api/core/get_memory.md @@ -0,0 +1,81 @@ +--- +title: Получение Памяти (Get Memories) +desc: Пагинация или полной экспорт заданной коллекции памяти в Cube, поддержка фильтрации по типу и извлечения подграфа. +--- + +**Путь к интерфейсу**: +* **Пагинация Запроса**:`POST /product/get_memory` +* **Полный Экспорт**:`POST /product/get_all` + +**Описание функции**:Используется для перечисления или экспорта заданных активов памяти в **MemCube**. С помощью этих двух интерфейсов вы можете получить оригинальные фрагменты памяти, сгенерированные системой, предпочтения пользователей или записи использования инструментов, поддержка пагинации и структурированного экспорта. + +## 1. Основной Механизм: Пагинация vs. Полный Экспорт + +В открытой версии система предоставляет два различных режима доступа к коллекции через **MemoryHandler**: + +* **Бизнес Пагинация (`/get_memory`)**: + * **Цель проектирования**:Для дизайна списка пользовательского интерфейса. Поддержка параметров `page` и `page_size`. + * **Особенности**:По умолчанию включает предпочтительную память (`include_preference`), поддержка легкой загрузки данных. +* **Полный Экспорт (`/get_all`)**: + * **Цель проектирования**:Для миграции данных или сложного анализа отношений. + * **Основная способность**:Поддержка передачи `search_query` для извлечения связанных **подграфов (Subgraph)** или экспорта всех данных по `memory_type` (текст/действие/параметр). + + +## 2. Ключевые Параметры Интерфейса + +### 2.1 Параметры Пагинации (`/get_memory`) + +| Параметр | Тип | Обязательный | Описание | +| :--- | :--- | :--- | :--- | +| **`mem_cube_id`** | `str` | Да | Целевой MemCube ID. | +| **`user_id`** | `str` | Нет | Уникальный идентификатор пользователя. | +| **`page`** | `int` | Нет | Номер страницы (начиная с 1). Если установлено в `None`, будет попытка полного экспорта. | +| **`page_size`** | `int` | Нет | Количество записей на странице. | +| `include_preference` | `bool` | Нет | Включать ли предпочтительные воспоминания. | + +### 2.2 Параметры Полного Экспорта/Подграфа (`/get_all`) + +| Параметр | Тип | Обязательный | Описание | +| :--- | :--- | :--- | :--- | +| **`user_id`** | `str` | Да | Идентификатор пользователя. | +| **`memory_type`** | `str` | Да | Тип памяти: `text_mem`, `act_mem`, `para_mem`. | +| `mem_cube_ids` | `list` | Нет | Список Cube ID для экспорта. | +| `search_query` | `str` | Нет | Если предоставлено, будет выполнен поиск и возвращены соответствующие подграфы памяти. | + +## 3. Пример Быстрого Начала + +### 3.1 Пагинация на стороне клиента (Вызов SDK) + +```python +# Получить первую страницу, 10 записей памяти на страницу +res = client.get_memory( + user_id="sde_dev_01", + mem_cube_id="cube_research_01", + page=1, + page_size=10 +) + +for mem in res.data: + print(f"[{mem['type']}] {mem['memory_value']}") +``` +### 3.2 Экспорт Определенного Факта Памяти Подграфа +```python +# Извлечь все фактические воспоминания, связанные с "R языком" +res = client.get_all( + user_id="sde_dev_01", + memory_type="text_mem", + search_query="R language visualization" +) +``` + +## 4. Описание Структуры Ответа +Интерфейс возвращает стандартный бизнес-ответ, в котором data содержит массив объектов памяти. Каждый объект памяти обычно включает в себя следующие ключевые поля: + +`id`: Уникальный идентификатор памяти, используемый для выполнения операций Получить Подробности или Удалить. + +`memory_value`: Текст памяти, обработанный алгоритмом. + +`tags`: Связанные пользовательские метки. + +::note +Совет разработчика: Если вы знаете ID памяти и хотите просмотреть ее полные метаданные (например, confidence или usage записи), используйте интерфейс `Получить Подробности Памяти` (Get_memory_by_id). ::: diff --git a/content/ru/open_source/open_source_api/core/get_memory_by_id.md b/content/ru/open_source/open_source_api/core/get_memory_by_id.md new file mode 100644 index 00000000..db0ea7ab --- /dev/null +++ b/content/ru/open_source/open_source_api/core/get_memory_by_id.md @@ -0,0 +1,58 @@ +--- +title: Получение Подробностей О Памяти (Get Memory Detail) +desc: Получите полные метаданные одной записи памяти по уникальному идентификатору (ID), включая уверенность, фоновую информацию и историю использования. +--- + +**Путь к интерфейсу**:`GET /product/get_memory/{memory_id}` +**Описание функции**:Этот интерфейс позволяет разработчикам извлекать все основные детали одной записи памяти. В отличие от интерфейса поиска, который возвращает сводную информацию, этот интерфейс раскрывает данные о жизненном цикле этой памяти (такие как состояние синхронизации векторов, фоновая информация AI и т.д.), что является основным инструментом для управления системой и устранения неполадок. + +## 1. Почему Нужно Получать Подробности? + +* **Метаданные**:Просмотрите `confidence` и `background`, когда AI извлекал эту запись памяти. +* **Проверка Жизненного Цикла**:Подтвердите, успешно ли выполнена `vector_sync` (синхронизация векторов) для этой памяти, а также временную метку `updated_at`. +* **Отслеживание Использования**:Отслеживайте, в каких сессиях эта память была вызвана и помогла в генерации, через записи `usage`. + + +## 2. Ключевые Параметры Интерфейса + +Этот интерфейс использует стандартную форму параметров пути RESTful: + +| Параметр | Место | Тип | Обязательный | Описание | +| :--- | :--- | :--- | :--- | :--- | +| **`memory_id`** | Путь | `str` | Да | Уникальный идентификатор памяти (UUID). Вы можете получить этот ID из [**Получить Список Памяти**](./get_memory_list.md) или результатов [**Поиска**](./search_memory.md). | + +## 3. Принцип Работы (MemoryHandler) + +1. **Прямой Запрос**:**MemoryHandler** напрямую обходит уровень бизнес-оркестрации и взаимодействует с основным компонентом **naive_mem_cube**. +2. **Дополнение Данных**:Система извлекает полный словарь `metadata` из постоянной базы данных и возвращает его, не производя никаких семантических обрезок. + +## 4. Подробности Ответных Данных + +Объект `data` в теле ответа содержит следующие ключевые поля: + +| Название Поля | Описание | +| :--- | :--- | +| **`id`** | Уникальный идентификатор памяти. | +| **`memory`** | Текстовое содержание памяти, обычно включает аннотации (например, `[user观点]`). | +| **`metadata.confidence`** | Уровень уверенности AI в извлечении этой памяти (0.0 - 1.0). | +| **`metadata.type`** | Категория памяти, например, `fact` (факт) или `preference` (предпочтение). | +| **`metadata.background`** | Подробное описание, почему AI извлек эту память и ее контекст. | +| **`metadata.usage`** | В виде списка, фиксирует историю времени и окружения, в которых использовалась эта память. | +| **`metadata.vector_sync`**| Статус синхронизации векторной базы данных, обычно `success`. | + +## 5. Пример Быстрого Начала + +Инициируйте запрос на получение подробностей с помощью SDK: + +```python +# Предполагается, что известен ID памяти +mem_id = "2f40be8f-736c-4a5f-aada-9489037769e0" + +# Получить Полные Подробности +res = client.get_memory_by_id(memory_id=mem_id) + +if res and res.code == 200: + metadata = res.data.get('metadata', {}) + print(f"Контекст Памяти: {metadata.get('background')}") + print(f"Статус Синхронизации: {metadata.get('vector_sync')}") +``` diff --git a/content/ru/open_source/open_source_api/core/search_memory.md b/content/ru/open_source/open_source_api/core/search_memory.md new file mode 100644 index 00000000..44da9d29 --- /dev/null +++ b/content/ru/open_source/open_source_api/core/search_memory.md @@ -0,0 +1,95 @@ +--- +title: Поиск Памяти (Search Memory) +desc: На основе механизма изоляции MemCube, используя семантический поиск и логическую фильтрацию для вызова наиболее релевантной контекстной информации из хранилища памяти. +--- + +**Путь интерфейса**:`POST /product/search` +**Описание функции**:Этот интерфейс является ядром реализации поиска с улучшенной генерацией (RAG) в MemOS. Он может выполнять семантическое соответствие через несколько изолированных **MemCube**, автоматически вызывая соответствующие факты, предпочтения пользователей и записи вызовов инструментов. + +## 1. Основной Механизм: Читаемые Кубы (Readable Cubes) + +В отличие от единой пользовательской перспективы облачных сервисов, интерфейс с открытым исходным кодом реализует чрезвычайно гибкий контроль диапазона поиска через **`readable_cube_ids`**: + +* **Поиск через Кубы**:Вы можете одновременно указать несколько ID Кубов (например, `[Личный Куб Пользователя, Корпоративная Общественная База Знаний Куб]`), алгоритм будет параллельно вызывать наиболее релевантный контент из этих изолированных хранилищ памяти. +* **Вес мягких сигналов**:Передавая `session_id`, система будет при вызове в первую очередь учитывать контент внутри этой сессии. Это служит лишь для повышения релевантности "веса", а не для обязательной фильтрации. +* **Абсолютная Изоляция**:Контент Кубов, не включенных в список `readable_cube_ids`, полностью невидим на уровне алгоритма, что обеспечивает безопасность данных в многопользовательской среде. + + + +## 2. Ключевые Параметры Интерфейса + +Определение основных параметров поиска следующее: + +### Основы Поиска +| Параметр | Тип | Обязательный | Описание | +| :--- | :--- | :--- | :--- | +| **`query`** | `str` | Да | Пользовательский поисковый запрос, на основе которого система будет выполнять семантическое соответствие. | +| **`user_id`** | `str` | Да | Уникальный идентификатор инициатора запроса, используемый для аутентификации и отслеживания контекста. | +| **`readable_cube_ids`**| `list[str]`| Да | **Ключевой параметр**: указывает список Cube ID, доступных для чтения в этом запросе. | +| **`mode`** | `str` | Нет | **Стратегия поиска**: опционально `fast` (быстрый), `fine` (точный), `mixture` (смешанный). | + +### Контроль Вызова +| Параметр | Тип | Значение по умолчанию | Описание | +| :--- | :--- | :--- | :--- | +| **`top_k`** | `int` | `10` | Максимальное количество возвращаемых текстовых воспоминаний. | +| **`include_preference`**| `bool` | `true` | Нужно ли возвращать связанные воспоминания о предпочтениях пользователя (явные/неявные предпочтения). | +| **`search_tool_memory`**| `bool` | `true` | Нужно ли возвращать связанные записи вызовов инструментов. | +| **`filter`** | `dict` | - | Логический фильтр, поддерживающий точную фильтрацию по меткам или метаданным. | +| **`dedup`** | `str` | - | Стратегия удаления дубликатов: `no` (без удаления), `sim` (семантическое удаление дубликатов), `None` (по умолчанию точное удаление дубликатов). | + +## 3. Принцип Работы (Стратегия SearchHandler) + +Когда запрос достигает сервера, **SearchHandler** вызывает различные компоненты для выполнения поиска в зависимости от указанного `mode`: + +1. **Переписывание Запроса**:Используя LLM для семантического улучшения `query` пользователя, повышая точность соответствия. +2. **Многоуровневое Соответствие**: + * **Быстрый Режим**:Быстрый вызов через векторный индекс, подходит для сценариев с очень высокими требованиями к скорости ответа. + * **Точный Режим**:Добавление этапа повторной сортировки (Rerank), повышая релевантность вызываемого контента. + * **Смешанный Режим**:Сочетание семантического поиска и поиска по графу, вызывая более глубокую связанную память. +3. **Многомерная Агрегация**:Система параллельно ищет факты, предпочтения (`pref_top_k`) и память инструментов (`tool_mem_top_k`), и агрегирует результаты для возврата. +4. **Постобработка Удаления Дубликатов**:Сжимаем сильно схожие записи памяти в соответствии с конфигурацией `dedup`. + +## 4. Пример Быстрого Начала + +Совершение совместного поиска через несколько Кубов с помощью SDK: + +```python +from memos.api.client import MemOSClient + +client = MemOSClient(api_key="...", base_url="...") + +# Сценарий: одновременный поиск воспоминаний пользователя и двух специализированных баз знаний +res = client.search_memory( + user_id="sde_dev_01", + query="На основе моих предыдущих предпочтений, порекомендуйте некоторые визуализационные решения для R", + # Передача списка доступных для чтения Cube, включая личное пространство и две базы знаний + readable_cube_ids=["user_01_private", "kb_r_lang", "kb_data_viz"], + mode="fine", # Используйте точный режим для получения более точных рекомендаций + include_preference=True, # Вызов "Пользователь предпочитает лаконичный стиль" и другие предпочтения + top_k=5 +) + +if res: + # Результаты содержатся в memory_detail_list + print(f"Результаты вызова: {res.data}") +``` + +## 5. Продвинутый: Использование Фильтров (Filter) +SearchHandler поддерживает сложные фильтры для удовлетворения более детализированных бизнес-требований: +```python + +# Пример: искать только воспоминания с меткой "Programming", созданные после 2026 года +search_filter = { + "and": [ + {"tags": {"contains": "Programming"}}, + {"created_at": {"gt": "2026-01-01"}} + ] +} + +res = client.search_memory( + query="Логика очистки данных", + user_id="sde_dev_01", + readable_cube_ids=["user_01_private"], + filter=search_filter +) +``` diff --git a/content/ru/open_source/open_source_api/help/error_codes.md b/content/ru/open_source/open_source_api/help/error_codes.md new file mode 100644 index 00000000..5d571f72 --- /dev/null +++ b/content/ru/open_source/open_source_api/help/error_codes.md @@ -0,0 +1,48 @@ +--- +title: Код Ошибки +--- + +| Код Ошибки | Значение | Рекомендуемое Решение | +| :--- | :--- | :--- | +| **Ошибка Параметра** | | | +| 40000 | Ошибка Запроса Параметра | Проверьте, соответствуют ли имена параметров, типы и форматы требованиям | +| 40001 | Запрашиваемые Данные Не Существуют | Проверьте, правильный ли ресурс ID (например, memory_id) | +| 40002 | Обязательный Параметр Не Может Быть Пустым | Дополните отсутствующие обязательные поля | +| 40003 | Параметр Пустой | Проверьте, не пустой ли переданный список или объект | +| 40006 | Неподдерживаемый Тип | Проверьте значение поля type | +| 40007 | Неподдерживаемый Формат Файла | Загружайте только разрешенные форматы (.pdf, .docx, .doc, .txt) | +| 40008 | Неверное Содержимое Base64 | Проверьте, не содержит ли строка Base64 недопустимые символы | +| 40009 | Неверный Формат Base64 | Проверьте, правильный ли формат кодирования Base64 | +| 40010 | Слишком Длинный Пользовательский ID | Длина user_id не должна превышать 100 символов | +| 40011 | Слишком Длинный ID Сессии | Длина conversation_id не должна превышать 100 символов | +| 40020 | Неверный ID Проекта | Убедитесь, что формат Project ID правильный | +| **Ошибка Аутентификации и Прав Доступа** | | | +| 40100 | Требуется Аутентификация API Key | Добавьте действительный API Key в заголовок | +| 40130 | Требуется API Key Аутентификация | Добавьте действующий API Key в заголовок | +| 40132 | API Key недействителен или истек | Проверьте состояние API Key или сгенерируйте заново | +| **Ошибки Квоты и Ограничения** | | | +| 40300 | Превышен лимит вызовов интерфейса | Получить больше лимитов | +| 40301 | Превышен лимит вызовов токена запроса | Уменьшите вводимый контент или получите больше лимитов | +| 40302 | Превышен лимит вызовов токена ответа | Укоротите ожидаемый вывод или получите больше лимитов | +| 40303 | Длина одного диалога превышает лимит | Уменьшите длину одного ввода/вывода | +| 40304 | Общие вызовы API аккаунта исчерпаны | Получить больше лимитов | +| 40305 | Ввод превышает лимит токена за раз | Уменьшите вводимый контент | +| 40306 | Ошибка аутентификации при удалении памяти | Убедитесь, что у вас есть право удалить эту память | +| 40307 | Удаляемая память не существует | Проверьте, действителен ли memory_id | +| 40308 | Пользователь, соответствующий удаляемой памяти, не существует | Проверьте, правильный ли user_id | +| **Ошибки Системы и Сервиса** | | | +| 50000 | Внутренняя ошибка системы | Сервер перегружен или возникла ошибка, пожалуйста, свяжитесь с поддержкой | +| 50002 | Операция не удалась | Проверьте логику операции или повторите попытку позже | +| 50004 | Служба памяти временно недоступна | Повторите попытку записи/получения памяти позже | +| 50005 | Служба поиска временно недоступна | Повторите попытку поиска памяти позже | +| **Ошибка Базы Знаний И Операций** | | | +| 50103 | Превышено количество файлов | Максимальное количество файлов для загрузки за один раз не должно превышать 20 | +| 50104 | Размер одного файла превышает лимит | Убедитесь, что размер одного файла не превышает 100MB | +| 50105 | Общий размер всех файлов превышает лимит | Убедитесь, что общий размер загрузки за один раз не превышает 300MB | +| 50107 | Формат загружаемого файла не соответствует требованиям | Проверьте и измените формат файла | +| 50120 | База знаний не существует | Убедитесь, что ID базы знаний правильный | +| 50123 | База знаний не связана с этим проектом | Убедитесь, что база знаний была авторизована для текущего проекта | +| 50131 | Задача не существует | Проверьте, правильный ли task_id (часто встречается при проверке статуса обработки) | +| 50143 | Не удалось добавить память | Исключение при обработке алгоритмической службы, повторите попытку позже | +| 50144 | Не удалось добавить сообщение | Не удалось сохранить историю чата | +| 50145 | Не удалось сохранить отзыв и записать память | Произошло исключение в процессе обработки отзыва | diff --git a/content/ru/open_source/open_source_api/message/feedback.md b/content/ru/open_source/open_source_api/message/feedback.md new file mode 100644 index 00000000..21683234 --- /dev/null +++ b/content/ru/open_source/open_source_api/message/feedback.md @@ -0,0 +1,78 @@ +--- +title: Добавить Обратную Связь +desc: Отправить пользователем обратную связь о ответах большой модели, чтобы помочь MemOS в реальном времени исправлять, оптимизировать или удалять неточные воспоминания. +--- + + +**Путь Интерфейса**:`POST /product/feedback` +**Описание Функции**:Этот интерфейс используется для обработки обратной связи пользователей о ответах ИИ или содержимом воспоминаний. Анализируя `feedback_content`, система может автоматически находить и исправлять ошибочные факты, хранящиеся в **MemCube**, или корректировать вес воспоминаний на основе положительной или отрицательной обратной связи пользователей. + +## 1. Основной Механизм: Цикл Коррекции Воспоминаний + +**FeedbackHandler** предоставляет более тонкую логику управления, чем обычный интерфейс добавления: + +* **Точное Исправление (Precise Correction)**:Предоставив `retrieved_memory_ids`, система может непосредственно исправить несколько конкретных результатов поиска, избегая случайного повреждения других воспоминаний. +* **Анализ Контекста**:С учетом `history` (истории диалога), система может понять истинные намерения, стоящие за обратной связью (например, "Вы ошиблись, моя текущая компания - A, а не B"). +* **Отображение Результатов**:Если включен `corrected_answer=true`, интерфейс после обработки исправления воспоминаний попытается вернуть ответ, основанный на новых фактах. + +## 2. Ключевые Параметры Интерфейса +Основные параметры этого интерфейса определены следующим образом: + +| Параметр | Тип | Обязательный | Значение по умолчанию | Описание | +| :--- | :--- | :--- | :--- | :--- | +| **`user_id`** | `str` | Да | - | Уникальный идентификатор пользователя. | +| **`history`** | `list` | Да | - | Последняя история диалогов, используемая для предоставления контекста обратной связи. | +| **`feedback_content`** | `str` | Да | - | **Основное:** Текст обратной связи пользователя. | +| **`writable_cube_ids`**| `list` | Нет | - | Список целевых Кубов, для которых необходимо выполнить коррекцию памяти. | +| `retrieved_memory_ids` | `list` | Нет | - | Необязательно. Список конкретных идентификаторов памяти, которые были извлечены в последний раз и нуждаются в исправлении. | +| `async_mode` | `str` | Нет | `async` | Режим обработки: `async` (фоновая обработка) или `sync` (обработка в реальном времени с ожиданием). | +| `corrected_answer` | `bool` | Нет | `false` | Нужно ли системе вернуть исправленный новый ответ после коррекции памяти. | +| `info` | `dict` | Нет | - | Дополнительные метаданные. | + +## 3. Принцип Работы + +1. **Обнаружение Конфликтов**:После получения обратной связи `FeedbackHandler` сравнивает `history` с существующими фактами воспоминаний в `writable_cube_ids`. +2. **Локализация и Обновление**: + * Если предоставлены `retrieved_memory_ids`, то соответствующие узлы обновляются напрямую. + * Если ID не предоставлены, система находит наиболее релевантные устаревшие воспоминания для замены или помечает их как недействительные через семантическое соответствие. +3. **Корректировка Весов**:Для нечеткой обратной связи система корректирует `confidence` (уровень уверенности) или уровень достоверности конкретных записей воспоминаний. +4. **Асинхронное Производство**:В режиме `async` логика исправления выполняется асинхронно `MemScheduler`, интерфейс немедленно возвращает `task_id`. + +## 4. Пример Быстрого Начала + + +```python +from memos.api.client import MemOSClient + +client = MemOSClient(api_key="...", base_url="...") + +# Сценарий: Коррекция ошибочной памяти AI о профессии пользователя +res = client.add_feedback( + user_id="dev_user_01", + feedback_content="Я больше не худею, сейчас не нужно контролировать питание.\n" + history=[ + {"role": "assistant", "content": "Вы находитесь на диете, контролировали ли вы недавно калории в пище?"}, + {"role": "user", "content": "Я больше не худею..."} + ], + writable_cube_ids=["private_cube_01"], + # Укажите конкретный идентификатор ошибочной памяти для точного воздействия + retrieved_memory_ids=["mem_id_old_job_123"], + corrected_answer=True # Требуется, чтобы AI ответил мне заново на основе новых фактов +) + +if res and res.code == 200: + print(f"Исправление Прогресса: {res.message}") + if res.data: + print(f"Исправленный Ответ: {res.data}") +``` + + +## 5. Сценарии Использования +### 5.1 Исправление Ошибочных Выводов ИИ +Ручное вмешательство: В административной панели предоставляется кнопка "Исправить Ошибку", когда администратор обнаруживает, что извлеченные ИИ записи воспоминаний неверны, вызывается этот интерфейс для ручного исправления. +### 5.2 Обновление Устаревших Пользовательских Предпочтений +Мгновенная коррекция пользователем: В пользовательском интерфейсе диалога, если пользователь говорит что-то вроде "Я ошибся", "Это не так" и т.д., этот интерфейс может быть автоматически вызван, используя is_feedback=True для реализации мгновенной очистки воспоминаний. + +::note +Если обратная связь касается общедоступной базы знаний, пожалуйста, убедитесь, что текущий пользователь имеет права на запись в этот Cube. +:: diff --git a/content/ru/open_source/open_source_api/message/get_message.md b/content/ru/open_source/open_source_api/message/get_message.md new file mode 100644 index 00000000..d2e05599 --- /dev/null +++ b/content/ru/open_source/open_source_api/message/get_message.md @@ -0,0 +1,75 @@ +--- +title: Получение Сообщений +desc: Получение оригинальной истории диалога между пользователем и помощником в указанном сеансе, используемой для построения интерфейса чата или извлечения оригинального контекста. +--- + +::warning +**[Прямо Смотрите Документацию API Здесь](/api_docs/message/get_message)** +
+
+ +**Данный документ сосредоточен на функциональном описании открытого проекта, подробные поля интерфейса и ограничения можно посмотреть, нажав на текстовую ссылку выше** +:: + +**Путь интерфейса**:`POST /product/get/message` +**Описание функции**:Этот интерфейс используется для получения оригинальных записей диалога между пользователем и помощником в указанном сеансе. В отличие от интерфейса "памяти", который возвращает сводную информацию, этот интерфейс возвращает необработанный оригинальный текст, который является основным интерфейсом для построения функции обратного просмотра истории чата. + +## 1. Память (Memory) vs Сообщение (Message) + +В процессе разработки, пожалуйста, различайте следующие два типа данных: +* **Получение памяти (`/get_memory`)**:Возвращает обработанный системой **сводный отчет о фактах и предпочтениях** (например: "Пользователь предпочитает язык R для визуализации"). +* **Получение сообщений (`/get_message`)**:Возвращает **оригинальный текст диалога** (например: "Я недавно сам изучаю язык R, порекомендуйте пакет для визуализации"). + +## 2. Ключевые Параметры Интерфейса +Данный интерфейс поддерживает следующие параметры: + +| Параметр | Тип | Обязательный | Значение по умолчанию | Описание | +| :--- | :--- | :--- | :--- | :--- | +| `user_id` | `str` | Да | - | Уникальный идентификатор пользователя, связанный с получением сообщения. | +| `conversation_id` | `str` | Нет | `None` | Уникальный идентификатор заданной беседы. | +| `message_limit_number` | `int` | Нет | `6` | Ограничение на количество возвращаемых сообщений, максимальное рекомендуемое значение - 50. | +| `conversation_limit_number`| `int` | Нет | `6` | Ограничение на количество возвращаемой истории бесед. | +| `source` | `str` | Нет | `None` | Идентификация канала источника сообщения. | + +## 3. Принцип Работы + + +1. **Определение сеанса**:Система извлекает записи сообщений, принадлежащие данному пользователю и сеансу, из базового хранилища по предоставленному `conversation_id`. +2. **Обработка срезов**:В зависимости от параметра `message_limit_number`, система начинает обратный отсчет от последних сообщений, чтобы обеспечить возврат самых свежих диалогов. +3. **Безопасная изоляция**:Все запросы проходят через промежуточное ПО `RequestContextMiddleware`, строго проверяя право собственности `user_id`, чтобы предотвратить несанкционированный доступ. + +## 4. Пример Быстрого Начала + +Используйте встроенный в открытой версии `MemOSClient` для быстрого извлечения истории диалога: + +```python +from memos.api.client import MemOSClient + +# Инициализация Клиента +client = MemOSClient( + api_key="YOUR_LOCAL_API_KEY", + base_url="http://localhost:8000/product" +) + +# Получение 10 Последних Записей Беседы +res = client.get_message( + user_id="memos_user_123", + conversation_id="conv_r_study_001", + message_limit_number=10 +) + +if res and res.code == 200: + # Перебор возвращаемого списка сообщений + for msg in res.data: + print(f"[{msg['role']}]: {msg['content']}") +``` + +## 5. Сценарии Использования +### 5.1 Загрузка Истории Чата +Когда пользователь нажимает на определенный исторический сеанс, вызов этого интерфейса может восстановить сцену диалога. Рекомендуется использовать `message_limit_number` для реализации постраничной загрузки, чтобы повысить производительность фронтенда. + +### 5.2 Внедрение Контекста Внешней Модели +Если вы используете собственную логику большого модели (не встроенный интерфейс чата MemOS), вы можете получить оригинальную историю диалога через этот интерфейс и вручную объединить ее в массив сообщений модели. + +### 5.3 Анализ Обратной Связи Сообщений +Вы можете периодически экспортировать оригинальные записи диалога для оценки качества ответов ИИ или анализа потенциальных намерений пользователей. diff --git a/content/ru/open_source/open_source_api/message/get_suggestion_queries.md b/content/ru/open_source/open_source_api/message/get_suggestion_queries.md new file mode 100644 index 00000000..3c1a4d39 --- /dev/null +++ b/content/ru/open_source/open_source_api/message/get_suggestion_queries.md @@ -0,0 +1,70 @@ +--- +title: Получение Предложений (Get Suggestions) +desc: На основе текущего контекста диалога или недавней памяти в Cube автоматически генерируются 3 предложения для последующего диалога. +--- + +# Получение Предложений (Get Suggestion Queries) + +**Путь к интерфейсу**:`POST /product/suggestions` +**Описание функции**:Этот интерфейс реализует функцию "Предположим, что вы хотите спросить". Система будет генерировать 3 связанных вопроса на основе предоставленного контекста диалога или недавней памяти в **MemCube**, чтобы помочь пользователю продолжить диалог. + +## 1. Основной Механизм: Двухрежимная Генерация Стратегии + +**SuggestionHandler** поддерживает два гибких режима генерации в зависимости от входных параметров: + +* **Мгновенные предложения на основе диалога (Context-based)**: + * **Условия активации**:В запросе предоставлено `message` (запись диалога). + * **Логика**:Система анализирует недавнее содержание диалога и генерирует 3 последующих вопроса, тесно связанных с текущей темой. +* **Предложения на основе памяти (Memory-based)**: + * **Условия активации**:`message` не предоставлено. + * **Логика**:Система извлекает "недавнюю память" из памяти, указанной в `mem_cube_id`, и на основе этого генерирует эвристические вопросы, связанные с недавней жизнью и рабочим состоянием пользователя. + + + +## 2. Ключевые Параметры Интерфейса + +Основные параметры определены следующим образом: + +| Параметр | Тип | Обязательный | Значение по умолчанию | Описание | +| :--- | :--- | :--- | :--- | :--- | +| **`user_id`** | `str` | Да | - | Уникальный идентификатор пользователя. | +| **`mem_cube_id`** | `str` | Да | - | **Основной параметр**: Укажите память, на основе которой будут генерироваться рекомендации. | +| **`language`** | `str` | Нет | `zh` | Язык, используемый для генерации рекомендаций: `zh` (китайский) или `en` (английский). | +| `message` | `list/str`| Нет | - | Текущий контекст диалога. Если предоставлено, то генерируются рекомендации на основе диалога. | + +## 3. Принцип Работы (SuggestionHandler) + +1. **Распознавание контекста**:`SuggestionHandler` сначала проверяет поле `message`. Если есть значение, то извлекается суть диалога; если пусто, то обращается к базовому `MemCube` для получения недавней динамики. +2. **Соответствие шаблону**:Система автоматически переключает встроенные шаблоны подсказок (Prompt Templates) на основе параметра `language`. +3. **Моделирование вывода**:Вызывает LLM для вывода на основе фоновых данных, чтобы гарантировать, что сгенерированные 3 вопроса логичны и имеют эвристический характер. +4. **Форматированный вывод**:Возвращает предложенные вопросы в виде массива, чтобы фронтенд мог непосредственно отобразить их как кнопки для нажатия. + +## 4. Пример Быстрого Начала + +Используйте SDK для получения китайских предложений для текущего диалога: + +```python +from memos.api.client import MemOSClient + +client = MemOSClient(api_key="...", base_url="...") + +# Сценарий: Генерация рекомендаций на основе недавнего диалога о "R языке" +res = client.get_suggestions( + user_id="dev_user_01", + mem_cube_id="private_cube_01", + language="zh", + message=[ + {"role": "user", "content": "Я хочу изучить визуализацию на R языке."}, + {"role": "assistant", "content": "Рекомендуем вам изучить пакет ggplot2, который является основным инструментом визуализации на R языке."} + ] +) + +if res and res.code == 200: + # Пример вывода: ["Как установить ggplot2?", "Какие классические учебники по ggplot2?", "Какие еще пакеты для визуализации на R языке?"] + print(f"Рекомендованный вопрос: {res.data}") +``` + +## 5. Рекомендации по Использованию +Направление диалога:После того как ИИ ответит пользователю, автоматически вызывается этот интерфейс, чтобы отобразить кнопки предложений под полем ответа, направляя пользователя к более глубокому обсуждению. + +Активация холодного старта:Когда пользователь входит в новый сеанс и еще не высказался, показываются возможные интересные темы из прошлого через "режим на основе памяти", чтобы разорвать молчание. diff --git a/content/ru/open_source/open_source_api/scheduler/ wait.md b/content/ru/open_source/open_source_api/scheduler/ wait.md new file mode 100644 index 00000000..0c97580a --- /dev/null +++ b/content/ru/open_source/open_source_api/scheduler/ wait.md @@ -0,0 +1,77 @@ +--- +title: Расширенная Синхронизация Задач (Advanced Task Synchronization) +desc: Обеспечивает возможность блокирующего ожидания и потокового наблюдения за прогрессом, гарантируя, что все асинхронные задачи указанного пользователя полностью обработаны перед выполнением последующих операций. +--- + + +**Путь к интерфейсу**: +* **Синхронное Блокирующее Ожидание**:`POST /product/scheduler/wait` +* **Поток Реального Времени (SSE)**:`GET /product/scheduler/wait/stream` + +**Описание функции**:В сценариях автоматизации скриптов, миграции данных или интеграционного тестирования обычно необходимо убедиться, что все асинхронные задачи извлечения памяти (такие как LLM извлечение фактов, векторное хранилище) полностью завершены. Интерфейс этого модуля позволяет клиенту "приостановить" запрос, пока планировщик не обнаружит, что очередь задач целевого пользователя пуста. + +## 1. Основной Механизм: Обнаружение Свободного Планировщика + +Система через **SchedulerHandler** в реальном времени отслеживает состояние работы базового **MemScheduler**: + +* **Проверка очереди**:Система проверяет ожидающие задачи (Pending) и задачи в очереди (Remaining) в Redis Stream, принадлежащие этому пользователю. +* **Определение свободного состояния**:Только когда количество в очереди равно 0 и в данный момент нет Worker, выполняющего задачи этого пользователя, определяется как "свободное (Idle)". +* **Защита от таймаута**:Чтобы избежать бесконечного блокирования, интерфейс поддерживает установку `timeout_seconds`. Если лимит достигнут, а задачи все еще не завершены, интерфейс вернет текущее состояние и прекратит ожидание. + + + +## 2. Ключевые Параметры Интерфейса + +Эти два интерфейса разделяют следующие параметры запроса (Query Parameters): + +| Параметр | Тип | Обязательный | Значение По Умолчанию | Описание | +| :--- | :--- | :--- | :--- | :--- | +| **`user_name`** | `str` | Да | - | Имя или ID целевого пользователя. | +| `timeout_seconds`| `num` | Нет | - | Максимальная продолжительность ожидания (в секундах). Превышение этого времени приведет к автоматическому возврату. | +| `poll_interval` | `num` | Нет | - | Частота внутренней проверки состояния очереди (в секундах). | + +## 3. Выбор Режима Ответа + +### 3.1 Синхронный Блокирующий Режим (`/wait`) +* **Особенности**:Стандартный HTTP ответ. Соединение будет оставаться открытым до тех пор, пока задачи не будут очищены или не истечет время. +* **Сценарий**:Написание автоматизированных тестовых скриптов или обеспечение того, чтобы данные были загружены перед выполнением `search`. + +### 3.2 Режим Реального Времени (`/wait/stream`) +* **Особенности**:На основе технологии **Server-Sent Events (SSE)**. +* **Сценарий**:Отображение динамической полосы прогресса в административной панели, показывающей процесс уменьшения очереди задач в реальном времени. + +## 4. Пример Быстрого Начала + +Использование открытой версии SDK для блокирующего ожидания: + +```python +from memos.api.client import MemOSClient + +client = MemOSClient(api_key="...", base_url="...") +user_name = "dev_user_01" + +# --- Сценарий A:Синхронное Блокирующее Ожидание (обычно используется в автоматизированных скриптах Python) --- +print(f"Ожидание очистки очереди задач пользователя {user_name}...") +res = client.wait_until_idle( + user_name=user_name, + timeout_seconds=300, + poll_interval=2 +) +if res and res.code == 200: + print("✅ Все задачи завершены.") + +# --- Сценарий B:Наблюдение за Потоком Прогресса (обычно используется для рендеринга индикатора прогресса на фронтенде) --- +print("Начинаю слушать поток реального времени задач...") +# Обратите внимание: интерфейс SSE обычно возвращает генератор (Generator) в SDK +progress_stream = client.stream_scheduler_progress( + user_name=user_name, + timeout_seconds=300 +) + +for event in progress_stream: + # Реальное время печати оставшегося количества задач + print(f"Текущее количество задач в очереди: {event['remaining_tasks_count']}") + if event['status'] == 'idle': + print("🎉 Диспетчер свободен") + break +``` diff --git a/content/ru/open_source/open_source_api/scheduler/get_status.md b/content/ru/open_source/open_source_api/scheduler/get_status.md new file mode 100644 index 00000000..03458c61 --- /dev/null +++ b/content/ru/open_source/open_source_api/scheduler/get_status.md @@ -0,0 +1,97 @@ +--- +title: Планирование Задач И Мониторинг Состояния (Scheduler Status) +desc: Мониторинг жизненного цикла асинхронных задач MemOS, предоставляющий всесторонние возможности наблюдения, включая прогресс задач, накопление в очереди и нагрузку на систему. +--- + +**Путь Интерфейса**: +* **Обзор На Уровне Системы**: `GET /product/scheduler/allstatus` +* **Запрос Прогресса Задачи**: `GET /product/scheduler/status` +* **Показатели Очереди Пользователя**: `GET /product/scheduler/task_queue_status` + +**Описание Функции**:Интерфейс этого модуля предназначен для предоставления разработчикам наблюдаемости асинхронной цепочки памяти. С помощью этих интерфейсов вы можете в реальном времени отслеживать состояние выполнения конкретных задач, мониторить накопление задач в очереди Redis и получать показатели работы всей системы планирования. + +## 1. Основной Механизм: Система Планирования MemScheduler + +В открытой архитектуре **MemScheduler** отвечает за обработку всех ресурсоемких фоновых задач (таких как извлечение памяти LLM, построение векторных индексов и т.д.): + +* **Поток Состояний**:Задача в течение жизненного цикла проходит через состояния `waiting` (ожидание), `in_progress` (в процессе выполнения), `completed` (завершено) или `failed` (неудача). +* **Мониторинг Очереди**:Система реализует распределение задач на основе Redis Stream. Мониторя количество `pending` (доставленных, но не подтвержденных) и `remaining` (в очереди) задач, можно оценить нагрузку на систему. +* **Многомерное Наблюдение**:Поддерживает состояние с трех измерений: "одна задача", "очередь одного пользователя" и "обзор всей системы". + + +## 2. Подробности Интерфейса + +### 2.1 Запрос Прогресса Задачи (`/status`) +Используется для отслеживания текущей стадии выполнения конкретной асинхронной задачи. + +| Имя Параметра | Тип | Обязательный | Описание | +| :--- | :--- | :--- | :--- | +| **`user_id`** | `str` | Да | Уникальный идентификатор пользователя для запроса. | +| `task_id` | `str` | Нет | Необязательно. Если предоставлено, то запрашивается только статус этой конкретной задачи. | + +**Описание Статуса Возврата**: +* `waiting`: Задача вошла в очередь, ожидая свободного Worker для выполнения. +* `in_progress`: Worker вызывает большую модель для извлечения памяти или записи в базу данных. +* `completed`: Память успешно сохранена и синхронизирована с векторным индексом. +* `failed`: Задача завершилась неудачей. + +### 2.2 Показатели Очереди Пользователя (`/task_queue_status`) +Используется для мониторинга накопления задач конкретного пользователя в Redis. + +| Имя Параметра | Тип | Обязательный | Описание | +| :--- | :--- | :--- | :--- | +| **`user_id`** | `str` | Да | ID пользователя, для которого необходимо запросить состояние очереди. | + +**Ключевые Показатели**: +* `pending_tasks_count`: Количество задач, распределенных Worker, но еще не получивших подтверждение (Ack). +* `remaining_tasks_count`: Общее количество задач, которые все еще находятся в очереди и ожидают распределения. +* `stream_keys`: Список имен ключей Redis Stream, соответствующих. + +### 2.3 Обзор Системы (`/allstatus`) +Получите глобальный обзор работы планировщика, обычно используется для мониторинга администратором. + +* **Основная Информация Возврата**: + * `scheduler_summary`: Содержит текущую нагрузку и состояние здоровья системы. + * `all_tasks_summary`: Сводная статистика всех выполняемых и ожидающих задач. + +## 3. Принцип Работы (SchedulerHandler) + +Когда вы инициируете запрос на проверку состояния, **SchedulerHandler** выполняет следующие действия: + +1. **Поиск в Кэше**:Сначала ищет текущий прогресс, соответствующий `task_id`, в кэше состояния Redis. +2. **Подтверждение Очереди**:Если запрашиваются показатели очереди, Handler вызывает команды статистики Redis (такие как `XLEN`, `XPENDING`), чтобы проанализировать состояние Stream. +3. **Агрегация Показателей**:Для глобальных запросов состояния Handler собирает показатели всех активных узлов и генерирует сводные данные на уровне системы. + +## 4. Пример Быстрого Начала + +Используйте SDK для опроса состояния задачи до ее завершения: + +```python +from memos.api.client import MemOSClient +import time + +client = MemOSClient(api_key="...", base_url="...") + +# 1. Обзор На Уровне Системы: Просмотр Здоровья Работы Весь MemOS Системы +global_res = client.get_all_scheduler_status() +if global_res: + print(f"Состояние Работы Системы: {global_res.data['scheduler_summary']}") + +# 2. Мониторинг Показателей Очереди: Проверка Накопления Задач Для Конкретного Пользователя +queue_res = client.get_task_queue_status(user_id="dev_user_01") +if queue_res: + print(f"Количество Задач На Обработке: {queue_res.data['remaining_tasks_count']}") + print(f"Количество Выданных Но Не Завершенных Задач: {queue_res.data['pending_tasks_count']}") + +# 3. Отслеживание Прогресса Задачи: Периодическая Проверка Конкретной Задачи До Завершения +task_id = "task_888999" +while True: + res = client.get_task_status(user_id="dev_user_01", task_id=task_id) + if res and res.code == 200: + current_status = res.data[0]['status'] # data является списком статусов + print(f"Задача {task_id} Текущий Статус: {current_status}") + + if current_status in ['completed', 'failed', 'cancelled']: + break + time.sleep(2) +``` diff --git a/content/ru/open_source/open_source_api/start/configuration.md b/content/ru/open_source/open_source_api/start/configuration.md new file mode 100644 index 00000000..4db39cb6 --- /dev/null +++ b/content/ru/open_source/open_source_api/start/configuration.md @@ -0,0 +1,7 @@ +--- +title: Конфигурация Проекта +--- + +Подробное описание конфигурации API сервера открытой версии MemOS (включая движок LLM, хранилище и настройки переменных окружения) можно найти по следующей ссылке: + +👉 [**Руководство По Настройке REST API Сервера**](../../../getting_started/rest_api_server.md) diff --git a/content/ru/open_source/open_source_api/start/overview.md b/content/ru/open_source/open_source_api/start/overview.md new file mode 100644 index 00000000..c65c1535 --- /dev/null +++ b/content/ru/open_source/open_source_api/start/overview.md @@ -0,0 +1,52 @@ +--- +title: Обзор +--- + +## 1. Введение в Интерфейс + +Проект MemOS предоставляет набор высокопроизводительных REST API сервисов, написанных на **FastAPI**. Система использует архитектуру **Component (Компонент) + Handler (Обработчик)**, все основные логики (такие как извлечение памяти, семантический поиск, асинхронное планирование) могут быть вызваны через стандартные REST интерфейсы. + +![MemOS Architecture](https://cdn.memtensor.com.cn/img/memos_run_server_success_compressed.png) +
Обзор Архитектуры Сервиса MemOS REST API
+ +### Основные Функции + +* **Многомерное Производство Памяти**: Поддержка обработки диалогов, текстов или документов через `AddHandler`, с автоматическим преобразованием в структурированную память. +* **Физическая Изоляция MemCube**: Реализация физической изоляции данных и независимых индексов между различными пользователями или базами знаний на основе Cube ID. +* **Замкнутый Цикл Диалога**: Полный процесс «извлечение -> генерация -> асинхронное хранение» организован через `ChatHandler`. +* **Асинхронное Планирование Задач**: Встроенный движок планирования `MemScheduler`, поддерживающий сглаживание пиков и отслеживание состояния для масштабных задач по производству памяти. +* **Механизм Самокоррекции**: Предоставляет интерфейс обратной связи, позволяющий использовать естественный язык для исправления или маркировки уже сохраненной памяти. + +## 2. Руководство по Началу Работы + +Быстро интегрируйте возможности памяти в ваше AI приложение с помощью следующих двух основных шагов: + +* [**Добавить Память**](./core/add_memory.md): Используя интерфейс `POST /product/add`, запишите исходный поток сообщений в указанный MemCube, чтобы начать производственную цепочку. +* [**Извлечь Память**](./core/search_memory.md): Используя интерфейс `POST /product/search`, извлеките соответствующий контекст из нескольких Cube на основе семантической схожести. + +## 3. Классификация Интерфейсов + +Функциональные интерфейсы MemOS делятся на следующие основные категории: + +* **[Основная Память (Core)](./core/add_memory.md)**: Включает атомарные операции добавления, удаления, изменения и поиска памяти. +* **[Интеллектуальный Диалог (Chat)](./chat/chat.md)**: Реализует потоковые или полные ответы на диалоги с улучшенной памятью. +* **[Управление Сообщениями (Message)](./message/feedback.md)**: Охватывает интерфейсы для обратной связи от пользователей, предположений и других улучшенных взаимодействий. +* **[Асинхронное Планирование (Scheduler)](./scheduler/get_status.md)**: Используется для мониторинга прогресса и состояния очереди фоновых задач по извлечению памяти. +* **[Системные Инструменты (Tools)](./tools/check_cube.md)**: Предоставляет вспомогательные функции, такие как проверка существования Cube и обратный поиск принадлежности памяти. + +## 4. Аутентификация и Контекст + +### Механизм Аутентификации +В открытой среде все API запросы должны содержать поле `Authorization` в заголовке. +* **Разработка**: Вы можете настроить `API_KEY` в локальном `.env` или `configuration.md`. +* **Производственный Деплоймент**: Рекомендуется расширить OAuth2 или более сложную логику проверки подлинности через `RequestContextMiddleware`. + +### Контекст Запроса +* **user_id**: Этот идентификатор должен быть включен в тело запроса для отслеживания идентичности на уровне обработчика. +* **MemCube ID**: Основной изолированный элемент в открытой версии. Указав `readable_cube_ids` или `writable_cube_ids`, вы можете точно контролировать физические границы чтения и записи данных. + +## 5. Следующие Шаги + +* 👉 [**Конфигурация Системы**](./start/configuration.md): Настройте вашего поставщика LLM и движок векторной базы данных. +* 👉 [**Добавить Первую Память**](./core/add_memory.md): Попробуйте отправить первую группу сообщений через SDK или Curl. +* 👉 [**Изучить Распространенные Ошибки**](./help/error_codes.md): Узнайте о кодах состояния API и механизмах обработки исключений за ними. diff --git a/content/ru/open_source/open_source_api/tools/check_cube.md b/content/ru/open_source/open_source_api/tools/check_cube.md new file mode 100644 index 00000000..c6a28e2d --- /dev/null +++ b/content/ru/open_source/open_source_api/tools/check_cube.md @@ -0,0 +1,50 @@ +--- +title: Проверка Существования MemCube (Check Cube Existence) +desc: Проверка, инициализирован ли указанный ID MemCube в системе и доступен ли он. +--- + +**Путь интерфейса**:`POST /product/exist_mem_cube_id` +**Описание функции**:Этот интерфейс используется для проверки, существует ли указанный `mem_cube_id` в системе. Он является "сторожевым" интерфейсом для обеспечения согласованности данных, рекомендуется вызывать перед динамическим созданием базы знаний или распределением пространства для новых пользователей, чтобы избежать повторной инициализации или недействительных операций. + +## 1. Основной Механизм: Проверка Индекса Cube + +В архитектуре MemOS существование MemCube определяет законность всех последующих операций памяти: + +* **Логическая проверка**:Система использует **MemoryHandler** для извлечения индекса хранения, чтобы подтвердить, зарегистрирован ли этот ID. +* **Гарантия холодного старта**:Для сценариев создания Cube по запросу этот интерфейс может использоваться для определения необходимости выполнения первоначальной операции `add` для активации памяти. + + + +## 2. Ключевые Параметры Интерфейса +Определение тела запроса следующее: + +| Параметр | Тип | Обязательный | Описание | +| :--- | :--- | :--- | :--- | +| **`mem_cube_id`** | `str` | Да | Уникальный идентификатор MemCube для проверки. | + +## 3. Принцип Работы (MemoryHandler) + +1. **Прямой индекс**:После получения запроса **MemoryHandler** напрямую вызывает интерфейс запроса метаданных нижнего уровня **naive_mem_cube**. +2. **Поиск состояния**:Система ищет в слое постоянного хранения файл конфигурации или запись в базе данных, соответствующую этому ID. +3. **Булевый ответ**:Результат не содержит содержимого памяти, только в форме `code` или `data` сообщает, активирован ли этот Cube. + +## 4. Пример Быстрого Начала + +Используйте SDK для проверки состояния целевого Cube: + +```python +from memos.api.client import MemOSClient + +client = MemOSClient(api_key="...", base_url="...") + +# Сценарий: Подтвердите, что целевая база знаний создана перед импортом документа +kb_id = "kb_finance_2026" +res = client.exist_mem_cube_id(mem_cube_id=kb_id) + +if res and res.code == 200: + # Предположим, что поле data возвращает булево значение или объект существования + if res.data.get('exists'): + print(f"✅ MemCube '{kb_id}' готов.") + else: + print(f"❌ MemCube '{kb_id}' еще не инициализирован.") +``` diff --git a/content/ru/open_source/open_source_api/tools/get_user_names.md b/content/ru/open_source/open_source_api/tools/get_user_names.md new file mode 100644 index 00000000..fa676958 --- /dev/null +++ b/content/ru/open_source/open_source_api/tools/get_user_names.md @@ -0,0 +1,53 @@ +--- +title: Обратный Запрос Пользователя (Get User Names) +desc: По Уникальному Идентификатору (ID) Выполняется Обратный Запрос Имени Пользователя, К которому Принадлежит Эта Память. +--- + +**Путь Интерфейса**:`POST /product/get_user_names_by_memory_ids` +**Описание Функции**:Этот интерфейс предоставляет возможность "обратного отслеживания". Когда вы получаете определенный `memory_id` в системном журнале или общем хранилище, но не можете определить его создателя, вы можете использовать этот интерфейс для массового получения соответствующих имен пользователей. + +## 1. Основной Механизм: Прослеживание Метаданных + +В Архитектуре Хранения MemOS Каждая Сгенерированная Запись Памяти Связана с Метаданными Исходного Пользователя. Этот Интерфейс Выполняет Прослеживание По Следующей Логике: + +* **Многие к Одному Соответствие**:Поддерживает Одновременный Ввод Нескольких `memory_id`, Система Вернет Соответствующий Список Пользователей. +* **Прозрачность Управления**:Этот Инструмент Обычно Используется в Административной Панели, Помогая Администраторам Определять Участников Различных Записей в Общем Cube. + + + +## 2. Ключевые Параметры Интерфейса + +Определение Тела Запроса Следующее: + +| Параметр | Тип | Обязательный | Описание | +| :--- | :--- | :--- | :--- | +| **`memory_ids`** | `list[str]` | Да | Список уникальных идентификаторов памяти для запроса. | + +## 3. Принцип Работы (MemoryHandler) + +1. **Разбор ID**:**MemoryHandler** После Получения Списка ID Запрашивает Глобальную Индексную Таблицу. +2. **Поиск Связей**:Система Извлекает Связанные Атрибуты `user_id` Или `user_name` Из Низкоуровневого Уровня Хранения (или Узлов Графа Связей). +3. **Данные Дезактивации**:В Соответствии с Конфигурацией Системы Возвращает Соответствующее Имя Пользователя или Идентификатор. + +## 4. Пример Быстрого Начала + +Используйте SDK Для Выполнения Обратного Запроса: + +```python +from memos.api.client import MemOSClient + +client = MemOSClient(api_key="...", base_url="...") + +# Подготовка списка идентификаторов памяти для запроса +target_ids = [ + "2f40be8f-736c-4a5f-aada-9489037769e0", + "5e92be1a-826d-4f6e-97ce-98b699eebb98" +] + +# Выполнение запроса +res = client.get_user_names_by_memory_ids(memory_ids=target_ids) + +if res and res.code == 200: + # res.data обычно возвращает отображение словаря или список пользователей + print(f"Этот фрагмент памяти принадлежит пользователю: {res.data}") +``` diff --git a/content/ru/openclaw/changes.md b/content/ru/openclaw/changes.md new file mode 100644 index 00000000..5a782041 --- /dev/null +++ b/content/ru/openclaw/changes.md @@ -0,0 +1,59 @@ +--- +title: OpenClaw Плагин Обновление Журнала +--- + +::OpenclawReleaseTimeline +--- +releases: + - date: '2026-03-24' + plugins: + - title: 'Облачный Плагин' + version: 'v0.1.10' + sections: + - items: + - '**Улучшение Качества Входящих Сообщений**: Добавлена и усилена очистка входящих метаданных OpenClaw, временных меток, системных подсказок в конце Feishu, что снижает запись неэффективного шума в память.' + - '**Оптимизация Очистки Префиксов Многочисленных Каналов**: Расширена и унифицирована обработка envelope/префиксов сообщений для WebChat, WhatsApp, Telegram, Slack, Discord, Zalo и других каналов, что снижает влияние упаковочной информации платформы на качество записи и извлечения из памяти.' + - '**Более Точная Демонстрация Извлечения**: Время отображения результатов извлечения теперь приоритетно использует время обновления, что повышает семантическую согласованность времени.' + - '**Более Устойчивый Recall Filter**: Параметры по умолчанию и значения отката во время выполнения (тайм-аут, повторная попытка) остаются согласованными, что повышает стабильность локальных моделей в сценах.' + - '**Оптимизация Тайм-аутов и Управления Ресурсами**: Исправлена проблема очистки таймера, чтобы избежать утечек ресурсов в аномальных путях.' + - '**Дополнение Возможностей Конфигурации**: Схема плагина дополнена полями, связанными с Recall Filter, что делает конфигурацию более полной и управляемой.' + - '**Усиление Наблюдаемости**: Добавлены журналы количества до и после фильтрации, что упрощает диагностику качества извлечения и эффективности фильтрации.' + - date: '2026-03-13' + plugins: + - title: 'Облачный Плагин' + version: 'v0.1.9' + summary: 'Незаметное обновление и оптимизация извлечения памяти. Это обновление в основном включает следующие улучшения, направленные на повышение удобства использования плагина и использования Token:' + sections: + - title: 'Незаметное Автообнаружение Версии Плагина' + items: + - 'Добавлен механизм автообнаружения версии плагина, который регулярно проверяет последнюю версию в NPM репозитории.' + - 'При обнаружении новой версии автоматически запускается процесс тихого обновления, пользователю не нужно выполнять ручные действия для получения новых возможностей и исправлений.' + - title: 'Поддержка Конфигурации Модели Пользователем для Извлечения Памяти' + items: + - 'Введена возможность вторичной фильтрации памяти на основе LLM.' + - 'Добавлены параметры recallFilterModel, recallFilterBaseUrl и другие, которые позволяют указать независимую модель для оценки релевантности.' + - 'Эффективно исключает помехи, оставляя только те фрагменты памяти, которые действительно полезны для текущего диалога.' + - title: 'Оптимизация Внедрения Диалога (Оптимизация System Prompt)' + items: + - 'Переработана логика внедрения памяти, статические протоколы и инструкции перемещены в appendSystemContext.' + - 'prependContext сохраняет только динамически извлеченные данные memory-list.' + - 'Значительно снижает потребление Token от повторяющихся подсказок и повышает фокус модели на ключевой памяти.' + - date: '2026-03-09' + plugins: + - title: 'Облачный Плагин' + version: 'v0.1.8' + summary: 'Поддержка пользователей в включении режима Multi-Agent, позволяющего из контекста идентифицировать агента для изоляции памяти, также добавлен переключатель для совместимости со старыми версиями.' + + - date: '2026-03-05' + plugins: + - title: 'Облачный Плагин' + version: 'v0.1.7' + summary: 'Поддержка пользовательской настройки поля relativity интерфейса searchMemory.' + + - date: '2026-02-26' + plugins: + - title: 'Облачный Плагин' + version: 'Другие Исторические Версии (Базовые Функции)' + summary: 'Поддержка событий before_agent_start для searchMemory и добавления сообщений в событии agent_end.' +--- +:: diff --git a/content/ru/openclaw/examples/multi_agent.md b/content/ru/openclaw/examples/multi_agent.md new file mode 100644 index 00000000..c757e5cf --- /dev/null +++ b/content/ru/openclaw/examples/multi_agent.md @@ -0,0 +1,100 @@ +--- +title: Множественная Изоляция Памяти Агентов +--- +## Облачный Плагин + +MemOS Openclaw облачный плагин поддерживает полную изоляцию памяти и истории сообщений между несколькими агентами. Каждый агент видит только свою память и не мешает другим. + +### Как Использовать + +Просто настройте, чтобы разные агенты имели независимое пространство памяти. Поддерживаются два режима: автоматическое распознавание и статическое указание. + +#### 1. Включение Режима Множественных Агентов + +Добавьте в конфигурацию `openclaw.json`: + +```json +{ + "plugins": { + "entries": { + "memos-cloud-openclaw-plugin": { + "config": { + "multiAgentMode": true + } + } + } + } +} +``` + +Или установите переменную окружения: + +```bash +MEMOS_MULTI_AGENT_MODE=true +``` + +#### 2. Автоматическое Распознавание Агентов + +После включения плагин автоматически считывает `ctx.agentId`, память разных агентов автоматически изолируется. Дополнительная настройка не требуется. + +#### 3. Статическое Указание Агента (по желанию) + +Если необходимо зафиксировать определенный ID агента, можно указать в конфигурации: + +```json +{ + "config": { + "agentId": "marketing_agent" + } +} +``` + +### Введение в Принципы + +- **/search/memory**: Поиск памяти — возвращает только память текущего агента +- **/add/message**: Добавление записи — автоматически помечается как данные текущего агента +- **Обратная Совместимость**: По умолчанию агент `"main"` будет игнорироваться, чтобы гарантировать, что данные одного агента старых пользователей не будут затронуты + +### Сценарии Применения + +- **Многофункциональное Сотрудничество**: Стратегические/Бизнесовые/Маркетинговые/Технические агенты работают совместно +- **Независимость Бизнес-Линий**: Агенты разных бизнес-линий работают независимо и не мешают друг другу +- **Согласованность Персонажей**: Поддержание долгосрочной согласованности персонажей и стиля поведения агентов + +--- + +## Локальный Плагин + +MemOS Openclaw локальный плагин по умолчанию поддерживает три функции в сценариях с несколькими агентами: изоляция памяти, общая память, совместное использование навыков. + +### Правила + +- Личная Память: `owner = agent:{agentId}`, только текущий агент может искать +- Общая Память: `owner = public`, все агенты могут искать +- Личные Навыки: `visibility = private`, видны только владельцу навыка +- Общие Навыки: `visibility = public`, могут быть найдены и установлены другими агентами + +### Примеры Операций + +```text +Agent Alpha: + memory_search("deploy config") + → sees own + public memories only + memory_write_public("shared deploy config") + skill_publish("nginx-proxy") ✓ now public + +Agent Beta: + memory_search("alpha private deploy detail") + → no alpha private memories + memory_search("shared deploy config") + → found public memory + skill_search("nginx deployment") + → Found: nginx-proxy (public) + skill_install("nginx-proxy") ✓ installed +``` + +### Ожидаемые Результаты + +- Личная память Alpha и Beta не видна друг другу +- Содержимое, записанное в `memory_write_public`, может быть найдено обеими сторонами +- После публикации общих навыков Alpha, Beta может искать и устанавливать их diff --git a/content/ru/openclaw/examples/recall_filter.md b/content/ru/openclaw/examples/recall_filter.md new file mode 100644 index 00000000..7842727a --- /dev/null +++ b/content/ru/openclaw/examples/recall_filter.md @@ -0,0 +1,104 @@ +--- +title: Вторичная Фильтрация Воспоминаний +--- +## Облачный Плагин + +MemOS Openclaw облачный плагин поддерживает использование заданной большой языковой модели для вторичной точной фильтрации вызванных воспоминаний. После фильтрации только воспоминания, которые имеют высокую степень релевантности к текущей задаче, будут внедрены в контекст, эффективно избегая помех от нерелевантных воспоминаний и экономя токены. + +### Как Использовать + +Просто настройте совместимый интерфейс модели формата OpenAI (например, локальный Ollama или сторонний API большой модели) и включите переключатель фильтрации, чтобы активировать функцию вторичной фильтрации воспоминаний. + +#### 1. Включите Функцию Фильтрации Воспоминаний + +При настройке большой модели для фильтрации воспоминаний, **необходимо** настроить API Key и Base URL. + +Добавьте в конфигурацию `openclaw.json`: +```json +{ + "plugins": { + "entries": { + "memos-cloud-openclaw-plugin": { + "config": { + "recallFilterEnabled": true, + "recallFilterBaseUrl": "http://127.0.0.1:11434/v1", + "recallFilterApiKey": "sk-...", + "recallFilterModel": "qwen2.5_7b" + } + } + } + } +} +``` + +Или настройте переменные окружения: +```bash +MEMOS_RECALL_FILTER_ENABLED=true +MEMOS_RECALL_FILTER_BASE_URL="http://127.0.0.1:11434/v1" +MEMOS_RECALL_FILTER_API_KEY="sk-..." +MEMOS_RECALL_FILTER_MODEL="qwen2.5_7b" +``` + +#### 2. Настройка Аутентификации и Расширенных Параметров (по желанию) + +Если необходимо настроить время ожидания и стратегию обработки ошибок, можно указать в конфигурации: +```json +{ + "config": { + "recallFilterTimeoutMs": 6000, + "recallFilterFailOpen": true + } +} +``` + +### Введение в Принципы +- **Перехват После Вызова**: Перед каждым раундом диалога, после вызова воспоминаний из облака, плагин отправляет кандидатные воспоминания в настроенную вами модель фильтрации для вторичной проверки. +- **Точная Сохранность**: После оценки модель фильтрации сохраняет только те записи, которые помечены как `keep`, и в конечном итоге внедряет их в контекст агента. +- **Высокая Доступность Резервирования**: По умолчанию включено разрешение на сбой ( `recallFilterFailOpen: true`). Когда запрос к модели фильтрации превышает время ожидания или завершается неудачей, автоматически происходит возврат к полному внедрению без фильтрации, что гарантирует, что текущий диалог не будет прерван. + +### Подходящие Сценарии +- **Сокращение Долгосрочных Воспоминаний**: При накоплении большого количества воспоминаний в долгих диалогах удаляются нерелевантные к текущему запросу элементы, что значительно снижает потребление токенов основным моделью. +- **Повышение Точности Выводов**: Для агентов, которым необходимо сосредоточиться на сложных задачах, фильтруются ранние нерелевантные воспоминания, что повышает точность вывода по основным задачам. +- **Синергия Локальных Моделей**: В сочетании с локально работающей малой моделью (например, `qwen2.5_7b`, работающей на Ollama) в качестве недорогого предварительного фильтра, повышается качество внедрения воспоминаний без увеличения затрат на API основной модели. + +--- + +## Локальный Плагин + +MemOS Openclaw локальный плагин поддерживает вторичную фильтрацию воспоминаний большой модели для удаления нерелевантного контента после вызова. + +### Пример Конфигурации + +Можно вручную настроить модель в Memory Viewer или настроить модель в `~/.openclaw/openclaw.json`: + +```json +{ + "agents": { + "defaults": { + "memorySearch": { "enabled": false } + } + }, + "plugins": { + "entries": { + "memos-local-openclaw-plugin": { + "enabled": true, + "config": { + "summarizer": { + "provider": "openai_compatible", + "endpoint": "https://your-api-endpoint/v1", + "apiKey": "${OPENAI_API_KEY}", + "model": "gpt-4o-mini", + "temperature": 0 + } + } + } + } + } +} +``` + +### Ожидаемые Результаты + +- Каждый раунд auto-recall сначала вызывает кандидатов, затем фильтруется большой моделью +- Внедренные в контекст воспоминания более сосредоточены, меньше шума +- При недоступности модели автоматически происходит возврат, не влияя на базовый вызов diff --git a/content/ru/openclaw/guide.md b/content/ru/openclaw/guide.md new file mode 100644 index 00000000..be7b9142 --- /dev/null +++ b/content/ru/openclaw/guide.md @@ -0,0 +1,343 @@ +--- +title: OpenClaw Облачный Плагин +desc: Улучшение памяти OpenClaw и снижение потребления токенов на 72%: плагин MemOS OpenClaw теперь доступен! +--- + +OpenClaw в последнее время привлекает много внимания, но на практике пользователи часто сталкиваются с двумя неотъемлемыми проблемами: + +1. **Слишком быстрое потребление токенов**: OpenClaw может обрабатывать множество долгосрочных задач, но каждый запуск требует значительного количества токенов. Когда вы заставляете его следить за экраном, выполнять запланированные задачи или обрабатывать сложные рабочие процессы, потребление токенов становится поразительным. + + > ("Вы знаете, что токены — это деньги🫠") + +2. **Слабая память**: Хотя многие утверждают, что память OpenClaw превосходит ChatGPT, на практике вы обнаружите, что он может запомнить некоторую информацию, но часто это не те ключевые данные, которые вам нужны. Важные предпочтения могут быть забыты, в то время как несущественные разговоры запоминаются в мельчайших деталях. + + > ("Можешь ли ты запомнить некоторые вещи, которые действительно важны для меня???") + +::tip +**Это не ошибка OpenClaw, все AI-агенты сталкиваются с этими проблемами.** +:: + +Этот учебник поможет вам решить эти 3 основные проблемы с помощью плагина MemOS OpenClaw: +- **Значительное снижение потребления токенов** — интеллектуальный поиск соответствующей памяти, а не безразборная загрузка всей истории +- **Сделать память действительно полезной** — профессиональная классификация и управление памятью, запоминать нужное, забывать ненужное +- **Сохранить основные преимущества OpenClaw** — управление между устройствами, активное взаимодействие, человекоподобный опыт остаются неизменными + +--- + +## Почему OpenClaw стал "Убийцей Токенов"🥷? + +### Проблемы OpenClaw + +```plaintext +Первый Диалог: 500 токенов +Второй Диалог: 500 + 800 = 1,300 токенов +Третий Диалог: 1,300 + 600 = 1,900 токенов +Десятый Диалог: 10,000+ токенов +``` + +Когда вы заставляете OpenClaw следить за экраном, выполнять запланированные задачи и работать по расписанию, это число растет еще быстрее. + +### Три ключевых недостатка родного управления памятью OpenClaw + +Память OpenClaw хранится в локальных `.md` файлах и делится на глобальную память и ежедневную память. Хотя это звучит неплохо, на практике существуют три неизбежные проблемы: + +#### 1. Неконтролируемый рост глобальной памяти +С накоплением глобальной памяти возникает перегрузка контекста. Еще хуже, что эта память продолжает мешать текущему разговору — вы можете просто захотеть задать простой вопрос, а он вытащит каждое ваше слово за последние три месяца. + +#### 2. Сложности с поиском ежедневной памяти +Накопление ежедневной памяти делает поиск затруднительным. Чтобы вспомнить действия вчера, вам нужно пройти через дополнительный процесс поиска. Поддерживать память между сессиями становится практически невозможно. + +#### 3. Память зависит от активной записи модели +Система памяти OpenClaw зависит от самой модели для записи информации, а не от автоматической записи. Это означает, что она часто упускает детали — вы упоминаете что-то, и она сразу забывает. + +> Я сам сталкивался с этим несколько раз: я четко подчеркивал конфигурацию проекта, но на следующий день, перезапуская разговор, она совершенно не помнила, и мне пришлось объяснять все заново. + +--- + +## OpenClaw против OpenClaw + MemOS: Сравнение решений по памяти + +### Родное решение памяти OpenClaw + +#### Решение по хранению памяти + +**Основная философия: файл — это истина** — отказываемся от непрозрачных векторных баз данных и выбираем Markdown файлы в качестве основного носителя памяти. + +![OpenClaw记忆方案](https://cdn.memtensor.com.cn/img/1772698365666_utw5a2_compressed.png) + +#### Решение по поиску памяти: Двойной двигатель + +| Двигатель | Технология | Особенности | +|-----|------|------| +| **Векторный Поиск** (Vector Search) | Косинусное Сходство | Улавливает семантические связи, хорошо справляется с "соответствием концепций", например, связывает "процесс входа" с "аутентификацией" | +| **BM25 Поиск** (Lexical Matching) | Лексическое соответствие на основе FTS5 | Обрабатывает "точные токены", такие как коды ошибок, имена функций или конкретные ID | + +**Способы активации поиска**: активация через Prompt, модель принимает автоматические решения + +**Слияние Взвешенных Оценок**: `Score = (0.7 * VectorScore) + (0.3 * BM25Score)` + +#### Проблемы существующих решений + +- **Примитивный алгоритм поиска**: нестабильный возврат, слабая релевантность, агент многократно пробует и ошибается, токены быстро накапливаются +- **Чрезмерная инъекция контекста**: фиксированное чтение today + yesterday + долгосрочная память, высокий процент неэффективного контекста +- **Отсутствие структуры и редукции в памяти**: длинные выводы вызовов инструментов записываются напрямую и многократно передаются, стоимость накапливается + +### Решение по памяти OpenClaw + MemOS + +![MemOS-OpenClaw](https://cdn.memtensor.com.cn/img/1772627912577_gvwyaz_compressed.png) + +#### Три основных эффекта + +**Эффект 1: Контроль затрат токенов 💰** +> Из "полного вливания контекста" в "точный возврат по задачам" + +OpenClaw больше не заполняет каждый раз today+yesterday+долгосрочную память, а MemOS ищет наиболее релевантную небольшую память в зависимости от текущей задачи (можно установить бюджет/количество возвратов), значительно снижая процент неэффективного контекста и избегая накопления токенов. + +**Эффект 2: Поиск более стабильный и точный 🎯** +> Уменьшите количество повторных проб и вопросов, повысив вероятность успешного выполнения с первого раза. + +MemOS предоставляет более мощные возможности организации и поиска памяти (структурированный, иерархический/многоуровневый, семантический поиск + фильтрация по правилам и т.д.), что делает содержание, вызываемое OpenClaw, более релевантным и стабильным, уменьшая повторные рассуждения и подтверждения, вызванные "нестабильностью вызова". + +**Эффект три: Память более чистая и полезная ✨** +> Структурированный + Устранение избыточности + Высокая компрессия, избегая "загрязнения длинным выводом" + +Длинные выводы вызовов инструментов (например, результаты обхода, config/schema и т.д.) не будут напрямую записываться в контекст в неизменном виде; MemOS может делать резюме/сжатие, удаление дубликатов и архивирование, в результате чего при длительной работе память становится "чище", а качество памяти со временем улучшается, а не ухудшается. + +--- + +## Эффект после интеграции плагина MemOS OpenClaw 👇🏻 + +- ✅ Каждый раз извлекается только 3-5 связанных воспоминаний +- ✅ Сохранение стабильности контекста в пределах 2,000-3,000 токенов +- ✅ Независимо от длины диалога, стоимость всегда остается контролируемой + +### Улучшения, которые плагин MemOS может принести OpenClaw + +| Функция | Описание | +|-----|------| +| **Автоматическая Память Всех Диалогов** | Не зависит от модели для активной записи, гарантирует, что ключевая информация не будет упущена | +| **Точный Вызов** | Извлекает соответствующую память на основе текущего намерения задачи, избегая нерелевантных исторических данных | +| **Запоминание Предпочтений Пользователя** | Специальная классификация и хранение информации о предпочтениях, поддерживает эффективность между сессиями | + +MemOS OpenClaw реконструировал модель потребления токенов, изменив стоимость с "функции исторической длины" на "функцию релевантности задачи". Ваши локальные затраты OpenClaw становятся контролируемыми, а работа системы более стабильной. + +--- + +## Быстрый старт + +Всего 3 шага, чтобы ваш агент обладал базовыми возможностями памяти. + +### 1. Установка OpenClaw + +Убедитесь, что в вашей системе установлена среда OpenClaw: + +```bash +# Установка Последней Версии +npm install -g openclaw@latest + +# Инициализация и настройка запуска +openclaw onboard +``` + +### 2. Получите и настройте API Key + +#### 2.1 Получение ключа + +Войдите/зарегистрируйтесь в MemOS Cloud, чтобы получить ваш API Key 🔗 [MemOS Cloud](https://memos-dashboard.openmem.net/cn/apikeys/) + +![image.png](https://cdn.memtensor.com.cn/img/1772443326905_kkxve6_compressed.webp) + +#### 2.2 Установите переменные окружения + +Плагин будет пытаться последовательно прочитать env файл (**openclaw → moltbot → clawdbot**). Для каждого ключа предпочтительно использовать первый файл, содержащий это значение. +Если эти файлы отсутствуют (или отсутствует соответствующий ключ), будет выполнен возврат к переменным окружения процесса. + +**Место конфигурации** +- Файлы (порядок приоритета): + - `~/.openclaw/.env` + - `~/.moltbot/.env` + - `~/.clawdbot/.env` +- Каждый ряд имеет формат `KEY=value` + +**Быстрая конфигурация (Shell)** +```bash +echo 'export MEMOS_API_KEY="mpg-..."' >> ~/.zshrc +source ~/.zshrc + +# or + +echo 'export MEMOS_API_KEY="mpg-..."' >> ~/.bashrc +source ~/.bashrc +``` + +**Быстрая настройка (Windows PowerShell)** +```powershell +[System.Environment]::SetEnvironmentVariable("MEMOS_API_KEY", "mpg-...", "User") +``` + +Если отсутствует `MEMOS_API_KEY`, плагин предложит инструкции по настройке и ссылку для получения API Key. + +**Минимальная конфигурация** +```env +MEMOS_API_KEY=YOUR_TOKEN +``` + +### 3. Установите плагин + +#### Вариант A — NPM (рекомендуется) + +```bash +openclaw plugins install @memtensor/memos-cloud-openclaw-plugin@latest +openclaw gateway restart +``` + +> Внимание пользователям Windows: если вы столкнетесь с `Error: spawn EINVAL`, это известная проблема установщика плагина OpenClaw на Windows. Пожалуйста, используйте вариант B (ручная установка) ниже. + +Пожалуйста, убедитесь, что в `~/.openclaw/openclaw.json` включено: + +```json +{ + "plugins": { + "entries": { + "memos-cloud-openclaw-plugin": { "enabled": true } + } + } +} +``` + +#### Вариант B — Ручная установка (совместимый вариант для Windows) + +1. Скачайте последнюю версию `.tgz` пакета с [NPM](https://www.npmjs.com/package/@memtensor/memos-cloud-openclaw-plugin). +2. Распакуйте в локальный каталог (например: `C:\Users\YourName\.openclaw\extensions\memos-cloud-openclaw-plugin`). +3. Настройте `~/.openclaw/openclaw.json` (или `%USERPROFILE%\.openclaw\openclaw.json`): + +```json +{ + "plugins": { + "entries": { + "memos-cloud-openclaw-plugin": { "enabled": true } + }, + "load": { + "paths": [ + "C:\\Users\\YourName\\.openclaw\\extensions\\memos-cloud-openclaw-plugin" + ] + } + } +} +``` + +::info +Внимание: распакованная директория обычно содержит подкаталог `package`. Пожалуйста, укажите путь к папке, содержащей `package.json`. +:: + +После изменения конфигурации перезапустите шлюз. + +### 4. Обновите плагин + +Вы можете вручную обновить облачный сервис плагина до последней версии с помощью следующей команды: + +```bash +openclaw plugins update @memtensor/memos-cloud-openclaw-plugin@latest +openclaw gateway restart +``` + +## Расширенная конфигурация открытого проекта + +Если вы хотите разблокировать больше возможностей, вы также можете провести дальнейшее исследование и настройку через проект MemOS на Github! + +### Визуальный интерфейс конфигурации (Config UI) + +С версии `v0.1.12` облачный плагин включает встроенный локальный визуальный сервис конфигурации, который позволяет вам более наглядно управлять и изменять конфигурацию плагина. + +**Как получить доступ:** +1. Запустите узел OpenClaw или хост-шлюз. +2. После успешной загрузки плагина и обнаружения готовности шлюза, сервис Config UI автоматически запустится в фоновом режиме. +3. В журнале консоли терминала будет напечатана ссылка для доступа (обычно по умолчанию это `http://127.0.0.1:38463`). +4. Откройте эту ссылку в браузере, чтобы войти в визуальную панель управления плагином. + +**Особенности:** +- **Интуитивное редактирование**: поддерживает редактирование всех основных конфигураций в форме формы (например, ID базы знаний, параметры поиска больших моделей, правила перекрытия для нескольких агентов и т.д.). +- **Мгновенная синхронизация**: изменения конфигурации, сохраненные в интерфейсе, немедленно вступают в силу во время работы плагина, без необходимости перезапуска сервиса. +- **Мониторинг состояния**: интерфейс предоставляет проверку состояния связи с хост-шлюзом, чтобы гарантировать здоровье канала синхронизации конфигурации. + +### Поддержка и изоляция нескольких агентов (Multi-Agent) + +Плагин имеет мощную встроенную поддержку режима нескольких агентов (реализованную через параметр `agent_id`), что делает его идеальным для использования в сложных рабочих процессах или сценариях командных агентов. + +**1. Включение и изоляция данных** +- **Способ Включения**: В настройках установите `"multiAgentMode": true` или настройте переменную окружения `MEMOS_MULTI_AGENT_MODE=true`. +- **Автоматическая Изоляция**: После включения плагин автоматически будет считывать `ctx.agentId` из контекста. При выполнении операций по извлечению и записи памяти будет автоматически прикрепляться идентификатор этого агента, что обеспечит полную изоляцию данных памяти между разными агентами одного пользователя (примечание: по умолчанию идентификатор `"main"` агента будет игнорироваться для обеспечения совместимости со старыми данными). + +**2. Включение Памяти По Агенту (Контроль Белого Списка)** +В режиме нескольких агентов, если вы не хотите, чтобы все агенты использовали память, вы можете использовать `allowedAgents` для точного контроля белого списка: +```json +{ + "plugins": { + "entries": { + "memos-cloud-openclaw-plugin": { + "enabled": true, + "config": { + "multiAgentMode": true, + "allowedAgents": ["research-agent", "coding-agent"] + } + } + } + } +} +``` +*(Подсказка: 1. Если `allowedAgents` не настроен или является пустым массивом `[]`, это означает, что **все агенты** могут использовать извлечение и запись памяти. 2. Если настройка была выполнена, то агенты, не входящие в конфигурацию, будут полностью пропущены, только агенты из конфигурации будут действовать для извлечения и записи памяти, что позволит избежать потерь токенов). * + +**3. Индивидуальная Настройка Параметров По Агенту (agentOverrides)** +Кроме простого переключателя, вы также можете использовать `agentOverrides` для **индивидуального переопределения параметров памяти для каждого агента**. Например, разрешить исследовательскому помощнику иметь более широкий порог извлечения, в то время как кодовый помощник будет читать только определенные знания из кодовой базы: + +```json +{ + "plugins": { + "entries": { + "memos-cloud-openclaw-plugin": { + "enabled": true, + "config": { + "multiAgentMode": true, + "allowedAgents": ["research-agent", "coding-agent"], + "memoryLimitNumber": 6, + "relativity": 0.45, + + "agentOverrides": { + "research-agent": { + "knowledgebaseIds": ["kb-research-papers"], + "memoryLimitNumber": 12, + "relativity": 0.3, + "queryPrefix": "research context: " + }, + "coding-agent": { + "knowledgebaseIds": ["kb-codebase"], + "memoryLimitNumber": 9, + "addEnabled": false + } + } + } + } + } + } +} +``` +*(В приведенном выше примере `coding-agent` был запрещен на запись памяти и может извлекать только 9 наиболее релевантных воспоминаний из базы знаний `kb-codebase`).* + +### Глубокая Настройка Переменных Окружения + +Кроме обязательного API ключа, вы также можете настроить поведение плагина с помощью переменных окружения. + +Больше деталей конфигурации можно найти в [MemTensor GitHub официальном репозитории плагинов](https://github.com/MemTensor/MemOS/tree/main/apps/MemOS-Cloud-OpenClaw-Plugin) + +## Тестирование Функции Памяти + +Теперь вы можете вести многократные беседы с вашим агентом, например: + +**Первый Диалог:** +- "Мой любимый язык программирования - Python" +- "Я разрабатываю проект электронной коммерции" + +**Второй Диалог (новый запуск):** +- "Ты помнишь, какой язык программирования мне нравится?" +- "Как продвигается проект, о котором я говорил ранее?" + +Теперь ваш OpenClaw будет извлекать память из MemOS Cloud и давать точные ответы~ diff --git a/content/ru/openclaw/hermes_local_plugin.md b/content/ru/openclaw/hermes_local_plugin.md new file mode 100644 index 00000000..71b28d14 --- /dev/null +++ b/content/ru/openclaw/hermes_local_plugin.md @@ -0,0 +1,254 @@ +--- +title: Hermes Локальный Плагин +desc: Предоставляет полностью локализованную долговременную память, интеллектуальное резюме задач, автоматическую эволюцию навыков и многопользовательское сотрудничество для Hermes Agent. +--- + +MemOS Hermes Локальный Плагин предоставляет **Hermes Agent** полностью локализованную возможность долговременной памяти. Все данные хранятся в локальном SQLite (`~/.hermes/memos-state/`), без облачной зависимости. Viewer слушает только 127.0.0.1, защищен паролем. + +## Основные Характеристики + +| Характеристика | Описание | +|------|------| +| 💾 Полное Запись Памяти | Автоматически захватывает каждый разговор, после семантической фрагментации сохраняет. | +| ⚡ Резюме Задач И Эволюция Навыков | Фрагменты разговоров обобщаются в структурированные задачи, затем перерабатываются в переиспользуемые навыки и постоянно обновляются. | +| 🔍 Гибридный Поиск | FTS5 + Вектор, RRF, MMR, временное затухание. | +| 🧠 Полная Визуализация | 7 страниц управления: память/задачи/навыки/анализ/журнал/импорт/настройки. | +| 💰 Модели Разного Уровня | Embedding/резюме/навыки могут быть независимо настроены с разными моделями. | +| 🤝 Сотрудничество Множественных Агентов | Изоляция памяти + Общая память + Обмен навыками, совместная эволюция нескольких агентов. | +| 🐍 Нативная Интеграция Python | Нативная интеграция Hermes Agent через интерфейс MemoryProvider, без дополнительной настройки шлюза. | +| 👥 Центр Совместного Использования Команды | Архитектура Hub-Client, совместное использование памяти/задач/навыков между экземплярами. Процесс утверждения, управление ролями, уведомления в реальном времени. | +| 🔗 Умное Понижение Уровня LLM | Модель навыков → Модель резюме → Трехуровневая автоматическая понижение уровня модели Hermes, без ручного вмешательства. | + +--- + +## Архитектура Системы + +Hermes Agent общается с демоном моста MemOS через интерфейс Python MemoryProvider. Четыре конвейера: запись памяти → резюме задач и эволюция навыков (асинхронно) → интеллектуальный поиск → совместное использование. Каждый агент имеет независимое пространство памяти, достигая совместной эволюции через общую память и обмен навыками. + +``` +Поток 1: Запись +Hermes Agent → Bridge Daemon (TCP :18992) → Ingest (chunk→summary→embed→dedup) → SQLite+FTS5 + +Поток 2: Задачи & Навыки (асинхронно) +Task Processor (обнаружение темы → резюме) → Skill Evolver (оценка → генерация/обновление) + +Поток 3: Автоматический Вызов +prefetch (auto-recall) → Recall (FTS+Vector) → LLM filter → Inject context + +Поток 4: По Запросу Поиск +Agent (memory_search) → RRF→MMR→Decay → LLM filter → excerpts+chunkId/task_id +→ task_summary / skill_get / memory_timeline +``` + +### Поток Данных + +#### Запись +1. `sync_turn` → Bridge Daemon → Chunk → LLM Резюме → Встраивание → Удаление дубликатов → Хранение +2. Асинхронно: обнаружение задач → резюме задач → оценка навыков → генерация/обновление навыков + +#### Поиск +1. Каждый раунд автоматически: `prefetch` использует сообщения пользователя для поиска → LLM фильтрует релевантные → внедряет контекст системы; при отсутствии результатов предлагает агенту самостоятельно сгенерировать запрос для вызова `memory_search`. +2. `memory_search` → FTS5+Vector → RRF → MMR → Decay → LLM filter → excerpts + chunkId/task_id +3. `task_summary` / `skill_get`(skillId|taskId) / `memory_timeline`(chunkId) / `skill_install` + +--- + +## Быстрый Старт + +### Предварительные Условия + +- **Node.js** ≥ 18 +- **Python 3** +- **Hermes Agent** установлен (`~/.hermes/hermes-agent` или локальный репозиторий) +- Embedding / Summarizer API по желанию, без настройки автоматически использует локальную модель + +### Шаг 1: Установка Одним Нажатием (Рекомендуется) + +Одна команда завершает всю установку, без необходимости ручных действий: + +```bash +curl -fsSL https://raw.githubusercontent.com/MemTensor/MemOS/openclaw-local-plugin-20260408/apps/memos-local-plugin/install.sh | bash +``` + +#### Установка через npm + +```bash +mkdir -p ~/.hermes/memos-plugin && cd ~/.hermes/memos-plugin && npm pack @memtensor/memos-local-hermes-plugin && tar xzf *.tgz && mv package/* . && rm -rf package *.tgz && bash install.sh +``` + +::note +Что делает установщик? Автоматически обнаруживает и устанавливает Node.js (если отсутствует) → Загружает пакет плагина из npm → Устанавливает зависимости → Создает символическую ссылку `memtensor` в директории плагинов Hermes → Обновляет `~/.hermes/config.yaml` → Проверяет загрузку плагина → Запускает демон моста и Memory Viewer. +:: + +::warning +Не удалось установить? Наиболее распространенная проблема — сбой компиляции нативного модуля `better-sqlite3`. Убедитесь, что установлены инструменты сборки ( `gcc`, `make`, `python3`). На Ubuntu/Debian: `apt install build-essential`. +:: + +### Шаг 2: Начать Использовать + +```bash +hermes chat +``` + +Скрипт установки автоматически запускает Memory Viewer. После этого каждый раз, когда вы запускаете `hermes chat`, демон автоматически поднимается (если еще не запущен). После выхода из hermes демон продолжает работать в фоновом режиме. + +::tip +После установки каждый диалог автоматически сохраняется в памяти. Посетите `http://127.0.0.1:18901`, чтобы увидеть Memory Viewer. +:: + +### Шаг 3: Настройка + +**Два Способа**: редактирование `~/.hermes/config.yaml` или онлайн-изменение через панель Viewer. Поддерживает иерархические модели. + +#### Основная Настройка (config.yaml) + +```yaml +# ~/.hermes/config.yaml +memory: + memory_enabled: true + user_profile_enabled: true + provider: memtensor +``` + +#### Настройка Моделей (через переменные окружения) + +```bash +# Embedding — Легковесная Модель +export MEMOS_EMBEDDING_PROVIDER="openai_compatible" +export MEMOS_EMBEDDING_API_KEY="sk-••••••" +export MEMOS_EMBEDDING_ENDPOINT="https://your-api-endpoint/v1" + +# Пользовательский Порт +export MEMOS_DAEMON_PORT=18992 +export MEMOS_VIEWER_PORT=18901 + +# Пользовательский Каталог Данных +export MEMOS_STATE_DIR="/custom/path/memos-state" +``` + +#### Расширенная Настройка (через JSON конфигурации моста) + +```bash +export MEMOS_BRIDGE_CONFIG='{ + "stateDir": "~/.hermes/memos-state", + "config": { + "embedding": { + "provider": "openai_compatible", + "model": "bge-m3", + "endpoint": "https://your-api-endpoint/v1", + "apiKey": "sk-••••••" + }, + "summarizer": { + "provider": "openai_compatible", + "model": "gpt-4o-mini", + "endpoint": "https://your-api-endpoint/v1", + "apiKey": "sk-••••••" + }, + "skillEvolution": { + "summarizer": { + "provider": "openai_compatible", + "model": "claude-4.6-opus", + "endpoint": "https://your-api-endpoint/v1", + "apiKey": "sk-••••••" + } + }, + "recall": { + "vectorSearchMaxChunks": 0 + }, + "viewerPort": 18901 + } +}' +``` + +--- + +## Модули + +### Capture +С помощью интерфейса `sync_turn` захватываются сообщения user/assistant на каждом раунде, а с помощью `on_memory_write` захватываются обновления профиля пользователя. Передаются в конвейер Ingest через демон моста. + +### Ingest +Асинхронная очередь: семантическая сегментация → LLM резюме → векторизация → интеллектуальное удаление дубликатов (Top-5 похожих + LLM определяет DUPLICATE/UPDATE/NEW, UPDATE объединяет резюме и добавляет контент) → хранение; блок эволюции записывает merge_history. + +### Резюме Задач +Асинхронное поочередное обнаружение границ задач: группировка по раундам пользователя → первая строка назначается напрямую → последующие строки определяются LLM, меняется ли тема (сильный уклон на SAME, чтобы избежать чрезмерного разделения) → 2h тайм-аут принудительно разделяет → структурированное резюме (цель/шаги/результаты). Поддерживает редактирование, удаление, повторную попытку генерации навыков. + +### Эволюция Навыков +Фильтрация по правилам → Оценка LLM (только повторяемые/ценные задачи генерируют навыки) → Генерация SKILL.md (шаги/предупреждения/скрипты)/обновление → Оценка качества → Установка. LLM использует трехуровневую цепочку понижения (модель навыков → модель резюме → родная модель Hermes). Поддерживает редактирование, удаление, установку на публичный/приватный. + +### Recall +FTS5+Vector → RRF(k=60) → MMR(λ=0.7) → Decay(14d) → Normalize → Filter(≥0.45) → Top-K. Автоматическая ассоциация Task/Skill. + +### Viewer +7 страниц: CRUD/поиск/идентификация эволюции памяти, задачи (диалоговые пузырьки), навыки (версии/загрузка), анализ, журналы (входные и выходные данные вызовов инструментов), импорт, онлайн-настройка. Защита паролем. Порт по умолчанию `18901`. + +--- + +## Алгоритмы Поиска + +### RRF (Обратное Ранжирование Слияния) + +$$\text{RRF}(d) = \sum_i \frac{1}{k + \text{rank}_i(d) + 1}$$ + +### MMR (Максимальная Маргинальная Связь) + +$$\text{MMR}(d) = \lambda \cdot \text{rel}(d) - (1-\lambda) \cdot \max \text{sim}(d, d_s)$$ + +### Временное Убывание + +$$\text{final} = \text{score} \times \bigl(0.3 + 0.7 \times 0.5^{t/14}\bigr)$$ + +--- + +## Цепочка Понижения LLM + +Все вызовы LLM (резюме, обнаружение тем, удаление дубликатов, генерация/обновление навыков) используют трехуровневый автоматический механизм понижения: + +``` +skillSummarizer (модель для навыков, по желанию) → summarizer (универсальная модель резюме) → Hermes Native (автоматическое обнаружение) +``` + +- Автоматически пытаться на следующем уровне после каждой неудачи, без необходимости ручного вмешательства +- При отсутствии конфигурации `skillSummarizer` сразу переходить к `summarizer` +- Если все модели потерпели неудачу, откатиться к правилу (без LLM) или пропустить этот шаг + +--- + +## Переменные Среды + +| Переменная | По Умолчанию | Описание | +|------|------|------| +| `MEMOS_STATE_DIR` | `~/.hermes/memos-state` | Положение базы данных памяти | +| `MEMOS_DAEMON_PORT` | `18992` | TCP порт демона Bridge | +| `MEMOS_VIEWER_PORT` | `18901` | HTTP порт Memory Viewer | +| `MEMOS_EMBEDDING_PROVIDER` | `local` | Поставщик Embedding | +| `MEMOS_EMBEDDING_API_KEY` | — | Ключ API для Embedding | +| `MEMOS_EMBEDDING_ENDPOINT` | — | Пользовательская конечная точка Embedding | +| `MEMOS_BRIDGE_CONFIG` | — | Полная конфигурация моста JSON | +| `MEMOS_BRIDGE_SCRIPT` | — | Путь к скрипту моста | +| `HERMES_HOME` | `~/.hermes` | Главный каталог Hermes | + +--- + +## Значения По Умолчанию + +| Параметр | По умолчанию | Описание | +|------|------|------| +| maxResults | 6 (макс 20) | Число возвращаемых по умолчанию | +| minScore (tool) | 0.45 | Минимальный балл memory_search | +| minScore (viewer) | 0.64 | Порог векторного поиска Viewer | +| rrfK | 60 | Константа слияния RRF | +| mmrLambda | 0.7 | Связь MMR vs разнообразие | +| recencyHalfLife | 14d | Полураспад временного затухания | +| vectorSearchMaxChunks | 0 (все) | 0=искать все; для больших баз можно установить 200k-300k | +| dedup threshold | 0.75 | Семантическая косинусная схожесть для удаления дубликатов | +| viewerPort | 18901 | Memory Viewer | +| daemonPort | 18992 | Bridge Daemon TCP | +| owner | hermes | Идентификатор принадлежности памяти | +| taskIdle | 2h | Тайм-аут простоя задачи | + +--- + +## Дополнительная Информация + +- [GitHub](https://github.com/MemTensor/MemOS/tree/main/apps/memos-local-plugin) diff --git a/content/ru/openclaw/plugin_compare.md b/content/ru/openclaw/plugin_compare.md new file mode 100644 index 00000000..2433263a --- /dev/null +++ b/content/ru/openclaw/plugin_compare.md @@ -0,0 +1,76 @@ +--- +title: Облачные Плагины vs Локальные Плагины +desc: Оба плагина могут предоставить OpenClaw возможность долговременной памяти, но предназначены для совершенно разных сценариев. Эта статья поможет вам быстро понять основные различия между ними и найти наиболее подходящее решение. +--- + +## Введение в Плагины + +### Облачные Плагины + +Хранит память в **MemOS Cloud**, достаточно настроить API Key для использования, поддерживает совместное использование памяти между несколькими агентами на разных устройствах, по результатам бенчмарков может снизить потребление токенов примерно на **72%**, подходит для быстрого старта или командной работы. + +### Локальные Плагины + +Полностью хранит память на **локальной машине (SQLite)**, без облачной зависимости, поддерживает смешанный поиск (FTS5 + векторный), автоматическое резюмирование задач и саморазвитие навыков, а также включает локальный интерфейс управления Memory Viewer (7 страниц управления). Подходит для разработчиков с более высокими требованиями к конфиденциальности, безопасности или локальному выполнению. + +--- + +## Основные Отличия + +| Сравнительные Параметры | ☁️ MemOS Облачный Плагин | 🖥️ MemOS Локальный Плагин | +| --- | --- | --- | +| 💾 **Хранение Данных И Конфиденциальность** | **Облачное Хранение**: Данные памяти хранятся в облаке MemOS, что упрощает совместное использование между устройствами и множеством экземпляров. Конфиденциальность и безопасность зависят от поставщика облачных услуг. | **Локальное Хранение**: Все данные (SQLite + векторы) хранятся локально у пользователя, поддерживается полная работа в оффлайн-режиме, данные на 100% под контролем пользователя, что соответствует самым высоким требованиям конфиденциальности и безопасности. | +| 🔑 **API Ключ** | API Ключ MemOS Cloud (предоставляется MemOS) | API Ключ модели встраивания (предоставляется самостоятельно, можно настроить локальную модель без ключа) | +| 🔍 **Способности Поиска** | Облачный семантический векторный поиск + графический поиск | Полнотекстовый поиск FTS5 + смешанный векторный возврат (RRF + MMR + временное затухание) | +| 🧠 **Эволюция Памяти** | Автоматически выполняется облачным сервисом: структурная обработка записанной памяти, устранение избыточности и коррекция естественного языка | Автоматическая индукция фрагментированных диалогов в структурированные задачи, после выполнения задач инициируется оценка навыков, автоматически создаются или обновляются повторно используемые навыки | +| 👥 **Много Агентов** | ✅ Поддерживается (`multiAgentMode`, изоляция данных) | ✅ Поддерживается (изоляция памяти + общая память + совместное использование навыков) | +| 💡 **Дополнительные Возможности** | • Снижение стоимости токенов на 72%
• Автоматическая запись всех диалогов
• Специальная классификация пользовательских предпочтений
• Низкая задержка, поддержка высокопроизводительных производственных сред | • Визуализация полной памяти (веб-панель управления, 7 страниц)
• Однокнопочный импорт родной памяти
• Конфигурация многоуровневой модели (распределение различных моделей для разных задач) | +| 🛠️ **Развертывание И Конфигурация** | **Минимально**: Завершение за три шага (установка плагина, получение API ключа, настройка переменных окружения), в основном зависит от облачных услуг. | **Средний**: Необходимо подготовить локальную среду компиляции, самостоятельно настроить несколько моделей, таких как встраивание, резюме и т.д. (поддержка локальных или облачных моделей), высокая гибкость, но начальная настройка немного сложнее. | + +--- + +## Обзор Установки + +### Облачные Плагины (Завершение за 3 Шага) + +1. **Установка Плагина** + ```bash + openclaw plugins install @memtensor/memos-cloud-openclaw-plugin@latest + ``` + +2. **Получение И Настройка API Ключа** + +Получить API Key:[MemOS Cloud Dashboard](https://memos-dashboard.openmem.net/cn/apikeys/) + + ```bash + mkdir -p ~/.openclaw && echo "MEMOS_API_KEY=mpg-..." > ~/.openclaw/.env + ``` + +3. **Перезагрузить gateway** + + ```bash + openclaw gateway restart + ``` + +**Ручное Обновление Плагина**: +```bash +openclaw plugins update @memtensor/memos-cloud-openclaw-plugin@latest +openclaw gateway restart +``` + +> Для получения дополнительной информации смотрите [Документацию по Облачным Плагинам Openclaw](/cn/openclaw/guide#快速开始) + +### Локальные Плагины (Необходимо Подготовить Среду Компиляции) +```bash +# macOS +xcode-select --install +# Linux +sudo apt install build-essential python3 + +# Установка плагина +curl -fsSL https://cdn.memtensor.com.cn/memos-local-openclaw/install.sh | bash +``` + +> После завершения сборки автоматически запустятся openclaw gateway и плагин memos-local-openclaw-plugin. Далее просто откройте http://127.0.0.1:18799 для доступа к Memory Viewer и настройки различных моделей. +> +> Полная конфигурация (Embedding, Summarizer, Skill Evolution по уровням) смотрите в [Документации по Локальным Плагинам OpenClaw](/cn/openclaw/local_plugin#快速开始) diff --git a/content/ru/settings.yml b/content/ru/settings.yml new file mode 100644 index 00000000..1a2c2743 --- /dev/null +++ b/content/ru/settings.yml @@ -0,0 +1,151 @@ +nav: + # You can include icons using the syntax `(ri:icon-name)`. + # The frontend will render these as actual icons. + # You can find available icons at https://icones.js.org/ + - "(ri:cloud-line) MemOS Cloud": + - "(ri:book-line) Начало Использования": + - "(ri:eye-line) Обзор": memos_cloud/overview.md + - "(ri:rocket-line) Быстрый Старт": memos_cloud/quick_start.md + - "(ri:home-line) Основные Понятия": + - "(ri:add-line) Производство Памяти": memos_cloud/introduction/mem_production.md + - "(ri:calendar-line) Расписание Памяти": memos_cloud/introduction/mem_schedule.md + - "(ri:search-line) Восстановление Памяти": memos_cloud/introduction/mem_recall.md + - "(ri:refresh-line) Управление Жизненным Циклом Памяти": memos_cloud/introduction/mem_lifecycle.md + - "(ri:cpu-line) Обзор Принципов Алгоритма": memos_cloud/introduction/algorithm.md + - "(ri:dashboard-line) Облачная Платформа и Открытые Решения": memos_cloud/cloud_and_opensource.md + - "(ri:shield-line) Квоты и Ограничения": memos_cloud/limit.md + + - "(ri:question-line) Поддержка и Устранение Проблем": + - "(ri:question-line) FAQs Часто Задаваемые Вопросы": memos_cloud/faq.md + + - "(ri:edit-box-line) Операции с Памятью": + - "(ri:message-3-line) Add Message": memos_cloud/mem_operations/add_message.md + - "(ri:search-2-line) Search Memory": memos_cloud/mem_operations/search_memory.md + - "(ri:delete-bin-line) Delete Memory": memos_cloud/mem_operations/delete_memory.md + - "(ri:feedback-line)Add Feedback": memos_cloud/mem_operations/add_feedback.md + + - "(ri:function-line) Введение в Функции": + - "(ri:flag-line) Основные Функции": + - "(ri:filter-3-line) Фильтрация Памяти": memos_cloud/features/basic/filters.md + - "(ri:timer-flash-line) Асинхронный Режим": memos_cloud/features/basic/async_mode.md + - "(ri:image-add-line) Мультимодальные Сообщения": memos_cloud/features/basic/multimodal.md + - "(ri:price-tag-3-line) Пользовательские Метки": memos_cloud/features/basic/custom_tags.md + - "(ri:vip-diamond-line) Расширенные Функции": + - "(ri:function-line) Навыки": memos_cloud/features/advanced/skill.md + - "(ri:book-read-line) База Знаний": memos_cloud/features/advanced/knowledge_base.md + - "(ri:tools-line) Вызов Инструментов": memos_cloud/features/advanced/tool_calling.md + - "(ri:chat-history-line) Непрерывный Диалог": memos_cloud/features/advanced/continuous_dialogue.md + + - "(ri:github-line) Открытые Проекты": + - "(ri:rocket-line) Быстрый Ввод": + - "(ri:install-line) Руководство по Установке": open_source/getting_started/installation.md + - "(ri:bookmark-line) Создайте Вашу Первую Память": open_source/getting_started/your_first_memory.md + - "(ri:lightbulb-line) Основные Понятия": open_source/home/core_concepts.md + - "(ri:building-2-line) Архитектурный Дизайн": open_source/home/architecture.md + - "(ri:file-code-line) REST API Сервис": open_source/getting_started/rest_api_server.md + - "(ri:code-line) Пример MemOS": open_source/getting_started/examples.md + + - "(ri:cpu-line) MemOS": + - "(ri:eye-line) Руководство по Разработке API": open_source/modules/mos/overview.md + - "(ri:checkbox-multiple-blank-line) MemCube Память": open_source/modules/mem_cube.md + - "(ri:book-open-line) MemReader Чтение Памяти": open_source/modules/mem_reader.md + - "(ri:calendar-line) MemScheduler Расписание Памяти": open_source/modules/mem_scheduler.md + - "(ri:calendar-line) MemChat Чат с Использованием Памяти": open_source/modules/mem_chat.md + - "(ri:feedback-line) MemFeedback Обратная Связь по Памяти": open_source/modules/mem_feedback.md + + + - "(ri:brain-line) Система Памяти": + - "(ri:database-2-line) Обзор Модулей Памяти": open_source/modules/memories/overview.md + - "(ri:book-2-line) Открытая Память": + - "(ri:file-text-line) Простая Открытая Память": open_source/modules/memories/naive_textual_memory.md + - "(ri:file-text-line) Универсальная Открытая Память": open_source/modules/memories/general_textual_memory.md + - "(ri:user-heart-line) Предпочтительная Открытая Память": open_source/modules/memories/preference_textual_memory.md + - "(ri:tree-line) Деревовидная Открытая Память": open_source/modules/memories/tree_textual_memory.md + - "(ri:database-line) Neo4j Графовая База Данных": open_source/modules/memories/neo4j_graph_db.md + - "(ri:database-line) PolarDB Графовая База Данных": open_source/modules/memories/polardb_graph_db.md + - "(ri:database-2-line) KVCache Память": open_source/modules/memories/kv_cache_memory.md + - "(ri:cpu-line) Параметрическая Память (в Разработке)": open_source/modules/memories/parametric_memory.md + + - "(ri:star-line) Лучшие Практики": + - "(ri:speed-line) Оптимизация Производительности": open_source/best_practice/performance_tuning.md + - "(ri:wifi-line) Решение Сетевых Проблем": open_source/best_practice/network_workarounds.md + - "(ri:error-warning-line) Распространенные Ошибки и Решения": open_source/best_practice/common_errors_solutions.md + - "(ri:tools-line) Руководство по Интеграции MemOS MCP": open_source/best_practice/mcp_for_cozespace_and_tools.md + + - "(ri:heart-line) Руководство по Вкладу": + - "(ri:eye-line) Участие в Разработке MemOS": open_source/contribution/overview.md + - "(ri:tools-line) Настройка Разработческой Среды": open_source/contribution/setting_up.md + - "(ri:git-branch-line) Процесс Разработки": open_source/contribution/development_workflow.md + - "(ri:git-commit-line) Стандарты Коммитов": open_source/contribution/commit_guidelines.md + - "(ri:article-line) Руководство по Написанию Документации": open_source/contribution/writing_docs.md + - "(ri:flask-line) Как Писать Тесты": open_source/contribution/writing_tests.md + + - "(ri:file-code-line) Документация API": api-reference/search-memories + + - "(ri:cpu-line) Описание Собственных Моделей": + - "(ri:flask-line) Извлечение Моделей": + - "(ri:file-code-line) Примеры Использования": self_developed_model/extraction_usage_example.md + + - "(ri:puzzle-line) Поддержка MCP и Agent Фреймов": + - "(ri:tools-line) MCP Сервис": + - "(ri:book-open-line) Руководство по Использованию": mcp_agent/mcp/guide.md + + - "(ri:robot-line) Разработка Agent": + - "(ri:book-open-line) Руководство по Использованию": mcp_agent/agent/guide.md + + - "(ri:robot-line) Agent": + - "(ri:book-open-line) Облачные Плагины vs Локальные Плагины": openclaw/plugin_compare.md + - "(ri:file-list-3-line) Журнал Изменений": openclaw/changes.md + - "(ri:download-line) Руководство по Установке": + - "(ri:cloud-line) Облачный Плагин OpenClaw": openclaw/guide.md + - "(ri:computer-line) Локальный Плагин OpenClaw": openclaw/local_plugin.md + - "(ri:server-line) Локальный Плагин Hermes": openclaw/hermes_local_plugin.md + - "(ri:flask-line) Примеры Использования": + - "(ri:team-line) Изоляция Памяти Мультиагентов": openclaw/examples/multi_agent.md + - "(ri:filter-3-line) Вторичная Фильтрация Вызова Памяти": openclaw/examples/recall_filter.md + - "(ri:terminal-box-line) Использование Локального Плагина Hermes": openclaw/examples/hermes_usage.md + + - "(ri:file-code-line) Документация API": + - "(ri:rocket-line) Начало Использования": + - "(ri:eye-line) Обзор": api_docs/start/overview.md + - "(ri:settings-3-line) Конфигурация Проекта": api_docs/start/configuration.md + + - "(ri:edit-box-line) Основные Операции": + - "(ri:message-3-line) Add Message": api_docs/core/add_message.md + - "(ri:search-2-line) Search Memory": api_docs/core/search_memory.md + - "(ri:file-list-line) Get Memory": api_docs/core/get_memory.md + - "(ri:delete-bin-line) Delete Memory": api_docs/core/delete_memory.md + - "(ri:feedback-line) Add Feedback": api_docs/message/add_feedback.md + + - "(ri:cpu-line) Собственные Модели": + - "(ri:flask-line) Extract Memory": api_docs/core/extract_memory.md + + - "(ri:chat-1-line) Сообщения": + - "(ri:file-list-line) Get Message": api_docs/message/get_message.md + - "(ri:task-line) Get Task Status": api_docs/message/get_status.md + + - "(ri:chat-smile-2-line) Диалоги": + - "(ri:chat-4-line) Chat": api_docs/chat/chat.md + + - "(ri:book-read-line) База Знаний": + - "(ri:add-box-line) Создание Базы Знаний": api_docs/knowledge/create_kb.md + - "(ri:delete-back-2-line) Удаление Базы Знаний": api_docs/knowledge/remove_kb.md + - "(ri:file-add-line) Добавление Документа в Базу Знаний": api_docs/knowledge/add_kb_doc.md + - "(ri:file-search-line) Получение Документа из Базы Знаний": api_docs/knowledge/get_kb_doc.md + - "(ri:file-reduce-line) Удаление Документа из Базы Знаний": api_docs/knowledge/delete_kb_doc.md + + - "(ri:customer-service-line) Помощь и Поддержка": + - "(ri:error-warning-line) Код Ошибки": api_docs/help/error_codes.md + + - "(ri:projector-line) Пример Проекта": + - "(ri:lightbulb-line) Лучшие Практики": + - "(ri:customer-service-2-line) Помощник по Вопросам и Ответам": usecase/knowledge_qa_assistant.md + - "(ri:money-dollar-circle-line) Помощник по Финансам": usecase/financial_assistant.md + - "(ri:edit-line) Помощник По Написанию": usecase/writting_assistant.md + - "(ri:heart-line) Помощник По Семейной Жизни": usecase/home_assistant.md + # - "(ri:customer-service-2-line) Корпоративный Сервис Поддержки WeChat": usecase/wecom_customer_service.md + + - "(ri:layout-grid-line) Фреймы И Платформы": + # - "(ri:chrome-line) Плагин Для Браузера": usecase/frameworks/browser_extension.md + - "(ri:brain-line) Claude MCP": usecase/frameworks/claude_mcp.md + - "(ri:puzzle-2-line) Инструменты Плагина Coze": usecase/frameworks/coze_plugin.md \ No newline at end of file diff --git a/content/ru/usecase/financial_assistant.md b/content/ru/usecase/financial_assistant.md new file mode 100644 index 00000000..0dd98a32 --- /dev/null +++ b/content/ru/usecase/financial_assistant.md @@ -0,0 +1,275 @@ +--- +title: Позвольте Финансовому Ассистенту Понять Предпочтения За Клиентским Поведением +desc: С помощью MemOS операции пользователей и поведенческие действия абстрагируются в "память", что позволяет выявить и извлечь инвестиционные предпочтения, обеспечивая более персонализированное обслуживание клиентов. +--- + + +## 1. Обзор + +В продуктах интеллектуального инвестирования пользователи оставляют множество **поведенческих следов**: + +* **Источник трафика**: откуда пользователь пришел по рекламе или твиту? (например, кликнув на рекламу "пенсионного инвестирования") + +* **Операции в приложении**: какие инвестиционные продукты были просмотрены? какие финансовые инструменты были сохранены? + +* **Записи общения**: взаимодействие с менеджером по инвестициям, содержание диалога с AI инвестиционным ассистентом. + + +Это всего лишь исходные действия, если сохранить их в виде логов, это будет иметь ограниченную пользу для больших моделей. **Ключевым моментом является то, как абстрагировать действия в "память"**: + + +### 1.1 Как абстрагировать действия в память? + +| Пользовательское Поведение (Исходная Траектория) | Соответствующая Память (Семантическая Абстракция) | +| --- | --- | +| Нажатие на рекламу «Пенсионные Инвестиции» для входа в APP | Память: «Пользователь имеет потенциальный интерес к пенсионным инвестициям» | +| Многоразовый просмотр страниц с информацией о фондах с низким риском | Память: «Пользователь предпочитает консервативный риск» | +| Сохранение «Продуктов с Низким Риском» | Память: «Пользователь склонен выбирать инвестиции с низким риском» | +| В разговоре сказать «Я не хочу рисковать слишком сильно» | Память: «Явно выражает требования к низкому риску» | + +Когда пользователь снова спрашивает «Какой инвестиции мне подходит?», инвестиционный ассистент не должен просматривать кучу логов, а должен использовать эти семантические воспоминания для генерации персонализированного ответа. + + +### 1.2 Почему не использовать традиционный RAG? + +RAG больше подходит для вопросов и ответов по знаниям, например, для объяснения «Что такое облигация». Но он не сможет подвести предпочтения из поведения пользователя: + +| Традиционный RAG | MemOS | +| --- | --- | +| Возврат статических фрагментов знаний о финансах | Абстрагирует поведение пользователя в семантическую память (интересы, предпочтения, профили) | +| Не может ответить на «Какое инвестирование мне подходит?» | Может генерировать персонализированные рекомендации, основываясь на памяти | + +### 1.3 Почему не создавать собственное решение? + +Разработчики, конечно, могут хранить действия самостоятельно, но столкнутся с тремя проблемами: + +* **Недостаток абстракции**: простое хранение «кликнул на фонд A» бесполезно, нужно преобразовать в «предпочтение риска = низкий риск». + +* **Сложная интеграция**: перед вызовом модели необходимо самостоятельно составить Prompt, абстрагируя разрозненные действия в семантическую информацию. + +* **Плохая масштабируемость**: с увеличением каналов, продуктов и сценариев общения код быстро выходит из-под контроля. + + +### 1.4 Почему стоит использовать MemOS? + +При выборе можно наглядно сравнить три решения: + +| Решение | Особенности | Ограничения | Преимущества MemOS | +| --- | --- | --- | --- | +| **Традиционный RAG** | Поиск документов в базе знаний | Не обрабатывает поведение пользователя, не может сформировать профиль | Подходит для FAQ, но не может делать персонализированные инвестиционные рекомендации | +| **Собственное Хранилище** | Прямое хранение журналов поведения | Необходимо самостоятельно абстрагировать поведение → память; высокая стоимость создания Prompt | Необходимо разработать большое количество glue кода | +| **MemOS** | Два интерфейса: `addMessage` для записи, `searchMemory` для поиска | —— | Автоматически абстрагирует траектории поведения в память, доступную для прямого использования моделью | + + +### 1.5 Что будет показано в этом примере? + +В этом примере показано, как с помощью облачного сервиса MemOS быстро реализовать интеллектуального инвестиционного ассистента, который «превращает поведение пользователей в память». + +В Demo: + +* **D1 Поведение трафика**: клик на рекламу «пенсионного инвестирования» → создание памяти «интерес к пенсионному инвестированию». + +* **D2 Поведение в приложении**: просмотр и сохранение фондов с низким риском → создание памяти «предпочтение риска = низкий риск». + +* **D3 Поведение в диалоге**: сказать «не хочу рисковать» → создание памяти «четкое требование к низкому риску». + + +Когда пользователь спрашивает «Какой инвестиции мне подходит?»: + +* `searchMemory` находит вышеупомянутую память + +* Ответ, сгенерированный большой моделью, будет учитывать эти образы → вывод «более подходящие продукты с низким риском и фиксированным доходом». + + +При запуске этого сценария разработчик увидит в консоли: + +* Каждый запрос/ответ `addMessage` (действие сохранено) + +* Каждый запрос/ответ `searchMemory` (попадание в семантическую память) + +* Персонализированные инвестиционные рекомендации, выданные моделью в конечном итоге + + +## 2. Пример + +### 2.1 Подготовка окружения + +Используйте pip для установки необходимых зависимостей + +```shell +pip install MemoryOS -U +``` + +### 2.2 Полный код + +```python +import os +import uuid +from openai import OpenAI +from memos.api.client import MemOSClient + +os.environ["MEMOS_API_KEY"] = "mpg-xx" # Получите MemOS_API_KEY из консоли облачного сервиса +os.environ["OPENAI_API_KEY"] = "sk-xx" # Замените на свой собственный API_KEY + +conversation_counter = 0 + +def generate_conversation_id(): + global conversation_counter + conversation_counter += 1 + return f"conversation_{conversation_counter:03d}" + +class FinancialManagementAssistant: + """AI Финансовый Менеджер, обладающий памятью""" + + def __init__(self): + self.memos_client = MemOSClient(api_key=os.getenv("MEMOS_API_KEY")) + self.openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) + + def search_memory(self, query, user_id, conversation_id): + """Запрос Связанных Памятей""" + response = self.memos_client.search_memory(query, user_id, conversation_id) + + return [memory_detail.memory_value for memory_detail in response.data.memory_detail_list] + + def build_system_prompt(self, memories): + """Создание Системного Подсказки С Форматированными Памятями""" + base_prompt = """ + Вы Являетесь Знанием Обогащенным И Профессиональным Помощником По Управлению Финансами. + Вы Можете Доступить Память Диалога, Чтобы Помочь Вам Предоставить Более Индивидуализированные Ответы. + Используйте Память, Чтобы Понять Фон Пользователя, Предпочтения И Прошлые Взаимодействия. + Если Память Предоставлена, Пожалуйста, Естественно Ссылайтесь На Нее В Соответствующих Ситуациях, Но Не Упоминайте Явно О Наличии Памяти. + """ + + if memories: + # Форматирование Памяти В Нумерованный Список + formatted_memories = "## Память:\n" + for i, memory in enumerate(memories, 1): + formatted_memories += f"{i}. {memory}\n" + + return f"{base_prompt}\n\n{formatted_memories}" + else: + return base_prompt + + + def add_message(self, messages, user_id, conversation_id): + """Добавить Сообщение""" + self.memos_client.add_message(messages, user_id, conversation_id) + + def get_message(self, user_id, conversation_id): + """Получить Сообщение""" + response = self.memos_client.get_message(user_id, conversation_id) + + return response.data.message_detail_list + + def chat(self, query, user_id, conversation_id): + """Основная Функция Чата Для Обработки Диалогов С Интеграцией Памяти""" + # 1. Поиск Связанных Памятей + memories = self.search_memory(query, user_id, conversation_id) + + # Создание Системного Подсказки С Памятью + system_prompt = self.build_system_prompt(memories) + + # 2. Использование OpenAI Для Генерации Ответов + response = self.openai_client.chat.completions.create( + model="gpt-4o", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": query} + ] + ) + answer = response.choices[0].message.content + + # 3. Сохранение Диалога В Памяти + messages = [ + {"role": "user", "content": query}, + {"role": "assistant", "content": answer} + ] + self.memos_client.add_message(messages, user_id, conversation_id) + + return answer + +ai_assistant = FinancialManagementAssistant() +user_id = "memos_financial_management_user_123" + +def demo_questions(): + return [ + 'Каков мой риск-профиль', + "Рекомендуйте некоторые инвестиции, подходящие для меня" + ] + +def preset_user_behaviors(): + """Показать предустановленную память о поведении пользователя""" + conversation_id = generate_conversation_id() + + print(f"\n📊 Предустановленная память о поведении пользователя (conversation_id={conversation_id}):") + print("=" * 60) + + behaviors = [{ + "role": "user", + "content": "Нажмите на рекламу 'Финансовое планирование для пенсионеров', чтобы войти в APP" + }, { + "role": "user", + "content": "Просмотр и сохранение фондов с низким риском" + }] + + for i, behavior in enumerate(behaviors, 1): + print(f"{i}. {behavior['content']}") + ai_assistant.add_message(behaviors, user_id, conversation_id) + + print("=" * 60) + print("💡 Вышеуказанная память о поведении была записана в MemOS, помощник будет предоставлять персонализированные рекомендации на основе этой информации") + +def main(): + print("💰 Добро пожаловать в MemOS, чтобы увидеть примеры использования в помощнике по управлению финансами!") + print("💡 С помощью MemOS сделайте вашего финансового помощника более умным и заботливым! 😊 \n") + + # Спросите пользователя, хочет ли он сначала выполнить предустановленный диалог + while True: + pre_chat = input("🤔 Хотите сначала загрузить память о поведении пользователя? Ожидается расход 1 раза add лимита, выполнять? (y/n): ").strip().lower() + + if pre_chat in ['y', 'yes', '是', 'Y']: + preset_user_behaviors() + break + elif pre_chat in ['n', 'no', '否', 'N']: + print("📝 Начать новый диалог...") + break + else: + print("⚠️ Пожалуйста, введите 'y' для да или 'n' для нет") + + print("\n⚡️ В следующем вы вводите каждый вопрос, который будет развиваться в новом разговоре (новый conversation id). MemOS будет автоматически вспоминать вашу историю действий между сессиями, чтобы предоставить вам непрерывное, персонализированное обслуживание.") + print("\n🎯 Вот несколько примеров вопросов, вы можете продолжить разговор с помощником:") + for i, question in enumerate(demo_questions(), 1): + print(f" {i}. {question}") + + while True: + user_query = input("\n🤔 Пожалуйста, введите ваш вопрос (или введите 'exit' для выхода): ").strip() + + if user_query.lower() in ['quit', 'exit', 'q', '退出']: + print("👋 Спасибо за использование помощника по управлению финансами!") + break + + if not user_query: + continue + + print("🤖 Обработка...") + conversation_id = generate_conversation_id() + answer = ai_assistant.chat(user_query, user_id, conversation_id) + print(f"\n💬 conversation_id: {conversation_id}\n💡 [助手]: {answer}\n") + print("-" * 60) + + +if __name__ == "__main__": + main() +``` + +### 2.3 Объяснение кода + +1. Установите ваш MemOS API ключ и Open AI ключ в переменных окружения + +2. Создайте экземпляр FinancialManagementAssistant + +3. Выберите, выполнять ли диалог с предустановленными значениями, это потребует 1 раз `add` и 2 раза `search` + +4. Используйте функцию `main()`, чтобы взаимодействовать с ассистентом через цикл диалога + +5. Ассистент вызовет chat, сначала выполнит `search` для поиска памяти, затем вызовет OpenAI для диалога, и, наконец, выполнит `add` для сохранения памяти diff --git a/content/ru/usecase/frameworks/browser_extension.md b/content/ru/usecase/frameworks/browser_extension.md new file mode 100644 index 00000000..aab94635 --- /dev/null +++ b/content/ru/usecase/frameworks/browser_extension.md @@ -0,0 +1,3 @@ +--- +title: Плагин Браузера +--- diff --git a/content/ru/usecase/frameworks/claude_mcp.md b/content/ru/usecase/frameworks/claude_mcp.md new file mode 100644 index 00000000..b3afbb4b --- /dev/null +++ b/content/ru/usecase/frameworks/claude_mcp.md @@ -0,0 +1,59 @@ +--- +title: Claude MCP +--- + + +## 1. Конфигурация MCP и MemOS Облачного Сервиса + +Заполните следующую конфигурацию в клиенте: + +```json +{ + "mcpServers": { + "memos-api-mcp": { + "timeout": 60, + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@memtensor/memos-api-mcp" + ], + "env": { + "MEMOS_API_KEY": "mpg-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "MEMOS_USER_ID": "your-user-id", + "MEMOS_CHANNEL": "MODELSCOPE" + } + } + } +} +``` + +Способы получения переменных окружения: +- `MEMOS_API_KEY`: Зарегистрируйте аккаунт на официальном сайте MemOS [API Консоль](https://memos-dashboard.openmem.net/cn/apikeys/), затем создайте api-key на странице ключей API и скопируйте его сюда. + +![Создание api-key в MemOS API консоли](https://cdn.memtensor.com.cn/img/1763452232848_t268eh_compressed.png) + +- `MEMOS_USER_ID`: Определяемый пользователем уникальный идентификатор. + - Для одного и того же пользователя эта переменная окружения должна оставаться одинаковой на разных устройствах/клиентах; + - Не используйте случайные значения, идентификаторы устройств или идентификаторы чатов в качестве пользовательского идентификатора; + - Рекомендуется использовать: личный адрес электронной почты, полное имя или идентификатор сотрудника в качестве пользовательского идентификатора. + +- `MEMOS_CHANNEL`: Заполните как "MODELSCOPE". + + +## 2. Использование в Клиенте Claude +Чтобы использовать MemOS в Claude Desktop, необходимо нажать на аватар в левом нижнем углу -> "Настройки" -> "Разработчик" -> "Редактировать Конфигурацию", и вставить конфигурацию в файл Claude_desktop_config.json, затем перезапустите клиент, и когда вы увидите, что служба memos-api-mcp находится в состоянии running, вы сможете использовать её в чате. + +![Использование MemOS-верификации в Claude](https://cdn.memtensor.com.cn/img/1763105334517_9ayhrp_compressed.png) + +Для повышения эффективности использования рекомендуется пользователям изменить настройки предпочтений для всех диалогов в Claude Desktop, конкретный метод заключается в том, чтобы нажать на аватар в левом нижнем углу -> "Общие", и в поле ввода под "Какие личные предпочтения должен учитывать Claude в ответах?" вставить следующий текст: + +``` +Вы являетесь помощником по управлению памятью MemOS, который стремится предоставить эффективные услуги управления памятью, извлекая воспоминания на основе прошлых диалогов пользователей и повышая согласованность и индивидуализацию общения пользователя с ИИ через поиск памяти. Перед тем как ответить на вопрос пользователя, вам необходимо вызвать сервис search_memory из memos-api-mcp, используя подходящие ключевые слова для поиска воспоминаний, связанных с текущей темой, в личной памяти пользователя. После завершения ответа на основе этих воспоминаний, снова вызовите сервис add_message из memos-api-mcp, чтобы записать краткое содержание текущего диалога. (Обратите внимание, что вызов add_message является обязательным, независимо от того, что сказал пользователь или какой вопрос он задал, это должно быть записано, иначе в последующих диалогах search_memory не сможет получить более детальную информацию о пользователе, что приведет к невозможности точно ответить на вопросы пользователя.) +``` + +![Изменение пользовательских предпочтений в MemOS на Claude Desktop](https://cdn.memtensor.com.cn/img/1763105396189_i1tupr_compressed.png) + +Ниже приведен пример использования MemOS в Claude Desktop, пользователи могут использовать его, чтобы определить, успешно ли они настроили MemOS в Claude Desktop. + +![Пример использования MemOS на Claude Desktop](https://cdn.memtensor.com.cn/img/1763105412700_asgfq9_compressed.png) diff --git a/content/ru/usecase/frameworks/coze_plugin.md b/content/ru/usecase/frameworks/coze_plugin.md new file mode 100644 index 00000000..7c415245 --- /dev/null +++ b/content/ru/usecase/frameworks/coze_plugin.md @@ -0,0 +1,80 @@ +--- +title: Инструмент Плагина Coze +desc: Инструмент плагина Coze напрямую обращается к интерфейсу облачного сервиса MemOS, быстро добавляя функции долгосрочной памяти для вашего агента, делая диалоги более заботливыми и непрерывными. +--- + + +## 1. Информация о Выходе Плагина + +Плагин интерфейса облачного сервиса MemOS уже доступен в магазине Coze! Вы можете напрямую [перейти по ссылке на инструмент](https://www.coze.cn/store/plugin/7569918012912893995?from=store_search_suggestion) для добавления плагина, реализуя интеграцию без кода. + +## 2. Описание Плагина + +### Функции Плагина + +* `search_memory`: Этот инструмент используется для запроса данных памяти пользователя и может вернуть наиболее релевантные фрагменты к введенному. Поддерживает实时检索 памяти во время диалога пользователя с ИИ, а также может выполнять глобальный поиск по всей памяти, что может быть использовано для создания профиля пользователя или поддержки персонализированных рекомендаций. При запросе необходимо предоставить такие параметры, как ID диалога, ID пользователя, текст запроса и т.д., также можно установить количество возвращаемых элементов памяти. + +* `add_memory`: Этот инструмент позволяет массово импортировать одно или несколько сообщений в базу данных памяти MemOS, что упрощает поиск в будущих диалогах, поддерживая управление историей чата, отслеживание поведения пользователей и персонализированное взаимодействие. При использовании необходимо указать ID диалога, содержание сообщения, роль отправителя, время диалога и ID пользователя. + +### Описание Интерфейса + +* search_memory интерфейс + +| Параметр Название | Параметр Тип | Описание | Обязательный | +| --- | --- | --- | --- | +| memory_limit_number | строка | Ограничение на количество возвращаемых элементов памяти, если не указано, по умолчанию 6 | Нет | +| memos_key | строка | Авторизационный ключ MemOS облачного сервиса | Да | +| memos_url | строка | URL-адрес MemOS облачного сервиса | Да | +| query | строка | Ввод пользователя | Да | +| user_id | строка | Уникальный идентификатор пользователя, связанный с запрашиваемой памятью | Да | + +* add_memory интерфейс + +| Параметр Название | Параметр Тип | Описание | Обязательный | +| --- | --- | --- | --- | +| conversation_id | строка | Уникальный идентификатор разговора | Да | +| memos_key | строка | Авторизационный ключ MemOS облачного сервиса | Да | +| memos_url | строка | URL-адрес MemOS облачного сервиса | Да | +| messages | Массив | Массив объектов сообщений | Да | +| user_id | строка | Уникальный идентификатор пользователя, связанный с запрашиваемой памятью | Да | + +## 3. Пример Вызова Агента + +### Пример Разработки Персонажа Агента и Логики Ответов +``` +Ты — робот для вопросов и ответов, который каждый раз читает память и интересы пользователя и отвечает с очень ясной логикой, чтобы завоевать симпатию пользователя. + +## Содержимое Рабочего Процесса +# 1. Доступ к {search_memory} для извлечения данных + Каждый раз, когда пользователь говорит, сначала вызывается функция поиска в памяти MemOS — плагин {search_memory}, вводя информацию: + Запишите имя пользователя как user_id, если это первый доступ, установите user_id как случайно сгенерированную строку из 16 символов UUID. + Использовать содержание речи пользователя в качестве query +# 2. Обработка {search_memory} Выходных Данных: + Получить данные, и если в них есть поле memory_detail_list, независимо от того, пуст ли список memory_detail_list, сразу вывести список memory_detail_list в формате json; если возвращаемое сообщение не равно ok, то вывести "Ошибка поиска плагина". +# 3. Ответить на вопросы пользователя на основе найденного memory_detail_list + Извлечь значение поля memory_value для каждого элемента в memory_detail_list и объединить все строки с помощью "\n" в качестве контекста для ответа на вопрос пользователя; большой модель может отвечать на запрос пользователя на основе информации, предоставленной в контексте; если контекстная информация пустая строка, большая модель может просто ответить на запрос пользователя. + Затем записать содержание ответа большой модели в answer. +# 4. Доступ к {add_memory} для хранения данных + Вызвать функцию add_memory для хранения вопроса пользователя и соответствующего ответа, вводя информацию: + chat_time: Вызвать {current_time} для получения текущего времени, отформатировать временную метку в формате "%I:%M %p on %d %B, %Y UTC" + conversation_id: Записать текущее время chat_time с точностью до минут, строка времени будет использоваться как conversation_id + user_id: Записать имя пользователя как user_id + messages: Записать введенный пользователем query и все полученные ответы answer как content для роли messages и content для assistant, chat_time использовать только что полученное значение chat_time, организовать в одну запись messages: + [ + {"role": "user", "content": query, "chat_time": chat_time}, + {"role": "assistant", "content": answer, "chat_time": chat_time} + ] + Получить обратную связь от плагина {add_memory}, если поле success в data равно True, то это успех, *не нужно уведомлять пользователя*; если возвращаемое поле не равно True, то сообщить пользователю, что доступ к add_memory не удался. + +## Требования +Каждый раз при доступе к {search_memory} и {search_memory} необходимо передавать два фиксированных параметра: +memos_url = "https://memos.memtensor.cn/api/openmem/v1" +memos_key = "Token mpg-XXXXXXXXXXXXXXXXXXXXXXXXXXX" + +Вашей ролью является мудрый и заботливый помощник по памяти, имя которого — 小智. +Если все плагины работают без сбоев, в ответах большой модели не нужно уведомлять пользователя о том, что все прошло успешно. +Только при первом диалоге с пользователем сгенерируйте user_id с помощью UUID, этот user_id будет использоваться в дальнейшем. +``` + +[Пример агента](https://www.coze.cn/s/85NOIg062vQ) +![Рабочий процесс агента](https://cdn.memtensor.com.cn/img/coze_workflow_compressed.png) diff --git a/content/ru/usecase/home_assistant.md b/content/ru/usecase/home_assistant.md new file mode 100644 index 00000000..e8c7a92b --- /dev/null +++ b/content/ru/usecase/home_assistant.md @@ -0,0 +1,284 @@ +--- +title: Построение Семейного Помощника С Памятью +desc: С помощью MemOS, семейный помощник может связать повседневные дела с долгосрочными планами, быстро понимать и реагировать на истинные потребности пользователей. +--- + +## 1. Обзор + +При разработке таких продуктов, как семейный помощник, разработчики часто сталкиваются с одной проблемой: **как только контекст разговора заканчивается, информация о пользователе теряется**. + +* Задачи, которые пользователь упоминает вскользь ("В субботу нужно взять детей в зоопарк") + +* Привычки пользователя ("При напоминании сначала нужно перечислить основные моменты, а затем дать одно предложение с рекомендацией") + +* Информация о семье пользователя ("Мою жену зовут Сяо Юнь, ребенку 6 лет") + + +Если помощник не может запомнить эту информацию, он будет казаться "бессердечным": когда пользователь на следующий день спросит "Что у меня запланировано на выходные?", помощник совершенно не будет знать, о чем идет речь. + + +### 1.1 Почему Не Использовать Традиционный RAG? + +Многие люди сразу же подумают: можно ли использовать RAG (Улучшение Генерации Поиском)? +Но особенности традиционного RAG определяют, что он не подходит для такого "персонализированного помощника": + +| Традиционный RAG | MemOS | +| --- | --- | +| Зависит от статической базы знаний, требует постоянного ручного обслуживания документов | Информация, возникающая в диалоге, может быть записана напрямую, без дополнительного обслуживания | +| Может только механически возвращать фрагменты, не будет автоматически обучаться предпочтениям | Будет автоматически формировать задачи, предпочтения, образы и другие воспоминания в ходе диалога | +| Ориентирован на "общие знания", не подходит для хранения персонализированной информации | Специально разработан для индивидуальных сценариев, поддерживает долгосрочное отслеживание и вызов | + + +### 1.2 Почему Не Создать Свой Собственный Решение? + +Конечно, вы также можете попробовать самостоятельно хранить эту информацию, но это приведет к нескольким проблемам: + +* **Сложная Логика Хранения и Поиска**: Необходимо различать содержание разговора, долгосрочную память, предпочтения и факты, и гарантировать возможность поиска по запросу в любое время. + +* **Проблемы с Интеграцией с Большими Моделями**: Необходимо не только хранить данные, но и передавать соответствующую информацию в "Prompt" перед генерацией ответа. + +* **Плохая Масштабируемость**: С увеличением функциональности (задачи, предпочтения, профили) код становится все труднее поддерживать. + + +### 1.3 Почему Использовать MemOS? + +При выборе решения можно наглядно сравнить три варианта: + +| Решение | Особенности | Ограничения | Преимущества MemOS | +| --- | --- | --- | --- | +| Традиционный RAG | Путем векторного поиска документов базы знаний, вставляется в Prompt | Требует ручного обслуживания статических документов; не может хранить персонализированные задачи/предпочтения; будет только механически возвращать фрагменты | Автоматически захватывает ключевую информацию из диалога, поддерживает персонализацию, динамическое обновление | +| Собственное решение для хранения | Создание таблиц/кэша, сохранение информации о диалоге | Логика сложная: нужно различать диалог/долгосрочную память/предпочтения/образы; перед вызовом модели нужно вручную составить Prompt; сложно поддерживать расширение функций | MemOS объединяет хранение + поиск + инъекцию Prompt, снижая нагрузку на разработку | +| MemOS | Два интерфейса: `addMessage` для записи, `searchMemory` для поиска | —— | Поддерживает долгосрочное отслеживание, сохранение предпочтений, сочетание образов; готов к использованию, легко расширяем | + +Достаточно вызвать два интерфейса: + +* `addMessage`: записать сообщение пользователя или помощника в систему. + +* `searchMemory`: перед генерацией ответа модели выполнить поиск соответствующей памяти и вставить результат в "Prompt". + + +Таким образом, помощник сможет проявить настоящую "память": + +* **Отслеживание Задач** + + * Пользователь говорит "В субботу нужно взять детей в зоопарк" + + * Через несколько дней спрашивает "Что у меня запланировано на выходные?" → может точно ответить + +* **Сохранение Предпочтений** (будущие версии будут поддерживать более детальную доработку инструкций) + + * Пользователь говорит "Напоминание должно сначала перечислить основные моменты + одно предложение с рекомендацией" + + * Затем спрашивает "Помоги мне спланировать распределение домашних дел на следующую неделю" → вывод сохраняет стиль предпочтений + +* **Комбинирование Профилей** + + * Пользователь говорит "Мою жену зовут Сяо Юнь, ребенку 6 лет" + + * Затем спрашивает "Какое мероприятие можно организовать на выходные для семьи?" → предлагает подходящий план мероприятий для семей с детьми + +### 1.4 Что Будет Показано В Этом Примере? + +Мы быстро реализуем семейного помощника, который "помнит пользователей", с помощью облачного сервиса MemOS. +При запуске сценария примера разработчики смогут увидеть полный журнал: + +* Запросы/ответы на каждое вызов `addMessage` и `searchMemory` + +* Попадания в записи памяти + +* Составленные инструкции и полные инструкции ← TODO: скоро будет доступно, следите за обновлениями + +* Ответы, сгенерированные моделью (при отсутствии интеграции с большой моделью будет сообщение [Не подключена большая модель]) + + +## 2. Пример + +### 2.1 Подготовка Окружения + +Используйте pip для установки необходимых зависимостей + +```shell +pip install MemoryOS -U +``` + + +### 2.2 Полный Код + +```python +import os +import uuid +from openai import OpenAI +from memos.api.client import MemOSClient + +os.environ["MEMOS_API_KEY"] = "mpg-xx" # Получите MemOS_API_KEY из консоли облачного сервиса +os.environ["OPENAI_API_KEY"] = "sk-xx" # Замените на свой собственный API_KEY + +conversation_counter = 0 + +def generate_conversation_id(): + global conversation_counter + conversation_counter += 1 + return f"conversation_{conversation_counter:03d}" + +class HomeAssistant: + def __init__(self): + self.memos_client = MemOSClient(api_key=os.getenv("MEMOS_API_KEY")) + self.openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) + + def search_memory(self, query, user_id, conversation_id): + """Запросить связанные воспоминания""" + response = self.memos_client.search_memory(query, user_id, conversation_id) + + return [memory_detail.memory_value for memory_detail in response.data.memory_detail_list] + + def add_message(self, messages, user_id, conversation_id): + """Добавить сообщение""" + self.memos_client.add_message(messages, user_id, conversation_id) + + def get_message(self, user_id, conversation_id): + """Получить сообщение""" + response = self.memos_client.get_message(user_id, conversation_id) + + return response.data.message_detail_list + + def build_system_prompt(self, memories): + """Создать системное сообщение с форматированными воспоминаниями""" + base_prompt = """ + Вы — знающий и заботливый помощник по домашнему хозяйству. + Вы можете использовать диалоговую память, чтобы предоставить более персонализированные ответы. + Пожалуйста, воспользуйтесь этой памятью, чтобы понять контекст, предпочтения и прошлые взаимодействия пользователя. + Если предоставлено содержимое памяти, в соответствующих случаях необходимо естественно ссылаться на эту информацию, но не нужно явно упоминать, что у вас есть функция памяти. + """ + + if memories: + # Форматирование памяти в нумерованный список + formatted_memories = "## Память:\n" + for i, memory in enumerate(memories, 1): + formatted_memories += f"{i}. {memory}\n" + + return f"{base_prompt}\n\n{formatted_memories}" + else: + return base_prompt + + + def chat(self, query, user_id, conversation_id): + """Основная функция чата для обработки диалогов с интеграцией памяти""" + # 1. Поиск соответствующей памяти + memories = self.search_memory(query, user_id, conversation_id) + + # Создание системного подсказки с памятью + system_prompt = self.build_system_prompt(memories) + + # 2. Использование OpenAI для генерации ответа + response = self.openai_client.chat.completions.create( + model="gpt-4o", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": query} + ] + ) + answer = response.choices[0].message.content + + # 3. Сохранение диалога в памяти + messages = [ + {"role": "user", "content": query}, + {"role": "assistant", "content": answer} + ] + self.memos_client.add_message(messages, user_id, conversation_id) + + return answer + +ai_assistant = HomeAssistant() +user_id = "memos_home_management_user_123" + +def demo_questions(): + return [ + "Какие у меня планы на выходные?" + "Помоги мне спланировать распределение домашних дел на следующую неделю" + ] + +def pre_configured_conversations(): + """Возврат преднастроенной пары диалогов""" + return [ + { + "user": "В субботу я должен взять детей в зоопарк, запомни это.", + }, + { + "user": "Пожалуйста, напомни или запланируй, сначала перечисли три основных момента, а затем добавь короткое предложение с советом.", + } + ] + +def execute_pre_conversations(): + """Выполнение преднастроенного диалога""" + conversation_id = generate_conversation_id() + conversations = pre_configured_conversations() + + print(f"\n🔄 Выполняется преднастроенный диалог (conversation_id={conversation_id})...") + print("=" * 60) + + for i, conv in enumerate(conversations, 1): + print(f"\n💬 Диалог {i}") + print(f"👤 Пользователь: {conv['user']}") + + # Выполнение диалога + answer = ai_assistant.chat(conv['user'], user_id, conversation_id) + print(f"🤖 [Ассистент]: {answer}") + print("-" * 40) + + print("\n✅ Выполнение преднастроенного диалога завершено!") + print("=" * 60) + +def main(): + print("🏠 Добро пожаловать, посмотрите примеры использования MemOS в домашнем помощнике!") + print("💡 С помощью MemOS ваши продукты смогут достичь эффекта настоящего управляющего! 😊 \n") + + # Спросить пользователя, хочет ли он сначала выполнить преднастроенный диалог + while True: + pre_chat = input("🤔 Вы хотите сначала выполнить преднастроенный диалог? Ожидается использование 2 вызовов add и 2 вызовов search, выполнять? (y/n): ").strip().lower() + + if pre_chat in ['y', 'yes', '是', 'Y']: + execute_pre_conversations() + break + elif pre_chat in ['n', 'no', '否', 'N']: + print("📝 Начинаем новый диалог...") + break + else: + print("⚠️ Пожалуйста, введите 'y' для да или 'n' для нет") + + print("\n⚡️ В следующем вы вводите каждый вопрос, который будет развиваться в новом разговоре (новый conversation id). MemOS будет автоматически вспоминать вашу историю действий между сессиями, чтобы предоставить вам непрерывное, персонализированное обслуживание.") + print("\n🎯 Вот несколько примеров вопросов, вы можете продолжить разговор с помощником:") + for i, question in enumerate(demo_questions(), 1): + print(f" {i}. {question}") + + while True: + user_query = input("\n🤔 Пожалуйста, введите ваш вопрос (или введите 'exit' для выхода): ").strip() + + if user_query.lower() in ['quit', 'exit', 'q', '退出']: + print("👋 Спасибо за использование домашнего помощника!") + break + + if not user_query: + continue + + print("🤖 Обработка...") + conversation_id = generate_conversation_id() + answer = ai_assistant.chat(user_query, user_id, conversation_id) + print(f"\n💬 conversation_id: {conversation_id}\n💡 [助手]: {answer}\n") + print("-" * 60) + + +if __name__ == "__main__": + main() +``` + +### 2.3 Объяснение Кода + +1. Установите ваш MemOS API ключ и Open AI ключ в переменных окружения + +2. Создайте экземпляр `HomeAssistant` + +3. Выберите, хотите ли вы выполнить диалог с предустановленными значениями, это потребует 2 вызова add и 2 вызова search + +4. Используйте функцию `main()` для взаимодействия с помощником через цикл диалога + +5. Помощник вызовет chat, сначала выполнит поиск памяти, затем вызовет OpenAI для диалога, и в конце выполнит add для хранения памяти diff --git a/content/ru/usecase/knowledge_qa_assistant.md b/content/ru/usecase/knowledge_qa_assistant.md new file mode 100644 index 00000000..39817c1a --- /dev/null +++ b/content/ru/usecase/knowledge_qa_assistant.md @@ -0,0 +1,430 @@ +--- +title: Построение Усиленного Памятью Помощника По Вопросам И Ответам +desc: Интеграция Долговременной Памяти И Базы Знаний, Прощание С "Тысячи Лицами" Результатов Поиска, Предоставление Персонализированных И Точных Ответов На Основе Фона И Предпочтений Пользователя, Позволяя Базе Знаний Стать Вашим Личным Консультантом. +--- + +## 1. Обзор + +В Разработке Приложений AI Построение Помощника По Вопросам И Ответам, Который Может Понимать Контекст И Запоминать Исторические Взаимодействия, Всегда Было Основной Необходимостью. Традиционные Большие Языковые Модели Хотя И Мощные, Но Лишены Долговременной Памяти, Каждая Беседа Начинается Как "Амнезия". RAG (Усиление Поиска Генерацией) Хотя И Может Искать Связанную Информацию, Но Не Может По Настоящему "Запомнить" Предпочтения И Исторические Взаимодействия Пользователя. + +MemOS Предоставляет Полную Экосистему Операционной Системы Памяти, Позволяя Приложениям AI Обладать Настоящей Долговременной Памятью. На Основе Базы Знаний MemOS, В Сочетании С Подсказками, Предоставляется Контекстная Информация Большой Модели AI, Что Позволяет Получить Более Точные И Персонализированные Ответы. Этот Опыт Значительно Превосходит Прямое Общение В Интернете С Общими Большими Моделями. + +### 1.1 Уровень Памяти MemOS vs RAG: Основные Отличия + +Основная Проблема Традиционных Решений RAG (Усиление Поиска Генерацией) Заключается В ТОМ, ЧТО:**Оно Безсостояние**. Каждый Запрос Является Независимым, Система Может Искать Статическую Информацию В Базе Знаний Только На Основе Семантического Сходства, Но Не Может Запомнить "Кто Ты", "Что Ты Говорил Ранее", "Каковы Твои Предпочтения". Это Похоже На Библиотекаря С Амнезией, Который Каждый Раз Должен Задавать Твои Потребности, Не Могущего Предоставить Персонализированные Рекомендации На Основе Твоей Истории Чтения. + +Основная Ценность Уровня Памяти MemOS Заключается В ТОМ, ЧТО:**Позволяет Приложениям AI Обладать Долговременной Памятью**. Оно Не Только Может Искать Знания, Но И Понимать Связи, Время И Предпочтения, Связывая Текущую Проблему С Исторической Памятью, Ищет И Использует Знания С Учетом "Контекста". С Продолжением Использования Пользователем, MemOS Будет Динамически Эволюционировать И Обновлять Память На Основе Содержания Беседы, Способствуя Автоматической Итерации И Самоэволюции Базы Знаний. + +| Сравнительные Параметры | Традиционное RAG Решение | MemOS Уровень Памяти | +| --- | --- | --- | +| **Способности Памяти** | Может Только Искать, Не Может Запоминать - Основано на Векторном Сходстве для Поиска Статической Базы Знаний, Не Может Динамически Записывать Историю Взаимодействия Пользователя | Динамические Способности Памяти - Автоматически Захватывает, Хранит и Управляет Историей Диалогов и Поведением Пользователя | +| **Персонализация** | Отсутствие Персонализации - Не Может Настраивать Стратегию Ответов на Основе Исторического Поведения Пользователя | Персонализированный Опыт - Предоставляет Индивидуальные Ответы на Основе Исторических Предпочтений Пользователя | +| **Управление Контекстом** | Разрыв Контекста - Связанная Информация в Многораундных Диалогах Трудно Эффективно Управлять | Умная Связь - Устанавливает Связи Между Памятью на Основе Семантического Понимания | +| **Обновление Знаний** | Трудности с Обновлением Знаний - Новые Знания Требуют Повторной Постройки Векторного Индекса | Реальное Обновление - Поддерживает Инкрементное Обновление Памяти и Управление Приоритетами | + +### 1.2 Сравнение Реальных Сценариев: Помощник По Базе Знаний Для Предприятия + +Давайте Через Один Реальный Бизнес-Сценарий Наглядно Ощутим Основные Различия Между RAG И MemOS: + +```python +ДЕНЬ 1 Сотрудник Спрашивает: Мой Компьютер - MacBook Pro 13 дюймов, Чип Intel. Как Мне Установить Прокси для Внутренней Сети Компании? +ДЕНЬ 1 Ассистент Предоставил Шаги Установки для Версии Intel. +ДЕНЬ 20 Сотрудник Спрашивает: Прокси для Внутренней Сети Не Открывается, Какую Версию Мне Переустановить? +``` + +#### Проблемы Решения RAG + +```python +# Поиск Содержимого, Связанного с "Прокси для Внутренней Сети" и "Не Открывается", Но Не Удалось Вспомнить "Модель Устройства Пользователя" +Найдены Знания: +1. Расследование Распространенных Неполадок Прокси для Внутренней Сети +2. Инструкции по Установке Прокси для Внутренней Сети для Версий M1/M2 (ARM) +3. Инструкции по Установке Клиента Прокси для Внутренней Сети для Windows +4. Проблемы с Сетевым Подключением и Сертификатами +5. Общие Вопросы и Ответы + +❌ Ассистент Базы Знаний: Пожалуйста, попробуйте заново скачать и установить последнюю версию для Mac M1/M2(ARM) или клиент внутреннего прокси для Windows. Вот шаги установки:... +``` + +#### Преимущества Решения MemOS + +```python +# Поиск "внутреннего прокси" и "не открывается" связанных воспоминаний по вопросам сотрудников, автоматическое определение модели устройства этого сотрудника +Найдены воспоминания: +1. Пользователь установил внутренний прокси компании 20 дней назад, его устройство - MacBook Pro 13(Intel) +2. Часто встречающиеся неисправности внутреннего прокси +3. Инструкция по установке внутреннего прокси для версии Intel + +✅ Ассистент Базы Знаний: Вы используете MacBook Pro с чипом Intel, рекомендуется заново установить клиент внутреннего прокси для версии Intel. Вот ссылка для скачивания и шаги установки для версии Intel:... +``` + +### 1.3 Почему Использовать MemOS? + +На Основе Вышеупомянутых Реальных Сценариев, Мы Можем Ясно Увидеть Три Основных Преимущества MemOS По Сравнению С Традиционным RAG: + +1. **Понимание Пользователя: Автоматическое Дополнение Контекста** + + RAG Умеет Искать Информацию, Семантически Похожую На Запрос, Но Оно Безсостояние: Каждый Запрос Является Независимым, Лишенным Понимания Конкретного Пользователя И Контекста. Пользователь Должен Каждый Раз Повторять Фоновую Информацию В Беседе. + + MemOS Может Понимать Связи, Время И Предпочтения, Зная "Кто Ты", "Что Ты Делаешь". Достаточно Задать Вопрос, MemOS Автоматически Дополнит Контекст, Не Требуя Повторного Объяснения "Моя Собака Не Ест Куриное Мясо" Или "Мой Компьютер На Чипе Intel". + +2. **Персонализация: Запоминание Привычек И Предпочтений Пользователя** + + Пользователи С Разными Должностями И Рабочими Привычками Нуждаются В Разных Способах Обслуживания. MemOS Может Запомнить: + + "Этот Клиент Не Любит Слишком Агрессивные Продажи" + + "Ты Чаще Используешь Python, А Не Java" + + "Ты В Последний Раз Спрашивал О Политике Возмещения, Нужно Ли Тебе Войти В Процесс Заявки На Этот Раз" + + Эта Персонализированная Способность Позволяет Приложениям AI Действительно Стать "Твоим" Помощником, А Не Обычным Инструментом. + +3. **Эволюция Знаний: Постоянное Обучение Из Взаимодействий** + + +Когда В Реальных Процессах Существуют "Правила Опыта", Которые Не Записаны В Документах, MemOS Будет Закреплять Их В Виде Новой Памяти, Постоянно Дополняя И Совершенствуя Систему Знаний. С Продолжением Использования Конечными Пользователями, MemOS Будет Динамически Эволюционировать И Обновлять Память На Основе Содержания Беседы, Делая Базу Знаний Часть "Памяти", А Не Просто Хранилищем Статических Документов. + +На Этой Основе, MemOS 2.0 Предоставляет Базу Знаний И Мультимодальные Возможности, Поддерживая Разработчиков В Интеграции Бизнес-Документов С MemOS, В Сочетании С Открытыми Большими Моделями, Позволяя Быстро Создать Помощника По Вопросам И Ответам, Который Понимает Пользователя. + +## 2. Учебник По Построению + +### 2.1 Подготовка Базы Знаний (5мин) + +#### Создание Базы Знаний + +Создайте базу знаний через [консоль](https://memos-dashboard.openmem.net/cn/knowledgeBase/) или API. Эта статья основана на [официальной документации MemOS](https://github.com/MemTensor/MemOS-Docs), статьях, опубликованных Memory Tensor, и примечаниях к релизу, чтобы классифицировать базу знаний для удобства последующих обновлений и управления. В этом примере вы можете создать только одну базу знаний и загрузить несколько документов для тестирования. + +![image.png](https://cdn.memtensor.com.cn/img/1768481403940_o97qz4_compressed.png) + +#### Загрузка Документов + +Перейдите в базу знаний, загрузите документы, обратите внимание на требования к документам. MemOS-Docs все в формате MD, их можно легко преобразовать в формат TXT с помощью AI, а затем загрузить. При загрузке необходимо учитывать требования к документам, все остальное **хранение, анализ, сегментация, генерация памяти** полностью доверяется MemOS, вам нужно просто спокойно ждать, пока документы будут обработаны, пока статус не покажет «Доступно». + +![image.png](https://cdn.memtensor.com.cn/img/1768481436752_31pl0b_compressed.png) + +### 2.2 Запуск Кода (5мин) + +Следующий пример кода демонстрируется в среде выполнения python. + +#### 2.2.1 Скопируйте Полный Код Запуска + +```python +import os +import requests +import json +from openai import OpenAI +from datetime import datetime + +# Получите MemOS_API_KEY из консоли облачных сервисов +os.environ["MEMOS_API_KEY"] = "mpg-xxx" +# Замените на ваш собственный API_KEY +os.environ["OPENAI_API_KEY"] = "sk-xxx" +os.environ["MEMOS_BASE_URL"] = "https://memos.memtensor.cn/api/openmem/v1" +# Замените на ваш собственный ID базы знаний, следующий ID является лишь примером и не является реальным ID базы знаний +os.environ["KNOWLEDGE_BASE_IDS"] = json.dumps([ + "based540fb25-ddf1-4456-935b-41d901518e04", + "base3908d457-da43-4dde-989e-020be132eff4", + "base1db3a7ea-6ecc-4925-881a-e87800da8d2e" +]) + +openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) + +class KnowledgeBaseAssistant: + + def __init__(self): + self.openai_client = openai_client + self.base_url = os.getenv("MEMOS_BASE_URL") + self.knowledge_base_ids = json.loads(os.getenv("KNOWLEDGE_BASE_IDS")) + self.headers = { + "Content-Type": "application/json", + "Authorization": f"Token {os.environ['MEMOS_API_KEY']}" + } + + def search_memory(self, query, user_id): + """Запросить связанные воспоминания""" + data = { + "query": query, + "user_id": user_id, + "conversation_id": user_id, + "knowledgebase_ids": self.knowledge_base_ids + } + res = requests.post(f"{self.base_url}/search/memory", headers=self.headers, data=json.dumps(data)) + + if res.json().get('code') != 0: + print(f"❌ Запрос воспоминаний не удался, {res.json().get('message')}") + return [], [] + + memory_detail_list_raw = res.json().get('data').get('memory_detail_list', []) + # Фильтровать воспоминания с релевантностью менее 0.5 + memory_detail_list = [ + x for x in memory_detail_list_raw + if x.get('relativity', 0) >= 0.5 + ] + preference_detail_list = res.json().get('data').get('preference_detail_list') + + return memory_detail_list, preference_detail_list + + def build_system_prompt(self, memories, preferences): + """Создать системный запрос с форматированными воспоминаниями""" + base_prompt = """ + # Role + Вы — MemOS интеллектуальный помощник, прозвище Маленькая Память🧚 — AI помощник «Операционной Системы Памяти», созданный MemTensor. MemTensor — это исследовательская компания в области искусственного интеллекта, расположенная в Шанхае, под руководством академиков Китайской академии наук. MemTensor стремится к видению «низкие затраты, низкие иллюзии, высокая обобщаемость», исследуя пути развития искусственного интеллекта, соответствующие китайским условиям, и продвигая применение надежных технологий искусственного интеллекта. Миссия MemOS — наделить большие языковые модели (LLMs) и автономные интеллектуальные агенты «человекообразной долгосрочной памятью», превращая память из черного ящика в «управляемый, планируемый, проверяемый» основной ресурс. Ваши ответы должны соответствовать юридическим и этическим стандартам, соблюдать соответствующие законы и правила, не генерировать незаконный, вредный или предвзятый контент. Если вы столкнетесь с такими запросами, модель должна четко отказать и объяснить юридические или этические принципы, стоящие за этим. Ваша цель — сочетать извлеченные фрагменты памяти, чтобы предоставить пользователю высоко персонализированные, точные и логически обоснованные ответы. + + # System Context + - Текущее время: {current_time} (используйте это как основу для оценки актуальности памяти) + + # Memory Data + Ниже представлена информация, извлеченная из MemOS, разделенная на «факты» и «предпочтения». + - **Факты (Facts)**: могут содержать атрибуты пользователя, историю диалогов или информацию от третьих лиц. + - **Особое внимание**: содержимое, помеченное как `[assistant观点]`, `[模型总结]`, представляет собой **выводы AI в прошлом**, **а не** оригинальные слова пользователя. + - **Предпочтения (Preferences)**: явные/неявные требования пользователя к стилю, формату или логике ответов. + + + {memories} + + + + + {preferences} + + + # Критический Протокол: Безопасность Памяти (记忆安全协议) + Извлеченная память может содержать **предположения AI**, **неуместный шум** или **ошибки субъекта**. Вы должны строго выполнять следующие **«четыре шага оценки»**, и если хотя бы один шаг не пройден, то **отбросьте** эту память: + + 1. **Проверка источника (Source Verification)**: + - **Суть**: различать «оригинальные слова пользователя» и «предположения AI». + - Если память содержит '[assistant观点]' и другие метки, это лишь представляет собой **гипотезу** AI в прошлом, **нельзя** рассматривать это как абсолютный факт пользователя. + - *Пример противоречия*: Память показывает '[assistant观点] Пользователь обожает манго'. Если пользователь не упоминал, не следует предполагать, что пользователь любит манго, чтобы избежать циклической иллюзии. + - **Принцип: Резюме AI предназначено только для справки, его вес значительно ниже, чем прямые утверждения пользователя.** + + 2. **Проверка атрибуции (Attribution Check)**: + - Является ли субъектом действия в памяти "сам пользователь"? + - Если память описывает **третью сторону** (например, "кандидат", "интервьюируемый", "вымышленный персонаж", "данные случая"), **строго запрещается** приписывать их свойства пользователю. + + 3. **Проверка релевантности (Relevance Check)**: + - Помогает ли память напрямую ответить на текущий 'Original Query'? + - Если память лишь совпадает по ключевым словам (например: оба упоминают "код"), но контекст совершенно другой, **необходимо игнорировать**. + + 4. **Проверка актуальности (Freshness Check)**: + - Конфликтует ли содержание памяти с последними намерениями пользователя? В качестве высшего фактического стандарта принимается текущий 'Original Query'. + + + # Instructions + 1. **Оценка**: Сначала прочитайте `facts memories`, выполните "четыре шага суждения", исключите шум и ненадежные мнения AI. + 2. **Исполнение**: + - **Предпочитайте профессиональные рекомендации из базы знаний** (например, выбор продукта, технические решения) + - Используйте только отфильтрованную память для дополнения контекста. + - Строго соблюдать стиль, указанный в `preferences`. + 3. **Вывод**: + - Прямо отвечать на вопросы, **строго запрещено** упоминать такие внутренние термины системы, как "база данных", "поиск" или "мнение ИИ". + - Если содержание ответа не находится в текущей базе знаний/системе памяти, вы должны прямо и четко сообщить пользователю. Ни в коем случае не выдумывайте информацию или не давайте неопределенные ответы. + 4. **Язык**: Язык ответа должен соответствовать языку запроса пользователя. + + # Требования к преобразованию формата Markdown + - Когда вам нужно преобразовать данный текст в формате Markdown (MD) в чистый текст, вы должны строго следовать следующим требованиям, чтобы обеспечить четкость читаемости и отсутствие ошибок форматирования: + - Основные требования к адаптации формата: WeChat не поддерживает оригинальный синтаксис MD (например, #заголовок, жирный текст, блоки кода, таблицы). Вы должны использовать 'символ + перенос строки + пробел', чтобы смоделировать иерархическую структуру, избегая использования меток, которые WeChat не может распознать;" + - Обработка уровней заголовков: сначала проверьте, содержит ли оригинал формат заголовка Markdown (строки, начинающиеся с #). Если да: заголовки первого уровня (высший уровень) используют китайские числовые обозначения, такие как ' 一. '、' 二. '、' 三. ' (обратите внимание: используйте '.' вместо '、'); заголовки второго уровня (на один # больше, чем высший уровень) используют арабские числовые обозначения, такие как '1. '、'2. '、'3. '; заголовки третьего уровня (на два # больше, чем высший уровень) и ниже используют символ '・' в качестве маркированного списка. Номера должны автоматически увеличиваться в зависимости от структуры документа для поддержания согласованной иерархии. Если нет: не добавляйте никаких номеров заголовков, сохраняйте исходную структуру абзацев. Пример: оригинальный MD заголовок '### Заголовок 1' → ' 一. Заголовок 1'; оригинальный MD заголовок '#### Заголовок 2' → '1. Заголовок 2'; оригинальный MD заголовок '##### Заголовок 3' → '・Заголовок 3'; когда в оригинале нет MD заголовков, 'Заголовок 1' остается 'Заголовок 1'; + - Обработка Ссылок: Сохраняйте формат Markdown ссылок в виде 'текст'. Не изменяйте и не удаляйте содержимое ссылок (пример: MemOS 文档保持为 MemOS 文档);" + - Обработка Списков: У统一将'- 内容'格式的 MD списки преобразовать в упорядоченные списки (например, '1. 内容', '2. 内容') или неупорядоченные списки (используя символ '・', например, '・内容'). Каждый элемент списка должен быть на отдельной строке, с одним пустым пространством сверху и снизу для повышения читаемости;" + - Замена Таблиц: Если оригинальный MD содержит таблицы, разбейте их на '▶ 场景类型 A:XXX', '▶ 场景类型 B:XXX' формат пунктов. Под каждой категорией используйте '1. 2. 3. ' для перечисления соответствующего содержания, убедитесь, что информация не пропущена и символы таблицы не сохраняются;" + - Подчеркивание Ключевого Содержания: Не используйте * или ** символы, замените оригинальное жирное содержание в MD на '「XXX」' (китайские двойные кавычки);" + - Оптимизация Чтения: Оставляйте 1 пустую строку между основными абзацами (например, ' 一. XXX', ' 二. XXX'). Для слишком длинных технических терминов или сложных описаний в оригинальном MD используйте более разговорные выражения для упрощения, но не изменяйте оригинальный смысл; используйте китайские символы в качестве всех разделителей (например, ▶、・、:), избегайте смешивания китайских и английских символов, чтобы избежать путаницы в формате;" + - Требования к Выходу: Выводите только преобразованный чистый текст; не включайте дополнительные пояснения (например, '转换完成'); не изменяйте оригинальное содержание — только заменяйте формат; убедитесь, что 100% оригинальной информации MD (например, сравнительные размеры, функциональные точки, ссылки, данные) не пропущены или изменены; финальный текст должен быть готов к прямой отправке без дальнейшего редактирования." + """ + + # Конструирование Текста Памяти (может быть пустым) + if len(memories) > 0: + formatted_memories = "## 相关记忆:\n" + for i, memory in enumerate(memories, 1): + formatted_memories += f"{i}. {memory.get('memory_value')}\n" + else: + formatted_memories = "" + + # Конструирование Текста Предпочтений (может быть пустым) + if len(preferences) > 0: + formatted_preferences = "## 偏好:\n" + for i, preference_detail in enumerate(preferences, 1): + formatted_preferences += f"{i}. {preference_detail.get('preference')}\n" + else: + formatted_preferences = "" + + base_prompt = base_prompt.format( + current_time=datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + memories=formatted_memories, + preferences=formatted_preferences, + ) + + return base_prompt + + def add_message(self, messages, user_id): + """Добавить Сообщение""" + data = { + "messages": messages, + "user_id": user_id, + "conversation_id": user_id + } + + res = requests.post(f"{self.base_url}/add/message", headers=self.headers, data=json.dumps(data)) + + if res.json().get('code') == 0: + print(f"✅ Добавлено Успешно") + else: + print(f"❌ Добавление Не Удалось, {res.json().get('message')}") + + + def get_message(self, user_id): + """Получить Сообщение""" + data = { + "user_id": user_id, + "conversation_id": user_id, + "message_limit_number": 15 + } + res = requests.post(f"{self.base_url}/get/message", headers=self.headers, data=json.dumps(data)) + + if res.json().get('code') == 0: + return res.json().get('data').get('message_detail_list') + else: + print(f"❌ Не удалось получить сообщение, {res.json().get('message')}") + return [] + + def chat(self, query, user_id): + """Основная функция чата для обработки диалогов с интеграцией памяти""" + # 1. Запрос недавних сессий + chat_history = self.get_message(user_id) + + # 2. Поиск связанных воспоминаний + memories, preferences = self.search_memory(query, user_id) + + # 3. Создание системного подсказки с учетом памяти + system_prompt = self.build_system_prompt(memories, preferences) + + messages = [ + {"role": "system", "content": system_prompt}, + *chat_history, + {"role": "user", "content": query} + ] + + # 4. Использование OpenAI для генерации ответа + response = self.openai_client.chat.completions.create( + model="gpt-4o", + messages=messages, + temperature=0.3, + top_p=0.9 + ) + answer = response.choices[0].message.content + + # 5. Сохранение диалога в памяти + messages = [ + {"role": "user", "content": query}, + {"role": "assistant", "content": answer} + ] + self.add_message(messages, user_id) + + # 6. Возврат ответа + return answer + +ai_assistant = KnowledgeBaseAssistant() +user_id = "memos_knowledge_base_user_123" + +def demo_questions(): + return [ + 'Кто ты?' + ] + +def main(): + print("💡 Добро пожаловать в помощник по вопросам базы знаний!\n") + print("\n🎯 Вот несколько примеров вопросов, вы можете продолжить диалог с помощником:") + for i, question in enumerate(demo_questions(), 1): + print(f" {i}. {question}") + + while True: + user_query = input("\n🤔 Пожалуйста, введите ваш вопрос (или введите 'exit' для выхода): ").strip() + + if user_query.lower() in ['quit', 'exit', 'q', 'выход']: + print("👋 Спасибо за использование помощника по вопросам базы знаний!") + break + + if not user_query: + continue + + print("🤖 Обработка...") + answer = ai_assistant.chat(user_query, user_id) + print(f"💡 [助手]: {answer}") + print("-" * 60) + + +if __name__ == "__main__": + main() + +``` + +#### 2.2.2 Инициализация Среды Выполнения + +```python +pip install OpenAI && pip install datetime +``` + +#### 2.2.3 Замените Переменные Среды В Коде + +##### Получите Ключ (API\_KEY) + +Войдите в консоль [https://memos-dashboard.openmem.net/cn/apikeys/](https://memos-dashboard.openmem.net/cn/apikeys/), скопируйте ключ + +![image.png](https://cdn.memtensor.com.cn/img/1768481468406_q51iqx_compressed.png) + +```python +os.environ["MEMOS_API_KEY"] = "mpg-xx" +``` + +##### Клиент Большой Модели + +```python +# Замените на ваш собственный API_KEY +os.environ["OPENAI_API_KEY"] = "sk-xx" + +openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) +``` + +##### Получите ID Базы Знаний + +Для только что загруженной базы знаний скопируйте ID и сохраните. + +![image.png](https://cdn.memtensor.com.cn/img/1768481493435_bkwqlu_compressed.png) + +```python +# Замените на ваш собственный ID базы знаний, следующий ID является лишь примером и не является реальным ID базы знаний +os.environ["KNOWLEDGE_BASE_IDS"] = json.dumps([ + "based540fb25-ddf1-4456-935b-41d901518e04" +]) +``` + +##### Выполните Код +```python +python knowledge_qa_assistant.py +``` + +![image.png](https://cdn.memtensor.com.cn/img/1768533833272_krke26_compressed.jpeg) + +### 2.3 Описание Кода + +1. Установите свой собственный API-ключ MemOS, ключ OpenAI и ID базы знаний в переменных среды. + +2. Создайте экземпляр KnowledgeBaseAssistant. + +3. Используйте функцию `main()`, чтобы взаимодействовать с помощником в цикле диалога. + +4. Помощник вызовет chat, чтобы взаимодействовать с вами, chat после выполнения следующих шагов вернет вам ответ большой модели. + + +* Вызовите get\_message, чтобы найти сообщения из истории диалога. + +* Вызовите search\_memory, чтобы получить память и предпочтения. + +* Постройте prompt на основе системы памяти. + +* Используйте большую модель для генерации ответа. + +* Вызовите add\_message, чтобы сохранить запрос пользователя и ответ большой модели в памяти, создавая долгосрочную память. + +* Верните ответ большой модели. diff --git a/content/ru/usecase/plugin_tool.md b/content/ru/usecase/plugin_tool.md new file mode 100644 index 00000000..3f30c2b2 --- /dev/null +++ b/content/ru/usecase/plugin_tool.md @@ -0,0 +1,84 @@ +--- +title: Инструменты Плагинов Платформы Разработки Agent +desc: Доступ к размещенным инструментам плагинов осуществляется через интерфейс облачного сервиса MemOS, что позволяет быстро добавить функции долгосрочной памяти для вашего Agent, делая диалоги более внимательными и последовательными. +--- + + +## 1. Инструменты Плагинов Платформы Coze + +### 1.1 Информация о Размещении Плагинов + +Плагин интерфейса облачного сервиса MemOS уже доступен в магазине Coze! Вы можете напрямую искать или перейти по ссылке для добавления плагина, осуществляя интеграцию без кода. + +[工具链接](https://www.coze.cn/store/plugin/7569918012912893995?from=store_search_suggestion) + +### 1.2 Описание Плагина + +* **Описание Функций Плагина** + +* `search_memory`: Этот инструмент используется для запроса данных памяти пользователя и может вернуть наиболее релевантные фрагменты к введенному запросу. Поддерживает实时检索 памяти во время диалога пользователя с AI, а также может выполнять глобальный поиск по всей памяти, что может быть использовано для создания профилей пользователей или поддержки персонализированных рекомендаций. При запросе необходимо предоставить такие параметры, как ID диалога, ID пользователя, текст запроса и т.д., также можно установить количество возвращаемых элементов памяти. + +* `add_memory`: Этот инструмент позволяет массово импортировать одно или несколько сообщений в базу данных памяти MemOS, что упрощает их поиск в будущих диалогах, поддерживая управление историей чата, отслеживание поведения пользователей и персонализированное взаимодействие. При использовании необходимо указать ID диалога, содержание сообщения, роль отправителя, время диалога и ID пользователя. + +* **Описание Интерфейса** + +* Интерфейс search_memory + +| 参数名称 | 参数类型 | 描述 | 是否必填 | +| --- | --- | --- | --- | +| memory_limit_number | string | Ограничение на количество возвращаемых элементов памяти. Если не указано, по умолчанию 6 | Нет | +| memos_key | string | Авторизационный ключ для MemOS облачного сервиса | Да | +| memos_url | string | URL адрес MemOS облачного сервиса | Да | +| query | string | Ввод пользователя | Да | +| user_id | string | Уникальный идентификатор пользователя, связанный с запрашиваемой памятью | Да | + +* add_memory接口 + +| 参数名称 | 参数类型 | 描述 | 是否必填 | +| --- | --- | --- | --- | +| conversation_id | string | Уникальный идентификатор разговора | Да | +| memos_key | string | Авторизационный ключ для MemOS облачного сервиса | Да | +| memos_url | string | URL адрес MemOS облачного сервиса | Да | +| messages | Array | Массив объектов сообщений | Да | +| user_id | string | Уникальный идентификатор пользователя, связанный с запрашиваемой памятью | Да | + +### 1.3 Примеры Вызова Agent + +* **Примеры Персонажа Разработчика Agent и Логики Ответов** +``` +Вы — робот для вопросов и ответов, который каждый раз читает память и интересы пользователя и отвечает с очень ясной логикой, чтобы завоевать симпатию пользователя. + +## 工作流内容 +# 1. 访问{search_memory}检索数据资料 + Каждый раз после того, как пользователь говорит, сначала вызывается функция поиска в памяти MemOS — плагин {search_memory}, вводя информацию: + Запишите имя пользователя как user_id. Если это первый визит, установите user_id как случайно сгенерированную 16-значную строку UUID. + Использовать содержание речи пользователя в качестве query +# 2. Обработка {search_memory} Выходных Данных: + Получить данные, и если в них есть поле memory_detail_list, независимо от того, пуст ли список memory_detail_list, сразу вывести список memory_detail_list в формате json; если возвращаемое сообщение не равно ok, то вывести "Ошибка поиска плагина". +# 3. Ответить на вопросы пользователя, используя найденный memory_detail_list + Извлечь значения поля memory_value из каждого элемента memory_detail_list и соединить все строки с помощью "\n" в качестве контекста для ответа на вопрос пользователя; большой модель может отвечать на запрос пользователя, основываясь на информации из контекста; если контекстная информация пустая строка, большая модель может просто ответить на запрос пользователя. + Затем записать содержание ответа большой модели в answer. +# 4. Доступ к {add_memory} для хранения данных + Вызвать функцию add_memory, чтобы сохранить вопрос пользователя и соответствующий ответ, вводя информацию: + chat_time: Вызвать {current_time} для получения текущего времени, отформатировать временную метку в формате "%I:%M %p on %d %B, %Y UTC" + conversation_id: Записать текущее время chat_time с точностью до минут, строка времени будет использоваться как conversation_id + user_id: Записать имя пользователя как user_id + messages: Записать введенный пользователем query и все полученные ответы answer как content в role и assistant соответственно, chat_time использовать только что полученное значение chat_time, организовать в одну запись messages: + [ + {"role": "user", "content": query, "chat_time": chat_time}, + {"role": "assistant", "content": answer, "chat_time": chat_time} + ] + Получить обратную связь от плагина {add_memory}, если поле success в data равно True, то это успех, *не нужно уведомлять пользователя*; если возвращаемое поле не равно True, то сообщить пользователю, что доступ к add_memory не удался. + +## Требования +Каждый раз при доступе к {search_memory} и {search_memory} необходимо передавать два фиксированных параметра: +memos_url = "https://memos.memtensor.cn/api/openmem/v1" +memos_key = "Token mpg-XXXXXXXXXXXXXXXXXXXXXXXXXXX" + +Ваш персонаж — это мудрый и заботливый помощник по памяти, его зовут Сяо Чжи. +Если все плагины работают успешно, в ответах большой модели не нужно уведомлять пользователя о том, что все прошло успешно. +Только при первом диалоге с пользователем сгенерируйте user_id с помощью UUID, этот user_id будет использоваться в дальнейшем. +``` + +[Пример агента](https://www.coze.cn/s/85NOIg062vQ) +![Рабочий процесс агента](https://cdn.memtensor.com.cn/img/coze_workflow_compressed.png) diff --git a/content/ru/usecase/writting_assistant.md b/content/ru/usecase/writting_assistant.md new file mode 100644 index 00000000..ea5cad7f --- /dev/null +++ b/content/ru/usecase/writting_assistant.md @@ -0,0 +1,282 @@ +--- +title: Памятный Помощник По Письму Более Удобен +desc: С помощью MemOS ваш продукт будет автоматически запоминать привычки и контекст письма пользователей, делая процесс творчества более последовательным и менее беспокойным. +--- + +## 1. Обзор + +В продуктах типа помощника по письму пользователи часто хотят, чтобы помощник мог **запоминать свой стиль и привычки письма**, а не начинать с нуля каждый раз. + +* **Стиль письма** + «Когда я прошу написать резюме, тон должен быть более легким» + +* **Часто используемая информация** + «Запомни, что я отвечаю за маркетинг в компании XX» + +* **Предпочтения в письме** + «В будущем в начале писем всегда добавляй 'Уважаемый клиент'» + +* **Продолжение контекста** + «Оптимизируй вчерашнее резюме, добавь раздел с бюджетом» + + +Если нет памяти, эта информация будет потеряна после завершения разговора. Пользователи вынуждены постоянно напоминать помощнику, что делает опыт разрозненным и непрофессиональным. + + +### 1.1 Почему Не Использовать Традиционный RAG? + +В сценарии помощника по письму RAG не подходит. + +| Традиционный RAG | MemOS | +| --- | --- | +| Зависит от статической базы знаний, требует постоянного ручного обслуживания документов | Информация, возникающая в диалоге, может быть записана напрямую, без дополнительного обслуживания | +| Результаты поиска обычно представляют собой общие фрагменты знаний | Можно хранить и извлекать персонализированные стили, тон, часто используемые выражения | +| Лучше подходит для сценариев типа "корпоративные документы/энциклопедические знания" | Лучше подходит для "постоянной итерации, персонализированного" помощника по написанию | + + +### 1.2 Почему Не Создавать Свой Собственный Решение? + +Конечно, вы также можете попробовать сохранить предпочтения пользователей и контекст в базе данных, но это приведет к нескольким проблемам: + +* **Сложная логика хранения и извлечения**: необходимо различать основной текст, предпочтения и пользовательские профили, а также разрабатывать стратегии извлечения. + +* **Проблемы с интеграцией с большими моделями**: сохранить данные — это только первый шаг, нужно также «вставить» соответствующую информацию в Prompt перед вызовом большой модели. + +* **Плохая масштабируемость**: с увеличением потребностей пользователей (стиль письма, часто используемые фразы, связь контекста) код быстро разрастается. + + +### 1.3 Почему Использовать MemOS? + +При выборе можно наглядно сравнить три варианта: + +| Решение | Особенности | Ограничения | Преимущества MemOS | +| --- | --- | --- | --- | +| **Традиционный RAG** | Путем векторного поиска документов базы знаний, вставляется в Prompt | Требует ручного обслуживания статических документов; не подходит для персонализированных привычек написания | Автоматически захватывает стиль и предпочтения пользователя, раскрытые в диалоге | +| **Собственное решение для хранения** | Создание таблиц/кэша, сохранение предпочтений и контента | Логика сложная: необходимо различать основной текст/предпочтения/изображения; также нужно вручную составлять Prompt; трудности с расширением | MemOS упаковывает хранение + поиск + инъекцию Prompt, снижая нагрузку на разработку | +| **MemOS** | Достаточно двух интерфейсов: `addMessage` для записи, `searchMemory` для поиска | —— | Поддерживает долгосрочное отслеживание стиля написания, повторное использование часто используемой информации; готово к использованию, легко расширяемо | + + +### 1.4 Что Будет Показано В Этом Примере? + +Этот пример демонстрирует, как с помощью облачного сервиса MemOS быстро реализовать помощника по письму, который «запоминает пользователей». + +В этом Demo пользователи могут: + +* Указать предпочтения: «Когда я прошу написать резюме, тон должен быть более легким» + +* Повторно использовать контекст: «Запомни, что я отвечаю за маркетинг в компании XX» + +* Итеративные задачи: «Оптимизируй вчерашнее резюме, добавь раздел с бюджетом» + + +С MemOS помощник по письму может: + +1. **Сохранять стиль**: поддерживать требуемый пользователем тон и формат. + +2. **Повторно использовать информацию**: автоматически включать часто используемую пользователем информацию о контексте. + +3. **Быстро итеративно**: продолжать редактирование на основе существующего контента, а не начинать с нуля. + + +При запуске этого сценария разработчики увидят в консоли: + +* Запросы/ответы при каждом вызове `addMessage` и `searchMemory` + +* Извлеченные стили письма, информацию о контексте и другие воспоминания + +* Окончательный ответ, сгенерированный моделью (если большая модель не подключена, будет сообщение [Не подключена большая модель]) + + +##  2. Пример + +### 2.1 Подготовка Окружения + +Используйте pip для установки необходимых зависимостей. + +```shell +pip install MemoryOS -U +``` + + +### 2.2 Полный Код + +```python +import os +import uuid +from openai import OpenAI +from memos.api.client import MemOSClient + +os.environ["MEMOS_API_KEY"] = "mpg-xx" # Получите MemOS_API_KEY из консоли облачного сервиса +os.environ["OPENAI_API_KEY"] = "sk-xx" # Замените на свой собственный API_KEY + +conversation_counter = 0 + +def generate_conversation_id(): + global conversation_counter + conversation_counter += 1 + return f"conversation_{conversation_counter:03d}" + +class WritingAssistant: + """AI помощник по написанию, помогает пользователям в написании, обладает памятью""" + + def __init__(self): + self.memos_client = MemOSClient(api_key=os.getenv("MEMOS_API_KEY")) + self.openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) + + def search_memory(self, query, user_id, conversation_id): + """Запросить соответствующую память""" + response = self.memos_client.search_memory(query, user_id, conversation_id) + + return [memory_detail.memory_value for memory_detail in response.data.memory_detail_list] + + def build_system_prompt(self, memories): + """Создать системный подсказку с форматированной памятью""" + base_prompt = """ + Вы профессиональный помощник по написанию, способный запоминать стиль и предпочтения пользователя. + Вы можете использовать память диалога, чтобы предоставить более персонализированные ответы. + Пожалуйста, воспользуйтесь этими воспоминаниями, чтобы понять контекст, предпочтения и прошлые взаимодействия пользователя. + Если воспоминания предоставлены, пожалуйста, естественно упоминайте их в соответствующих моментах, но не упоминайте явно о наличии функции памяти. + """ + + if memories: + # Отформатируйте воспоминания в виде нумерованного списка + formatted_memories = "## Воспоминания:\n" + for i, memory in enumerate(memories, 1): + formatted_memories += f"{i}. {memory}\n" + + return f"{base_prompt}\n\n{formatted_memories}" + else: + return base_prompt + + + def add_message(self, messages, user_id, conversation_id): + """Добавить сообщение""" + self.memos_client.add_message(messages, user_id, conversation_id) + + def get_message(self, user_id, conversation_id): + """Получить сообщение""" + response = self.memos_client.get_message(user_id, conversation_id) + + return response.data.message_detail_list + + def chat(self, query, user_id, conversation_id): + """Основная функция чата для обработки диалогов с интеграцией воспоминаний""" + # 1. Найти соответствующие воспоминания + memories = self.search_memory(query, user_id, conversation_id) + + # Сформировать системное сообщение с воспоминаниями + system_prompt = self.build_system_prompt(memories) + + # 2. Использовать OpenAI для генерации ответа + response = self.openai_client.chat.completions.create( + model="gpt-4o", + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": query} + ] + ) + answer = response.choices[0].message.content + + # 3. Сохранить диалог в воспоминаниях + messages = [ + {"role": "user", "content": query}, + {"role": "assistant", "content": answer} + ] + self.memos_client.add_message(messages, user_id, conversation_id) + + return answer + +ai_assistant = WritingAssistant() +user_id = "memos_writing_user_123" + +def demo_questions(): + return [ + "Помоги мне написать уведомление о командном обеде", + "Помоги мне написать письмо клиенту, в котором будет подведен итог новых функций нашего финансового приложения, которое скоро будет запущено", + ] + +def pre_configured_conversations(): + """Вернуть преднастроенные пары диалогов""" + return [ + { + "user": "Я работаю в маркетинговом отделе интернет-компании, тон письма должен быть легким, в начале добавьте 'Дорогой XX'" + }, + { + "user": "Когда я пишу резюме, я обычно сначала перечисляю три основных момента" + } + ] + +def execute_pre_conversations(): + """Выполнение предустановленного диалога""" + conversations = pre_configured_conversations() + conversation_id = generate_conversation_id() + + print(f"\n🔄 Выполняется предустановленный диалог (conversation_id={conversation_id})...") + print("=" * 60) + + for i, conv in enumerate(conversations, 1): + print(f"\n💬 Диалог {i}") + print(f"👤 Пользователь: {conv['user']}") + + # Выполнение диалога + answer = ai_assistant.chat(conv['user'], user_id, conversation_id) + print(f"🤖 Ассистент: {answer}") + print("-" * 40) + + print("\n✅ Выполнение предустановленного диалога завершено!") + print("=" * 60) + +def main(): + print("📝 Добро пожаловать к просмотру примеров использования MemOS в качестве помощника по написанию!") + print("💡 С помощью MemOS ваш помощник по написанию лучше понимает ваш стиль и предпочтения! ✍️ \n") + + # Спросить пользователя, хочет ли он сначала выполнить предустановленный диалог + while True: + pre_chat = input("🤔 Вы хотите сначала выполнить предустановленный диалог? Ожидается расход 2 вызовов add и 2 вызовов search, выполнять? (y/n): ").strip().lower() + + if pre_chat in ['y', 'yes', '是', 'Y']: + execute_pre_conversations() + break + elif pre_chat in ['n', 'no', '否', 'N']: + print("📝 Начинаем новый диалог помощника по написанию...") + break + else: + print("⚠️ Пожалуйста, введите 'y' для 'да' или 'n' для 'нет'") + + print("\n⚡️ В следующем вашем вопросе будет развернута новая сессия (новый conversation id). MemOS будет автоматически вспоминать вашу историю действий между сессиями, чтобы предоставить вам непрерывное, персонализированное обслуживание.") + print("\n🎯 Вот несколько примеров вопросов, вы можете продолжить диалог с помощником по написанию:") + for i, question in enumerate(demo_questions(), 1): + print(f" {i}. {question}") + + while True: + user_query = input("\n🤔 Пожалуйста, введите ваши требования к написанию (или введите 'exit' для выхода): ").strip() + + if user_query.lower() in ['quit', 'exit', 'q', '退出']: + print("👋 Спасибо за использование помощника по написанию, желаем вам приятного написания!") + break + + if not user_query: + continue + + print("🤖 Создание...") + conversation_id = generate_conversation_id() + answer = ai_assistant.chat(user_query, user_id, conversation_id) + print(f"\n💬 conversation_id: {conversation_id}\n💡 [助手]: {answer}\n") + print("-" * 60) + + +if __name__ == "__main__": + main() +``` + +### 2.3 Описание Кода + +1.  Установите ваш MemOS API ключ и Open AI ключ в переменных окружения + +2.  Создайте экземпляр `WritingAssistant` + +3.  Выберите, выполнять ли диалог с предустановленными значениями, это потребует 2 вызова add и 2 вызова search + +4.  Используйте функцию `main()` для взаимодействия с помощником через цикл диалога + +5.  Помощник вызовет chat, сначала выполнит search для извлечения памяти, затем вызовет OpenAI для диалога, и в конце выполнит add для сохранения памяти.