C#调用大模型

文章目录

P.S. 目前国内还是很缺AI人才的,希望更多人能真正加入到AI行业,共同促进行业进步,增强我国的AI竞争力。想要系统学习AI知识的朋友可以看看我精心打磨的教程 http://blog.csdn.net/jiangjunshow http://blog.csdn.net/jiangjunshow/article/details/77338485,教程通俗易懂,高中生都能看懂,还有各种段子风趣幽默,从深度学习基础原理到各领域实战应用都有讲解,我22年的AI积累全在里面了。注意,教程仅限真正想入门AI的朋友,否则看看零散的博文就够了。


一、开篇:为啥要写这篇文章

兄弟们,说实话啊,我搞AI这22年,见过太多奇葩事了。

前几天有个做.NET开发的老弟找我,说公司领导让他把ChatGPT接进项目里。他一脸懵,问我:"哥,C#咋调大模型啊?网上资料乱七八糟的..."

我当时就笑了。这问题太典型了!

你看啊,现在市面上讲Python调OpenAI的文章满天飞,但C#的?少得可怜!好像咱们.NET开发者不配玩AI似的...

扯淡!

C#调大模型不但能干,而且干得贼漂亮。微软自家就是搞AI的,Semantic Kernel这玩意儿就是亲儿子,稳定得一匹。

今天我就把我这些年踩过的坑、试过的路,一股脑儿全倒给你们。

二、准备工作:别急着写代码

2.1 先搞个API Key

这事儿简单,但必须得说。

OpenAI官网注册一个账号,去API页面复制你的Key。注意啊,这Key就跟你的银行卡密码一样,千万别往GitHub上扔!

我一般放环境变量里:

bash 复制代码
# Windows
setx OPENAI_API_KEY "sk-你的密钥"

# 或者代码里读取
string apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");

2.2 创建项目

Visual Studio新建一个控制台项目,.NET 8就行。别整那些花里胡哨的,先跑通再说。

bash 复制代码
dotnet new console -n CSharpLLMDemo
cd CSharpLLMDemo

2.3 装NuGet包

这里有好几条路可以走,我给你列清楚:

方案A:直接用OpenAI官方SDK(最简单)

bash 复制代码
dotnet add package OpenAI --version 2.0.0

方案B:用Semantic Kernel(推荐,功能最强)

bash 复制代码
dotnet add package Microsoft.SemanticKernel --version 1.0.0
dotnet add package Microsoft.SemanticKernel.Connectors.OpenAI --version 1.0.0

方案C:用Microsoft.Extensions.AI(最新最潮)

bash 复制代码
dotnet add package Microsoft.Extensions.AI --version 9.0.0

我主要讲方案B,Semantic Kernel。为啥?因为这才是工业级的玩法!

三、基础调用:先让整个"Hello AI"

3.1 最简单的聊天

来,上代码:

csharp 复制代码
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;

class Program
{
    static async Task Main(string[] args)
    {
        // 1. 创建Kernel
        var builder = Kernel.CreateBuilder();
        builder.AddOpenAIChatCompletion(
            modelId: "gpt-4o-mini",  // 这个模型便宜又好用
            apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY")!
        );
        
        var kernel = builder.Build();
        
        // 2. 获取聊天服务
        var chatService = kernel.GetRequiredService<IChatCompletionService>();
        
        // 3. 开聊!
        var history = new ChatHistory();
        history.AddSystemMessage("你是一个幽默的AI助手,说话要带梗");
        history.AddUserMessage("你好,给我讲个程序员笑话");
        
        var response = await chatService.GetChatMessageContentAsync(history);
        
        Console.WriteLine($"AI说:{response.Content}");
    }
}

运行结果大概长这样:

复制代码
AI说:为啥程序员总是分不清圣诞节和万圣节?

因为 31 OCT = 25 DEC!

(八进制的31等于十进制的25,懂的人自然懂...)

看到没?就这么几行代码,AI就跟你聊上了。

3.2 流式输出

上面的代码有个问题:要等AI全部想完了才给你显示。如果回复很长,用户会以为程序卡死了...

改成流式输出:

csharp 复制代码
var history = new ChatHistory();
history.AddUserMessage("写一篇关于C#的500字短文");

await foreach (var chunk in chatService.GetStreamingChatMessageContentsAsync(history))
{
    Console.Write(chunk.Content);  // 来一个字符就显示一个
}

