チャット セッションを永続化すると、.NET アプリケーションが再起動後も存続し、会話のバックアップが提供され、セッションを別のマシンに移動できるようになります。このガイドでは、Aspose.LLM を使用して C# でチャット セッションを永続化および再開する 方法を解説し、パターンを使用すべきタイミング、セッションの保存と読み込み方法、保存されるデータ、ポータビリティ上の考慮点、そしてセキュリティのベストプラクティスについて説明します。

なぜチャットセッションを永続化し、再開する必要があるのか?

開発者は、インタラクティブなアシスタント、サポートボット、または長時間実行されるデータ分析ワークフローを構築することがよくあります。多くのシナリオでは、チャットコンテキストが単一プロセスの寿命を超えて存続する必要があります:

  • ユーザーがアプリを閉じた後でも、以前の問い合わせが利用可能であることを期待するデスクトップサポートツール。
  • 複数のステップにまたがり、メンテナンスのために再起動される可能性があるサーバー側自動化。
  • 会話全体のスナップショットを要求する監査またはコンプライアンス要件。
  • 開発者のラップトップから本番サーバーへトラブルシューティングセッションを移行すること。

セッションを JSON ファイルに永続化することで、完全なメッセージ履歴と正確な継続に必要な内部 KV キャッシュを取得でき、上記のユースケースを簡単に実装できます。

Aspose.LLM の開始

まず、プロジェクトに Aspose.LLM パッケージを追加します:

Install-Package Aspose.LLM

製品の詳細は Aspose.LLM .NET 製品ページ で確認できます。SDK には有効なライセンスが必要ですので、テンポラリまたは永続的なライセンス ファイルを用意してください。

前提条件

  • Aspose.LLM NuGet パッケージをインストールします。
  • Aspose.LLM.License を使用して Aspose.LLM ライセンスを適用します。
  • AsposeLLMApi インスタンスを作成します(例として Qwen25Preset を使用)。

このパターンを使用すべき時

このパターンは、会話を現在のプロセスを超えて持続させる必要がある場合や、バックアップや移行のために信頼できるスナップショットが必要な場合に特に有効です。典型的なシナリオは次のとおりです:

  • ユーザーがチャットの持続性を期待するデスクトップまたはサーバーアプリケーション。
  • プロセスの寿命を超えて会話が続く必要がある長時間実行ワークフロー。
  • アクティブな会話をスナップショットしてバックアップおよび監査目的に使用する。
  • 同じ SDK バージョンとプリセットを持つマシン間でセッション状態を移行する。

前提条件

セッションを保存または復元できるようにするには、以下が整っていることを確認してください:

  1. Aspose.LLM NuGet package – 以前示したコマンドでインストールします。
  2. LicenseAspose.LLM.License オブジェクトを作成し、.lic ファイルを使用して SetLicense を呼び出します。
  3. API instance – 目的のプリセット(例: new Qwen25Preset())で AsposeLLMApi をインスタンス化します。

これらの手順は、記事の後半にある完全な例で示されています。

セッションの保存

SDK はチャット セッションを永続化するための 3 つの便利な方法を提供します。以下の手順に従い、その後コードサンプルをご覧ください。

  1. 既知の場所にファイルが必要な場合は、明示的なファイル パスを指定して SaveChatSession を呼び出します。
  2. パスを省略すると、SDK が実行ファイルの横に <sessionId>.json を書き込みます。
  3. Path.Combine で一時パスを作成し、ディレクトリが存在することを確認してから、分離されたまたはサンドボックス化されたシナリオで保存します。

コードサンプル – セッションの保存

次の例は、3 つのすべてのアプローチを示しています:

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 は現在の作業ディレクトリにセッション ID にちなんだ名前のファイルを作成します。
*決定的または一時的な場所が必要な場合は、Path.GetTempPath と独自のフォルダー構造を組み合わせ、保存する前にディレクトリを作成してください。

Note: これらのスニペットは公式の Aspose ドキュメントから転載されたもので、サンドボックスで実行されていません。実稼働環境で使用する前に、必ずご自身の環境で確認してください。

Restore a Session

