Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.Net: Allow Modifying the OpenAI endpoint #3159

Closed
239573049 opened this issue Oct 12, 2023 · 7 comments
Closed

.Net: Allow Modifying the OpenAI endpoint #3159

239573049 opened this issue Oct 12, 2023 · 7 comments
Labels
auto-closed Automatically closed

Comments

@239573049
Copy link

How to change the endpoint of sk's openai? Instead of forcing the use of official endpoints

@matthewbolanos matthewbolanos changed the title Modify the openai endpoint .NET: Allow Modifying the OpenAI endpoint Oct 26, 2023
@MaxAkbar
Copy link

MaxAkbar commented Nov 5, 2023

I found the following:
https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/KernelSyntaxExamples/Example41_HttpClientUsage.cs. It seems we can override the URI using a custom HttpClient. Can you confirm? I plan to test it next week.

EDIT:
So, I tested this, and it's not using my HttpClient Base Address :(.

@RogerBarreto
Copy link
Member

RogerBarreto commented Nov 6, 2023

@MaxAkbar Try using the IDelegatingHandlerFactory

This example it uses the IDelegatingHandlerFactory to make a retry but you can create your own to alter the Url at the Task<HttpResponseMessage> SendAsync override

@MaxAkbar
Copy link

MaxAkbar commented Nov 7, 2023

That worked, calling my custom endpoint, and is a workaround. I hope this ticket addresses the issue of us reusing the OpenAI standard for accessing our own LLMs, thank you.

@MaxAkbar
Copy link

It seems that the latest code no longer includes IDelegatingHandlerFactory. Has it been replaced by another interface or another way of doing this?

Thanks in advance,
-Max

@stephentoub
Copy link
Member

stephentoub commented Dec 19, 2023

Has it been replaced by another interface or another way of doing this?

Yes. SK's IDelegatingHandlerFactory was a bespoke mechanism for doing this, when .NET already has such a mechanism, so SK's custom thing was removed in favor of just using what .NET already provides. In particular, HttpClient is already built around a pipeline of HttpMessageHandlers, and the core libraries provide a DelegatingHandler that makes it easy to create your own that wraps another. So, for example, if want to create a delegating handler that wraps the core HttpClientHandler but changes the host of any request Uris to be localhost, I can write:

sealed class MyRedirectingHandler() : DelegatingHandler(new HttpClientHandler())
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.RequestUri = new UriBuilder(request.RequestUri!) { Host = "localhost" }.Uri;
        return base.SendAsync(request, cancellationToken);
    }
}

(this is using C# 12 syntax for primary constructors just to simplify things ab it). Then, if I had my SK usage like:

IKernelBuilder builder = 
    Kernel.CreateBuilder()
    .AddOpenAIChatCompletion("gpt-4", apikey);

Kernel kernel = builder.Build();

Console.WriteLine(await kernel.InvokePromptAsync("What color is the sky?"));

I could add one line before the call to Build:

builder.Services.ConfigureHttpClientDefaults(b =>
    b.ConfigurePrimaryHttpMessageHandler(() => new MyRedirectingHandler()));

and now any HttpClient instances created via this kernel or its services (like the one created as part of the AddOpenAIChatCompletion method) will automatically pick up that handler. This approach also means you can take advantage of the rich ecosystem around such handlers. For example, if you want resiliency in the form of retries, automatically respecting Retry-After in response headers, etc., you can add a reference to the Microsoft.Extensions.Http.Reslience package, and then change the line above to be:

builder.Services.ConfigureHttpClientDefaults(b =>
{
    b.AddStandardResilienceHandler();
    b.ConfigurePrimaryHttpMessageHandler(() => new MyRedirectingHandler());
});

and now in addition to using my custom handler, it'll inject into the handler pipeline support for retries and circuit breakers and so on (which can be customized further).

@matthewbolanos matthewbolanos added .NET Issue or Pull requests regarding .NET code ai connector Anything related to AI connectors labels Jan 2, 2024
@github-actions github-actions bot changed the title .NET: Allow Modifying the OpenAI endpoint .Net: Allow Modifying the OpenAI endpoint Jan 2, 2024
@sangyuxiaowu
Copy link
Contributor

Here is a temporary solution to modify private variables through reflection, hoping to help friends with needs. Of course, other content can also be modified through this method.

I also submitted a modification Azure/azure-sdk-for-net#41242

using Azure.AI.OpenAI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using System.Reflection;

var builder = Kernel.CreateBuilder();
var aiclietn =  new OpenAIClient(
            new Uri("http://127.0.0.1:8000/v1"),
            new Azure.AzureKeyCredential("empty")
        );
// 获取_isConfiguredForAzureOpenAI字段的引用
var field = typeof(OpenAIClient).GetField("_isConfiguredForAzureOpenAI", BindingFlags.NonPublic | BindingFlags.Instance);
// 修改_isConfiguredForAzureOpenAI字段的值
if (field != null)
{
    field.SetValue(aiclietn, false);
}

builder.AddOpenAIChatCompletion("qwen",aiclietn);
// ... 省略部分代码

@markwallace-microsoft
Copy link
Member

All .Net issues prior to 1-Dec-2023 are being closed. Please re-open, if this issue is still relevant to the .Net Semantic Kernel 1.x release. In the future all issues that are inactive for more than 90 days will be labelled as 'stale' and closed 14 days later.

@markwallace-microsoft markwallace-microsoft added auto-closed Automatically closed and removed .NET Issue or Pull requests regarding .NET code ai connector Anything related to AI connectors labels Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-closed Automatically closed
Projects
Archived in project
Development

No branches or pull requests

8 participants