Skip to content

Commit a85e40a

Browse files
committed
added questions 13 and 14 answers in AI
1 parent a9db0ed commit a85e40a

2 files changed

Lines changed: 269 additions & 2 deletions

File tree

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,123 @@
1-
# AI - Question13 - Describe the "Planner" concept in Microsoft’s Semantic Kernel. How does it allow an AI to autonomously choose which C# methods to execute to solve a complex goal?
1+
# AI - Question13 - Describe the "Planner" concept in Microsoft’s Semantic Kernel. How does it allow an AI to autonomously choose which C# methods to execute to solve a complex goal?
2+
3+
**In modern Semantic Kernel (as of 2025–2026), the dedicated "Planner" classes** (such as the old Sequential, Stepwise, and Handlebars Planners) have been deprecated and removed from the core package. The recommended and far more powerful approach is **automatic function calling** (also called tool calling) integrated directly with the `Kernel` and chat completion services. This mechanism effectively *is* the current Planner.
4+
5+
### What is the Planner Concept?
6+
A **Planner** in Semantic Kernel is an orchestration component that enables an LLM to break down a complex natural-language **goal** into a sequence of executable steps by intelligently selecting and invoking registered **plugins** (collections of functions). These functions can be:
7+
8+
- **Native Functions**: Plain C# methods decorated with `[KernelFunction]`.
9+
- **Prompt Functions**: Semantic prompts defined in YAML or inline.
10+
11+
The AI autonomously decides *which* C# methods to call, *in what order*, with *what parameters*, and can iterate (observe results and replan) until the goal is achieved.
12+
13+
**Mermaid: Modern Function-Calling Planner Flow**
14+
```mermaid
15+
flowchart TD
16+
A["User Goal<br/>'Book a meeting and summarize notes'"] --> B[Kernel + Chat Service]
17+
C["LLM receives Function Schemas<br/>(JSON descriptions of all C# methods)"] --> D{LLM Decides}
18+
B --> C
19+
D -->|Needs info| E["Call C# Method e.g. GetCalendar()"]
20+
D -->|Action ready| F["Call C# Method e.g. CreateEvent()"]
21+
E --> G[Execute Native C# Code]
22+
F --> G
23+
G --> H[Return Result to LLM]
24+
H --> I[LLM Evaluates + Next Step or Final Answer]
25+
I -->|Not Done| B
26+
I -->|Goal Achieved| J[Return Final Response]
27+
```
28+
29+
### How It Allows Autonomous C# Method Execution
30+
31+
1. **Function Exposure**: You register plugins. Semantic Kernel automatically generates detailed JSON schemas (including descriptions, parameter types, and `KernelFunction` attributes) for the LLM.
32+
33+
2. **Automatic Tool Choice**: Set `FunctionChoiceBehavior.Auto()` (or `Required`/`None`). The LLM receives these schemas in every request.
34+
35+
3. **Iterative Execution Loop**: SK handles the full ReAct-style loop internally:
36+
- LLM requests one or more function calls (parallel supported).
37+
- SK invokes the corresponding C# methods.
38+
- Results are injected back into the chat history.
39+
- LLM decides the next action or produces a final answer.
40+
41+
This gives the AI true autonomy while keeping all business logic safely in your strongly-typed C# code.
42+
43+
### Code Example: Autonomous Planning via Function Calling
44+
```csharp
45+
using Microsoft.SemanticKernel;
46+
using Microsoft.SemanticKernel.ChatCompletion;
47+
using Microsoft.SemanticKernel.Connectors.OpenAI;
48+
49+
public class CalendarPlugin
50+
{
51+
[KernelFunction("GetUpcomingEvents")]
52+
[Description("Retrieves upcoming calendar events")]
53+
public async Task<string> GetUpcomingEventsAsync()
54+
{
55+
// Real implementation (Outlook, Google, etc.)
56+
return "Team sync at 10am tomorrow";
57+
}
58+
59+
[KernelFunction("CreateEvent")]
60+
[Description("Creates a new calendar event")]
61+
public async Task<string> CreateEventAsync(string title, string dateTime, string attendees)
62+
{
63+
// Business logic here
64+
return $"Event '{title}' created successfully.";
65+
}
66+
}
67+
68+
// Setup
69+
var builder = Kernel.CreateBuilder()
70+
.AddAzureOpenAIChatCompletion("gpt-4o", endpoint, apiKey);
71+
72+
builder.Plugins.AddFromType<CalendarPlugin>("Calendar");
73+
Kernel kernel = builder.Build();
74+
75+
var chatService = kernel.GetRequiredService<IChatCompletionService>();
76+
77+
// Enable autonomous planning
78+
var executionSettings = new OpenAIPromptExecutionSettings
79+
{
80+
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() // This is the Planner
81+
};
82+
83+
var history = new ChatHistory();
84+
history.AddUserMessage("Schedule a 30-minute sync with the team tomorrow at 10am and confirm availability.");
85+
86+
var result = await chatService.GetChatMessageContentAsync(
87+
history,
88+
executionSettings,
89+
kernel); // SK handles multiple tool calls automatically
90+
91+
Console.WriteLine(result);
92+
```
93+
94+
**Mermaid: Single Interaction with Autonomous Steps**
95+
```mermaid
96+
sequenceDiagram
97+
participant User
98+
participant SK Kernel
99+
participant LLM
100+
participant CSharpCode as C# Plugin Methods
101+
102+
User->>SK Kernel: Complex Goal
103+
SK Kernel->>LLM: Goal + All Function Schemas
104+
LLM->>SK Kernel: Call GetUpcomingEvents()
105+
SK Kernel->>CSharpCode: Execute method
106+
CSharpCode-->>SK Kernel: Result
107+
SK Kernel->>LLM: Result injected
108+
LLM->>SK Kernel: Call CreateEvent(title, time, attendees)
109+
SK Kernel->>CSharpCode: Execute method
110+
CSharpCode-->>SK Kernel: Success
111+
SK Kernel->>User: Final natural language response
112+
```
113+
114+
### Key Advantages
115+
- **Autonomy**: The LLM dynamically composes solutions using your C# logic without hard-coded workflows.
116+
- **Safety**: All execution stays within your controlled C# methods (no arbitrary code gen in production).
117+
- **Observability**: Full chat history shows every tool call and result.
118+
- **Extensibility**: Combine with `Microsoft.Extensions.AI`, memory/vector stores (RAG), and agents.
119+
- **Performance**: Leverages native function calling in modern models (OpenAI, Azure, Anthropic, etc.) — faster and more reliable than old prompt-based planners.
120+
121+
**Note on Legacy Planners**: Older `HandlebarsPlanner` and `StepwisePlanner` are no longer recommended or included by default. Microsoft now directs developers to function calling for new applications due to superior flexibility, streaming support, and accuracy.
122+
123+
This function-calling planner pattern is the foundation of modern agentic applications in Semantic Kernel. It transforms static C# methods into dynamic, AI-orchestrated capabilities while maintaining full type safety and enterprise control. For the latest patterns, refer to the official Microsoft Learn documentation on Semantic Kernel planning and function calling.
Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,146 @@
1-
# AI - Question 14 - How would you design a DI-friendly service that can swap between local LlamaEdge models and OpenAI cloud models without changing the business logic?
1+
# AI - Question 14 - How would you design a DI-friendly service that can swap between local LlamaEdge models and OpenAI cloud models without changing the business logic?
2+
3+
**Use `Microsoft.Extensions.AI` abstractions** (`IChatClient` and `IEmbeddingGenerator<TInput, TEmbedding>`) for a clean, DI-friendly, provider-agnostic design. This allows seamless swapping between cloud OpenAI and local models (via Ollama for Llama models or LlamaEdge’s OpenAI-compatible server) without altering business logic.
4+
5+
### Core Design Principle
6+
Code against the **abstractions** (`IChatClient`). Register the concrete implementation (OpenAI, Azure, Ollama, etc.) in the DI container via configuration or environment. Middleware (logging, retry, telemetry, function calling) applies uniformly.
7+
8+
**Provider-Agnostic Architecture**
9+
```mermaid
10+
flowchart TD
11+
A[Business Services] --> B[IChatClient Interface]
12+
C["Middleware Pipeline<br/>(Logging, Caching, FunctionCalling, OTEL)"] --> D{Configuration}
13+
B --> C
14+
D -->|Production| E["OpenAIChatClient / Azure"]
15+
D -->|Development / Edge| F["OllamaChatClient / LlamaEdge via OpenAI endpoint"]
16+
E --> G[Cloud LLM]
17+
F --> H[Local Llama Model]
18+
style B fill:#90EE90
19+
```
20+
21+
### DI Registration (Program.cs / Startup)
22+
```csharp
23+
using Microsoft.Extensions.AI;
24+
using Microsoft.Extensions.DependencyInjection;
25+
using Microsoft.Extensions.Configuration;
26+
27+
var builder = WebApplication.CreateBuilder(args);
28+
29+
// Read configuration
30+
var aiSettings = builder.Configuration.GetSection("AI").Get<AISettings>() ?? new();
31+
32+
IChatClient chatClient;
33+
34+
if (aiSettings.UseLocalModel)
35+
{
36+
// Local: Ollama (recommended for Llama models)
37+
chatClient = new OllamaChatClient(
38+
new Uri(aiSettings.LocalEndpoint ?? "http://localhost:11434"),
39+
aiSettings.LocalModel ?? "llama3.2");
40+
41+
// Alternative: LlamaEdge (OpenAI-compatible server)
42+
// chatClient = new OpenAIChatClient(
43+
// new OpenAIClient(new ApiKeyCredential("ignored"), new OpenAIClientOptions
44+
// {
45+
// Endpoint = new Uri(aiSettings.LocalEndpoint)
46+
// }))
47+
// .GetChatClient(aiSettings.LocalModel);
48+
}
49+
else
50+
{
51+
// Cloud
52+
chatClient = new OpenAIChatClient(aiSettings.OpenAIModel, aiSettings.ApiKey);
53+
// Or Azure: new AzureOpenAIChatClient(...)
54+
}
55+
56+
// Add to DI with middleware
57+
builder.Services.AddChatClient(chatClient)
58+
.UseLogging()
59+
.UseFunctionInvocation() // For tool calling / agents
60+
.UseOpenTelemetry(); // Observability
61+
62+
// Optional: Keyed services for multiple models
63+
// builder.Services.AddKeyedChatClient("local", localClient);
64+
// builder.Services.AddKeyedChatClient("cloud", cloudClient);
65+
```
66+
67+
**Configuration Example (appsettings.json):**
68+
```json
69+
{
70+
"AI": {
71+
"UseLocalModel": true,
72+
"LocalEndpoint": "http://localhost:11434",
73+
"LocalModel": "llama3.2",
74+
"OpenAIModel": "gpt-4o",
75+
"ApiKey": "sk-..."
76+
}
77+
}
78+
```
79+
80+
### DI-Friendly Service (No Provider Awareness)
81+
```csharp
82+
public interface IRagService
83+
{
84+
Task<string> AnswerQuestionAsync(string question, CancellationToken ct = default);
85+
}
86+
87+
public class RagService : IRagService
88+
{
89+
private readonly IChatClient _chatClient;
90+
private readonly IEmbeddingGenerator<string, Embedding<float>> _embeddingGenerator; // Optional for RAG
91+
92+
public RagService(IChatClient chatClient, IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator)
93+
{
94+
_chatClient = chatClient;
95+
_embeddingGenerator = embeddingGenerator;
96+
}
97+
98+
public async Task<string> AnswerQuestionAsync(string question, CancellationToken ct = default)
99+
{
100+
// Business logic stays identical regardless of provider
101+
var history = new ChatHistory();
102+
history.AddUserMessage(question);
103+
104+
// Optional: RAG retrieval using embeddings...
105+
106+
var response = await _chatClient.GetResponseAsync(
107+
history,
108+
new ChatOptions { Temperature = 0.7f },
109+
ct);
110+
111+
return response.Message.Text ?? string.Empty;
112+
}
113+
}
114+
115+
// Registration
116+
builder.Services.AddScoped<IRagService, RagService>();
117+
```
118+
119+
**Mermaid: Service Dependency Flow**
120+
```mermaid
121+
flowchart TD
122+
subgraph "Business Layer"
123+
A[RagService / Agents] --> B[IChatClient]
124+
A --> C[IEmbeddingGenerator]
125+
end
126+
subgraph "DI Container"
127+
B --> D[OpenAI Implementation]
128+
B --> E[Ollama / LlamaEdge Implementation]
129+
end
130+
D --> F[Cloud]
131+
E --> G[Local Llama]
132+
```
133+
134+
### Key Benefits
135+
- **Zero business logic changes** when switching providers.
136+
- **Middleware reuse** — logging, retry, caching, and function calling work for both local and cloud.
137+
- **Environment-specific** behavior via configuration (local for dev/privacy, cloud for production scale/quality).
138+
- **Streaming support** remains identical using `IAsyncEnumerable<StreamingChatCompletionUpdate>`.
139+
- **Semantic Kernel compatibility** — SK works natively on top of `IChatClient`.
140+
141+
### Local Model Notes (Llama)
142+
- **Ollama** is the most common, stable choice for Llama models in .NET via `OllamaSharp` / `Microsoft.Extensions.AI.Ollama` (or successor packages).
143+
- **LlamaEdge** exposes an OpenAI-compatible endpoint, so the standard `OpenAIChatClient` with a custom `Endpoint` works perfectly.
144+
- For pure native execution without a server, consider LLamaSharp or ONNX Runtime GenAI with custom wrappers implementing `IChatClient`.
145+
146+
This design follows official Microsoft recommendations for provider-agnostic .NET AI applications. It scales from development (fast local iteration) to production (cloud reliability) while keeping your core application code clean and maintainable. Always test model-specific behaviors (context length, tool calling quality) when swapping. Refer to Microsoft Learn documentation for `Microsoft.Extensions.AI` for the latest configuration patterns.

0 commit comments

Comments
 (0)