Section 18

Agentic AI: from chatbots to autonomous agents

LLMs that plan, use tools, remember and act in a loop toward a goal, plus the protocols (MCP, A2A), patterns and guardrails that make them safe in an enterprise.

18.1 What is Agentic AI?

An AI agent is an LLM that decides its own next steps. It reasons, calls tools, observes the results and repeats until the goal is met.

Chatbotanswers from memory
→
RAG assistantanswers from your docs
→
WorkflowLLM steps in fixed code paths
→
Single agentchooses tools & steps
→
Multi-agent systemagents collaborate
Autonomy, power and risk increase left → right

🧠 Model (brain)

Reasoning and decision-making.

🛠 Tools (hands)

APIs, search, code execution, databases, other agents.

💾 Memory

Conversation state, long-term knowledge, past experiences.

🗺 Planning

Break goals into steps, reflect, re-plan.

🛡 Guardrails

Permissions, limits, approvals, monitoring.

How to implement it
Building blockLibrary / APIPackage
Model (brain)IChatClientMicrosoft.Extensions.AI
Agent + loopAIAgent / ChatClientAgent (chatClient.AsAIAgent(...)), AgentSessionMicrosoft.Agents.AI (Agent Framework, GA since April 2026)
Tools (hands)AIFunctionFactory.Create, MCP toolsMicrosoft.Extensions.AI, ModelContextProtocol
MemorySessions, chat reducers, vector storesMicrosoft.Agents.AI, Microsoft.Extensions.VectorData.Abstractions
Planning / multi-stepGraph workflows and orchestrationsMicrosoft.Agents.AI.Workflows
Hosted agentsAzure AI Foundry Agent ServiceAzure.AI.Projects, Azure.AI.Projects.Agents
AIAgent agent = chatClient.AsAIAgent(
    name: "CardAssistant",
    instructions: "You help customers with card issues. Ask before doing anything risky.",
    tools: [AIFunctionFactory.Create(GetCardStatus), AIFunctionFactory.Create(BlockCard)]);

AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("I lost my card in Bali", session));

Agent Framework is the successor to Semantic Kernel agents and AutoGen. Semantic Kernel still works, but start new agent work on Agent Framework.

Chatbot vs Agent in one line 🤖

A chatbot tells you how to reset your card PIN.

An agent checks your identity, calls the card API, resets the PIN, confirms by SMS, and asks for approval before anything risky.

Agents = LLM + tools + memory + a loop. With great autonomy comes great need for guardrails.

#AgenticAI #GenAI #AIAgents

18.2 Workflows vs Agents (and the 5 workflow patterns) Added

Workflows: LLMs and tools follow paths you coded. Agents: the LLM decides the path. Use the simplest option that works.

1. Prompt chaining

LLM 1
→
check
→
LLM 2

Fixed sequence, e.g. draft → review → translate.

2. Routing

Router
→
A | B | C

Classify, then send to a specialised prompt or model (complaints vs FAQs).

3. Parallelisation

Split
⇉
LLMs
⇉
Merge

Sectioning (subtasks) or voting (several tries for confidence).

4. Orchestrator-workers

Orchestrator
→
workers…

A central LLM plans subtasks dynamically and delegates them.

5. Evaluator-optimiser

Generate
⇄
Critique

Loop until quality criteria are met.

🤖 Agent

LLM
⇄
tools / env

Open-ended loop. Use it when the steps can't be predicted in advance.

  • Workflows are predictable, testable and cheaper. Agents are flexible but cost more and are harder to control. Start with a workflow and add autonomy only where it pays off (Anthropic, "Building effective agents").
How to implement it
PatternLibrary / API
Prompt chaining, routingPlain C# over IChatClient: call, check, call again; GetResponseAsync<T> to classify, then switch
Parallelisation (sectioning / voting)built-in Task.WhenAll over several calls
Orchestrator-workers, evaluator-optimiserAgent Framework workflows (Microsoft.Agents.AI.Workflows): executors and edges in a graph, with streaming, checkpointing and human-in-the-loop
Long-running, durable stepsDurable Functions (Microsoft.Azure.Functions.Worker.Extensions.DurableTask) for hours/days-long flows that survive restarts
Open-ended agentMicrosoft.Agents.AI (AIAgent)
public enum Route { Complaint, Faq, Fraud }
public sealed record Classification(Route Route);