以前に保存したセッションを復元するのも同様に簡単です。APIはJSONファイルを読み取り、内部状態を再作成し、セッション識別子を返すので、IDを手動で渡すことなくメッセージングを続行できます。

  1. LoadChatSession を JSON ファイルへのパスで呼び出します。
  2. 返された sessionId を保存します。
  3. 復元した ID を使用して SendMessageToSessionAsync を呼び出し、会話を続けます。

コードサンプル – セッションの復元

string sessionId = await api.LoadChatSession("session-42.json");
string reply = await api.SendMessageToSessionAsync(sessionId, "What did we discuss?");

LoadChatSession はファイルを読み取り、復元されたセッション ID を返します。 復元されたセッションは自動的にアクティブなものとして設定され、SendMessageToSessionAsync をすぐに呼び出すことができます。

Note: これらのスニペットは公式の Aspose ドキュメントから転載されたもので、サンドボックスで実行されていません。 本番環境で使用する前に、環境で検証してください。

完全な例 — 保存、再起動、再開

以下は、完全なエンドツーエンドのデモです。最初のブロックはチャットを開始し、いくつかのメッセージを送信し、セッションを保存します。2番目のブロックは、保存されたファイルをロードして会話を続行する新しいプロセスをシミュレートします。

コードサンプル – エンドツーエンド ワークフロー

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);
}

最初のブロックはライセンスを作成し、Qwen25Preset で API をインスタンス化し、support-ticket-1234 という名前の新しいチャットを開始し、コンテキストを構築するために 3 つのメッセージを送信し、最後にセッションを support-ticket-1234.json に書き込みます。2 番目のブロックはライセンスと API を再作成し、JSON ファイルをロードして対話を続行し、モデルが以前のメッセージを保持していることを示します。

Note: これらのスニペットは公式 Aspose ドキュメントから再現されたもので、サンドボックスで実行されていません。 本番環境で使用する前に、環境で検証してください。

保存されるものは何ですか?

SaveChatSession は、3つの重要なセクションを含む JSON ドキュメントを生成します:

  1. Session Identifier – チャット開始時に提供したユニークなIDです。
  2. Message History – 役割、内容、およびメディアメタデータを含む、すべてのユーザーとアシスタントのメッセージの順序付けされたリストです。
  3. KV Cache Metadata – 各メッセージのキー‑バリューキャッシュの内部位置とサイズで、モデルが中断した箇所から正確に再開できるようにします。

キャッシュデータが含まれているため、復元されたセッションは以前の注意を再計算せずに生成を続行でき、再開操作が高速かつ決定的になります。

移植性の制約

JSON ファイルには完全な継続に必要なすべてが含まれていますが、特定の条件下でのみ移植可能です:

  • Same SDK Major Version – ファイル形式はメジャーリリース間で変更される可能性があるため、両方の側で同じメジャーバージョンの Aspose.LLM を使用する必要があります。
  • Identical Model File – 基礎となる Hugging Face モデル(量子化を含む)が完全に一致している必要があります。そうでない場合、KV キャッシュが互換性を失います。
  • Matching BinaryManagerParameters.ReleaseTag – モデルをロードするために使用される llama.cpp ランタイムのバージョンが同じでなければなりません。そうでないと、低レベルのテンソルレイアウトが異なります。

これらの制約が違反されると、InvalidOperationException のようなエラーや文字化けが発生する可能性があります。

既知のロード時のニュアンス

LoadChatSession を呼び出すと、SDK は会話を再構築しますが、デフォルトContextParametersChatParametersSamplerParameters を適用します。元のセッション中に使用したカスタム設定(例: temperature、max tokens、system prompts)は 自動的に 復元されません。正確な生成動作を維持するには、ロード後にカスタムパラメータを再適用するか、希望する設定で新しいセッションで会話を再生してください。

共通エラー

以下は、セッションの読み込み中に遭遇する可能性のある一般的な問題の簡単なチェックリストです:

  • FileNotFoundException – ファイルパスを確認してください。相対パスは現在の作業ディレクトリに対して解決されます。
  • InvalidOperationException on load – 互換性のない SDK バージョンまたは破損した JSON ファイルが原因であることを示します。
  • Garbled output after load – 通常、モデルファイルや ReleaseTag の不一致が原因です。ロードするマシンに同一のモデルバイナリが存在することを確認してください。

