Сохранение сеанса чата позволяет вашему .NET приложению переживать перезапуски, обеспечивает резервную копию беседы и даёт возможность перемещать сеанс между машинами. В этом руководстве мы пройдемся по Persist and Resume a Chat Session in C# с использованием Aspose.LLM, охватывая, когда использовать этот шаблон, как сохранять и загружать сеансы, какие данные сохраняются, вопросы переносимости и лучшие практики безопасности.
Почему сохранять и возобновлять сеанс чата?
Разработчики часто создают интерактивных помощников, ботов поддержки или длительные рабочие процессы анализа данных. Во многих сценариях контекст чата должен сохраняться после завершения работы отдельного процесса:
- Настольный инструмент поддержки, где пользователи ожидают, что их предыдущие запросы останутся доступными после закрытия приложения.
- Серверная автоматизация, охватывающая несколько шагов и может быть перезапущена из‑за обслуживания.
- Требования аудита или соответствия, требующие снимка всей беседы.
- Перенос сеанса устранения неполадок с ноутбука разработчика на сервер производства.
Сохраняя сеанс в JSON‑файл, вы фиксируете полную историю сообщений и внутренний KV‑кеш, необходимый для точного продолжения, что делает приведённые выше сценарии использования простыми для реализации.
Начало работы с Aspose.LLM
Сначала добавьте пакет Aspose.LLM в ваш проект:
Install-Package Aspose.LLM
Вы можете найти более подробную информацию о продукте на странице продукта Aspose.LLM .NET. Для SDK требуется действительная лицензия, поэтому убедитесь, что у вас готов временный или постоянный файл лицензии.
Требования
- Установите пакет NuGet Aspose.LLM.
- Примените лицензию Aspose.LLM, используя
Aspose.LLM.License. - Создайте экземпляр
AsposeLLMApi(например, сQwen25Preset).
Когда использовать этот шаблон
Этот шаблон особенно полезен, когда вам необходимо, чтобы диалог сохранялся за пределами текущего процесса, или когда вы хотите надёжный снимок для резервного копирования или миграции. Типичные сценарии включают:
- Настольные или серверные приложения, где пользователи ожидают, что чат будет сохраняться между запусками.
- Длительные рабочие процессы, которым необходимо, чтобы разговор продолжался после завершения процесса.
- Цели резервного копирования и аудита путем создания снимка активного разговора.
- Перенос состояния сеанса между машинами с одинаковой версией SDK и предустановкой.
Требования
Прежде чем вы сможете сохранить или восстановить сеанс, убедитесь, что выполнены следующие условия:
- Aspose.LLM NuGet package – установлен через команду, показанную ранее.
- License – создайте объект
Aspose.LLM.Licenseи вызовитеSetLicenseс вашим файлом.lic. - API instance – создайте экземпляр
AsposeLLMApiс нужным набором параметров (например,new Qwen25Preset()).
Эти шаги демонстрируются в полном примере позже в статье.
Сохранить сеанс
SDK предлагает три удобных способа сохранить чат‑сеанс. Следуйте инструкциям ниже, а затем посмотрите пример кода.
- Вызовите
SaveChatSessionс явным путем к файлу, если вам нужен файл в известном месте. - Опустите путь, чтобы SDK записал
<sessionId>.jsonрядом с исполняемым файлом. - Создайте временный путь с помощью
Path.Combine, убедитесь, что каталог существует, и сохраните туда для изолированных или песочничных сценариев.
Пример кода – Сохранение сеанса
Следующий пример демонстрирует все три подхода:
api.SaveChatSession(sessionId, "session-42.json");
api.SaveChatSession(sessionId); // writes <sessionId>.json next to the executable
string path = Path.Combine(Path.GetTempPath(), "chats", $"{sessionId}.json");
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
api.SaveChatSession(sessionId, path);
api.SaveChatSession(sessionId, "session-42.json") записывает JSON‑файл в указанное место.
Если вызвать SaveChatSession без указания пути, SDK создаёт файл, имя которого соответствует идентификатору сеанса, в текущем рабочем каталоге.
Когда требуется определённое или временное расположение, объедините Path.GetTempPath со своей структурой папок и создайте каталог перед сохранением.
Примечание: Эти фрагменты воспроизведены из официальной документации Aspose и не были выполнены в песочнице. Проверьте их в своей среде перед использованием в продакшене.
Восстановление сеанса
Загрузка ранее сохранённого сеанса столь же проста. API читает файл JSON, воссоздаёт внутреннее состояние и возвращает идентификатор сеанса, чтобы вы могли продолжать обмен сообщениями без необходимости вручную передавать ID снова.
- Вызовите
LoadChatSessionс путем к файлу JSON. - Сохраните возвращённый
sessionId. - Используйте
SendMessageToSessionAsyncс восстановленным идентификатором, чтобы продолжить разговор.
Пример кода – Восстановление сеанса
string sessionId = await api.LoadChatSession("session-42.json");
string reply = await api.SendMessageToSessionAsync(sessionId, "What did we discuss?");
LoadChatSession читает файл и возвращает восстановленный идентификатор сеанса.
Восстановленный сеанс автоматически устанавливается как активный, позволяя сразу вызывать SendMessageToSessionAsync.
Примечание: Эти фрагменты воспроизведены из официальной документации Aspose и не были выполнены в песочнице. Проверьте их в своей среде перед использованием в продакшене.
Полный пример — Сохранить, перезапустить, возобновить
Ниже представлена полная демонстрация от начала до конца. Первый блок запускает чат, отправляет несколько сообщений и сохраняет сеанс. Второй блок имитирует новый процесс, который загружает сохранённый файл и продолжает разговор.
Пример кода – сквозной рабочий процесс
using Aspose.LLM;
using Aspose.LLM.Abstractions.Parameters.Presets;
// ---------- First run: save ----------
{
var license = new Aspose.LLM.License();
license.SetLicense("Aspose.LLM.lic");
using var api = AsposeLLMApi.Create(new Qwen25Preset());
string sessionId = await api.StartNewChatAsync(sessionId: "support-ticket-1234");
await api.SendMessageToSessionAsync(sessionId,
"Customer reports that the migration from v25 to v26 broke their startup script.");
await api.SendMessageToSessionAsync(sessionId,
"Their environment: Windows Server 2022, .NET 8, CUDA 12.6.");
await api.SendMessageToSessionAsync(sessionId,
"What questions should I ask them next?");
api.SaveChatSession(sessionId, "support-ticket-1234.json");
Console.WriteLine("Session saved.");
}
// ---------- Second run: resume ----------
{
var license = new Aspose.LLM.License();
license.SetLicense("Aspose.LLM.lic");
using var api = AsposeLLMApi.Create(new Qwen25Preset());
string sessionId = await api.LoadChatSession("support-ticket-1234.json");
Console.WriteLine($"Resumed session: {sessionId}");
string reply = await api.SendMessageToSessionAsync(sessionId,
"They replied that they use a custom build step that copies native DLLs. How should I proceed?");
Console.WriteLine(reply);
}
Первый блок создает лицензию, инициализирует API с Qwen25Preset, запускает новый чат с именем support-ticket-1234, отправляет три сообщения для построения контекста и, наконец, записывает сессию в support-ticket-1234.json. Второй блок повторно создает лицензию и API, загружает JSON‑файл и продолжает диалог, демонстрируя, что модель сохраняет предыдущие сообщения.
Примечание: Эти фрагменты воспроизведены из официальной документации Aspose и не были выполнены в песочнице. Проверьте их в своей среде перед использованием в продакшене.
Что сохраняется?
SaveChatSession создаёт JSON‑документ с тремя основными разделами:
- Идентификатор сеанса – уникальный ID, который вы указали при запуске чата.
- История сообщений – упорядоченный список всех сообщений пользователя и помощника, включая роль, содержание и любые метаданные медиа.
- Метаданные кэша KV – внутренние позиции и размеры кэша «ключ‑значение» для каждого сообщения, позволяющие модели продолжить работу точно с того места, где она остановилась.
Поскольку данные кэша включены, восстановленная сессия может продолжать генерацию без повторного вычисления предыдущего внимания, делая операцию возобновления быстрой и детерминированной.
Ограничения переносимости
Хотя JSON‑файл содержит всё необходимое для идеального продолжения, он переносим только при соблюдении определённых условий:
- Same SDK Major Version – формат файла может изменяться между мажорными выпусками, поэтому обе стороны должны использовать одну и ту же мажорную версию Aspose.LLM.
- Identical Model File – базовая модель Hugging Face (включая квантизацию) должна точно совпадать; иначе кеш KV становится несовместимым.
- Matching BinaryManagerParameters.ReleaseTag – версия среды выполнения llama.cpp, используемая для загрузки модели, должна быть одинаковой, иначе различаются низкоуровневые макеты тензоров.
Если любые из этих ограничений нарушены, вы можете увидеть ошибки, такие как InvalidOperationException, или получить искажённый вывод.
Известный нюанс при загрузке
Когда вы вызываете LoadChatSession, SDK восстанавливает разговор, но применяет значения по умолчанию ContextParameters, ChatParameters и SamplerParameters. Любые пользовательские настройки (например, temperature, max tokens, system prompts), которые вы использовали в оригинальной сессии, не восстанавливаются автоматически. Чтобы сохранить точное поведение генерации, повторно примените свои пользовательские параметры после загрузки или воспроизведите разговор в новой сессии с нужными настройками.
Общие ошибки
Ниже приведён быстрый чек‑лист типичных проблем, с которыми вы можете столкнуться при загрузке сеанса:
- FileNotFoundException – Проверьте путь к файлу; относительные пути разрешаются относительно текущего рабочего каталога.
- InvalidOperationException on load – Указывает на несовместимую версию SDK или повреждённый JSON‑файл.
- Garbled output after load – Обычно вызывается несоответствующим файлом модели или ReleaseTag. Убедитесь, что на машине загрузки присутствует точно такой же бинарный файл модели.
Корректная обработка этих исключений и запись подробных диагностических данных сделают ваше приложение более надёжным.
Безопасность
Сохранённый файл JSON содержит plain‑text копии каждого сообщения пользователя и помощника. Хранение его в незащищённом месте может раскрыть конфиденциальные данные. Рассмотрите следующие меры по смягчению:
- Шифруйте файл перед записью на диск (например, Windows DPAPI, Azure Key Vault или кроссплатформенная библиотека, такая как libsodium).
- Ограничьте разрешения файловой системы так, чтобы только учетная запись службы, запускающая приложение, могла читать/записывать файл.
- Если файл должен передаваться по сети, используйте TLS‑шифрованные каналы и рассмотрите возможность подписания файла для обнаружения подделки.
Что дальше
Теперь, когда вы можете сохранять и возобновлять чаты, вы можете изучить связанные возможности:
- Сценарии многократного диалога – поддерживайте более длительные диалоги в течение множества взаимодействий.
- Настройка пользовательского пресета – адаптируйте пресет модели к вашему домену перед сохранением.
- Справочник по полной сохранности сеанса – ознакомьтесь со справочником API для более глубокого понимания семантики
SaveChatSessionи связанных метаданных.
Выбор правильного подхода
В статье представлены три способа сохранения сеанса и простой метод загрузки. Выберите подход, соответствующий вашему сценарию развертывания.
- Explicit path – лучше всего, когда файл должен находиться в известном месте, например, в пользовательской папке или на общем сетевом диске.
- Default filename – удобно для быстрых прототипов или когда сессия находится рядом с исполняемым файлом.
- Temporary path with directory creation – идеально для изолированных сред, CI‑конвейеров или когда вы хотите, чтобы ОС управляла очисткой.
Все подходы используют один и тот же базовый API; они различаются только тем, как вы управляете файловой системой.
Получить бесплатную лицензию
Если у вас еще нет постоянной лицензии, вы можете получить временную оценочную лицензию со страницы Aspose temporary license page.
Бесплатные дополнительные ресурсы
Заключение
Сохранение чат‑сессии с Aspose.LLM обеспечивает долговечность, возможность аудита и гибкость перемещения разговоров между процессами или машинами. Вы узнали, когда применять этот шаблон, как сохранить сессию тремя разными способами, как её восстановить, что содержит JSON‑файл, а также какие вопросы совместимости и безопасности следует учитывать. Имея полный пример, вы теперь можете интегрировать постоянное хранение сессий в любое .NET‑решение для чата.
Часто задаваемые вопросы
Когда сохранение сеанса чата полезно?
Сохранение полезно для настольных или серверных приложений, которым необходимо сохранять состояние диалога между запусками, для длительных рабочих процессов, требований к аудиту или резервному копированию, а также для переноса сеансов между машинами с одной и той же версией SDK.Как указать пользовательский путь к файлу при сохранении сеанса?
Вызовитеapi.SaveChatSession(sessionId, "myfolder\myfile.json");или сформируйте путь с помощьюPath.Combineи убедитесь, что каталог существует перед сохранением.Что возвращает LoadChatSession?
Он возвращает идентификатор восстановленного сеанса, позволяя продолжать отправлять сообщения без необходимости повторно указывать ID.Можно ли переместить сохранённый файл сеанса на другую машину?
Да, при условии, что целевая машина использует ту же основную версию SDK, идентичный файл модели и совпадающий ReleaseTag llama.cpp.Безопасен ли сохранённый JSON‑файл?
Файл хранит данные диалога в виде обычного текста, поэтому его следует шифровать перед сохранением в ненадёжных местах.Почему мои пользовательские настройки сэмплера или контекста не восстанавливаются после загрузки?
LoadChatSession применяет параметры по умолчанию; повторно задайте любые пользовательские настройки после загрузки или воспроизведите историю в новом сеансе.
