English | 简体中文
An unofficial DashScope SDK maintained by Cnblogs.
Warning: this project is under active development, Breaking Changes may introduced without notice or major version change. Make sure you read the Release Notes before upgrading.
Install Cnblogs.DashScope.AI Package
var client = new DashScopeClient("your-api-key").AsChatClient("qwen-max"); var completion = await client.CompleteAsync("hello"); Console.WriteLine(completion)Install Cnblogs.DashScope.Sdk package.
var client = new DashScopeClient("your-api-key"); var completion = await client.GetQWenCompletionAsync(QWenLlm.QWenMax, prompt); // or pass the model name string directly. // var completion = await client.GetQWenCompletionAsync("qwen-max", prompt); Console.WriteLine(completion.Output.Text);Install the Cnblogs.DashScope.AspNetCore package.
Program.cs
builder.AddDashScopeClient(builder.Configuration);appsettings.json
{ "DashScope": { "ApiKey": "your-api-key", } }Usage
public class YourService(IDashScopeClient client) { public async Task<string> CompletePromptAsync(string prompt) { var completion = await client.GetQWenCompletionAsync(QWenLlm.QWenMax, prompt); return completion.Output.Text; } }- Text Embedding API -
GetTextEmbeddingsAsync() - Text Generation API(qwen-turbo, qwen-max, etc.) -
GetQWenCompletionAsync()andGetQWenCompletionStreamAsync() - DeepSeek Models -
GetDeepSeekCompletionAsync()andGetDeepSeekCompletionStreamAsync() - BaiChuan Models - Use
GetBaiChuanTextCompletionAsync() - LLaMa2 Models -
GetLlama2TextCompletionAsync() - Multimodal Generation API(qwen-vl-max, etc.) -
GetQWenMultimodalCompletionAsync()andGetQWenMultimodalCompletionStreamAsync() - Wanx Models(Image generation, background generation, etc)
- Image Synthesis -
CreateWanxImageSynthesisTaskAsync()andGetWanxImageSynthesisTaskAsync() - Image Generation -
CreateWanxImageGenerationTaskAsync()andGetWanxImageGenerationTaskAsync() - Background Image Generation -
CreateWanxBackgroundGenerationTaskAsync()andGetWanxBackgroundGenerationTaskAsync()
- Image Synthesis -
- File API that used by Qwen-Long -
UploadFileAsync()andDeleteFileAsync - Application call -
GetApplicationResponseAsync()andGetApplicationResponseStreamAsync()
Visit snapshots for calling samples.
Visit tests for more usage of each api.
Use client.GetTextCompletionAsync and client.GetTextCompletionStreamAsync to access text generation api directly.
var completion = await dashScopeClient.GetTextCompletionAsync( new ModelRequest<TextGenerationInput, ITextGenerationParameters> { Model = "your-model-name", Input = new TextGenerationInput { Prompt = prompt }, Parameters = new TextGenerationParameters() { // control parameters as you wish. EnableSearch = true } }); var completions = dashScopeClient.GetTextCompletionStreamAsync( new ModelRequest<TextGenerationInput, ITextGenerationParameters> { Model = "your-model-name", Input = new TextGenerationInput { Messages = [TextChatMessage.System("you are a helpful assistant"), TextChatMessage.User("How are you?")] }, Parameters = new TextGenerationParameters() { // control parameters as you wish. EnableSearch = true, IncreamentalOutput = true } });var prompt = "hello" var completion = await client.GetQWenCompletionAsync(QWenLlm.QWenMax, prompt); Console.WriteLine(completion.Output.Text);var history = new List<ChatMessage> { ChatMessage.User("Please remember this number, 42"), ChatMessage.Assistant("I have remembered this number."), ChatMessage.User("What was the number I metioned before?") } var parameters = new TextGenerationParameters() { ResultFormat = ResultFormats.Message }; var completion = await client.GetQWenChatCompletionAsync(QWenLlm.QWenMax, history, parameters); Console.WriteLine(completion.Output.Choices[0].Message.Content); // The number is 42Use completion.Output.Choices![0].Message.ReasoningContent to access the thoughts from reasoning model.
var history = new List<ChatMessage> { ChatMessage.User("Calculate 1+1") }; var completion = await client.GetDeepSeekChatCompletionAsync(DeepSeekLlm.DeepSeekR1, history); Console.WriteLine(completion.Output.Choices[0]!.Message.ReasoningContent);Use TextGenerationParameters.EnableThinking to toggle reasoning.
var stream = dashScopeClient .GetQWenChatStreamAsync( QWenLlm.QWenPlusLatest, history, new TextGenerationParameters { IncrementalOutput = true, ResultFormat = ResultFormats.Message, EnableThinking = true });Creates a function with parameters
string GetCurrentWeather(GetCurrentWeatherParameters parameters) { // actual implementation should be different. return "Sunny, 14" + parameters.Unit switch { TemperatureUnit.Celsius => "℃", TemperatureUnit.Fahrenheit => "℉" }; } public record GetCurrentWeatherParameters( [property: Required] [property: Description("The city and state, e.g. San Francisco, CA")] string Location, [property: JsonConverter(typeof(EnumStringConverter<TemperatureUnit>))] TemperatureUnit Unit = TemperatureUnit.Celsius); public enum TemperatureUnit { Celsius, Fahrenheit }Append tool information to chat messages (Here we use JsonSchema.NET to generate JSON Schema).
var tools = new List<ToolDefinition>() { new( ToolTypes.Function, new FunctionDefinition( nameof(GetCurrentWeather), "Get the weather abount given location", new JsonSchemaBuilder().FromType<GetCurrentWeatherParameters>().Build())) }; var history = new List<ChatMessage> { ChatMessage.User("What is the weather today in C.A?") }; var parameters = new TextGenerationParamters() { ResultFormat = ResultFormats.Message, Tools = tools }; // send question with available tools. var completion = await client.GetQWenChatCompletionAsync(QWenLlm.QWenMax, history, parameters); history.Add(completion.Output.Choice[0].Message); // model responding with tool calls. Console.WriteLine(completion.Output.Choice[0].Message.ToolCalls[0].Function.Name); // GetCurrentWeather // calling tool that model requests and append result into history. var result = GetCurrentWeather(JsonSerializer.Deserialize<GetCurrentWeatherParameters>(completion.Output.Choice[0].Message.ToolCalls[0].Function.Arguments)); history.Add(ChatMessage.Tool(result, nameof(GetCurrentWeather))); // get back answers. completion = await client.GetQWenChatCompletionAsync(QWenLlm.QWenMax, history, parameters); Console.WriteLine(completion.Output.Choice[0].Message.Content);Append the tool calling result with tool role, then model will generate answers based on tool calling result.
Upload file first.
var file = new FileInfo("test.txt"); var uploadedFile = await dashScopeClient.UploadFileAsync(file.OpenRead(), file.Name);Using uploaded file id in messages.
var history = new List<ChatMessage> { ChatMessage.File(uploadedFile.Id), // use array for multiple files, e.g. [file1.Id, file2.Id] ChatMessage.User("Summarize the content of file.") } var parameters = new TextGenerationParameters() { ResultFormat = ResultFormats.Message }; var completion = await client.GetQWenChatCompletionAsync(QWenLlm.QWenLong, history, parameters); Console.WriteLine(completion.Output.Choices[0].Message.Content);Delete file if needed
var deletionResult = await dashScopeClient.DeleteFileAsync(uploadedFile.Id);Use GetApplicationResponseAsync to call an application.
Use GetApplicationResponseStreamAsync for streaming output.
var request = new ApplicationRequest() { Input = new ApplicationInput() { Prompt = "Summarize this file." }, Parameters = new ApplicationParameters() { TopK = 100, TopP = 0.8f, Seed = 1234, Temperature = 0.85f, RagOptions = new ApplicationRagOptions() { PipelineIds = ["thie5bysoj"], FileIds = ["file_d129d632800c45aa9e7421b30561f447_10207234"] } } }; var response = await client.GetApplicationResponseAsync("your-application-id", request); Console.WriteLine(response.Output.Text);ApplicationRequest use an Dictionary<string, object?> as BizParams by default.
var request = new ApplicationRequest() { Input = new ApplicationInput() { Prompt = "Summarize this file.", BizParams = new Dictionary<string, object?>() { { "customKey1", "custom-value" } } } }; var response = await client.GetApplicationResponseAsync("your-application-id", request); Console.WriteLine(response.Output.Text);You can use the generic version ApplicationRequest<TBizParams> for strong-typed BizParams. But keep in mind that client use snake_case by default when doing json serialization, you may need to use [JsonPropertyName("camelCase")] for other type of naming policy.
public record TestApplicationBizParam( [property: JsonPropertyName("sourceCode")] string SourceCode); var request = new ApplicationRequest<TestApplicationBizParam>() { Input = new ApplicationInput<TestApplicationBizParam>() { Prompt = "Summarize this file.", BizParams = new TestApplicationBizParam("test") } }; var response = await client.GetApplicationResponseAsync("your-application-id", request); Console.WriteLine(response.Output.Text);