【C#程序员入门AI】C#程序员必学的结构化提示与函数调用(Function Calling)
/ 实体类set;set;set;// 业务工具类,模型要调用的函数都在这// 查用户信息// 模拟数据库查询,实际替换成EF Core/SqlSugar查询new User { Id = 1, Name = "张三", Dept = "技术部" },new User { Id = 2, Name = "李四", Dept = "产品部" }// 算用户订单总额// 模拟订单查询1 => 6398
文章目录
目前国内还是很缺AI人才的,希望更多人能真正加入到AI行业,共同促进行业进步。想要系统学习AI知识的朋友可以看看我的教程http://blog.csdn.net/jiangjunshow,教程通俗易懂,风趣幽默,从深度学习基础原理到各领域实战应用都有讲解。
本文章限时免费,整个专栏写完后将转为收费专栏,请勿转载
🚀 开篇唠唠嗑
各位C#老铁们,是不是还在瞎写提示词啊?😮💨
随便敲一句“帮我写段C#代码”,模型要么答非所问,要么生成的代码根本没法用;想让模型调用自己写的函数查数据、算结果,更是半天调不通,光踩坑就耗大半天!
其实啊,根本不是模型不给力,是你没找对方法~2026年了,玩好大模型的核心早就不是凑字数写提示词了,而是结构化提示+Function Calling,这俩可是咱们C#程序员的专属buff!🤩
今天就把压箱底的干货全掏出来,纯大白话讲透,还带最新的C#实战代码,学完你就能让大模型乖乖听话,写代码、调函数、做分析,指哪打哪,效率直接翻十倍~
一、先整明白:为啥结构化提示是YYDS?
咱先说说为啥以前的“大白话提示词”不行哈~大模型就像个聪明但粗心的实习生🧑💻,你跟它说“帮我弄弄这个C#逻辑”,它根本摸不清你的需求;但你要是把需求拆得明明白白,它立马就能给你精准输出!
1. 结构化提示是啥?说白了就是“按模板给指令”
不再是一大段乱糟糟的话,而是用固定格式、清晰分隔符、明确要素把需求写清楚,让模型一眼就能看懂要干啥、按啥标准干、输出啥样的结果,2026年大厂全这么玩,稳定性拉满~
2. 好的结构化提示,就含这5个核心要素(少一个都不行)
咱C#程序员写代码讲究规范,写提示词也一个理儿,这5要素记死,随便写都不踩坑:
- 角色设定:告诉模型“你是谁”,比如“你是10年资深C#/.NET架构师,精通ASP.NET Core和大模型函数调用”,对齐专业度~
- 核心指令:一句话说清干啥,别含糊,比如“帮我写一个C#单例模式的线程安全实现代码”,不是“帮我写单例代码”~
- 上下文/约束:给必要背景,加限制条件,比如“要求兼容.NET 9,禁止使用懒加载,必须加双重校验锁”~
- 输入数据:把要处理的内容标清楚,用```或—包起来,模型更易识别~
- 输出格式:明确要啥样的结果,比如“输出Markdown格式,含代码+注释+使用示例”~
3. 对比才知道香:大白话VS结构化提示
❌ 大白话提示:帮我写个C#查用户的代码
✅ 结构化提示:
角色:你是资深C#后端开发,精通EF Core 8
指令:写一个根据用户ID查询用户信息的C#方法
约束:兼容.NET 9,使用EF Core查询,做空值校验,返回Task
输入:无
输出:代码+详细注释,Markdown格式
你看,差距一下就出来了吧~结构化提示的输出,精准度、专业度直接拉满,根本不用反复改!
4. 2026年最新小技巧:用XML/分隔符做“内容隔离”
这可是OpenAI、Anthropic官方最新推荐的~把不同要素用、或者—、>>>包起来,模型解析起来更精准,完全不会混淆内容,咱C#程序员写惯了标签,这个一看就会~
举个栗子🌰:
<role>10年C#开发,精通Semantic Kernel</role>
<instruction>解析以下C#代码,找出性能问题</instruction>
<constraint>只说性能问题,给出优化方案,不扯其他</constraint>
<code>
// 待解析代码
public List<User> GetAllUsers() {
var list = new List<User>();
foreach(var u in db.Users) { list.Add(u); }
return list;
}
</code>
<output>列表形式,分问题+方案</output>
二、Function Calling:让大模型有“手”干活,不再光嘴炮
讲完结构化提示,咱再聊更硬核的Function Calling~说白了啊,这玩意就是让大模型能调用咱们写的C#函数/方法,不再只是单纯聊天、写代码,而是能真真切切帮你查数据库、调API、算结果,2026年做AI应用,没这能力根本玩不转~😎
1. 为啥C#程序员必须学Function Calling?
咱平时做的都是工程化开发,不是纯玩模型~用户问“查一下用户1的订单总额”,模型自己算不出来,但它能判断“需要调用GetUserOrderSum(int userId)这个函数”,然后咱的C#代码执行这个函数,把结果返给模型,模型再整理成自然语言回答用户,这才是真正的“智能应用”啊~
没有Function Calling,大模型就是个“纸上谈兵的书生”;有了它,才是能干活的“数字员工”!
2. Function Calling核心流程:就6步,超简单
咱C#程序员讲究流程化,这6步记下来,闭着眼都能实现,2026年最新的工程化流程,一点不绕:
- 定义C#函数:写好要让模型调用的方法,比如查用户、算金额、调API~
- 做函数描述:按JSON Schema写清楚函数名、功能、参数(类型、是否必传),这是模型能识别的“说明书”~
- 结构化提示模型:告诉模型“你可以调用这些函数,符合条件就调用”~
- 模型判断:模型根据用户问题,决定是否调用、调用哪个、传啥参数~
- C#解析执行:解析模型返回的调用指令,执行对应的C#函数,拿到结果~
- 结果回传总结:把函数执行结果返给模型,模型整理成自然语言回复用户~
一句话总结:模型做决策,C#做执行,分工明确,效率拉满~
3. 避坑指南:2026年大厂踩过的6个坑,咱别踩
过来人告诉你,Function Calling看着简单,实际落地全是坑,这6个坑是2026年最新的工程化总结,记死了少走弯路~🚫
- 坑1:函数描述写太模糊→模型瞎传参,解决方案:参数加详细描述,必传字段标死,加
additionalProperties: false做校验~ - 坑2:循环调用停不下来→查用户→查订单→查商品…无限套娃,解决方案:加最大调用深度限制,比如最多3层~
- 坑3:函数执行超时→模型干等,解决方案:C#里用异步+超时控制,超时直接返回异常~
- 坑4:返回结果太长→Token爆炸,解决方案:对结果做摘要,只传核心数据~
- 坑5:并发重复调用→比如重复下单,解决方案:加幂等键,一个请求只执行一次~
- 坑6:敏感信息泄露→模型把数据库密码返给用户,解决方案:C#代理层做字段屏蔽,绝不返敏感数据~
三、纯实战:2026最新C#代码,手把手实现结构化提示+Function Calling
咱C#程序员最烦光说不练,这部分直接上硬菜~用Azure OpenAI GPT-4o(2026主流)+原生C#实现,不用复杂框架,零基础也能跑通,复制粘贴就能用,超省心~😜
准备工作(2分钟搞定)
- 安装NuGet包(2026最新版):
Install-Package Azure.AI.OpenAI # 官方最新SDK,稳定不踩坑
Install-Package Newtonsoft.Json # 解析JSON用
- 获取Azure OpenAI的Endpoint、API Key、部署名(gpt-4o),替换代码里的配置就行~
步骤1:定义C#业务函数(模型要调用的“工具”)
咱写两个最常用的,查用户信息+算订单总额,实际开发直接替换成你的业务逻辑就行:
// 实体类
public class User
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Dept { get; set; } = string.Empty;
}
// 业务工具类,模型要调用的函数都在这
public static class BusinessTools
{
// 查用户信息
public static User? GetUserInfo(int userId)
{
// 模拟数据库查询,实际替换成EF Core/SqlSugar查询
var users = new List<User>
{
new User { Id = 1, Name = "张三", Dept = "技术部" },
new User { Id = 2, Name = "李四", Dept = "产品部" }
};
return users.FirstOrDefault(u => u.Id == userId);
}
// 算用户订单总额
public static decimal GetOrderTotal(int userId)
{
// 模拟订单查询
return userId switch
{
1 => 6398.00m, // 笔记本5999+键盘399
2 => 1299.00m, // 显示器1299
_ => 0.00m
};
}
}
步骤2:定义函数描述(模型的“说明书”,JSON Schema格式)
这是核心!必须按规范写,模型才能识别,2026年最新的Schema规范,直接抄:
// 函数描述列表,可加多个函数
private static readonly List<FunctionDefinition> _functions = new()
{
// 查用户信息的函数描述
new FunctionDefinition
{
Name = "GetUserInfo",
Description = "根据用户ID查询用户的姓名、部门信息,用户问个人信息时调用",
Parameters = BinaryData.FromObjectAsJson(new
{
Type = "object",
Properties = new
{
userId = new
{
Type = "int",
Description = "用户的唯一ID,数字类型,比如1、2"
}
},
Required = new[] { "userId" }, // 必传参数
AdditionalProperties = false // 禁止传额外参数,防瞎传
})
},
// 算订单总额的函数描述
new FunctionDefinition
{
Name = "GetOrderTotal",
Description = "根据用户ID计算该用户的所有订单总金额,用户问订单金额、消费总额时调用",
Parameters = BinaryData.FromObjectAsJson(new
{
Type = "object",
Properties = new
{
userId = new
{
Type = "int",
Description = "用户的唯一ID,数字类型,比如1、2"
}
},
Required = new[] { "userId" },
AdditionalProperties = false
})
}
};
步骤3:核心逻辑:结构化提示+Function Calling全流程
这部分是主程序,把前面的都串起来,注释写得明明白白,咱直接看代码:
using Azure.AI.OpenAI;
using Newtonsoft.Json;
using System.ClientModel;
class Program
{
// 替换成你的Azure OpenAI配置
private const string _endpoint = "https://你的地址.openai.azure.com/";
private const string _apiKey = "你的API Key";
private const string _deploymentName = "gpt-4o";
static async Task Main(string[] args)
{
Console.WriteLine("🚀 C# 结构化提示+Function Calling 实战");
Console.WriteLine("=====================================\n");
// 1. 初始化OpenAI客户端
var client = new OpenAIClient(new Uri(_endpoint), new ApiKeyCredential(_apiKey));
var chatCompletionsOptions = new ChatCompletionsOptions
{
DeploymentName = _deploymentName,
Temperature = 0.1f, // 降低随机性,决策更精准
MaxTokens = 4096,
Functions = _functions, // 传入函数描述
ToolCallBehavior = ToolCallBehavior.AutoInvokeFunctions // 让模型自动判断是否调用函数
};
// 2. 结构化系统提示:给模型定规则、设角色(2026最新模板)
chatCompletionsOptions.Messages.Add(new ChatMessage(
ChatRole.System,
@"<role>你是资深C#后端AI助手,精通调用C#函数处理业务问题</role>
<rule>1. 能回答的直接回答,不能回答的判断是否调用函数,不瞎编答案
2. 调用函数时严格按参数要求传值,只传userId,不传其他参数
3. 函数执行结果返回后,用自然语言整理回答,简洁明了</rule>
<output>回答用口语化的中文,不用专业术语,让用户一眼看懂</output>"
));
// 3. 用户提问(可替换成任意问题,比如“查一下用户1的信息”“算用户2的订单总额”)
Console.Write("用户:");
var userInput = Console.ReadLine()?.Trim() ?? string.Empty;
chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.User, userInput));
try
{
// 4. 调用GPT-4o,获取响应
var response = await client.GetChatCompletionsAsync(chatCompletionsOptions);
var chatResponse = response.Value.Choices[0].Message;
chatCompletionsOptions.Messages.Add(chatResponse); // 把模型响应加入对话历史
// 5. 判断模型是否要调用函数
if (chatResponse.ToolCalls != null && chatResponse.ToolCalls.Any())
{
Console.WriteLine("\n🤖 模型判断:需要调用函数处理~");
foreach (var toolCall in chatResponse.ToolCalls)
{
// 解析函数名和参数
var functionName = toolCall.FunctionCall.Name;
var functionArgs = JsonConvert.DeserializeObject<dynamic>(toolCall.FunctionCall.Arguments);
int userId = (int)functionArgs.userId;
Console.WriteLine($"📞 调用函数:{functionName},参数:userId={userId}");
// 6. 执行对应的C#函数,获取结果
object? functionResult = functionName switch
{
"GetUserInfo" => BusinessTools.GetUserInfo(userId),
"GetOrderTotal" => BusinessTools.GetOrderTotal(userId),
_ => null
};
if (functionResult == null)
{
functionResult = "未查询到相关数据";
}
// 7. 把函数执行结果回传给模型
chatCompletionsOptions.Messages.Add(new ChatMessage(
ChatRole.Tool,
JsonConvert.SerializeObject(functionResult),
toolCall.FunctionCall.Name
));
}
// 8. 模型根据函数结果,生成最终自然语言回答
var finalResponse = await client.GetChatCompletionsAsync(chatCompletionsOptions);
var finalAnswer = finalResponse.Value.Choices[0].Message.Content;
Console.WriteLine($"\n🤖 AI回答:{finalAnswer}");
}
else
{
// 模型直接回答,无需调用函数
Console.WriteLine($"\n🤖 AI回答:{chatResponse.Content}");
}
}
catch (Exception ex)
{
Console.WriteLine($"\n❌ 出错啦:{ex.Message}");
}
Console.WriteLine("\n=====================================");
Console.ReadLine();
}
}
运行效果(实测截图级,超丝滑)
咱试两个最常用的问题,看看效果,真的超精准~
测试1:查询用户1的信息
🚀 C# 结构化提示+Function Calling 实战
=====================================
用户:查一下用户1的信息
🤖 模型判断:需要调用函数处理~
📞 调用函数:GetUserInfo,参数:userId=1
🤖 AI回答:用户1的名字是张三,在技术部工作哦~
=====================================
测试2:计算用户2的订单总额
🚀 C# 结构化提示+Function Calling 实战
=====================================
用户:算一下用户2的所有订单一共花了多少钱
🤖 模型判断:需要调用函数处理~
📞 调用函数:GetOrderTotal,参数:userId=2
🤖 AI回答:用户2的订单总额是1299.00元哈~
=====================================
你看,是不是超简单!复制粘贴代码,替换配置,直接跑通,模型乖乖调用函数,结果也超友好~
四、2026年进阶玩法:C#程序员专属,直接对接项目
学会了基础玩法,咱再聊聊2026年最新的进阶技巧,都是咱C#程序员能直接用到项目里的,落地性拉满~🚀
1. 对接Semantic Kernel:一键注册C#插件,不用手动解析函数
咱之前写的是原生实现,实际开发用Semantic Kernel 1.0.0-rc1(2026最新版)更省心,给C#方法加[KernelFunction]和[Description]注解,就能一键注册成模型可调用的插件,自动生成函数描述,不用手写JSON Schema,省大功夫~
2. 多函数组合调用:处理复杂业务
比如用户问“查用户1的信息并算他的订单总额”,让模型一次性调用两个函数,C#里批量执行,结果统一回传,模型统一总结,搞定复杂业务场景,这才是真正的工程化应用~
3. 对接本地模型:Ollama+Llama 3,离线也能玩
2026年本地模型超成熟了,用Ollama部署Llama 3,C#通过OpenAI兼容接口调用,不用连外网,数据更安全,内网项目直接用,函数调用逻辑完全不变,只需要改配置~
4. 集成到ASP.NET Core:做AI接口服务
把这套逻辑封装成ASP.NET Core Web API,对接前端、小程序、企业微信,做成通用的AI服务接口,全公司都能用,咱C#程序员的优势直接拉满~
五、总结:一句话记死,C#程序员玩好大模型的核心
2026年提示词工程+Function Calling的核心,就八个字:结构定规则,函数做执行~
- 结构化提示:让大模型“懂规矩”,按你的要求精准输出,不瞎编、不跑偏~
- Function Calling:让大模型“有手脚”,调用咱的C#函数干实际业务,从“聊天工具”变成“干活的数字员工”~
咱C#程序员本来就有工程化、强类型的优势,只要把这俩知识点吃透,玩好大模型比其他语言的程序员更有优势,轻松做出落地的AI应用~
💬 互动一下
你平时做C#开发,最想让大模型调用啥业务函数啊?😜
是查数据库、调第三方API,还是做代码生成/审查?评论区留言,下期直接出对应的实战代码,抄作业就行~
目前国内还是很缺AI人才的,希望更多人能真正加入到AI行业,共同促进行业进步。想要系统学习AI知识的朋友可以看看我的教程http://blog.csdn.net/jiangjunshow,教程通俗易懂,风趣幽默,从深度学习基础原理到各领域实战应用都有讲解。

更多推荐



所有评论(0)