用户体验瞬间起飞!就像看AI在打字一样,爽得很。

四、进阶玩法:让AI真正"会做事"

4.1 什么是Function Calling

兄弟们,重点来了啊!

大模型有个毛病:它只会"说话",不会"做事"。

你问它"1234567除以7654321等于多少",它可能会瞎猜一个答案。为啥?因为它没有计算器!

Function Calling就是解决这个问题的。简单说:你给AI一堆工具(函数),让它自己决定什么时候用哪个。

4.2 实战:做个计算器插件

来,看这段代码:

csharp 复制代码
using Microsoft.SemanticKernel;
using System.ComponentModel;

public class CalculatorPlugin
{
    [KernelFunction("add_numbers")]
    [Description("将两个数字相加")]
    public int AddNumbers(
        [Description("第一个数字")] int a,
        [Description("第二个数字")] int b)
    {
        Console.WriteLine($"[计算器被调用] {a} + {b}");
        return a + b;
    }
    
    [KernelFunction("divide_numbers")]
    [Description("将第一个数字除以第二个数字")]
    public double DivideNumbers(
        [Description("被除数")] double a,
        [Description("除数")] double b)
    {
        Console.WriteLine($"[计算器被调用] {a} / {b}");
        return a / b;
    }
}

注意那两个特性标签:

  • [KernelFunction]:标记这个方法可以被AI调用
  • [Description]:告诉AI这个方法是干嘛的

4.3 注册插件并让AI使用

csharp 复制代码
// 1. 注册插件
builder.Plugins.AddFromType<CalculatorPlugin>();
var kernel = builder.Build();

// 2. 配置让AI自动调用工具
var settings = new OpenAIPromptExecutionSettings
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions,
    Temperature = 0.1  // 准确度优先,别乱发挥
};

// 3. 创建带配置的函数
var func = kernel.CreateFunctionFromPrompt(
    "用户问题:{input}", 
    settings
);

// 4. 提问
var result = await kernel.InvokeAsync(func, new KernelArguments 
{ 
    ["input"] = "1234567除以7654321等于多少?精确到5位小数" 
});

Console.WriteLine(result);

运行结果:

复制代码
[计算器被调用] 1234567 / 7654321
AI说:1234567除以7654321等于0.16129

看到没?AI发现自己不会算,就调用了我们的计算器!这才是真正的智能嘛。

4.4 更实用的例子:天气查询

光会算数有啥用?来整点实际的:

csharp 复制代码
public class WeatherPlugin
{
    [KernelFunction("get_weather")]
    [Description("获取指定城市的当前天气")]
    public string GetWeather(
        [Description("城市名称,比如'北京'、'上海'")] string city)
    {
        // 这里调真实的天气API,我先模拟一下
        var random = new Random();
        var temp = random.Next(15, 35);
        var conditions = new[] { "晴天", "多云", "小雨", "阴天" };
        var condition = conditions[random.Next(conditions.Length)];
        
        return $"{city}当前天气:{condition},温度{temp}°C";
    }
}

注册进去,然后问AI:

csharp 复制代码
var result = await kernel.InvokeAsync(func, new KernelArguments 
{ 
    ["input"] = "我想去北京旅游,那边天气怎么样?" 
});

AI会自动提取出"北京"这个城市名,然后调用GetWeather函数!

五、对话上下文管理

5.1 为啥需要上下文

AI有个特点:它"记性不好"。每次调用都是独立的,它不记得你之前说过啥。

所以得用ChatHistory来保存对话记录:

csharp 复制代码
var history = new ChatHistory();
history.AddSystemMessage("你是专业客服,态度要好");

while (true)
{
    Console.Write("用户:");
    var input = Console.ReadLine();
    if (input == "exit") break;
    
    history.AddUserMessage(input);
    
    var response = await chatService.GetChatMessageContentAsync(history);
    Console.WriteLine($"AI:{response.Content}");
    
    history.AddAssistantMessage(response.Content!);  // 关键!把AI回复也存起来
}

这样AI就能记住之前的对话了,体验跟ChatGPT一样丝滑。

5.2 上下文长度限制

但要注意啊,GPT-4o-mini最多支持128K tokens。超过这个限制,就得删掉一些老消息。

