大多數今天加入 AI 功能的 .NET 團隊最終都在編寫相同的基礎設施:HTTP 客戶端、重試策略、API 金鑰的機密管理,以及在某人信用卡上的每個代幣計費行。Aspose.LLM 採取了不同的路徑。它是一個 NuGet 套件,能在 在您的程式內部 執行大型語言模型推理——無需呼叫服務,無需輪換金鑰,且不會有請求離開機器。
本文介紹了該庫,說明了其 API 所基於的三個概念,並帶您一步步完成一個可運作的聊天應用程式。如果您能添加套件參考,僅需幾十行程式碼即可發送提示。
為什麼本地模型很重要
在進程內執行模型會改變您能構建的內容。
- 資料保持不變。 提示永不離開主機,這在處理合約、醫療筆記、原始程式碼或任何受資料居留政策約束的內容時尤為重要。
- 無每代幣成本。 一旦模型位於磁碟上,推論僅消耗您已擁有的 CPU 或 GPU 成本,而非計量的 API 呼叫。
- 執行時無網路依賴。 桌面工具、本地服務以及隔離環境皆以相同方式運作。
- 單一部署工件。 模型配置隨您的應用程式一起發佈,而不是存在於其他帳戶的儀表板中。
這個權衡是誠實且值得提前說明的:您提供硬體。需要在本地運行的模型需要本地記憶體,且首次執行時需要下載數個千兆位元組。
Aspose.LLM for .NET 三個概念
表面積刻意設計得很小。幾乎所有使用 Aspose.LLM 的操作都涉及這三種類型。
| 概念 | 類型 | 角色 |
|---|---|---|
| License | Aspose.LLM.License | 啟用庫。 在使用任何其他 API 之前呼叫 SetLicense。 |
| Preset | e.g. Qwen25Preset | 將模型檔案與生成參數(例如抽樣器溫度)捆綁在一起。 |
| API instance | AsposeLLMApi | 入口點。 從預設值建立,保存對話,公開 SendMessageAsync。 |
預設是比較有趣的那個。與其讓您手動設定模型路徑、分詞器設定和抽樣器值,預設會打包一個已知良好的組合。Qwen25Preset 是預設的起始點,您可以調整其參數或稍後換成其他預設,而無需觸及其餘程式碼。
先決條件
在編寫任何程式碼之前:
- 安裝套件 -
Install-Package Aspose.LLM - 放置授權 - 將
Aspose.LLM.lic放在可於執行時讀取的位置。 - 檢查記憶體預算 - Qwen25 預設至少需要 8 GB 的可用 RAM。
如需產品詳細資訊,請參閱 Aspose.LLM for .NET 產品頁面。
您的第一個聊天
以下是最簡短的程式,可進行真實對話。請注意第二次和第三次呼叫:API 實例會自行追蹤上下文,因此模型仍然知道 Alice 是誰。
程式碼的功能
- 建立一個
License並指向您的授權檔案。 - 使用其預設設定實例化
Qwen25Preset。 - 從該預設建立一個
AsposeLLMApi實例。 - 發送多個提示,全部共享同一個對話。
using Aspose.LLM;
using Aspose.LLM.Abstractions.Parameters.Presets;
var license = new Aspose.LLM.License();
license.SetLicense("Aspose.LLM.lic");
var preset = new Qwen25Preset();
using var api = AsposeLLMApi.Create(preset);
string reply = await api.SendMessageAsync("What is 2 + 2?");
Console.WriteLine(reply);
// Output: 2 + 2 equals 4.
await api.SendMessageAsync("My name is Alice.");
string reply2 = await api.SendMessageAsync("What is my name?");
Console.WriteLine(reply2);
// Output: Your name is Alice.
AsposeLLMApi.Create(preset) 會回傳一個具備會話感知的客戶端。每個 SendMessageAsync 呼叫會將提示詞附加到正在進行的對話中,因而在不自行管理任何狀態的情況下獲得多輪互動行為。using 宣告很重要——實例擁有本機資源,需要被釋放。
注意: 這些範例遵循官方 Aspose 文件,且未在沙盒中執行。請在自己的環境中驗證後再發布。
調整單個請求的行為
對話式答案受益於一定的隨機性。算術則不會。與其重新配置實例,不如建立第二個預設,並將其傳遞給需要的那一次呼叫。
程式碼的功能
- 如往常一樣,建立預設 preset 和 API 實例。
- 使用低採樣器溫度建立
strictPreset。 - 透過
preset參數將其傳遞給SendMessageAsync。 - 保留後續呼叫使用原始的預設。
using Aspose.LLM.Abstractions.Parameters.Presets;
// Default preset used by the API instance
var defaultPreset = new Qwen25Preset();
using var api = AsposeLLMApi.Create(defaultPreset);
// A more deterministic preset, for this question only
var strictPreset = new Qwen25Preset();
strictPreset.SamplerParameters.Temperature = 0.1f;
string reply = await api.SendMessageAsync(
"What is the square root of 144?",
preset: strictPreset);
Console.WriteLine(reply);
// Output: The square root of 144 is 12.
SamplerParameters.Temperature 控制抽樣器引入的隨機程度。接近 0.1 的值會產生近乎確定性的輸出;較高的值會產生更為多變的措辭。由於預設僅在呼叫範圍內有效,覆寫不會洩漏到對話的其他部分。
取消與逾時
生成長度並非完全可預測,且執行時間過長的請求會阻塞所有等待它的操作。SendMessageAsync 接受一個 CancellationToken,因此請提供它。
程式碼的功能
- 建立一個具有 30 秒預算的
CancellationTokenSource。 - 將
cts.Token傳遞給SendMessageAsync。 - 捕獲
OperationCanceledException並優雅地降級。
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
try
{
string reply = await api.SendMessageAsync(
"Write a 500-word essay about migration patterns of the Arctic tern.",
cancellationToken: cts.Token);
Console.WriteLine(reply);
}
catch (OperationCanceledException)
{
Console.WriteLine("Generation timed out.");
}
取消操作會保留會話狀態,因此對話在下一次呼叫時會正常繼續。 在 ASP.NET Core 處理程序中,亦應將請求本身的 RequestAborted 令牌轉發到此處——沒有理由為已斷線的客戶端繼續產生請求。
完整的控制台應用程式
把它組合起來:一個 REPL,讓單一會話在整個進程生命週期內保持活躍,並能從每條訊息的失敗中恢復。
程式碼的功能
- 在啟動時設定一次授權和預設設定。
- 為整個程式建立單一個
AsposeLLMApi實例。 - 持續迴圈等待使用者輸入,直到使用者輸入
quit。 - 傳送每一行並列印回覆。
- 為每條訊息捕獲例外,確保單一失敗不會終止會話。
using Aspose.LLM;
using Aspose.LLM.Abstractions.Parameters.Presets;
internal class SimpleChatDemo
{
public static async Task Main()
{
var license = new Aspose.LLM.License();
license.SetLicense("Aspose.LLM.lic");
var preset = new Qwen25Preset();
using var api = AsposeLLMApi.Create(preset);
Console.WriteLine("Ask me anything. Type 'quit' to exit.");
while (true)
{
Console.Write("> ");
string? line = Console.ReadLine();
if (line == null || line.Equals("quit", StringComparison.OrdinalIgnoreCase))
break;
try
{
string reply = await api.SendMessageAsync(line);
Console.WriteLine(reply);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
}
兩個設計要點值得在實際應用中保留。首先,實例僅建立 一次 並重複使用——建立成本高,且如下一節所述,不允許同時存在多個實例。其次,try-catch 放在迴圈內部而不是外部,這樣單一錯誤訊息只會消耗一次回合,而不會影響整個會話。
使用臨時許可證評估此庫,請前往 Aspose 臨時許可證頁面。
您可能首先遇到的錯誤
| 錯誤 | 常見原因 | 解決方法 |
|---|---|---|
Not licensed for this method | 授權檔案遺失或路徑錯誤 | 確認 Aspose.LLM.lic 可從工作目錄讀取,且在任何其他 API 呼叫之前執行 SetLicense。 |
Only one AsposeLLMApi instance can be created at a time | 同時存在兩個實例,通常來自每個請求的工廠 | 將實例註冊為單例,或在建立新實例前先釋放先前的實例。 |
| 首次回應需要數分鐘 | 引擎正在下載本機二進位檔和模型權重 | 在全新機器上預計需要 5-15 分鐘。於啟動時觸發 Create,以免將成本轉嫁給使用者。 |
在服務情境中,第二行值得特別強調。
如果您將 Aspose.LLM 接入 DI 容器,請將 AsposeLLMApi 註冊為單例,並將對其的存取序列化——範圍或暫時性註冊在兩個請求重疊時會失敗。
其他資源
結論
Aspose.LLM 將「add an LLM to this .NET application」簡化為三種型別和一個方法。授權會啟用函式庫,預設設定定義模型及其生成方式,而 AsposeLLMApi 實例則承載對話。從此,SendMessageAsync 可處理單一問題、多回合會話、每次呼叫的參數覆寫,以及可取消的長時間生成。
先從控制台範例開始,確認模型的行為符合您的功能需求,然後在基礎穩固後再進行多會話和持久化工作。
常見問題
1. 什麼是 Aspose.LLM for .NET?
一個 NuGet 庫,可在您自己的 .NET 進程中執行大型語言模型推理。您可以建立預設、建立 API 實例,並傳送提示——無需外部服務,無需 API 金鑰。
2. 使用它是否需要網際網路連線?
僅在首次執行時。首次呼叫 Create 會下載原生引擎和預設定義的模型檔案,之後資產會被緩存於本機。
3. 代碼範例的先決條件是什麼?
Aspose.LLM NuGet 套件、有效的 Aspose.LLM.lic 檔案,以及足夠的可用 RAM 以符合您選擇的預設 - 請為 Qwen25 至少規劃 8 GB。
4. 如何在單個請求中更改模型的行為?
建立第二個預設設定,調整其參數(例如 SamplerParameters.Temperature),並透過 preset 參數將其傳遞給 SendMessageAsync。之後的呼叫會恢復為實例的預設預設設定。
5. 如何停止耗時過長的生成?
將 CancellationToken 傳遞給 SendMessageAsync,並捕獲 OperationCanceledException。會話狀態在取消後仍然保留,對話會正常繼續。
6. 為什麼第一次回應這麼慢?
第一次 Create 呼叫會下載本機二進位檔和模型權重,這在全新機器上可能需要 5‑15 分鐘。請在應用程式啟動時預熱實例,而不是在使用者的首次請求時才進行。
