
How to use Reasoning with Claude 3.7 Sonnet on Amazon Bedrock - C#/.NET Edition
Learn how to use Claude 3.7 Sonnet's step-by-step thinking process with the AWS SDK for .NET. This tutorial walks you through a practical example to receive Claude's internal thought process in your own applications.
- Break down complex questions into manageable components
- Explore multiple approaches to solving a problem
- Analyze information systematically and draw logical conclusions
- Show its work, particularly valuable for mathematical or logical problems
- Identify potential flaws in its own thinking
- An AWS account with access to Amazon Bedrock
- .NET 8.0 or later installed
- The AWS CLI installed and configured
- Access to Claude 3.7 Sonnet enabled in your account¹
1
dotnet add package AWSSDK.BedrockRuntime
1
2
3
4
<ItemGroup>
<PackageReference Include="AWSSDK.BedrockRuntime" Version="3.7.413" />
<PackageReference Include="AWSSDK.Core" Version="3.7.402.6" />
</ItemGroup>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using Amazon;
using Amazon.BedrockRuntime;
using Amazon.BedrockRuntime.Model;
using Amazon.Runtime.Documents;
public class Program
{
public static async Task Main(string[] args)
{
// We'll call our reasoning method here
}
private static async Task<ReasoningResponse> ReasoningExample()
{
// We'll implement this method in the next steps
return null;
}
}
// Record to hold both reasoning and final response
public record ReasoningResponse(ReasoningContentBlock? Reasoning, string? Text);
ReasoningExample()
method:1
2
3
4
5
// Create the Amazon Bedrock runtime client
using var client = new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1);
// Specify the model ID for Claude 3.7 Sonnet
const string modelId = "us.anthropic.claude-3-7-sonnet-20250219-v1:0";
1
2
3
4
5
6
7
8
// Create the message with the user's prompt
const string userMessage = "Describe the purpose of a 'hello world' program in one line.";
var message = new Message
{
Role = ConversationRole.User,
Content = [new ContentBlock { Text = userMessage }]
};
1
2
3
4
5
6
7
8
9
// Configure reasoning parameters with a 2000 token budget
Document reasoningConfig = Document.FromObject(new
{
thinking = new
{
type = "enabled",
budget_tokens = 2000
}
});
budget_tokens
parameter defines the maximum number of tokens Claude can use for its reasoning process. Adjust this value based on the complexity of your prompt.1
2
3
4
5
6
7
// Send message and reasoning configuration to the model
var response = await client.ConverseAsync(new ConverseRequest
{
ModelId = modelId,
Messages = [message],
AdditionalModelRequestFields = reasoningConfig
});
AdditionalModelRequestFields
parameter is what allows us to pass the reasoning configuration.1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Extract and return the reasoning and text from the response
ReasoningContentBlock? reasoning = null;
string? text = null;
// Process each content block to find reasoning and response text
foreach (var block in response.Output.Message.Content)
{
if (block.ReasoningContent is not null)
reasoning = block.ReasoningContent;
else if (block.Text is not null)
text = block.Text;
}
return new ReasoningResponse(reasoning, text);
Main()
method:1
2
3
4
5
6
7
// Execute the example and display reasoning and final response
var response = await ReasoningExample();
Console.WriteLine("\n<thinking>");
Console.WriteLine(response.Reasoning?.ReasoningText.Text);
Console.WriteLine("</thinking>\n");
Console.WriteLine(response.Text);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using Amazon;
using Amazon.BedrockRuntime;
using Amazon.BedrockRuntime.Model;
using Amazon.Runtime.Documents;
namespace Reasoning;
/**
* This example demonstrates how to use Anthropic Claude 3.7 Sonnet's reasoning capability
* with Amazon Bedrock. It shows how to:
* - Set up the Amazon Bedrock runtime client
* - Create a message
* - Configure reasoning parameters
* - Send a request with reasoning enabled
* - Process both the reasoning output and final response
*/
public class Program
{
public static async Task Main(string[] args)
{
// Execute the example and display reasoning and final response
var response = await ReasoningExample();
Console.WriteLine("\n<thinking>");
Console.WriteLine(response.Reasoning?.ReasoningText.Text);
Console.WriteLine("</thinking>\n");
Console.WriteLine(response.Text);
}
private static async Task<ReasoningResponse> ReasoningExample()
{
// Create the Amazon Bedrock runtime client
using var client = new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1);
// Specify the model ID. For the latest available models, see:
// https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html
const string modelId = "us.anthropic.claude-3-7-sonnet-20250219-v1:0";
// Create the message with the user's prompt
const string userMessage = "Describe the purpose of a 'hello world' program in one line.";
var message = new Message
{
Role = ConversationRole.User,
Content = [new ContentBlock { Text = userMessage }]
};
// Configure reasoning parameters with a 2000 token budget
Document reasoningConfig = Document.FromObject(new
{
thinking = new
{
type = "enabled",
budget_tokens = 2000
}
});
try
{
// Send message and reasoning configuration to the model
var response = await client.ConverseAsync(new ConverseRequest
{
ModelId = modelId,
Messages = [message],
AdditionalModelRequestFields = reasoningConfig
});
ReasoningContentBlock? reasoning = null;
string? text = null;
// Process each content block to find reasoning and response text
foreach (var block in response.Output.Message.Content)
{
if (block.ReasoningContent is not null)
reasoning = block.ReasoningContent;
else if (block.Text is not null)
text = block.Text;
}
return new ReasoningResponse(reasoning, text);
}
catch (AmazonBedrockRuntimeException e)
{
Console.WriteLine($"ERROR: Can't invoke '{modelId}'. Reason: {e.Message}");
throw;
}
}
}
// Record to hold both reasoning and final response
public record ReasoningResponse(ReasoningContentBlock? Reasoning, string? Text);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<thinking>
I need to explain the purpose of a "Hello World" program in a single line.
A "Hello World" program is typically the simplest program that can be written in
a programming language. Its purpose is to:
1. Verify that the programming environment is set up correctly
2. Demonstrate the minimal syntax needed to create a functioning program
3. Provide a simple introduction to the language
4. Output the text "Hello, World!" or a similar message
I need to condense this information into a concise, one-line description that
captures the essence of what a "Hello World" program is for.
</thinking>
A "Hello World" program serves as the simplest introduction to a programming
language by demonstrating basic syntax while verifying the environment works correctly.
- Adjusting the token budget based on your problem complexity – more complex problems may benefit from larger reasoning budgets
- Using the reasoning output to validate multi-step calculations or complex analytical processes
- Comparing different reasoning approaches by adjusting your prompts
- Integrating reasoning with other Claude capabilities like function calling for powerful, transparent AI solutions
- Using reasoning as an educational tool to understand expert-level problem-solving approaches
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.