csharp 复制代码
// 简单的截断策略:保留最近10轮对话
if (history.Count > 20)  // 10轮 = 20条消息(用户+AI各10条)
{
    // 保留System消息,删除最老的用户/AI消息对
    var systemMessage = history.FirstOrDefault(m => m.Role == AuthorRole.System);
    history.Clear();
    if (systemMessage != null) history.Add(systemMessage);
}

六、国内大模型怎么调

6.1 用DeepSeek

OpenAI的API国内访问不稳定,而且贵!DeepSeek便宜多了。

csharp 复制代码
builder.AddOpenAIChatCompletion(
    modelId: "deepseek-chat",
    apiKey: "你的DeepSeek Key",
    endpoint: new Uri("https://api.deepseek.com")  // 关键!改端点
);

6.2 用阿里云通义千问

csharp 复制代码
builder.AddOpenAIChatCompletion(
    modelId: "qwen-turbo",
    apiKey: "你的阿里云Key",
    endpoint: new Uri("https://dashscope.aliyuncs.com/compatible-mode/v1")
);

6.3 用Azure OpenAI(企业首选)

csharp 复制代码
builder.AddAzureOpenAIChatCompletion(
    deploymentName: "gpt-4",  // 你的部署名
    endpoint: "https://你的资源名.openai.azure.com/",
    apiKey: "你的Azure Key"
);

Semantic Kernel的好处就是:换模型只需要改配置,业务代码完全不用动!

七、踩坑实录

7.1 网络问题

国内访问OpenAI API,十有八九会超时。解决方案:

  1. 用国内的大模型(DeepSeek、文心一言、通义千问)
  2. 用代理(自己想办法)
  3. 用Azure OpenAI(微软在国内有节点)

7.2 Token计算

每次调用都要花钱,得心里有数:

csharp 复制代码
var response = await chatService.GetChatMessageContentAsync(history);

// 查看用了多少token
if (response.Metadata?.TryGetValue("Usage", out var usage) == true)
{
    Console.WriteLine($"Prompt tokens: {usage.PromptTokens}");
    Console.WriteLine($"Completion tokens: {usage.CompletionTokens}");
    Console.WriteLine($"Total tokens: {usage.TotalTokens}");
}

GPT-4o-mini的价格是:输入0.15美元/百万token,输出0.6美元/百万token。便宜得很!

7.3 超时设置

默认超时可能不够,特别是生成长文本的时候:

csharp 复制代码
var httpClient = new HttpClient { Timeout = TimeSpan.FromMinutes(5) };

var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion(
    modelId: "gpt-4o-mini",
    apiKey: apiKey,
    httpClient: httpClient  // 传进去
);

八、完整实战:做个智能客服

来,把上面的知识点串起来,写个完整的例子:

csharp 复制代码
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;

class Program
{
    static async Task Main(string[] args)
    {
        // 1. 初始化Kernel
        var builder = Kernel.CreateBuilder();
        builder.AddOpenAIChatCompletion(
            modelId: "gpt-4o-mini",
            apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY")!
        );
        
        // 2. 注册业务插件
        builder.Plugins.AddFromType<OrderPlugin>();
        builder.Plugins.AddFromType<ProductPlugin>();
        
        var kernel = builder.Build();
        var chatService = kernel.GetRequiredService<IChatCompletionService>();
        
        // 3. 设置系统人设
        var history = new ChatHistory();
        history.AddSystemMessage("""
            你是某电商平台的智能客服,名字叫"小智"。
            你的职责是:
            1. 回答用户关于商品的咨询
            2. 帮用户查询订单状态
            3. 处理退换货申请
            
            说话要亲切自然,多用表情符号😊
            遇到不懂的问题,诚实告诉用户你会转接人工客服
        """);
        
        // 4. 配置工具调用
        var settings = new OpenAIPromptExecutionSettings
        {
            ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
        };
        
        // 5. 开始对话
        Console.WriteLine("小智:您好!我是智能客服小智,有什么可以帮您的吗?😊");
        
        while (true)
        {
            Console.Write("\n用户:");
            var input = Console.ReadLine();
            if (string.IsNullOrWhiteSpace(input)) continue;
            if (input.ToLower() == "exit") break;
            
            history.AddUserMessage(input);
            
            var response = await chatService.GetChatMessageContentAsync(
                history, 
                settings, 
                kernel
            );
            
            Console.WriteLine($"\n小智:{response.Content}");
            history.AddAssistantMessage(response.Content!);
        }
    }
}