// Routing workflow: the code decides the path, the LLM only classifies
var c = (await chat.GetResponseAsync<Classification>($"Classify this message: {message}")).Result;

string reply = c.Route switch
{
    Route.Fraud     => await EscalateToFraudTeamAsync(message),   // no LLM on the risky path
    Route.Complaint => (await complaintsAgent.RunAsync(message)).Text,
    _               => (await faqAgent.RunAsync(message)).Text
};

18.3 The agent loop (ReAct) Added

ReAct = Reason + Act. Think, act with a tool, observe the result, repeat.

Perceive
→
Reason / plan
→
Act (tool)
→
Observe
↺
until done / limit hit
  • Always set stop conditions: max steps, max tokens or cost, timeouts. Agents can loop forever.
  • Variants: Plan-and-execute (plan everything first, then run it), Reflexion (self-critique after failures).
How to implement it
Library / APIPackageUse it for
FunctionInvokingChatClientMicrosoft.Extensions.AI (UseFunctionInvocation())Runs the ReAct loop for you: model asks for a tool, the tool runs, the result goes back, repeat
Step limitFunctionInvokingChatClient.MaximumIterationsPerRequestStop condition so the agent can't loop forever
Token / time budgetChatOptions.MaxOutputTokens, CancellationTokenSource.CancelAfterCap cost and wall-clock time per task
ChatClientAgentMicrosoft.Agents.AIThe same loop wrapped as an agent, with sessions and middleware
IChatClient chat = new ChatClientBuilder(inner)
    .UseFunctionInvocation(configure: f => f.MaximumIterationsPerRequest = 8)  // max steps
    .Build();

using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60));          // max time
ChatResponse r = await chat.GetResponseAsync(goal,
    new ChatOptions { Tools = tools, MaxOutputTokens = 1_000 }, cts.Token);

18.4 Tools & function calling Added

You describe tools with a name, a description and a JSON schema. The LLM replies with a structured tool call. Your code runs it and sends the result back.

  • Good tools: clear names and descriptions, narrow scope, validated inputs, helpful error messages, idempotent where possible.
  • Run tools with the end user's identity (delegated auth), not a super-user service account.
  • Fewer, well-designed tools beat 100 overlapping ones. The model gets confused.
How to implement it
Library / APIPackageUse it for
AIFunctionFactory.CreateMicrosoft.Extensions.AITurn any C# method into a tool. The JSON schema is generated from the parameters and [Description] attributes
ChatOptions.Tools / ToolModeMicrosoft.Extensions.AIOffer tools per request; ChatToolMode.RequireAny forces a call
Delegated identityMicrosoft.Identity.Web (on-behalf-of), IHttpClientFactoryTools call downstream APIs as the end user, not a super-user
Input validationbuilt-in System.ComponentModel.DataAnnotationsValidate tool arguments; return a clear error string the model can act on
public sealed class CardTools(ICardApi cards)
{
    [Description("Gets the status of a customer's card by its last 4 digits.")]
    public async Task<string> GetCardStatus([Description("Last 4 digits of the card")] string last4) =>
        last4.Length == 4 ? await cards.GetStatusAsync(last4) : "Error: last4 must be 4 digits";
}

IChatClient chat = new ChatClientBuilder(inner).UseFunctionInvocation().Build();
var cardTools = new CardTools(cardApi);

var options = new ChatOptions { Tools = [AIFunctionFactory.Create(cardTools.GetCardStatus)] };
ChatResponse reply = await chat.GetResponseAsync("Is my card ending 4821 blocked?", options);

The model only sees names, descriptions and parameter schemas, so write them for the model: clear verbs, narrow scope, few parameters.

18.5 Memory & planning Added

Memory lets an agent keep context within a task and across sessions. Planning lets it break a goal into steps and recover from mistakes.