これらの例外を適切に処理し、詳細な診断情報をログに記録することで、アプリケーションの堅牢性が向上します。

セキュリティ

永続化された JSON ファイルには、すべてのユーザーおよびアシスタントメッセージの プレーンテキスト のコピーが含まれます。保護されていない場所に保存すると、機密データが漏洩する可能性があります。以下の緩和策を検討してください:

  • ファイルをディスクに書き込む前に暗号化します(例: Windows DPAPI、Azure Key Vault、または libsodium のようなクロスプラットフォームライブラリ)。
  • ファイルシステムの権限を制限し、アプリケーションを実行しているサービス アカウントだけがファイルを読み書きできるようにします。
  • ファイルをネットワーク越しに転送する必要がある場合は、TLS 暗号化チャネルを使用し、改ざん検出のためにファイルに署名することも検討してください。

次のステップ

チャットを永続化して再開できるようになったので、関連する機能を検討してみてください:

  • マルチターンチャットのユースケース – 多くのやり取りにわたって長い対話を維持します。
  • カスタムプリセット構成 – 永続化する前にモデルのプリセットをドメインに合わせて調整します。
  • 完全なセッション永続性リファレンスSaveChatSession と関連メタデータに関する深いセマンティクスを確認するために API リファレンスを参照してください。

適切なアプローチの選択

この記事では、セッションを保存する3つの方法とシンプルなロード方法を紹介しました。デプロイシナリオに合ったアプローチを選択してください:

  • Explicit path – ファイルを既知の場所(ユーザー固有のフォルダーや共有ネットワークドライブなど)に配置する必要がある場合に最適です。
  • Default filename – クイックプロトタイプや、セッションが実行ファイルと同じ場所にある場合に便利です。
  • Temporary path with directory creation – サンドボックス環境、CIパイプライン、または OS にクリーンアップを任せたい場合に理想的です。

すべてのアプローチは同じ基盤となる API を使用しますが、ファイルシステムの管理方法が異なるだけです。

無料ライセンスを取得する

まだ永続的なライセンスをお持ちでない場合は、Aspose の一時ライセンスページから一時評価ライセンスを取得できます。

無料の追加リソース

結論

Aspose.LLM を使用してチャット セッションを永続化すると、耐久性、監査可能性、およびプロセスやマシン間で会話を移動させる柔軟性が得られます。パターンを適用すべきタイミング、3 つの異なる方法でセッションを保存する方法、復元方法、JSON ファイルに含まれる内容、そして考慮すべき互換性とセキュリティの注意点を学びました。完全なサンプルを手に入れたので、あらゆる .NET チャット ソリューションにセッション永続化を組み込むことができます。

FAQs

  1. チャット セッションを永続化するのはいつ役立ちますか?
    永続化は、起動間で会話状態を保持する必要があるデスクトップまたはサーバー アプリ、長時間実行されるワークフロー、監査やバックアップの要件、そして同じ SDK バージョンのマシン間でセッションを移行する場合に役立ちます。

  2. セッションを保存するときにカスタム ファイル パスを指定するにはどうすればよいですか?
    api.SaveChatSession(sessionId, "myfolder\myfile.json"); を呼び出すか、Path.Combine でパスを構築し、保存前にディレクトリが存在することを確認してください。

  3. LoadChatSession は何を返しますか?
    復元されたセッション識別子を返し、ID を再度指定せずにメッセージの送信を続けることができます。

  4. 保存したセッション ファイルを別のマシンに移動できますか?
    はい、対象のマシンが同じメジャー SDK バージョン、同一のモデル ファイル、そして一致する llama.cpp ReleaseTag を使用している限り可能です。

  5. 保存された JSON ファイルは安全ですか?
    このファイルはプレーンテキストの会話データを保存するため、信頼できない場所に保存する前に暗号化することを推奨します。

  6. ロード後にカスタム サンプラーやコンテキスト設定が復元されないのはなぜですか?
    LoadChatSession はデフォルトのパラメータを適用するため、ロード後にカスタム設定を再度適用するか、新しいセッションで履歴を再生してください。

続きを読む