Skip to content

[API Proposal]: ChatOptions ReasoningΒ #7192

@verdie-g

Description

@verdie-g

Background and motivation

While we can use ChatOptions.RawRepresentationFactory to set the reasoning configuration of a request, things get complicated when different providers are supported by the IChatClient. Reasoning seems to be supported by most providers so we should start thinking about how to expose it in ChatOptions.

Here is a summary of how it works for different providers:

Provider Reasoning Comment
Claude output_config={ "effort": "medium" } "thinking": { "type": "enabled", "budget_tokens": 10000 } Enum: low, medium, high. Also supports thinking budget. Effort seems to be the new thing. Default is high
Gemini thinking_config=types.ThinkingConfig(thinking_level="low") thinking_config=types.ThinkingConfig(thinking_budget=1024) Enum: low, high. Also supports budget but the level is "recommended for Gemini 3 models and onwards". Default is dynamic.
Mistral "prompt_mode": "reasoning" reasoning is the default value. Can be set to null to disable it.
OpenAI reasoning={"effort": "medium"} Enum: none, minimal, low, medium, high, xhigh
xAI reasoning_effort="high" Enum: low, high
Amazon ??

API Proposal

public class Reasoning
{
    public static Reasoning None { get; }
    public static Reasoning Low { get; }
    public static Reasoning Medium { get; }
    public static Reasoning High { get; }
}

public class ChatOptions
{
    public Reasoning? Reasoning { get; set; }
}

Low/Medium/High with bool-based providers (Mistral)

None => disable
Low/Medium/High => enable

Default Value

If ChatOptions.Reasoning is null, the provider's default is used:

  • Claude: high
  • Gemini: dynamic thinking
  • Mistral: true
  • OpenAI: medium

API Usage

ChatResponse response = await chatClient.GetResponseAsync("Hi", new ChatOptions
{
    Reasoning = Reasoning.Medium,
});

Alternative Designs

Reasoning.FromBudget(int budget)

Mapping a budget to an enum (for OpenAI) is tricky. With Claude and Gemini moving to enums, I don't think we need to deal with budgets. This greatly simplify things.

Additional Property

Use an additional property. Though, my goal is to be able to use reasoning with all providers so I would rather add it to ChatOptions.

Risks

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-aiMicrosoft.Extensions.AI librariesuntriaged

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions