Files
semantic-kernel/dotnet
Roger Barreto 1369c2e0ce .Net: Add ExtraBody to OpenAIPromptExecutionSettings (#12307) (#13934)
### Motivation and Context

Closes #12307. Provides .NET parity with the Python fix in #11852 by
adding an escape-hatch `ExtraBody` property to
`OpenAIPromptExecutionSettings`. This allows callers to inject
vendor-specific or preview parameters into the request body without
waiting for SDK modeling. Use cases from the issue include:

- Qwen3 open-source models requiring `enable_thinking: false` for
non-streaming calls
- ChatGLM thinking-mode flags
- Any OpenAI-compatible endpoint exposing fields not modeled by the SDK

### Description

Adds `IDictionary<string, object?>? ExtraBody` to
`OpenAIPromptExecutionSettings` (inherited automatically by
`AzureOpenAIPromptExecutionSettings`), marked
`[Experimental("SKEXP0010")]`.

#### Hybrid key syntax (diverges intentionally from Python to leverage
the OpenAI .NET SDK's `JsonPatch`)

- A plain key is treated as a literal top-level field name. Keys with
dots, brackets, or other special characters are bracket-quoted
automatically and remain literal.
- `ExtraBody["enable_thinking"] = false` → `{ "enable_thinking": false
}`
  - `ExtraBody["weird.key"] = "x"` → `{ "weird.key": "x" }`
- A key starting with `$.` is interpreted as a JSONPath expression and
applied as a deep patch onto the request body.
- `ExtraBody["$.thinking.enabled"] = false` → `{ "thinking": {
"enabled": false } }`
- `ExtraBody["$.tools[0].function.name"] = "x"` → patches into array
elements
- Nested dictionaries are also supported via plain keys:
`ExtraBody["thinking"] = new Dictionary<string,object?> { ["enabled"] =
false }`.

#### Behavior

- **Last-write-wins on collisions** with strongly-typed properties (e.g.
`Temperature`). Documented.
- **`null` values emit JSON `null`**. Field removal is not supported.
- **No input validation, no telemetry emission** of `ExtraBody` contents
(Python parity).
- **Shallow `Clone()`**, `ReadOnlyDictionary` on `Freeze()`.

#### Wiring

- Classic path: `ClientCore.ChatCompletion.cs` and
`AzureClientCore.ChatCompletion.cs` apply patches at the end of
`CreateChatCompletionOptions`.
- `IChatClient` path: new `protected virtual
PrepareChatOptionsForRequest(ChatOptions)` hook on
`PromptExecutionSettings` (mirrors the existing
`PrepareChatHistoryForRequest` pattern). The OpenAI override sets
`ChatOptions.RawRepresentationFactory` and removes the redundant
`AdditionalProperties["extra_body"]` entry produced by `ToChatOptions`'s
round-trip.

#### Files changed

- `SemanticKernel.Abstractions/AI/PromptExecutionSettings.cs` — new hook
+ internal bridge
- `SemanticKernel.Abstractions/AI/PromptExecutionSettingsExtensions.cs`
— invokes the hook on the original derived instance
- `Connectors.OpenAI/Settings/OpenAIPromptExecutionSettings.cs` —
property, Freeze, Clone, `PrepareChatOptionsForRequest` override,
`ApplyExtraBody`/`ApplyExtraBodyEntry` helpers
- `Connectors.OpenAI/Core/ClientCore.ChatCompletion.cs` — apply in
classic path
- `Connectors.AzureOpenAI/Core/AzureClientCore.ChatCompletion.cs` —
apply in Azure classic path
- `samples/Concepts/ChatCompletion/OpenAI_ChatCompletionExtraBody.cs` —
concept sample (flat field + deep patch)

#### Tests (14 new, all passing)

`Connectors.OpenAI.UnitTests` (11): non-streaming flat key, streaming
flat key, collision (last-write-wins), nested dict, `$.` deep patch,
literal dotted key, `null` value, `FromExecutionSettings` round-trip,
Clone shallow, Freeze read-only, `ToChatOptions`
`RawRepresentationFactory` + `AdditionalProperties` cleanup.

`Connectors.AzureOpenAI.UnitTests` (3): flat key, collision, `$.` deep
patch.

#### Regression

- `Connectors.OpenAI.UnitTests`: 485 passed
- `Connectors.AzureOpenAI.UnitTests`: 493 passed
- `SemanticKernel.UnitTests`: 1606 passed (verifies the new hook in
Abstractions has no side effects)

### Contribution Checklist

- [x] The code builds clean without any errors or warnings
- [x] The PR follows the SK Contribution Guidelines and the
pre-submission formatting script raises no violations
- [x] All unit tests pass, and I have added new tests where possible
- [x] I didn't break anyone 😄
2026-04-30 14:36:51 +00:00
..
2025-12-01 17:08:24 +00:00
2025-06-05 07:18:12 +00:00
2025-12-01 17:08:24 +00:00

Get Started with Semantic Kernel ⚡

Important

Semantic Kernel is now Microsoft Agent Framework! Microsoft Agent Framework (MAF) is the enterprise‑ready successor to Semantic Kernel. Microsoft Agent Framework is now available at version 1.0 as a production-ready release: stable APIs, and a commitment to long-term support. Whether you're building a single assistant or orchestrating a fleet of specialized agents, Microsoft Agent Framework 1.0 gives you enterprise-grade multi-agent orchestration, multi-provider model support, and cross-runtime interoperability via A2A and MCP.

Learn more about Semantic Kernel and Agent Framework here: Semantic Kernel and Microsoft Agent Framework on the Agent Framework blog, and try out the Semantic Kernel migration guide.

OpenAI / Azure OpenAI API keys

To run the LLM prompts and semantic functions in the examples below, make sure you have an

Nuget package

Here is a quick example of how to use Semantic Kernel from a C# console app. First, let's create a new project, targeting .NET 6 or newer, and add the Microsoft.SemanticKernel nuget package to your project from the command prompt in Visual Studio:

dotnet add package Microsoft.SemanticKernel

Running prompts with input parameters

Copy and paste the following code into your project, with your Azure OpenAI key in hand:

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;

var builder = Kernel.CreateBuilder();

builder.AddAzureOpenAIChatCompletion(
         "gpt-35-turbo",                      // Azure OpenAI Deployment Name
         "https://contoso.openai.azure.com/", // Azure OpenAI Endpoint
         "...your Azure OpenAI Key...");      // Azure OpenAI Key

// Alternative using OpenAI
//builder.AddOpenAIChatCompletion(
//         "gpt-3.5-turbo",                  // OpenAI Model name
//         "...your OpenAI API Key...");     // OpenAI API Key

var kernel = builder.Build();

var prompt = @"{{$input}}

One line TLDR with the fewest words.";

var summarize = kernel.CreateFunctionFromPrompt(prompt, executionSettings: new OpenAIPromptExecutionSettings { MaxTokens = 100 });

string text1 = @"
1st Law of Thermodynamics - Energy cannot be created or destroyed.
2nd Law of Thermodynamics - For a spontaneous process, the entropy of the universe increases.
3rd Law of Thermodynamics - A perfect crystal at zero Kelvin has zero entropy.";

string text2 = @"
1. An object at rest remains at rest, and an object in motion remains in motion at constant speed and in a straight line unless acted on by an unbalanced force.
2. The acceleration of an object depends on the mass of the object and the amount of force applied.
3. Whenever one object exerts a force on another object, the second object exerts an equal and opposite on the first.";

Console.WriteLine(await kernel.InvokeAsync(summarize, new() { ["input"] = text1 }));

Console.WriteLine(await kernel.InvokeAsync(summarize, new() { ["input"] = text2 }));

// Output:
//   Energy conserved, entropy increases, zero entropy at 0K.
//   Objects move in response to forces.

Semantic Kernel Notebooks

The repository contains also a few C# Jupyter notebooks that demonstrates how to get started with the Semantic Kernel.

See here for the full list, with requirements and setup instructions.

  1. Getting started
  2. Loading and configuring Semantic Kernel
  3. Running AI prompts from file
  4. Creating Semantic Functions at runtime (i.e. inline functions)
  5. Using Kernel Arguments to Build a Chat Experience
  6. Introduction to the Function Calling
  7. Vector Stores and Embeddings
  8. Creating images with DALL-E 3
  9. Chatting with ChatGPT and Images
  10. BingSearch using Kernel

Semantic Kernel Samples

The repository also contains the following code samples:

Type Description
GettingStarted Take this step by step tutorial to get started with the Semantic Kernel and get introduced to the key concepts.
GettingStartedWithAgents Take this step by step tutorial to get started with the Semantic Kernel Agents and get introduced to the key concepts.
Concepts This section contains focussed samples which illustrate all of the concepts included in the Semantic Kernel.
Demos Look here to find a sample which demonstrates how to use many of Semantic Kernel features.
LearnResources Code snippets that are related to online documentation sources like Microsoft Learn, DevBlogs and others

Nuget packages

Semantic Kernel provides a set of nuget packages to allow extending the core with more features, such as connectors to services and plugins to perform specific actions. Unless you need to optimize which packages to include in your app, you will usually start by installing this meta-package first:

  • Microsoft.SemanticKernel

This meta package includes core packages and OpenAI connectors, allowing to run most samples and build apps with OpenAI and Azure OpenAI.

Packages included in Microsoft.SemanticKernel:

  1. Microsoft.SemanticKernel.Abstractions: contains common interfaces and classes used by the core and other SK components.
  2. Microsoft.SemanticKernel.Core: contains the core logic of SK, such as prompt engineering, semantic memory and semantic functions definition and orchestration.
  3. Microsoft.SemanticKernel.Connectors.OpenAI: connectors to OpenAI and Azure OpenAI, allowing to run semantic functions, chats, text to image with GPT3, GPT3.5, GPT4, DALL-E3.

Other SK packages available at nuget.org:

  1. Microsoft.SemanticKernel.Connectors.Qdrant: Qdrant connector for plugins and semantic memory.
  2. Microsoft.SemanticKernel.Connectors.Sqlite: SQLite connector for plugins and semantic memory
  3. Microsoft.SemanticKernel.Plugins.Document: Document Plugin: Word processing, OpenXML, etc.
  4. Microsoft.SemanticKernel.Plugins.MsGraph: Microsoft Graph Plugin: access your tenant data, schedule meetings, send emails, etc.
  5. Microsoft.SemanticKernel.Plugins.OpenApi: OpenAPI Plugin.
  6. Microsoft.SemanticKernel.Plugins.Web: Web Plugin: search the web, download files, etc.