Short-term (working)

The current conversation and scratchpad in the context window. Summarise or trim as it grows.

Long-term

Stored outside the model (vector DB, key-value store): user preferences, facts, past cases.

Episodic / semantic / procedural

Past experiences · facts about the world · how-to skills and instructions.

State & checkpoints

Persist agent state so long tasks can pause, resume or wait for human approval (e.g. LangGraph checkpoints).

Planning techniques

How to implement it
Memory typeLibrary / APINotes
Short-termList<ChatMessage> (Microsoft.Extensions.AI); AgentSession (Microsoft.Agents.AI)The conversation so far, sent with each call
Trim / summariseMessageCountingChatReducer, SummarizingChatReducer (IChatReducer)Keep the system message + recent turns, or fold old turns into a summary. Experimental APIs (warning MEAI001)
Long-termA VectorData collection (Microsoft.Extensions.VectorData.Abstractions); Agent Framework context providersStore facts and past cases as embeddings and inject the relevant ones per turn
State & checkpointsAgent Framework workflow checkpointing; serialise sessions to Cosmos DB / Redis / SQLPause, resume, or wait days for a human approval
PlanningGetResponseAsync<Plan> (structured output), then execute steps in a workflowPlan-and-execute with a typed, inspectable plan
// Short-term memory: keep the system prompt + the last 20 messages
IChatReducer reducer = new MessageCountingChatReducer(20);
List<ChatMessage> history = [new(ChatRole.System, systemPrompt)];

history.Add(new(ChatRole.User, userInput));
var trimmed = await reducer.ReduceAsync(history, ct);
ChatResponse r = await chat.GetResponseAsync(trimmed, options, ct);
history.AddMessages(r);

18.6 Multi-agent patterns Added

Several specialised agents work together, like a team with roles.

👔 Supervisor / orchestrator

Supervisor
→
Research · Writer · Checker

A central agent routes work and combines the results.

🏢 Hierarchical

Supervisors of supervisors, for big problems.

🏭 Sequential pipeline

Agent A → B → C, like an assembly line.

🤝 Handoff (swarm)

Agents pass control to each other ("transfer to billing agent").

💬 Group chat / debate

Agents discuss or critique each other to reach a better answer.

  • Frameworks: LangGraph, Microsoft Agent Framework / Semantic Kernel / AutoGen, CrewAI, OpenAI Agents SDK, Google ADK, Azure AI Foundry Agent Service, Amazon Bedrock Agents.
  • More agents means more cost, latency and failure modes. Use multiple agents only when roles really differ.
How to implement it
PatternLibrary / APINotes
Sequential pipelineAgentWorkflowBuilder.BuildSequentialEach agent works on the previous agent's output
Concurrent, handoff, group chatAgentWorkflowBuilder orchestrationsFan-out/merge, "transfer to billing agent", agents debating in a shared chat
Supervisor (Magentic)MagenticWorkflowBuilder previewA manager agent plans and picks the next agent. Experimental in .NET (MAAIW001)
Agent as a tool (hierarchical)Wrap a sub-agent as an AIFunction for a parent agentSimple supervisor without a workflow engine
Across services / vendorsA2A (see next section)Agents in other processes or frameworks

All in Microsoft.Agents.AI.Workflows. Tool approvals pause the workflow and surface as events.

AIAgent researcher = chat.AsAIAgent(name: "Researcher", instructions: "Find the relevant policy facts.");
AIAgent writer     = chat.AsAIAgent(name: "Writer",     instructions: "Draft a clear customer reply.");
AIAgent checker    = chat.AsAIAgent(name: "Checker",    instructions: "Check the reply against policy and tone.");

var workflow = AgentWorkflowBuilder.BuildSequential([researcher, writer, checker]);
// Run it with InProcessExecution and read the streamed WorkflowEvents

18.7 MCP & A2A protocols Added

MCP (Model Context Protocol) is a standard way for AI apps to connect to tools and data, "USB-C for AI". A2A (Agent2Agent) is a standard for agents to talk to each other.

