Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
155563 stories
·
33 followers

Zero Trust for AI Agents

1 Share

As AI agents become more capable and autonomous, they also introduce new security challenges. In this 'Fully Connected' episode, Dan and Chris unpack Anthropic’s Zero Trust for AI Agents security framework and what it means for organizations deploying agentic systems. They examine the key security risks facing agentic systems and discuss how organizations can apply Zero Trust principles to deploy AI agents safely. Along the way, they break down practical security controls and discuss how traditional cybersecurity principles must evolve for the age of AI agents.

Featuring:

Links: 

Sponsors:

Upcoming Events: 





Download audio: https://pscrb.fm/rss/p/dts.podtrac.com/redirect.mp3/media.transistor.fm/5c1a087d/89d77a53.mp3
Read the whole story
alvinashcraft
12 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Fable 5 Raises the Bar for AI Ambition

1 Share
From: AIDailyBrief
Duration: 35:25
Views: 1,834

Anthropic’s Fable 5 is a major leap in frontier AI, but the bigger shift is what it asks of users: less prompting for small tasks, more imagination about what can now be delegated to agents for hours or days at a time. In the headlines: Fable’s guardrails spark backlash, enterprise retention concerns emerge, and OpenAI hints it may have an answer coming.

The AI Daily Brief helps you understand the most important news and discussions in AI.
Subscribe to the podcast version of The AI Daily Brief wherever you listen: https://pod.link/1680633614
Get it ad free at http://patreon.com/aidailybrief
Learn more about the show https://aidailybrief.ai/

Read the whole story
alvinashcraft
22 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Building Your First Agentic AI Workflow in C# with Microsoft AutoGen

1 Share

Hello geeks! If you have been following the tech trends lately, you already know that artificial intelligence is fundamentally reshaping how we build software today. As C# developers, it is crucial for us to adapt to these massive changes and start bringing intelligent, autonomous features into our existing enterprise applications.

 

Today, we are going to explore how to build your very first multi-agent system using the powerful Microsoft AutoGen framework directly within your familiar .NET environment. Let's dive right in and learn how to make multiple AI entities seamlessly converse, write code, and solve complex problems together.

 

Step-by-Step Guide to Microsoft AutoGen for C# Developers
Create Multi-Agent AI Systems in .NET with AutoGen

 

 

  • Understand the foundational concepts of agentic workflows, exploring how independent bots communicate and collaborate to solve complex technical problems much faster than traditional static scripting.
  • Learn how to properly configure your local .NET development environment, including installing the right SDKs and securing your API keys to support robust framework execution natively in C#.
  • Discover the step-by-step process of defining, instantiating, and connecting specialized Assistant and User Proxy components within your enterprise applications to foster intelligent automation.
  • See practical examples of how multiple cognitive entities can seamlessly brainstorm, write syntax, test functions, and debug runtime errors together without requiring constant manual oversight.
  • Gain valuable architectural insights into troubleshooting, optimizing token usage, and securely scaling your intelligent software solutions for production-grade enterprise deployments.

 

 

Understanding Agentic AI and Microsoft AutoGen

For a long time, integrating artificial intelligence into our projects meant sending a single prompt and receiving a single response. However, the real power of modern AI lies in agentic workflows, where independent AI agents can reason, plan, and collaborate to achieve a goal.

 

Microsoft AutoGen is an innovative open-source framework that simplifies the orchestration of these complex multi-agent conversations. It allows developers to define specialized bots that can chat with each other, execute logic, and even ask for human feedback when they get stuck on a difficult task.

 

As we discussed in a previous article about The AI-Powered Revolutionary Tools Transforming Software Development, having smart assistants dramatically boosts productivity. By leveraging this framework in our C# projects, we can build custom solutions that automate repetitive coding, testing, and data analysis tasks efficiently.

 

 

 

Setting Up the .NET Environment for AI

