Add a sample using multiple services (#851)

This commit is contained in:
Stephen Toub
2025-09-22 21:07:51 -04:00
committed by GitHub
Unverified
parent ca810076e8
commit 09bdd64dcb
5 changed files with 105 additions and 0 deletions
+2
View File
@@ -82,6 +82,8 @@
<!-- MCP -->
<PackageVersion Include="ModelContextProtocol" Version="0.3.0-preview.4" />
<!-- Inference SDKs -->
<PackageVersion Include="Anthropic.SDK" Version="5.5.1" />
<PackageVersion Include="AWSSDK.Extensions.Bedrock.MEAI" Version="4.0.3.1" />
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI" Version="0.9.2" />
<PackageVersion Include="OllamaSharp" Version="5.4.4" />
<!-- Identity -->
+1
View File
@@ -110,6 +110,7 @@
<Project Path="samples/GettingStarted/Workflows/_Foundational/02_Streaming/02_Streaming.csproj" />
<Project Path="samples/GettingStarted/Workflows/_Foundational/03_AgentsInWorkflows/03_AgentsInWorkflows.csproj" />
<Project Path="samples/GettingStarted/Workflows/_Foundational/04_AgentWorkflowPatterns/04_AgentWorkflowPatterns.csproj" />
<Project Path="samples/GettingStarted/Workflows/_Foundational/05_MultiModelService/05_MultiModelService.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/" />
<Folder Name="/Samples/SemanticKernelMigration/AzureAIFoundry/">
@@ -15,6 +15,8 @@ Please begin with the [Foundational](./_Foundational) samples in order. These th
| [Executors and Edges](./_Foundational/01_ExecutorsAndEdges) | Minimal workflow with basic executors and edges |
| [Streaming](./_Foundational/02_Streaming) | Extends workflows with event streaming |
| [Agents](./_Foundational/03_AgentsInWorkflows) | Use agents in workflows |
| [Agentic Workflow Patterns](./_Foundational/04_AgentWorkflowPatterns) | Demonstrates common agentic workflow patterns |
| [Multi-Service Workflows](./_Foundational/05_MultiModelService) | Shows using multiple AI services in the same workflow |
Once completed, please proceed to other samples listed below.
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<NoWarn>$(NoWarn);OPENAI001</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Anthropic.SDK" />
<PackageReference Include="AWSSDK.Extensions.Bedrock.MEAI" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.Workflows\Microsoft.Agents.Workflows.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Extensions.AI.Agents.AzureAI\Microsoft.Extensions.AI.Agents.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Extensions.AI.Agents\Microsoft.Extensions.AI.Agents.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,76 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
using Amazon.BedrockRuntime;
using Microsoft.Agents.Workflows;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.AI.Agents;
// Define the topic discussion.
const string Topic = "Goldendoodles make the best pets.";
// Create the IChatClients to talk to different services.
IChatClient aws = new AmazonBedrockRuntimeClient(
Environment.GetEnvironmentVariable("BEDROCK_ACCESSKEY"!),
Environment.GetEnvironmentVariable("BEDROCK_SECRETACCESSKEY")!,
Amazon.RegionEndpoint.USEast1).AsIChatClient("amazon.nova-pro-v1:0");
IChatClient anthropic = new Anthropic.SDK.AnthropicClient(
Environment.GetEnvironmentVariable("ANTHROPIC_APIKEY")!).Messages.AsBuilder()
.ConfigureOptions(o =>
{
o.ModelId ??= "claude-sonnet-4-20250514";
o.MaxOutputTokens ??= 10 * 1024;
})
.Build();
IChatClient openai = new OpenAI.OpenAIClient(
Environment.GetEnvironmentVariable("OPENAI_APIKEY")!).GetChatClient("gpt-4o-mini").AsIChatClient();
// Define our agents.
AIAgent researcher = new ChatClientAgent(aws,
instructions: """
Write a short essay on topic specified by the user. The essay should be three to five paragraphs, written at a
high school reading level, and include relevant background information, key claims, and notable perspectives.
You MUST include at least one silly and objectively wrong piece of information about the topic but believe
it to be true.
""",
name: "researcher",
description: "Researches a topic and writes about the material.");
AIAgent factChecker = new ChatClientAgent(openai,
instructions: """
Evaluate the researcher's essay. Verify the accuracy of any claims against reliable sources, noting whether it is
supported, partially supported, unverified, or false, and provide short reasoning.
""",
name: "fact_checker",
description: "Fact-checks reliable sources and flags inaccuracies.",
[new HostedWebSearchTool()]);
AIAgent reporter = new ChatClientAgent(anthropic,
instructions: """
Summarize the original essay into a single paragraph, taking into account the subsequent fact checking to correct
any inaccuracies. Only include facts that were confirmed by the fact checker. Omit any information that was
flagged as inaccurate or unverified. The summary should be clear, concise, and informative.
You MUST NOT provide any commentary on what you're doing. Simply output the final paragraph.
""",
name: "reporter",
description: "Summarize the researcher's essay into a single paragraph, focusing only on the fact checker's confirmed facts.");
// Build a sequential workflow: Researcher -> Fact-Checker -> Reporter
AIAgent workflowAgent = AgentWorkflowBuilder.BuildSequential(researcher, factChecker, reporter).AsAgent();
// Run the workflow, streaming the output as it arrives.
string? lastAuthor = null;
await foreach (var update in workflowAgent.RunStreamingAsync(Topic))
{
if (lastAuthor != update.AuthorName)
{
lastAuthor = update.AuthorName;
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"\n\n** {update.AuthorName} **");
Console.ResetColor();
}
Console.Write(update.Text);
}