Host appIDE, chat, agent
→
MCP client
⇄JSON-RPC (stdio / streamable HTTP)
MCP server: Jira
MCP server: SQL DB
MCP server: Internal APIs

MCP primitives

  • Tools: actions the model can call
  • Resources: data the app can read (files, records)
  • Prompts: reusable templates

Build a connector once, and any MCP-compatible app or agent can use it, instead of N×M custom integrations.

A2A

  • Agents publish an Agent Card (capabilities, endpoint, auth)
  • Agents delegate tasks to each other across vendors and frameworks
  • MCP = agent ↔ tools. A2A = agent ↔ agent
  • Treat MCP servers like any integration: authentication (OAuth), least-privilege scopes, input validation, audit logs, and trusting only vetted servers (tool poisoning is a real risk).
How to implement it
Library / APIPackageUse it for
MCP server (stdio)ModelContextProtocolOfficial C# SDK (v1.0 March 2026, now 2.x). [McpServerTool], [McpServerResource], [McpServerPrompt] attributes
MCP server (HTTP)ModelContextProtocol.AspNetCoreStreamable HTTP transport via MapMcp(), with ASP.NET Core auth (OAuth)
MCP clientModelContextProtocol (McpClient)Its tools are AIFunctions, so pass them straight to ChatOptions.Tools or an agent
A2AA2A, A2A.AspNetCore previewPublish an Agent Card and handle tasks from other agents (MapA2A, A2AClient)
A2A for Agent FrameworkMicrosoft.Agents.AI.Hosting.A2A.AspNetCore previewExpose an AIAgent over A2A
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMcpServer()
    .WithHttpTransport()             // streamable HTTP
    .WithToolsFromAssembly();        // finds [McpServerTool] methods

var app = builder.Build();
app.MapMcp("/mcp");                  // add .RequireAuthorization() in real life
app.Run();

[McpServerToolType]
public static class CardTools
{
    [McpServerTool, Description("Gets the status of a card by its last 4 digits.")]
    public static string GetCardStatus(string last4) => $"Card ending {last4} is active.";
}

18.8 Guardrails, safety & human-in-the-loop Added

Agents act in the real world, so wrap them in controls before, during and after every step.

Input guardrailsprompt injection · PII · topic filter
→
Agent
→
Tool guardrailsallowlist · least privilege · sandbox · HITL approval
→
Output guardrailsgroundedness · toxicity · schema · PII redaction

Prompt injection

Direct: "ignore previous instructions…". Indirect: hidden instructions inside retrieved web pages, emails or documents. Treat all retrieved content as untrusted data.

Excessive agency

Too many tools or permissions. Scope tools tightly and require approval for money movement, deletions and external communications.

Budgets & limits

Max steps, tokens, cost and time per task. Rate limits on tools.

Audit & explainability

Log every thought, tool call and result for review and compliance.

OWASP Top 10 for LLM Applications (2025)

LLM01 Prompt Injection · LLM02 Sensitive Information Disclosure · LLM03 Supply Chain · LLM04 Data & Model Poisoning · LLM05 Improper Output Handling · LLM06 Excessive Agency · LLM07 System Prompt Leakage · LLM08 Vector & Embedding Weaknesses · LLM09 Misinformation · LLM10 Unbounded Consumption

  • Human-in-the-loop for high-impact actions. Human-on-the-loop (monitoring) for low-risk ones.
  • Responsible AI: fairness, transparency, privacy, accountability. Align with your organisation's AI policy and risk assessments.