Before writing the business logic for our Agentic AI system, we must prepare our development workspace. You need a modern development environment that supports the latest framework features, as C# and .NET are continually evolving to embrace machine learning capabilities natively.

 

The transition to intelligent systems is happening rapidly across all corporate sectors. If you read about AI Everywhere: The Increasing Integration of Artificial Intelligence in Organizations, you will know that having the right infrastructure is half the battle won when adopting these new technologies.

Essential Prerequisites

  • Visual Studio 2022: Make sure you have the latest version of Visual Studio installed with the .NET desktop development workload checked, as this provides the best integrated environment for writing and debugging your intelligent workflows natively.
  • .NET 8 SDK: You will need the latest long-term support version of .NET installed on your machine, ensuring you have access to the latest performance improvements and C# language features required by modern machine learning libraries.
  • OpenAI API Key: To power the conversational logic behind your multi-agent setups, you must generate a valid API key from either the standard OpenAI platform or your dedicated Microsoft Azure OpenAI service dashboard before compiling.

Once these tools are ready, you can create a standard Console Application and use the NuGet Package Manager to install the required packages, which will expose the necessary classes to build our conversational architecture.

 

 

 

Architecting the Multi-Agent Conversation

The core concept behind Microsoft AutoGen is defining different personas that can interact with one another. Typically, you will start by defining at least two distinct personas: an Assistant Agent that acts as the brain, and a User Proxy Agent that acts as the executor or human stand-in.

 

The Assistant Agent is configured with your chosen Large Language Model (LLM) and is responsible for writing scripts, answering questions, or planning the steps needed to solve the problem. It relies on the robust capabilities of models like GPT-4 to generate highly accurate C# snippets or analytical reports.

 

On the flip side, the User Proxy Agent receives the generated code and can actually execute it safely within your local environment. This seamless interaction allows the system to write a script, test it, read the error logs, and automatically fix the bugs without any manual intervention.

 

 

 

Writing the C# Code for Your Agents

Now, let's get our hands dirty with some code. First, initialize the configuration for your LLM by creating an instance of the OpenAI setup. You pass your API key and the model name, which ensures that your Agentic AI entities have the cognitive power required to process complex queries.

 

Next, instantiate the assistant class and the proxy class. You will bind the configuration object to the Assistant, while the User Proxy is usually set to execute code locally or prompt the console for human input if the workflow encounters an ambiguous situation.

 

When debugging these interactions, understanding the execution context is crucial, much like tracing caller info which I covered in my older post on CallerMemberName in C#. Finally, initiate the chat by calling the asynchronous method on the proxy, passing the target assistant and the initial prompt to kick off the automation.

 

 

 

Testing and Scaling Your AI Solution

Press F5 in Visual Studio to run your newly built console application. You will see a fascinating back-and-forth dialogue in your command prompt as the bots brainstorm, share snippets, and review each other's outputs until the requested task is fully completed.

 

While a two-persona system is great for learning, the real magic happens when you scale up. You can introduce specialized roles like a Code Reviewer, a Database Architect, or a QA Tester, creating a comprehensive digital software factory inside your custom application.

 

If things do not work as expected, check your token limits and ensure the execution environment permissions are correctly set. Sometimes, the User Proxy might fail to execute a file if it lacks folder permissions, requiring a quick check of your local security configurations.

 

 

 

Frequently Asked Questions (FAQ)

1. What exactly is an Agentic AI workflow?

An agentic workflow involves multiple autonomous AI entities that can plan, execute tasks, collaborate, and adapt to changing conditions without requiring constant human prompting for every single step.

2. Why should C# developers care about Microsoft AutoGen?

It brings the power of multi-agent orchestration directly into the .NET ecosystem, allowing C# developers to build intelligent, self-healing, and autonomous enterprise applications using familiar tools and languages.

3. Can I use Azure OpenAI with this framework in .NET?

Yes, the framework natively supports both standard OpenAI platform keys and Microsoft Azure OpenAI enterprise endpoints, making it highly secure for corporate enterprise environments.