// 订单查询插件
public class OrderPlugin
{
    [KernelFunction("query_order")]
    [Description("根据订单号查询订单状态")]
    public string QueryOrder(
        [Description("订单号,格式为ORD开头的一串数字")] string orderId)
    {
        // 实际项目中查数据库
        var mockData = new Dictionary<string, string>
        {
            ["ORD12345"] = "订单状态:已发货,预计明天送达📦",
            ["ORD67890"] = "订单状态:处理中,正在打包..."
        };
        
        return mockData.GetValueOrDefault(orderId, "未找到该订单,请检查订单号");
    }
}

// 商品查询插件
public class ProductPlugin
{
    [KernelFunction("search_product")]
    [Description("根据关键词搜索商品")]
    public string SearchProduct(
        [Description("搜索关键词,比如'手机'、'耳机'")] string keyword)
    {
        // 实际项目中查ES或数据库
        if (keyword.Contains("手机"))
            return "为您找到以下手机:\n1. iPhone 15 Pro - ¥7999\n2. 小米14 - ¥3999";
        
        return $"抱歉,暂时没有与'{keyword}'相关的商品";
    }
}

运行效果:

复制代码
小智:您好!我是智能客服小智,有什么可以帮您的吗?😊

用户:我想查一下订单ORD12345
小智:好的,我帮您查一下...🔍

[插件被调用] query_order: ORD12345

小智:您的订单状态:已发货,预计明天送达📦

用户:你们有什么手机推荐
小智:为您找到以下手机:
1. iPhone 15 Pro - ¥7999
2. 小米14 - ¥3999

看到没?AI自动识别了用户的意图,调用了对应的插件!这就是Agent的雏形啊兄弟们!

九、写在最后

说实话,写这篇文章的时候,我挺感慨的。

22年前我开始搞AI的时候,哪有这么方便的API啊。那时候写个神经网络,C++代码几千行,调参调到头秃...

现在呢?几行C#代码就能跟GPT-4对话,还能让它帮你干活。技术的进步真的太快了!

但我也发现一个问题:很多.NET开发者还在观望,觉得AI是Python的天下。这想法得改改了!

微软在AI这块的布局很深,Semantic Kernel、ML.NET、ONNX Runtime...全是给.NET开发者准备的武器。咱们不能守着金山要饭吃啊!

最后送大家一句话:

别问能不能做,问就是能做。C#调大模型,稳得一批!

有啥问题评论区见,我看到都会回。咱们一起进步!


P.S. 目前国内还是很缺AI人才的,希望更多人能真正加入到AI行业,共同促进行业进步,增强我国的AI竞争力。想要系统学习AI知识的朋友可以看看我精心打磨的教程 [http://blog.csdn.net/jiangjunshow\],(http://blog.csdn.net/jiangjunshow/article/details/77338485)教程通俗易懂,高中生都能看懂,还有各种段子风趣幽默,从深度学习基础原理到各领域实战应用都有讲解,我22年的AI积累全在里面了。注意,教程仅限真正想入门AI的朋友,否则看看零散的博文就够了。

相关推荐
陈老老老板1 小时前
Bright Data Web Scraper 实战:构建 eBay Web Scraping 自动化 Skill(2026)
大数据·人工智能·自动化
霍小毛2 小时前
轻量黑科技!数字孪生重构智慧城乡供水一体化新范式
人工智能
如此风景2 小时前
Playwright 速查表
人工智能
草青工作室2 小时前
AI主流大模型参数量和收费情况参考(26年4月)
人工智能
Y敲键盘的地方2 小时前
第1章:从命令行到智能体
人工智能
雷工笔记2 小时前
读书笔记|《AI知识库:个人与企业的智慧玩法》
人工智能
李可以量化2 小时前
【2026 量化工具选型】通达信 TdxQuant vs 迅投 QMT/miniQMT 深度对比:新手该怎么选?
大数据·人工智能·区块链·通达信·qmt·量化 qmt ptrade
互联科技报2 小时前
零售数字化:高准确率客流分析系统优质推荐
大数据·人工智能
互联科技报2 小时前
成熟零售客流系统该怎么选?决定门店效率的关键选择
人工智能·零售