.NET集成ChatGPT API:开源库rodion-m/ChatGPT_API_dotnet实战指南
1. 项目概述一个为 .NET 开发者准备的 ChatGPT API 集成利器如果你是一名 .NET 开发者最近正琢磨着怎么把 ChatGPT 的能力优雅地集成到自己的应用里那你可能已经踩过一些坑了。官方的 OpenAI API 虽然强大但直接裸用HttpClient去调用你得自己处理认证、序列化、错误重试、对话历史管理还有那个让人又爱又恨的流式响应Streaming。更别提在 ASP.NET Core 这种依赖注入DI框架里如何设计一个既线程安全又好用的服务层了。我自己在几个企业级项目里折腾了一圈后发现了一个叫rodion-m/ChatGPT_API_dotnet的开源库它几乎把我能想到的痛点都解决了。简单说这是一个专门为 .NET 生态打造的 ChatGPT API 客户端库。它的核心价值不在于“能用”而在于“好用”和“工程化”。它原生支持 ASP.NET Core 的依赖注入无缝集成 Entity Framework Core 来持久化对话历史还内置了像结构化响应把 AI 回复自动转成 C# 对象、翻译模块这样的高级功能。无论是快速构建一个聊天机器人后台还是需要 AI 能力来处理业务逻辑比如自动分类用户反馈、生成报告摘要这个库都能让你省下大量搭建基础设施的时间。它的设计哲学很明确让开发者专注于业务逻辑而不是反复编写调用 API 的样板代码。2. 核心设计思路与架构解析2.1 分层设计与职责分离这个库的设计非常清晰遵循了 .NET 生态中常见的分层模式。理解它的结构能帮助你在使用时做出正确的选择。基础层OpenAI.ChatGPT这是最底层的核心。它提供了一个纯粹的OpenAIClient类封装了与 OpenAI、Azure OpenAI 以及 OpenRouter 等兼容 API 端点的所有 HTTP 交互。这一层不关心 DI也不管数据怎么存只负责发送请求、接收响应包括流式响应、处理错误和序列化。如果你正在构建一个控制台应用、一个桌面程序或者一个非常轻量级的服务直接用这一层就足够了。它给了你最大的灵活性。集成层OpenAI.ChatGPT.AspNetCore / OpenAI.ChatGPT.EntityFrameworkCore这是库的精华所在也是它区别于其他简单封装的核心。这一层引入了ChatGPTFactory和ChatGPT这两个关键类将 AI 对话抽象为一种有状态的、与特定用户或会话绑定的服务。ChatGPTFactory负责按需创建ChatGPT实例而ChatGPT实例则通过IChatHistoryStorage接口来保存和加载对话历史。默认的 EF Core 实现 (ChatHistoryStorage) 帮你把消息记录到数据库里这意味着用户的每一次对话都能在服务重启后得以延续实现了真正的“上下文记忆”。模块层Modules在核心服务之上库通过独立的 NuGet 包提供了可插拔的功能模块比如StructuredResponse和Translator。这种设计非常巧妙它避免了核心库的膨胀允许开发者按需引用。StructuredResponse模块利用了 GPT-3.5-Turbo 和 GPT-4 的 JSON 模式能强制 AI 以指定的 JSON 格式回应并自动反序列化成你定义的 C# 类。这在需要从非结构化文本中提取结构化数据的场景下如订单信息解析、事件摘要是革命性的大大减少了后续解析的代码和错误。2.2 配置驱动的多后端支持2024年8月的更新带来了一个关键特性对 OpenAI、Azure OpenAI 和 OpenRouter 的统一支持。这通过一个配置驱动的模式来实现。在你的appsettings.json里你可以通过AIProvider字段指定使用哪个服务商并填写对应的凭证。注意将 API Key 直接写在appsettings.json并提交到代码仓库是极不安全的。生产环境中务必使用 .NET 的用户机密User Secrets用于开发、环境变量或 Azure Key Vault 等安全配置源来管理这些敏感信息。库本身支持通过Configuration对象读取与 .NET 的标准配置模式完全一致。这种设计的好处是你的业务代码不需要关心底层调用的到底是哪个服务。你可以根据成本、速率限制、模型可用性甚至地理合规性要求在配置文件中轻松切换后端而无需修改任何一行业务逻辑代码。例如在开发测试时使用 OpenAI 的沙盒在生产环境使用 Azure OpenAI 以获得企业级的 SLA 和支持。2.3 对话状态管理ChatGPT与ChatService这是库中最需要理解的一个概念。ChatGPT类代表一个与特定“用户”或“会话”绑定的对话代理。当你通过ChatGPTFactory.Create(userId)创建一个实例时库会为这个userId加载或创建新的对话历史。而ChatService则是实际执行对话操作的对象通过await chatGpt.ContinueOrStartNewTopic()获得。ChatService内部维护着当前话题的消息列表。每次调用GetNextMessageResponse它都会将整个历史记录包括系统指令、之前的问答作为上下文发送给 AI从而保证对话的连贯性。实操心得userId的设计非常灵活。它不一定是一个真实的用户 ID。你可以用它来区分不同的聊天会话、不同的业务实体如一个客服工单、一个文档处理任务。只要保证同一逻辑会话使用相同的userId就能维持其对话上下文。这为构建复杂的多轮交互应用提供了基础。3. 从零开始集成详细步骤与避坑指南3.1 环境准备与项目初始化首先你需要一个 API 密钥。根据你的选择前往对应平台创建OpenAI访问 platform.openai.com 注册并创建 API Key。Azure OpenAI需要在你的 Azure 订阅中申请访问并部署一个模型终端Deployment。记下终结点Endpoint、部署名Deployment Name和密钥Key。OpenRouter作为一个聚合平台可以访问多种模型适合需要灵活性的场景。创建一个新的 ASP.NET Core Web API 项目这里以 .NET 8 为例dotnet new webapi -n MyChatGptService cd MyChatGptService3.2 安装与基础配置根据你的需求安装对应的 NuGet 包。如果你需要对话历史持久化推荐使用 EF Core 集成包。# 安装 EF Core 集成包包含基础客户端和 ASP.NET Core 集成 dotnet add package OpenAI.ChatGPT.EntityFrameworkCore # 安装 SQLite 用于本地开发或选择 SQL Server、PostgreSQL 等 dotnet add package Microsoft.EntityFrameworkCore.Sqlite接下来配置appsettings.json。这里以 OpenAI 为例并展示如何为不同环境设置不同的配置。appsettings.Development.json(开发环境使用用户机密){ Logging: { LogLevel: { Default: Information, Microsoft.AspNetCore: Warning } }, ConnectionStrings: { DefaultConnection: Data Source./chatgpt.db }, AIProvider: openai }注意这里没有直接写 ApiKey。我们使用 .NET 的用户机密管理工具来存储敏感信息。在项目根目录运行以下命令设置用户机密dotnet user-secrets init dotnet user-secrets set OpenAICredentials:ApiKey 你的-OpenAI-API-KEYappsettings.Production.json(生产环境使用环境变量){ AIProvider: openai, OpenAICredentials: { ApiHost: https://api.openai.com/v1/ }, ConnectionStrings: { DefaultConnection: Server生产数据库服务器;DatabaseChatAppDb;... } }在生产环境的服务器上你可以设置环境变量ASPNETCORE_OpenAICredentials__ApiKey注意双下划线__是 .NET Configuration 中冒号:的等价物来注入 API Key。3.3 服务注册与数据库配置在Program.cs中添加服务注册和数据库配置。这是将库集成到 ASP.NET Core 管道的核心步骤。using Microsoft.EntityFrameworkCore; using OpenAI.ChatGpt.AspNetCore; var builder WebApplication.CreateBuilder(args); // 添加基础服务 builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // 1. 注册 ChatGPT 服务并配置使用 SQLite 数据库存储历史 builder.Services.AddChatGptEntityFrameworkIntegration( builder.Configuration, // 传入配置库会从中读取 AIProvider 和 Credentials options options.UseSqlite(builder.Configuration.GetConnectionString(DefaultConnection)) ); // 如果你使用 SQL Server可以这样写 // builder.Services.AddChatGptEntityFrameworkIntegration( // builder.Configuration, // options options.UseSqlServer(builder.Configuration.GetConnectionString(DefaultConnection)) // ); var app builder.Build(); // 2. 确保数据库被创建仅用于开发环境生产环境请使用迁移 using (var scope app.Services.CreateScope()) { var dbContext scope.ServiceProvider.GetRequiredServiceChatGptDbContext(); dbContext.Database.EnsureCreated(); } // 配置 HTTP 请求管道 if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();重要警告dbContext.Database.EnsureCreated()在开发初期快速搭建原型时很方便但它不能处理数据库架构的后续变更。对于任何严肃的项目强烈建议使用 Entity Framework Core 的迁移Migrations功能来管理数据库变更。你可以运行dotnet ef migrations add InitialCreate和dotnet ef database update来生成和应用迁移脚本。3.4 编写第一个聊天接口现在让我们创建一个简单的控制器来验证集成是否成功。using Microsoft.AspNetCore.Mvc; using OpenAI.ChatGpt; namespace MyChatGptService.Controllers; [ApiController] [Route(api/[controller])] public class ChatController : ControllerBase { private readonly ChatGPTFactory _chatGptFactory; // 通过构造函数注入 ChatGPTFactory public ChatController(ChatGPTFactory chatGptFactory) { _chatGptFactory chatGptFactory; } [HttpPost(talk)] public async TaskActionResultstring SendMessage( [FromBody] ChatRequest request, [FromQuery] string? userId null) { // 为简单演示如果未提供 userId则生成一个随机的会话ID。 // 实际应用中userId 应该来自认证后的用户身份。 var effectiveUserId userId ?? Guid.NewGuid().ToString(); // 1. 为该用户创建/获取一个 ChatGPT 对话实例 ChatGPT chatGpt await _chatGptFactory.Create(effectiveUserId); // 2. 继续现有话题或开始新话题获取 ChatService var chatService await chatGpt.ContinueOrStartNewTopic(); // 3. 发送用户消息并获取 AI 回复 string response await chatService.GetNextMessageResponse(request.Message); return Ok(new { UserId effectiveUserId, Response response }); } [HttpPost(talk/stream)] public async IAsyncEnumerablestring SendMessageStream( [FromBody] ChatRequest request, [FromQuery] string? userId null) { var effectiveUserId userId ?? Guid.NewGuid().ToString(); ChatGPT chatGpt await _chatGptFactory.Create(effectiveUserId); var chatService await chatGpt.ContinueOrStartNewTopic(); // 使用流式响应逐块返回 await foreach (string chunk in chatService.StreamNextMessageResponse(request.Message)) { // 每个 chunk 是 AI 回复的一部分 yield return chunk; } } } // 简单的请求模型 public record ChatRequest(string Message);启动项目用 Swagger 或 Postman 测试/api/chat/talk接口。你会发现即使你多次调用同一个userIdAI 也能记住之前的对话上下文因为它被持久化在数据库里了。而流式接口/api/chat/talk/stream会以 SSEServer-Sent Events或类似流的形式返回数据非常适合实现类似 ChatGPT 网页版那种逐字打印的效果。4. 高级功能深度解析与应用4.1 结构化响应让 AI 的输出直接成为你的业务对象这是我认为最强大的功能之一。想象一下你让 AI 分析一段客户评论并希望直接得到一个包含“情感倾向”枚举、“关键词列表”字符串数组和“建议行动”字符串的对象。手动解析 AI 返回的文本既繁琐又容易出错。StructuredResponse模块解决了这个问题。首先安装模块包dotnet add package OpenAI.ChatGPT.Modules.StructuredResponse然后定义你的数据模型。这里的关键是使用清晰、自解释的属性名并尽量使用基础类型。public enum Sentiment { Positive, Neutral, Negative } public record CustomerFeedbackAnalysis { public Sentiment OverallSentiment { get; set; } public Liststring KeyTopics { get; set; } new(); public string? SuggestedAction { get; set; } }在你的服务中注入IOpenAIClient注意这里用的是基础客户端不是ChatGPT服务然后直接调用using OpenAI.ChatGpt.Modules.StructuredResponse; public class FeedbackService { private readonly IOpenAIClient _openAiClient; public FeedbackService(IOpenAIClient openAiClient) { _openAiClient openAiClient; } public async TaskCustomerFeedbackAnalysis AnalyzeFeedbackAsync(string feedbackText) { // 1. 构建一个对话明确指示 AI 以 JSON 格式返回 var dialog Dialog .StartAsSystem(你是一个客户反馈分析助手。请将用户的反馈分析为指定的 JSON 格式。) .ThenUser($请分析以下反馈{feedbackText}); // 2. 直接获取结构化对象 // 指定 model 为支持 JSON 模式的 GPT-4-Turbo var analysis await _openAiClient.GetStructuredResponseCustomerFeedbackAnalysis( dialog, model: ChatCompletionModels.Gpt4Turbo ); return analysis; } }实操心得与注意事项模型选择务必使用支持 JSON 模式的模型如Gpt4Turbo(gpt-4-1106-preview) 或Gpt3_5_Turbo_1106。对于 GPT-3.5虽然库也支持但响应稳定性可能稍差建议在提示词中提供更详细的示例examples参数。提示词工程系统消息StartAsSystem至关重要。必须清晰地告诉 AI 你需要它返回一个结构化的 JSON并描述这个结构。有时在用户消息中再次强调“请以 JSON 格式回复”也能提高成功率。错误处理AI 可能返回格式不正确的 JSON。GetStructuredResponse方法内部会尝试反序列化如果失败会抛出异常。在生产代码中务必用try-catch包裹并设计降级策略例如记录日志并返回一个空的或默认的分析对象。复杂嵌套该模块支持复杂的嵌套对象、列表和枚举。对于枚举AI 通常会返回枚举值的字符串名称序列化器能正确识别。4.2 翻译模块不仅仅是文本翻译翻译模块同样强大它不仅能翻译字符串还能翻译整个对象图并与结构化响应模块结合实现“接收一种语言的对象返回另一种语言的对象”的复杂流程。安装翻译模块dotnet add package OpenAI.ChatGPT.Modules.Translatorusing OpenAI.ChatGpt.Modules.Translator; public class TranslationService { private readonly IChatGptTranslatorService _translator; public TranslationService(IChatGptTranslatorService translator) { _translator translator; } // 简单文本翻译 public async Taskstring TranslateSimpleText(string text) { return await _translator.TranslateText(text, English, Chinese); } // 翻译复杂对象 public async TaskProductCatalog TranslateCatalog(ProductCatalog englishCatalog) { // 这会递归地翻译对象中所有字符串属性根据你的配置 var chineseCatalog await _translator.TranslateObject(englishCatalog, English, Chinese); return chineseCatalog; } } public record ProductCatalog { public string CategoryName { get; set; } ; // 会被翻译 public ListProduct Products { get; set; } new(); // 列表内的对象也会被递归翻译 } public record Product { public string Name { get; set; } ; public string Description { get; set; } ; }4.3 配置详解与性能调优库提供了丰富的配置选项可以通过appsettings.json或代码进行设置。ChatGPTConfig配置示例{ ChatGPTConfig: { InitialSystemMessage: 你是一个专业的软件开发助手回答需简洁、准确。, InitialUserMessage: null, MaxTokens: 1500, Model: gpt-4-turbo-preview, Temperature: 0.7, PassUserIdToOpenAiRequests: false } }InitialSystemMessage为每个新话题设置默认的系统角色指令。这非常有用可以为你的应用设定统一的 AI 行为基调。例如客服机器人可以设置为“你是一个耐心、专业的客服代表”。MaxTokens限制单次回复的最大令牌数。必须谨慎设置。设置过低会导致回答被截断设置过高则浪费 Token 并可能收到不完整的回复如果上下文太长。一个经验法则是预留出你期望答案长度的 1.5 倍同时要确保MaxTokens 上下文令牌数不超过模型的总限制例如GPT-4 Turbo 是 128k。库提供了ChatCompletionMessage.CalculateApproxTotalTokenCount方法进行粗略估算。Temperature控制创造性与确定性。对于代码生成、事实问答建议较低的值0.2-0.5对于创意写作、头脑风暴可以调高0.7-1.0。ChatCompletionTemperatures类提供了Deterministic(0.2),Balanced(0.5),Creative(0.8) 等预设常量。PassUserIdToOpenAiRequests是否将你的userId传递给 OpenAI API 用于监控和滥用检测。根据你的隐私政策决定是否开启。通过ChatGPTFactory动态配置你可以在创建ChatGPT实例时覆盖全局配置这为多租户或不同功能场景提供了灵活性。var config new ChatGPTConfig { Model ChatCompletionModels.Gpt4, Temperature ChatCompletionTemperatures.Deterministic, InitialSystemMessage 你现在是一个严格的代码审查员只指出代码中的问题。 }; ChatGPT strictReviewer await _chatGptFactory.Create(userId, config);5. 生产环境必备异常处理、重试与线程安全5.1 异常处理库主要会抛出两种异常NotExpectedResponseException当 API 返回非成功状态码时抛出如认证失败401、额度不足429、服务器错误5xx。异常对象中包含来自 OpenAI 的错误信息对于调试非常关键。OperationCanceledException当请求被取消例如用户在前端取消了操作或设置了超时时抛出。在流式响应中你可能不希望这个异常破坏流程可以通过StreamNextMessageResponse(text, throwOnCancellation: false)来抑制它。一个健壮的服务层应该这样处理异常public async Taskstring GetRobustResponse(string userId, string prompt) { try { ChatGPT chatGpt await _chatGptFactory.Create(userId); var chatService await chatGpt.ContinueOrStartNewTopic(); return await chatService.GetNextMessageResponse(prompt); } catch (NotExpectedResponseException ex) { _logger.LogError(ex, OpenAI API 请求失败。状态码{StatusCode}, 内容{Content}, ex.StatusCode, ex.Content); // 根据状态码决定策略429 可以重试401 需要报警400 可能是提示词问题。 if (ex.StatusCode System.Net.HttpStatusCode.TooManyRequests) { // 触发重试逻辑 throw new TransientException(请求过于频繁请稍后重试。, ex); } return 抱歉AI 服务暂时不可用。; } catch (HttpRequestException ex) { // 网络问题 _logger.LogError(ex, 网络错误导致 OpenAI 请求失败。); return 网络连接出现问题请检查后重试。; } catch (Exception ex) { // 其他未预料错误 _logger.LogCritical(ex, 处理 AI 请求时发生未知错误。); return 系统内部错误请联系管理员。; } }5.2 重试与弹性策略由于依赖网络和外部 API重试机制是生产级应用的必备品。库的ChatGPTFactory依赖于IHttpClientFactory这使得集成 Polly 这样的弹性库变得异常简单。首先安装 Polly 扩展dotnet add package Microsoft.Extensions.Http.Polly然后在Program.cs中配置一个带重试和熔断策略的 HttpClientusing Polly; using Polly.Extensions.Http; builder.Services.AddHttpClient(OpenAIClient) // 这个名称会被库内部使用 .AddPolicyHandler(GetRetryPolicy()) // 添加重试策略 .AddPolicyHandler(GetCircuitBreakerPolicy()); // 添加熔断器策略 // 定义重试策略对 429、5xx 和网络异常进行重试 static IAsyncPolicyHttpResponseMessage GetRetryPolicy() { return HttpPolicyExtensions .HandleTransientHttpError() // 处理 5xx 和 408, 502, 503, 504 .OrResult(msg (int)msg.StatusCode 429) // 额外处理 429 限流 .WaitAndRetryAsync(3, retryAttempt TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); } // 定义熔断器策略连续失败5次后熔断30秒 static IAsyncPolicyHttpResponseMessage GetCircuitBreakerPolicy() { return HttpPolicyExtensions .HandleTransientHttpError() .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); }注意Polly 策略是全局应用的。你需要仔细考虑重试对幂等性的影响对于非幂等的 POST 请求重试可能导致重复操作。幸运的是ChatGPT 的聊天补全 API 在语义上通常是幂等的发送相同的消息历史应得到相同回复但重试仍可能产生额外的 API 调用费用。5.3 线程安全与异步最佳实践文档明确指出ChatGPTFactory线程安全性取决于IChatHistoryStorage的实现。使用 EF Core 时它不是线程安全的。这意味着你不应该在多个线程间共享同一个ChatGPTFactory实例或者并发地为同一个userId创建ChatGPT实例这可能导致数据库上下文冲突。ChatGPT与ChatService同样不是线程安全的。它们设计为在单个逻辑会话如一个 HTTP 请求中使用。正确的使用模式是在 ASP.NET Core 的 Controller 或 Service 中通过依赖注入获取ChatGPTFactory它是单例的线程安全。在处理方法如 Action内部为当前请求/用户创建ChatGPT和ChatService实例。在该请求的上下文中使用这些实例完成操作后让其随请求生命周期结束。// 正确示例在 Scoped 或 Transient 服务中创建和使用 public class MyScopedService { private readonly ChatGPTFactory _factory; public MyScopedService(ChatGPTFactory factory) _factory factory; public async Task ProcessUserSession(string userId) { // 每个会话/请求创建独立的实例 ChatGPT chatGpt await _factory.Create(userId); var chatService await chatGpt.ContinueOrStartNewTopic(); // ... 使用 chatService // 请求结束后实例会被释放不会干扰其他请求。 } }所有库方法都使用了ConfigureAwait(false)这意味着在 UI 应用如 WPF, WinForms中回调不会强制回到 UI 线程你需要自己处理线程切换。但在 ASP.NET Core 中这通常不是问题。6. 常见问题排查与实战技巧在实际集成过程中你肯定会遇到各种问题。下面是我总结的一些常见坑点及其解决方案。问题现象可能原因排查步骤与解决方案抛出NotExpectedResponseException状态码 401API Key 无效、过期或配置错误。1. 检查appsettings.json或环境变量中的ApiKey是否正确前后有无空格。2. 确认AIProvider设置与提供的 Credentials 匹配例如设置了openai却填了 Azure 的 Key。3. 对于 Azure OpenAI检查ApiHost格式是否为https://{your-resource}.openai.azure.com/以及DeploymentName是否正确。抛出NotExpectedResponseException状态码 429达到速率限制RPM/TPM或配额不足。1.速率限制检查 OpenAI 账户的用量面板。对于免费额度或新账户限制很严格。需要降低请求频率或升级到付费计划。2.配额不足检查是否已用完免费额度或设置的用量上限。需要在 OpenAI 平台调整配额。3.实施退避重试集成 Polly 重试策略如上文所示自动处理 429 错误。AI 回复被截断或不完整MaxTokens参数设置过小或者上下文回复的总令牌数超过了模型上限。1. 调大MaxTokens值。2. 估算当前对话历史的令牌数。如果历史太长需要主动清理旧消息。库的持久化历史功能可能导致对话无限增长你需要实现一个策略例如只保留最近 N 条消息或当令牌数超过阈值时总结之前的对话并清空历史。流式响应 (StreamNextMessageResponse) 不工作或提前结束网络连接不稳定或者客户端如浏览器未正确处理流式响应。1. 在服务端代码中检查是否正确处理了IAsyncEnumerable并使用了[Produces(text/plain)]或类似的 Attribute。2. 在客户端确保使用正确的 API 来读取流如 Fetch API 的response.body.getReader()。3. 检查服务端和客户端的超时设置流式响应可能需要更长的超时时间。结构化响应反序列化失败AI 返回的 JSON 格式不符合 C# 类定义。1.检查提示词确保系统消息明确要求返回指定格式的 JSON。2.简化模型确保你的 C# 类是可反序列化的有无参构造函数属性有 getter/setter。对于复杂类型先从简单的record开始测试。3.查看原始响应在调用GetStructuredResponse前先用GetChatCompletionsRaw等方法获取原始响应文本看看 AI 到底返回了什么。可能 AI 在 JSON 外加了说明文字。数据库迁移冲突或EnsureCreated失败模型变更后现有数据库架构不匹配。绝对不要在生产环境使用EnsureCreated。切换到 EF Core Migrations1.dotnet ef migrations add AddChatHistoryTable2.dotnet ef database update3. 后续模型变更时重复此过程。为同一userId并发请求时出现数据库错误违反了ChatGPT/ChatService的非线程安全原则。确保对同一个userId的请求是串行处理的或者引入锁机制。更常见的模式是将userId与一个具体的“会话ID”区分开每个独立的聊天窗口使用不同的会话ID即使背后是同一个用户。独家避坑技巧上下文管理策略对于长对话定期调用await chatGpt.StartNewTopic()来开启一个全新的话题避免上下文过长导致性能下降和费用增加。你可以基于令牌数或对话轮数来实现自动切换。成本监控每次 API 调用的响应中都包含Usage信息总令牌数、提示令牌数、完成令牌数。考虑将这些数据也存入数据库用于分析和成本核算。虽然库没有直接暴露这个数据但你可以通过扩展IChatHistoryStorage或在调用后记录日志来实现。模型降级在appsettings.json中可以将Model设置为null这样库会使用默认模型通常是 GPT-3.5-Turbo。在非关键路径或内部工具中使用更便宜的模型可以显著降低成本。自定义IChatHistoryStorage如果你不想用 EF Core或者想将对话历史存到 Redis、Cosmos DB 等其他地方实现自己的IChatHistoryStorage接口非常简单。这给了你极大的灵活性例如实现基于内存的临时会话或者与你的现有用户数据存储集成。这个库极大地简化了在 .NET 应用中集成大型语言模型的过程其工程化的设计让开发者能从繁琐的基础设施代码中解脱出来。从简单的聊天接口到复杂的结构化数据提取它都提供了优雅的解决方案。理解其分层架构、熟练运用配置、妥善处理异常和并发你就能构建出稳定、高效且易于维护的 AI 赋能应用。