4. Do I need an advanced GPU to run these workflows?

No, because the heavy cognitive processing is handled by cloud-based LLMs like GPT-4. Your local machine only handles the lightweight orchestration and local script execution.

5. How does the User Proxy agent execute code locally?

The User Proxy reads the syntax generated by the assistant, saves it to a temporary file within your designated working directory, and invokes the respective compiler or interpreter to run it.

6. Is this framework free to use for commercial projects?

Yes, it is an open-source framework provided by Microsoft. However, you will still need to pay for the API token usage billed by your chosen LLM provider.

7. How can I prevent the agents from entering an infinite loop?

You can configure max_consecutive_auto_reply limits in your connection settings to strictly cap how many times the bots can respond to one another before terminating.

8. What is the difference between Semantic Kernel and AutoGen?

Semantic Kernel focuses primarily on integrating AI capabilities and plugins into existing application logic, whereas this framework specializes in orchestrating multiple autonomous entities talking to each other.

9. Can these bots interact with existing SQL databases?

Absolutely. You can prompt the assistant to generate safe SQL queries, which the proxy can then execute against your database if provided with the correct connection string.

10. Does this support older versions like .NET Framework 4.8?

While some core libraries might be backported, it is highly recommended to use .NET 8 or later to ensure full compatibility with modern asynchronous paradigms and security standards.

 

 

Wrapping Up

As we wrap up this comprehensive guide, I hope you are feeling excited about the incredible possibilities that autonomous bots bring to the table. Building your first intelligent system in .NET is just the beginning of a much larger journey into the future of automated enterprise software development.

 

Do not be afraid to experiment with different personas, configuration prompts, and architectures. The developer community is rapidly evolving, and mastering these next-generation frameworks now will put you significantly ahead of the curve in your professional career as a solution architect.

 

If you found this tutorial helpful, please share it with your fellow programmers and drop a comment below with your thoughts or questions. Stay tuned to Kunal-Chowdhury.com for more deep dives into advanced programming and the fascinating world of automation. Happy coding, geeks!

 

Read the whole story
alvinashcraft
37 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Introducing Corvus.Text.Json V5: Pooled-Memory Parsing

1 Share

At endjin, we maintain Corvus.JsonSchema, and in the previous post we looked at schema validation.

Now let's talk about the foundation that makes V5's performance possible: pooled-memory parsing.

The allocation problem

If you've profiled a .NET service that processes a lot of JSON, you've probably seen a familiar pattern in the GC profiler: a steady stream of small allocations from JsonNode, JsonObject, and JsonArray. Each node in the mutable document model is a separate heap object. For a document with 100 properties, that's 100+ allocations. Each one contributes to GC pressure.

System.Text.Json.JsonDocument solves this with a pooled model, but it's read-only. The moment you need to modify the JSON, you're back to JsonNode and its per-node allocations.

V5's ParsedJsonDocument<T> gives you the best of both: a pooled, read-only document that uses ArrayPool<byte> for all its backing memory, with just 136 bytes of GC pressure per document. This is true regardless of size.

And when you do need to modify things, the JsonDocumentBuilder we'll discuss in the next post uses the same pooled memory model.

Basic usage

Parsing from a string

using var doc = ParsedJsonDocument<JsonElement>.Parse(
    """
    {
        "name": "Alice",
        "age": 30,
        "address": {
            "city": "London",
            "country": "UK"
        }
    }
    """);

JsonElement root = doc.RootElement;
string name = root.GetProperty("name"u8).GetString();
int age = root.GetProperty("age"u8).GetInt32();

The using statement is important. When the document is disposed, all rented memory is returned to ArrayPool. This is the core lifetime rule for ParsedJsonDocument<T>. There are no leaked buffers, and no GC pressure beyond the 136 bytes for the document object itself.

Parsing from UTF-8 bytes

If you already have UTF-8 data from a network buffer, a file read, or an HTTP request body, you can parse directly without transcoding:

