基础使用
https://siliconflow.cn/网站有些免费的大模型可以使用,去注册个账户,拿到apikey
引用 nuget
Microsoft.Extensions.AI.OpenAI
using Microsoft.Extensions.AI;
using OpenAI;
using System.ClientModel;
namespace ConsoleApp2
{
internal class Program
{
static async Task Main(string[] args)
{
OpenAIClientOptions openAIClientOptions = new OpenAIClientOptions();
openAIClientOptions.Endpoint = new Uri("https://api.siliconflow.cn/v1");
// SiliconCloud API Key
string mySiliconCloudAPIKey = "你的api key";
OpenAIClient client = new OpenAIClient(new ApiKeyCredential(mySiliconCloudAPIKey), openAIClientOptions);
IChatClient chatClient = client.AsChatClient("Qwen/Qwen2.5-7B-Instruct");
while (true)
{
var response = chatClient.CompleteStreamingAsync(Console.ReadLine());//手动输入问题
await foreach (var item in response)
{
Console.Write(item.Text);
}
Console.Write("\r\n\r\n");
}
}
}
}
给大模型额外提供函数能力
using OpenAI;
using OpenAI.Chat;
using System.ClientModel;
namespace ConsoleApp2
{
internal class Program
{
static async Task Main(string[] args)
{
OpenAIClientOptions openAIClientOptions = new OpenAIClientOptions();
openAIClientOptions.Endpoint = new Uri("https://api.siliconflow.cn/v1");
// SiliconCloud API Key
string mySiliconCloudAPIKey = "你的api key";
OpenAIClient client = new OpenAIClient(new ApiKeyCredential(mySiliconCloudAPIKey), openAIClientOptions);
var assistantClient = client.GetChatClient("Qwen/Qwen2.5-7B-Instruct");
await FunctionCallPlayground(assistantClient, "how is the weather today in beijing?");
Console.ReadKey();
}
private static async Task FunctionCallPlayground(ChatClient chatClient, string prompt)
{
Console.WriteLine(prompt);
var messages = new[]
{
new UserChatMessage( prompt)
};
BinaryData functionParameters = BinaryData.FromBytes("""
{
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The name of the city to query weather for."
}
},
"required": ["city"],
"additionalProperties": false
}
"""u8.ToArray());
var chatTool = ChatTool.CreateFunctionTool("get_weather", "Get the current weather for a given city.", functionParameters);
var options = new ChatCompletionOptions
{
Temperature = 0.01f,
TopP = 0.95f,
};
options.Tools.Add(chatTool);
var response = chatClient.CompleteChat(messages, options);
// 假设我们只处理第一个工具调用请求
var func1Name = response.Value.ToolCalls[0].FunctionName;
var func1Args = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string,string>>( response.Value.ToolCalls[0].FunctionArguments.ToString());
var func1Out = await GetWeather(func1Args["city"] );
options = new ChatCompletionOptions
{
Temperature = 0.01f,
TopP = 0.95f,
};
response = chatClient.CompleteChat(new ChatMessage[] { messages[0] , new ToolChatMessage(response.Value.ToolCalls[0].Id, func1Out) }, options);
Console.WriteLine(response.Value.Content.FirstOrDefault()?.Text);
}
private static async Task<string> GetWeather(string city)
{
return $"23摄氏度";
}
}
}
用Microsoft.Extensions.AI库实现
using Microsoft.Extensions.AI;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel;
namespace ConsoleApp2
{
internal class Program
{
const string APIKEY = "你的apikey";
static async Task Main(string[] args)
{
OpenAIClientOptions openAIClientOptions = new OpenAIClientOptions();
openAIClientOptions.Endpoint = new Uri("https://api.siliconflow.cn/v1");
// SiliconCloud API Key
string mySiliconCloudAPIKey = APIKEY;
var weathfunc = new GetWeatherFunction();
var humidtyfunc = new GetHumidityFunction();
ChatOptions chatOptions = new ChatOptions()
{
Temperature = 0.01f,
TopP = 0.95f,
Tools = new AIFunction[] { weathfunc, humidtyfunc }
};
OpenAIClient client = new OpenAIClient(new ApiKeyCredential(mySiliconCloudAPIKey), openAIClientOptions);
IChatClient chatClient = client.AsChatClient("Qwen/Qwen2.5-7B-Instruct");
while (true)
{
var question = Console.ReadLine();//手动输入问题
var response = await chatClient.CompleteAsync(question, chatOptions);
_check:
if(response.FinishReason == Microsoft.Extensions.AI.ChatFinishReason.ToolCalls)
{
List<AIContent> callRets = new List<AIContent>();
foreach( var aiContent in response.Choices[0].Contents)
{
if(aiContent is FunctionCallContent callContent)
{
var callid = callContent.CallId;
var func = (AIFunction)chatOptions.Tools.FirstOrDefault(m=>((AIFunction)m).Metadata.Name == callContent.Name);
var ret =await func!.InvokeAsync(callContent.Arguments);
callRets.Add(new FunctionResultContent(callid , callContent.Name , ret));
}
}
List<Microsoft.Extensions.AI.ChatMessage> list = new List<Microsoft.Extensions.AI.ChatMessage>();
list.Add(new Microsoft.Extensions.AI.ChatMessage(Microsoft.Extensions.AI.ChatRole.User, question));
list.Add(new Microsoft.Extensions.AI.ChatMessage(Microsoft.Extensions.AI.ChatRole.Tool, callRets));
response = await chatClient.CompleteAsync(list, chatOptions);
goto _check;
}
else
{
Console.WriteLine(response.Choices[0].Contents.FirstOrDefault()?.ToString());
}
Console.Write("\r\n");
}
}
}
public class GetWeatherFunction : AIFunction
{
Microsoft.Extensions.AI.AIFunctionMetadata _Metadata;
public override AIFunctionMetadata Metadata => _Metadata;
public GetWeatherFunction() {
_Metadata = new Microsoft.Extensions.AI.AIFunctionMetadata("get_weather")
{
Description = "Get the current weather for a given city.",
Parameters = new[] { new AIFunctionParameterMetadata("city") {
ParameterType = typeof(string),
Description = "The name of the city to query weather for.",
IsRequired = true,
} },
};
}
protected override async Task<object?> InvokeCoreAsync(IEnumerable<KeyValuePair<string, object?>> arguments, CancellationToken cancellationToken)
{
return $"23摄氏度";
}
}
public class GetHumidityFunction : AIFunction
{
Microsoft.Extensions.AI.AIFunctionMetadata _Metadata;
public override AIFunctionMetadata Metadata => _Metadata;
public GetHumidityFunction()
{
_Metadata = new Microsoft.Extensions.AI.AIFunctionMetadata("get_humidity")
{
Description = "获取指定城市的湿度",
Parameters = new[] { new AIFunctionParameterMetadata("city") {
ParameterType = typeof(string),
Description = "要获取湿度的城市名称",
IsRequired = true,
} },
};
}
protected override async Task<object?> InvokeCoreAsync(IEnumerable<KeyValuePair<string, object?>> arguments, CancellationToken cancellationToken)
{
return $"70%";
}
}
}
用json格式回答
通过设置ResponseFormat 为json,可以让大模型以json格式输出
上面代码修改为:
List<Microsoft.Extensions.AI.ChatMessage> list = new List<Microsoft.Extensions.AI.ChatMessage>();
list.Add(new Microsoft.Extensions.AI.ChatMessage(Microsoft.Extensions.AI.ChatRole.User, question));
list.Add(new Microsoft.Extensions.AI.ChatMessage(Microsoft.Extensions.AI.ChatRole.Tool, callRets));
ChatOptions chatOptions2 = new ChatOptions()
{
Temperature = 0.01f,
TopP = 0.95f,
MaxOutputTokens = int.MaxValue,
ResponseFormat = Microsoft.Extensions.AI.ChatResponseFormat.Json,
};
response = await chatClient.CompleteAsync(list, chatOptions2);
注意:如果你的提问需要调用你自己定义的函数去计算,那么,提问时不要设置ResponseFormat ,否则回答类型不会是FinishReason == Microsoft.Extensions.AI.ChatFinishReason.ToolCalls,也就无法触发你的程序去调用函数了,只有计算完结果后,回传结果给大模型时才设置 ResponseFormat = Microsoft.Extensions.AI.ChatResponseFormat.Json
提问需要这么提问:
北京现在的温度和湿度是多少?请用这种格式回答:[“温度值”,“湿度值”]