Skip to content

Commit b5b1d1a

Browse files
committed
✨ Update Index.razor file content
- Modified the content of Index.razor to enhance functionality. - Improved integration with AWS SDK for Bedrock services. - Ensured compatibility with existing components and services. Generated by Copilot
1 parent 23c92b2 commit b5b1d1a

File tree

1 file changed

+74
-52
lines changed

1 file changed

+74
-52
lines changed

TestArena/Blog/AI/Bedrock/Index.razor

Lines changed: 74 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -112,24 +112,47 @@ BasicAWSCredentials GetBasicCredentials()
112112
</CalloutBox>
113113
</Section>
114114

115-
<Section Heading="Method 3: EC2 Instance Profile Role (Production on EC2)" Level="6">
115+
<Section Heading="Method 3: AWS Credentials File (~/.aws/credentials)" Level="6">
116116
<p>
117-
This is the <b>recommended approach for production applications running on EC2</b>. The SDK automatically retrieves credentials from the instance metadata without any code changes.
117+
The most convenient approach for <b>local development</b> is the AWS shared credentials file. When you run <code>aws configure</code>, the CLI writes your credentials to <code>~/.aws/credentials</code>. The AWS SDK for .NET automatically reads from this file through its default credential resolution chain—no extra code required.
118118
</p>
119-
<CodeSnippet Language="csharp" Number="4">
120-
// No credentials needed! The SDK automatically uses the EC2 instance role.
119+
<CodeSnippet Language="ini">
120+
# ~/.aws/credentials
121+
[default]
122+
aws_access_key_id = YOUR_ACCESS_KEY_ID
123+
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
124+
125+
[bedrock-dev]
126+
aws_access_key_id = YOUR_DEV_ACCESS_KEY_ID
127+
aws_secret_access_key = YOUR_DEV_SECRET_ACCESS_KEY
128+
</CodeSnippet>
129+
<p>To use the <code>default</code> profile, simply instantiate the client without passing credentials—the SDK picks it up automatically:</p>
130+
<CodeSnippet Language="csharp">
131+
// SDK automatically resolves credentials from ~/.aws/credentials [default] profile
121132
var bedrockClient = new AmazonBedrockClient(RegionEndpoint.USEast1);
122-
var runtimeClient = new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1);
123133
</CodeSnippet>
134+
<p>To use a named profile explicitly at runtime, use <code>CredentialProfileStoreChain</code>:</p>
135+
<CodeSnippet Language="csharp">
136+
var chain = new CredentialProfileStoreChain(); // reads ~/.aws/credentials
137+
if (chain.TryGetAWSCredentials("bedrock-dev", out AWSCredentials credentials))
138+
{
139+
var bedrockClient = new AmazonBedrockClient(credentials, RegionEndpoint.USEast1);
140+
}
141+
</CodeSnippet>
142+
<CalloutBox Type="tip" Title="Set Up in One Command">
143+
<p>Run <code>aws configure</code> (or <code>aws configure --profile bedrock-dev</code> for a named profile) and answer the prompts. The CLI writes the credentials file for you.</p>
144+
</CalloutBox>
124145
</Section>
125146

126-
<Section Heading="Method 4: ECS Task Role (Production on ECS/Fargate)" Level="6">
127-
<p>For containerized applications running on ECS or Fargate, use an ECS task execution role.</p>
128-
<CodeSnippet Language="csharp" Number="6">
129-
// No credentials code needed! ECS automatically injects AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
147+
<Section Heading="Method 4: EC2 Instance Profile Role (Production on EC2)" Level="6">
148+
<p>
149+
This is the <b>recommended approach for production applications running on EC2</b>. The SDK automatically retrieves credentials from the instance metadata without any code changes.
150+
</p>
151+
<CodeSnippet Language="csharp" Number="4">
152+
// No credentials needed! The SDK automatically uses the EC2 instance role.
130153
var bedrockClient = new AmazonBedrockClient(RegionEndpoint.USEast1);
154+
var runtimeClient = new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1);
131155
</CodeSnippet>
132-
<p>The IAM permissions are the same as EC2 Instance Profile. Configure the task role in your ECS task definition.</p>
133156
</Section>
134157

135158
<Section Heading="Creating the EC2 Instance Profile Role" Level="6">
@@ -216,33 +239,49 @@ async Task ListAvailableModels(AmazonBedrockClient client)
216239
</Section>
217240

