文章目录
-
-
- 开篇:当C#程序员遇上"人工智能+"
- 套路一:别把AI当黑盒,要像拼乐高一样玩插件
-
- 场景痛点:AI总是"胡说八道"怎么办?
- [核心思路:插件化架构(Plugin Architecture)](#核心思路:插件化架构(Plugin Architecture))
- 实战代码:订单查询插件
- 避坑指南
- 套路二:复杂任务拆解,用多Agent协作搞定
-
- 场景痛点:一个AI搞不定复杂任务怎么办?
- [核心思路:多Agent架构(Multi-Agent Architecture)](#核心思路:多Agent架构(Multi-Agent Architecture))
- 实战代码:多Agent协作示例
- 生产环境建议
- 套路三:给AI装上记忆,打造有上下文的智能体
-
- 场景痛点:AI记不住之前的对话怎么办?
- [核心思路:记忆体系(Memory System)](#核心思路:记忆体系(Memory System))
- 实战代码:带记忆的客服Agent
- 生产环境建议
- 写在最后:C#开发者的AI时代生存指南
-
目前国内还是很缺AI人才的,希望更多人能真正加入到AI行业,共同促进行业进步,增强我国的AI竞争力。想要系统学习AI知识的朋友可以看看我精心打磨的教程 http://blog.csdn.net/jiangjunshow,教程通俗易懂,高中生都能看懂,还有各种段子风趣幽默,从深度学习基础原理到各领域实战应用都有讲解,我22年的AI积累全在里面了。注意,教程仅限真正想入门AI的朋友,否则看看零散的博文就够了。
开篇:当C#程序员遇上"人工智能+"
今年的政府工作报告里,"人工智能+"被正式写入,这意味着啥?简单来说,就是国家层面开始把AI当成水电煤一样的基础设施来推了。就像当年"互联网+"让每个公司都得有个网站一样,接下来几年,每个企业都得有自己的AI Agent。
但问题是,很多C#开发者看着Python那边LangChain玩得飞起,心里直痒痒:咱们.NET生态有没有能打的?答案是肯定的------Semantic Kernel(简称SK),这是微软亲儿子,完全开源,C#原生支持,而且设计理念比LangChain更适合企业级应用。
今天这篇不搞虚的,直接上三个从实战中总结出来的套路,手把手教你用C#搭建能在生产环境跑的企业级Agent。
套路一:别把AI当黑盒,要像拼乐高一样玩插件
场景痛点:AI总是"胡说八道"怎么办?
很多企业第一次接大模型API,最大的 shock 就是发现这玩意儿有时候会一本正经地瞎编。比如让它查订单状态,它可能直接给你编一个订单号出来。这就是典型的**"黑盒"问题**------你把所有逻辑都扔给大模型,它就只能靠幻觉硬撑。
核心思路:插件化架构(Plugin Architecture)
Semantic Kernel的解决思路特别像拼乐高。你把AI的能力拆成一个个小插件(Plugin),每个插件负责一个具体功能:查数据库的专门查数据库,发邮件的专门发邮件,大模型只负责决定什么时候调用哪个插件。
这就像餐厅里的服务员(大模型)不需要亲自炒菜(执行业务逻辑),只需要把菜单(用户请求)传给后厨(插件),然后端菜(返回结果)就行了。
实战代码:订单查询插件
csharp
using Microsoft.SemanticKernel;
using System.ComponentModel;
// 第一步:定义插件,就像写一个普通的C#类
public class OrderPlugin
{
private readonly IOrderService _orderService;
public OrderPlugin(IOrderService orderService)
{
_orderService = orderService;
}
// 这个特性告诉SK:这是一个可以被AI调用的函数
[KernelFunction("get_order_status")]
[Description("根据订单号查询订单状态,返回订单详情")]
public async Task<string> GetOrderStatusAsync(
[Description("订单号,格式为ORD-开头")] string orderId)
{
// 这里接你的真实业务逻辑
var order = await _orderService.GetOrderAsync(orderId);
if (order == null)
return "未找到该订单,请检查订单号是否正确";
return $"订单状态:{order.Status},预计送达:{order.EstimatedDelivery}";
}
[KernelFunction("cancel_order")]
[Description("取消指定订单")]
public async Task<string> CancelOrderAsync(
[Description("要取消的订单号")] string orderId,
[Description("取消原因")] string reason)
{
var result = await _orderService.CancelAsync(orderId, reason);
return result ? "取消成功" : "取消失败,该订单可能已发货";
}
}
// 第二步:注册并使用
public async Task RunAgentAsync()
{
var builder = Kernel.CreateBuilder();
// 接入Azure OpenAI或其他支持OpenAI格式的服务
builder.AddAzureOpenAIChatCompletion(
deploymentName: "gpt-4",
endpoint: "https://your-resource.openai.azure.com/",
apiKey: "your-api-key");
// 注册插件,支持依赖注入
builder.Services.AddSingleton<IOrderService, OrderService>();
builder.Plugins.AddFromType<OrderPlugin>();
var kernel = builder.Build();
// 开启自动函数调用
var settings = new OpenAIPromptExecutionSettings
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};
var result = await kernel.InvokePromptAsync(
"帮我查一下订单ORD-20250312的状态,如果还没发货就取消它,原因是买错了",
new KernelArguments(settings));
Console.WriteLine(result);
}
避坑指南
- Description必须写清楚:SK靠描述来让AI理解什么时候该调用哪个函数,描述模糊就像菜单上只写"菜",服务员根本不知道该上什么。
- 函数参数要明确:每个参数都要加Description,告诉AI这个参数是干嘛的、格式是什么。
- 返回值要标准化:插件返回的结果最好是结构化的字符串或JSON,方便AI理解和整合。
- 异常要捕获:插件内部要处理好异常,不要让错误直接抛给AI,否则会导致整个Agent崩溃。
套路二:复杂任务拆解,用多Agent协作搞定
场景痛点:一个AI搞不定复杂任务怎么办?
当用户的请求需要跨多个领域、多个系统时,单个大模型很容易顾此失彼。比如"帮我分析上个月的销售数据,然后生成一份报告并发送给销售总监",这个任务涉及数据分析、报告生成、邮件发送三个子任务,一个Agent很难同时做好。
核心思路:多Agent架构(Multi-Agent Architecture)
Semantic Kernel支持创建多个专用Agent,每个Agent负责一个领域:
- 数据Agent:负责查询数据库、分析数据
- 报告Agent:负责生成结构化报告
- 通信Agent:负责发送邮件、通知
然后用一个**主Agent(Orchestrator)**来统筹协调,把复杂任务拆解成子任务,分配给对应的专用Agent,最后整合结果返回给用户。
实战代码:多Agent协作示例
csharp
// 定义专用Agent接口
public interface IDataAgent
{
Task<string> AnalyzeSalesDataAsync(DateTime startDate, DateTime endDate);
}
public interface IReportAgent
{
Task<string> GenerateReportAsync(string dataAnalysis);
}
public interface ICommunicationAgent
{
Task<string> SendEmailAsync(string to, string subject, string body);
}
// 主Agent统筹
public class OrchestratorAgent
{
private readonly IDataAgent _dataAgent;
private readonly IReportAgent _reportAgent;
private readonly ICommunicationAgent _communicationAgent;
private readonly Kernel _kernel;
public OrchestratorAgent(IDataAgent dataAgent, IReportAgent reportAgent, ICommunicationAgent communicationAgent, Kernel kernel)
{
_dataAgent = dataAgent;
_reportAgent = reportAgent;
_communicationAgent = communicationAgent;
_kernel = kernel;
}
public async Task<string> ExecuteComplexTaskAsync(string userRequest)
{
// 第一步:主Agent理解用户需求,拆解任务
var taskDecomposition = await _kernel.InvokePromptAsync(
$"请将以下用户请求拆解为具体的子任务:{userRequest}");
// 第二步:调用数据Agent分析数据
var dataAnalysis = await _dataAgent.AnalyzeSalesDataAsync(DateTime.Now.AddMonths(-1), DateTime.Now);
// 第三步:调用报告Agent生成报告
var report = await _reportAgent.GenerateReportAsync(dataAnalysis);
// 第四步:调用通信Agent发送邮件
var sendResult = await _communicationAgent.SendEmailAsync("sales-director@company.com", "上月销售报告", report);
// 第五步:整合结果返回
return $"任务完成:{sendResult}\n报告内容:\n{report}";
}
}
生产环境建议
- Agent职责单一化:每个Agent只负责一件事,就像专业的员工一样,术业有专攻。
- 通信标准化:Agent之间的通信要使用统一的格式(如JSON),方便数据传递和解析。
- 错误重试机制:子任务失败时,主Agent要能自动重试或切换到备用方案。
- 监控与日志:每个Agent的执行过程都要记录日志,方便排查问题。
套路三:给AI装上记忆,打造有上下文的智能体
场景痛点:AI记不住之前的对话怎么办?
用户和AI对话时,经常会提到之前的内容,比如"刚才说的那个订单,再帮我查一下物流"。如果AI没有记忆,就会一脸茫然,不知道"那个订单"指的是什么。
核心思路:记忆体系(Memory System)
Semantic Kernel内置了强大的记忆功能,分为两种:
- 短期记忆(Short-Term Memory):保存最近的对话历史,让AI理解上下文
- 长期记忆(Long-Term Memory):保存企业知识库、用户信息等,让AI可以随时检索
实战代码:带记忆的客服Agent
csharp
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Memory;
using Microsoft.SemanticKernel.Connectors.OpenAI;
public class CustomerServiceAgent
{
private readonly Kernel _kernel;
private readonly ISemanticTextMemory _memory;
private readonly ChatHistory _chatHistory;
public CustomerServiceAgent(Kernel kernel, ISemanticTextMemory memory)
{
_kernel = kernel;
_memory = memory;
_chatHistory = new ChatHistory();
// 初始化系统提示
_chatHistory.AddSystemMessage("你是企业智能客服,回答问题时请注意:\n1. 优先使用提供的背景知识\n2. 如果用户问的是之前聊过的内容,结合上下文回答\n3. 涉及价格时,必须确认用户的公司规模和具体需求");
}
public async Task StartConversationAsync()
{
// 先导入知识库
await ImportKnowledgeBaseAsync(_memory);
Console.WriteLine("客服AI已启动,输入'exit'退出");
// 开始对话循环
while (true)
{
Console.Write("用户:");
var input = Console.ReadLine();
if (input == "exit") break;
// RAG检索:先查向量数据库找相关资料
var memories = _memory.SearchAsync("product-docs", input, limit: 3, minRelevanceScore: 0.7);
var contextBuilder = new StringBuilder();
await foreach (var m in memories)
{
contextBuilder.AppendLine($"相关文档:{m.Metadata.Text}");
}
// 把检索到的上下文注入Prompt
var prompt = $"""
背景知识:
{contextBuilder}
用户问题:{input}
请基于背景知识回答。如果背景知识不足,请明确告知。
""";
_chatHistory.AddUserMessage(prompt);
// 调用AI(自动包含历史对话)
var response = await _kernel.GetRequiredService<IChatCompletionService>()
.GetChatMessageContentAsync(_chatHistory);
Console.WriteLine($"AI:{response.Content}");
_chatHistory.AddAssistantMessage(response.Content!);
}
}
// 导入知识库的方法
private async Task ImportKnowledgeBaseAsync(ISemanticTextMemory memory)
{
// 模拟从文件或数据库读取产品文档
var documents = new[]
{
("doc1", "企业版支持无限用户,年费10万元起,包含专属客户经理"),
("doc2", "专业版最多支持100人,年费3万元,支持API接入"),
("doc3", "免费版仅供个人使用,限制5个项目的存储空间"),
// ... 更多文档
};
foreach (var (id, text) in documents)
{
// 自动生成向量并存储
await memory.SaveInformationAsync(
collection: "product-docs", // 集合名,相当于数据库的表
id: id,
text: text,
description: "产品定价与功能说明"
);
}
Console.WriteLine("知识库导入完成");
}
}
生产环境建议
- 向量数据库选型:开发阶段用VolatileMemoryStore(内存存储)没问题,但生产环境强烈建议用Azure AI Search、Qdrant或Redis。SQL Server 2025版本也开始支持向量存储了,如果你本来就在用SQL Server,可以考虑统一技术栈。
- 记忆裁剪:对话历史不能无限增长,否则Token消耗爆炸。可以用Summarization技术,每10轮对话总结一次,把精华保留下来,细节扔掉。
- 权限隔离:企业级应用必须做好数据隔离,A部门的人不能查到B部门的文档。Semantic Kernel支持在检索时加Tag过滤,确保向量查询带权限参数。
写在最后:C#开发者的AI时代生存指南
写这篇文章的时候,我翻了一下GitHub上Semantic Kernel的Release记录,发现微软几乎每周都在发新版本,1.0之后的API稳定性已经相当不错了。相比Python那边LangChain的"祖传代码半年必挂",SK的向后兼容做得相当良心。
三个套路总结一下:
- 插件化解决的是AI"乱说话"的问题,让专业的人干专业的事;
- 多Agent解决的是复杂任务拆解问题,避免单点瓶颈;
- 记忆体系解决的是上下文连贯性问题,让AI有"人味"。
今年的"人工智能+"风口,对C#开发者来说其实是利好------企业级市场本来就是.NET的主战场,而Semantic Kernel的设计理念(强类型、依赖注入、插件化)完全契合.NET程序员的思维习惯。
别再观望了,找个小需求把这三个套路跑一遍,你就是公司里最早一批能吃上AI红利的人。代码我都测过了,直接复制粘贴改改配置就能跑,有问题欢迎评论区留言讨论。
毕竟,站在风口上,猪都能飞;但前提是,你得先站到风口上去。
目前国内还是很缺AI人才的,希望更多人能真正加入到AI行业,共同促进行业进步,增强我国的AI竞争力。想要系统学习AI知识的朋友可以看看我精心打磨的教程 http://blog.csdn.net/jiangjunshow,教程通俗易懂,高中生都能看懂,还有各种段子风趣幽默,从深度学习基础原理到各领域实战应用都有讲解,我22年的AI积累全在里面了。注意,教程仅限真正想入门AI的朋友,否则看看零散的博文就够了。
