@@ -67,6 +67,13 @@ public class YourService(IDashScopeClient client)
6767## 支持的 API
6868
6969- [ 文本生成] ( #文本生成 ) - QWen3, DeepSeek 等,支持推理/工具调用/网络搜索/翻译等场景
70+ - [ 多轮对话] ( #多轮对话 )
71+ - [ 深度思考] ( #深度思考 )
72+ - [ 联网搜索] ( #联网搜索 )
73+ - [ 工具调用] ( #工具调用 )
74+ - [ 前缀续写] ( #前缀续写 )
75+ - [ 长上下文(Qwen-Long)] ( #长上下文(Qwen-Long) )
76+
7077- [ 多模态] ( #多模态 ) - QWen-VL,QVQ 等,支持推理/视觉理解/OCR/音频理解等场景
7178- [ 语音合成] ( #语音合成 ) - CosyVoice,Sambert 等,支持 TTS 等应用场景
7279- [ 图像生成] ( #图像生成 ) - wanx2.1 等,支持文生图,人像风格重绘等应用场景
@@ -1129,15 +1136,170 @@ Usage: in(31)/out(34)/reasoning()/total(65)
11291136 */
11301137```
11311138
1139+ ### 长上下文(Qwen-Long)
1140+
1141+ 尽管 QWen-Long 支持直接传入字符串,但还是推荐先将文件上传后再通过 FileId 的形式传入 ` message ` 数组中。
1142+
1143+ 上传文件,使用 ` UploadFileAsync() ` 方法传入文件(注意不是 ` UploadTemporaryFileAsync ` , 后者是用于上传媒体文件的):
1144+
1145+ ``` csharp
1146+ var file1 = await client .UploadFileAsync (File .OpenRead (" 1024-1.txt" ), " file1.txt" );
1147+ ```
1148+
1149+ 然后将文件作为 ` system ` 消息传入消息数组中,注意第一条 ` system ` 消息不能省略,否则模型可能会将文件里的内容当作 System prompt 。
1150+
1151+ ``` csharp
1152+ var messages = new List <TextChatMessage >();
1153+ messages .Add (TextChatMessage .System (" You are a helpful assistant" ));
1154+ messages .Add (TextChatMessage .File (file1 .Id ));
1155+ messages .Add (TextChatMessage .File (file2 .Id ));
1156+ // 也可以传入文件数组 messages.Add(TextChatMessage.File([file1.Id, file2.Id]));
1157+ ```
1158+
1159+ 再以 ` user ` 消息添加与文件内容相关的问题。
1160+
1161+ ``` csharp
1162+ messages .Add (TextChatMessage .User (" 这两篇文章分别讲了什么?" ));
1163+ ```
1164+
1165+ 最后向模型发送请求,注意这个接口获得的文件 ID 只有 ` qwen-long ` 模型可以访问,其他模型是访问不到的。
1166+
1167+ ``` csharp
1168+ var completion = client .GetTextCompletionStreamAsync (
1169+ new ModelRequest <TextGenerationInput , ITextGenerationParameters >()
1170+ {
1171+ Model = " qwen-long" ,
1172+ Input = new TextGenerationInput () { Messages = messages },
1173+ Parameters = new TextGenerationParameters ()
1174+ {
1175+ ResultFormat = " message" ,
1176+ IncrementalOutput = true
1177+ }
1178+ });
1179+ ```
1180+
1181+ 最后可以通过 ` DeleteFileAsync() ` 方法删除上传的文件
1182+
1183+ ``` csharp
1184+ var result = await client .DeleteFileAsync (file1 .Id );
1185+ Console .WriteLine (result .Deleted ? " Success" : " Failed" );
1186+ ```
1187+
1188+ 完整示例
1189+
1190+ ``` csharp
1191+ Console .WriteLine (" Uploading file1..." );
1192+ var file1 = await client .UploadFileAsync (File .OpenRead (" 1024-1.txt" ), " file1.txt" );
1193+ Console .WriteLine (" Uploading file2..." );
1194+ var file2 = await client .UploadFileAsync (File .OpenRead (" 1024-2.txt" ), " file2.txt" );
1195+ Console .WriteLine ($" Uploaded, file1 id: {file1 .Id .ToUrl ()}, file2 id: {file2 .Id .ToUrl ()}" );
1196+
1197+ var messages = new List <TextChatMessage >();
1198+ messages .Add (TextChatMessage .System (" You are a helpful assistant" ));
1199+ messages .Add (TextChatMessage .File (file1 .Id ));
1200+ messages .Add (TextChatMessage .File (file2 .Id ));
1201+ messages .Add (TextChatMessage .User (" 这两篇文章分别讲了什么?" ));
1202+
1203+ messages .ForEach (m => Console .WriteLine ($" {m .Role } > {m .Content }" ));
1204+ var completion = client .GetTextCompletionStreamAsync (
1205+ new ModelRequest <TextGenerationInput , ITextGenerationParameters >()
1206+ {
1207+ Model = " qwen-long" ,
1208+ Input = new TextGenerationInput () { Messages = messages },
1209+ Parameters = new TextGenerationParameters ()
1210+ {
1211+ ResultFormat = " message" ,
1212+ IncrementalOutput = true
1213+ }
1214+ });
1215+ var reply = new StringBuilder ();
1216+ var reasoning = false ;
1217+ TextGenerationTokenUsage ? usage = null ;
1218+ await foreach (var chunk in completion )
1219+ {
1220+ var choice = chunk .Output .Choices ! [0 ];
1221+ if (string .IsNullOrEmpty (choice .Message .ReasoningContent ) == false )
1222+ {
1223+ // reasoning
1224+ if (reasoning == false )
1225+ {
1226+ Console .Write (" Reasoning > " );
1227+ reasoning = true ;
1228+ }
1229+
1230+ Console .Write (choice .Message .ReasoningContent );
1231+ continue ;
1232+ }
1233+
1234+ if (reasoning )
1235+ {
1236+ reasoning = false ;
1237+ Console .WriteLine ();
1238+ Console .Write (" Assistant > " );
1239+ }
1240+
1241+ Console .Write (choice .Message .Content );
1242+ reply .Append (choice .Message .Content );
1243+ usage = chunk .Usage ;
1244+ }
1245+
1246+ Console .WriteLine ();
1247+ messages .Add (TextChatMessage .Assistant (reply .ToString ()));
1248+ if (usage != null )
1249+ {
1250+ Console .WriteLine (
1251+ $" Usage: in({usage .InputTokens })/out({usage .OutputTokens })/reasoning({usage .OutputTokensDetails ? .ReasoningTokens })/total({usage .TotalTokens })" );
1252+ }
1253+
1254+ // Deleting files
1255+ Console .Write (" Deleting file1..." );
1256+ var result = await client .DeleteFileAsync (file1 .Id );
1257+ Console .WriteLine (result .Deleted ? " Success" : " Failed" );
1258+ Console .Write (" Deleting file2..." );
1259+ result = await client .DeleteFileAsync (file2 .Id );
1260+ Console .WriteLine (result .Deleted ? " Success" : " Failed" );
1261+
1262+ /*
1263+ Uploading file1...
1264+ Uploading file2...
1265+ Uploaded, file1 id: fileid://file-fe-b87a5c12cc354533bd882f04, file2 id: fileid://file-fe-f5269f9996d544c4aecc5f80
1266+ system > You are a helpful assistant
1267+ system > fileid://file-fe-b87a5c12cc354533bd882f04
1268+ system > fileid://file-fe-f5269f9996d544c4aecc5f80
1269+ user > 这两篇文章分别讲了什么?
1270+ 这两篇文章都围绕“中国程序员节”的设立展开,但内容侧重点不同:
1271+
1272+ **第一篇文章《file1.txt》:**
1273+ 这篇文章是一篇征求意见稿,标题为《中国程序员节,10月24日,你同意吗?》。文章回顾了此前关于设立中国程序员节的讨论背景——受俄罗斯程序员节(每年第256天)启发,有网友提议设立中国的程序员 节。文中提到曾有人建议定在10月10日(因为“1010”类似二进制),但作者认为10月24日更具意义:
1274+ - 因为1024 = 2^10,是计算机中“1K”的近似值;
1275+ - 1024在二进制、八进制和十六进制中都有特殊表示;
1276+ - 节日时间上避开国庆后的调整期。
1277+ 因此,文章向读者征求是否同意将**10月24日**作为中国程序员节,并邀请大家参与投票和提出庆祝活动建议。
1278+
1279+ **第二篇文章《file2.txt》:**
1280+ 这篇文章是第一篇的后续,标题为《程序员节,10月24日!》,属于正式 announcement(公告)。它宣布:
1281+ - 根据前一次讨论的反馈结果,正式确定将**每年的10月24日**定为“中国程序员节”;
1282+ - 博客园将在该日组织线上庆祝活动;
1283+ - 文章进一步升华主题,强调程序员的社会价值和责任感,呼吁尊重程序员群体,肯定他们是“用代码改变世界的人”,并表达了对技术创造力的敬意。
1284+
1285+ **总结:**
1286+ - 第一篇是**征求意见**,探讨是否将10月24日设为中国程序员节;
1287+ - 第二篇是**正式确认**节日日期,并倡导庆祝与认同程序员的价值。
1288+ Usage: in(513)/out(396)/reasoning()/total(909)
1289+ Deleting file1...Success
1290+ Deleting file2...Success
1291+ */
1292+ ```
1293+
11321294
11331295
1134- ### 多模态
1296+ ## 多模态
11351297
11361298使用 ` dashScopeClient.GetMultimodalGenerationAsync ` 和 ` dashScopeClient.GetMultimodalGenerationStreamAsync ` 来访问多模态文本生成接口。
11371299
11381300相关文档:[ 多模态_大模型服务平台百炼(Model Studio)-阿里云帮助中心] ( https://help.aliyun.com/zh/model-studio/multimodal )
11391301
1140- #### 视觉理解/推理
1302+ ### 视觉理解/推理
11411303
11421304使用 ` MultimodalMessage.User() ` 可以快速创建对应角色的消息。
11431305
@@ -1198,7 +1360,7 @@ await foreach (var modelResponse in response)
11981360}
11991361```
12001362
1201- ### 语音合成
1363+ ## 语音合成
12021364
12031365通过 ` dashScopeClient.CreateSpeechSynthesizerSocketSessionAsync() ` 来创建一个语音合成会话。
12041366
@@ -1235,9 +1397,9 @@ Console.WriteLine($"audio saved to {file.FullName}, token usage: {tokenUsage}");
12351397break ;
12361398```
12371399
1238- ### 图像生成
1400+ ## 图像生成
12391401
1240- #### 文生图
1402+ ### 文生图
12411403
12421404我们针对通义万相提供了快捷 API ` dashScopeClient.CreateWanxImageSynthesisTaskAsync() ` 和 ` GetWanxImageSynthesisTaskAsync() ` 。
12431405
@@ -1286,7 +1448,7 @@ Console.WriteLine($"Task timout, taskId: {task.TaskId}");
12861448
12871449图像背景生成 - ` CreateWanxBackgroundGenerationTaskAsync ` 和 ` GetWanxBackgroundGenerationTaskAsync `
12881450
1289- ### 应用调用
1451+ ## 应用调用
12901452
12911453` GetApplicationResponseAsync ` 用于进行应用调用。
12921454
@@ -1354,7 +1516,7 @@ var response = await client.GetApplicationResponseAsync("your-application-id", r
13541516Console .WriteLine (response .Output .Text );
13551517```
13561518
1357- ### 文本向量
1519+ ## 文本向量
13581520
13591521使用 ` GetTextEmbeddingsAsync ` 来调用文本向量接口。
13601522
0 commit comments