ReadOnlyMemory<byte> utf8Data = GetUtf8FromNetwork();
using var doc = ParsedJsonDocument<JsonElement>.Parse(utf8Data);

Async stream parsing

For large files or network streams, async parsing avoids blocking:

using FileStream stream = File.OpenRead("large-data.json");
using var doc = await ParsedJsonDocument<JsonElement>.ParseAsync(stream);

UTF-8 property access

One of the subtle performance wins in V5 is that property names are stored and compared as UTF-8 bytes. The "name"u8 syntax gives you a ReadOnlySpan<byte> - no string allocation, no UTF-16 transcoding.

// Fast: UTF-8 comparison, no allocation
string name = root.GetProperty("name"u8).GetString();

// Also works, but transcodes from UTF-16
string name = root.GetProperty("name").GetString();

For properties you access frequently, V5 can optionally build an O(1) property map for repeated lookups. This is an opt-in feature. You enable it when you know you'll be accessing the same properties repeatedly and want to avoid the cost of linear scanning.

Types are views, not containers

This is a key concept, and it's worth exploring in more detail.

In most .NET serialization frameworks, a deserialized object owns its data. A Person class has a string Name field backed by its own heap-allocated string. The data lives in the object.

In V5, that's not what happens. A generated Person struct is just two fields: a reference to its parent IJsonDocument, and an int index into that document's metadata table. That's it. The struct doesn't hold the string "Alice". It holds a pointer to where "Alice" lives in the document's pooled UTF-8 byte buffer.

┌──────────────────┐      ┌─────────────────────────────────────┐
│  Person struct   │      │   ParsedJsonDocument (pooled)       │
│  ┌────────────┐  │      │  ┌─────────────────────────────┐    │
│  │ _parent ───┼──┼─────▶│  │ MetadataDb (token offsets)  │    │
│  │ _idx: 0    │  │      │  ├─────────────────────────────┤    │
│  └────────────┘  │      │  │ UTF-8 value buffer          │    │
└──────────────────┘      │  │ {"name":"Alice","age":30}   │    │
                          │  └─────────────────────────────┘    │
                          └─────────────────────────────────────┘

This means:

  1. Creating a typed view is free. doc.RootElement doesn't copy anything. It returns a struct with the document reference and index 0. Accessing person.Name returns another struct pointing at the same document with a different index.
  2. Multiple views share the same data. You can have Person, JsonElement, and Address structs all pointing into the same document. No duplication.
  3. The document owns the lifetime. When you dispose the ParsedJsonDocument, the pooled memory goes back to ArrayPool. Any struct that still references it becomes invalid. This is why the using statement matters.

So far we've used JsonElement, but the real power comes from typed documents. Given a generated Person type (from the source generator in post 2):

using var doc = ParsedJsonDocument<Person>.Parse(
    """{"name":"Alice","age":30}""");
Person person = doc.RootElement;

string name = (string)person.Name;      // "Alice"
int age = (int)person.Age;              // 30
bool valid = person.EvaluateSchema();   // true

person is a view. person.Name is a view. Neither allocates. The only allocation is the 136-byte document object itself.

Extended types

V5 supports types beyond what System.Text.Json offers natively:

JSON Schema format .NET Type Example
"format": "int128" Int128 Large integer IDs
"format": "uint128" UInt128 Large unsigned integer IDs
"format": "half" Half Low-precision floats
Arbitrary precision integer BigInteger Cryptographic or scientific values
Arbitrary precision BigNumber Financial or scientific values
"format": "uri" Utf8UriValue Absolute URIs
"format": "uri-reference" Utf8UriReferenceValue Absolute or relative URIs
"format": "iri" Utf8IriValue Internationalized URIs
"format": "iri-reference" Utf8IriReferenceValue Internationalized URI references
"format": "date" NodaTime.LocalDate Calendar dates
"format": "date-time" NodaTime.OffsetDateTime Timestamps with offset
"format": "duration" NodaTime.Period ISO 8601 durations

