Skip to content

Commit 50e0dc3

Browse files
authored
feat: support code interpreter (#157)
* chore: code clean up * feat: support code interpreter
1 parent 2ccade3 commit 50e0dc3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+887
-331
lines changed

README.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ Console.WriteLine($"Image token usage: {raw?.Usage?.ImageTokens}");
175175
- [Tool Calling](#tool-calling)
176176
- [Prefix Completion](#prefix-completion)
177177
- [Long Context (Qwen-Long)](#long-context-qwen-long)
178+
- [Code Interpreter](#code-interpreter)
178179
- [Multimodal](#multimodal) - QWen-VL, QVQ, etc. Supports reasoning/visual understanding/OCR/audio understanding
179180
- [Upload file for multimodal usage](#upload-file-for-multimodal-usage)
180181
- [Image Recognition/Thinking](#image-recognition/thinking)
@@ -595,7 +596,118 @@ Console.WriteLine(completion.Output.Choices[0].Message.Content);
595596
await dashScopeClient.OpenAiCompatibleDeleteFileAsync(uploadedFile.Id);
596597
```
597598

599+
### Code Interpreter
600+
601+
**This capability is mutually exclusive with Function Call and cannot be used simultaneously.**
602+
603+
Use the `EnableCodeInterpreter` parameter in `Parameters` to allow the model to write code and call an internal code interpreter for calculations.
604+
605+
Example Request:
606+
607+
```csharp
608+
var completion = client.GetTextCompletionStreamAsync(
609+
new ModelRequest<TextGenerationInput, ITextGenerationParameters>()
610+
{
611+
Model = "qwen3-max-preview",
612+
Input = new TextGenerationInput() { Messages = messages },
613+
Parameters = new TextGenerationParameters()
614+
{
615+
ResultFormat = "message",
616+
EnableThinking = true,
617+
EnableCodeInterpreter = true,
618+
IncrementalOutput = true
619+
}
620+
});
621+
```
622+
623+
The code that model generated will be included in `chunk.Output.ToolInfo.CodeInterpreter`. The invocation process can be considered part of the reasoning process.
624+
625+
Full example,
626+
627+
```csharp
628+
var messages = new List<TextChatMessage>();
629+
const string input = "123的21次方是多少?";
630+
Console.Write($"User > {input}");
631+
messages.Add(TextChatMessage.User(input));
632+
var completion = client.GetTextCompletionStreamAsync(
633+
new ModelRequest<TextGenerationInput, ITextGenerationParameters>
634+
{
635+
Model = "qwen3-max-preview",
636+
Input = new TextGenerationInput { Messages = messages },
637+
Parameters = new TextGenerationParameters
638+
{
639+
ResultFormat = "message",
640+
EnableThinking = true,
641+
EnableCodeInterpreter = true,
642+
IncrementalOutput = true
643+
}
644+
});
645+
var reply = new StringBuilder();
646+
var codeGenerated = false;
647+
var reasoning = false;
648+
TextGenerationTokenUsage? usage = null;
649+
await foreach (var chunk in completion)
650+
{
651+
var choice = chunk.Output.Choices![0];
652+
var tool = chunk.Output.ToolInfo?.FirstOrDefault();
653+
if (codeGenerated == false && tool?.CodeInterpreter != null)
654+
{
655+
Console.WriteLine($"Code > {tool.CodeInterpreter.Code}");
656+
codeGenerated = true;
657+
}
658+
659+
if (string.IsNullOrEmpty(choice.Message.ReasoningContent) == false)
660+
{
661+
// reasoning
662+
if (reasoning == false)
663+
{
664+
Console.WriteLine();
665+
Console.Write("Reasoning > ");
666+
reasoning = true;
667+
}
668+
669+
Console.Write(choice.Message.ReasoningContent);
670+
continue;
671+
}
672+
673+
if (reasoning && string.IsNullOrEmpty(choice.Message.Content.Text) == false)
674+
{
675+
reasoning = false;
676+
Console.WriteLine();
677+
Console.Write("Assistant > ");
678+
}
679+
680+
Console.Write(choice.Message.Content);
681+
reply.Append(choice.Message.Content);
682+
usage = chunk.Usage;
683+
}
684+
685+
Console.WriteLine();
686+
messages.Add(TextChatMessage.Assistant(reply.ToString()));
687+
if (usage != null)
688+
{
689+
Console.WriteLine(
690+
$"Usage: in({usage.InputTokens})/out({usage.OutputTokens})/reasoning({usage.OutputTokensDetails?.ReasoningTokens})/plugins({usage.Plugins?.CodeInterpreter?.Count})/total({usage.TotalTokens})");
691+
}
692+
693+
/*
694+
User > 123的21次方是多少?
695+
Reasoning > 用户问的是123的21次方是多少。这是一个大数计算问题,我需要使用代码计算器来计算这个值。
696+
697+
我需要调用code_interpreter函数,传入计算123**21的Python代码。
698+
123**21
699+
用户询问123的21次方是多少,我使用代码计算器计算出了结果。结果是一个非常大的数字:77269364466549865653073473388030061522211723
700+
701+
我应该直接给出这个结果,因为这是一个精确的数学计算问题,不需要额外的解释或
702+
Assistant > 123的21次方是:77269364466549865653073473388030061522211723
703+
Usage: in(704)/out(234)/reasoning(142)/plugins(1)/total(938)
704+
*/
705+
```
706+
707+
708+
598709
## Multimodal
710+
599711
Use `GetMultimodalGenerationAsync`/`GetMultimodalGenerationStreamAsync`
600712
[Official Documentation](https://help.aliyun.com/zh/model-studio/multimodal)
601713

0 commit comments

Comments
 (0)