{"id":60832,"date":"2026-09-16T14:00:00","date_gmt":"2026-09-16T21:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=60832"},"modified":"2026-09-29T11:46:41","modified_gmt":"2026-09-29T18:46:41","slug":"build-your-own-ai-agent-harness-in-csharp-the-maf-claw-live-series","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/build-your-own-ai-agent-harness-in-csharp-the-maf-claw-live-series\/","title":{"rendered":"Build Your Own AI Agent Harness in C#, the MafClaw Live Series"},"content":{"rendered":"<p>A few weeks ago I wrote about going <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/from-dotnet-run-to-foundry-hosted-agent-in-3-lines-of-csharp\/\">from <code>dotnet run<\/code> to a Foundry Hosted Agent in three lines of C#<\/a>. The feedback was great. Developers liked the deployment story, the managed infrastructure, and especially the part where we did <strong>not<\/strong> spend the afternoon writing a Dockerfile, a session store, a telemetry pipeline, and a small distributed system just to expose one agent \ud83d\ude05.<\/p>\n<p>But that post starts near the end of the journey. It assumes you already have an agent worth deploying.<\/p>\n<p>So the next question is:<\/p>\n<blockquote>\n<p>&#8220;What should I put inside the agent before I deploy it?&#8221;<\/p>\n<\/blockquote>\n<p>Tools. Planning. Safe file access. Human approval. Memory. Skills. Shell commands. Code execution. Background agents. Observability. Governance. Evaluations.<\/p>\n<p>That list gets big very quickly.<\/p>\n<p>The good news is that you do not need to build the runtime for all of it from scratch. Microsoft Agent Framework includes an <strong>agent harness<\/strong>, and I am building a complete C# agent with it live, one capability at a time, in a four-part series called <strong>From Model to Agent: The Agent Framework Harness, Live in C#<\/strong>.<\/p>\n<p>The series streamed live simultaneously on the <strong><a href=\"https:\/\/www.youtube.com\/@dotnet\">.NET YouTube channel<\/a><\/strong> and Microsoft Reactor over four Thursdays in September. All four sessions are now available on demand, along with the complete C# sample repository, the audience slides, and the session guides. Let me show you what we built and why the harness makes this much easier.<\/p>\n<p><div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/aka.ms\/mafclaw\" target=\"_blank\">Watch the complete Agent Framework series<\/a><\/div><\/p>\n<h2>What we build across four sessions<\/h2>\n<p>We start with this:<\/p>\n<pre><code class=\"language-csharp\">AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions\n{\n    ChatOptions = new ChatOptions\n    {\n        Instructions = instructions,\n        Tools = tools\n    }\n});<\/code><\/pre>\n<p>Then we grow the same agent through four stages:<\/p>\n<ol>\n<li>Give it tools, web search, and a plan.<\/li>\n<li>Let it work with files, approvals, and durable memory.<\/li>\n<li>Add skills, shell, CodeAct, and background agents.<\/li>\n<li>Add observability, governance, evaluations, and a hosted deployment.<\/li>\n<\/ol>\n<p>That is the complete journey: from one call around an <code>IChatClient<\/code> to a capable agent that we can inspect, evaluate, govern, and run in Microsoft Foundry.<\/p>\n<h2>First: what is an agent harness?<\/h2>\n<p>A language model can generate text. An agent needs more.<\/p>\n<p>It needs a loop that can call tools, inspect the results, update a plan, remember useful information, request approval for risky actions, manage a growing context window, and keep working until the task is complete.<\/p>\n<p>That surrounding runtime is the <strong>harness<\/strong>.<\/p>\n<p><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>Where the term comes from<\/strong><\/p>The Microsoft Agent Framework team introduced the concept in the excellent <a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/build-your-own-claw-and-agent-harness-with-microsoft-agent-framework\/\">Build your own claw and agent harness with Microsoft Agent Framework<\/a> series. Their explanation is simple: a &#8220;claw&#8221; is a CLI-style agent built on top of a harness. You bring the model, instructions, and domain tools. The harness supplies the agentic machinery around them.<\/div><\/p>\n<p>In .NET, the key line is this one:<\/p>\n<pre><code class=\"language-csharp\">AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions\n{\n    ChatOptions = new ChatOptions\n    {\n        Instructions = \"You are a personal finance education assistant.\",\n        Tools = [StockTools.GetStockPrice]\n    }\n});<\/code><\/pre>\n<p>That call gives the agent a complete pipeline with capabilities such as:<\/p>\n<ul>\n<li>automatic function invocation<\/li>\n<li>history persistence after model calls<\/li>\n<li>planning with todo and agent-mode providers<\/li>\n<li>context compaction<\/li>\n<li>file memory<\/li>\n<li>web search when the model service supports it<\/li>\n<li>tool approvals<\/li>\n<li>skills<\/li>\n<li>OpenTelemetry instrumentation<\/li>\n<\/ul>\n<p>Each capability is configurable. You can replace it, disable it, or add your own provider.<\/p>\n<p>That is the advantage of starting with the harness: you spend your time on what makes the agent useful, instead of rebuilding the same orchestration loop for every project.<\/p>\n<h2>The agent we are building<\/h2>\n<p>Across the four sessions, we build one personal finance education assistant.<\/p>\n<p>Why finance? Because it gives us realistic boundaries to discuss:<\/p>\n<ul>\n<li>Looking up a stock price is a read-only tool call.<\/li>\n<li>Reading a portfolio means accessing user data.<\/li>\n<li>Writing a report changes a file.<\/li>\n<li>Placing a simulated trade is a side effect and needs approval.<\/li>\n<li>Remembering a risk profile needs durable, user-scoped memory.<\/li>\n<li>Calculating portfolio value is better done with code than model arithmetic.<\/li>\n<li>Running shell commands requires confinement and policy.<\/li>\n<li>A production finance agent needs traces, governance, and evaluations.<\/li>\n<\/ul>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>This is a learning scenario<\/strong><\/p>All prices and transactions in the samples are mock and illustrative. This is not financial advice. It is a useful scenario for learning how agent systems behave when tools have different levels of risk.<\/div><\/p>\n<p>The complete code is in the <a href=\"https:\/\/aka.ms\/mafclaw\/repo\">MafClaw sample repository<\/a>.<\/p>\n<h2>Session 1: turn a model into an agent<\/h2>\n<p>In <a href=\"https:\/\/www.youtube.com\/watch?v=iUs15X1v2w4\">Meet Your Claw: A Harness in Three Lines of C#<\/a>, we started with the smallest useful agent.<\/p>\n<p>First, create an <code>IChatClient<\/code> backed by a model in Microsoft Foundry:<\/p>\n<pre><code class=\"language-csharp\">IChatClient chatClient =\n    new AIProjectClient(new Uri(endpoint), new AzureCliCredential())\n        .GetProjectOpenAIClient()\n        .GetResponsesClient()\n        .AsIChatClient(model);<\/code><\/pre>\n<p>Then wrap it with the harness and give it one custom tool:<\/p>\n<pre><code class=\"language-csharp\">AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions\n{\n    ChatOptions = new ChatOptions\n    {\n        Instructions = \"\"\"\n            You are a personal finance education assistant.\n            Use get_stock_price for stock prices.\n            Use hosted web search for recent market news and cite sources.\n            Use the todo list to track multi-step work.\n            \"\"\",\n        Tools = [StockTools.GetStockPrice]\n    }\n});<\/code><\/pre>\n<p>The custom tool is ordinary C#. Agent Framework generates its tool schema from the function signature and descriptions:<\/p>\n<pre><code class=\"language-csharp\">[Description(\"Gets the illustrative stock price for a ticker symbol.\")]\npublic static string GetStockPriceBySymbol(\n    [Description(\"Stock ticker symbol, e.g. MSFT\")] string symbol)\n{\n    var upper = symbol.Trim().ToUpperInvariant();\n    return upper switch\n    {\n        \"MSFT\" =&gt; \"MSFT: 512.34 USD (mock)\",\n        \"NVDA\" =&gt; \"NVDA: 184.72 USD (mock)\",\n        \"AMZN\" =&gt; \"AMZN: 241.18 USD (mock)\",\n        _ =&gt; $\"{upper}: not available\"\n    };\n}\n\npublic static AIFunction GetStockPrice { get; } =\n    AIFunctionFactory.Create(\n        GetStockPriceBySymbol,\n        \"get_stock_price\");<\/code><\/pre>\n<p>Now the difference between a chat application and an agent becomes visible.<\/p>\n<p>Ask:<\/p>\n<pre><code class=\"language-text\">What is the price of MSFT?<\/code><\/pre>\n<p>The model chooses the tool, the harness invokes it, the result returns to the model, and the agent produces the final answer.<\/p>\n<p>Ask something larger:<\/p>\n<pre><code class=\"language-text\">Review my watchlist and suggest what I should research next.<\/code><\/pre>\n<p>The harness can create a plan and maintain a todo list while it works. We did not write a custom planning engine for the demo. We configured the behavior that makes this finance agent ours, and the harness supplied the planning runtime.<\/p>\n<p>Watch Session 1:<\/p>\n<p><iframe loading=\"lazy\" width=\"800\" height=\"450\" src=\"https:\/\/www.youtube.com\/embed\/iUs15X1v2w4\" allowfullscreen><\/iframe><\/p>\n<h2>Session 2: work with user data safely<\/h2>\n<p>An agent becomes much more useful when it can work with your data.<\/p>\n<p>It also becomes much more dangerous.<\/p>\n<p>In <a href=\"https:\/\/www.youtube.com\/watch?v=V58coa0llUo\">Working With Your Data, Safely: Files, Approvals and Memory<\/a>, we gave the finance assistant access to a portfolio CSV, but only inside an approved working directory:<\/p>\n<pre><code class=\"language-csharp\">var workingDirectory =\n    Path.Combine(AppContext.BaseDirectory, \"working\");\n\nAIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions\n{\n    FileAccessStore =\n        new FileSystemAgentFileStore(workingDirectory),\n\n    ChatOptions = new ChatOptions\n    {\n        Instructions = \"\"\"\n            The user's portfolio is in portfolio.csv.\n            Read it before answering portfolio questions.\n            Write generated reports under the approved working folder.\n            \"\"\",\n    }\n});<\/code><\/pre>\n<p>The model does not receive arbitrary filesystem access. The application supplies a file store rooted at one folder, and the harness exposes file tools against that boundary.<\/p>\n<p>This means the happy path works:<\/p>\n<pre><code class=\"language-text\">What is in my portfolio?<\/code><\/pre>\n<p>And the unsafe path is blocked:<\/p>\n<pre><code class=\"language-text\">Read C:\\some-other-folder\\outside-portfolio.csv<\/code><\/pre>\n<p>The second boundary is human approval.<\/p>\n<p>A simulated trade is wrapped in <code>ApprovalRequiredAIFunction<\/code>:<\/p>\n<pre><code class=\"language-csharp\">public static AIFunction RequestSimulatedTrade { get; } =\n    new ApprovalRequiredAIFunction(\n        AIFunctionFactory.Create(\n            RequestSimulatedTradeOrder,\n            \"request_simulated_trade\"));<\/code><\/pre>\n<p>The model can request the action, but it cannot execute it directly. The harness emits an approval request first. The host application can show exactly which tool and arguments need approval, then return the human decision to the same agent session.<\/p>\n<p>We also configured a low-friction safe path:<\/p>\n<pre><code class=\"language-csharp\">ToolApprovalAgentOptions = new ToolApprovalAgentOptions\n{\n    AutoApprovalRules =\n    [\n        FileAccessProvider.ReadOnlyToolsAutoApprovalRule\n    ],\n},<\/code><\/pre>\n<p>Read-only file operations can proceed automatically. Writes, destructive operations, and the simulated trade still cross an approval boundary.<\/p>\n<p>That distinction matters. If every harmless read interrupts the user, approval becomes noise. The goal is not to show more confirmation dialogs. The goal is to make consequential actions visible.<\/p>\n<h3>A question from the audience became a new sample<\/h3>\n<p>During the live Q&amp;A, someone asked:<\/p>\n<blockquote>\n<p>&#8220;What if the user does not answer the approval request?&#8221;<\/p>\n<\/blockquote>\n<p>Great question.<\/p>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Silence is not consent<\/strong><\/p>An approval flow that waits forever is not complete. So, after the session, I built a new sample with a bounded approval policy: a five-second deadline per attempt, a maximum of five attempts, retries for missing or invalid input, immediate approval for <code>y<\/code>, immediate denial for <code>n<\/code>, automatic denial after the final attempt, sticky denial for the rest of the user prompt, and a limit on repeated approval rounds from the model.<\/div><\/p>\n<p>The policy starts with a small configuration:<\/p>\n<pre><code class=\"language-csharp\">const int maxApprovalAttempts = 5;\nvar approvalTimeout = TimeSpan.FromSeconds(5);\n\nvar approvalPolicy = new TimedApprovalPolicy(\n    maxApprovalAttempts,\n    approvalTimeout);<\/code><\/pre>\n<p>You can find the complete implementation in <a href=\"https:\/\/github.com\/elbruno\/mafclaw\/tree\/main\/session-02\/samples\/22-approval-retries-timeouts\">Sample 22: approval retries and timeouts<\/a>.<\/p>\n<p>The final part of Session 2 was memory. We compared local, application-owned JSON memory with managed Foundry Memory, and discussed why the model saying &#8220;I saved that&#8221; is not proof that anything was persisted. The application needs a real storage result, a scope, and a way to surface failures.<\/p>\n<p>Watch Session 2:<\/p>\n<p><iframe loading=\"lazy\" width=\"800\" height=\"450\" src=\"https:\/\/www.youtube.com\/embed\/V58coa0llUo\" allowfullscreen><\/iframe><\/p>\n<h2>Session 3: skills, shell, CodeAct, and background agents<\/h2>\n<p>The first two sessions make the agent useful and safe. The third makes it more capable.<\/p>\n<p>In <a href=\"https:\/\/www.youtube.com\/watch?v=rMhX0-oE4aY\">Scaling the Claw: Skills, Shell, CodeAct and Background Agents<\/a>, we added four capabilities without turning the system prompt into a 400-page instruction manual. You can try each one separately:<\/p>\n<ul>\n<li><strong><a href=\"https:\/\/github.com\/elbruno\/mafclaw\/tree\/main\/session-03\/samples\/11-skills-agent\">Skills<\/a><\/strong> let the agent discover a skill and load its instructions when needed. No need to put every valuation rule in the main prompt.<\/li>\n<li><strong><a href=\"https:\/\/github.com\/elbruno\/mafclaw\/tree\/main\/session-03\/samples\/21-confined-shell-agent\">Shell<\/a><\/strong> lets it work with commands inside a confined working directory, with command policy, timeouts, and explicit approval.<\/li>\n<li><strong><a href=\"https:\/\/github.com\/elbruno\/mafclaw\/tree\/main\/session-03\/samples\/31-codeact-agent\">CodeAct<\/a><\/strong> lets it calculate the mock portfolio value with Python in a Hyperlight micro-VM, rather than asking the model to do arithmetic in prose.<\/li>\n<li><strong><a href=\"https:\/\/github.com\/elbruno\/mafclaw\/tree\/main\/session-03\/samples\/41-background-agents\">Background agents<\/a><\/strong> let it delegate independent research tasks and collect the results.<\/li>\n<\/ul>\n<p><div class=\"alert alert-warning\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Warning\"><\/i><strong>Confinement, not just approval<\/strong><\/p>Shell and code execution are powerful capabilities. Confinement, policy, and approval improve the experience, but they are not a substitute for isolation. That boundary still matters.<\/div><\/p>\n<p>We still choose what can execute. The skills sample rejects scripts. The CodeAct sample automatically approves generated code only <strong>inside the sandbox<\/strong>, with mock data and no direct host filesystem access. That demo choice does not mean sandboxing replaces human approval.<\/p>\n<p>For background work, start with one focused research agent and give it to the harness:<\/p>\n<pre><code class=\"language-csharp\">AIAgent research = chatClient.AsAIAgent(\n    name: \"TickerResearchAgent\",\n    description: \"Searches the web for recent news about a single stock ticker.\",\n    instructions: \"Research one ticker and return facts with sources.\",\n    tools: [new HostedWebSearchTool()]);\n\nAIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions\n{\n    BackgroundAgents = [research],\n});<\/code><\/pre>\n<p>Now the main agent can hand off ticker research without us writing a queue and a result collector first. The <a href=\"https:\/\/github.com\/elbruno\/mafclaw\/tree\/main\/session-03\">Session 3 guide and samples<\/a> take this further with specialist teams, deadlines, and a report that waits for human approval.<\/p>\n<p>Watch Session 3:<\/p>\n<p><iframe loading=\"lazy\" width=\"800\" height=\"450\" src=\"https:\/\/www.youtube.com\/embed\/rMhX0-oE4aY\" allowfullscreen><\/iframe><\/p>\n<h2>Session 4: make the agent production-ready<\/h2>\n<p>At this point the claw can plan, use tools, work with files, request approvals, remember facts, load skills, execute code, and delegate research.<\/p>\n<p>That is the moment when somebody asks:<\/p>\n<blockquote>\n<p>&#8220;OK, the agent is done\u2026 now, how do I deploy this thing?&#8221;<\/p>\n<\/blockquote>\n<p>Yes, we are back to the question from my previous post \ud83d\ude04.<\/p>\n<p>In <a href=\"https:\/\/www.youtube.com\/watch?v=dCIBza-WxUc\">Production Ready: Observability, Governance and Deployment<\/a>, we worked through four questions:<\/p>\n<ol>\n<li><strong>Observability:<\/strong> What did the agent actually do? Follow its model and tool calls with OpenTelemetry.<\/li>\n<li><strong>Governance:<\/strong> Which actions should it be allowed to take? Keep approval boundaries and optionally connect Microsoft Purview.<\/li>\n<li><strong>Evaluations:<\/strong> How do we check quality beyond &#8220;it felt right in the demo&#8221;?<\/li>\n<li><strong>Deployment:<\/strong> How do we expose the agent over HTTP without carrying every local capability into production?<\/li>\n<\/ol>\n<p><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Choose what you deploy<\/strong><\/p>Local filesystem and shell access may be useful on your machine. That does not mean a shared hosted container should inherit them. Choose the capabilities each host needs.<\/div><\/p>\n<p>First, make the work visible. We wrap the model and the harness with OpenTelemetry, keeping sensitive content out of the traces:<\/p>\n<pre><code class=\"language-csharp\">using var observedModel = model.AsBuilder()\n    .UseOpenTelemetry(\n        sourceName: TraceConsole.SourceName,\n        configure: telemetry =&gt; telemetry.EnableSensitiveData = false)\n    .Build();\n\nvar harness = observedModel.AsHarnessAgent(options);\n\nvar agent = harness.AsBuilder()\n    .UseOpenTelemetry(\n        TraceConsole.SourceName,\n        telemetry =&gt; telemetry.EnableSensitiveData = false)\n    .Build();<\/code><\/pre>\n<p>Now we can follow the agent&#8217;s model and tool calls instead of guessing what happened. A companion sample sends traces, metrics, and logs to the local Aspire dashboard. Fixture runs are labeled separately from live Foundry model runs.<\/p>\n<p>Then we start small with hosting: a greeting agent, not the whole finance assistant. Agent Framework handles the Responses protocol:<\/p>\n<pre><code class=\"language-csharp\">var builder = WebApplication.CreateBuilder();\nbuilder.Services.AddFoundryResponses(agent);\n\nawait using var app = builder.Build();\napp.MapFoundryResponses();\nawait app.RunAsync();<\/code><\/pre>\n<p>That gets us a local HTTP endpoint. It does not prove a cloud deployment: identity, permissions, Purview licensing, and remote Foundry evaluation still need their own setup and checks.<\/p>\n<p>The <a href=\"https:\/\/github.com\/elbruno\/mafclaw\/tree\/main\/session-04\">Session 4 guide and samples<\/a> also answer questions from Session 3 about external MCP tools, saving and restoring an <code>AgentSession<\/code>, and running with Foundry Local. We try those pieces separately before bringing them together in the finance app.<\/p>\n<p>For the next step, my earlier <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/from-dotnet-run-to-foundry-hosted-agent-in-3-lines-of-csharp\/\">three-lines-of-C# post<\/a> introduces the hosting model. This claw has more capabilities, so we have more decisions to make before deploying it.<\/p>\n<p>Watch Session 4:<\/p>\n<p><iframe loading=\"lazy\" width=\"800\" height=\"450\" src=\"https:\/\/www.youtube.com\/embed\/dCIBza-WxUc\" allowfullscreen><\/iframe><\/p>\n<h2>Why start with the harness?<\/h2>\n<p>You can build every one of these pieces yourself.<\/p>\n<p>You can write a tool loop, serialize history after every service call, maintain a plan, compact context, build a memory layer, design an approval protocol, load skills, manage background workers, and instrument the whole pipeline.<\/p>\n<p>Sometimes you need that level of control.<\/p>\n<p>But most teams want to spend their time on the domain behavior that makes the agent valuable:<\/p>\n<ul>\n<li>What tools should it have?<\/li>\n<li>What data can it access?<\/li>\n<li>Which actions require approval?<\/li>\n<li>What should it remember?<\/li>\n<li>Which skills should it load?<\/li>\n<li>Which tasks can run concurrently?<\/li>\n<li>What policies apply?<\/li>\n<li>How will we evaluate whether it works?<\/li>\n<\/ul>\n<p>The harness gives those decisions a composable home.<\/p>\n<p>You still own the boundaries. You still choose the tools. You still decide what gets approved, remembered, executed, traced, and deployed.<\/p>\n<p>You just do not have to rebuild the agent runtime before answering any of those questions.<\/p>\n<h2>Watch the complete series<\/h2>\n<p>The Microsoft Agent Framework blog has the complete written, .NET-and-Python version of this journey:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/build-your-own-claw-and-agent-harness-with-microsoft-agent-framework\/\">Build your own claw and agent harness with Microsoft Agent Framework<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/meet-your-agent-harness-and-claw\/\">Part 1: Meet your agent harness and claw<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/agent-harness-working-with-your-data-safely\/\">Part 2: Working with your data, safely<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/agent-harness-scaling-the-claw-or-harness-capabilities\/\">Part 3: Scaling the claw<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/agent-harness-making-your-claw-production-ready\/\">Part 4: Making your claw production-ready<\/a><\/li>\n<\/ul>\n<p>In the series, we build the .NET version one capability at a time. All four recordings are available on demand:<\/p>\n<ol>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=iUs15X1v2w4\">Meet Your Claw: A Harness in Three Lines of C#<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=V58coa0llUo\">Working With Your Data, Safely: Files, Approvals and Memory<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=rMhX0-oE4aY\">Scaling the Claw: Skills, Shell, CodeAct and Background Agents<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=dCIBza-WxUc\">Production Ready: Observability, Governance and Deployment<\/a><\/li>\n<\/ol>\n<p><div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/aka.ms\/mafclaw\" target=\"_blank\">Watch the complete Agent Framework series<\/a><\/div>\n<div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/aka.ms\/mafclaw\/repo\" target=\"_blank\">Get the complete C# samples<\/a><\/div><\/p>\n<p>Bring your questions. The approval timeout sample exists because someone did exactly that.<\/p>\n<h2>Learn more<\/h2>\n<ul>\n<li><a href=\"https:\/\/aka.ms\/mafclaw\/blog\">Series introduction: From Model to Agent<\/a><\/li>\n<li><a href=\"https:\/\/aka.ms\/mafclaw\">Microsoft Reactor series page<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/@dotnet\">.NET YouTube channel<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=iUs15X1v2w4\">Session 1: Meet Your Claw: A Harness in Three Lines of C#<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=V58coa0llUo\">Session 2: Working With Your Data, Safely: Files, Approvals and Memory<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=rMhX0-oE4aY\">Session 3: Scaling the Claw: Skills, Shell, CodeAct and Background Agents<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=dCIBza-WxUc\">Session 4: Production Ready: Observability, Governance and Deployment<\/a><\/li>\n<\/ul>\n<p>Happy coding!<\/p>\n<p>Bruno<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I am building a complete C# agent live, from a single call around an IChatClient to a production-ready, observable, governed agent, using the Microsoft Agent Framework harness in a 4-part Microsoft Reactor series.<\/p>\n","protected":false},"author":120281,"featured_media":60952,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,7781,756,7252],"tags":[8210,58,8158,8209],"class_list":["post-60832","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-ai","category-csharp","category-cloud","tag-agent-harness","tag-csharp","tag-microsoft-agent-framework","tag-microsoft-reactor"],"acf":[],"blog_post_summary":"<p>I am building a complete C# agent live, from a single call around an IChatClient to a production-ready, observable, governed agent, using the Microsoft Agent Framework harness in a 4-part Microsoft Reactor series.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/60832","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/120281"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=60832"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/60832\/revisions"}],"predecessor-version":[{"id":60951,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/60832\/revisions\/60951"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/60952"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=60832"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=60832"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=60832"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}