How to implement it
GuardrailLibrary / APINotes
Harmful contentAzure.AI.ContentSafety (ContentSafetyClient.AnalyzeText)Hate, violence, sexual, self-harm scores on input and output
Prompt injectionAzure AI Content Safety Prompt Shields (text:shieldPrompt REST, GA) via HttpClientChecks the user prompt and retrieved documents (indirect attacks)
Ungrounded outputContent Safety groundedness detection (REST) previewEnglish only. Or run GroundednessEvaluator on a sample
Custom input / output checksDelegatingChatClient (Microsoft.Extensions.AI); Agent Framework middlewareOne place to block, rewrite or log every call
Human-in-the-loopApprovalRequiredAIFunction → ToolApprovalRequestContent / CreateResponse(approved)Agent Framework pauses and asks before running the tool
PII in logs, budgetsMicrosoft.Extensions.Compliance.Redaction; MaximumIterationsPerRequest, MaxOutputTokens, ASP.NET Core rate limitingLimit data exposure and unbounded consumption
// Money movement needs a human "yes" before it runs
AITool transfer = new ApprovalRequiredAIFunction(AIFunctionFactory.Create(TransferMoney));
AIAgent agent = chat.AsAIAgent(instructions: "...", tools: [transfer]);

AgentResponse r = await agent.RunAsync("Pay $500 to John", session);
foreach (var request in r.Messages.SelectMany(m => m.Contents).OfType<ToolApprovalRequestContent>())
{
    bool ok = await AskUserAsync(request);      // show what will run, with the arguments
    r = await agent.RunAsync(new ChatMessage(ChatRole.User, [request.CreateResponse(ok)]), session);
}

ApprovalRequiredAIFunction only marks a tool. The agent runtime (Agent Framework) enforces it. If you call IChatClient directly, check approval in your own code. Azure AI Foundry guardrails can also apply Prompt Shields and content filters to a model deployment without code.

18.9 Agent evaluation & AgentOps Added

You test an agent on its trajectory (the steps and tools it used), not just its final answer.

Metrics

  • Task success rate
  • Tool-call accuracy (right tool, right arguments)
  • Steps, latency, cost per task
  • Escalation and human-override rate
  • Safety violations

Practices

  • Scenario test suites + regression runs in CI
  • Tracing every step (OpenTelemetry GenAI conventions)
  • Replay failed runs
  • Version prompts, tools and models

Tools

LangSmith, Langfuse, Arize Phoenix, Azure AI Foundry tracing & evaluation, Weights & Biases Weave.

When to use an agent? Checklist

How to implement it
Library / APIPackageUse it for
Tracing every stepMicrosoft.Extensions.AI (UseOpenTelemetry()); Agent Framework's built-in OpenTelemetrySpans for model calls and tool calls using the OpenTelemetry GenAI semantic conventions (tokens, model, tool names)
Export + dashboardsOpenTelemetry.Extensions.Hosting, Azure.Monitor.OpenTelemetry.AspNetCoreAspire dashboard locally; Application Insights / Azure AI Foundry tracing in Azure
Agent evaluatorsMicrosoft.Extensions.AI.Evaluation.QualityIntentResolutionEvaluator, TaskAdherenceEvaluator, plus groundedness and relevance
Scenario suites in CIMicrosoft.Extensions.AI.Evaluation.Reporting + dotnet aievalRegression runs on every PR, cached responses, HTML reports
Cloud evaluationAzure.AI.ProjectsFoundry evaluation runs against agents and datasets
IChatClient chat = new ChatClientBuilder(inner)
    .UseFunctionInvocation()
    .UseOpenTelemetry(sourceName: "Bank.Agents")   // GenAI spans: chat, execute_tool, tokens
    .Build();

builder.Services.AddOpenTelemetry()
    .WithTracing(t => t.AddSource("Bank.Agents"))
    .WithMetrics(m => m.AddMeter("Bank.Agents"))
    .UseOtlpExporter();                            // Aspire dashboard / collector

⚡ Quick-fire Q&A

Difference between RAG and an agent?

RAG is a fixed retrieve-then-generate pipeline. An agent decides dynamically what to do, and retrieval can be one of its tools (agentic RAG).

MCP vs function calling?

Function calling is how a model asks to invoke a tool. MCP is a standard protocol for exposing and discovering tools, resources and prompts from external servers, so tools are reusable across apps.

How do you defend against indirect prompt injection?

Treat retrieved content as data, not instructions. Isolate privileges, scope tools tightly, require approval for sensitive actions, use content filters and injection detection, and monitor tool use.

← 17 · RAG & GenAI