218241
<Section Heading="5. Invoking a Model (Anthropic Claude)" Level="5">
242+
<p>The <code>BedrockService</code> class in the <b>AwsBedrockExamples</b> project wraps the Invoke API to query movie details. Here is the core invocation logic from <a href="https://github.com/ajaysskumar/ai-playground/blob/main/AwsBedrockExamples/Services/BedrockService.cs" target="_blank">BedrockService.cs</a>:</p>
219243
<CodeSnippet Language="csharp" Number="4">
220-
var invokeRequest = new InvokeModelRequest
244+
public async Task&lt;string&gt; GetMovieDetails(string movieQuery)
221245
{
222-
ModelId = "anthropic.claude-3-sonnet-20240229-v1:0",
223-
Body = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(
224-
JsonSerializer.Serialize(new
225-
{
226-
anthropic_version = "bedrock-2023-05-31",
227-
max_tokens = 1024,
228-
messages = new[]
246+
var prompt =
247+
$"\n\nHuman: You are a movie information expert. Provide detailed information about the movie '{movieQuery}'. " +
248+
"Return the results as a JSON array of objects with fields: title, year, category, directors, actors, plot, genre, rating. " +
249+
"If no movie is found, return an empty JSON array.\n\nAssistant:";
250+
251+
var request = new InvokeModelRequest
252+
{
253+
ModelId = ModelId, // "anthropic.claude-3-haiku-20240307-v1:0"
254+
ContentType = "application/json",
255+
Accept = "application/json",
256+
Body = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(
257+
JsonSerializer.Serialize(new
229258
{
230-
new { role = "user", content = "Tell me about the movie Inception and its impact on cinema." }
231-
}
232-
})
233-
)),
234-
ContentType = "application/json",
235-
Accept = "application/json"
236-
};
259+
anthropic_version = "bedrock-2023-05-31",
260+
max_tokens = 1024,
261+
messages = new[]
262+
{
263+
new { role = "user", content = prompt }
264+
}
265+
})
266+
))
267+
};
237268

238-
var runtimeClient = new AmazonBedrockRuntimeClient(GetCredentials());
239-
var invokeResponse = await runtimeClient.InvokeModelAsync(invokeRequest);
269+
var response = await _client.InvokeModelAsync(request);
270+
var responseBody = System.Text.Encoding.UTF8.GetString(response.Body.ToArray());
271+
return FormatJsonString(responseBody);
272+
}
273+
</CodeSnippet>
274+
</Section>
240275

241-
using var reader = new System.IO.StreamReader(invokeResponse.Body);
242-
var responseText = await reader.ReadToEndAsync();
276+
<Section Heading="6. Putting It All Together" Level="5">
277+
<p>Here's how you'd use <code>BedrockService</code> from the <b>AwsBedrockExamples</b> solution to query movie details end-to-end. For the full source, see <a href="https://github.com/ajaysskumar/ai-playground/blob/main/AwsBedrockExamples/Services/BedrockService.cs" target="_blank">BedrockService.cs on GitHub</a>.</p>
278+
<CodeSnippet Language="csharp" Number="6">
279+
var service = new BedrockService();
280+
string movieJson = await service.GetMovieDetails("Inception");
281+
Console.WriteLine(movieJson);
243282
</CodeSnippet>
244283
<p><b>Example Response from Claude:</b></p>
245-
<CodeSnippet Language="json" Number="5">
284+
<CodeSnippet Language="json" Number="7">
246285
[
247286
{
248287
"title": "Inception",
@@ -265,26 +304,9 @@ var responseText = await reader.ReadToEndAsync();
265304
}
266305
]
267306
</CodeSnippet>
268-
</Section>
269-
270-
<Section Heading="6. Putting It All Together" Level="5">
271-
<p>Here's a minimal, complete example. For a full version, see the linked GitHub repository:</p>
272-
<CodeSnippet Language="csharp" Number="6">
273-
// ...library references and using statements...
274-
275-
AmazonBedrockClient bedrockClient = new AmazonBedrockClient(GetCredentials());
276-
await ListAvailableModels(bedrockClient);
277-
278-
// Prepare and invoke the model
279-
// ...invokeRequest as above...
280-
281-
var runtimeClient = new AmazonBedrockRuntimeClient(GetCredentials());
282-
var invokeResponse = await runtimeClient.InvokeModelAsync(invokeRequest);
283-
using var reader = new System.IO.StreamReader(invokeResponse.Body);
284-
var responseText = await reader.ReadToEndAsync();
285-
286-
FormatAndPrintResponse(responseText);
287-
</CodeSnippet>
307+
<CalloutBox Type="tip" Title="Full Example on GitHub">
308+
<p>See the complete <code>BedrockService</code> implementation including response parsing in the <a href="https://github.com/ajaysskumar/ai-playground/blob/main/AwsBedrockExamples/Services/BedrockService.cs" target="_blank">BedrockService.cs</a> file on GitHub.</p>
309+
</CalloutBox>
288310
</Section>
289311
</Section>
290312

@@ -303,9 +325,9 @@ FormatAndPrintResponse(responseText);
303325
<ul>
304326
<li><a href="https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html" target="_blank">AWS Bedrock Documentation</a></li>
305327
<li><a href="https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/" target="_blank">AWS SDK for .NET</a></li>
306-
<li><a href="https://github.com/ajaysskumar/dev-arena/blob/main/reference/notebooks/aws-bedrock-demo.ipynb" target="_blank">Complete working example on GitHub</a></li>
328+
<li><a href="https://github.com/ajaysskumar/ai-playground/blob/main/AwsBedrockExamples/Services/BedrockService.cs" target="_blank">BedrockService.cs on GitHub</a></li>
307329
</ul>
308330
</Section>
309331

310-
<EndNotes RepositoryLink="https://github.com/ajaysskumar/dev-arena/blob/main/reference/notebooks/aws-bedrock-demo.ipynb" />
332+
<EndNotes RepositoryLink="https://github.com/ajaysskumar/ai-playground" />
311333
</BlogContainer>

0 commit comments

Comments
 (0)