BigNumber is rarely needed, but when you do need it, it is essential. It's a custom arbitrary-precision decimal type that operates directly on the UTF-8 bytes of the JSON, without intermediate conversion to double or decimal. There is no precision loss and no floating-point surprises.

String and UTF-8 formatting

Every JSON type - JsonElement and all generated types - implements IFormattable, ISpanFormattable, and IUtf8SpanFormattable on .NET 9+. On netstandard2.0 the interfaces aren't available, but the underlying static formatting methods are still there, so you can call them directly. For numeric elements, this means you can format values with standard .NET format strings:

using var doc = ParsedJsonDocument<JsonElement>.Parse("""{"price": 1234.5}""");
JsonElement price = doc.RootElement.GetProperty("price"u8);

// String formatting with culture support
string display = price.ToString("C", CultureInfo.GetCultureInfo("en-GB"));
// "£1,234.50"

// String interpolation (uses IFormattable)
string message = $"Total: {price:N2}";
// "Total: 1,234.50"

For zero-allocation hot paths, write directly to a UTF-8 byte span:

Span<byte> buffer = stackalloc byte[64];
if (price.TryFormat(buffer, out int bytesWritten, "F2", CultureInfo.InvariantCulture))
{
    ReadOnlySpan<byte> utf8Price = buffer.Slice(0, bytesWritten);
    // Write to a Utf8JsonWriter, HTTP response, or log sink - no string allocation
}

The standard numeric format specifiers are all supported: G (general), F (fixed-point), N (number with grouping), E (scientific), C (currency), and P (percentage).

At a glance

JsonNode JsonDocument ParsedJsonDocument<T>
Memory model Per-node allocation Pooled, read-only Pooled, read-only (mutable via builder)
GC pressure ~1,528B (typical) ~480B ~136B
Mutable Yes No Via JsonDocumentBuilder
Schema validation No No Yes
Property access O(1) O(n) O(n), optional O(1) property map
Generic No No Yes (IJsonElement<T>)

Next up

We've seen how V5 pools memory for read-only documents. But what about mutation? In the next post, we'll look at JsonDocumentBuilder and JsonWorkspace. They provide the pooled, version-tracked builder pattern that's at the heart of V5's design trade-off with V4.



Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

Introducing the LogRocket MCP: Take the blindfold off your AI agents

1 Share

Most of the product and engineering teams I talk to are building and deploying AI agents, but these agents are blind to how customers are actually experiencing your product.

This is why I’m excited to announce that the LogRocket MCP is now available to everyone.

Let’s suppose your conversion rate dropped last week. You ask Claude or Cursor what went wrong, but find nothing obviously amiss.

When you enable the LogRocket MCP, you and your agents can watch thousands of session replays in minutes.

So now if conversion rate dips, the LogRocket MCP identifies the problem immediately: on mobile Chrome, autofill triggers a spinner that never resolves. This context, and a suggested fix, is delivered wherever you need it: Claude, Cursor, or right to your agent.

Let’s dive into how the MCP is changing the way our customers monitor their products.

What is the LogRocket MCP?

The LogRocket MCP connects your agents directly to LogRocket’s Galileo AI, which is already watching session replays, listening to customer calls, reading support tickets, and tracking product changes.

Galileo detects issues, diagnoses root causes, quantifies user impact, and suggests fixes. Via the MCP, it sends this context to your agent, without anyone on your team needing to pull up LogRocket:gif of LogRocket MCP agent watching real user sessions

How are product and engineering teams using the LogRocket MCP?

Rippling, the HR, payroll, and IT software provider, is using the MCP to identify customer issues in near-realtime.

Matt MacInnis, Rippling’s President and Chief Product Officer, posted about it on X:rippling tweets about using LogRocket MCP

Nick Ciubotariu, CTO at ShipStation Global, the shopping and logistics provider behind products like ShipStation and Stamps.com, shared how his team is connecting its coding agents to the MCP to generate PRs to fix user issues.

