openai / openai-dotnet

The official .NET library for the OpenAI API
https://www.nuget.org/packages/OpenAI
MIT License
1.43k stars 138 forks source link

Add Support for OpenAI new Structured Outputs. #160

Closed RogerBarreto closed 2 months ago

RogerBarreto commented 2 months ago

Add Support for Structured Outputs

As mentioned in the recent blog post from OpenAI.

Now is possible to specify the response_format as json_schema.

Additional context

twf-datacom commented 2 months ago

To make it similar to the python and node sdks that use pydantic and zod respectively, could we use something like NJsonSchema to specify the response_format?

MosheAzraf commented 2 months ago

I've tried to use it, it does response with a JSON string, but doesn't always response with a consist object form, In fact, I've opened an issue about that, in the Q/A discussion.

sagos95 commented 2 months ago

It would be brilliant if there were the ability to use this feature like as the JsonSerializer works, for example: var pocoModel = await chatCompletionService.GetChatMessageContentsAsync<PocoUserResponseType>("prompt") or something similar.

HavenDV commented 2 months ago

I added this feature to LangChain.NET generated OpenAI SDK(https://github.com/tryAGI/OpenAI) today, here's what it looks like, maybe it will help. It also includes trimming/NativeAOT support:

using OpenAI;

using var api = new OpenAiApi("API_KEY");

MathReasoning? mathReasoning = await api.Chat.CreateChatCompletionAsAsync<MathReasoning>(
            messages: ["How can I solve 8x + 7 = -23?"],
            model: CreateChatCompletionRequestModel.Gpt4o20240806,
            strict: true);

Console.WriteLine($"Final answer: {mathReasoning?.FinalAnswer}");
Console.WriteLine("Reasoning steps:");

foreach (MathReasoningStep step in mathReasoning?.Steps ?? [])
{
    Console.WriteLine($"  - Explanation: {step.Explanation}");
    Console.WriteLine($"    Output: {step.Output}");
}
public class MathReasoning
{
    public MathReasoningStep[] Steps { get; set; } = [];
    public string FinalAnswer { get; set; } = string.Empty;
}

public class MathReasoningStep
{
    public string Explanation { get; set; } = string.Empty;
    public string Output { get; set; } = string.Empty;
}
Final answer: x = -15/4
Reasoning steps:
  - Explanation: Start by isolating 8x on one side of the equation. To do this, subtract 7 from both sides.
    Output: 8x + 7 - 7 = -23 - 7
  - Explanation: Simplify both sides of the equation by performing the subtraction.
    Output: 8x = -30
  - Explanation: Next, solve for x by dividing both sides by 8 to isolate x.
    Output: 8x/8 = -30/8
  - Explanation: Simplify the division on the right-hand side to find the value of x.
    Output: x = -30/8
  - Explanation: Reduce the fraction to its simplest form.
    Output: x = -15/4

Tests are available here: https://github.com/tryAGI/OpenAI/blob/main/src/tests/OpenAI.IntegrationTests/Tests.Chat.StructuredOutputs.cs Main implementation is here: https://github.com/tryAGI/OpenAI/blob/main/src/libs/OpenAI/TypeToSchemaHelpers.cs

StephenHodgson commented 2 months ago

I too have finished Structured Outputs in og OpenAI-DotNet 8.2.0

sagos95 commented 2 months ago

@StephenHodgson works fine! But it can't deserialize bool? fields for some reason. Anyway, thanks for your solution

StephenHodgson commented 2 months ago

can't deserialize bool? fields for some reason.

Ideally you should be able to! I'll double check by adding sample values in a unit test to verify.

joseharriaga commented 2 months ago

Thank you for reaching out, @RogerBarreto ! Support for structured outputs has been added as part of this PR: 🔗 https://github.com/openai/openai-dotnet/pull/180

It is now available on NuGet starting with version 2.0.0-beta.9: 🔗 https://www.nuget.org/packages/OpenAI/2.0.0-beta.9

Here we have an example on how to use it with chat completions: 🔗 Example07_StructuredOutputsAsync.cs

andreylukin commented 2 months ago

Hi, I dont see a JSON Schema generator implementation as part of 2.0.0-beta.9 or 2.0.0-beta.10. Are there any plans to add it?

r-Larch commented 1 month ago

Hi @andreylukin, @sagos95 and @StephenHodgson

I've written a JSON Schema generator to produce OpenAi compatible JSON Schema. It's available as Nuget:

LarchSys.OpenAi.JsonSchema

LarchSys.OpenAi.JsonSchema is a lightweight library for generating valid JSON Schema for OpenAI models' Structured Outputs feature. It supports a wide range of types, ensures compatibility with OpenAI's JSON Schema format, and leverages C# descriptions and attributes for schema generation.

StephenHodgson commented 1 month ago

FWIW, starting in .net 9 System.Text.Json has native support to generate and export schema for you