通义千问1.5-1.8B-Chat-GPTQ-Int4.NET开发者如何通过REST API集成AI功能最近在捣鼓一些AI功能集成到我的.NET应用里发现很多教程要么是Python的要么就是直接用官方SDK对于想用纯REST API方式在C#里调用的朋友来说资料还真不多。正好前段时间在星图GPU平台上部署了通义千问1.5-1.8B-Chat的量化版本整个过程跑下来还挺顺畅的今天就跟大家分享一下怎么在.NET应用里通过最基础的HttpClient把AI对话能力给集成进来。如果你跟我一样主要技术栈是C#不想引入太多复杂的依赖就想用最直接的方式调用一个AI服务那这篇文章应该能帮到你。我会从怎么在星图平台部署模型开始讲到怎么在C#里写代码调用最后再做个简单的WPF聊天窗口演示一下。整个过程用的都是.NET里最常见的东西没什么黑魔法保证你看完就能上手试试。1. 第一步在星图GPU平台部署模型并获取API端点想在.NET里调用AI模型首先得有个服务端。自己从头搭环境、配显卡太麻烦了我直接用了星图GPU平台它提供了预置的模型镜像一键部署就能拿到一个可用的API地址。1.1 选择并部署模型镜像登录星图GPU平台后在镜像广场里搜索“通义千问”很快就能找到“通义千问1.5-1.8B-Chat-GPTQ-Int4”这个镜像。选它主要是因为模型尺寸小经过GPTQ和Int4量化后对资源要求不高响应速度也快特别适合用来做集成测试或者对延迟有要求的应用。点击部署后平台会让你选择实例规格。对于这个1.8B参数量的量化版模型选一个带T4或者V100这种入门级GPU的实例就完全够用了成本也低。部署过程是全自动的大概等个几分钟状态变成“运行中”就说明好了。1.2 找到你的API访问地址部署成功后在实例的管理页面你会看到一个“访问地址”或者“Endpoint”。这个地址就是我们后面在C#代码里要用的基础URL。通常格式是http://你的实例IP:端口号。星图的预置镜像一般会把模型的API服务直接开在某个端口上比如7860或者8000具体的端口号在镜像详情页有说明。关键一步记下这个完整的地址比如http://123.45.67.89:7860。同时检查一下实例的安全组设置确保你本地开发机的IP地址能够访问这个端口不然等下代码会连不上。2. 第二步理解并准备调用REST API模型服务跑起来后它对外提供的是一个标准的HTTP接口。我们不需要知道模型内部怎么工作的只需要知道怎么给它发请求、怎么收回复就行。这跟调用任何一个普通的Web API没什么两样。2.1 了解API的基本格式通义千问Chat模型的API通常兼容OpenAI的聊天补全格式这让我们调用起来非常方便。一个最简单的请求主要包含两个部分消息历史 (messages): 这是一个数组里面按顺序存放了对话的历史记录。每条记录都有个“角色”role比如user代表用户说的话assistant代表AI之前的回复。模型参数: 虽然服务端模型是固定的但有些API为了保持格式统一还是会要求传一个model字段我们可以按服务端的要求传一个固定的值比如qwen1.5-1.8b-chat。我们的目标就是构建一个符合这个格式的JSON字符串用HTTP POST请求发送到服务端的/v1/chat/completions这样的路径具体路径请查看你的镜像文档然后解析返回的JSON取出AI生成的文本。2.2 准备.NET项目打开Visual Studio或者你喜欢的IDE新建一个.NET项目。这里用控制台应用、WPF、或者ASP.NET Core Web API项目都可以原理相通。我这里为了演示完整会先在一个 .NET 8 的控制台应用里测试然后再过渡到WPF。记得在项目里我们只需要用到.NET自带的System.Net.Http.Json这个库它能帮我们更方便地处理JSON序列化和反序列化不用额外安装NuGet包。3. 第三步使用HttpClient在C#中调用API这是最核心的部分了。我们会创建一个服务类把调用AI API的逻辑封装起来这样在应用的其他地方就能很方便地复用。3.1 创建API客户端类我们先定义一个请求和响应的数据结构这能让代码更清晰。// 定义请求和响应的数据结构 public class ChatMessage { public string role { get; set; } // user 或 assistant public string content { get; set; } } public class ChatCompletionRequest { public string model { get; set; } qwen1.5-1.8b-chat; // 根据实际模型名填写 public ListChatMessage messages { get; set; } new(); public double temperature { get; set; } 0.7; // 控制随机性0-1之间 public int max_tokens { get; set; } 512; // 生成的最大长度 } public class ChatChoice { public ChatMessage message { get; set; } } public class ChatCompletionResponse { public ListChatChoice choices { get; set; } }接下来实现一个简单的客户端类using System.Net.Http.Json; using System.Text.Json; public class QwenAIClient { private readonly HttpClient _httpClient; private readonly string _apiBaseUrl; public QwenAIClient(string baseUrl) { _apiBaseUrl baseUrl.TrimEnd(/); // 确保URL末尾没有斜杠 _httpClient new HttpClient(); // 可以在这里设置一些默认超时时间 _httpClient.Timeout TimeSpan.FromSeconds(60); } public async Taskstring GetChatResponseAsync(ListChatMessage conversationHistory, CancellationToken cancellationToken default) { var request new ChatCompletionRequest { messages conversationHistory, // model, temperature 等参数使用定义时的默认值也可以在调用时传入 }; // 构建完整的API端点URL var apiUrl ${_apiBaseUrl}/v1/chat/completions; // 注意你的镜像具体端点路径可能不同可能是 /chat/completions 或 /generate请以镜像文档为准 try { // 发送POST请求并自动将请求对象序列化为JSON var response await _httpClient.PostAsJsonAsync(apiUrl, request, cancellationToken); // 确保响应是成功的 response.EnsureSuccessStatusCode(); // 读取并解析响应JSON var apiResponse await response.Content.ReadFromJsonAsyncChatCompletionResponse(cancellationToken: cancellationToken); // 从响应中提取AI回复的文本内容 if (apiResponse?.Choices?.Count 0) { return apiResponse.Choices[0].Message.Content.Trim(); } else { return 抱歉AI没有返回有效内容。; } } catch (HttpRequestException ex) { // 处理网络或HTTP错误 return $请求API时出错: {ex.Message}; } catch (TaskCanceledException) when (cancellationToken.IsCancellationRequested) { // 处理用户取消的请求 return 请求已取消。; } catch (Exception ex) { // 处理其他意外错误 return $处理响应时发生错误: {ex.Message}; } } }这个类做了几件事初始化HttpClient构建符合API格式的请求体发送POST请求然后处理响应和可能发生的异常。异常处理很重要因为网络请求可能会失败。3.2 在控制台应用中测试写好了客户端我们马上在Main方法里测试一下class Program { static async Task Main(string[] args) { // 替换成你在星图平台获取的真实API地址 string apiBaseUrl http://你的实例IP:7860; var aiClient new QwenAIClient(apiBaseUrl); // 初始化对话历史 var conversation new ListChatMessage { new ChatMessage { role system, content 你是一个乐于助人的AI助手。 }, // 可选的系统提示 new ChatMessage { role user, content 你好请用C#写一个Hello World程序。 } }; Console.WriteLine(用户: conversation.Last().Content); Console.WriteLine(AI思考中...\n); // 调用API获取回复 string aiReply await aiClient.GetChatResponseAsync(conversation); Console.WriteLine(通义千问: aiReply); // 将AI的回复加入历史以便后续连续对话 conversation.Add(new ChatMessage { role assistant, content aiReply }); // 接下来可以继续循环实现多轮对话... Console.WriteLine(\n--- 第一轮对话结束 ---); } }运行这个程序如果一切配置正确你应该能看到控制台输出了通义千问模型生成的C#代码。这就意味着你的.NET程序已经成功通过HTTP调用了远端的AI模型4. 第四步构建一个简单的WPF聊天演示程序光在控制台里跑还不够直观我们把它集成到一个有界面的WPF程序里这样就更像一个真正的聊天应用了。4.1 创建WPF项目并设计界面新建一个WPF应用项目。在MainWindow.xaml里我们可以设计一个非常简单的界面Window x:ClassQwenChatDemo.MainWindow ... Grid Grid.RowDefinitions RowDefinition Height*/ RowDefinition HeightAuto/ /Grid.RowDefinitions !-- 聊天消息显示区域 -- ScrollViewer Grid.Row0 VerticalScrollBarVisibilityAuto ItemsControl x:NameMessageItemsControl ItemsControl.ItemTemplate DataTemplate Border Margin5 Padding10 CornerRadius5 Background{Binding BackgroundColor} TextBlock TextWrappingWrap Text{Binding Content}/ /Border /DataTemplate /ItemsControl.ItemTemplate /ItemsControl /ScrollViewer !-- 底部输入和发送区域 -- StackPanel Grid.Row1 OrientationHorizontal Margin5 TextBox x:NameInputTextBox Width300 Margin5 KeyDownInputTextBox_KeyDown/ Button x:NameSendButton Content发送 Margin5 Padding10,5 ClickSendButton_Click/ Button x:NameClearButton Content清空 Margin5 Padding10,5 ClickClearButton_Click/ /StackPanel /Grid /Window再创建一个简单的数据模型来绑定消息public class ChatMessageModel { public string Content { get; set; } public string Sender { get; set; } // User 或 AI public Brush BackgroundColor Sender User ? Brushes.LightBlue : Brushes.LightGray; }4.2 编写后台逻辑在MainWindow.xaml.cs文件中我们将之前写的QwenAIClient集成进来并处理按钮点击事件。public partial class MainWindow : Window { private QwenAIClient _aiClient; private ListChatMessage _apiConversationHistory; // 用于API调用的历史 private ObservableCollectionChatMessageModel _uiMessages; // 用于界面显示的消息 public MainWindow() { InitializeComponent(); // 初始化集合并绑定到UI _uiMessages new ObservableCollectionChatMessageModel(); MessageItemsControl.ItemsSource _uiMessages; // 初始化API客户端和历史记录 // 注意实际项目中API地址应该从配置文件读取 _aiClient new QwenAIClient(http://你的实例IP:7860); _apiConversationHistory new ListChatMessage { new ChatMessage { role system, content 你是一个有用的助手用中文回答。 } }; } private async void SendButton_Click(object sender, RoutedEventArgs e) { await SendMessageAsync(); } private async void InputTextBox_KeyDown(object sender, KeyEventArgs e) { if (e.Key Key.Enter Keyboard.Modifiers ModifierKeys.None) { e.Handled true; await SendMessageAsync(); } } private async Task SendMessageAsync() { string userInput InputTextBox.Text.Trim(); if (string.IsNullOrEmpty(userInput)) return; // 1. 更新UI显示用户消息 _uiMessages.Add(new ChatMessageModel { Content userInput, Sender User }); InputTextBox.Clear(); SendButton.IsEnabled false; // 发送时禁用按钮防止重复发送 // 2. 更新API调用历史 _apiConversationHistory.Add(new ChatMessage { role user, content userInput }); // 3. 在UI上添加一个“思考中...”的提示 var thinkingMsg new ChatMessageModel { Content 思考中..., Sender AI }; _uiMessages.Add(thinkingMsg); try { // 4. 调用AI API注意这里会阻塞UI线程实际项目应考虑用BackgroundWorker或更佳方式 string aiResponse await _aiClient.GetChatResponseAsync(_apiConversationHistory); // 5. 移除“思考中...”提示添加真正的AI回复 _uiMessages.Remove(thinkingMsg); _uiMessages.Add(new ChatMessageModel { Content aiResponse, Sender AI }); // 6. 将AI回复加入API历史以便后续上下文对话 _apiConversationHistory.Add(new ChatMessage { role assistant, content aiResponse }); } catch (Exception ex) { _uiMessages.Remove(thinkingMsg); _uiMessages.Add(new ChatMessageModel { Content $出错: {ex.Message}, Sender AI }); } finally { SendButton.IsEnabled true; // 滚动到最新消息 var scrollViewer FindVisualChildScrollViewer(MessageItemsControl); scrollViewer?.ScrollToEnd(); } } // 一个辅助方法用于在可视化树中查找子控件 private static T FindVisualChildT(DependencyObject depObj) where T : DependencyObject { if (depObj null) return null; for (int i 0; i VisualTreeHelper.GetChildrenCount(depObj); i) { var child VisualTreeHelper.GetChild(depObj, i); if (child is T result) return result; var childItem FindVisualChildT(child); if (childItem ! null) return childItem; } return null; } private void ClearButton_Click(object sender, RoutedEventArgs e) { _uiMessages.Clear(); // 清空API历史但保留系统提示 _apiConversationHistory.RemoveAll(m m.role ! system); InputTextBox.Clear(); } }这样一个具备基本聊天功能的WPF程序就完成了。你可以输入问题点击发送程序会调用部署在星图平台上的通义千问模型并把回复显示在界面上。清空按钮可以重置对话。5. 总结走完这一整套流程你会发现在.NET应用里集成一个像通义千问这样的AI模型其实并没有想象中那么复杂。核心就是三步把模型服务部署好并拿到API地址用HttpClient按照约定格式发送HTTP请求最后处理好返回的数据。这种方式的好处是很灵活不依赖特定的SDK任何能发HTTP请求的.NET项目比如ASP.NET Core Web API做后端服务或者Blazor做前端都能用。而且因为模型是部署在星图这样的云GPU平台你不需要操心显卡、驱动这些底层设施专注在业务逻辑集成上就行。我提供的代码示例只是一个起点你可以在此基础上增加更多功能比如流式输出让AI回复一个字一个字显示、调整生成参数temperature、top_p等、管理更长的对话历史或者把API客户端做成一个后台服务。希望这个分享能帮你打开思路轻松地把AI能力带到你的下一个.NET项目里。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。