“We’re using the LogRocket MCP to feed real user session data directly to our AI agents,” Nick said. “When an issue surfaces, the agent doesn’t wait for us to investigate; it pulls the sessions, diagnoses the root cause, and opens a pull request automatically. That’s an amazing advantage, and it’s a great accelerator for our engineering teams and a huge benefit to our customers.”

The pattern we’re seeing across early customers: their agents flag issues faster, which means they ship fixes faster.

What can you use the LogRocket MCP for?

Three examples of agents real LogRocket customers are building:

  • An issue resolution agent that watches user sessions, surfaces usability and technical problems, and routes those issues to their coding agents to fix automatically.
  • A product research agent that connects to the code base, identifies new features being shipped, and shows how customers are using and responding to them.
  • A customer support agent that, when a customer has a problem, can see exactly what they experienced and help accordingly.

And that’s just a sampling. What agents will your team build?

Why this matters

When we founded LogRocket in 2016, the goal was to give teams a complete understanding of how users experience their product, without consuming all of their time.

Ask Galileo took us a big step forward. Teams could answer almost any question about their product experience in seconds.

The MCP takes it another step.

Galileo’s intelligence stops being something your team has to go look at. Now it helps you surface issues, resolve tickets, and propose fixes on its own.

The blindfold is off. We’re one step closer to software that fixes itself.

How to get started with the LogRocket MCP

The LogRocket MCP Server is available now.

Existing LogRocket customers can connect via the hosted server at mcp.logrocket.com/mcp: no local setup required, OAuth authentication, works with Cursor, Claude Desktop, Claude Code, Codex, and any MCP-compatible client.

If you’re new to LogRocket, you can learn more by checking out our docs or trying it for yourself at logrocket.com.

The post Introducing the LogRocket MCP: Take the blindfold off your AI agents appeared first on LogRocket Blog.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

Multi-agent patterns with the GitHub Copilot SDK (continued)

1 Share

This final post continues on the multi-agent path: instead of one agent doing more things, we compose multiple agents doing the right things.

Yesterday I demonstrated how to do this inside the Copilot SDK itself, today we look the broader ecosystem and I’ll show you how to integrate your Copilot SDK agent in the Microsoft Agent Framework.

Microsoft Agent Framework

The Microsoft Agent Framework(MAF) is the unified successor to Semantic Kernel and AutoGen. It provides a standard interface for building, orchestrating, and deploying AI agents. Dedicated integration packages let you wrap a Copilot SDK client as a first-class MAF agent — interchangeable with any other agent provider in the framework.

The key distinction from Part 1: custom agents inside the SDK work within a single Copilot session, with the Copilot runtime as orchestrator. MAF operates at a higher level — it can compose a Copilot SDK agent with agents backed by Azure OpenAI, Anthropic, or any other provider, using structured orchestration patterns that MAF controls.

Microsoft Agent Framework serves as the orchestration backbone while calling the GitHub Copilot SDK for the agent harness layer. Any agent in the workflow can delegate to a Copilot SDK-powered agent — leveraging its native Model Context Protocol support, skills integration, shell execution, and file operations — then pass results to the next agent in the pipeline.

Setup: Adding the MAF integration package

dotnet add package Microsoft.Agents.AI.GitHub.Copilot --prerelease

This adds the integration that lets you convert a CopilotClient into a standard MAF AIAgent.

The Core Conversion: AsAIAgent()

Create a CopilotClient and use the AsAIAgent extension method to create an agent. The Copilot agent is a standard MAF agent, so it supports tools, instructions, streaming, sessions, MCP servers, and built-in OpenTelemetry observability.

using GitHub.Copilot;
using Microsoft.Agents.AI;

await using var copilotClient = new CopilotClient();
await copilotClient.StartAsync();

