SmallThinker-3B-Preview集成实战.NET后端服务中的AI能力调用最近在做一个企业内部的智能内容平台需要集成一个轻量级的AI模型来处理一些文本分析任务。选型的时候SmallThinker-3B-Preview进入了我的视野——它体积小、推理快而且效果还不错特别适合在资源有限的后端服务里跑。但怎么把它平滑地集成到我们现有的.NET技术栈里确实花了我一些功夫去琢磨。今天这篇文章我就来聊聊我们是怎么做的。我会从一个实际的需求出发带你走一遍从模型API调用、到客户端封装、再到最终集成到ASP.NET Core服务里的完整过程。整个过程没有太多高深的理论就是一些实实在在的代码和踩过的坑希望能给正在考虑类似方案的你一些参考。1. 为什么选择SmallThinker-3B-Preview在开始动手之前我们得先搞清楚为什么要选这个模型。市面上模型那么多大模型能力固然强但对我们这种企业内部应用来说有时候“合适”比“强大”更重要。SmallThinker-3B-Preview最大的特点就是“轻”。这里的轻不只是说模型文件小更重要的是它对计算资源的要求不高。我们测试过在一台配置普通的服务器上它就能跑得很流畅不需要专门去采购昂贵的GPU卡。这对于控制项目成本来说是个很大的优势。另一个让我们心动的点是它的响应速度。因为模型参数少推理过程很快大多数文本处理任务都能在秒级内返回结果。这在构建实时或近实时的应用时体验会好很多用户不用等太久。当然它的能力也完全能满足我们这类场景的需求。比如文本分类、情感分析、关键信息提取、简单的对话生成这些它都处理得不错。虽然在一些特别复杂、需要深度推理的任务上它可能比不上那些百亿、千亿参数的大模型但对于企业里常见的自动化流程、内容辅助审核、智能客服路由这些场景它已经绰绰有余了。所以如果你的应用场景也是类似的——对响应速度有要求、计算资源有限、并且不需要处理极其复杂的逻辑——那么SmallThinker-3B-Preview会是一个性价比很高的选择。2. 环境准备与模型服务搭建要把模型用起来首先得让它跑起来。SmallThinker-3B-Preview通常以API服务的形式提供这意味着我们需要先有一个地方来托管这个模型。2.1 获取模型与启动服务模型服务这块现在有很多成熟的开源项目可以帮你快速搭建。比如一些主流的模型推理框架都提供了非常方便的一键部署脚本。你只需要准备好模型文件然后运行几条命令一个支持HTTP接口的模型服务就起来了。这里我假设你已经通过某种方式将SmallThinker-3B-Preview模型部署在了一台服务器上并且它提供了一个标准的HTTP API端点。这个端点通常能接受JSON格式的请求里面包含了你要处理的文本和一些可选的参数比如生成长度、温度系数等然后返回模型生成的结果。一个典型的请求地址可能长这样http://your-model-server:8000/v1/completions。当然具体的路径和端口取决于你用的部署工具。2.2 .NET项目基础配置模型服务准备好之后我们回到.NET这边。我新建了一个ASP.NET Core Web API项目作为我们集成AI能力的起点。首先我们需要安装几个必要的NuGet包。最核心的是System.Net.Http.Json它提供了非常便捷的方法来发送和接收JSON数据。如果你计划做更复杂的HTTP操作比如处理重试、熔断那么Microsoft.Extensions.Http.Polly也是一个很好的选择。// 在你的项目文件(.csproj)里添加这些包引用 ItemGroup PackageReference IncludeSystem.Net.Http.Json Version8.0.0 / PackageReference IncludeMicrosoft.Extensions.Http.Polly Version8.0.0 / /ItemGroup安装好包之后我们可以在Program.cs里通过依赖注入的方式配置一个专用于调用模型API的HttpClient。这样做的好处是我们可以集中管理这个客户端的配置比如超时时间、重试策略等。using System.Net.Http.Json; using Microsoft.Extensions.DependencyInjection; var builder WebApplication.CreateBuilder(args); // 添加一个命名的HttpClient专门用于调用AI模型服务 builder.Services.AddHttpClient(SmallThinkerClient, client { // 这里替换成你模型服务的实际地址 client.BaseAddress new Uri(http://your-model-server:8000/); client.Timeout TimeSpan.FromSeconds(30); // 设置一个合理的超时时间 client.DefaultRequestHeaders.Add(Accept, application/json); }); // 添加其他服务... builder.Services.AddControllers(); var app builder.Build(); // ... 后续配置这样基础的环境就搭好了。接下来我们就要开始写代码去跟模型“对话”了。3. 核心用C#调用模型API和模型服务通信本质上就是发送一个HTTP POST请求。我们需要按照模型服务要求的格式构造请求体然后解析返回的响应。3.1 定义请求与响应模型为了让代码更清晰、类型安全我们先定义两个类分别对应API的请求和响应。// 定义请求模型 public class SmallThinkerRequest { // 必需的要发送给模型的提示文本 public string Prompt { get; set; } string.Empty; // 可选的生成文本的最大长度 public int? MaxTokens { get; set; } 150; // 可选的温度参数控制输出的随机性0.0-1.0 public float? Temperature { get; set; } 0.7f; // 可选的是否流式输出我们这里先按非流式处理 public bool? Stream { get; set; } false; // 你可以根据模型支持的其他参数继续添加属性 // public float? TopP { get; set; } // public int? Seed { get; set; } } // 定义响应模型 public class SmallThinkerResponse { // 模型生成的文本结果 public string Text { get; set; } string.Empty; // 本次请求消耗的token数量输入输出 public int? Usage { get; set; } // 请求处理耗时如果服务端提供的话 public long? ProcessingTimeMs { get; set; } // 通常响应里还会有一个choices数组我们这里简化处理直接取第一个结果 // 实际解析时可能需要根据服务端返回的具体结构进行调整 }3.2 实现基础的HTTP客户端调用有了数据模型调用就很简单了。我们创建一个服务类来封装所有的调用逻辑。using System.Net.Http.Json; public interface ISmallThinkerService { Taskstring GenerateTextAsync(string prompt, CancellationToken cancellationToken default); } public class SmallThinkerService : ISmallThinkerService { private readonly HttpClient _httpClient; private readonly ILoggerSmallThinkerService _logger; // 通过构造函数注入配置好的HttpClient public SmallThinkerService(IHttpClientFactory httpClientFactory, ILoggerSmallThinkerService logger) { _httpClient httpClientFactory.CreateClient(SmallThinkerClient); _logger logger; } public async Taskstring GenerateTextAsync(string prompt, CancellationToken cancellationToken default) { if (string.IsNullOrWhiteSpace(prompt)) { throw new ArgumentException(提示词不能为空, nameof(prompt)); } // 1. 构造请求 var request new SmallThinkerRequest { Prompt prompt, MaxTokens 200, Temperature 0.8f }; try { _logger.LogInformation(正在向SmallThinker发送请求提示词长度: {PromptLength}, prompt.Length); // 2. 发送POST请求 // 注意这里的API路径“/v1/completions”需要替换成你模型服务的实际路径 var response await _httpClient.PostAsJsonAsync(/v1/completions, request, cancellationToken); // 3. 确保请求成功 response.EnsureSuccessStatusCode(); // 4. 读取并解析响应 // 这里直接读取为我们定义的响应模型 var apiResponse await response.Content.ReadFromJsonAsyncSmallThinkerResponse(cancellationToken: cancellationToken); if (apiResponse null || string.IsNullOrEmpty(apiResponse.Text)) { _logger.LogWarning(模型服务返回了空响应或无效数据。); return string.Empty; } _logger.LogInformation(请求成功返回文本长度: {TextLength}, apiResponse.Text.Length); return apiResponse.Text.Trim(); } catch (HttpRequestException ex) { _logger.LogError(ex, 调用SmallThinker API时发生网络错误。); throw; // 或者返回一个默认值取决于你的错误处理策略 } catch (TaskCanceledException) when (cancellationToken.IsCancellationRequested) { _logger.LogInformation(用户取消了请求。); throw; } catch (Exception ex) { _logger.LogError(ex, 调用SmallThinker API时发生未知错误。); throw; } } }记得在Program.cs里注册这个服务builder.Services.AddScopedISmallThinkerService, SmallThinkerService();现在在你的控制器或者其他服务里你就可以通过注入ISmallThinkerService轻松地调用GenerateTextAsync方法来获取AI生成的内容了。4. 进阶让调用更健壮上面的代码能跑通基本流程但在生产环境里网络是不稳定的服务也可能临时出问题。我们需要让这个调用过程更健壮。4.1 实现重试与超时策略我们可以利用Polly这个库为我们的HTTP调用增加重试和超时机制。这能有效应对短暂的网络抖动或服务端压力过大。首先在Program.cs中配置Polly策略using Polly; using Polly.Extensions.Http; var builder WebApplication.CreateBuilder(args); // 配置一个带重试和超时策略的HttpClient builder.Services.AddHttpClient(SmallThinkerClient, client { client.BaseAddress new Uri(http://your-model-server:8000/); client.DefaultRequestHeaders.Add(Accept, application/json); }) // 添加重试策略对于5xx错误和408请求超时错误重试3次每次间隔递增 .AddPolicyHandler(GetRetryPolicy()) // 添加超时策略整个请求包括重试超过30秒则放弃 .AddPolicyHandler(Policy.TimeoutAsyncHttpResponseMessage(TimeSpan.FromSeconds(30))); // 定义重试策略的方法 static IAsyncPolicyHttpResponseMessage GetRetryPolicy() { return HttpPolicyExtensions .HandleTransientHttpError() // 处理5xx和408错误 .OrResult(msg msg.StatusCode System.Net.HttpStatusCode.TooManyRequests) // 也处理429请求过多 .WaitAndRetryAsync(3, retryAttempt TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); // 重试3次间隔2,4,8秒 }4.2 封装为内部微服务当你的应用里有多个地方都需要用到AI能力时最好把它封装成一个独立的内部微服务。这样做有几个好处一是逻辑集中方便维护和升级二是可以统一做限流、监控和缓存三是其他服务通过简单的接口调用即可降低了耦合度。我们的SmallThinkerService已经是一个很好的起点。你可以进一步扩展它比如添加缓存对于一些常见的、结果不变的提示词比如固定的系统指令可以将结果缓存起来避免重复调用模型提升响应速度并节省资源。增加监控在方法里记录每次调用的耗时、成功失败状态、消耗的token数等方便后续分析和优化。实现限流如果模型服务的并发能力有限可以在调用层控制并发请求数防止打垮后端服务。提供更丰富的接口除了文本生成还可以封装文本分类、情感分析等特定功能的方法。// 一个增强版的服务接口示例 public interface IEnhancedAIService { Taskstring GenerateTextAsync(string prompt, ...); Taskstring ClassifyTextAsync(string text, string[] categories, ...); // 文本分类 Taskfloat AnalyzeSentimentAsync(string text, ...); // 情感分析 Taskstring[] ExtractKeywordsAsync(string text, ...); // 关键词提取 // ... 其他功能 }这样其他业务部门只需要调用你这个统一的AI服务网关而不需要关心背后用的是哪个模型、怎么调用的。5. 实战案例构建智能内容审核接口理论说了这么多我们来个实际的。假设我们要在内容发布系统里增加一个自动审核的环节用AI来初步判断用户提交的文本是否合规。5.1 场景与需求分析用户在我们平台发布文章或评论时系统需要快速判断内容是否包含不友善、违规或广告信息。完全依赖人工审核效率太低我们想用SmallThinker-3B-Preview来做一个初筛。需求输入一段用户提交的文本。AI模型判断该文本的“风险等级”例如安全、低风险、高风险。并给出简要的判断理由。整个过程需要在1-2秒内完成不影响用户发布体验。5.2 设计提示词Prompt要让AI完成这个任务关键是如何“问”它。我们需要设计一个清晰的提示词。// 这是一个提示词模板 private const string ModerationPromptTemplate 请对以下用户生成的内容进行安全审核。 内容{0} 请按照以下步骤分析 1. 判断内容是否包含不友善、人身攻击、歧视性言论。 2. 判断内容是否包含明显的广告或垃圾信息。 3. 判断内容是否涉及虚假或有害信息。 请用JSON格式返回你的审核结果包含以下两个字段 - risk_level: 风险等级可选值为 safe安全、low_risk低风险、high_risk高风险。 - reason: 简要的审核理由用中文说明。 只返回JSON不要有其他任何解释。 ;这个提示词做了几件事明确了任务、给出了分析步骤、规定了输出格式JSON。这样模型返回的结果就非常结构化方便我们后续的程序解析。5.3 实现ASP.NET Core API接口现在我们在Web API项目里创建一个控制器。using Microsoft.AspNetCore.Mvc; [ApiController] [Route(api/[controller])] public class ContentModerationController : ControllerBase { private readonly ISmallThinkerService _aiService; private readonly ILoggerContentModerationController _logger; public ContentModerationController(ISmallThinkerService aiService, ILoggerContentModerationController logger) { _aiService aiService; _logger logger; } [HttpPost(check)] public async TaskIActionResult CheckContent([FromBody] ContentCheckRequest request) { if (request null || string.IsNullOrWhiteSpace(request.Text)) { return BadRequest(请求内容不能为空。); } try { // 1. 构造完整的提示词 string fullPrompt string.Format(ModerationPromptTemplate, request.Text); // 2. 调用AI服务 string aiResponse await _aiService.GenerateTextAsync(fullPrompt); // 3. 解析AI返回的JSON这里需要更健壮的解析考虑AI可能不严格按格式输出 var moderationResult ParseAiResponse(aiResponse); // 4. 返回审核结果 return Ok(new ContentCheckResponse { OriginalText request.Text, RiskLevel moderationResult.RiskLevel, Reason moderationResult.Reason, CheckedAt DateTime.UtcNow }); } catch (Exception ex) { _logger.LogError(ex, 内容审核处理失败。文本: {Text}, request.Text); // 发生错误时返回一个“需要人工复核”的安全结果 return Ok(new ContentCheckResponse { OriginalText request.Text, RiskLevel unknown, Reason 系统审核暂时不可用请人工复核。, CheckedAt DateTime.UtcNow }); } } private (string RiskLevel, string Reason) ParseAiResponse(string rawResponse) { // 简化版的解析逻辑 // 实际应用中你需要更健壮的JSON解析并处理AI输出可能不规范的情况 try { // 尝试从返回文本中提取JSON部分 // 这里只是一个简单示例你可能需要使用正则表达式或更复杂的文本处理 if (rawResponse.Contains(risk_level) rawResponse.Contains(reason)) { // 假设我们能直接反序列化 var result System.Text.Json.JsonSerializer.DeserializeDictionarystring, string(rawResponse); if (result ! null result.TryGetValue(risk_level, out var level) result.TryGetValue(reason, out var reason)) { return (level, reason); } } } catch { // 解析失败 } // 默认返回需要人工复核 return (unknown, AI返回格式无法识别建议人工复核。); } } // 请求模型 public class ContentCheckRequest { public string Text { get; set; } string.Empty; } // 响应模型 public class ContentCheckResponse { public string OriginalText { get; set; } string.Empty; public string RiskLevel { get; set; } string.Empty; // safe, low_risk, high_risk, unknown public string Reason { get; set; } string.Empty; public DateTime CheckedAt { get; set; } }5.4 效果与后续优化这个接口上线后确实帮我们过滤掉了很多明显的违规内容减轻了人工审核的压力。当然AI不是万能的它也会有误判。所以我们目前的策略是标记为high_risk的内容直接进入人工审核队列暂不发布。标记为low_risk的内容可以正常发布但会被记录供后续抽样复查。标记为safe的内容直接通过。标记为unknown或调用失败的也转入人工审核。后续我们还可以做很多优化比如优化提示词根据误判案例不断调整和优化提示词让AI更懂我们的审核标准。加入后处理结合一些规则引擎比如关键词过滤对AI的结果进行二次校验。建立反馈闭环把人工审核的最终结果反馈给系统用于持续优化AI模型如果支持微调的话或调整判断阈值。6. 总结把SmallThinker-3B-Preview这样的轻量级AI模型集成到.NET后端服务里整个过程其实并不复杂。核心就是处理好HTTP通信、做好错误处理、并根据业务场景设计好提示词。从我们的实践来看这种集成方式非常灵活。你可以像我们一样把它封装成一个内部服务供多个业务系统调用也可以根据具体需求把它做成一个独立的微服务甚至集成到现有的工作流引擎里。最大的体会是提示词的设计质量直接决定了AI的应用效果。花时间去琢磨怎么把任务描述清楚怎么规定输出格式往往比调参带来的提升更明显。另外在生产环境里一定要把AI服务当作一个可能不稳定外部依赖来处理重试、降级、熔断这些机制都得考虑进去。如果你也在做类似的集成不妨先从一个小而具体的场景开始比如一个内容审核接口或者一个智能客服的意图识别模块。跑通整个流程看到实际效果后再逐步扩展到更复杂的场景中去。这样迭代起来信心会更足方向也更明确。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
SmallThinker-3B-Preview集成实战:.NET后端服务中的AI能力调用
SmallThinker-3B-Preview集成实战.NET后端服务中的AI能力调用最近在做一个企业内部的智能内容平台需要集成一个轻量级的AI模型来处理一些文本分析任务。选型的时候SmallThinker-3B-Preview进入了我的视野——它体积小、推理快而且效果还不错特别适合在资源有限的后端服务里跑。但怎么把它平滑地集成到我们现有的.NET技术栈里确实花了我一些功夫去琢磨。今天这篇文章我就来聊聊我们是怎么做的。我会从一个实际的需求出发带你走一遍从模型API调用、到客户端封装、再到最终集成到ASP.NET Core服务里的完整过程。整个过程没有太多高深的理论就是一些实实在在的代码和踩过的坑希望能给正在考虑类似方案的你一些参考。1. 为什么选择SmallThinker-3B-Preview在开始动手之前我们得先搞清楚为什么要选这个模型。市面上模型那么多大模型能力固然强但对我们这种企业内部应用来说有时候“合适”比“强大”更重要。SmallThinker-3B-Preview最大的特点就是“轻”。这里的轻不只是说模型文件小更重要的是它对计算资源的要求不高。我们测试过在一台配置普通的服务器上它就能跑得很流畅不需要专门去采购昂贵的GPU卡。这对于控制项目成本来说是个很大的优势。另一个让我们心动的点是它的响应速度。因为模型参数少推理过程很快大多数文本处理任务都能在秒级内返回结果。这在构建实时或近实时的应用时体验会好很多用户不用等太久。当然它的能力也完全能满足我们这类场景的需求。比如文本分类、情感分析、关键信息提取、简单的对话生成这些它都处理得不错。虽然在一些特别复杂、需要深度推理的任务上它可能比不上那些百亿、千亿参数的大模型但对于企业里常见的自动化流程、内容辅助审核、智能客服路由这些场景它已经绰绰有余了。所以如果你的应用场景也是类似的——对响应速度有要求、计算资源有限、并且不需要处理极其复杂的逻辑——那么SmallThinker-3B-Preview会是一个性价比很高的选择。2. 环境准备与模型服务搭建要把模型用起来首先得让它跑起来。SmallThinker-3B-Preview通常以API服务的形式提供这意味着我们需要先有一个地方来托管这个模型。2.1 获取模型与启动服务模型服务这块现在有很多成熟的开源项目可以帮你快速搭建。比如一些主流的模型推理框架都提供了非常方便的一键部署脚本。你只需要准备好模型文件然后运行几条命令一个支持HTTP接口的模型服务就起来了。这里我假设你已经通过某种方式将SmallThinker-3B-Preview模型部署在了一台服务器上并且它提供了一个标准的HTTP API端点。这个端点通常能接受JSON格式的请求里面包含了你要处理的文本和一些可选的参数比如生成长度、温度系数等然后返回模型生成的结果。一个典型的请求地址可能长这样http://your-model-server:8000/v1/completions。当然具体的路径和端口取决于你用的部署工具。2.2 .NET项目基础配置模型服务准备好之后我们回到.NET这边。我新建了一个ASP.NET Core Web API项目作为我们集成AI能力的起点。首先我们需要安装几个必要的NuGet包。最核心的是System.Net.Http.Json它提供了非常便捷的方法来发送和接收JSON数据。如果你计划做更复杂的HTTP操作比如处理重试、熔断那么Microsoft.Extensions.Http.Polly也是一个很好的选择。// 在你的项目文件(.csproj)里添加这些包引用 ItemGroup PackageReference IncludeSystem.Net.Http.Json Version8.0.0 / PackageReference IncludeMicrosoft.Extensions.Http.Polly Version8.0.0 / /ItemGroup安装好包之后我们可以在Program.cs里通过依赖注入的方式配置一个专用于调用模型API的HttpClient。这样做的好处是我们可以集中管理这个客户端的配置比如超时时间、重试策略等。using System.Net.Http.Json; using Microsoft.Extensions.DependencyInjection; var builder WebApplication.CreateBuilder(args); // 添加一个命名的HttpClient专门用于调用AI模型服务 builder.Services.AddHttpClient(SmallThinkerClient, client { // 这里替换成你模型服务的实际地址 client.BaseAddress new Uri(http://your-model-server:8000/); client.Timeout TimeSpan.FromSeconds(30); // 设置一个合理的超时时间 client.DefaultRequestHeaders.Add(Accept, application/json); }); // 添加其他服务... builder.Services.AddControllers(); var app builder.Build(); // ... 后续配置这样基础的环境就搭好了。接下来我们就要开始写代码去跟模型“对话”了。3. 核心用C#调用模型API和模型服务通信本质上就是发送一个HTTP POST请求。我们需要按照模型服务要求的格式构造请求体然后解析返回的响应。3.1 定义请求与响应模型为了让代码更清晰、类型安全我们先定义两个类分别对应API的请求和响应。// 定义请求模型 public class SmallThinkerRequest { // 必需的要发送给模型的提示文本 public string Prompt { get; set; } string.Empty; // 可选的生成文本的最大长度 public int? MaxTokens { get; set; } 150; // 可选的温度参数控制输出的随机性0.0-1.0 public float? Temperature { get; set; } 0.7f; // 可选的是否流式输出我们这里先按非流式处理 public bool? Stream { get; set; } false; // 你可以根据模型支持的其他参数继续添加属性 // public float? TopP { get; set; } // public int? Seed { get; set; } } // 定义响应模型 public class SmallThinkerResponse { // 模型生成的文本结果 public string Text { get; set; } string.Empty; // 本次请求消耗的token数量输入输出 public int? Usage { get; set; } // 请求处理耗时如果服务端提供的话 public long? ProcessingTimeMs { get; set; } // 通常响应里还会有一个choices数组我们这里简化处理直接取第一个结果 // 实际解析时可能需要根据服务端返回的具体结构进行调整 }3.2 实现基础的HTTP客户端调用有了数据模型调用就很简单了。我们创建一个服务类来封装所有的调用逻辑。using System.Net.Http.Json; public interface ISmallThinkerService { Taskstring GenerateTextAsync(string prompt, CancellationToken cancellationToken default); } public class SmallThinkerService : ISmallThinkerService { private readonly HttpClient _httpClient; private readonly ILoggerSmallThinkerService _logger; // 通过构造函数注入配置好的HttpClient public SmallThinkerService(IHttpClientFactory httpClientFactory, ILoggerSmallThinkerService logger) { _httpClient httpClientFactory.CreateClient(SmallThinkerClient); _logger logger; } public async Taskstring GenerateTextAsync(string prompt, CancellationToken cancellationToken default) { if (string.IsNullOrWhiteSpace(prompt)) { throw new ArgumentException(提示词不能为空, nameof(prompt)); } // 1. 构造请求 var request new SmallThinkerRequest { Prompt prompt, MaxTokens 200, Temperature 0.8f }; try { _logger.LogInformation(正在向SmallThinker发送请求提示词长度: {PromptLength}, prompt.Length); // 2. 发送POST请求 // 注意这里的API路径“/v1/completions”需要替换成你模型服务的实际路径 var response await _httpClient.PostAsJsonAsync(/v1/completions, request, cancellationToken); // 3. 确保请求成功 response.EnsureSuccessStatusCode(); // 4. 读取并解析响应 // 这里直接读取为我们定义的响应模型 var apiResponse await response.Content.ReadFromJsonAsyncSmallThinkerResponse(cancellationToken: cancellationToken); if (apiResponse null || string.IsNullOrEmpty(apiResponse.Text)) { _logger.LogWarning(模型服务返回了空响应或无效数据。); return string.Empty; } _logger.LogInformation(请求成功返回文本长度: {TextLength}, apiResponse.Text.Length); return apiResponse.Text.Trim(); } catch (HttpRequestException ex) { _logger.LogError(ex, 调用SmallThinker API时发生网络错误。); throw; // 或者返回一个默认值取决于你的错误处理策略 } catch (TaskCanceledException) when (cancellationToken.IsCancellationRequested) { _logger.LogInformation(用户取消了请求。); throw; } catch (Exception ex) { _logger.LogError(ex, 调用SmallThinker API时发生未知错误。); throw; } } }记得在Program.cs里注册这个服务builder.Services.AddScopedISmallThinkerService, SmallThinkerService();现在在你的控制器或者其他服务里你就可以通过注入ISmallThinkerService轻松地调用GenerateTextAsync方法来获取AI生成的内容了。4. 进阶让调用更健壮上面的代码能跑通基本流程但在生产环境里网络是不稳定的服务也可能临时出问题。我们需要让这个调用过程更健壮。4.1 实现重试与超时策略我们可以利用Polly这个库为我们的HTTP调用增加重试和超时机制。这能有效应对短暂的网络抖动或服务端压力过大。首先在Program.cs中配置Polly策略using Polly; using Polly.Extensions.Http; var builder WebApplication.CreateBuilder(args); // 配置一个带重试和超时策略的HttpClient builder.Services.AddHttpClient(SmallThinkerClient, client { client.BaseAddress new Uri(http://your-model-server:8000/); client.DefaultRequestHeaders.Add(Accept, application/json); }) // 添加重试策略对于5xx错误和408请求超时错误重试3次每次间隔递增 .AddPolicyHandler(GetRetryPolicy()) // 添加超时策略整个请求包括重试超过30秒则放弃 .AddPolicyHandler(Policy.TimeoutAsyncHttpResponseMessage(TimeSpan.FromSeconds(30))); // 定义重试策略的方法 static IAsyncPolicyHttpResponseMessage GetRetryPolicy() { return HttpPolicyExtensions .HandleTransientHttpError() // 处理5xx和408错误 .OrResult(msg msg.StatusCode System.Net.HttpStatusCode.TooManyRequests) // 也处理429请求过多 .WaitAndRetryAsync(3, retryAttempt TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); // 重试3次间隔2,4,8秒 }4.2 封装为内部微服务当你的应用里有多个地方都需要用到AI能力时最好把它封装成一个独立的内部微服务。这样做有几个好处一是逻辑集中方便维护和升级二是可以统一做限流、监控和缓存三是其他服务通过简单的接口调用即可降低了耦合度。我们的SmallThinkerService已经是一个很好的起点。你可以进一步扩展它比如添加缓存对于一些常见的、结果不变的提示词比如固定的系统指令可以将结果缓存起来避免重复调用模型提升响应速度并节省资源。增加监控在方法里记录每次调用的耗时、成功失败状态、消耗的token数等方便后续分析和优化。实现限流如果模型服务的并发能力有限可以在调用层控制并发请求数防止打垮后端服务。提供更丰富的接口除了文本生成还可以封装文本分类、情感分析等特定功能的方法。// 一个增强版的服务接口示例 public interface IEnhancedAIService { Taskstring GenerateTextAsync(string prompt, ...); Taskstring ClassifyTextAsync(string text, string[] categories, ...); // 文本分类 Taskfloat AnalyzeSentimentAsync(string text, ...); // 情感分析 Taskstring[] ExtractKeywordsAsync(string text, ...); // 关键词提取 // ... 其他功能 }这样其他业务部门只需要调用你这个统一的AI服务网关而不需要关心背后用的是哪个模型、怎么调用的。5. 实战案例构建智能内容审核接口理论说了这么多我们来个实际的。假设我们要在内容发布系统里增加一个自动审核的环节用AI来初步判断用户提交的文本是否合规。5.1 场景与需求分析用户在我们平台发布文章或评论时系统需要快速判断内容是否包含不友善、违规或广告信息。完全依赖人工审核效率太低我们想用SmallThinker-3B-Preview来做一个初筛。需求输入一段用户提交的文本。AI模型判断该文本的“风险等级”例如安全、低风险、高风险。并给出简要的判断理由。整个过程需要在1-2秒内完成不影响用户发布体验。5.2 设计提示词Prompt要让AI完成这个任务关键是如何“问”它。我们需要设计一个清晰的提示词。// 这是一个提示词模板 private const string ModerationPromptTemplate 请对以下用户生成的内容进行安全审核。 内容{0} 请按照以下步骤分析 1. 判断内容是否包含不友善、人身攻击、歧视性言论。 2. 判断内容是否包含明显的广告或垃圾信息。 3. 判断内容是否涉及虚假或有害信息。 请用JSON格式返回你的审核结果包含以下两个字段 - risk_level: 风险等级可选值为 safe安全、low_risk低风险、high_risk高风险。 - reason: 简要的审核理由用中文说明。 只返回JSON不要有其他任何解释。 ;这个提示词做了几件事明确了任务、给出了分析步骤、规定了输出格式JSON。这样模型返回的结果就非常结构化方便我们后续的程序解析。5.3 实现ASP.NET Core API接口现在我们在Web API项目里创建一个控制器。using Microsoft.AspNetCore.Mvc; [ApiController] [Route(api/[controller])] public class ContentModerationController : ControllerBase { private readonly ISmallThinkerService _aiService; private readonly ILoggerContentModerationController _logger; public ContentModerationController(ISmallThinkerService aiService, ILoggerContentModerationController logger) { _aiService aiService; _logger logger; } [HttpPost(check)] public async TaskIActionResult CheckContent([FromBody] ContentCheckRequest request) { if (request null || string.IsNullOrWhiteSpace(request.Text)) { return BadRequest(请求内容不能为空。); } try { // 1. 构造完整的提示词 string fullPrompt string.Format(ModerationPromptTemplate, request.Text); // 2. 调用AI服务 string aiResponse await _aiService.GenerateTextAsync(fullPrompt); // 3. 解析AI返回的JSON这里需要更健壮的解析考虑AI可能不严格按格式输出 var moderationResult ParseAiResponse(aiResponse); // 4. 返回审核结果 return Ok(new ContentCheckResponse { OriginalText request.Text, RiskLevel moderationResult.RiskLevel, Reason moderationResult.Reason, CheckedAt DateTime.UtcNow }); } catch (Exception ex) { _logger.LogError(ex, 内容审核处理失败。文本: {Text}, request.Text); // 发生错误时返回一个“需要人工复核”的安全结果 return Ok(new ContentCheckResponse { OriginalText request.Text, RiskLevel unknown, Reason 系统审核暂时不可用请人工复核。, CheckedAt DateTime.UtcNow }); } } private (string RiskLevel, string Reason) ParseAiResponse(string rawResponse) { // 简化版的解析逻辑 // 实际应用中你需要更健壮的JSON解析并处理AI输出可能不规范的情况 try { // 尝试从返回文本中提取JSON部分 // 这里只是一个简单示例你可能需要使用正则表达式或更复杂的文本处理 if (rawResponse.Contains(risk_level) rawResponse.Contains(reason)) { // 假设我们能直接反序列化 var result System.Text.Json.JsonSerializer.DeserializeDictionarystring, string(rawResponse); if (result ! null result.TryGetValue(risk_level, out var level) result.TryGetValue(reason, out var reason)) { return (level, reason); } } } catch { // 解析失败 } // 默认返回需要人工复核 return (unknown, AI返回格式无法识别建议人工复核。); } } // 请求模型 public class ContentCheckRequest { public string Text { get; set; } string.Empty; } // 响应模型 public class ContentCheckResponse { public string OriginalText { get; set; } string.Empty; public string RiskLevel { get; set; } string.Empty; // safe, low_risk, high_risk, unknown public string Reason { get; set; } string.Empty; public DateTime CheckedAt { get; set; } }5.4 效果与后续优化这个接口上线后确实帮我们过滤掉了很多明显的违规内容减轻了人工审核的压力。当然AI不是万能的它也会有误判。所以我们目前的策略是标记为high_risk的内容直接进入人工审核队列暂不发布。标记为low_risk的内容可以正常发布但会被记录供后续抽样复查。标记为safe的内容直接通过。标记为unknown或调用失败的也转入人工审核。后续我们还可以做很多优化比如优化提示词根据误判案例不断调整和优化提示词让AI更懂我们的审核标准。加入后处理结合一些规则引擎比如关键词过滤对AI的结果进行二次校验。建立反馈闭环把人工审核的最终结果反馈给系统用于持续优化AI模型如果支持微调的话或调整判断阈值。6. 总结把SmallThinker-3B-Preview这样的轻量级AI模型集成到.NET后端服务里整个过程其实并不复杂。核心就是处理好HTTP通信、做好错误处理、并根据业务场景设计好提示词。从我们的实践来看这种集成方式非常灵活。你可以像我们一样把它封装成一个内部服务供多个业务系统调用也可以根据具体需求把它做成一个独立的微服务甚至集成到现有的工作流引擎里。最大的体会是提示词的设计质量直接决定了AI的应用效果。花时间去琢磨怎么把任务描述清楚怎么规定输出格式往往比调参带来的提升更明显。另外在生产环境里一定要把AI服务当作一个可能不稳定外部依赖来处理重试、降级、熔断这些机制都得考虑进去。如果你也在做类似的集成不妨先从一个小而具体的场景开始比如一个内容审核接口或者一个智能客服的意图识别模块。跑通整个流程看到实际效果后再逐步扩展到更复杂的场景中去。这样迭代起来信心会更足方向也更明确。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。