AIAgent reviewAgent = copilotClient.AsAIAgent(
sessionConfig: new SessionConfig
{
    OnPermissionRequest=PermissionHandler.ApproveAll,
    Streaming=true,
Tools = [AIFunctionFactory.Create(GetProjectConventions)] }, ownsClient: true, name: "Code Reviewer", description: "You are a thorough code reviewer. Focus on correctness, clarity, and edge cases."
);

// Run standalone, just like any other MAF agent
Console.WriteLine(await copilotAgent.RunAsync("What changed in the last three commits?"));

Once wrapped as an AIAgent, the Copilot SDK agent is interchangeable with any other MAF agent. The orchestration layer doesn't know or care what's backing it.

Remark: At the moment of writing this blog post, there is a problem with the AsAIAgent extension method as there is a namespace conflict between the latest (preview) version of the package and the GitHub Copilot SDK NuGet package.

Advanced orchestration - An example

Multi-agent systems often start as a router that forwards to a specialist and sometimes break the first time an agent needs a follow-up question, more context from a peer, or realizes mid-turn that the request belongs elsewhere. Handoff orchestration is built for exactly that: you declare the agents and the directed edges between them, and the framework injects the handoff tools each agent uses to transfer control. Topology and guardrails stay with the developer; routing decisions stay with the agents.

await using var copilotClient = new CopilotClient();
await copilotClient.StartAsync();

AIAgent triage = copilotClient.AsAIAgent(new SessionConfig
        {
            OnPermissionRequest = PermissionHandler.ApproveAll,
        },
        name:"Triage Agent", 
        description: """
        You are a triage agent. Classify incoming requests:
        - If it's a bug report, hand off to 'bug-investigator'
        - If it's a feature request, hand off to 'feature-planner'
        - If it's unclear, ask the user to clarify before handing off
        """);

AIAgent bugInvestigator = copilotClient.AsAIAgent(new SessionConfig
        {
            OnPermissionRequest = PermissionHandler.ApproveAll,
        },
        name:"Bug Investigator", 
        description: """
        You investigate bug reports. Read code, trace execution, identify root causes.
        """);

// Azure OpenAI agent for structured planning output
var openAIClient = new OpenAI.OpenAIClient("<apikey>");
var featurePlanner=openAIClient.GetChatClient("gpt-4.1").AsAIAgent();

// Define the topology: triage can hand off to either specialist
HandoffWorkflowBuilder handoffBuilder = AgentWorkflowBuilder
    .CreateHandoffBuilderWith(featurePlanner)
        .WithHandoff(triage, bugInvestigator)
        .WithHandoff(triage, featurePlanner);

var workflow = handoffBuilder.Build();

await using StreamingRun run = await InProcessExecution.OpenStreamingAsync(workflow)
                                                          .ConfigureAwait(false);

await run.TrySendMessageAsync("Users are reporting that the export function produces empty CSV files when the date filter is active");

Triage receives every request. It decides which specialist is appropriate and hands off. The agents decide the routing; the developer controls which handoffs are allowed in the topology. Invalid routes (an agent trying to hand off to a destination not in the graph) are rejected by the framework.

Choosing between SDK custom agents and MAF orchestration

Both approaches produce multi-agent behaviour. The choice comes down to what you need:

  Copilot SDK Custom Agents Microsoft Agent Framework
Shared session context Yes — agents share conversation history No — agents have independent contexts
Orchestrator Copilot runtime (inference-based) MAF (deterministic graph topology)
Cross-provider No — all agents run on Copilot Yes — mix any MAF provider
Routing control Agent descriptions (semantic matching) You declare the topology and edges
Setup complexity Low — one SessionConfig Higher — MAF orchestrator + packages
Best for Mixed-intent interactive sessions Structured, repeatable pipelines

The two approaches are also composable. A Copilot SDK agent wrapped with AsAIAgent() can itself use custom agents internally — the MAF orchestrator sees only a single AIAgent, while internally the Copilot runtime delegates to its sub-agents. You can layer both patterns where it makes sense.

More information

MAF integration

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories